TabFM资料技术细节
P11 Technical Highlights · 02 · TabFM code reading

不减一列,为什么每个 token 却读了三列?

TabFM v1.0.0 不把 columns 切成互不重叠的三元组。它保留每一个原始位置作为 anchor, 再从本次 feature order 的环上读取 \(h\)、\(h+1\)、\(h+3\) 三个 source slots,分别编码后相加。 于是 token 数量不变,但每个初始 cell token 在进入后续 attention 以前,已经带上一小撮跨列上下文。

默认 group size\(G=3\)三个 slot,不是三列合成一个新列。
偏移\([0,1,3]\)来自 \(\delta_s=2^s-1\),不是普通连续窗口 \([0,1,2]\)。
shape\(H\rightarrow H\)临时多出 group axis,求和后 feature 位置数完全不变。
证据边界code-level mechanism公开材料没有证明这个 offset 公式最优,也没有单独 ablation。

最准确的一句话是:TabFM 以每个位置 \(h\) 为 anchor,在 active feature ring 上读取 \([h,h+1,h+3]\bmod d\),逐 source slot 做 typed Fourier encoding 与投影,再把三项相加成 anchor token。 它是一个 sparse circular stencil,不是降采样,也不是语义选邻居。

“邻近”只表示当前序列位置;feature permutation 改变以后,谁和谁被编成一组也会改变。

01 · FIRST REMOVE THE WRONG PICTURE

它没有把三列压成一列

真正变化的是每个 anchor 的感受野,不是输出 feature 数量。每个位置都生成自己的 overlapping group,所以输入有 \(H\) 个位置,输出仍有 \(H\) 个位置。

错误图像 · non-overlapping chunks

三列一包,包与包互不重叠

x₀x₁x₂ x₃x₄

这会减少位置数,而且每一列只属于一个包。TabFM 不是这样。

真实图像 · anchored overlapping groups

每个位置都锚定一组,位置数不变

x₀x₁x₃ x₁x₂x₄

\(x_1\) 等 source 会参加多个 anchor group,所以叫 overlapping。

\[ X\in\mathbb R^{B\times T\times H} \longrightarrow X^{\mathrm{grp}}\in\mathbb R^{B\times T\times H\times 3} \longrightarrow E\in\mathbb R^{B\times T\times H\times 256}. \]
02 · WALK AROUND THE FEATURE RING

从任意 anchor 出发,走 0、1、3 步

点击 anchor 看 group 怎样变化;再重排整组 columns,观察“邻居”怎样随 serialization order 改变。环形画法不是比喻:源码真的用 active feature count \(d\) 做 modulo wrap-around。

5-column grouping lab

当前:原始 column order

ANCHOR GROUPh=0 → 0,1,3
slot 0 · +0slot 1 · +1slot 2 · +3

这里把 column name 与 value 一起重排,表示合法的 feature permutation;只交换 value 而不交换其 feature identity 会是另一张表。

输出 anchor读取的 source positions当前 columns / values输出位置
03 · THREE SOURCES, ONE ANCHOR TOKEN

三路不是拼接,而是在 embedding 空间求和

slot identity 由频率库的第 \(s\) 行表达;同一种 feature type 的三个 slots 共用同一个 linear head。求和以后,group axis 消失。

精确机制 · 为清楚起见先写单一类型

令 \(\delta_s=2^s-1\),\(s\in\{0,1,2\}\),则 source index 为:

\[ q(h,s)=\bigl(h+\delta_s\bigr)\bmod d,\qquad \delta=[0,1,3]. \]

每个 source scalar 使用 slot-specific frequency row \(\Omega[s,:]\),经过同一个 linear projection \(W\) 后相加:

\[ \phi_s(v)= \left[\sin\!\bigl(v\Omega[s,:]\bigr),\; \cos\!\bigl(v\Omega[s,:]\bigr)\right], \qquad e_h=\sum_{s=0}^{2}\left(W\phi_s(x_{q(h,s)})+b\right). \]

因此第一维为 3 的 frequency bank 表示 group slot,不是 column ID;\(W\) 也不是三个 slot 各一套。

01 · INPUT[B,T,H]

每个 cell 是一个预处理后的 scalar。

02 · GROUP[B,T,H,3]

每个 anchor 读取三个 circular source slots。

03 · FREQUENCY[B,T,H,3,32]

每个 slot 使用 frequency bank 的对应行。

04 · SIN / COS[B,T,H,3,64]

32 个频率展开成 64 个周期 basis。

05 · LINEAR[B,T,H,3,256]

每个 slot 独立应用同一 type-specific head。

06 · SUM G[B,T,H,256]

三项相加;输出仍有 H 个 feature positions。

接近真实实现的伪代码JAX / PyTorch v1.0.0
# offsets = [2**s - 1 for s in range(3)] = [0, 1, 3]
group = [x[h], x[(h + 1) % d], x[(h + 3) % d]]
group_type = [cat_mask[h], cat_mask[(h + 1) % d], cat_mask[(h + 3) % d]]

cell = 0
for slot, (value, is_cat) in enumerate(zip(group, group_type)):
    omega = omega_cat[slot] if is_cat else omega_num[slot]
    linear = linear_cat if is_cat else linear_num
    phi = concat(sin(value * omega), cos(value * omega))
    cell += linear(phi)  # sum, not concat
04 · THE SOURCE SLOT CHOOSES ITS TYPE PATH

一组里可以同时混合 numerical 与 categorical

这是最容易在口头解释里丢失的细节:TabFM 对 cat_mask 做完全相同的 grouping,所以每个 source slot 根据自己的 source column 类型选路,而不是由 anchor 类型统治整组。

slot 0 · numerical\(x_h\)

使用 \(\Omega_{\mathrm{num}}[0,:]\) 与 \(W_{\mathrm{num}}\)。

+
slot 1 · categorical\(x_{h+1}\)

使用 \(\Omega_{\mathrm{cat}}[1,:]\) 与 \(W_{\mathrm{cat}}\)。

+
slot 2 · numerical\(x_{h+3}\)

使用 \(\Omega_{\mathrm{num}}[2,:]\) 与 \(W_{\mathrm{num}}\)。

完整 typed 公式
\[ \tau_{h,s}=\operatorname{type}\!\left(q(h,s)\right),\qquad e_h= \sum_{s=0}^{2} \left[ W_{\tau_{h,s}}\, \phi_{\tau_{h,s},s}\!\left(x_{q(h,s)}\right) +b_{\tau_{h,s}} \right]. \]

\((\Omega_{\mathrm{num}},W_{\mathrm{num}})\neq(\Omega_{\mathrm{cat}},W_{\mathrm{cat}})\);但每一对在同类型全部 columns 之间共享。slot-specific 的是 \(\Omega_\tau[s,:]\),不是额外的 column-specific 参数。

05 · WHY THIS IS INTERESTING

它像一层极小的、固定拓扑的早期 message passing

在第一层 attention 之前,每个 anchor token 已经从三个位置收集 value-dependent message。它以非常低的结构成本扩大初始感受野,但也把 column order 写进了表示。

Early context

孤立 scalar 先获得一点跨列上下文

某个值不再只由自己决定初始 token;后续 column / row modules 接到的入口已经带有稀疏交互。

Dilated stencil

三个点覆盖比 \([0,1,2]\) 更宽

\([0,1,3]\) 用相同 slot 数触达更远的位置,形态上类似小型 dilated pattern。

Shared parameters

不需要为每张表记住 column IDs

bank / head 按 type 与 slot 共享,因此机制能跨不同 feature counts 和 schemas 复用。

不是 semantic neighborhood

模型不知道“年龄应该看工龄”

它只按当前 order 机械取位置。一个看起来合理的组可能只是恰好出现,不是 schema-aware retrieval。

不是完整 interaction layer

三路求和会丢失部分可分辨信息

slot-specific frequencies 帮助区分来源角色,但最终仍压成一个 256 维和;完整全列交互仍交给后续 attention。

\[ \text{更像 sparse circular message aggregation,} \quad \text{而不是标准 convolution、semantic graph 或 column attention。} \]
06 · ORDER SENSITIVITY AND THE OUTER ENSEMBLE

单次 forward 不具备 column-permutation invariance

feature order 一变,ring 上的 \(h+1\) 与 \(h+3\) 就换人。官方 sklearn wrapper 默认用多个 feature permutations 建立 ensemble,降低对单一排序的依赖;这是一种有限平均,不是把单个 forward 变成严格不变量。

Inside one ensemble member

grouping 明确依赖本次排列

同一张表经 permutation \(\pi\) 后,模型在 \(X^\pi\) 的位置环上重新取 \([h,h+1,h+3]\)。cat mask 也同步重排。

\[ X^\pi_h=X_{\pi(h)},\qquad q^\pi(h,s)=(h+\delta_s)\bmod d. \]
Outside the model

默认 estimator 对多种排列做平均

classifier / regressor 默认 \(n_{\mathrm{estimators}}=32\)、feat_shuffle_method="random"。这能缓和顺序偶然性,但有限 ensemble 一般只能给近似稳定性。

\[ \widehat f_M(X)=\frac1M\sum_{m=1}^{M}f\!\left(P_mX\right). \]
不要混淆两种 permutation

feature permutation ≠ categorical relabeling

前者重排 columns 及其 mask;后者重映射某一类别列内部的 integer codes。TabFM 两者都有独立开关,本文讨论的是前者。

07 · MODULO HAS AN EDGE CASE

列很少时,三个 slots 可能撞到同一列

\([0,1,3]\) 会对 active feature count \(d\) 取模。只有当 residues 不重复时,三个 slots 才来自三列;小表中可能重复读取同一 source。

选择 active feature count \(d\)

\(d\)\([0,1,3]\bmod d\)对任意 anchor 的相对读取解释
1[0,0,0]同一列三次三个 slot 全部碰撞。
2[0,1,1]anchor 一次,另一列两次slot 1 与 slot 2 读同一 source,但用不同 frequency rows。
3[0,1,0]anchor 两次,下一列一次offset 3 回到 anchor。
4+[0,1,3]三个不同 positions仍会在行尾 circular wrap-around。

当 batch 中不同成员 padding 到同一宽度 \(H\) 时,源码按每个成员自己的 active \(d\) 回绕;padding positions 最后会被清零,不参与有效 attention。

08 · WHAT SHOULD P11 TAKE FROM THIS?

最值得吸收的不是固定 offset,而是“何时注入跨列上下文”这个问题

P11 当前主线追求 description-derived feature identity 与单次 forward 的 column symmetry。TabFM grouping 提供了一个强候选,也暴露出与 P11 设计原则的真实张力。

Ablation 1

孤立 value vs 早期 group

比较 \(G=1\)、\([0,1,2]\)、\([0,1,3]\);看收益来自“多读两列”还是特定 dilation。

Ablation 2

单次 symmetry vs permutation ensemble

分别测一次 forward 的 exact equality、有限 \(M\) 的 variance,以及 ensemble 成本。

Ablation 3

位置邻居 vs semantic neighbor

用 feature-description similarity 选择 sources,比较固定 ring 是否只是廉价 proxy。

Adoption boundary

这不是 P11 已采用的模块

P11 的默认 evidence encoder 仍以 position-free Transformer + symmetric pooling 为核心。若直接加入 order-dependent grouping,必须重新声明 symmetry contract,不能一边用它、一边继续声称单次 forward 严格 column-permutation invariant。

09 · PRIMARY-SOURCE EVIDENCE

代码告诉我们机制;没有公开报告替我们证明选择

本文核对的是 Google Research TabFM 仓库 commit b8a8b090… 的 v1.0.0 JAX 与 PyTorch 实现。官方 README 当前明确没有 technical report。

Not established

不能从代码推出

  • \([0,1,3]\) 已被证明优于其他 offsets;
  • grouping 是 TabFM 性能的主要来源;
  • finite permutation ensemble 保证严格 invariance;
  • position neighbors 在语义上天然相关;
  • P11 应当直接照搬这个模块。