Speculative Decoding 的原理是什么?为什么可以加速且保持目标模型分布?
简化版
推测解码让便宜的 Draft Model 先提议 K 个 token,再由 Target Model 用一次序列前向并行计算这些候选位置的概率。系统按顺序接受候选,首次拒绝时提交一个校正 token,并丢弃其后的候选;若一轮推进多个 token,就减少了目标模型的串行 Decode 轮数。
采样场景要用 min(1, p(x)/q(x)) 接受,并在拒绝处从归一化的 max(0, p-q) 残差分布重采样,才能保持目标模型分布。它不保证一定更快:收益取决于接受位置、Draft 成本、Target 批量验证成本和并发状态。正确性是“统计分布一致”,不是同随机种子必然逐字相同。
详细版
标准解码每个时间步调用一次目标模型,时间步之间有数据依赖。推测解码先用较便宜的模型串行生成候选 x1...xK,目标模型随后一次计算各候选位置的分布 p1...pK;目标验证仍有计算成本,但 GPU 可以用较宽的序列计算替代 K 次窄 Decode。
Draft: x1 -> x2 -> x3 -> x4
Target: [p1 p2 p3 p4] one verification pass
Accept: x1, x2; reject x3 -> sample corrected y3; discard x4
只有精确实现才能宣称不改变目标分布。温度、Top-k/Top-p 等变换必须在 p、q 两侧按算法一致处理;KV 只能提交到已接受和校正后的长度。性能评估则要同时看平均推进 token、拒绝位置、Target 调用次数、TPOT、总吞吐和单位 token 成本。
完整版教学
推测解码的关键不是“小模型猜对了多少”,而是用正确的接受—校正规则减少目标模型的串行轮数,并证明额外工作没有吞掉收益。
一、加速机会来自哪里
自回归 Decode 的第 t+1 个输入依赖第 t 个输出,因此目标模型不能预先并行生成未来 token。但如果 Draft 已经给出一段候选,Target 就能像 Prefill 一样同时评估这段已知序列的各位置。
目标验证并非计算量为零,也不必然比一次普通 Decode 便宜。优势来自一次较宽的目标前向可能比 K 次串行、低算术强度的目标前向更快,尤其在低并发、Decode 受带宽限制时。
二、一轮算法怎样执行
设当前已接受前缀为 h,Draft 依次从 q_i(.|h,x_<i) 采样 K 个候选。Target 对 h + x1...xK 做一次前向,得到对应的目标分布 p_i,然后从第一个候选开始顺序验证。
propose K candidates
-> target verifies K positions in parallel
-> accept consecutive prefix
-> correct first rejection, or emit one extra target token if all pass
-> commit KV and start next round
首次拒绝后,其后候选建立在未提交 token 上,必须全部作废。经典算法在 K 个候选全部接受时,还可从 Target 已计算出的下一位置分布再采一个 token,从而多推进一步。
三、接受概率为何是 min(1,p/q)
对当前候选 token x,Draft 概率为 q(x),Target 概率为 p(x):
a(x) = min(1, p(x) / q(x))
若 Draft 没有高估该 token,即 p(x) >= q(x),候选必然接受;若 Draft 高估,则只以 p(x)/q(x) 接受。实现还要妥善处理 q(x)=0 的数值边界,不过 Draft 实际采出的 token 通常具有正概率。
四、拒绝后为什么不能直接采 p
已接受分支已经占用了目标分布的一部分概率质量。拒绝时若再直接从 p 采样,会重复计算这部分质量并改变最终分布。正确的校正分布是:
r(z) = max(0, p(z) - q(z)) / Σv max(0, p(v) - q(v))
接受事件与残差采样合起来,才使最终 token 的边际分布精确等于 p。这个结论针对相应的精确算法;只比较 argmax、任意阈值接受或省略残差校正的变体不能沿用该保证。
五、采样变换和贪心模式怎么处理
温度、Top-k、Top-p 会改变实际采样分布,因此 p、q 必须按实现要求在一致的变换与归一化后进入接受规则。EOS、禁止词、重复惩罚等与历史有关的处理,也要在 Draft 和 Target 的对应条件下正确对齐。
贪心模式可使用另一套确定性规则:候选等于 Target argmax 就继续接受,首个不同时提交 Target argmax。它能保持普通贪心输出,但不是上述随机采样拒绝算法,面试中应把两种正确性分开说明。
六、用数字理解收益与浪费
假设 K=4,一轮 Draft 用 2 ms,Target 验证用 12 ms,平均推进 3 个 token;普通 Target Decode 每 token 用 8 ms,则普通推进 3 token 需 24 ms,而推测路径约需 14 ms,忽略其他开销时约快 24/14=1.71 倍。
若接受率下降,平均每轮只推进 1.2 token,同样 14 ms 就比普通路径的 1.2×8=9.6 ms 更慢。这个例子说明不能只报告接受率,还要用目标硬件上的时间和平均推进量计算净收益。
七、候选长度与 Draft 怎样选择
K 太短,草稿和调度固定成本难以摊薄;K 太长,较早拒绝会让后续候选验证工作无法推进输出。K=4~8 是某些实现的起点,不是通用答案,可以根据近期接受位置自适应调整。
Draft 太弱会频繁拒绝,太强又会自身昂贵。候选器可以是更小的同族模型、目标模型的额外预测头、早退层或 n-gram,但不同方法的成本、内存和正确性协议并不相同。
| 候选器 | 主要优点 | 主要代价 | 需验证的边界 |
|---|---|---|---|
| 独立小模型 | 概念清晰、可单独训练 | 多一套权重与调用 | 分词表和分布对齐 |
| 目标模型预测头 | 可共享主干状态 | 需要专门训练与 Kernel | 多分支验证规则 |
| 早退层 | 复用部分目标计算 | 层间同步更复杂 | 早退质量与净收益 |
| n-gram 候选 | 成本很低 | 开放式文本命中有限 | 回退和上下文匹配 |
八、KV Cache 和批处理有哪些工程难点
Target 验证会临时产生候选位置的 KV;系统只能提交已接受前缀和校正 token 对应的状态,被拒绝后续位置必须回滚或丢弃。Draft 自己的状态也要与已提交前缀重新对齐。
在线连续批处理中,每个请求接受长度不同,会形成动态形状和调度分歧。高并发时 Target 本来就有较大 batch,推测带来的额外 Draft 工作和验证 token 可能降低总吞吐,所以单请求 TPOT 改善不能代替系统容量测试。
九、怎样验证分布正确性
“同一个随机种子输出相同文本”不是可靠标准,因为两条执行路径消耗随机数的次数和顺序可能不同。精确性指大量样本的分布与普通 Target 采样一致,而非单次样本路径一致。
可在小词表、短序列模型上枚举理论概率,或大量采样后用频率、总变差距离等统计量比较;贪心模式则可逐 token 做确定性回归。还要覆盖 EOS、截断采样、惩罚项和低概率数值边界。
十、性能实验怎样设计
固定模型、精度和输入/输出分布,对比普通解码与推测解码。记录候选长度、各拒绝位置概率、平均推进 token、Draft/Target 时间、Target 验证轮数、TTFT、TPOT、端到端延迟、吞吐和单位 token 成本。
分别测试 batch=1、目标在线并发和过载边界。若低并发延迟下降但高并发 Goodput 降低,应按业务场景启停或自适应切换,不能给所有流量强制开启。
十一、常见误区与追问
- 误区:所有推测解码都天然保持目标分布。 只有满足对应接受与校正规则的算法才有该保证。
- 误区:同随机种子必须生成完全相同的样本。 分布一致不等于随机数消费路径一致。
- 误区:Target 批量验证一定更便宜。 它仍计算候选位置,只有替代串行调用的收益大于额外成本才加速。
- 误区:Draft 越大越好。 更高接受率可能被更高 Draft 成本抵消。
- 误区:候选 K 越长越好。 较早拒绝会让后续候选工作不能推进输出。
- 追问:贪心模式如何保证正确? 逐位置接受与 Target argmax 相同的候选,首个不同时提交 Target argmax。
- 追问:高并发为何可能变慢? Target 已被大 batch 充分利用时,额外 Draft 和验证 token 增加总计算与调度复杂度。
十二、加强记忆
记住“Draft 提议、Target 批量验证、拒绝处校正”。采样算法以 min(1,p/q) 接受,并在首次拒绝时从归一化的 max(0,p-q) 残差分布采样,才能保持目标分布;这不意味着相同种子逐字相同。性能看每轮推进量能否抵过 Draft、Target 验证和同步成本,低并发带宽受限场景通常更有利,高并发时可能损害吞吐。正确性和加速必须分别验收。