SpecOPD 技术解读
让投机解码的训练
也并行起来
Branch-Parallel On-Policy Distillation for Speculative Decoding
投机解码让大模型一次验证多个候选 token,从而减少逐 token 生成的串行开销。随着 DFlash、DSpark 等并行草稿模型的发展,一整个候选块已经可以在一次前向计算中提出。接下来的问题是:怎样把草稿模型训得更好,让这些候选真正被大模型接受?
On-policy distillation(OPD,在策略蒸馏)提供了一条有效路径:让草稿模型从自己生成的历史中学习。但常见的训练流程仍要逐轮执行“草稿—验证”,收集完整回答后再更新参数。推理阶段的串行依赖,也随之进入了训练阶段。
我们提出 SpecOPD,用分支并行的方式收集新鲜的 on-policy 监督,并复用不同分支的公共前缀计算。在论文的实验设置下,它带来三类收益:
- 相比顺序 rollout OPD,有效监督 token 吞吐达到 16.09×。
- 相比原始草稿模型,五项基准的平均接受长度最高提升 41.45%。
- 在 27B 目标模型的实测服务中,生成吞吐最高达到自回归解码的 3.56×。
这三个数字分别衡量训练效率、草稿质量和推理速度。下面从它们共同的起点——训练中的串行依赖——讲起。
为什么草稿模型的训练还在等待
投机解码由一个轻量草稿模型和一个目标模型协作完成。草稿模型提出候选,目标模型并行验证,并接受其中满足条件的前缀。验证规则保留目标模型的输出分布,而更长的接受前缀意味着一次目标模型计算可以推进更多 token。
并行草稿模型降低了提出候选的成本,但接受长度仍然取决于草稿与目标的对齐程度。只在固定的目标模型回答上训练,草稿模型看到的历史与自身实际生成的历史存在差异。OPD 让目标模型在草稿生成的历史上提供监督,帮助草稿学习如何处理自己的预测偏差。
然而,在典型的 rollout-and-distill 流程中,下一轮从哪里继续,取决于上一轮验证后接受了多少 token。一次完整回答往往需要多轮草稿和验证,随后才进入训练与权重更新。每一轮都在等待上一轮建立新的前缀,难以形成持续的大批量计算。
图 1|实测执行 profile 与训练吞吐。左侧上、下半部分分别展示顺序 rollout OPD 和 SpecOPD;两者使用各自的时间轴。右侧训练吞吐来自未开启 profiling 的独立计时,避免将分析开销混入效率比较。
在图示窗口中,顺序流程交替执行 rollout、训练和权重更新;SpecOPD 则批量执行草稿采样与目标模型打分。记录到的平均 GPU 活动率由 26.37% 提升至 77.23%。这使我们重新考虑:获得 on-policy 监督,是否一定要先生成一条完整的、经过验证的回答?
一段草稿只需要自己的历史
SpecOPD 的出发点很简单:监督一个草稿位置,只需要知道它前面的上下文。
这段上下文可以由两部分组成:一段固定的参考前缀,以及当前草稿模型在该前缀后新采样的 token。目标模型沿着这条采样历史提供监督,无需先接受或拒绝这些 token 来推进完整回答。
以参考回答 Enjoy a quiet evening at home 为例。我们在 a 后设置一个锚点,当前草稿模型采样出 short evening walk:
Enjoy a目标模型读取参考前缀与同一分支中此前采样的 token。另一分支和参考回答的后续 token 不进入这段历史。
即使采样结果偏离参考回答,目标模型仍然可以在这段真实采样的历史上给出下一 token 分布。因此,训练可以直接使用草稿自己的历史,而不必等待一次完整 rollout 结束。
进一步地,在同一参考回答的 evening 后,还可以采样另一条分支,例如 with soft music。两条分支各自依赖对应的参考前缀,不需要等待对方的验证结果。我们可以同时选择许多锚点,批量生成分支并收集目标监督。
这里的 on-policy 指的是:参考前缀固定,分支由当前草稿策略新鲜采样。训练保留了固定参考上下文,同时让模型在自己的分支历史上学习。
把独立分支组织成可复用的计算
如果每条分支都重新执行一遍完整参考前缀,重复计算会抵消部分并行收益。SpecOPD 将参考序列组织为共享主干,再把采样得到的草稿续写挂到对应锚点上,形成 proposal tree。
这样,不同分支可以复用共同祖先的计算;分叉后,每条分支仍然保留自己的历史。
图 2|从参考序列采样锚点,使用当前草稿模型生成分支,再将分支挂接到共享主干上。参考序列中的后续 token 不会成为分支可见的未来上下文。
不同目标架构保存历史的方式不同,也需要相应的执行机制:
| 目标层类型 | 需要解决的问题 | SpecOPD 的处理方式 |
|---|---|---|
| 全注意力 GQA | 多条路径共享 KV,但不能互相读取分叉后的 token | 复用主干 KV,以树形 attention mask 限定可见历史 |
| 稀疏注意力 QSA | 压缩后的 indexer group 需要与分支历史一致 | 使用分支一致的 indexer groups,保留分叉后的因果块选择 |
| 线性注意力 GDN | 历史保存在递归状态中,单靠 mask 无法隔离不同路径 | 从共享 checkpoint 恢复状态,重放到锚点,再分别推进各分支 |
这三种机制遵循同一个原则:共享前缀计算,保持分支历史独立。尤其在线性注意力中,indexed state replay 避免了为每条分支从头重算整个前缀,让分支并行能够用于混合注意力目标模型。
训练目标对齐接受长度
执行得快,还需要学到对解码有用的东西。
投机解码接受的是连续前缀:如果前面的候选被拒绝,后续位置即使预测准确,也无法作为该轮已接受前缀的一部分继续推进。因此,各位置独立的预测准确率不能完整反映一个草稿块的价值。
SpecOPD 采用 E2E-TV 接受长度代理目标。它先计算每个位置的草稿分布与目标分布的重叠,再聚合沿采样分支的前缀重叠乘积:
直观地说,较大的前缀乘积鼓励模型提高整段草稿被连续接受的机会。训练将这一信号与新鲜采样的分支结合,而实际收益通过服务中的接受长度直接评估。
训练效率提升来自两个方面
在 Qwen3.8-27B 与 DFlash V2、八张高性能 GPU 的原生配置比较中,SpecOPD 同时提升了更新速度和每次更新的监督量:
| 指标 | 顺序 rollout OPD | SpecOPD | 倍率 |
|---|---|---|---|
| 参数更新吞吐 | 0.077 updates/s | 0.381 updates/s | 4.95× |
| 每次更新的有效监督 token | 22.94k | 74.58k | 3.25× |
| 有效监督 token 吞吐 | 1.77k tokens/s | 28.42k tokens/s | 16.09× |
分支并行缩短了收集阶段的等待,也让每次更新利用更多监督位置。这里的 token 只统计实际参与 loss 的预测,不包含仅作为上下文输入的 token。
比较覆盖各自的训练工作流,不包含离线参考回答的准备;不同方法保留各自的原生配置。16.09× 描述的是监督处理能力,不能直接解释为达到同等模型质量所需时间缩短 16.09 倍。
接受长度改善如何转化为推理收益
我们在 8B 全注意力、27B 全—线性混合注意力、125B 稀疏—线性混合注意力目标模型上评估 SpecOPD,覆盖 DFlash、DSpark 和 DFlash V2 三类草稿模型,以及对话、代码、数学和 Agent 四类任务领域。
五项基准分别为 MT-Bench、HumanEval、MATH-500、SWE 和 Terminal。在已完成的比较中,五基准平均接受长度最高提升 41.45%,Agent 任务上的接受长度最高提升 81.51%。后一个数字衡量从记录上下文继续生成时的解码效率。
这些收益也有架构和任务差异。27B 和 125B 目标上的五基准平均接受长度最高分别提升 3.48% 和 5.01%。在另一组公开 DFlash V2 初始化、FP8 Flash-Next 目标的实验中,block 4 和 block 8 的最高任务—温度接受长度提升分别为 7.72% 和 15.57%,各自使用对应的匹配初始模型比较。
图 3|27B 目标模型在不同任务与并发度下的实测生成吞吐。实验使用 BF16、TP=1、FA3 和 CUDA Graphs。
在这组服务实验中,SpecOPD 的生成吞吐最高达到同 GPU 自回归解码的 3.56×。五项任务的几何平均加速比分别为 2.97×、2.23× 和 1.35×,对应并发度 1、8 和 32。
相比原始 DFlash V2,SpecOPD 的几何平均吞吐增益最高为 2.83%。这个比较说明了两个不同层面的贡献:投机解码本身带来相对自回归解码的加速,而进一步训练草稿模型带来额外收益。
接受长度提升也不总与吞吐同比例变化。并发度、草稿计算成本和目标验证成本都会影响端到端表现,因此我们同时报告接受长度和真实服务吞吐。
为什么仍然需要 on-policy 学习
我们还比较了固定参考回答上的离线 CE、离线 E2E-TV,以及使用新鲜采样分支的 SpecOPD。
在匹配优化步数与参考序列 batch 的实验中,SpecOPD 相比离线 E2E-TV 的平均接受长度优势最高为 15.71%,相比离线 CE 最高为 6.96%。这些训练配方的计算分配与梯度路径有所不同,比较衡量的是相应配方下的训练效果。
图 4|训练 loss、三个基准的接受长度,以及各草稿位置的前缀存活率变化。阴影表示按问题聚类 bootstrap 得到的逐点 95% 区间。
一个值得关注的现象是:三种训练都能降低训练 loss,但离线基线的接受长度可能随训练下降,SpecOPD 则改善了实际接受行为。
在按平均接受长度选出的最佳已评估 checkpoint 上,SpecOPD 提高了全部七个草稿位置的前缀存活率;第七个位置相对初始化提高 4.33 个百分点。这将训练收益进一步连接到连续前缀能走多远,也提醒我们在优化 loss 的同时持续检查真实解码表现。
从并行草稿走向并行训练
SpecOPD 从一个局部观察出发:一个草稿块可以直接从目标模型对自身采样历史的监督中学习。
参考锚点提供独立分支,proposal tree 暴露共享前缀,分支一致的执行机制适配全注意力、稀疏注意力和线性注意力,再由接受长度代理目标指导更新。这些设计共同将逐轮收集完整回答的工作,转化为更适合 GPU 批量执行的训练计算。
随着目标模型架构不断变化,如何让草稿持续学习、快速迭代,并将接受行为的改善转化为稳定的服务收益,仍然值得继续探索。SpecOPD 为这一过程提供了分支并行的训练路径。
论文
论文标题:SpecOPD: Branch-Parallel On-Policy Distillation for Speculative Decoding。本文图表与实验数字对应论文公开版;其中接受长度包含 bonus token。
引用本文
如果这项工作对你的研究有帮助,欢迎使用下面的 BibTeX 引用我们的论文。
@misc{liu2026specopd,
title = {{SpecOPD}: Branch-Parallel On-Policy Distillation
for Speculative Decoding},
author = {Liu, Tianyu and Zhang, Jun and Huang, Wenjie and
Shen, Yuhao and Xu, Tianqi and Hao, Xinyue and
Gu, Hongyaoxing and Liu, Xuyang and Zhang, Baolin and
Zhu, Yating and Ge, Shuang and Dai, Jun and
Chen, Lei and Li, Yue and Wan, Mingchen},
year = {2026},
url = {https://github.com/QwenApp/SpecOPD}
}
致谢
感谢
LightSeek Foundation 的 Jue Wang、Yubo Wang,以及
团队对本工作的反馈与支持。