好久没有写博客了。这次想认真说说,我作为 TabU 的作者,对这些表格基础模型(TFM)到底是什么态度。
我承认它们的预测能力,也承认其中扎实的研究工作。但在架构审美上,我确实很不满意。
我所说的“丑”,有具体含义:一个模型为了处理表格,究竟引入了多少种特殊身份、特殊阶段、特殊接口?这些复杂性有多少来自问题本身,又有多少来自最初的抽象选择?
参数多一点、层数深一点,我都能接受。我最受不了的是:一个本来应该统一的问题,被架构拆成许多例外,然后我们再为修补这些例外的技巧鼓掌。
当然,“统一”也不是免检证书。把五个模块换成一个大名字,内部照样保留五套例外,那不叫简洁,只是目录变短了。我关心的是遇到新问题时,还要新增多少规则,原来的计算还能保留多少,以及这些规则究竟换来了什么。
我想逐个把这件事说清楚。
TabPFN-3:你的工程能力,我认;你的表格抽象,我还不服
列级分布嵌入、行内聚合、行级 ICL,再配上检索式分类头、缓存和精确分块,这条路线确实把预测效率做得很认真。技术报告 §2把几个阶段讲得很清楚:先在列方向组织分布信息,再用学习到的 CLS tokens 聚合每行特征,后续的上下文学习主要围绕行表示展开。
这里的 ICL,也就是 in-context learning,是把有标签的样本作为上下文,让模型据此回答新样本的问题。把每一行压成固定维度的表示,确实能让后续处理不必一直背着整张单元格张量跑。这个计算收益是真实的,不能因为我不喜欢这个抽象,就装作它不存在。
尤其检索式分类头,已经在摆脱固定输出位置的束缚,这个进步不能装作没看见。它用测试行表示作 query,训练行表示作 keys,训练标签的 one-hot 表示作 values,输出对类别的预测。这里的“检索”是模型内部的分类解码机制,不是外挂一个搜索引擎。
但我的不满也正在这里:进入后续 ICL 的主要对象,已经是压缩过的行表示。
这种压缩对某个指定目标完全可能足够,甚至非常划算。可一旦我的要求变成查询不同列、同时回答不同位置的问题、保留可直接读取的单元格状态,就必须重新说明:这个摘要究竟对哪些问题足够?
比如,一张表里有年龄、收入、职业和某个风险标签。当任务一直是预测最后那个标签时,行摘要只要保留对它有用的信息,就已经很成功。但如果现在改问收入,再同时问另一个位置,我不愿意直接沿用之前的成功结论。哪些信息仍然可用?是否需要重新组织输入、重新聚合,或者增加新的出口?这是另一组问题。
这不是证明行表示一定做不到。只要维度和编码方式允许,行表示当然可能承载很丰富的信息。我质疑的是:我们是否已经为更广的读出需求付清了证明的账。
我不接受用单目标预测的成功,替整个表格对象体系下结论。
在我的设计标准里,你把“如何高效预测指定目标”回答得很好;至于“表格应该以什么对象长期存在”,你选择了一个有明确计算收益、也有明确结构代价的答案。这个代价值得挑战。
TabFM:前面的表示工程这么讲究,出口却是一道小门
列与行的上下文化、CLS 压缩、后续 ICL,都有投入。但公开的 TabFM 1.0.0 分类检查点,明确限制最多十个输出类别。官方 PyTorch 模型卡在 Available Checkpoints、Not Intended For 和 Limitations 中都写明了这件事。
这里说的是预测目标的类别数,不能混同于输入类别特征的基数。一个输入字段里有很多不同取值,与模型最后需要区分多少种目标标签,是两回事。回归检查点也不能拿这个分类上限去概括。
我看到这里,真的会忍不住:
“Foundation”挂在门口,第十一个类别来了,门关了?
这当然可以通过后续版本、编码方案或其他机制扩展。我批评的是这个公开版本的接口,不是宣判 TabFM 这个模型家族永远跨不过十类。但它暴露了一个我很在意的问题:任务空间仍然受到预设接口的强烈约束。
我希望类别集合由当前问题决定,预测位置由查询决定。为了多几个类别、换一个目标,就不断引入额外适配规则,在我的审美里,这笔复杂性债务应该尽早算清楚。
固定输出空间并非没有好处。维度已知,训练和部署都更容易安排,单个任务的实现也可以很干净。可如果我要讨论“基础模型”的接口,那么换任务时谁来支付改造成本,就不能一直留在模型定义之外。
当然,TabU 的动态接口也必须承担真实代价:类别支持从哪里来、候选集合多大、罕见类别如何估计,一个都不能靠“统一”两个字糊弄过去。
尤其是上下文里根本没有出现过的类别。把输出槽位做成动态,并不会凭空生出关于这个类别的证据。模型需要什么支持信息、是否允许拒答、怎么校准不确定性,都得说清楚。我不能一边嫌别人的门小,一边把自己还没建好的门画得无限宽。
TabICLv2:为什么表格要先服从列位置的几何?
TabICLv2 论文把列按循环偏移组成三元组,例如 (j, j+1, j+3) mod m,其中 m 是列数;再经过列嵌入、行压缩和 ICL。这种重复特征分组有明确设计目的,论文也报告了收益。更丰富的先验、Muon 和 QASSMax 同样有实验支持。
但列摆在旁边,通常不代表它们在语义上更接近。
图像里的相邻像素,往往确实有局部关系。表格里的相邻列,可能只是某个人导出 CSV 时的顺手排序。年龄后面放收入还是邮编,通常不应该先决定哪些特征更有资格进入同一个局部交互单元。对于没有额外顺序语义的普通表格,我会对此非常敏感。
于是我会追问:为什么文件里的排列位置,要先获得决定局部交互的权力? 即使打乱和集成可以缓和这种依赖,我仍然更偏爱把应有的置换对称性直接落实到模型定义里。
说得更具体一点:如果我把整列及其对应信息一起换位置,模型对同一个问题的回答应该怎样变化?如果是单个目标预测,我希望答案保持一致;如果读出的是按列组织的状态,我希望输出随对应列一起移动。不是拿掉一切列身份,而是别把偶然的存储顺序当作问题语义。
我承认,这种分组可能以很低成本改善表示。我的批评针对的是它引入了什么结构假设,以及这个假设在换列顺序、换表宽、换任务时要付多少代价。若某类表的顺序本来就有含义,那当然应该单独讨论,不能拿“表格”两个字抹掉真实结构。
而且 TabICLv2 的训练配方与消融,是我必须认真面对的门槛。QASSMax 处理的是长上下文下注意力的缩放问题;Muon 关乎优化;先验决定模型预训练时见到了什么样的任务。这些工作不会因为我的对象定义更整齐,就自动失去价值。
一个漂亮的 TabU,如果缺少同样扎实的先验和训练研究,照样可能输。公式的整齐,不能代替训练的功夫。
Xiaomi-TabLDM:设备越来越齐全,基本结构还要不要重新想?
双流分组、沿深度融合历史表示的 AttnRes、稀疏 MoE,再接行表示上的 ICL。官方仓库明确列出了 dual-stream feature grouping、lightweight Attention Residual 和 sparse Mixture-of-Experts。这些模块各自解决真实问题:交互覆盖、优化与表示复用、异质任务容量。
可放在一起,我会忍不住问一句:这份复杂性清单,什么时候算到头?
我希望每增加一个机制,都能解释清楚:它买到了什么能力,增加了什么成本,同预算下是否还有更简单的办法。尤其比较时,总参数、激活参数、显存、推理时间和集成都得一起算。
MoE 的总参数多,不意味着每个样本都付了同样多的计算;反过来,激活参数少,也不意味着端到端延迟和显存就一定低。缓存能加速后续预测,但首次构建缓存的时间和保存状态的空间不能消失。集成带来的分数提升也很好,只是不能把多次推理的收益当成单次推理的免费午餐。
我关心的不是把每一项都骂成“补丁”,而是把账放到同一张纸上。一个更复杂但同预算效果更好的系统,有资格赢;一个概念漂亮但实际更贵、更慢的模型,没有资格只靠审美领奖。
模块名单越来越长,本身不会让我更相信一个架构抓住了表格的本质。
当然,我也不能拿 OAttention 去冒充 AttnRes 或 MoE 的万能替代品。源资格、深度优化、条件计算是不同问题。允许哪些对象提供信息,并不自动回答如何更好地融合深层表示,也不自动给出专家路由和稀疏执行。
TabU 真想赢,就得证明统一结构能够减少实际需要的专门机制,而非只是把机制藏进一个更大的名字里。
LimiX-2M:这一个,我得骂得最认真
因为它确实碰到了我在乎的问题。
LimiX-2M 论文 §4保留单元格张量,用 RaBEL 改善数值表示,并通过“跨样本注意力 → 前馈网络 → 特征注意力”的顺序,让跨样本信息进入最终读出的特征表示。按论文 §4 的定义,这个顺序记作 S→N→F;这里的 N 是前馈网络,不是归一化。
RaBEL 也值得具体说一下。它不是只把一个标量乘上一个向量,而是先对数值进行逐列标准化和径向基函数展开,再通过共享线性投影与 LayerNorm 形成表示。论文认真研究了数值编码的表达能力,也研究了信息应该按什么顺序抵达读出端。这比简单增加容量更接近我的兴趣。
所以我不能把“过早压成行向量”这顶帽子扣给它。
我的追问会更进一步:当读出对象变成 Cell、Unit、Feature 时,各自的信息来源、接收身份和输出语义,能否由同一套规则清楚定义?
一个单元格的状态、一个 Unit 的状态、一个 Feature 的状态,并不是换三个标签就能互相替代。它们分别在表达什么?允许吸收哪些事实?在没有观测值时,又以什么身份参与计算?我希望模型定义能回答这些问题,而不是等到了每个任务的最后一层才临时解释。
为某一种终端安排一条有效的信息路径,是重要进步。我要追求的是,不同终端都能在一个清楚的对象体系里得到解释。
不过这里也轮到我接受审问:显式增加 Unit 和 Feature,究竟减少了多少特殊处理,又增加了多少状态与计算?如果最后只是多了几个名字、多存了几块张量,那我没有资格说自己更简单。
TabU:每一个漂亮概念,都必须兑现
我喜欢 Cell、Unit、Feature 有明确身份;喜欢事实、查询和结构空位有清楚边界;喜欢“在哪里提问”能够成为稳定接口;喜欢一个问题增加以后,不必无缘无故改变其他问题所依赖的事实计算。
事实是模型可以依赖的观测。查询表达我要问什么,但不能仅仅因为它占了一个位置,就被当作已经知道的答案。结构空位则不能悄悄冒充一个有数值、有证据的单元格。这些区别如果只存在于说明文档里,不存在于实际计算里,那我还是在自我感动。
这些性质要落实到编码、每一层更新、归一化、缓存和读出里。
举个我会反复检查的问题:在同样的已知表格上,我先放一个查询,再额外放一个查询。旧查询可以依赖的事实明明没变,但如果新增位置改变了某层的归一化分母,或者查询状态反过来污染了事实状态,那么“事实计算保持稳定”就未必成立。只在输入端区分身份是不够的,每一层都得守住自己声称的边界。
这也是缓存是否站得住的前提。我要复用一个事实表示,就得知道它依赖什么、什么时候失效。不能一边说“事实与查询解耦”,一边让查询集合的变化悄悄改写事实表示。
我不会把“写成零”自动算成省了计算。一个稠密注意力矩阵即使许多位置被 mask 掉,底层实现仍然可能执行了大部分稠密运算。真正省了多少,要看执行路径和测量结果。
我也不会把“没有行压缩”自动算成没有信息瓶颈。有限的隐藏维度、聚合操作、注意力路径,都可能形成瓶颈。保留了单元格位置,只能说明某种对象还在,不能说明所有信息都完好无损。
更不会因为查询接口统一,就宣布模型已经掌握所有任务。分类、回归、缺失值推断,乃至不同粒度的读出,仍然需要各自的训练支持、有效评测和误差分析。
我对自己,也应该比对这些模型更苛刻。
我可以为 120 张表兴奋,但不提前宣布胜利
这两天,TabU 在我实验中的 120 张表上都能够很好拟合。这件事让我非常兴奋:我开始看到,这套自己相信的结构确实能够学起来。
但我知道,这项结果支持的是当前实验条件下的拟合与可训练性。这里记录的是我的实验观察,不是一份已经公开完整协议、逐表指标与复现材料的 benchmark 报告。跨表泛化、未见数据集表现,以及面对成熟 TFM 时的效率和精度,还要另外拿证据。
我完全可以现在就为它骄傲,同时把胜负留给公平实验。
公平也得落到具体事情上。训练数据和预训练预算要交代,测试表是否见过要交代;数据切分、预处理、模型选择和调参预算要一致或明确披露。基线不能随手跑一个欠训练版本就算交差,TabU 也不能只挑一次幸运的随机种子。
如果我要说某个结构有用,就得做去掉它的消融。如果收益可能只是来自更多参数、更长训练或某个训练配方,就得用匹配预算的对照把它拆开。对于预训练或初始化带来的收益,也应有随机初始化对照,而不是把不同来源的增益全记在架构名下。
推理则要同时看首次处理和后续查询,区分单模型与集成,并报告显存、时间和实际任务规模。最后,所谓“更少特殊规则”,也不能只凭我自己数得开心。别人照着实现,究竟少写了哪些分支,遇到新类别、新目标、新表宽时少改了什么,应该能够指给人看。
我真正想争取的,是这样一个结果:在明确的训练与推理预算下,TabU 用更少的特殊规则,支持更广的查询,并取得更好的预测。
如果做到这一步,我当然愿意说:你们过去支付的某些复杂性,原来他妈的可以不用付。
我对这些模型最大的不服,就在这里:我想亲手证明,表格值得一个更简洁、更一致、也更有效的定义。
来源与版本说明
本文讨论的是以下公开版本和论文所描述的机制,不把某个版本的接口限制外推为整个模型家族的永久边界。架构审美与设计目标是我的判断;120 张表的拟合是我的实验自述,不是引用文献中的结果。
- TabPFN-3:技术报告,重点见 §2 的分阶段架构与 attention-based retrieval decoder。
- TabFM 1.0.0:官方 PyTorch 模型卡、Google Research 官方代码。十类限制指该版本分类检查点的输出类别数。
- TabICLv2:论文与消融。循环三元组按列数取模;本文对顺序假设的批评,不是否认论文报告的分组收益。
- Xiaomi-TabLDM:官方仓库与技术资料入口。本文不声称 OAttention 可直接替代其 AttnRes 或 MoE。
- LimiX-2M:论文,本文使用 §4 对 RaBEL 与模块顺序的定义。论文后续消融段落的缩写存在不一致,所以正文同时写明完整模块顺序,避免仅凭缩写产生误解。
三张图均为本文的概念示意,不是各模型的完整计算图,也不是 TabU 已完成能力的证明。