Advanced RAG 02:揭秘 PDF 解析

Advanced RAG 02:揭秘 PDF 解析

摘要:本文深入探讨了 PDF 文档解析在 RAG 系统中的关键作用,详细介绍了基于规则、深度学习模型和多模态大模型的三种解析方法。文章重点分析了使用开源框架 Unstructured 解析 PDF 时面临的三大挑战(表格/图像提取、双栏排版重排、多级标题提取),并提供了相应的算法思路和代码示例,适合希望提升非结构化数据处理能力的开发者阅读。

对于 RAG 来说,从文档中提取信息是一个不可避免的场景。确保从源头提取内容的有效性对于提高最终输出的质量至关重要。

不要低估这个过程,这一点很重要。在实施 RAG 时,解析过程中糟糕的信息提取可能导致对 PDF 文件中包含的信息的理解和利用受限。

解析过程在 RAG 中的位置如图 1 所示:

在实际工作中,非结构化数据远比结构化数据丰富。如果这些海量数据无法被解析,它们的巨大价值将无法实现。

在非结构化数据中,PDF 文档占大多数。 有效地处理 PDF 文档也可以极大地帮助管理其他类型的非结构化文档。

本文主要介绍解析 PDF 文件的方法。它提供了有效地解析 PDF 文档并尽可能多地提取有用信息的算法和建议。

1、解析 PDF 的挑战

PDF 文档是非结构化文档的代表,然而,从 PDF 文档中提取信息是一个具有挑战性的过程。

与其说是一种数据格式,不如说 PDF 更准确地描述为打印指令的集合 。PDF 文件由一系列指令组成,这些指令指示 PDF 阅读器或打印机如何在屏幕或纸张上显示符号。这与 HTML 和 docx 等文件格式形成对比,后者使用 <p><w:p>, <table><w:tbl> 等标签来组织不同的逻辑结构,如图 2 所示:

解析 PDF 文档的挑战在于准确提取整个页面的布局,并将内容(包括表格、标题、段落和图像)转换为文档的文本表示。 该过程涉及处理文本提取中的不准确性、图像识别以及表格中行列关系的混淆。

2、如何解析 PDF 文档

一般来说,解析 PDF 有三种方法:

  • 基于规则的方法:根据文档的组织特征确定每个部分的样式和内容。然而,这种方法通用性不强,因为 PDF 的类型和布局众多,无法用预定义的规则涵盖所有情况。
  • 基于深度学习模型的方法:例如结合目标检测和 OCR 模型的流行解决方案。
  • 基于多模态大模型解析复杂结构或提取 PDF 中的关键信息。

2.1 基于规则的方法

最具代表性的工具之一是 pypdf,这是一个广泛使用的基于规则的解析器。它是 LangChainLlamaIndex 中解析 PDF 文件的标准方法。

下面是使用 pypdf 解析"Attention Is All You Need"论文第 6 页的尝试。原始页面如图 3 所示。

代码如下:

python 复制代码
import PyPDF2
filename = "/Users/Florian/Downloads/1706.03762.pdf"
pdf_file = open(filename, 'rb')

reader = PyPDF2.PdfReader(pdf_file)

page_num = 5
page = reader.pages[page_num]
text = page.extract_text()

print('--------------------------------------------------')
print(text)

pdf_file.close()

执行结果如下(为简洁起见省略其余部分):

bash 复制代码
(py) Florian:~ Florian$ pip list | grep pypdf
pypdf                    3.17.4
pypdfium2                4.26.0

(py) Florian:~ Florian$ python /Users/Florian/Downloads/pypdf_test.py

Table 1: Maximum path lengths, per-layer complexity and minimum number of sequential operations
for different layer types. nis the sequence length, dis the representation dimension, kis the kernel
size of convolutions and rthe size of the neighborhood in restricted self-attention.
Layer Type Complexity per Layer Sequential Maximum Path Length
Operations
Self-Attention O(n2·d) O(1) O(1)
Recurrent O(n·d2) O(n) O(n)
Convolutional O(k·n·d2) O(1) O(logk(n))
Self-Attention (restricted) O(r·n·d) O(1) O(n/r)
3.5 Positional Encoding
Since our model contains no recurrence and no convolution, in order for the model to make use of the
order of the sequence, we must inject some information about the relative or absolute position of the
tokens in the sequence. To this end, we add "positional encodings" to the input embeddings at the
bottoms of the encoder and decoder stacks. The positional encodings have the same dimension dmodel
as the embeddings, so that the two can be summed. There are many choices of positional encodings,
learned and fixed [9].
In this work, we use sine and cosine functions of different frequencies:
PE(pos,2i)=sin(pos/100002i/d model)
PE(pos,2i+1)=cos(pos/100002i/d model)
where posis the position and iis the dimension. That is, each dimension of the positional encoding
corresponds to a sinusoid. The wavelengths form a geometric progression from 2πto10000 ·2π. We
chose this function because we hypothesized it would allow the model to easily learn to attend by
relative positions, since for any fixed offset k,PEpos+kcan be represented as a linear function of
PEpos.
...
...
...

根据 PyPDF 检测的结果,可以观察到它将 PDF 中的字符序列序列化为一个长序列,而没有保留结构信息。换句话说,它将文档的每一行视为由换行符 "\n" 分隔的序列,这使得无法准确识别段落或表格。

这种限制是基于规则的方法的固有特征。

2.2 基于深度学习模型的方法

这种方法的优点是能够准确识别整个文档的布局,包括表格和段落。它甚至可以理解表格内部的结构。这意味着它可以将文档划分为定义明确、完整的信息单元,同时保留预期的含义和结构。

然而,也有一些限制。目标检测和 OCR 阶段可能很耗时。因此,建议使用 GPU 或其他加速设备,并采用多进程和多线程进行处理。

这种方法涉及目标检测和 OCR 模型,我测试了几个具有代表性的开源框架:

  • Unstructured:它已被 集成到 langchain 中。使用 infer_table_structure=Truehi_res 策略的表格识别效果很好。然而,fast 策略表现不佳,因为它不使用目标检测模型,并且错误地识别了许多图像和表格。
  • Layout-parser:如果你需要识别复杂结构的 PDF,建议使用最大的模型以获得更高的准确性,尽管可能会稍慢一些。此外,Layout-parser 的模型 似乎在过去两年中没有更新。
  • PP-StructureV2:使用各种模型组合进行文档分析,性能高于平均水平。架构如图 4 所示:

除了开源工具外,还有像 ChatDOC 这样的付费工具,它们利用基于布局的识别 + OCR 方法来解析 PDF 文档。

接下来,我们将解释如何使用开源 unstructured 框架解析 PDF,解决三个关键挑战。

2.2.1 挑战 1:如何从表格和图像中提取数据

在这里,我们将使用 unstructured 框架作为示例。检测到的表格数据可以直接导出为 HTML。代码如下:

python 复制代码
from unstructured.partition.pdf import partition_pdf

filename = "/Users/Florian/Downloads/Attention_Is_All_You_Need.pdf"


elements = partition_pdf(filename=filename, infer_table_structure=True)
tables = [el for el in elements if el.category == "Table"]

print(tables[0].text)
print('--------------------------------------------------')
print(tables[0].metadata.text_as_html)

我追踪了 **partition_pdf** 函数的内部过程。图 5 是一个基本流程图。

代码的运行结果如下:

复制代码
Layer Type Self-Attention Recurrent Convolutional Self-Attention (restricted) Complexity per Layer O(n2 · d) O(n · d2) O(k · n · d2) O(r · n · d) Sequential Maximum Path Length Operations O(1) O(n) O(1) O(1) O(1) O(n) O(logk(n)) O(n/r)
--------------------------------------------------
<table><thead><th>Layer Type</th><th>Complexity per Layer</th><th>Sequential Operations</th><th>Maximum Path Length</th></thead><tr><td>Self-Attention</td><td>O(n? - d)</td><td>O(1)</td><td>O(1)</td></tr><tr><td>Recurrent</td><td>O(n- d?)</td><td>O(n)</td><td>O(n)</td></tr><tr><td>Convolutional</td><td>O(k-n-d?)</td><td>O(1)</td><td>O(logy(n))</td></tr><tr><td>Self-Attention (restricted)</td><td>O(r-n-d)</td><td>ol)</td><td>O(n/r)</td></tr></table>

复制 HTML 标签并将其保存为 HTML 文件。然后,使用 Chrome 打开它,如图 6 所示:

可以观察到,unstructured 的算法在很大程度上还原了整个表格。

2.2.2 挑战 2:如何重新排列检测到的块?特别是对于双栏 PDF

在处理双栏 PDF 时,让我们以论文"BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding"为例。阅读顺序由红色箭头显示:

在识别布局后,unstructured 框架会将每个页面划分为几个矩形块,如图 8 所示。

每个矩形块的详细信息可以通过以下格式获得:

复制代码
[

LayoutElement(bbox=Rectangle(x1=851.1539916992188, y1=181.15073777777613, x2=1467.844970703125, y2=587.8204599999975), text='These approaches have been generalized to coarser granularities, such as sentence embed- dings (Kiros et al., 2015; Logeswaran and Lee, 2018) or paragraph embeddings (Le and Mikolov, 2014). To train sentence representations, prior work has used objectives to rank candidate next sentences (Jernite et al., 2017; Logeswaran and Lee, 2018), left-to-right generation of next sen- tence words given a representation of the previous sentence (Kiros et al., 2015), or denoising auto- encoder derived objectives (Hill et al., 2016). ', source=<Source.YOLOX: 'yolox'>, type='Text', prob=0.9519357085227966, image_path=None, parent=None), 
...
]

其中 (x1, y1) 是左上角顶点的坐标,(x2, y2) 是右下角顶点的坐标:

复制代码
        (x_1, y_1) --------
            |             |
            |             |
            |             |
            ---------- (x_2, y_2)

此时,你可以选择重塑页面的阅读顺序。Unstructured 自带排序算法,但我发现在处理双栏情况时,排序结果并不是很令人满意。

因此,有必要设计一种算法。最简单的方法是先按左上角的水平坐标排序,如果水平坐标相同,再按垂直坐标排序。伪代码如下:

python 复制代码
layout.sort(key=lambda z: (z.bbox.x1, z.bbox.y1, z.bbox.x2, z.bbox.y2))

然而,我们发现即使是同一栏中的块,其水平坐标也可能存在差异。如图 9 所示,紫线块的水平坐标 bbox.x1 实际上更靠左。排序时,它会被放在绿线块之前,这显然违反了阅读顺序。

在这种情况下,可以使用的一种可能的算法如下:

  • 首先,对所有左上角 x 坐标 **x1** 进行排序,我们可以得到 **x1_min**
  • 然后,对所有右下角 x 坐标 **x2** 进行排序,我们可以得到 **x2_max**
  • 接下来,确定页面中心线的 x 坐标为:
python 复制代码
x1_min = min([el.bbox.x1 for el in layout])
x2_max = max([el.bbox.x2 for el in layout])
mid_line_x_coordinate = (x2_max + x1_min) /  2

接下来,**if bbox.x1 < mid_line_x_coordinate**,则该块被归类为左栏的一部分。否则,它被视为右栏的一部分。

分类完成后,根据 y 坐标对每栏中的块进行排序。最后,将右栏连接到左栏的右侧。

python 复制代码
left_column = []
right_column = []
for el in layout:
    if el.bbox.x1 < mid_line_x_coordinate:
        left_column.append(el)
    else:
        right_column.append(el)

left_column.sort(key = lambda z: z.bbox.y1)
right_column.sort(key = lambda z: z.bbox.y1)
sorted_layout = left_column + right_column

值得一提的是,这一改进也兼容单栏 PDF。

还需要提到的是,文中的 **LayoutElement** 是调试过程中的中间信息,我们也可以对函数 **partition_pdf** 的返回值 **elements** 进行排序,原理是一样的。

2.2.3 挑战 3:如何提取多级标题

提取标题(包括多级标题)的目的是提高 LLM 回答的准确性。

例如,如果用户想知道图 9 中 2.1 节的主旨,通过准确提取 2.1 节的标题,并将其连同相关内容作为上下文发送给 LLM,最终答案的准确性将显著提高。

该算法仍然依赖于图 9 所示的布局块。我们可以提取 **type='Section-header'** 的块并计算高度差(**bbox.y2 --- bbox.y1**)。高度差最大的块对应一级标题,其次是二级标题,然后是三级标题。

2.3 基于多模态大模型解析 PDF 中的复杂结构

在多模态模型爆发后,也可以使用多模态模型来解析表格。有几种选择

  • 检索相关图像(PDF 页面)并将其发送给 GPT4-V 以响应查询。
  • 将每个 PDF 页面视为图像,让 GPT4-V 对每个页面进行图像推理。为图像推理构建文本向量存储索引。针对图像推理向量存储查询答案。
  • 使用 Table Transformer 从检索到的图像中裁剪表格信息,然后将这些裁剪后的图像发送给 GPT4-V 进行查询响应。
  • 对裁剪后的表格图像应用 OCR,并将数据发送给 GPT4/GPT-3.5 以回答查询。

经过测试,确定第三种方法最有效。

此外,我们可以使用多模态模型从图像中提取或总结关键信息(PDF 文件可以轻松转换为图像),如图 10 所示。

3、结论

总的来说,非结构化文档提供了高度的灵活性,需要各种解析技术。然而,目前对于使用哪种最佳方法尚未达成共识。

在这种情况下,建议选择最适合你项目需求的方法。建议根据不同类型的 PDF 采用特定的处理方式。例如,论文、书籍和财务报表可能会根据其特征进行独特的设计。

尽管如此,如果条件允许,仍然建议选择基于深度学习或基于多模态的方法。这些方法可以有效地将文档分割成定义明确且完整的信息单元,从而最大程度地保留文档的预期含义和结构。

相关推荐
优化控制仿真模型12 小时前
26年初中中考英语大纲词汇1600个电子版PDF
经验分享·pdf
优化控制仿真模型12 小时前
【26专四】英语专业四级TEM4历年真题及答案电子版PDF(2009-2025年)
经验分享·pdf
小白跃升坊12 小时前
1Panel AI 终端:用自然语言,把 Linux 运维变简单
人工智能·ai·aigc·aiagent·openclaw
想你依然心痛12 小时前
TinyVue 3.0 与 AI 协同开发指南:从组件设计到智能体编排
人工智能·ai·组件·智能体·tinyvue
一位代码12 小时前
python | 使用 pdfplumber 库提取 pdf 中的所有超链接
pdf
CodeCaptain12 小时前
【七】Web 端初始化配置的详细步骤
windows·ubuntu·ai·openclaw
刘 大 望13 小时前
RAG相关技术介绍及Spring AI中使用--第二期
java·人工智能·spring·ai·chatgpt·aigc·etl
做cv的小昊13 小时前
【TJU】研究生应用统计学课程笔记(1)——第一章 数理统计的基本知识(1.1 数理统计的基本内容、1.2 数理统计的基本概念)
笔记·线性代数·考研·数学建模·ai·矩阵·概率论
Agent产品评测局13 小时前
企业超自动化落地,如何实现端到端的全流程闭环?2026企业级智能体架构与全景选型深度解析丨Agent产品测评局
运维·人工智能·ai·chatgpt·架构·自动化