"跨轮依赖"这四个字最近被挂在嘴边挺频繁,被抛出来的时候,通常配着一句"因为轮与轮之间有依赖嘛",然后就没了。
我自己也在这上面绕过弯,而且绕的不是这个词字面意思的弯。今天把它画开,越画到后面越觉得这个点本身不玄,难看懂是因为没人把那张图摆出来。
先说我一开始以为的样子。
块级视角:草稿一次前向,整块出 k 个
位置: i i+1 i+2 i+3
[a] [b] [c] [d]
└── 目标并行验这一块 ──┘
接受 r 个
在这个视角里训练目标特别自然:这一块期望接受几个 token。局部量,块和块之间解耦,一个位置能不能被接受,就看这个位置的草稿分布离目标分布有多近。
大部分现有训练目标就是在这张图上做文章。我也用了挺久没觉得有问题,直到它解释不了一件事——为什么块内接受率涨了,端到端却不怎么快。
那问题肯定不在'块'里。重来,画轮。
轮级视角:一次拒绝,把下一轮起点推后
起点 i ──► 草稿出 k 个 ──► 目标并行验 ──► 接受 r 个
▲ │
│ ▼
└──── 下一轮起点 = i + r + 1 ◄───── 位置 i+r 被拒
▲
└── r 是随机变量
就差这一行:r 是随机的,所以下一轮从哪起也是随机的。第一版图里我把"块"当成了独立的单位,可块根本没有固定起点,它的起点是上一轮打出来的。
那会儿我还觉得"行,随机就随机,平均一下不就完了"。于是我试着把某个位置上的"拒绝代价"当常数来算,想看看差多少——一算发现它压根不是常数。
一个位置"被当作轮次起点"的频率(示意)
位置: 1 2 3 4 5
频率 μ: 100% 55% 22% 9% 2%
位置 1 被拒一次:后面整条解码链跟着重排
位置 5 被拒一次:可能总共也没几轮走到过这儿
位置 1 的拒绝和位置 5 的拒绝,不是一个量级的事。你优化"块内接受率",可块内最高的地方,未必是每轮都会起手的地方。
这就是跨轮依赖的真身。它不是在说"草稿模型和目标模型要对齐"——那是另一个话题。它是在说:训练信号得按"这个位置被轮到的频率"加权,而这个频率是前面所有位置的接受率合起来决定的。你只看块内,就等于把一个乘数当成 1。
(反过来不完全成立:加权对了也不保证最优,它只是必要条件。缺了它,优化方向是歪的;有了它,方向对不对还得看别的。)
——
十月初挂到 arXiv 那篇的做法,就是绕开了"自己造一个加权"这条弯路。它把解码过程本身建模成一个马尔可夫奖励过程:
状态: s = 当前解码位置 i
动作: a = 目标模型从 i 处采下一个 token
转移: 接受 → i+1;拒绝 → 目标模型在 i+r 处改采一个,下一轮从 i+r+1 起
代价: 一次拒绝 = 损失一轮
EDR = Σ_i μ(i) · c(i)
└ 状态占用率 ┘ └ 局部拒绝代价 ┘
μ(i) 是 i 被当作轮次起点的频率,c(i) 是 i 处的局部拒绝代价。EDR 在数值上恰好等于期望解码轮数。是恒等,不是替代量。
我在这一步咔哒一下扣上了✨。它顺手回答了我读到一半冒出来的问题:"凭什么不用辅助超参数?"答案就一句:之前那些训练目标要辅助超参数,是因为它们优化的是替代量,替代量得配个权重去跟真实轮数对齐;EDR 没有替代量,它跟被测量的东西是同一个数。
(这个比喻在这里漏风:说"它就是它"听起来像故弄玄虚。更准确的说法是,EDR 是从轮数的生成机制里直接推出来的,中间没有"估一个替代量再校准"这一层。它的便宜不是碰巧便宜,是结构上便宜。)
——
后面两件事,我觉得是这篇里最值钱的副产品。
一个是梯度。既然建模成了马尔可夫奖励过程,就可以做 TD——在目标模型的采样轨迹上做时序差分,推出来的梯度是无偏的。好处很实际:你不用把接受长度的所有可能分布都枚举一遍,采一条轨迹,就能估。
另一个是那个精确的离线轮数评估器。你手里已经有目标
