容器中的大模型(三)|利用大型语言模型:容器化部署高效的 PDF 解析器实践

by June 2024-03-18

作者: 宋文欣,智领云科技联合创始人兼 CTO

武汉大学计算机系本科及硕士,美国纽约州立大学石溪分校计算机专业博士。曾先后就职于Ask.com 和 EA (电子艺界)。在 Ask.com 期间,担任大数据部门技术负责人及工程经理,使用Hadoop 集群处理实时搜索数据,形成全球规模领先的 Search Ads Arbitrage 用户;在EA期间,担任数字平台部门高级研发经理,从无到有组建EA数据平台团队,建设公司大数据平台,为EA全球工作室提供数据能力支持。2016 年回国联合创立智领云科技有限公司,组建智领云技术团队,开发了 BDOS 大数据平台操作系统。

1.简介

在构建大型语言模型(LLMs)应用时,我们经常面临信息不准确性和信息过时等挑战。为了解决这些问题,检索增强生成(RAG)技术日益成为研究和应用的热点。RAG 技术将各种文档类型转换成 LLMs 易于解读的格式,通过结合检索机制和生成机制,极大地提升了 LLMs 处理复杂查询的能力,而 PDF 文档作为信息传递的重要载体,其内容的抽取和理解对于实现高质量的RAG 输出至关重要。

本文讨论了在大语言模型(LLMs)中应用检索增强生成(RAG)技术,并展示如何在 Docker 容器中运行三个不同的 PDF 解析器:LLMSherpa、Unstructured 和 LlamaParse ,通过比较这些解析器的独特优势,包括它们在解析精度、速度、以及容易性方面的特点,帮助读者选择最适合自己需求的 PDF 解析器。

本文也将演示如何在容器化环境中快速部署和使用,完成从环境搭建到 PDF 解析器选择的全过程:

此外,本文还将介绍运行演示所需的准备工作,代码结构等,并对关键的技术要点和实践经验进行总结,为项目中实施 RAG 技术的技术人员和研究者提供参考,以便选择最适合需求的 PDF 解析器,并帮助读者更好地理解 RAG 技术背后的原理,以及如何高效地利用这些技术来提升数据处理和分析能力。

2. 技术背景

LLMSherpa

LLMSherpa 提供一个免费开放的 API 服务器,用于解析各种 PDF 文件。LLMSherpa 的 LayoutPDFReader 是一个基于规则的解析器,使用来自修改版 Tika 的文本坐标(边界框)、图形和字体数据,为需要解析 PDF 文件的用户提供了一个非常实用的解决方案。通过其免费开放的 API 服务器,用户可以轻松处理各种 PDF 文档,无论是公开资源还是需要在私有服务器上托管的数据。

本文演示中,我们特别展示了如何在 Docker 容器中运行一个自托管的 LLMSherpa API 服务器,为用户提供了更多的灵活性和控制权。

Unstructured

Unstructured 是 unstructured.io 提供的开源库,用于摄取和预处理包括 PDF、HTML、Word 文档等格式在内的图像和文本文档。这个库不仅支持多种文档格式,而且还提供了一个免费的API服务,用户可以免费处理高达 1000 页的文档。

本文演示中,我们将重点关注如何利用 Unstructured 的开源库进行文档处理,而不依赖其 API 服务。用户可以在自己的服务器上部署和使用这个强大的库,享受数据处理的灵活性和自主性。

LlamaParse

LlamaParse 是由 LlamaIndex 推出的 API,旨在高效解析和呈现文件内容,进而配合LlamaIndex 框架实现快速检索和上下文增强。截至 2024年2月26日,这项服务目前处于免费预览阶段,且只专注于支持 PDF 格式文件的处理。

3.演示

宋博士的原文是在 AWS EC2 CPU/GPU 进行配置以运行,本篇博客会以国内用户更加熟悉的本机环境和国内(阿里云)为主要演示环境进行呈现。 

我们也会在文稿的后半部分保留宋博士原文中关于在 AWS EC2 CPU 或 GPU 上进行配置的演示内容。这样感兴趣的读者可以根据自己的需求选择合适的部署环境,并参考相应的操作步骤。

前置条件

  1. 操作系统:应与大多数 Linux 发行版兼容,并已在 Ubuntu 22.04 上进行了测试。
  2. Docker:系统上必须安装有 docker。具体来说,我们已经在 Ubuntu 22.04 上使用 Docker Engine 社区版 25.0.1 测试了这个演示。
  3. OpenAI API 密钥(可选):如果希望在此演示中使用 ChatGPT 功能,需要 OpenAI API 密钥。请注意,此 API 的使用受 OpenAI 的定价和使用政策的约束。我们使用 OpenAI 文本生成模型来优化解析某些特殊组件(如标题或表格等)。没有这个 API 密钥,仍然可以尝试所有三种方法。
  4. LlamaParse API 密钥:如果希望尝试新推出的 LlamaParse API 服务,需要从 其网页门户获取 API 密钥。没有这个 API 密钥,将无法尝试 LlamaParse。

本机电脑(Mac,非GPU配置,已安装 Docker)

以下是在 本机电脑(Mac,非GPU配置,已安装 Docker) 上启动演示的操作指南:

1)选择合适路径,右键 Open in Terminal,输入如下命令克隆仓库:

git clone https://github.com/LinkTime-Corp/llm-in-containers.git
cd llm-in-containers/pdf2md

2)若需要使用 OpenAI 的模型进行推理,将您的OpenAI API密钥设置到conf/config.json的“OPENAI_API_KEY”中,包括:替换API 密钥 ‘{your-openai-api-key}’ 和 ‘{your-llamaparse-api-key}’ ,使用以下的命令:

export OPENAI_API_KEY={your-openai-api-key}
export LLAMAPARSE_API_KEY={your-llamaparse-api-key}

如果用户的OpenAI 未进行订阅,这里则需要修改model为:”OPENAI_API_MODEL”: “gpt-3.5-turbo”,

3)打开 Docker Desktop

4)启动演示

bash run.sh

5)访问 http://localhost:8501/ 上的用户界面

在用户界面上,您可以选择“LLMSherpa”,“Unstructured”或“LlamaParse”来解析上传的PDF文件。

6)关闭演示

bash shutdown.sh

国内阿里云服务器

以下是在国内阿里云服务器(非GPU配置,已安装Docker) 上启动演示的逐步指南:

1)ssh 登录服务器

2)选择合适路径,输入如下命令克隆仓库:

git clone https://github.com/LinkTime-Corp/llm-in-containers.git
cd llm-in-containers/pdf2md

3)若需要使用 OpenAI 的模型进行推理,将您的OpenAI API 密钥设置到conf/config.json的“OPENAI_API_KEY”中,包括:替换API 密钥 ‘{your-openai-api-key}’ 和 ‘{your-llamaparse-api-key}’ ,使用以下的命令:

export OPENAI_API_KEY={your-openai-api-key}
export LLAMAPARSE_API_KEY={your-llamaparse-api-key}

如果用户的 OpenAI 未进行订阅,这里则需要修改model为:”OPENAI_API_MODEL”: “gpt-3.5-turbo”,

4)启动演示

sudo bash run.sh

5)访问 http://{阿里云CPU实例的IP地址}:8501上的用户界面。在用户界面上,您可以选择“LLMSherpa”,“Unstructured”或“LlamaParse”来解析上传的PDF文件。

6)关闭演示

sudo bash shutdown.sh

备注:在 AWS EC2 CPU 或 GPU 实例上运行

关于如何配置 AWS EC2 CPU 或 GPU 实例以在 Docker 容器中运行本地 LLM,可以参考这篇博客。以下是在 AWS 实例上启动演示的操作指南:

1)首先,将此仓库克隆到已安装Docker的主机机器上:

git clone https://github.com/LinkTime-Corp/llm-in-containers.git
cd llm-in-containers/pdf2md

2)用你的 API 密钥替换 ‘{your-openai-api-key}’ 和 ‘{your-llamaparse-api-key}’ 以下的命令。然后启动演示。

export OPENAI_API_KEY={your-openai-api-key}
export LLAMAPARSE_API_KEY={your-llamaparse-api-key}
bash run.sh

如果用户的 OpenAI 未进行订阅,这里则需要修改model为:”OPENAI_API_MODEL”: “gpt-3.5-turbo”,

3)访问 http://{主机的IP}:8501 的用户界面

在用户界面上,您可以选择“LLMSherpa”,“Unstructured”或“LlamaParse”来解析上传的PDF文件。

4)关闭演示。

bash shutdown.sh
  1. 代码结构

演示的代码结构设计得简单直观,不同的组件被组织到单独的文件中以便于清晰和易于维护:

1. main.py:此文件包含用户界面(UI)的代码。

2. llmsherpa_pdf2md.py:来自 LLMSherpa 的 LayoutPDFReader 的代码。

3. unstructured_pdf2md.py:它使用 Unstructured 的 partition_pdf 函数来解析PDF。

4. llamaparse_pdf2md.py:LlamaParse API 服务的 Python 客户端。

5. openai_utils.py:我们编写的代码,用于优化 OpenAI 文本生成 API 对标题和表格的解析。

5.要点笔记

PDF解析器选择

在选择PDF解析器时,不仅要考虑敏感信息的处理、成本因素,还需要评估各种工具的准确性和兼容性等。通过在实际文件上进行测试和评估,结合对不同场景的理解,选择或组合最适合您需求的解析器。

  • 敏感信息处理:如果 PDF 文件包含敏感信息,并且对数据的安全性和隐私性有较高要求,在私有服务器上使用开源解决方案可能是最佳选择。LLMSherpa 和 Unstructured 都可在私人服务器上部署的开源 PDF 解析器,可以为处理敏感文档提供更高的安全保障。
  • 成本考虑:如果对成本较为敏感,且 PDF 文件不包含敏感信息,那么可以考虑使用LlamaParse 或 ChatDoc。LlamaParse 目前提供免费的预览模式,而ChatDoc 虽然需要申请获得使用权限,但可能在未来推出收费的高级服务。
  • 准确性和兼容性:目前没有任何工具或服务能够保证 100% 准确无误地解析所有 PDF 文件。PDF 格式的复杂性意味着解析器在处理不同结构或布局的文档时可能遇到挑战。因此,可以在特定的文件上测试不同的解析器,以确定哪个工具在准确性和功能性方面最能满足需求。
  • 混合使用方案:可以在处理非敏感信息时使用LlamaParse 或 ChatDoc,而对于需要更高安全性的敏感文档,则转而使用 LLMSherpa 或Unstructured。

LLMSherpa:解析PDF文件以及层次布局信息

LLMSherpa 的 LayoutPDFReader 提供了一种高效的方法来解析 PDF 文件及其层次布局信息,利用其“智能分块”技术,能够识别文档中的不同部分和小节以及它们的嵌套结构,将文本行合并成连贯的段落并建立部分之间的联系。

尽管在大多数情况下 LayoutPDFReader 的性能表现出色,但也存在一些限制,如某些部分可能不会被正确地分类。对于需要 PDF 文件中信息的上下文感知分块,同时能够接受偶尔出现的分类不准确情况的 LLM 应用,LLMSherpa 的 LayoutPDFReader 成为了一个值得尝试的选项。

Unstructured:使用正确的模型来检测PDF文档中的元素

在处理PDF文档时,正确选择用于检测文档中元素的模型,将直接影响到文档解析的效率和准确性。Unstructured Python 库提供了几种不同的模型选项,以适应不同的需求和应用场景:

  • detectron2_onnx:是基于Facebook AI的计算机视觉模型,使用ONNX Runtime,提供了快速的对象检测和分割能力。如果主要关注点是速度,并且需要高效的对象检测功能,detectron2_onnx 可以是最佳选择。
  • yolox:是基于YOLOv3并且进行了优化的单阶段实时对象检测器,使用了DarkNet53作为主干网络。适用于需要实时对象检测同时关注模型准确度的场景。
  • yolox_quantized:它的运行速度比 YoloX 快,其速度更接近Detectron2。如果寻找一个既快速又相对准确的解决方案,yolox_quantized 是一个不错的选择。
  • chipper (beta version):chipper 是 Unstructured 内置的图像到文本模型,基于Transformer 架构的视觉文档理解(VDU)模型。适用于需要从图像中提取文本并进行深度理解的复杂应用场景。由于它还处于beta版本,可能需要进一步的测试和调整以满足特定的需求。

您还可以参考此文档,将定制模型引入到这个库。

6.Github链接

Github链接

https://github.com/LinkTime-Corp/llm-in-containers/tree/main/pdf2md

博客原文链接

https://blog.gopenai.com/running-pdf-parsers-in-docker-containers-5e7a7ed829c8

留言

评论

${{item['author_name']}} 回复 ${{idToContentMap[item.parent] !== undefined ? idToContentMap[item.parent]['author_name'] : ''}} · ${{item.date.slice(0, 10)}} 回复

暂时还没有一条评论.