MINI-TABPFN COURSE · LESSON 04

第 4 课讲义:Row Token——怎样把一行 feature states 变成可比较的对象?

这是一节可直接阅读、实现和验收的课程单元。页面正文由 canonical Markdown lesson source 投影生成。

第 04 / 08 课course-v0.5 / owner-review完整讲义 + 动手验收包
课程讲义 · 基础知识层canonical source: course/lectures/04-row-token.md · 先建立概念、符号、公式与边界,再进入工程实现。

讲义定位

前一课得到的是每个 cell 的 contextualized state;但预测通常需要以 row 为单位读取 context 或输出 query 结果。这一课对应 TabPFN-3 Stage 2: Feature aggregation (row-wise)

核心直觉:一行压成固定维向量,才能让后续 ICL 只随行数缩放。关键问题是:如何把 \(P\) 个 feature state 聚合成一个 row token,并明确顺序性质与信息损失?

与 TabPFN-3 Stage 2 对齐 / Mini 省略:官方用 \(C_{\mathrm{cls}}=4\) 个 CLS、non-causal row attention、 可选 RoPE,并 flatten 得到 \(D_{\mathrm{row}}=128\times 4=512\)。Mini 可无 RoPE、可用更小的 \(C_{\mathrm{cls}}\),须标注。Mean pooling 是对照基线,不是官方主路径。

1. 学习目标与先修知识

学完后你应该能够:

  1. 区分 cell state、feature token 和 row token;
  2. 解释 permutation invariance / equivariance 与 schema、RoPE 的关系;
  3. 比较 mean、single-CLS、multi-CLS,并写出官方主路径的 \(D_{\mathrm{row}}\);
  4. 写出 row aggregator 的 exact shape contract;
  5. 用 permutation、missing、padding audit 检查实现;
  6. 说明压缩损失为何仍值得换取「ICL 只随 \(N\) 缩放」。

本课符号:\(B\) batch,\(N\) rows,\(P\) features,\(D\) cell 宽, \(C_{\mathrm{cls}}\) = CLS 个数(不是类别数 \(C\)),\(D_{\mathrm{row}}=C_{\mathrm{cls}} D\)。

2. 为什么需要 Stage 2

Column encoder 之后:

\[H_{\mathrm{cell}}\in\mathbb{R}^{B\times N\times P\times D}\]

若直接在 cells 上做 ICL,序列长随 \(N\cdot P\) 增长。Stage 2 把每行压成固定宽度,使 Stage 3 序列长 只随 \(N\):

  • Stage 1:cell 在列分布中的意义;
  • Stage 2:一行作为对象的固定表示;
  • Stage 3:用已标记行预测未标记行。

3. Row:集合、序列,还是带 schema 的对象?

若一行是无序集合,则期望:

\[\operatorname{RowToken}(x_1,\ldots,x_P) =\operatorname{RowToken}\!\left(x_{\pi(1)},\ldots,x_{\pi(P)}\right)\]

但表格常有 schema;官方 Stage 2 还可启用 RoPE,使 feature 顺序成为位置结构。因此不能默认 「表格天然无序」:须声明是否有 column identity、重排时 metadata 是否一起动、是否使用位置编码。

4. 三种聚合假设(canon §3.4)

4.1 Mean pooling(对照)

\[r=\frac{\sum_p m_p h_p}{\max\bigl(\sum_p m_p,\,1\bigr)}\]

简单、对顺序不敏感;高阶交互易被抹平。带 mask,禁止用裸 \(P\) 除 padding。

4.2 Single CLS

\[\left[\mathrm{CLS},h_1,\ldots,h_P\right] \longrightarrow \operatorname{RowTransformer} \longrightarrow \operatorname{output}[\mathrm{CLS}]\]

CLS 是可学习读取槽位,须经 attention 读 feature;不是魔法压缩器。

4.3 Multi-CLS(官方主路径)

\[[\mathrm{CLS}_1,\ldots,\mathrm{CLS}_{C_{\mathrm{cls}}},\,h_1,\ldots,h_P] \to\operatorname{RowTransformer} \to[\mathrm{CLS}_1,\ldots,\mathrm{CLS}_{C_{\mathrm{cls}}}] \to\operatorname{flatten} \in\mathbb{R}^{D_{\mathrm{row}}}\]

官方 feat_agg_num_cls_tokens=4embed_dim=128

\[D_{\mathrm{row}}=C_{\mathrm{cls}}\cdot D=4\cdot 128=512\]

这就是后续 icl_emsize。只保留 CLS 隐状态再拼接;feature 输出丢弃。Row 内 attention 禁止跨 row 混读。

Mini 简化:可用 \(C_{\mathrm{cls}}=2\) 或无 RoPE。官方 TabPFN-3(App.C):\(C_{\mathrm{cls}}=4\), use_rope=True

5. Shape contract

\[\operatorname{feature\_states}\in\mathbb{R}^{B\times N\times P\times D}\]

整理为 row sequence:

\[\operatorname{row\_sequence}\in\mathbb{R}^{(BN)\times(P+C_{\mathrm{cls}})\times D}\]

输出:

\[\operatorname{cls\_states}\in\mathbb{R}^{(BN)\times C_{\mathrm{cls}}\times D},\qquad \operatorname{row\_tokens}\in\mathbb{R}^{B\times N\times D_{\mathrm{row}}}\]

Mean 路径输出 \(\mathbb{R}^{B\times N\times D}\)。比较 pooling 时须固定最终 \(D_{\mathrm{row}}\) (或投影到同一宽度),否则宽度差会伪装成方法差。

6. 信息瓶颈

\[\mathbb{R}^{P\times D}\longrightarrow\mathbb{R}^{D_{\mathrm{row}}}\]

当 \(P D\gg D_{\mathrm{row}}\) 时压缩通常不可逆。价值在于:后续 row-level attention 的复杂度与 mask 只随 \(N\) 增长。须明确「哪些信息留给 ICL、哪些可在行内丢弃」。

7. Column order 与 row order

Column:无 schema 时测 \(R(X_{\pi})\mathrel{?=}R(X)\);有 schema/RoPE 时 raw permute 预期改变表示。 Row:aggregator 只依赖本行时,应有 row-level equivariance:

\[\operatorname{RowEncoder}\!\left(P_{\mathrm{rows}}X\right) =P_{\mathrm{rows}}\operatorname{RowEncoder}(X)\]

后续 ICL 对 row order 的性质须单独测,不能由本课外推。

8. 模块接口

class RowAggregator(nn.Module):
    def forward(
        self,
        feature_states: Tensor,  # [B, N, P, D]
        feature_mask: Tensor,    # [B, N, P], True = valid
        row_mask: Tensor,        # [B, N], True = valid row
    ) -> Tensor:
        # mean: [B, N, D]
        # multi-CLS: [B, N, C_cls * D] = [B, N, D_row]
        ...

row_maskfeature_mask 不同轴;CLS 位置不得被当成 padding feature 掩掉。

9. 公平比较

维度固定或记录
输入同 task、同 context/query split
宽度同一 \(D_{\mathrm{row}}\)
参数/计算aggregator + 下游;token 数与时间
行为column/row permute、missing、padding
下游同一 ICL + head

对照:mean(基线)vs single-CLS vs multi-CLS(对齐 \(C_{\mathrm{cls}}=4\) 的简化版)。

10. 可视化与课堂顺序

可视化检查 collapse、context/query 关系、扰动敏感性、CLS 是否盯 padding——不作因果证明。

  1. 手算 masked mean;2. 实现 CLS 并打印 shape;3. 同 split 比较 mean/CLS;4. 零值 vs missing;
  2. permute audit;6. 固定 \(D_{\mathrm{row}}\) 再比 multi-CLS。

11. 知识检查

  1. invariance 与 equivariance 的区别?
  2. 有 schema 或 RoPE 时为何不能声称列序无关?
  3. 为何 \(D_{\mathrm{row}}=C_{\mathrm{cls}} D\),且 \(C_{\mathrm{cls}}\) 不是类别数?
  4. 为何 row_mask 不能替代 feature_mask
  5. 压缩丢了什么,为何 ICL 仍需要它?
  6. 公平 mean/CLS 比较要固定什么?

12. 本课的硬结论

Row token 用固定宽度摘要换取后续只随行数缩放;aggregation、mask、\(D_{\mathrm{row}}\) 与置换性质须 单独测量。「有一个向量输出」不是正确性证明。课程主路径对齐 multi-CLS;mean 仅作对照。

HAND-ON LAB · 工程实现与验收包

第 4 课:从 Cell States 生成 Row Token

本课交付

本课把 \([B,N,P,D]\) 变成 row-level ICL 可消费的 \([B,N,D_{\mathrm{row}}]\),并让学习者看见 pooling 如何改变信息瓶颈。交付:

  • models/row_aggregator.py:mean、single-CLS、multi-CLS;
  • tests/test_row_aggregator.py:axis、padding、CLS 保留;
  • mean vs CLS 对照实验与 representation 图;
  • 一份声明 column-order / row-order / missing 性质的记录。

对应讲义:lectures/04-row-token.md(Stage 2;canon §3.4)。

项目问题

Column encoder 仍保存:

\[\operatorname{cell\_states}\in\mathbb{R}^{B\times N\times P\times D}\]

row-level ICL 的 token 轴应是 rows。一行的 \(P\) 个 feature states 经 row 内 contextualization 后留下 固定宽度表示。核心直觉:一行压成固定维,后续才能只随行数缩放。

\[[\mathrm{CLS}_1,\ldots,\mathrm{CLS}_{C_{\mathrm{cls}}},\,h_1,\ldots,h_P] \to\operatorname{RowTransformer} \to[\mathrm{CLS}_1,\ldots,\mathrm{CLS}_{C_{\mathrm{cls}}}] \to\operatorname{flatten} \in\mathbb{R}^{D_{\mathrm{row}}}\]

其中 \(D_{\mathrm{row}}=C_{\mathrm{cls}} D\)。官方 \(C_{\mathrm{cls}}=4\)、\(D=128\) 得 \(512\)。 Mini 默认可用 \(C_{\mathrm{cls}}=2\),须标注。row token 不是 persistent Unit identity。

3 小时课堂流程

时间内容证据
00:00–00:25cells 不能直接当 row-level tokens画出两种 token 轴
00:25–00:55mean / CLS / multi-CLS 与 \(D_{\mathrm{row}}\)写出输出 shape
00:55–01:35row transformer 实现处理 \(B\cdot N\) 个 row block
01:35–01:50padding 错误CLS 不被 feature mask 误伤
01:50–02:25pooling 对照同 \(D_{\mathrm{row}}\) 比 query loss
02:25–02:50顺序与敏感性审计column / row permute
02:50–03:00退出评审交付 row contract

1. 三种 aggregation

Mean(带 mask,canon §3.4)

\[r=\frac{\sum_p m_p h_p}{\max\bigl(\sum_p m_p,\,1\bigr)}\]

禁止用裸 \(P\) 把 padding 零向量算进平均。

Single CLS

拼接 learned CLS,Transformer 后取 CLS 输出。CLS 须经 attention 读 feature。

Multi-CLS

\(C_{\mathrm{cls}}\) 个 CLS → flatten 成 \(D_{\mathrm{row}}=C_{\mathrm{cls}} D\)。 注意:此处 \(C_{\mathrm{cls}}\) 不是类别数 \(C\)。Mini 第一版可用 n_cls=2;对照官方时写清 feat_agg_num_cls_tokens=4

Mini 简化:可无 RoPE。官方 TabPFN-3(App.C):use_rope=True

2. Exact module contract

class RowAggregator(nn.Module):
    def __init__(self, d_cell: int, n_cls: int = 2,
                 mode: str = "multi_cls"):
        ...

    def forward(
        self,
        cell_states: Tensor,        # [B, N, P, D]
        feature_valid_mask: Tensor  # [B, N, P], True = valid
    ) -> tuple[Tensor, dict[str, Tensor]]:
        # row_repr: [B, N, n_cls * D]  (== D_row when multi_cls)
        ...
rows = cell_states.reshape(B * N, P, d_cell)
cls = self.cls.expand(B * N, -1, -1)
sequence = torch.cat([cls, rows], dim=1)  # [B*N, C_cls+P, D]
# Row 内 attention:禁止跨 row 混读

feature_valid_mask 扩展:CLS 全 valid。注意 src_key_padding_mask 常为 True=padding

3. Column / row order:先声明再测量

  1. 交换列但不交换生成器语义,测 cosine / query loss;
  2. 交换 row 顺序:aggregator 只在行内工作时,row token 应按相同 permutation 重排。
\[\text{支持:batch/row 对齐;masked feature 不读入。}\]
\[\text{未承诺:column permutation invariance;跨 row exchangeability。}\]

有位置编码时,raw column permute 预期改变表示。

4. Guided lab:mean vs CLS

固定 task、cell embedder、预算;只换 aggregator;固定最终 \(D_{\mathrm{row}}\)(必要时投影):

\[\begin{array}{ll} \text{A:}&\text{masked mean}\\ \text{B:}&\text{single CLS}\\ \text{C:}&\text{multi-CLS flatten(}C_{\mathrm{cls}}=2\text{ 或 }4\text{)} \end{array}\]

记录:\(D_{\mathrm{row}}\)、query loss、wall time、单 cell 扰动距离、missing 性能。

5. Visualization

2D projection 或 pairwise distance:同/异 task;扰动前后。图旁写明距离在 learned representation 上, 不是 ground-truth identity。

常见失败

  • reshape 弄乱 \(N/P\) 轴;
  • CLS 被 feature padding mask 屏蔽;
  • mean 把 padding 算进平均;
  • 用跨 row attention 提前泄漏 context/query;
  • 把相似 row token 叫成「同一个 Unit」;
  • 把 \(C_{\mathrm{cls}}\) 与类别数 \(C\) 混用。

退出条件与评分

  1. mean / CLS / multi-CLS 至少两条可运行;
  2. \([B,N,P,D]\to[B,N,D_{\mathrm{row}}]\);
  3. feature padding 不破坏有效归一化;
  4. row permutation 对齐通过;
  5. 对照表 + representation 图;
  6. 写明未承诺的 invariance。

评分:shape/mask 25%,aggregation 25%,对照 30%,边界 20%。

课后作业

实现 gated pooling,与 mean/CLS 比较;gate 权重只作 routing diagnostic,不作 causal contribution。