@jerryjliu0: 我们构建了最先进的表单阅读模型 表单文档具有以下会让VLMs头疼的特性:它们…

X AI KOLs Timeline 工具

摘要

这篇博客文章解释了为什么VLMs在处理表单文档时遇到困难,并介绍了LlamaParse,一个专为精确且经济高效的表单解析而构建的工具。

我们构建了最先进的表单阅读模型 📋 表单文档具有以下会让VLMs头疼的特性: ✅ 它们承载的结构远超过标准Markdown所能表示的。你需要为复选框、文本框、标签、签名字段等提供一致的类型。 ✅ 它们可能极其复杂(表单可能被扫描,可能有手写潦草,有些表单密集包含100多个字段),但准确率要求需要接近100% ✅ 任何表单解析器都需要精确的定位和归属。不仅应该提取值,还应该能够精确定位每个值在源文档中的来源。 ✅ 任何表单不仅需要准确,还需要经济高效且快速 在这篇博文中,我们深入探讨了构建表单解析器所需的要素:https://llamaindex.ai/blog/why-vlms-can-t-read-forms… 如果你想尝试我们的表单模型,请查看LlamaParse:https://cloud.llamaindex.ai
查看原文
查看缓存全文

缓存时间: 2026/09/28 21:38

我们为表格文档处理构建了最先进的模型 📋

表格文档具有以下特性,这些特性常常困扰视觉语言模型: ✅ 比标准Markdown能表示的结构复杂得多。你需要为复选框、文本框、标签和签名字段建立统一的类型体系。 ✅ 可能极其复杂(表格可能经过扫描,存在手写涂鸦,有些表格密集包含100+字段),但准确率要求必须接近100%。 ✅ 任何表格解析器都需要精确的定位与溯源能力。不仅要提取数值,还要能精确定位每个值在源文档中的来源位置。 ✅ 任何表格处理方案都需要兼顾准确性、成本和速度。

我们在这篇博文中深入探讨了构建表格解析器的关键要素:https://llamaindex.ai/blog/why-vlms-can-t-read-forms…

如果您想试用我们的表格模型,可以访问 LlamaParse:https://cloud.llamaindex.ai


表格解析为何如此困难:AI表格提取与视觉语言模型的对比

来源:https://www.llamaindex.ai/blog/why-vlms-can-t-read-forms 表格是企业最关键的文档类型之一,因为它承载着来自客户和用户的重要输入数据。除了处理大量文本时面临的成本、性能和延迟等复杂问题外,表格还会为任何文档处理流程带来独特的挑战。表格包含的结构信息远超标准Markdown所能表达,包括文本框、复选框以及控制相邻内容的标签。因此系统必须围绕这些特性专门设计。输出结果需要在相同表单类型间保持一致,同时还要能适应同一表单在不同年份出现的差异。在此类任务中,幻觉问题造成的后果比其他场景更为严重。 表格具有精确的结构,任何微小的错误都可能完全改变其含义。一个复选框是否选中,可能会彻底改变后续代理执行的操作。本文将深入探讨表格为何需要特殊处理,介绍LlamaParse如何将表格表示为JSON格式,并分析让视觉语言模型执行相同任务时会出现的问题。

为何需要专用表格解析器

解析表格的方法多种多样,但它们在成本和性能方面差异很大。虽然视觉语言模型可以作为实验工具(只需输入页面截图并请求输出),但它在成本、可靠性和性能方面存在挑战。视觉语言模型针对通用推理能力进行优化,而非针对文档或表格处理。我们的自有研究结果表明,增加推理能力并不能真正转化为更好的解析效果。

LlamaParse专为文档和表格理解而构建,在成本仅为视觉语言模型一小部分的情况下,性能却更胜一筹。其底层针对表格内容提取和边界框检测的优化流程经过精心调校和组合,以达到最佳效果。

表格结构的表示方式

表格可以表示为字段和分区的树状结构。字段可能包含id、label和value属性。field属性标识输入类型,而section则将相关字段分组到items中。以下是表格模式中的元素示例:

  • id: 表格上印刷的短标识符,如1、12a或e。
  • label: 描述该字段内容的文本。
  • field: 字段类型
    • checkbox: 布尔值框:选中时为true,未选中时为false。
    • text: 文本输入字段,包括数字、日期和地址等。
    • signature: 签名框,可已签或未签。
  • value: 字段值。文本字段对应字符串;复选框或签名字段对应布尔值。

表格对象可以通过以下简单的Pydantic类表示。根据表格的实际复杂程度,该结构可以具有任意嵌套层级。

查看以Pydantic类表示的最小化模式:

from typing import Literal, Optional, Union
from pydantic import BaseModel, Field

class FormField(BaseModel):
    """表单中的一个条目:文本框、复选框、签名或选项组。"""
    field: Literal["text", "checkbox", ...]
    id: Optional[str] = Field(None, description="表格上印刷的标识符,例如 '1'、'12a'、'e'")
    label: Optional[str] = Field(None, description="字段旁印刷的说明文字")
    value: Optional[Union[str, bool]] = Field(
        None, description="文本字段为原文文本;复选框或签名字段为真/假值")

class FormSection(BaseModel):
    """印刷的字段分组,例如 'Part III' 或 'Sign Here'。"""
    type: Literal["section"] = "section"
    id: Optional[str] = None
    label: Optional[str] = None
    items: list["FormNode"]

FormNode = Union[FormField, FormSection]

图1展示了这些元素在W-2税表中的组合方式。方框1成为id为1、标签为Wages, tips, other compensation、值为230303.03的文本字段。方框13保持为一个包含三个复选框选项的组。方框9虽然是空的,但仍然会出现在输出中。

图1. W-2表格源文件与表单表示。左侧为源页面;下方为JSON格式的表单表示。查看JSON输出

[
  {
    "type": "field",
    "field": "text",
    "id": "a",
    "label": "Employee's social security number",
    "value": "827-37-3673"
  },
  {
    "type": "field",
    "field": "text",
    "id": "1",
    "label": "Wages, tips, other compensation",
    "value": "230303.03"
  },
  {
    "type": "field",
    "field": "text",
    "id": "9",
    "isEmpty": true
  },
  {
    "type": "field",
    "field": "multi_select",
    "id": "13",
    "valueItems": [
      {
        "type": "field",
        "field": "checkbox",
        "label": "Statutory employee",
        "value": false
      },
      {
        "type": "field",
        "field": "checkbox",
        "label": "Retirement plan",
        "value": false
      },
      {
        "type": "field",
        "field": "checkbox",
        "label": "Third-party sick pay",
        "value": true
      }
    ]
  },
  {
    "type": "section",
    "id": "12a",
    "items": [
      {
        "type": "field",
        "field": "text",
        "label": "Code",
        "value": "H"
      },
      {
        "type": "field",
        "field": "text",
        "value": "8699"
      }
    ]
  }
]

虽然正确提取各个字段是第一步,但输出还必须保留它们之间的关联关系。图2显示了两个印刷分区中的独立“Date“字段。扁平化的元素列表会丢失每个字段所属的分区信息,导致两个Date字段无法区分。而LlamaParse将字段分组到分区中,将每个日期字段与其正确的父分区关联。

图2. 表格1040的分区展示:“Sign Here“和“Paid Preparer Use Only”。每个分区包含自己的“Date“字段。

扁平化列表
{ signature, "Your signature" }, { text, "Date" }, { text, "Phone no." },
{ text, "Preparer's name" }, { text, "Date" }      // 54个节点,0个分区

分组到分区
{ section, "Sign Here",              items: [ signature, Date, occupation, Phone ] },
{ section, "Paid Preparer Use Only", items: [ name, Date, PTIN, Phone ] }
                                                            // 28个节点,5个分区

虽然复选框状态是表格中最重要的信息之一,但对于视觉语言模型来说却是个挑战,因为它需要同时读取整个页面并预测所有内容。为了克服我们观察到的视觉语言模型的局限性,我们构建了一个小型复选框状态分类器,它可以单独查看每个复选框来预测状态,并修正模型的原始预测。

图3展示了一个被标记的复选框,初始视觉语言模型解析返回了false;我们的分类器将其修正为高置信度的已选中状态。

图3. W-9表格上的复选框状态修正。“Other“复选框已被标记,但初始视觉语言模型解析记录为false;复选框状态模型将其修正为true。

修正前   { "field": "checkbox", "label": "Other (see instructions)", "value": false }
                                          // 状态模型读取该框已选中 @ 0.94
修正后    { "field": "checkbox", "label": "Other (see instructions)", "value": true }
                                          // 值已修正,复选框未触碰

定位表格框

边界框是围绕目标对象的矩形区域,在表格中意味着文本字段或复选框。边界框对于下游应用和验证至关重要,因为它们允许审核人员和用户与原始文档进行核对。

图4. 表格1040上的边界框。蓝色框标记文本字段,绿色框标记复选框。 视觉语言模型在此任务上表现尤其不佳,会遗漏大量边界框。使用专用确定性模型能产生远优于此的效果。在LlamaIndex,我们从零开始训练了一个表格边界框检测模型,大幅提升了该任务的性能。

图5展示了一个观察到的失败案例:原始视觉语言模型在此运行中仅返回两个框,而LlamaParse检测到了所有字段边界框。

图5. 数字表格上观察到的一次视觉语言模型检测失败。视觉语言模型的全页输出包含两个错位框——一个在空白边距上,一个在印刷箭头(左);LlamaParse在同一页上的输出裁剪显示了检测到的商品成本部分(右)。 即使视觉语言模型能够输出大量边界框,将这些检测到的框与页面上的实际框对齐仍然是视觉语言模型面临的挑战。

图6. 扫描W-4表格上的边界框对齐。视觉语言模型的框在输入行之间漂移(左),而LlamaParse在23个输入单元格上各放置了一个框(右)。 还有一些开源模型,如FFDNet (https://github.com/jbarrow/commonforms),它们在数字表格上构建和测试,在准确性上可能优于视觉语言模型。但这些开源模型是在空白数字表格上训练和基准测试的,缺乏对已填写数据或扫描件的鲁棒性。图7展示了在已填写W-9表格上的失败案例,图8则展示了扫描手写1040表格上的问题。

图7. 已填写W-9表格上的边界框检测。开源检测器漏掉了已选中的框,并将框从输入值处偏移(左);LlamaParse在同一页面上正确定位了字段和控件(右)。 图8. 扫描手写表格1040上的边界框检测。开源检测器在一个空白字段上返回了一个框(左);LlamaParse在同一页上检测到了全部51个已填写字段(右)。

将框归属于字段

溯源能力使AI文档处理变得可审计。一旦提取了边界框,就必须将它们链接回对应的表格元素。

图9. 第8c行的检测矩形被归属于控制它的标签“债务抵消“。 通用视觉语言模型可以尝试进行这种归属,但可靠性有限。将边界框与正确内容匹配需要理解表格中每个组件的含义。随着表格变得更加密集,复杂性也随之增长。不幸的是,即使文本被完美读取,匹配也可能静默失败。图10展示了一个视觉语言模型归属失败的案例:模型正确返回了第8b行的值70870,但将其边界框关联到了第8a行。

图10. 一次静默归属错误,以及相同行的正确处理。左:通用视觉语言模型正确转录了第8b行的值,但将其边界框关联到了第8a行。右:LlamaParse正确地将值归属于第8b行。

使用LlamaParse解析表格

表格带来了一系列独特的挑战。正确解析它们需要专门的解决方案,能够表示表格结构、检测边界框,并将每个框归属于正确的元素以便追踪来源。在LlamaIndex,我们开发了一种表格解析解决方案,其性能优于视觉语言模型,且成本仅为后者的极小部分。

要在您自己的表格上尝试,只需在解析请求中添加一个选项。增强型表格处理适用于cost_effective、agentic和agentic_plus层级,每个表格页面增加10个积分(不包含表格的页面不增加积分)。

from llama_cloud import LlamaCloud

client = LlamaCloud()  # 从环境读取 LLAMA_CLOUD_API_KEY

file = client.files.create(file="w2-2024.pdf", purpose="parse")
result = client.parsing.parse(
    file_id=file.id,
    tier="agentic",
    version="latest",
    processing_options={"forms": "enrich"},   # 运行表格处理通道
    expand=["forms"],
)

for page in result.forms.pages:
    for form in page.forms:
        for node in form.json_:   # FormNode树,按阅读顺序
            print(node)

W-2表格的第一个字段返回结果如下——显示印刷的值及其读取的框位置:

{
  "type": "field",
  "field": "text",
  "id": "1",
  "label": "Wages, tips, other compensation",
  "value": "230303.03",
  "bbox": [{"x": 356.6, "y": 143.2, "w": 96.4, "h": 14.0}]
}

如需了解更多入门信息,请参阅我们的操作指南:

增强型表格处理示例 (https://developers.llamaindex.ai/llamaparse/parse/examples/enriched_forms/)

LlamaIndex 🦙 (@llama_index): 解析表格仍然困扰着最新的前沿视觉语言模型。

表格不是页面上的文本。它是一组字段,分组到分区中,每个字段都与特定的框相关联。这就是为什么表格需要专用解析,而不是更大的通用模型:

✅️ 检测每个字段,而不仅仅是明显的字段

相似文章