宣布 LlamaCloud 全面可用(以及我们 1900 万美元的 A 轮融资)!
LlamaIndex

Kiran Neelakanda Panicker 2023-10-18

精通 PDF:使用尖端解析器提取章节、标题、段落和表格

尽管最近有将自然语言处理应用于更广泛的现实世界应用的动机,但大多数自然语言处理论文、任务和管道都假定处理原始、干净的文本。然而,我们在现实中遇到的许多文本,包括绝大多数法律文件(例如,合同和法典),并非如此干净,其中许多是视觉结构化文档(VSD),如 PDF。PDF 功能多样,能保持文档的视觉完整性,但在提取和处理其内容时往往构成重大挑战。

在本次讨论中,我们的重点将主要放在仅含文本分层的 PDF 上,这类 PDF 常被许多人视为一个已解决的问题。

PDF 解析的复杂性

  1. 版式复杂性:PDF 可能包含复杂的版式,例如多列文本、表格、图像和复杂的格式。这种版式多样性使提取结构化数据变得复杂。
  2. 字体编码问题:PDF 使用多种字体编码系统,其中一些系统无法直接映射到 Unicode。这使得准确提取文本变得困难。
  3. 非线性文本存储:PDF 不按照文本在页面上的显示顺序存储文本。相反,它们将文本存储在可以在页面上任意位置放置的对象中。这意味着底层代码中的文本顺序可能与视觉上显示的文本顺序不一致。
  4. 空格使用不一致:在某些 PDF 中,空格使用不一致,或者单词之间根本没有空格。这使得甚至难以识别单词边界。

我们需要一个高效的解析器吗?

在大型语言模型时代,当大型语言模型可以处理整个 PDF 时,高效的解析器是否仍然至关重要?

如果下一个问题的答案是“是”,则这个问题就变得有意义了。

我们需要检索增强生成(RAG)吗?

虽然大型语言模型功能强大,但在一次处理的文本量和可引用的信息范围方面存在一定的局限性。进一步的最新研究表明,当相关信息出现在输入上下文的开头或结尾时,大型语言模型的性能通常最高;当模型必须访问长上下文中间的相关信息时,性能会显著下降。像 RAG 这样的技术有助于克服这些限制,从而能够更有效、更高效地处理大型文档和进行更广泛的信息检索。

仍然怀疑?让我们请一个大型语言模型来确认。

Chat GPT output mentioning the necessity of an efficient parser

现在我们已经确定了高效解析器的重要性,它对于构建有效的检索增强生成(RAG)管道以解决大型语言模型的局限性至关重要。让我们来探讨今天我们是如何实现这一点的。记住,输入到大型语言模型的上下文质量是有效 RAG 的基石,正如俗话所说,“垃圾输入 — 垃圾输出”。

在构建大型语言模型相关应用的背景下,分块(chunking)是将大块文本分解成更小段落的过程。这是一项基本技术,它有助于优化我们使用大型语言模型嵌入内容后从数据库中检索到的内容的相关性。涉及的一些策略包括

  1. 固定大小分块。这是最常见、最直接的分块方法:我们只需确定每个块中的 token 数量,并可选地决定它们之间是否应该有重叠。这种方法易于实现且最常用,但从未用于生产环境,因为其输出在概念验证 (POC) 设置中尚可,但随着进一步测试,其准确性会下降。
  2. “内容感知”分块。这是一系列利用待分块内容性质并应用更复杂分块方法的技术。由于上述原因,实现起来具有挑战性,但如果处理得当,它可能是生产级信息检索 (IR) 引擎最理想的构建块。

那么,这篇文章到底要讲什么呢?

当然,让我们结束历史和背景介绍,好吗?

介绍用于“内容感知”分块的 LayoutPDFReaderLayoutPDFReader 可以解析 PDF 并提供分层布局信息,从而成为您 RAG 工具库中最重要的工具,例如:

  1. 识别章节和子章节,以及它们各自的层级。
  2. 将行合并成连贯的段落。
  3. 建立章节和段落之间的连接。
  4. 识别表格并将其与其对应章节关联。
  5. 精确处理列表和嵌套列表结构。

使用 LayoutPDFReader 的第一步是向其提供一个 URL 或文件路径(假设已安装),然后获取一个文档对象。

from llmsherpa.readers import LayoutPDFReader

llmsherpa_api_url = "https://readers.llmsherpa.com/api/document/developer/parseDocument?renderFormat=all"
pdf_url = "https://arxiv.org/pdf/1910.13461.pdf" # also allowed is a file path e.g. /home/downloads/xyz.pdf
pdf_reader = LayoutPDFReader(llmsherpa_api_url)
doc = pdf_reader.read_pdf(pdf_url)

使用智能分块进行向量搜索和 RAG

LayoutPDFReader 采用智能分块来保持相关文本的连贯性

  • 它将所有列表项与前面的段落组合在一起。
  • 表格内的项目被分块组合在一起。
  • 它纳入了来自章节标题和嵌套章节标题的上下文信息。

作为一个快速示例,以下代码片段使用 LayoutPDFReader 生成的文档块创建了一个 LlamaIndex 查询引擎。

from llama_index.readers.schema.base import Document
from llama_index import VectorStoreIndex

index = VectorStoreIndex([])
for chunk in doc.chunks():
index.insert(Document(text=chunk.to_context_text(), extra_info={}))
query_engine = index.as_query_engine()

# Let's run one query
response = query_engine.query("list all the tasks that work with bart")
print(response)

我们得到以下回复:

BART works well for text generation, comprehension tasks, abstractive dialogue, question answering, and summarization tasks.

关键注意事项

  1. LLMSherpa 利用一个免费开放的 API 服务器。在解析过程中,您的 PDF 除了临时存储外不会被保留。
  2. LayoutPDFReader 已对各种 PDF 进行了广泛测试。然而,要实现对每个 PDF 的完美解析仍然是一项艰巨的任务。
  3. 请注意,目前尚不提供 OCR(光学字符识别)功能。该工具仅支持带有文本层的 PDF。
  4. 有关私有托管选项、OCR 支持或针对特定 PDF 相关问题的定制帮助,请随时通过 contact@nlmatics.com 或直接通过 联系我们。

如果您有任何问题,请在评论区留言,我会尽快回复。

联系方式?

如果您想联系我,请随时通过 LinkedIn 或通过 电子邮件 发送消息。

参考资料

https://github.com/nlmatics/llmsherpa

使用多模态转换解析器捕获视觉结构化文档的逻辑结构

迷失在中间:语言模型如何使用长上下文