乐于分享
好东西不私藏

Kreuzberg 表格检测:PDF 里的表格,终于不只是“一堆文字”了

Kreuzberg 表格检测:PDF 里的表格,终于不只是“一堆文字”了
很多文档抽取工具都有一个共同问题:普通段落还好,一遇到表格就开始变形。

行列错位、表头丢失、单元格顺序混乱、跨行跨列信息被打散。最后看起来像是抽出了文字,实际上已经很难继续用。

这对 RAG、知识库和企业搜索都很麻烦。因为表格里的信息往往不是装饰,而是关键数据:报价、规格、财务数字、测试结果、合同条款、实验记录、审计明细。段落抽错了,可能还能靠上下文补一补;表格抽错了,数字关系直接就没了。

Kreuzberg 的表格检测能力,就是为这类文档准备的。

它不是简单把页面文字抽出来,而是先理解页面布局,再识别表格区域,最后进一步恢复表格里的行、列、表头和跨行跨列关系。

官方文档入口:

https://docs.kreuzberg.dev/guides/layout-detection/[1]

表格检测到底解决什么问题?

传统文本抽取经常把 PDF 当成一块“可读文本”来处理。

这对简单文档没问题。比如单栏文章、纯文本报告、简单合同,直接抽段落就够了。

但 PDF 里的表格不是普通文本。

表格有区域,有行,有列,有表头,有合并单元格,有时还有边框,有时没有边框。有些表格在扫描件里,有些表格嵌在多栏论文或财报页面里。你不能只把页面上的字按坐标扫出来,然后假装它还是一张表。

Kreuzberg 的 Layout Detection 做的是第一步:先识别文档页面上的区域。

它会判断哪里是正文,哪里是标题,哪里是图,哪里是表格。官方文档里写到,Layout Detection 使用 ONNX 版 RT-DETR v2 模型,可以检测 17 类版面元素,包括 text blocks、tables、figures、headers、footers、captions、code、lists、sections、formulas、footnotes、page headers/footers、titles、checkboxes、key-value regions 和 document indexes。

识别出表格区域之后,Table Structure Recognition 再做第二步:分析表格里的行、列、表头和跨行跨列单元格。

这才是表格抽取真正有用的地方。

不是“我看见这里有文字”,而是“我知道这是一张表,并且知道这些文字之间是什么结构关系”。

先看懂页面,再抽取内容

Kreuzberg 的 Layout Detection 不是单独服务表格,而是让系统先具备页面版面理解能力。

官方文档里对它的描述很直接:检测 PDF 里的文档布局区域,比如 tables、figures、headers、text blocks 等。这个能力可以用于表格抽取、图片区域隔离、阅读顺序重建和选择性 OCR。

这几个点放在实际项目里都很关键。

多栏论文里,阅读顺序经常不是简单从左到右、从上到下。

业务表单里,字段和值可能分散在固定区域。

扫描文档里,OCR 不应该盲目处理整页,最好知道哪些区域更值得识别。

带图表的报告里,图、图注、正文和表格混在一起,直接抽文本很容易把上下文打乱。

Layout Detection 的作用,就是先把页面拆成更像人阅读时理解的结构。

官方还给了一个 CPU-only 的基准参考:在 171 份 PDF 文档语料上,Baseline 的 Structure F1 是 33.9%,Text F1 是 87.4%,平均每文档 447 ms;启用 Layout 后,Structure F1 提升到 41.1%,Text F1 提升到 90.1%,平均每文档 1500 ms。

这个数据很诚实。

启用版面检测会增加耗时,但结构质量会提升。对简单文档,你未必需要打开它;对复杂 PDF、扫描件、学术论文、业务表单,结构质量通常比少几百毫秒更重要。

表格结构识别,补齐关键一环

Kreuzberg 把表格结构识别做成了可配置后端。LayoutDetectionConfig 里的 table_model 字段可以选择不同模型。

官方 release 里列出的模型包括:

  • -tatr:默认模型,约 30 MB,适合通用场景;
  • -slanet_wired:约 365 MB,适合有边框或网格线的表格;
  • -slanet_wireless:约 365 MB,适合无边框表格;
  • -slanet_auto:约 737 MB,适合混合文档,会自动分类;
  • -slanet_plus:约 7.78 MB,适合资源受限环境。

这组选择很实用。

因为表格没有一种固定形态。财报里常见的是有线表格,论文里经常有三线表,合同附件可能是半结构化表格,扫描件里的线条还可能不完整。一个模型很难覆盖所有情况,所以 Kreuzberg 把选择权交给用户。

如果你想先用默认配置,选 tatr

如果你处理的是大量有边框表格,可以试 slanet_wired

如果是无边框表格,试 slanet_wireless

如果文档来源混杂,slanet_auto 更省心,但模型更大、速度也会慢一些。

如果部署环境紧张,slanet_plus 更轻。

怎么用?

Python 里可以这样配置:

from kreuzberg import ExtractionConfig, LayoutDetectionConfig, extract_fileconfig = ExtractionConfig(    layout=LayoutDetectionConfig(        confidence_threshold=0.5,        apply_heuristics=True,        table_model="tatr",))result =await extract_file("document.pdf", config=config)

TypeScript/Node.js 里可以这样写:

const result =awaitextract("document.pdf",{  layout:{    confidenceThreshold:0.5,    applyHeuristics:true,    tableModel:"tatr",},});

CLI 里也能直接开启:

kreuzberg extract document.pdf --layout --content-format markdown

指定表格模型:

kreuzberg extract document.pdf --layout --layout-table-model slanet_wired

如果要结合硬件加速,例如 Apple 平台的 CoreML:

kreuzberg extract document.pdf --layout--acceleration coreml

SLANeXT 模型默认不会全部下载。官方提供了预热命令,可以提前缓存表格模型:

kreuzberg cache warm --all-table-models

这对生产环境比较有用。上线后第一次请求才下载大模型,体验通常不会好。

这对 RAG 有什么用?

RAG 项目里,很多人会把注意力放在 embedding、rerank、prompt 和模型选择上。

这些当然重要。

但如果文档抽取阶段已经把表格弄乱了,后面再怎么调也很难恢复。

举个简单例子。

一张产品参数表里有三列:型号、功率、价格。

如果抽取结果只是把所有文字拼成一段,模型可能知道有这些数字,却不知道哪个价格对应哪个型号。检索命中了也没用,回答时很容易把行列关系说错。

表格检测和结构识别的价值,就在于尽量保留这些关系。

对于知识库来说,这意味着更好的上下文。

对于搜索来说,这意味着更可靠的字段关系。

对于自动化处理来说,这意味着 Markdown、HTML 或 JSON 输出可以继续进入下游程序,而不是让人再手工清洗一遍。

适合打开这个能力的场景

这些场景适合优先开启 Layout Detection:

  • -PDF 里有大量表格;
  • -文档是扫描件,或者 OCR 质量受布局影响明显;
  • -学术论文、研报、财报、检测报告等多栏或复杂版式文档;
  • -业务表单、报价单、合同附件、规格书;
  • -抽取结果要进入 RAG、数据库、数据清洗流程,而不是只给人粗略阅读。

但如果你的文档非常简单,比如纯文本 PDF 或单栏说明书,也可以先不开。

因为官方数据也显示,启用 Layout Detection 会增加处理时间。对高吞吐任务来说,应该按文档类型决定是否开启,而不是所有文件一刀切。

有哪些限制?

第一,Layout Detection 需要额外 feature。

官方文档写明,它需要 layout-detection Cargo feature,不在默认 feature set 中。

第二,WebAssembly 不支持 Layout Detection。

Features 页面里说明,布局检测能力适用于除 WebAssembly 外的语言绑定。原因也很直接:浏览器环境里没有 ONNX Runtime。

这意味着在线 Demo 适合体验本地浏览器抽取,但如果你要用 ONNX 模型做表格检测和版面理解,还是要走 SDK、CLI、API 或服务端部署。

第三,模型大小和速度要权衡。

tatr 比较轻,slanet_plus 更轻;SLANeXT 系列更强但模型明显更大。生产环境里最好拿自己的文档样本测一下,不要只看模型名字选。

为什么这项能力值得关注

这项能力补上了文档智能里最容易被低估的一块。

抽出文字只是第一步。

真正难的是保留结构。

表格、图注、标题、页眉页脚、列表、公式、表单字段,这些东西决定了文档能不能被机器继续理解。尤其是表格,很多企业文档里的关键信息都在里面。

Kreuzberg 把 Layout Detection 和 Table Structure Recognition 放进统一配置里,又提供多语言绑定和 CLI,这让它不只是一个“能跑模型”的功能,而是更容易进入实际工程。

对做 RAG、知识库、企业搜索、合同解析、报告处理的人来说,这项能力值得单独看。

总结

Kreuzberg 的表格检测能力,让文档抽取不再停留在“把 PDF 里的文字拿出来”。

它更关注页面结构,尤其是表格结构:哪里是表格,表格里有哪些行列,表头怎么对应,跨行跨列关系如何保留。

如果文档里有大量表格,或者抽取结果要进入 RAG、知识库、数据库和自动化流程,这项能力值得作为默认评估项。

References

[1] https://docs.kreuzberg.dev/guides/layout-detection/

[2] https://docs.kreuzberg.dev/features/#layout-detection

[3] https://github.com/kreuzberg-dev/kreuzberg/releases/tag/v4.5.0

[4] https://github.com/kreuzberg-dev/kreuzberg/releases/tag/v4.5.3

[5] https://github.com/kreuzberg-dev/kreuzberg/releases