由ChatGPT生成。
本文将探讨如何利用ExtractThinker高效处理大规模文档。我们将讨论何时选用不同的模型,如O1、GPT4o及其迷你版,如何处理OCR,提取图表,以及如何通过异步批量处理应对大量任务。
关于ExtractThinker简介这是一个灵活的文档智能库,帮助你提取并分类各种文档中的结构化数据,就像ORM在数据库处理中的作用一样,在文档处理中为我们提供类似的支持。其中有一句是这样说的:“文档智能用于LLMs”或“LangChain用于智能文档处理”。目的是为了满足文档处理中所需的特定功能,比如拆分大文件和进行高级分类。
以下是将要讨论的所有内容的映射:
提取ExtractThinker组件流程(作者:)
文档加载工具DocumentLoader 是文档与 LLM 之间的桥梁,通常使用最先进的 OCR 技术来实现。支持多种文档加载器,包括 Tesseract OCR、Azure 表单识别、AWS Textract、Google 文档理解 AI 等。
LLM(法学硕士)这是模型的装饰组件。它利用LiteLLM和Instructor等工具构建,旨在促进跨平台使用。围绕文档智能的需求进行设计。
赖约注:此处使用“赖约”一词,更贴近日常用语,适用于更广泛的语境。
也是一个针对 Pydantic 的装饰器。目标是自动包含并处理自定义特性,如验证器和 prompt 调优。
提取器组织文档加载器和大型语言模型之间的互动,以便提取结构化数据。
流程:表示文件间的流。它是基于上面的组件构建的。您可以根据特定用例选择DocumentLoaders,还可以选择提取器。
还有其他较小的组件,如Splitters和Classifications,但我们将在具体的例子中再详细讨论它们。
选择正确的模型选择合适的模型对于平衡性能、准确性和成本非常重要。首先,我们来看看成本:
OpenAI模型的价格(按作者)
GPT-4迷你版应用场景:基本的文字提取任务,例如类似于文字识别。
非常适合从文档中提取文本,将图像或PDF转换成可被机器读取的文本。经济高效且快速,适用于大量数据处理。
GPT-4o (占位符)示例:分类与拆分。
GPT-4o模型能够为你提供对文档内容和结构的更深入的理解。非常适合于文档分类、拆分合并文档为独立部分,以及执行复杂的分类工作。
何时用:
- 将文档归类为发票、合同或收据等常见类型。
- 根据内容将多页文档拆分为独立的部分。
- 高级分类,需要理解上下文和细微差别。
用于以下情况:需要从数据中推理并得出结论的高级提取工作。
o1和o1-mini模型 专为需要进行深度分析和推理的复杂提取场景而设计。比如从图表中获取数据、解析数值,以及利用这些坐标计算如人均GDP这样的汇总指标。
什么时候用:
利用提取的数据来进行计算或得出见解。
上面冗长的描述可以概括为如下图片。
根据复杂程度的每个模型的应用场景(由作者提供)
在 ExtractThinker 中使用 DocumentLoader 进行文档加载在ExtractThinker中,DocumentLoader 这个组件是一个关键部分,它将你的文档与大语言模型连接起来。它运用顶尖的OCR技术或直接提取文本工具来从各种文档格式中提取文本和布局信息。
OCR vs 纯视觉识别在这篇文章中,我们将探讨OCR技术与纯视觉识别技术的区别与联系。
仅使用大语言模型(LLM)就能很好地提取数据,不过,问题主要在于两个方面:幻觉和准确性。如果数据不够清晰或明显,就可能会产生幻觉。OCR可以准确地给你所需的数据,而LLM则提供结构。在一些含有签名的文档中,精度问题尤为突出,例如,在处理签名时,OCR表现得非常理想。
所以在实际应用中,尽量使用带有Vision功能的OCR。这会把OCR文本和图像一并加入到LLM请求中。
可用的 DocumentLoader 类型ExtractThinker 提供了多种文档加载器等多种工具,其中包括:
- DocumentLoaderTesseract : 从图片或扫描的 PDF 中提取文字。
- DocumentLoaderPyPdf : 使用 PyPDF 直接从数字生成的 PDFs 中提取文本。
- DocumentLoaderAWSTextract : 与 AWS Textract 集成以提供高级 OCR 功能。
- DocumentLoaderAzureForm : 使用 Azure Form Recognizer 提取结构化信息。
- DocumentLoaderGoogleDocumentAI : 与 Google Document AI 连接以实现 OCR 和数据提取功能。
它包括两个主要方法,load 方法在 extract() 中被调用,以及 load_content_list 方法在 split() 中被调用。
从Document Loader中获取内容信息
import os
from extract_thinker.document_loader import DocumentLoaderTesseract
# 设置Tesseract的可执行文件路径
tesseract_path = os.getenv('TESSERACT_PATH')
if not tesseract_path:
raise ValueError('如果没有设置 TESSERACT_PATH 环境变量')
# 获取内容,可以是JSON格式或纯文本
content = loader.load(test_file_path)
# 以JSON格式获取每一页的内容和图片
content = loader.load_content_list(test_file_path)
数据提取器:提取结构化数据和图表的工具
Extractor 是 ExtractThinker 中的核心组件,它负责协调 DocumentLoader 和 LLM 之间的互动,从文档中提取结构化数据。它利用 LLM 的能力来解释并根据预定义的结构(即 Contracts)组织提取的文本。
定义合同合同是 Pydantic 模型,用于定义您希望从文档中提取的数据结构。它们就像 Extractor 和 LLM 使用的框架,用于解析和整理提取的信息。
制定发票合同
从extract_thinker导入 Contract
from pydantic 导入 Field
from typing 导入 List
class InvoiceLineItem(Contract):
description: str = Field(description="项目描述")
quantity: int = Field(description="项目数量")
unit_price: float = Field(description="项目单价")
amount: float = Field(description="项目的总金额")
class InvoiceContract(Contract):
invoice_number: str = Field(description="发票号码")
invoice_date: str = Field(description="发票日期(YYYY-MM-DD格式)")
total_amount: float = Field(description="发票总额")
line_items: List[InvoiceLineItem] = Field(description="发票中的明细项列表")
合同中我们希望提取发票的号码、日期、总金额以及包括每项的具体内容。
从发票里提取数据
import os
from extract_thinker import Extractor
from extract_thinker.document_loader import DocumentLoaderPyPdf # 或加载其他合适的 DocumentLoader
# 初始化 Extractor
extractor = Extractor()
# 加载 DocumentLoader
extractor.load_document_loader(DocumentLoaderPyPdf())
# 加载 LLM
extractor.load_llm('gpt-4o-mini') # 根据你的实际情况选择合适的模型
# 定义文档路径
test_file_path = 'path/to/your/invoice.pdf'
# 执行提取操作
result = extractor.extract(test_file_path, InvoiceContract)
# 查看提取的数据
print("发票号码:", result.invoice_number)
print("发票日期:", result.invoice_date)
print("总金额:", result.total_amount)
for item in result.line_items:
print(f"项目: {item.description}, 数量: {item.quantity}, 单价: {item.unit_price}, 项目金额: {item.amount}")
从图表中获取数据
从图表中提取数据需要一个更高级的合同,能够处理图表的类型、描述和数据点信息。
定义图表合同
from extract_thinker import Contract
from pydantic import Field
from typing import List, Literal
class XY坐标(Contract):
x: float = Field(description='x轴的值')
y: float = Field(description='y轴的值')
class Chart(Contract):
classification: Literal['line', 'bar', 'pie'] = Field(description='类型为线、柱状、饼图')
description: str = Field(description='图表说明')
coordinates: List[XY坐标] = Field(description='图表中的数据坐标点')
gdp_variation: str = Field(description='GDP变化描述')
class 带有内容的图表(Contract):
content: str = Field(description='不含图表的页面内容描述')
chart: Chart = Field(description='提取的图表数据')
这项合同不仅允许我们获取文本内容,还能获取图表的细节,包括其数据点详情。
提取图表中的数据
import os
from extract_thinker import Extractor
from extract_thinker.document_loader import DocumentLoaderTesseract # 如果处理的是图片
# 初始化Extractor
extractor = Extractor()
# 加载DocumentLoader
tesseract_path = os.getenv('TESSERACT_PATH')
if not tesseract_path:
raise ValueError('环境变量 TESSERACT_PATH 未被设置')
extractor.load_document_loader(DocumentLoaderTesseract(tesseract_path))
# 加载LLM(如果需要高级推理,可以使用 'o1')
extractor.load_llm("o1-preview") # 使用 'o1' 进行高级推理
# 定义文档路径
test_file_path = 'path/to/your/document_with_chart.png'
# 执行提取操作
result = extractor.extract(test_file_path, ChartWithContent, vision=True)
# 访问提取的数据
print("不含图表的内容:", result.content)
print("图表类型:", result.chart.classification)
print("图表说明:", result.chart.description)
print("GDP变化量:", result.chart.gdp_variation)
print("数据点:")
for coord in result.chart.coordinates:
print(f"X: {coord.x}, Y: {coord.y}")
注意:选择模型时请记住一个简单的原则。如果需要根据数据得出结论,比如计算GDP,这种情况下,您必须使用o1模型,。
流程:拆分及分类在 ExtractThinker 中,Process 组件代表一个工作流,用于管理和安排从文档加载、分割、分类和提取数据的过程。这种模块化的方式能够帮助你高效地处理复杂的文档处理工作。
拆分工作流示例 — 作者
理解过程- 目的:管理文档的各种操作,包括加载、拆分、分类和提取。
- 组件:结合文档加载器、拆分器、分类器、提取器,创建一个灵活的处理流程。
- 灵活性:通过组合不同的组件,根据您的具体需求自定义工作流程。
在处理多页或合并文档时,将它们拆分成单独的段落或页面对于准确处理至关重要。ExtractThinker 提供拆分策略来有效处理。
一次性分割: 此策略一次性处理整个文档,提前找到所有分割点。它最适合用于适合模型的上下文窗口大小的小到中等文档,提供更简单的实现和更快速的小文档处理。
惰性分割: 这种方法是增量处理文档,通过逐步解析更小的部分来确定分割点。它特别适合那些超过模型上下文窗口的大文档,成为处理大量数据的有效且可扩展的选择。
如何使用分割器ExtractThinker 提供了不同的拆分器,例如 ImageSplitter
和 TextSplitter
,来处理拆分相关的逻辑。
安装信号分配器
from extract_thinker import Process, SplittingStrategy
from extract_thinker.splitter import ImageSplitter
from extract_thinker.document_loader import DocumentLoaderTesseract
# 初始化流程
process = Process()
# 加载文档加载器
tesseract_path = os.getenv('TESSERACT_PATH')
process.load_document_loader(DocumentLoaderTesseract(tesseract_path))
# 加载拆分器
process.load_splitter(
ImageSplitter('gpt-4o', strategy=SplittingStrategy.EAGER)
)
分类
分类是识别你正在处理的文档或部分内容的类型,例如,发票、合同或驾照。这一点至关重要,因为不同类型的文档可能需要不同的提取逻辑。
分类系统使用 Classification
类定义,指定名称、描述和关联的 Contract
以及使用的 Extractor
。
用多个 Extractor 来分类
from extract_thinker import Classification
from extract_thinker import Extractor
# 定义你的合同(如前所定义)
class InvoiceContract(Contract):
invoice_number: str
total_amount: float
# ... 其他字段
class DriverLicenseContract(Contract):
name: str
license_number: str
# ... 其他字段
# 如需初始化每个分类的 Extractor
invoice_extractor = Extractor()
invoice_extractor.load_document_loader(DocumentLoaderPyPdf())
invoice_extractor.load_llm('gpt-4o-mini')
license_extractor = Extractor()
license_extractor.load_document_loader(DocumentLoaderTesseract(tesseract_path))
license_extractor.load_llm('gpt-4o-mini')
# 初始化完成后,可以定义分类如下
classifications = [
Classification(
name="Invoice",
description="这是一张发票",
contract=InvoiceContract,
extractor=invoice_extractor
),
Classification(
name="驾驶证",
description="这是一张驾驶证",
contract=DriverLicenseContract,
extractor=license_extractor
)
]
result = process.classify(
test_file_path,
classifications,
) # 进行分类处理
高级分类方法
ExtractThinker 支持高级的分类策略,以提高准确率和可靠性。
分类方法:
- 共识:结合多个分类器的结果来达成共识决定。
- 高阶推理:利用高阶推理来实现更准确的分类。
- 阈值处理:应用置信度阈值以确定分类的确定程度。
高级分类
from extract_thinker import ClassificationStrategy
# 初始化多个Extractor进行分类
extractor1 = Extractor()
extractor1.load_document_loader(DocumentLoaderTesseract(tesseract_path))
extractor1.load_llm('gpt-4o')
extractor2 = Extractor()
extractor2.load_document_loader(DocumentLoaderPyPdf())
extractor2.load_llm('gpt-4o-mini')
# 添加分类器到处理流程
process.add_classify_extractor([[extractor1], [extractor2]])
# 使用此策略分类
result = process.classify(
test_file_path,
classifications,
strategy=ClassificationStrategy.CONSENSUS,
threshold=0.8
)
print("文档分类为:", result.name)
在处理过程中,我们结合了分割和分类的方法
通过拆分和分类结合,您可以高效处理包含多种内容的复杂文档。
完整的过程工作流
# 初始化流程并加载组件和加载项
process = Process()
process.load_document_loader(DocumentLoaderTesseract(tesseract_path))
process.load_splitter(
ImageSplitter('gpt-4o', strategy=SplittingStrategy.EAGER)
)
# 处理文档
test_file_path = 'path/to/your/multi_page_document.pdf'
split_content = process.load_file(test_file_path)\
.split(classifications)\
.extract()
# 查看提取的数据
for content in split_content:
if isinstance(content, InvoiceContract):
print("提取的发票:")
print("发票号:", content.invoice_number)
print("总金额:", content.total_amount)
elif isinstance(content, DriverLicenseContract):
print("提取的驾驶证:")
print("姓名:", content.name)
print("驾照号码:", content.license_number)
- load_file() :加载文档。
- split() :分割文档。
- extract() :根据每个分类部分的
Contract
定义来提取数据。
ExtractThinker 提供了一项批处理功能,利用异步执行有效处理繁重任务。这使您可以在不关心响应时间的情况下,以更便宜的价格处理文档。
批处理请求的使用
...
# 像往常一样设置提取器
path = 'path/to/your/document.pdf'
batch_job = extractor.extract_batch(
path,
InvoiceContract,
)
# 状态可以是 "queued"、"processing"、"completed" 或 "failed"
status = await batch_job.get_status()
# 等结果
result = await batch_job.get_result()
解释:
- extract_batch : 启动批次提取流程。
- BatchJob : 表示批次任务,允许你监控其状态并获取结果。
- get_status : 查询批次任务的当前状态。
- get_result : 任务完成后获取结果。
批处理任务可以有几种状态:
- 等待中:任务正在等待处理。
- 处理中:任务正在处理中。
- 已完成:任务已完成处理。
- 失败:任务失败。
这批处理是一次一个文件进行的,因此你需要自己控制批次的数量。批处理作业负责创建所有用于OpenAI API的JSONL文件,输出文件也是这样处理的。在处理完成后,无论成功与否,都会删除这些文件。
总之,如果没有时间请求的限制,你可以轻松通过这个ExtractThinker功能节省一半的成本。
结论部分在一个数据为王的世界里,ExtractThinker 让你能够充分发挥文档的潜力。通过智能选择,例如选择 GPT-4o Mini 进行快速文本提取、GPT-4o 进行高级分类以及 O1 进行深度推理任务的模型,你可以定制工作流以达到最大效率和准确性。我们探讨了选择合适的模型,使用 DocumentLoaders 加载文件,利用 Extractor 提取结构化数据,使用 Processes 管理复杂流程,以及通过异步 batch 处理大量任务。
这是我一获得O1模型API访问权限就写的文章,解决了几个具体的挑战,比如需要由单独代理处理的数据聚合和计算。
提取思考工具即将推出,这里展示文档的样貌。
如果你发现这篇文章有帮助,请考虑在GitHub上给ExtractThinker仓库点个星! 🌟
共同学习,写下你的评论
评论加载中...
作者其他优质文章