Skip to content

LLM文档对话 —— PDF解析关键问题

来自:AI GC面试宝典 作者:宁静致远 日期:2023年09月29日


一、为什么需要进行PDF解析?

最近在探索ChatPDF和ChatDoc等方案的思路,也就是用LLM实现文档助手。在此记录一些难题和解决方案,首先讲解主要思想,其次以问题+回答的形式展开。

📝 通俗解释:ChatPDF/ChatDoc就像一个"文档版Siri",你可以问PDF文档问题,它来回答。要实现这个功能,第一步就是要把PDF里的内容"读懂"、"拆开",这就是PDF解析要做的事情。


二、为什么需要对PDF进行解析?

当利用LLMs实现用户与文档对话时,首要工作就是对文档中内容进行解析。

由于PDF是最通用、也是最复杂的文档形式,所以对PDF进行解析变成利用LLM实现用户与文档对话的重中之重工作。

如何精确地回答用户关于文档的问题,不重也不漏?笔者认为非常重要的一点是文档内容解析。如果内容都不能很好地组织起来,LLM只能"瞎编"(即产生幻觉,生成错误信息)。

📝 通俗解释:想象一下,你要把一本纸质书的内容完整输入到电脑里让AI理解。PDF就像一张"打印好的纸",它的排版是为了人眼阅读,而不是为了电脑"理解"。所以我们需要把PDF"翻译"成电脑能看懂的格式,这就是解析的意义。


三、PDF解析有哪些方法?对应的区别是什么?

PDF的解析大体上有两条路:基于规则基于AI

方法一:基于规则

  • 介绍:根据文档的组织特点去"算"每部分的样式和内容
  • 存在问题:不通用,因为PDF的类型、排版实在太多了,没办法穷举
  • 适用场景:简单版面的文档

📝 通俗解释:就像通过"字体大小"来判断哪些是标题、哪些是正文。这种方法简单直接,但遇到花哨的排版就失效了——就像用一把钥匙开所有锁,不太可能。

方法二:基于AI(推荐)

  • 介绍:该方法为目标检测和OCR文字识别pipeline方法

PDF解析流程图:

┌─────────────────────────────────────────────────────────────┐
│                        PDF解析流程                           │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│   ┌──────────┐    ┌────────────┐    ┌──────────────────┐   │
│   │  输入    │───▶│   转图片   │───▶│   目标检测模型   │   │
│   │  PDF文件 │    │  (PDF→图片)│    │   (区块划分/     │   │
│   └──────────┘    └────────────┘    │    类型识别)     │   │
│                                     └────────┬─────────┘   │
│                                              │             │
│                                              ▼             │
│   ┌──────────────┐    ┌────────────────────────────┐      │
│   │  多级标题识别 │◀───│      OCR文字识别           │      │
│   │  + 区块排序   │    │    (提取文本内容)          │      │
│   └──────────────┘    └────────────────────────────┘      │
│                                                             │
└─────────────────────────────────────────────────────────────┘

📝 通俗解释:想象一下让人来"看"这份PDF:首先把PDF变成图片,然后用AI模型像画框一样圈出标题、正文、表格等不同区域,最后用OCR技术"读出"框里的文字。这个方法就像给AI装上了"眼睛"和"手",看得准、读得懂。


四、PDF解析存在哪些问题?

PDF转Text这块存在一定的偏差,尤其是paper中包含了大量的figure(图片)和table(表格),以及一些特殊的字符,直接调用LangChain官方给的PDF解析工具,有一些信息甚至是错误的。

解决方案

  1. 可以用arXiv的LaTeX源码直接抽取内容
  2. 可以尝试用各种OCR工具来提升表现

📝 通俗解释:就像把中文翻译成英文可能会有歧义一样,PDF转文字也容易"翻译"错。特别是数学公式、特殊符号,机器经常认错。解决方法一是找"原文"(LaTeX源码),二是用更聪明的OCR工具。


五、如何从长文档(书籍)中提取关键信息?

对于长文档(书籍),如何获取其中关键信息并构建索引:

方法一:分块索引法

  • 介绍:直接对长文档(书籍)进行分块,然后构建索引入库。后期问答,只需要从库中召回和用户query相关的内容块进行拼接成文章,输入到LLMs生成回复
  • 存在问题
    1. 将文章分块,会破坏文章语义信息
    2. 对于长文章,会被分割成很多块,并构建很多索引,这严重影响知识库存储空间
    3. 如果内容都不能很好地组织起来,LLM只能瞎编

📝 通俗解释:就像把一本书撕成很多页,每页单独存放。问问题的时候,找到相关的几页拼在一起给AI看。但问题是:撕开的地方可能正好在句子中间,AI会"断章取义"。

方法二:文本摘要法

  • 介绍:直接利用文本摘要模型对每一篇长文档(书籍)做文本摘要,然后对文本摘要内容构建索引入库。后期问答,只需要从库中召回和用户query相关的摘要内容,输入到LLMs生成回复
  • 存在问题
    1. 由于每篇长文档(书籍)内容比较多,直接利用文本摘要模型对其做文本摘要,需要比较大算力成本和时间成本
    2. 生成的文本摘要存在部分内容丢失问题,不能很好地概括整篇文章

📝 通俗解释:就像先让人读完整本书,写一篇简短摘要,再基于摘要回答问题。问题是:摘要会漏掉很多细节,就像你不能通过"电影简介"了解所有剧情一样。

方法三:多级标题构建文本摘要法

  • 介绍:把多级标题提取出来,然后适当做语义扩充,或者去向量库检索相关片段,最后用LLM整合即可

📝 通俗解释:就像看书先看目录,基于目录来理解结构。这种方法先提取标题作为"骨架",再填充相关内容。既保留了结构信息,又不会漏掉重点,是比较折中的方案。


六、为什么要提取标题甚至是多级标题?

没有处理过LLM文档对话的朋友可能不明白为什么要提取标题甚至是多级标题,因此我先来阐述提取标题对于LLM阅读理解的重要性有多大。

  1. 如Q1阐述的那样,标题是快速做摘要最核心的文本
  2. 对于有些high-level(高级别)的问题,没有标题很难得到用户满意的结果

举例说明

假如用户就想知道3.2节是从哪些方面讨论的(标准答案就是3个方面),如果我们没有将标题信息告诉LLM,而是把所有信息全部扔给LLM,那它大概率不会知道是3个方面(要么会少,要么会多)。做过的朋友秒懂

📝 通俗解释:就像问"这篇文章讲了什么",如果AI只知道"正文内容"而不知道"章节标题",它可能给你一个模糊的回答。但如果你告诉它"第二章讲的是 transformer 原理,2.1节是注意力机制,2.2是位置编码",AI就能准确回答了。


七、如何提取文章标题?

第一步:PDF转图片

用一些工具将PDF转换为图片,这里有很多开源工具可以选,笔者采用fitz,一个Python库。速度很快,时间在毫秒之间。

📝 通俗解释:把PDF文件变成一张张图片,这样后续的AI模型才能"看"到文档的排版和布局。

第二步:图片中元素识别

采用目标检测模型识别元素(标题、文本、表格、图片、列表等)。

工具对比:

工具优点缺点
Layout-parser最大的模型(约800MB)精度非常高速度稍慢
PaddlePaddle-ppstructure模型比较小,效果也还行精度略低于Layout-parser
unstructured支持精细化切分fast模式效果很差,基本不能用,会将很多公式也识别为标题

📝 通俗解释:这些工具就像给AI装上了"火眼金睛",能一眼看出哪里是标题、哪里是正文、哪里是表格。Layout-parser看得最准但"眼神"慢,PaddlePaddle快但没那么准,unstructured切得细但容易认错人。

第三步:标题级别判断

利用标题区块的高度(也就是字号)来判断哪些是一级标题,哪些是二级、三级、N级标题。

问题解决:如果目标检测模型提取的区块不是严格按照文字边去切,可以:

  • 使用unstructured的fast模式(按文字边切)
  • 同一级标题的区块高度误差在0.001之间
  • 用unstructured拿到标题的高度值即可

📝 通俗解释:一级标题通常字号最大,二级次之,以此类推。AI通过"量身高"来判断这是"爸爸"(一级标题)还是"儿子"(二级标题)。

提取效果展示

按照标题级别输出的效果:

1 Introduction
2 Language and semantics
   2.1 Semantics
   2.2 Language
3 Example

📝 通俗解释:提取后的结果就像得到了文章的"目录骨架",AI看到这个结构,就知道文章是怎么组织的了。


八、如何区分单栏还是双栏PDF?如何重新排序?

背景说明

很多目标检测模型识别区块之后并不是顺序返回的,因此我们需要根据坐标重新组织顺序。单栏的很好办,直接按照中心点纵坐标排序即可。双栏PDF就很棘手

📝 通俗解释:就像看报纸,双栏排版时,先读左栏从上往下,再读右栏从上往下。但AI识别的时候可能是"乱序"的,需要我们帮忙整理回正确的阅读顺序。

问题一:如何区分单双栏论文?

  • 方法:得到所有区块的中心点的横坐标,用这一组横坐标的极差来判断即可
  • 原理:双栏论文的极差远远大于单栏论文,因此可以设定一个极差阈值

问题二:双栏论文如何确定区块的先后顺序?

  • 方法
    1. 先找到中线,将左右栏的区块分开
    2. 中线横坐标 = $(x1 + x2) / 2$(借助求极差的两个横坐标x1和x2)
    3. 分为左右栏区块后,对于每一栏区块按照纵坐标排序
    4. 最后将右栏拼接到左栏后边

📝 通俗解释:就像把混在一起的左右两栏内容,先用"中线"分开,各自按从上到下排好,最后再把右栏接到左栏后面,恢复正常阅读顺序。


九、如何提取表格和图片中的数据?

思路仍然是目标检测OCR。无论是Layout-parser还是PaddleOCR都有识别表格和图片的目标检测模型,而表格的数据可以直接OCR导出为Excel形式数据,非常方便。

Layout-parser效果示例

Layout parser效果示例 展示了一份包含复杂表格和文本的文档的布局分析结果

PaddlePaddle PP-Structure效果示例

主要财务比率202020212022E2023E2024E
成长能力
营业收入97.08%33.28%65.00%42.10%21.00%
营业利润165.21%22.38%31.65%64.55%36.68%
归属于母公司净利润164.75%24.17%39.44%64.13%38.63%
获利能力
毛利率25.45%23.01%16.80%17.00%18.00%
净利率13.98%13.03%11.01%12.72%14.57%
ROE19.29%19.25%20.77%47.11%35.24%
ROIC44.53%41.55%44.21%32.59%62.14%
偿债能力
资产负债率48.28%54.90%57.79%65.62%58.84%
净负债率-39.12%-36.03%6.62%8.70%5.28%

提取出表格之后喂给LLM,LLM还是可以看懂的,可以设计prompt做一些指导。

📝 通俗解释:表格和图片里的数据也藏着重要信息!AI需要先"看到"哪里有表格,然后"读出"表格里的内容,最后才能回答关于表格数据的问题。


十、基于AI的文档解析有什么优缺点?

优点

  • 准确率高:能处理各种复杂的PDF排版
  • 通用性强:不依赖特定模板

缺点

  • 耗时慢:主要耗时在目标检测和OCR两个阶段
  • 建议:用GPU等加速设备,多进程、多线程去处理

📝 通俗解释:AI方法就像请了一个"专业大学生"来读文档——看得准、啥都懂,但就是比较慢、需要好电脑。其他步骤(排序、整合等)都很快,不耽误时间。


总结

  1. 建议按照不同类型的PDF做特定处理,例如论文、图书、财务报表、PPT都可以根据特点做一些小的专有设计
  2. 没有GPU的话,目标检测模型建议用PaddlePaddle提供的,速度很快
  3. Layout-parser只是一个框架,目标检测模型和OCR工具可以自由切换

📝 通俗解释:没有"万能药",论文有论文的读法,财务报表有财务报表的读法。根据不同文档特点"因材施教",效果才最好。

基于 MIT 许可发布