1. 复习:加速比到底从哪来
在上一篇里我们说到,一次推测解码(SD)步由两轮组成:
- 起草(Draft):小模型并行草拟 K 个候选 token;
- 验证(Verify):大模型一次并行前向,对这 K 个候选独立做接受 / 拒绝判断(拒绝采样)。
设平均被接受的候选数为 α,那么每消耗”一次大模型前向”,我们净产出约 α + 1 个 token(α 个被接受 + 1 个由大模型自己覆盖续写)。理想加速比近似为:
加速比 ≈ (α + 1) / (1 + cost_draft / cost_target)
当草稿模型足够便宜(cost_draft ≪ cost_target)时,分母趋近于 1,加速比 ≈ α + 1。
所以,SD 的天花板就是 α——接受长度。 想提速,先问:α 能有多大?
2. 接受长度 α 的物理上限
拒绝采样保证一个重要性质:被接受的 token 分布严格等于目标大模型分布(这就是”无损”的来源)。单个候选被接受的概率是
P(accept) = min(1, p_target(token) / p_draft(token))
可见:α 取决于草稿分布与目标分布的距离(KL 散度)。草稿模型越小越便宜,它与大模型的分布偏差通常越大 → 接受概率越低 → α 越小。
经验上,用”同架构小模型”作草稿时,α 一般落在 2–4 区间。这正是传统 SD 方案加速比停在 2–3× 的根本原因:不是工程没做好,而是分布偏差给 α 上了统计锁。
3. 自回归起草的”隐藏成本”
上面那个公式偷偷假设了一件事:起草 K 个 token 的成本约等于 0。但对自回归草稿模型来说,这不成立——
自回归草稿每生成 1 个 token,也要跑一次自己的前向,而且必须串行(第 i 个候选要等第 i−1 个算完才能起草)。于是:
- 起草 K 个候选 = K 次串行前向;
- 当 K 增大,起草延迟线性增长,把验证省下的收益一点点吃掉;
- 同时 α 并不会随 K 线性上涨——多起草的”尾部”候选大多会被拒(因为接受长度有统计上界)。
结果:盲目增大 K 不但不能线性提速,反而可能变慢。存在一个最优 K,而在这个最优点上,整体加速比就卡在 2–3× 附近。
4. 三个结构性瓶颈(小结)
| 瓶颈 | 说明 |
|---|---|
| (a) 起草串行 | 自回归草稿本身串行,抵消了”大模型并行验证”的收益 |
| (b) α 有统计上界 | 由草稿与目标分布偏差决定,难靠堆 K 突破 |
| (c) 块内顺序依赖 | token 间的顺序关系必须串行建模,无法天然并行 |
传统方案(EAGLE 系列等)已经把 (b) 榨到极限,却受 (a)(c) 拖累——这就是”卡在 2–3ד的真相。
5. 突破口(下篇预告)
既然瓶颈在”串行起草”和”块内顺序”,突破口就很清楚了:
- DFlash:把”串行自回归起草”换成块扩散(block diffusion)一次性并行起草,顺带用 KV 注入抬高接受率,并用 overlap scheduler 消除执行层空转(绕开 a、c);
- DSpark:用半自回归 + 马尔可夫头在块内建立顺序依赖,再用置信度调度器动态决定验证长度(缓解 a、b)。
下一篇,我们先深入 DFlash 的内部机制。
本篇属于「推测解码手记」系列 Ep2。下一篇:DFlash 深度解析。对比视角可先看 DFlash vs DSpark。
💬 留言
NaphJohn/LLM-blog尚未启用 Discussions:请在 GitHub 仓库 Settings → General → Features 勾选 Discussions 后刷新本页,评论区即自动显示。