为了账号安全,请及时绑定邮箱和手机立即绑定

用ExtractThinker高效处理文档:GPT-4o与Mini模型的应用解析

ChatGPT生成。

本文将探讨如何利用ExtractThinker高效处理大规模文档。我们将讨论何时选用不同的模型,如O1、GPT4o及其迷你版,如何处理OCR,提取图表,以及如何通过异步批量处理应对大量任务。

关于ExtractThinker简介

这是一个灵活的文档智能库,帮助你提取并分类各种文档中的结构化数据,就像ORM在数据库处理中的作用一样,在文档处理中为我们提供类似的支持。其中有一句是这样说的:“文档智能用于LLMs”或“LangChain用于智能文档处理”。目的是为了满足文档处理中所需的特定功能,比如拆分大文件和进行高级分类。

以下是将要讨论的所有内容的映射:

提取ExtractThinker组件流程(作者:)

文档加载工具

DocumentLoader 是文档与 LLM 之间的桥梁,通常使用最先进的 OCR 技术来实现。支持多种文档加载器,包括 Tesseract OCR、Azure 表单识别、AWS Textract、Google 文档理解 AI 等。

LLM(法学硕士)

这是模型的装饰组件。它利用LiteLLMInstructor等工具构建,旨在促进跨平台使用。围绕文档智能的需求进行设计。

赖约

注:此处使用“赖约”一词,更贴近日常用语,适用于更广泛的语境。

也是一个针对 Pydantic 的装饰器。目标是自动包含并处理自定义特性,如验证器和 prompt 调优。

提取器

组织文档加载器和大型语言模型之间的互动,以便提取结构化数据。

流程:

表示文件间的流。它是基于上面的组件构建的。您可以根据特定用例选择DocumentLoaders,还可以选择提取器

还有其他较小的组件,如SplittersClassifications,但我们将在具体的例子中再详细讨论它们。

选择正确的模型

选择合适的模型对于平衡性能、准确性和成本非常重要。首先,我们来看看成本:

OpenAI模型的价格(按作者)

GPT-4迷你版

应用场景:基本的文字提取任务,例如类似于文字识别。

非常适合从文档中提取文本,将图像或PDF转换成可被机器读取的文本。经济高效且快速,适用于大量数据处理。

GPT-4o (占位符)

示例:分类与拆分。

GPT-4o模型能够为你提供对文档内容和结构的更深入的理解。非常适合于文档分类、拆分合并文档为独立部分,以及执行复杂的分类工作。

何时用:

  • 将文档归类为发票、合同或收据等常见类型。
  • 根据内容将多页文档拆分为独立的部分。
  • 高级分类,需要理解上下文和细微差别。
o1 和 o1-mini 模型(或简称 o1 和 o1-mini)

用于以下情况:需要从数据中推理并得出结论的高级提取工作。

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 中的核心组件,它负责协调 DocumentLoaderLLM 之间的互动,从文档中提取结构化数据。它利用 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 提供了不同的拆分器,例如 ImageSplitterTextSplitter,来处理拆分相关的逻辑。

安装信号分配器

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仓库点个星! 🌟

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消