☰
StrucTab:结构优先的表格问答,先看懂布局再作答
2026/10/20 15:16:38 网站建设 项目流程

StrucTab 这个工作被 ECCV 2026 接收,最想分享的经验一句话就能讲完:表格问答要答得准,先得让模型把表格结构看明白,再让它生成答案。项目全称我们内部叫 Structure-First Table Answering,做法上刻意跟"直接把表格拉平喂给大模型"的主流路线唱了反调。一年多时间做下来,这步反调唱对了。如果你也在做文档理解、表格问答,或者想把图像里的表格变成结构化数据,这篇总结里的架构思路、训练细节和踩过的坑,应该能帮你省不少时间。这里先把这个核心结论摆出来:结构不是表格问答的附加题,它本身就是主答案。

1. 为什么表格解析必须先看懂结构

1.1 表格不是"长文本":二维布局的信息承载

先从一个常见误区说起。很多人处理表格,第一反应是把表格"拉平":转成 HTML、Markdown,或者一行行纯文本。这个做法不是不行,但只适用于非常规整的单层表。现实中表格的信息密度,恰恰藏在二维关系里——表头横向跨了多少列、某一行的项目纵向合并了几格、不同层级表头之间的包含关系,这些都是二维布局承载的语义。

拉平后的文本把这些关系压成了线性 token,模型需要自己从文字顺序里脑补出"这是第几列"。很多情况下它脑补不出来。举个实际例子,一张成绩表里,第二列的表头是"数学",但它下面又分出"期中"和"期末"两个子列。序列化成 Markdown 时如果不做特殊处理,"数学"这个表头只在文本里出现一次,模型要回答"张三期末数学多少分",就得自己猜子列归属。一个问题还好,十个问题叠加、表格再复杂一点,模型就开始乱配对了。

我拿真实数据测过一条基线:把表格线性化之后喂给常见多模态生成模型,只要遇到带合并单元格或者多级表头,正确率下降非常明显。问题不在模型能力,而在输入表示本身丢了结构信息。StrucTab 的出发点不是发明更聪明的解码器,而是先把输入侧的信息补全——表格在纸上明明是二维的,那就把二维结构显式还给模型。

1.2 直接端到端生成答案的三个典型痛点

在动手做 StrucTab 之前,我们花了几周复现市面上的端到端方案,把痛点总结了三条。

第一,长表格的注意力稀释。一个真实表格随便就有几十行、十几列,线性化之后 token 上千,生成答案时注意力被摊得很薄,关键单元格拿不到足够的权重。

第二,结构推断完全隐式化。模型必须从 token 顺序里自己解码出"第几行第几列交叉的格子是什么",这个过程没有任何监督信号,全靠隐式学习。碰到合并单元格,模型很容易把行列关系张冠李戴。

第三,可解释性几乎为零。模型答错了,你不知道它错在哪个环节——是没看懂表头,还是找错了单元格,还是数字计算错误?没法定位,想修都不知道从哪儿下手。

这三个痛点共同指向一个结论:结构不能靠大模型"顺便学",得用专门的模块显式建模。哪怕最终的目的只是"生成答案",结构理解也值得作为一个独立环节被推向前台。

1.3 StrucTab 的核心思路:先解析结构,再生成答案

StrucTab 的整体路线是两段式:第一阶段,结构感知模块把表格图像解析成显式结构表示,包含每个单元格的坐标、行列归属、角色(表头还是数据),以及合并关系;第二阶段,把这份结构表示和原始表格图像一起交给生成模块,模型"看着结构答卷"。

这里有一个关键设计:为什么要保留图像,而不是只用结构表示?因为结构解析不可能 100% 正确,保留视觉 token 相当于给生成器一份"校对底稿",结构解析出错时还能从像素层面兜底。这个设计后来在消融实验里被验证很值——结构模块故意加噪声后,答案正确率只掉了两个点,靠的就是视觉信息兜住了底。

2. 完整架构拆解与关键设计决策

2.1 结构感知模块:从像素到行列语义

结构感知模块最终采用的是这样一套结构:视觉 backbone 提取表格图像特征,一组可学习的查询向量通过 cross-attention 从特征里"捞"出单元格级别的信息,然后每个查询向量接三个输出头。

第一个头是单元格检测头,负责回归每个单元格的包围框;第二个头是角色分类头,区分表头单元格和数据单元格;第三个头是合并关系预测头,判断哪些单元格属于同一个合并组。三个头共享底层的查询向量表征,训练时联合收敛,效果比分开训更稳定。

这里最容易踩的坑是查询向量数量怎么定。表格单元格数量不固定,短表格十几个格子,长表格几百个格子。我们最开始用固定的 N=500,效果两头不讨好:短表格浪费计算,长表格又不够用。后来改了两版,第一版用全局特征回归一个数量预测,第二版直接把查询向量的数量做成动态的,由数量预测头输出范围(比如 20~800),再动态初始化对应数量的查询向量。显存占用下降了约 20%,长表格的召回率还涨了一截。建议后面复现的同学直接上动态方案,固定数量的做法我们基本弃用了。

合并关系预测这块,我们内部还认真吵过一轮。有人主张直接回归 rowspan 和 colspan 数值,一步到位;有人主张预测"两个单元格是否属于同一个合并组"。前一种翻译成检测任务的输出很直接,但数值回归容易震荡,训练不稳定;后一种更稳,但后续需要把配对关系重新组装成合并组。我们最后用了后一种,因为它在训练时天然适配匹配损失的形式,而且我们并不需要获得绝对精确的合并数值——生成答案时只需要知道"这一片格子是一个整体",知道这个就够了。

2.2 结构引导的答案生成模块

答案生成器是一个标准的自回归多模态模型,输入包含三部分:视觉 token、结构 token、问题 token。结构 token 不是简单地把表格"转成文本"塞进去,而是设计了一套结构化序列协议。

这套协议有几类基本符号:<row_start>表示新行开始,<header>标记表头单元格,<data>标记数据单元格,<merge_group_start>和<merge_group_end>包住一个合并区域。结构 token 序列长这样:

<row_start> <header> 姓名 <header> 数学 <merge_group_start> <header> 期中 <header> 期末 <merge_group_end> <row_start> <data> 张三 <data> 88 <data> 91 <row_start> <data> 李四 <data> 76 <data> 84

协议设计的核心原则是让生成器"无脑可用"——它不需要从坐标反推行列,也不需要脑补某个表头覆盖哪些列,只要顺着结构 token 读,行列归属和层级关系全部是显式的。序列长度会比纯文本长一些,但换来的是生成任务从"推断结构"降级为"阅读结构",难度直接降了一个量级。

几个候选方案我们都对比过。把结构 token 转成自然语言描述效果并不好,比如"第 3 行是表头,包括姓名、数学、语文",模型会被措辞带偏,因为自然语言不够严格。专门的符号协议更干净,模型学得快,推理也更稳定。

2.3 几个关键决策背后的为什么

很多同行问:为什么不直接做端到端?一次性前向传播把结构和答案都出来不是更省事吗?我们试过,效果不理想。原因在于,结构错误和答案错误在梯度上会互相污染,结构模块还没收敛时,生成器只能学到"在残缺结构上瞎猜答案"这个坏习惯。拆成两阶段以后,结构先收敛,再联合微调,训练节奏完全可控。

另一个决策是结构 token 与视觉 token 的融合顺序。我们试过把结构 token 放在视觉 token 前面、后面、中间。放前面时生成器倾向于过度依赖结构,忽略视觉细节;放后面时结构信息靠后,注意力容易被问题 token 带跑。最终稳定的方案是把结构 token 放在视觉 token 和问题 token 之间,形成"图像基础 + 结构骨架 + 问题"的阅读顺序,效果最平衡。

3. 实操过程与核心环节实现细节

3.1 数据准备:标注策略与合成数据

结构优先路线的数据要求比端到端高得多。模型不仅需要"表格图像-问题-答案"三元组,还需要每个单元格的框、角色和合并关系。我们在一批公开表格问答数据上做了二次标注,二次标注的规则坑尤其多。

最典型的坑是合并单元格的标注规则不统一。一张表格里,一个横向合并的单元格,对应的子列怎么标记?我们最初是每个子列都复制一遍表头文本,结果结构模块学出来的合并关系一团乱。后来统一了规则:合并区域只标一次主单元格,子单元格不复制文本,只记录"属于合并组 ID"。这个改动让合并关系预测头收敛快了很多。

如果从零开始造数据,我的建议是走"半自动合成"路线:先用程序生成大量表格图像,因为图像是自己画的,结构标注可以完全自动生成;用这批合成数据把结构模块训练到稳定,再拿少量真实文档做微调。这个路径比一上来就人工标注靠谱得多。合成阶段重点要覆盖多级表头、横向合并、纵向合并、无边框表格、斜线表头这些困难模式,真实数据微调时只需要几十张图就能见效。

数据标注的 JSON 格式我们用的是这种风格:

{ "image": "table_001.png", "cells": [ {"id": 0, "bbox": [12, 18, 100, 40], "role": "header", "row": 0, "col": 0}, {"id": 1, "bbox": [104, 18, 210, 40], "role": "header", "row": 0, "col": 1, "merge_group": 0} ], "merge_groups": [ {"id": 0, "start": 1, "span": [1, 2]} ], "questions": [ {"text": "张三期末数学多少分?", "answer": "91"} ] }

这个格式的核心是把结构信息和问答信息分开存,训练结构模块时只读 cells 和 merge_groups,训练生成模块时再拼出完整输入。

3.2 训练策略:三阶段推进,别跳步

训练分三步走,这一步经验非常重要,跳步训练后面一定出问题。

第一阶段:纯训练结构感知模块。loss 由三部分构成:单元格检测的回归损失和匹配损失、角色分类的交叉熵、合并关系的配对损失。这个阶段不需要生成器参与,结构模块单独收敛。合成数据上我们训练了大概 2 万步,检测 F1 稳定在 90 以上才进入下一步。

第二阶段:冻结结构模块,只训练生成器。生成器的输入是结构模块输出的 token(被冻结后不再回传梯度)加视觉 token 加问题 token。这一步的意义是让生成器先学会"读结构 token 的语法",把结构 token 当作一种新的输入语言来熟悉。如果跳过这步,直接联合微调,生成器没见过结构 token 的变化分布,会把结构信息当成噪声丢掉。

第三阶段:端到端联合微调。此时两部分都已有一定收敛基础,用小学习率把整个网络打通。我们在这一阶段观察到答案准确率还有一波提升,大概有 1.5 个点,来自结构与视觉信息的互补校准。

超参数方面,一个比较实用的组合是:学习率第一阶段 5e-5,第二阶段 3e-5,联合微调阶段降到 1e-5;batch size 第一、二阶段用 16,联合微调阶段因为显存变大降到 8。数据增强除了常规的随机旋转、缩放,强烈建议加入表格线条增强和无边框表格的合成噪声,这对结构模块的鲁棒性很有帮助。

3.3 推理时的结构化约束解码

推理阶段我们加了一个轻量级的约束解码技巧,论文里没重点写,但实际用下来很香。原理是:生成器在预测每个答案 token 时,除了正常的概率分布,我们额外维护了一份"当前引用的是哪个单元格"的状态。如果模型试图把某个数值 token 和一个在结构上完全没有对应关系的上下文强行关联,就在 logits 层面做一个轻微的抑制。

这个约束不强,不会强制模型做决定,只会降低幻觉概率。在我们的测试集上,加上约束后答案正确率涨了一个多点,并且结构化输出的可解释性大幅提升——做错误分析时,可以直接看模型最后引用的是哪个单元格,定位错误快了非常多。

这个技巧的背后逻辑是:表格问答里的数字答案,几乎总是来自某个确定单元格的取值,结构解析已经给了我们候选单元格列表,那么答案就应当被约束在这个候选空间里。逻辑上说得通,实测也一样稳定有效。

4. 效果观察与边界讨论

4.1 在公开表格问答基准上的表现

我们在 TabFact、WikiTQ 这类公开基准上都做了对比。结构识别这块,单元格检测的 F1 在 80 到 92 之间浮动——表格规整、线框清晰的数据集上能到 92,复杂表头、合并单元格多的数据集会掉到 80 出头。答案生成这块,整体比端到端基线平均高了接近 5 个百分点,在长表格子集上差距更大,最高能到 7 个点。

一个很有意思的观察是:结构解析 F1 和答案正确率不是严格线性关系。结构 F1 在 90 以上时,继续提升对答案的边际收益很小;但结构 F1 一旦跌到 85 以下,答案正确率下滑得特别快。这说明结构模块的上限不用追求极致,达到"足够好"就行,但绝对不能烂。这个结论对实际调参很有指导意义——与其在 95 到 96 的 F1 上死磕,不如把时间花在数据多样性和生成器的鲁棒性上。

4.2 消融实验带来的结论

消融实验验证了几件事,每一件都对应着一个设计选择。

去掉结构 token,只保留视觉 token 和问题 token,答案正确率掉了大概 4 个百分点。这直接验证了结构 token 不是锦上添花,而是核心信息源。

把合并关系预测头拿掉,让生成器只靠单元格框和角色信息,整体准确率似乎没怎么变,但一旦测试集里出现合并单元格,错误率直接翻倍。这说明合并关系对特定难例来说是刚需。

保留图像而不是只用结构 token,这是我们一开始就坚持的方向。在消融里我们做了一个反向实验:故意把结构模块的坐标输出加上噪声,只给生成器结构 token,不给视觉 token,正确率掉了 6 个点;同样的噪声情况下,保留视觉 token,正确率只掉 2 个点。视觉兜底的价值非常清楚。

这些消融结果可以浓缩成一句话:结构信息是核心骨架,视觉信息是安全网,两者缺一不可。

4.3 我看到的局限与边界

这个方案有明显的边界,说几个真实的短板。

第一,推理速度。两阶段结构比单阶段直接生成慢不少,结构模块一次前向加上生成器的自回归解码,延迟比端到端方案多 30% 到 50%。在一些对延迟敏感的实时场景里,这个方案用起来不舒服。解决办法是离线批量处理或者把结构模块裁剪成轻量版,但本质还是慢。

第二,表格类型的覆盖范围。StrucTab 对常见的三线表、单层表效果很好,对高度复杂的排版还是会翻车,比如跨页表格、旋转表头、斜线表头。斜线表头尤其麻烦,因为它的语义不是简单坐标能表示的,我们内部研究过,目前只能当半开放问题处理。

第三,领域迁移问题。在合成表格上训练的结构模块,直接迁移到真实扫描件上会掉点。我们做过实验,用少量真实标注做微调,效果恢复得很快,所以真实场景必须预留一批真实标注数据做兜底。

5. 复现与部署的注意事项

5.1 显存与框架选型经验

结构模块用检测框架的 Swin backbone 加查询机制,显存占用相当可观。我们最初尝试 batch size 直接拉满 16,训练一跑就 OOM。后来压缩到 8,配合梯度累积到等效 32,才稳定下来。如果你用的机器显存有限,可以先从 batch size 8 起步,别贪。

部署方面,离线批量解析推荐直接用 FP16 推理,速度和显存占用都比较理想。在线服务建议把结构模块和生成器拆成两个服务,中间用消息队列解耦,两个模块各自独立扩容。我们踩过一个大坑:两个模块放在同一个部署单元里,结构模块的显存波动会引发生成器的抖动,拆开之后问题直接消失。这个架构调整虽然多了一次网络调用,但稳定性收益非常值得。

5.2 常见问题与排查速查表

把实操中最常遇到的问题整理成一张表,方便大家对照排查:

现象可能原因解决办法
合并单元格识别不出来合并关系预测头训练不足在合成数据里增加合并单元格扰动,调高该分支 loss 权重
答案指向错误的行表头层级解析出错检查结构 token 协议中表头 ID 是否唯一,避免歧义
长表格生成截断上下文超限对表格做行分块,每块独立解析,再做跨块答案融合
无边框表格结构乱视觉特征缺少线条线索在 backbone 输入端叠加边缘增强预处理
显存溢出查询向量数量过大用数量预测头限制 query 数量上限,推理时动态裁剪
生成器忽略结构 token第二阶段冻结训练不充分增加冻结训练步数,观察结构 token 对应的 loss 是否下降
结构模块在真实数据上掉点合成数据与真实分布差距大准备少量真实标注做微调,建议不少于 50 张图

5.3 给准备复现的同行三条实在建议

第一条,先用合成数据把结构模块训到稳定,再碰真实数据。合成数据便宜、标注自动、分布可控,是调结构模块最好的热身场。

第二条,结构 token 协议一开始就定死,中途不要改。协议一旦变化,生成器等于要重新学一遍输入语法,成本非常高。我们中途改过一次合并区域的表达方式,生成器重新训练了 5 天,效果才恢复,教训深刻。

第三条,评测时不要只看最终答案准确率。把指标拆开:结构解析 F1、单元格角色准确率、合并关系准确率、答案正确率,分别记录。出了问题才能快速定位,全链路指标混在一起只看一个数,基本等于没评价。

另外说一句部署时的经验:结构模块的输出一定要留缓存,同一个表格被不同问题反复问到时,只需要做一次结构解析,后面的问题直接复用结构 token。这个简单的缓存策略,在真实问答系统里能省掉一半以上的重复计算,效果立竿见影。

6. 从论文到工程:一个被忽略的隐性收益

6.1 结构化中间产物改变了调试方式

做完 StrucTab 之后,一个比较意外的收获是:结构解析的中间产物让整个系统的调试方式彻底变了。以前做端到端表格问答,模型答错了,大家只能拿着错误案例猜原因,猜来猜去效率极低。现在,结构模块输出的单元格框可以直接可视化,跟原图叠加在一起看,一眼就能判断模型是不是看懂了表格布局。

这种可解释性带来的效率提升,在实际项目迭代中比几个点的准确率更有价值。团队里新同学上手时,我先让他们看结构化输出,再让他们改数据问题,而不是直接改模型。几次迭代下来,大家都养成了"先看结构,再归因"的习惯。

6.2 复用性:结构解析器可以独立使用

还有一个工程上的隐性收益:StrucTab 的结构感知模块并不是只能服务表格问答。它输出的单元格坐标、角色和合并关系,天然就是一份可用的"表格结构化数据"。

我们后来把结构模块单独抽出来,接了一个简单的导出管线,直接用于把扫描件表格转成 Excel、HTML 和 JSON 格式。这个能力在文档管理系统里非常好使,等于一个模块同时支撑了表格问答和表格结构化两个产品功能。因此如果你是做平台型系统,结构感知模块的复用价值值得提前评估,它大概率不会白训。

从 ECCV 2026 接收本身来说,这份工作的学术贡献主要在于把"结构优先"的理念用一个可复现的框架落地了。但对我来说,更真实的收获是过程中那一次次因为结构解析不到位导致的失败,以及最后把失败挨个修正掉的路径。我个人的体会是:表格解析从来都不是"生成答案"这一个环节的事情,它前面的结构理解决定了一切后续环节的上限。如果你正准备做表格相关任务,开工前先问自己一句——模型真的"看到"了表格的结构吗?如果答案是否定的,那再强的推理能力,也只是在漏风的房子里摆豪华家具。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询