三分钟版本
- 问题:Transformer 在两个方向上算东西——横着跨 token,竖着穿层。横向靠注意力,带宽是满的;纵向的跨步反馈却极窄:每步只有采样出的那一个 token 回到栈底,顶层状态直接丢弃。
- 做法:把上一步的顶层隐藏状态 \(\mathbf{h}_{t-1}^{L}\) 和这一步采样 token 的 embedding 用一个门控线性单元(GLU)融合,作为下一步的输入。架构、KV cache、训练目标全都不变,只改"输入怎么拼"。
- 代价:每生成一个 token 多两次 \(D\times D\) 矩阵乘,<1%。serving 侧 prefill 跑一遍或两遍(评测时还可以多跑几趟当作 prefill 阶段的 test-time scaling)。
- 训练:这个递归在位置上是串行的,会毁掉 teacher forcing 的并行性。论文用多趟(multi-pass)近似:每趟把上一趟的隐藏状态右移一位、融合、整条序列并行重跑。串行代价从"序列长度"降到"趟数 k"。
- 结果:1B 模型训到 400B token,潜在反馈解码在 GSM8K / MATH-500 / HumanEval / MBPP 上全面优于同权重的标准解码,大致相当于多训 1.5–2 倍数据的标准 Transformer;某些任务接近多训 5 倍数据的基线。基座模型上推理链还变短了。
- 机制证据:用线性探针测量——一步递归 prefill 后,全局状态在第 0 层就能被线性解码出来(\(99.6\% / 100\%\)),而标准 prefill 在第 0 层接近随机。作者也诚实地指出:可解码 \(\ne\) 被使用。
一个被浪费的信道
先把自回归解码当成一个通信问题来看,而不是当成"生成文本"。
第 \(t-1\) 步,模型把整个上下文送进 \(L\) 层堆栈,在顶层得到一个 \(D\) 维向量 \(\mathbf{h}_{t-1}^{L}\)。这个向量里装着模型这一步所有的"想法":它对下一个词的完整概率倾向、它对当前算到哪一步的判断、它的不确定性、它的半成品中间结果。
然后我们做了什么?把它乘以 \(\mathbf{W}_{\mathrm{head}}\) 投影到词表上,采样一个 token,把这个 token 的 embedding 当作下一步的输入。\(\mathbf{h}_{t-1}^{L}\) 本身被丢弃——它是唯一一个连 KV cache 都不存的状态。
从信息论角度,这个反馈信道的容量上界是 \(\log_2 |V|\) 比特。论文用的模型词表 100,352,也就是每步大约 16.6 比特。而那个被扔掉的向量,光是它的物理表示就有 \(1536 \times 16 = 24{,}576\) 比特。
拖动滑块看看两条通道的宽度差。左边是"每步真正回到栈底的信息量",右边是"被丢掉的那个向量的物理宽度"。注意纵轴是对数刻度——否则左边那根柱子会细到看不见。
1479× 是信道宽度之比,不是"信息量"之比。论文自己在 3.2 节讲得很清楚:\(\mathbf{z}_{t+1}\) 是 \(x_{1:t+1}\) 的确定性函数,它不携带上下文里没有的任何信息——KV cache 里本来就有全部历史。
所以增益不是信息上的,是计算上的("the gain is computational, not informational")。这句话是理解整篇论文的钥匙:真正的瓶颈不是"信息丢了",而是"信息在错误的深度上,够不着"。下一节讲这个。
"深度冻结":信息还在,但够不着
论文提出一个很好用的二分法:
- 水平轴(跨位置):稠密注意力让第 \(\ell\) 层的当前 token 能读到所有历史位置在第 \(\ell\) 层的表示。这条轴是满带宽的。
- 垂直轴(跨深度):\(\mathbf{h}_{t}^{\ell}\) 读不到任何 \(\ell'\) \(\ge\) \(\ell\) 的历史状态。第 3 层永远读不到历史 token 的第 20 层。
用集合写出来,标准 Transformer 在计算位置 \(t\)、层 \(\ell\) 时能够到的历史状态是:
注意那个 \(\ell'\lt\ell\)。它的后果是:一个在第 20 层算出来的结论,永远不可能回到第 0 层被重新加工。它被"冻结"在产生它的那个深度上,只能被更上面的层读取。论文把这叫 depth-frozen。
那模型怎么办?只有一条路:把它说出来。链式思维(CoT)之所以有效,本质上就是把中间状态外化成语言,然后下一步从头把它读回来。代价是这个外化过程要经过那个 16.6 比特的瓶颈,而且每个中间结果都要占掉一个 token 的位置。
而潜在反馈把可达集扩成:
\(\ell\) 从可达集里消失了。每一层,包括最底下那层,都能看到被完整堆栈处理过的历史。
每一列是一个 token,每一行是一层。点击(或悬停)任意格子,把它当成"正在计算的状态",网格会高亮它能读到的历史状态。用上面的开关切换两种模式,看可达集怎么从三角形变成矩形。

论文 Fig. 1(原图)。左:标准解码里,当前状态只能读到历史 token 的更低层状态(蓝色实心),更深的历史状态(白色空心)不可达,唯一的跨步反馈是那个绿色六边形——采样 token 的 embedding。右:全带宽 Transformer 把上一步的顶层状态通过一个保维度的门(\(\otimes\))和 token embedding 融合后送回输入端,于是整列历史状态全部变成可达。
值得注意的是,\(\ell'\lt\ell\) 这个约束正是 Transformer 能并行训练的原因:串行依赖只存在于层与层之间,不存在于 token 与 token 之间。但论文指出:解码时本来就已经是串行的了,这个约束在推理阶段什么好处也没换来——白白亏了。这就是整篇论文的动机缺口。
方法:一个门控,两个矩阵
改动小得有点不像话。标准解码是:
潜在反馈解码只把输入换掉:
那个 \(\otimes\) 是门控线性单元:
就这两个 \(D\times D\) 矩阵,是整个方法新增的全部参数。对 1B 模型来说是 \(2 \times 1536^2 \approx 4.7\mathrm{M}\),占比不到 0.5%。
为什么是"隐藏状态走值通路、token 当门"?
这个不对称是刻意的,也是论文里我最喜欢的一个设计论证。
假如你用对称的融合,比如 \(\mathbf{e}_t+\mathbf{W}\mathbf{h}_{t-1}\),那模型有一条捷径:把 \(\mathbf{W}\) 压到 0,输入就退化成纯 token embedding,模型立刻回到普通 Transformer,损失也回到预训练时的低点。梯度下降会毫不犹豫地走这条路——尤其当训练是从一个标准预训练 checkpoint 热启动的时候,那个低损失就摆在旁边。宽信道会被建好然后闲置。
门控版本把这条路堵死了:\(\mathbf{h}_{t-1}\) 在值通路上,把它丢掉等于把输入整个丢掉(输出直接变成 0)。token 的身份信息只能存活在它施加给状态的那个 \(D\) 维门控图样里。读状态从"可选"变成了"强制"。
下面是一个 16 维的玩具版本。左边是上一步的隐藏状态(走值通路),中间是 token embedding 经过 sigmoid 后的门(0 到 1),右边是融合结果。用"抑制状态通路"滑块模拟训练中"把状态权重压小"的行为,看两种融合方式的结局有多不同。
推理时几乎不要钱
\(\mathbf{h}_{t-1}^{L}\) 在标准解码里本来就算出来了(要拿它过 lm_head 采样)。所以额外开销只有那两次矩阵乘——相对于跑一遍 \(L\) 层堆栈可以忽略,论文说 <1%/token,而且这个开销与上下文长度和模型深度无关。
因为融合保维度,KV cache 布局、注意力实现、serving 栈统统不用改。论文还给了 vLLM 上的实现思路:像 EAGLE / MTP 那样,给每个请求留一个固定地址的 buffer 存最新的顶层状态,下一个 decode step 之前原地拷进去,这样 CUDA graph 还能把门控捕获进 forward 里。区别在于 EAGLE/MTP 把状态送给一个独立的草稿模型,而这里是喂回自己,并且直接定义真正的下一 token 分布。
解码循环的伪代码(论文 Fig. 2 右)——只差一行
h = model(embed(prompt)) # prefill
# h = model(glu_cross(shift_right(h), embed(prompt))) ← 打开这行就是 Fused
tok = sample(lm_head(h[-1]))
h_prev = h[-1]
while not done:
x = glu_cross(h_prev, embed(tok)) # ← 唯一的改动
# 标准解码:x = embed(tok)
h_prev = model_step(x, kv_cache)
tok = sample(lm_head(h_prev))和 CoT 是什么关系?
论文把两者都写成 MDP 的转移,对比就很清楚了:
\(s_{t+1}=s_t\mathbin\Vert a_t\)
跨步只有离散动作序列。真正的"解题状态"原则上是历史动作的确定性函数,但从 token 历史里恢复它本身就是一个状态追踪问题,而固定深度的 Transformer 每次前向只有有限的串行计算量。CoT 的解法是把状态写出来。
\(s_{t}\) = (\(a_{1:t}\), \(\mathbf{z}_{t}\))
只有 \(\mathbf{z}_{t}\) 作为递归变量在传——历史的 \(\mathbf{z}_{1:t-1}\) 已经折进了 KV cache(因为它们参与构成了那些位置的输入 \(\mathbf{u}\))。唯一 cache 不存的就是最新那个。
作者特别澄清了两件它没做到的事,这段很值得读:
- 不是可变寄存器。RNN / SSM 每步覆写一个压缩状态;这里历史状态全都留在 KV cache 里没被覆写,当前 token 依然能直接读到每一个早期状态。它是"递归的形式",不是"递归的信息瓶颈"。
- 解码时的渐进深度没有增加。有没有潜在反馈,每步都是 \(O\)(\(L\)) 深度的图,\(T\) 个 token 就是 \(O\)(\(\mathrm{TL}\))。变的是路径的带宽:现在有一条离散的语言信道和一条连续信道并行演化。(prefill 阶段多跑几趟倒是真能加深度。)
真正的难点:怎么并行地训一个循环
方法本身两行代码,麻烦全在训练。
两个坎:(1) 预训练模型从没见过"输入槽位里塞隐藏状态",所以推理时不能直接打开开关(论文只说"cannot simply be switched on",没有给出失败样例);(2) 式 (3) 定义的递归在位置上是串行的——位置 \(t\) 的输入要等位置 \(t-1\) 的完整前向跑完。直接照着训,就等于放弃了 teacher forcing 的并行性(论文没有量化,但按 8192 的上下文粗算,串行步数要涨三四个数量级)。
多趟近似(temporal parallelism)
论文的解法是把"沿位置的串行"换成"沿趟数的串行":
每一趟做的事就三步:把上一趟的隐藏状态整体右移一位 → 和 token embedding 融合 → 整个堆栈在所有位置上并行重跑一遍。因为它需要的所有状态都在上一趟算完了,所以趟内完全并行。
这在数值分析里叫 Jacobi 迭代:不等前一个位置收敛,直接用上一轮的值同时更新所有位置。关键性质是:\(k\) 趟能训练出 \(k-1\) 步的反馈视野(位置 \(t\) 的状态能影响到位置 \(t+k-1\) 的输入),代价是大约 \(k\times\) 的计算量。
点"下一趟"逐步推进。每一行是一趟前向,每一列是一个位置。灰色 = 纯 token embedding,蓝色 = 融合了上一趟状态的输入。橙色箭头显示状态是怎么斜着右移一位传下去的。打开 prefix mixin 看训练时怎么模拟"提示词是纯 embedding、生成部分是融合输入"的推理分布。
损失是每一趟的输出都算标准的 next-token-prediction,加权求和(论文里 \(\lambda\) = 1,没调):
两个细节值得注意:保留第 1 趟的损失,因为推理时提示词就是靠这个无反馈模式处理的;不 detach 梯度,所以后面趟的损失会反传进前面趟的隐藏状态里——这带来了一个副产品,下面会讲。
调度:什么时候、加几趟
每多一趟,整个训练 run 的成本就乘一次。所以论文用了一个渐进调度:绝大部分训练是普通单趟目标(这也让 run 可以从一个标准预训练 checkpoint 起步),只在训练中后期掺入两趟批次,再掺一点点三趟批次。
| Run | 反馈趟数混合 | 训练 token | 等效计算量 |
|---|---|---|---|
| 10B | 100% 三趟 | 10B | 40B * |
| 100B | 75% 一趟 / 25% 三趟 | 100B | 150B |
| 200B | 75% 一趟 / 22% 两趟 / 3% 三趟 | 200B | 256B |
| 400B | 75% 一趟 / 22% 两趟 / 3% 三趟 | 400B | 512B |
* 按论文自己的定义(训练 token × 每批平均前向次数),100% 三趟应为 30B;表中写的是 40B。这里照抄原文,读者知道有这个出入即可,其余三行都能对上。
那 3% 是整篇论文最有意思的实验
推理时反馈循环要展开成百上千步,远超训练见过的趟数。所以问题变成:学到的这个映射,反复自我复合会不会炸?
只用一趟+两趟批次训练(75/25)的模型,在训练深度内表现正常,但一旦往外推——验证损失暴涨,隐藏状态的变化量 \(\lVert\mathbf{h}^{(k)}-\mathbf{h}^{(k-1)}\rVert\) 开始剧烈震荡,说明迭代已经跑出了训练时的状态分布。
掺入 3% 的三趟批次(75/22/3),行为定性地改变了:验证损失在 30 步反馈内完全平坦,状态变化量单调衰减到一个小平台。学到的映射从"发散"变成了对某个不动点的收缩映射。附录里做到 1000 趟依然稳定。
这是一个示意性的迭代映射玩具,用来建立直觉:拖动"三趟批次占比",看轨迹从震荡不收敛变成衰减到平台。真实曲线在下面的论文原图里——注意原图右图纵轴是对数刻度,绿线(无三趟)在 10⁻¹ 到 10¹ 之间反复横跳,紫线(有 3% 三趟)直接掉到一条水平线上。

论文 Fig. 3(原图)。左:验证损失随反馈趟数的变化。绿线(75% 一趟 + 25% 两趟)在超出训练深度后损失直接飞到 9 以上;紫线(掺 3% 三趟)在放大图里可以看到损失甚至先降后平,稳在 2.45 左右。右:隐藏状态变化量(对数轴),绿线震荡,紫线单调衰减到平台——这就是"收缩映射"的实验签名。
另外三个稳定性配方
为了让反馈映射在长程自我复合下不跑偏,论文还叠了三个小技巧。这些细节在复现时大概率是必需的:
- 让顶层状态的尺度平稳。用 depth scaling 让 \(\lVert\mathbf{h}^{L}\rVert\sim O(1)\) 而不是标准 pre-norm 里可能出现的 \(O(L)\);融合后的输入再过一次 RMSNorm。
- 共享输入基底(权重绑定)。模型要吃两种输入:纯 token embedding(prefill)和融合输入(反馈解码)。把 embedding 层和输出头权重绑定,能让这两个空间待在一个兼容的基底里,省得融合矩阵去学一个大的旋转矫正。
- 噪声正则。训练时给被携带的隐藏状态加均匀抖动 \(\varepsilon \sim U[-\sigma,\sigma]^D\)(实验里 \(\sigma\) = 0.02),让反馈映射见过每个训练状态周围的一小片邻域,从而对长程累积的小偏差不敏感。
多趟目标还顺手当了一个表示层面的辅助监督。标准 NTP 里,\(\mathbf{h}_{t}^{L}\) 只通过"预测下一个 token"被监督一次。在后面的趟里,它会被右移、融进后续位置的输入,然后通过因果注意力影响多个未来位置的损失。梯度从这些未来预测反传回来,逼着 \(\mathbf{h}_{t}^{L}\) "作为输入是可复用的",而不只是"作为输出是可预测的"。
实验证据是:即使推理时完全不开潜在反馈,用这个目标训出来的模型在 LM Eval 和自由生成上也比纯 NTP 基线好。也就是说,你可以只把它当成一个"花训练算力买表示质量"的方法,serving 栈一行都不用改。
实验:它到底有没有用
全部实验都是 1B 参数的 decoder-only 模型:24 层、\(D\) = 1536、词表 100,352(输入输出权重绑定)、6656 维 SiLU-GLU FFN、GQA(16 个 Q 头 / 8 个 KV 头)、QK RMSNorm、RoPE、8192 上下文,大部分层用 2048 的滑动窗口、每第 6 层用全注意力。数据用 Phi-4 的混合配方。
论文对比三种解码模式(注意:同一份权重,只是推理方式不同):
- Std.(标准):单趟 prefill,生成时只用 token embedding。等于把全带宽模型当普通 Transformer 用——这一栏衡量"训了潜在反馈但不用,亏不亏"。
- Soft(软解码):单趟 prefill,生成时开潜在反馈。prefill 成本和 Std. 完全一样,每 token 只多两次矩阵乘。
- Fused(融合):提示词先多跑一趟融合 prefill,再按 Soft 生成。prefill 翻倍,但 prefill 是并行的,每 token 解码成本不变。
结果一:prefill 多跑几趟,白拿 2× 数据效率

论文 Fig. 4(原图)。横轴是 prefill 时施加的反馈趟数(0 = 普通 prefill)。左:验证损失;右:10 个任务上的 5-shot LM Eval 平均准确率(RTE、TruthfulQA-MC2、ARC-E/C、BoolQ、PIQA、WinoGrande、OpenBookQA、COPA、MMLU)。彩色虚线是同规模的标准 Transformer 基线,黑色虚线是 1T token 的标准基线。
三个观察:
- 增益是前置的。绝大部分提升来自第一趟融合 prefill——也就是顶层状态第一次出现在输入端的那一趟。之后继续加趟数还有效,但边际收益迅速衰减。这和"潜在反馈相当于给提示词加了有效深度"的解释是一致的:一旦全栈状态暴露给了第 0 层,最大的那块收益就已经拿到了。
- 不用它也不亏。在第 0 步(当普通 Transformer 评估),全带宽模型的验证损失只比标准基线差一点点,而 LM Eval 平均准确率已经更高了。
- 一点点 prefill 算力 \(\approx\) 两倍预训练数据。两趟反馈下,100B 的全带宽模型追上 200B 的标准基线,200B 的追上 400B 的。
横向对比同量级开源模型(0-shot),200B token 的全带宽模型(1 趟反馈)平均 53.58,高于 TinyLlama-1B(2T token,53.23)和 EvoLM-1B 全系列,离 Llama-3.2-1B(9T token,55.31)还有约 1.7 分,离 Qwen3-1.7B(36T token,57.30)更远。论文自己的说法比较克制:“与同等或更大训练预算的模型持平或更好”。数据配方不同,这里只能当粗略参照。
结果二:自由生成上,同一份权重换个解码方式就变强

论文 Fig. 5(原图)。实线是全带宽模型(橙 100B、绿 200B、紫 400B)在三种解码模式下的表现,虚线是同色的标准 Transformer 基线,黑虚线是 1T token 的标准基线。
- Soft 几乎在每个任务上都优于 Std.(论文原文说"每个",400B 的 Math500 是个例外,见下方读图提醒)——模型权重完全不变,纯粹靠改解码方式拿到的。
- 该用哪种模式看任务:数学题上 Soft 增益最大,代码题上 Fused 最强(HumanEval 0.31 → 0.34,MBPP 0.38 → 0.40,都能在图里读出来)。作者的解释很自然:代码奖励"对提示词的深层理解",数学奖励"把状态一路带着走"。
- 200B 的全带宽模型在潜在反馈下接近或超过训了 2–5 倍token 的标准基线。
- Pass@3 和 Pass@1 同步提升,说明条件化在隐藏状态上没有把采样多样性压塌。
论文正文写 "on Math500 the 200B model improves from 0.27 to 0.37, surpassing even the 1T no-recurrence baseline",但上面这张图(Fig. 5)里,200B 的绿线在 Math500 上是 \(\approx\)0.44 → \(\approx\)0.49,而 1T 黑虚线在 \(\approx\)0.565,并没有被越过。正文这句数字大概率是早期版本没随图更新,读图为准。
同样地,正文说 "Soft 在每个任务上都优于 Std.",但 Fig. 5 里 400B 紫线在 Math500 上 Soft 反而略低于 Std.,指令微调后的 Table 1 也是(46.00 vs 45.40)。更准确的说法是:100B / 200B 两个规模上 Soft 全面优于 Std.,400B 上有一个例外。
结果三:过了指令微调依然成立
200B / 400B 模型又做了长上下文扩展(12B token,8K→32K)和指令微调(6B token)。因为这两个阶段比预训练短得多,全程用三趟训练而不是预训练那个调度。评测不给 few-shot 示例。
点任务名切换,柱状图会画出 6 个配置的对比;三条虚线是标准 Transformer 在 200B / 400B / 1T token 上的成绩。加粗的是每个训练规模内最好的解码模式。
数学任务报 Pass@1,代码任务报 Pass@3(10 次 rollout 估计,温度在 {0.3, 0.5, 0.7} 中逐设置网格搜索)。单位为百分数。
值得单独指出的是 MBPP 上 Fused 拿到 41.22 / 41.70,而 1T token 的标准基线是 41.93——用 200B–400B 的数据基本追平了 1T。
一个漂亮的副作用:推理链变短了
如果"计算可以骑在隐藏状态上走"这个说法是对的,那就有一个可证伪的预测:模型不需要把那么多中间步骤说出来了。
基座模型上确实观察到了。Math500 上,Soft / Fused 解码的中位推理长度从约 500 token 降到 460–485,准确率持平或更好(Soft 从约 0.41 升到约 0.45,Fused 基本持平)——论文摘要的措辞就是 "at equal or better accuracy"。
一个具体例子(贪心解码,两边答案都对):
首先,列出除式:137 ÷ 500
由于 137 小于 500,展开将以 0 开头。[省略 326 个 token 的长除法过程]
由于余数现在是 0,137/500 的十进制展开是:0.274
小数点右边最后一个非零数字是 4。
137/500 = 0.274
小数点右边最后一个非零数字是 4。
论文 Fig. 8,题目:What is the last nonzero digit to the right of the decimal point in the decimal expansion of 137/500?
作者的解释我觉得很有说服力:微调数据相对潜在反馈解码是 off-policy 的。那些目标轨迹是标准逐 token 推理产生的,本身就模仿了那种啰嗦风格;去拟合它们,等于把"全部说出来"的习惯重新灌回去,跟隐藏状态能不能承载中间结果无关。
言下之意是:要保住简洁性,得做潜在反馈下的 on-policy 后训练(比如 RL)。论文把这个留给了未来工作——我觉得这是本文最值得跟进的一个坑。
机制可解释性工具箱:论文是怎么"看见"带宽变宽的
这一节先补背景,再讲论文的实验。因为最后那个探针实验设计得非常干净,值得完整理解。
7.1 残差流:Transformer 内部的那条总线
理解现代可解释性工作,第一个要装进脑子的图景是残差流(residual stream)视角。
标准的画法是"输入过 Attention,再过 MLP,一层一层往上"。残差流视角把它翻过来看:有一条贯穿全深度的 \(D\) 维向量总线,从 token embedding 开始;每个 attention 头和每个 MLP 都是挂在这条总线上的模块,它们从总线上读(通过各自的输入投影),算完之后把结果加回总线(残差连接)。
因为残差连接是加法,所以第 \(\ell\) 层的残差流可以精确写成 "embedding + 前面所有模块输出之和"。这让你可以问一些很具体的问题:某个信息是哪个模块写进总线的?哪个头把它读走了?这就是 "QK 电路 / OV 电路"、"归纳头(induction head)"这些概念的出发点。
论文里说的"顶层隐藏状态 \(\mathbf{h}^{L}\)",就是这条总线在最顶端的取值;说的"第 0 层输入",就是总线的初值。潜在反馈干的事,本质上是把总线的终点接回起点。
7.2 线性探针:怎么判断"信息在不在里面"
线性探针(linear probe)是最简单也最常用的一把尺。做法:
- 造一批输入,每条有一个你关心的标签(比如"这个计数器完成了没有")。
- 把这批输入喂给模型,在某一层、某个 token 位置把残差流向量抠出来。
- 用这些向量训一个线性分类器去预测标签,在留出集上看准确率。
为什么必须是线性的?因为如果允许用一个 MLP 去探测,那探针自己就可能把答案"算"出来,而不是"读"出来——一个足够强的探针能从几乎任何表示里榨出信息,结论就没意义了。限制成线性,测的才是"信息以线性可读的形式存在于这个方向上",而这恰好是下游那些线性读出(注意力的 Q/K/V 投影、lm_head)能利用的形式。
陷阱一:探针可能在作弊。如果训练和测试集共享表面模式,探针可能记住的是无关的统计相关性。标准对策是分组交叉验证——论文正是这么做的:完成度追踪任务按"数字对"整组留出,记忆任务按"scratch 上下文"整组留出,让探针没法靠记住具体样例过关。
陷阱二:可解码 \(\ne\) 被使用。这是最重要的一条,论文自己也专门写了一段(见 7.5)。
顺带认识几件常用工具
- Logit lens / tuned lens:把中间层的残差流直接乘上输出头 \(\mathbf{W}_{\mathrm{head}}\),看它"现在想说什么词"。相当于在半路上偷看模型的答案是怎么逐层成形的。tuned lens 给每层学一个小的仿射矫正,读数更可靠。本文没用,但它是理解"顶层状态里装着什么"的最直观方式——那个被丢掉的 \(\mathbf{h}^{L}\),正是 logit lens 读数最准的那一层。
- 激活修补 / 因果溯源(activation patching):跑两条只差一处的输入(干净的 vs 被破坏的),把干净那条的某个激活移植到破坏那条上,看输出恢复了多少。这是目前判断"某个成分是否因果地参与了某个行为"的主力方法。
- 稀疏自编码器(SAE):残差流是"多义"的——一个方向常常同时代表好几个概念。SAE 用一个过完备的稀疏字典把它拆成更单义的特征。近两年做"特征级"解释的主流工具。
- 注意力模式分析:直接看某个头在往哪儿看,配合 QK/OV 电路分解,找出"归纳头""名字搬运头"这类可命名的机制。
这篇论文只用了线性探针——但用得很聪明,因为它把探针放在了一个"标准 prefill 下必然是随机猜"的位置上。
7.3 三个合成任务:把变量控死
论文构造了成对的合成样本,标签完全由最后那个冒号之前的信息决定,而且所有样本都以同一个冒号 token 结尾。这个设计是整个实验的关键,等下会解释为什么。
required = 4 required = 4
completed = 9 completed = 4
scratch = 7 scratch = 7
scratch += 0 scratch += 0
...(8 次) ...(8 次)
Status: Status:左边标签 MORE,右边 DONE。两条样本共享 required、scratch 上下文、干扰序列和最后一个 token,只有两个计数器之间的关系不同。这测的是"从多个字段算出来的关系型状态"。state = 0 state = 1
scratch = 0 scratch = 0
scratch ^= 0 scratch ^= 0
scratch ^= 1 scratch ^= 1
...(8 次) ...(8 次)
# final state: # final state:标签 ZERO / ONE。中间是完全相同的、与标签无关的干扰操作。这测的是"把一个已经给定的状态原样运过去"。第三个任务是多寄存器最新写入追踪:给 8 个二进制寄存器反复赋值(每个寄存器 2/4/8 次写),然后查询其中一个的最新值。成对样本共享完整更新历史,只有被查询的寄存器不同。这个更难——模型得同时维护 8 个变量的最新值,还要把查询绑定到正确的那一个。
干扰操作(每条占一整行,不是一个 token)的数量在 0 / 8 / 32 / 128 / 256 之间变化,对应的输入长度是 37–1,350 token。这样可以在不改变标签的前提下改变序列长度。
7.4 为什么"第 0 层探针"是一个近乎完美的对照
这是我想让你特别注意的一点。
因为所有样本都以同一个冒号 token 结尾,在标准 prefill 下,最后一个位置的第 0 层输入就是那个冒号的 embedding——对所有样本一模一样,零标签信息。所以第 0 层探针的准确率必然是 50%(随机)。这不是经验发现,是构造出来的必然。
于是任何高于随机的准确率,都只能来自两个来源:(a) 前面的层处理了前缀,或者 (b) 递归融合把状态带了进来。变量被控死了。
对比的两种 prefill:
- 标准 prefill:最后一个 token 以纯 embedding 进入。
- 一步递归 prefill:那个 embedding 和前一个 token 的顶层状态按式 (4) 融合——这正是解码时潜在反馈在第 0 层提供的东西。
结果非常干脆:标准 prefill 下第 0 层接近随机,要爬好几层才能把全局状态重构出来;一步递归 prefill 下,第 0 层探针准确率就是完成度追踪 99.6%、延迟记忆 100%。
横轴是探测深度(0 = 第 0 层输入,即模型还没做任何计算的地方),纵轴是留出组准确率,0.5 是随机基线。切换任务和 prefill 方式,看曲线怎么从"要爬十层"变成"一开始就顶格"。数值系根据论文原图读数近似复刻,用于建立直觉;精确数值以下方原图为准。

论文 Fig. 7a(原图)。颜色代表不同的输入长度(Completion 为 37–1,317 token,Memory 为 70–1,350 token)。标准 prefill(第 1、3 格)下第 0 层是 0.5 的随机水平,之后逐层爬升;一步递归 prefill(第 2、4 格)下所有深度、所有长度直接贴着天花板。注意长度几乎不影响递归版本——这说明它拿到的是"被完整堆栈处理过的前缀摘要",而不是需要现场重算的原始信息。

论文 Fig. 7b(原图)。更难的多寄存器任务。灰线是标准 prefill,蓝色由浅到深是 1/2/4 步递归和"全递归"。可以看到:递归 prefill 显著抬高了浅层的可读性;但一步递归的优势在深层和高覆写量下会衰减,这时全递归(整条序列都做融合,代价是完全串行的 prefill)才最好——说明"一路维护状态"和"临时在末尾融合一下"确实不是一回事。
7.5 作者自己踩的刹车:可解码 \(\ne\) 被使用
"improved decodability does not by itself imply improved output. That a target is linearly recoverable at layer 0 shows the information is present, not that the model uses it to decide the next token; making state available and causally exploiting it are distinct, and only the downstream task results speak to the latter."
这段话我觉得应该裱起来。线性探针只证明信息以线性可读的形式存在;它不证明模型的后续计算真的读了这个方向。要拿因果证据,得做激活修补一类的干预实验:比如把融合进去的状态换成另一个样本的,看输出是否跟着变;或者把融合门消融掉,看下游任务掉多少。
论文没做这类干预,而是用"下游任务真的变好了"来承担因果论证。这是合理的分工,但也留下了空间:到底是潜在反馈提供的信息被用上了,还是多趟训练本身让表示变好了?Std. 解码那一栏(不开反馈时在多数任务上也比同规模基线强,MBPP 200B 是个例外)恰恰说明后者贡献不小。要拆开这两者,需要更精细的干预实验。
它在文献里的位置
把中间状态送回去这个想法不新,但这篇的组合是新的。几条主要脉络:
| 工作 | 怎么做 | 和本文的关键差别 |
|---|---|---|
| Feedback Transformer Fan et al. 2020 | 把每层表示混合成一个记忆,让未来位置去注意它 | 训练沿 token 串行,扩展不上去。有意思的是它的消融支持了本文的选择:只用最顶层几乎等于用全层混合,而只用第一层则不比标准 Transformer 好 |
| T²MLR / Latent Recurrent Transformer 2026 | 从固定的中间层取状态,通过额外的 KV 投影或直接注入残差流 | 思路最接近。本文的注入发生在模型外部(只改输入构造),零架构改动;新增参数只有 \(2D^2\),而 T²MLR 是 \(5D^2\)、LRT 是 \(LD^2\)。更大的差别是实验规模:本文做到 400B token 预训练并验证了真实推理收益,LRT 只做了非生成评测,T²MLR 只做了合成状态追踪任务和数学语料微调后的 GSM8K。论文也明确留了余地:"没有理由认为几种做法的性能会差很多",谁在大规模下最好"仍不清楚,因为我们没有资源去验证" |
| Coconut / Soft Thinking | 用连续潜变量替代离散 token 做推理 | 两点差别:本文关注预训练阶段;本文是增强而非替代——token 照出,所以能用标准语言建模损失监督,也更容易训,代价是 token 效率可能不如纯潜在推理 |
| PonderLM-2 | 把 embedding 和隐藏状态交错成输入序列,同样用多趟前向替代串行 rollout | 它把输入长度翻倍(KV cache 也翻倍),训练和推理开销都更大 |
| Loop Transformer Universal Transformer 一脉 | 反复施加同一个堆栈换取有效深度 | 推理时每多一轮就多跑一遍全部 block;本文复用已经算好的顶层状态,每 token 只加一次轻量融合。额外算力只在可选的多趟 prefill 时才付 |
| Mamba / Gated DeltaNet | 线性递归,可并行训练 | 线性约束带来表达力损失,实践中都要和标准注意力层混合来补偿 |
| ParaRNN | 用牛顿迭代解耦各步优化,并行训练非线性 RNN,语言建模效果可比 Transformer | 论文说自己"走的是反方向":ParaRNN 是让 RNN 变得可并行,本文是在 Transformer 上构造递归,结果比基线 Transformer 更好,而且效率明显更高 |
更大的图景
论文最后那段话我觉得是全文最有分量的判断之一:传统 scaling 主要在参数量和训练 token 数两个轴上走。但真实的大规模训练还被 GPU pod 大小、wall-clock 预算、以及高质量唯一 token 的存量卡着。一旦 token/参数比和可用数据池成为硬约束,"再多找点唯一 token"就不再是唯一、甚至不再是最直接的路径。
剩下的那个轴是:在同一份 token 上花更多计算。递归、迭代、反馈都属于这个方向。这篇论文的贡献是给出了一个"额外训练算力 → 解锁一种新解码模式 → 推理时几乎免费拿收益"的完整链路。
局限,以及我会追问的问题
论文自己列的两条:
- 规模只到 1B。没在更大模型上验证。作者的直觉是更深的模型收益更大(顶层状态信息更丰富),但这是猜测——也完全可能反过来:更深的模型本来就有足够深度在层内解决状态追踪,反馈的边际价值下降。
- 趟数调度是启发式的。"3% 三趟批次"这个数字怎么来的、递归训练阶段该多长,都缺少系统消融。作者建议未来用 Jacobi 迭代的收敛性诊断来原则性地决定趟数。
我自己会追问的几个:
- 拆解增益来源。Std. 解码那一栏已经比基线强,说明"多趟训练当辅助目标"本身贡献了一部分。这部分和"推理时真的用了潜在反馈"各占多少?一个干净的消融是:用多趟目标训练但推理时把融合门旁路掉,和完整版本比。(论文的 Std. 栏其实接近这个,但差值没有被单独拿出来分析。)
- 因果干预。如 7.5 所说,探针只给了相关性证据。把 \(\mathbf{h}_{t-1}\) 替换成随机向量 / 另一个样本的状态,掉多少分?这个实验很便宜,信息量很大。
- 和投机解码的相容性。论文提到 vLLM 实现借鉴了 EAGLE/MTP 的 buffer 模式。但投机解码要并行验证多个草稿 token,而潜在反馈让位置 \(t\) 的输入依赖位置 \(t-1\) 的完整前向——这两件事看起来有张力。批量投机验证还成立吗?这对实际部署很关键,论文没讨论。
- 简洁性怎么保住。指令微调把推理链变短的效果洗掉了。潜在反馈下的 on-policy RL 能不能既保住简洁又保住指令跟随?如果能,"更短的思维链 + 同等准确率"本身就是很值钱的推理成本优化。
- 状态漂移的长程行为。1000 趟 prefill 稳定,和"生成一万个 token"是不是一回事?前者每趟都重新看整条序列,后者是单向累积。论文在解码侧只验证到几百 token 的 rollout("hundred-token rollouts show no sign of breakdown"),一万 token 量级的行为仍是未知。
这篇论文的可爱之处在于:改动小到可以写进一页 PPT("把 \(\mathbf{h}^{L}\) 门控一下接回输入"),但把它训起来需要的工程判断(多趟 Jacobi 近似、渐进调度、3% 三趟批次、prefix mixin、depth scaling、权重绑定、抖动噪声)几乎全是这篇工作的实质内容。想法便宜,让想法能训起来很贵。

