给 ReTrace 这名字绕了不少弯。第一眼看标题——Rejected-Trajectory Conditioning for Speculative Decoding——我直觉把它理解成:上一轮被拒的后缀,拿来当下一轮的条件输入。脑子里立刻出现画面:学生重写错题的时候,把错的那一页垫在下面照抄。
这想法,说好听叫朴素,说难听点就是蠢。后来读到真正的实现细节才知道根本不是这么回事。
先把问题摆出来。推测解码的流程你我都熟:草稿模型噼里啪啦写一段,目标模型一口气验证,验证到第 k 位,不行,卡住。按标准做法,第 k 位之前采纳,第 k 位重新从目标分布采样,第 k 位之后那一整条后缀——直接丢,下一轮从新位置白纸起稿。
我之前一直觉得这事挺浪费的,但说不上来浪费在哪。草稿嘛,本来就是要被删的东西,删了又有什么可惜。
ReTrace 说:可惜。被拒的后缀不是废,是草稿模型用一次前向换来的路标。它上面写了这条路走到哪断的、断面长什么样,你却把它连根拔了,让模型下一轮从头再猜一遍。
标准做法:
draft: A B C✗ D E F
│
C 被拒,D E F 丢进回收站
下一轮从 C' 开始,D E F 不再参与任何计算
ReTrace:
同上,但 D E F 没丢
——被保留下来,作为下一轮草稿块的条件输入
第一版我画的就是上面这张图,画完有点得意,觉得这么简单一件事也能写篇论文。结果往细里读,发现自己漏了关键一格。
ReTrace 不是把被拒后缀当普通文本拼回去。它保留的是那串被拒后缀的隐藏表示——模型在生成它的时候,中间层留下的向量。草稿模型在算 D E F 的时候并不是瞎猜的:D E F 虽然被目标模型拒了,但里面带着"我当时认为下一步大概会长什么样"的全部结构信息。它把这个隐藏表示跟下一个草稿块做对齐,再拿同一轮验证过程中目标模型给的校正信号精炼一遍,最后通过一个门控残差融合,注入草稿模型的输入嵌入。
看到这里我愣了一下。这几个词放在一块,"对齐"、"校正信号"、"门控残差融合",乍一看像堆术语,其实翻译过来就是:把旧轨迹在被拒绝的那一瞬间长什么样,经过目标模型验证时暴露出来的偏差修正之后,悄悄放到草稿模型下一轮起笔的位置旁边。
不是把废稿贴在纸上让模型抄——是让模型在算下一块的时候,"手感"里还留着上一条路走到哪、往哪个方向走会撞墙的体感。
等等等等,先别急。我当时卡住的是另一个问题:一个被拒的词元永远不会被正式采纳,那它凭什么帮我生成下一个更合理的词元?
想了一会儿才反过劲来。我把它想反了。草稿模型不是把旧轨迹当标准答案,是当参照物。道理其实很朴素:草稿模型在某个位置选了 D,目标模型说不行——但那只说明 D 这一步概率不够高。D E F 这一段里,可能局部某个位置跟目标模型接下来的真实输出是吻合的;甚至整段方向都是对的,只是中间错了一两个词元。草稿模型不是全错,是局部有误差。
这就涉及一个更深的
