投机解码改变了大模型推理的推进单位:一次目标模型前向,可以提交多个 token。真正困难的地方,是把草稿模型、验证和服务调度的开销全部算进去以后,这些 token 依然比逐个生成更便宜。
本文从这个系统视角,对比美杜莎 Medusa、多 token 预测 MTP、EAGLE-1/2/3、DFlash、DDTree 和 DSpark,再对应到 vLLM 与 SGLang 的实际使用。资料核查日期为 2026 年 9 月 6 日。 启动示例经过文档与源码核对,但本文没有进行 GPU 性能实测。框架支持情况以文中固定的上游代码快照为准,不代表所有已发布安装包和硬件后端都支持。
1. 投机解码到底保证什么 #
小模型先起草一段候选,大模型利用因果注意力,一次计算这段候选各位置的分布,然后接受其中的一个前缀。某个位置被拒绝以后,后面的草稿也要丢弃,因为它们的目标模型概率是在错误前缀下计算的。
例如,草稿是 A B C D,其中 A B 被接受,C 被拒绝。本轮可以提交 A B R,R 是纠正 token。不能因为 D 看起来合理,就把它也保留下来。
在标准 speculative sampling 中,设相同前缀下目标分布为 \(p_i\),实际草稿提议分布为 \(q_i\),草稿采出的 token 为 \(y_i\),其接受概率为:
\[ \alpha_i(y_i)=\min\left(1,\frac{p_i(y_i)}{q_i(y_i)}\right). \]
第一次拒绝时,从正残差 \([p_i-q_i]_+\) 归一化后的分布中采样纠正 token;如果整段草稿都通过,则再从目标模型采样一个额外 token。这套构造可以保持目标模型的采样分布,不要求草稿模型具备同等能力。参见 Leviathan 等人的论文。
这里必须区分三个概念:
- 贪心结果一致:接受的 token 遵循目标模型的 argmax 决策,但实际计算还可能受到数值误差影响。
- 采样分布一致:随机输出服从相同的目标分布,不意味着相同随机种子下逐 token 完全相同。
- 生成质量相近:近似接受规则可能维持评测分数,但不再保证原始分布。
树状验证需要与其候选结构匹配的采样算法,上面的单链公式并不是完整的树采样算法。温度、概率截断、惩罚项和语法约束也必须正确纳入分布处理。置信度可以帮助决定验证多少,但不能代替目标模型验证。
2. 比较这些方法,先看成本模型 #
设 \(A\) 为接受的草稿前缀长度,不包含目标模型的纠正或额外 token。忽略 EOS 和输出长度上限造成的提前结束,一轮会推进 \(A+1\) 个 token。稳态下可以近似写成:
\[ T_{\mathrm{token}}\approx \frac{\mathbb{E}[T_{\mathrm{draft}}+T_{\mathrm{verify}}+T_{\mathrm{overhead}}]} {\mathbb{E}[A]+1}. \]
这里在 DFlash 论文 的延迟分析基础上,显式加入了调度和缓存管理开销。低并发时,GPU 的空闲计算能力可以让并行验证比较划算;高并发时,投机位置会与其他请求争夺计算和显存资源。一次验证前向,并不天然等于一次普通 decode 前向的成本。
看一个纯示意、非实测的例子:普通解码为 10 ms/token;一次投机解码花费 3 ms 起草、13 ms 验证、2 ms 管理。如果接受三个草稿 token,则每 token 为 \(18/4=4.5\) ms;如果只接受一个,则为 \(18/2=9\) ms。同一套实现,仅仅因为接受情况不同,收益就可能从显著变成很小。
下面的方法分别改进这个循环中的不同环节:生成草稿、选择候选路径,或分配验证计算。
3. Medusa 与 MTP:预测不止下一个 token #
Medusa:并行预测头 #
Medusa 在目标模型最后一层隐藏状态上增加多个预测头,不同头并行预测不同未来位置,再将候选组织成树,通过 tree attention 验证。预测头很便宜,但后一个头并没有以先前预测头实际选中的 token 为条件。
Medusa-1 冻结主干,只训练额外预测头;Medusa-2 联合训练预测头与主干,因此训练后的目标模型已不再是原始 checkpoint。论文还提供了 typical acceptance,主动放松分布一致性。因此,讨论“Medusa 无损”时,必须说明相对于哪个目标 checkpoint、使用哪种接受规则。参见 Medusa 论文。
MTP:一类训练目标与模型结构 #
MTP 并不是一个唯一确定的推理算法。Gloeckle 等人 使用共享主干和多个未来 token 预测头进行训练。这些辅助预测之后可以用作草稿,但训练时增加 MTP 目标,并不自动意味着线上推理获得加速。
DeepSeek-V3 使用的是串联 MTP 模块:每个模块将此前的表示与移位 token 的 embedding 结合,再经过 Transformer block,并共享 embedding 和输出头。它保留了不同预测深度之间的因果依赖,并非独立地并行猜测所有未来位置。参见 DeepSeek-V3 第 2.2 节。
部署时,要区分“训练了几个 MTP 模块”和“本轮想起草几个 token”。部分实现会重复使用模块来推进多个草稿步骤;提高投机长度,可能只是增加串行工作,并没有凭空增加训练好的预测头。原生 MTP 还依赖对应权重和模型专用加载逻辑,不能只靠一个命令行开关获得。
4. EAGLE-1、EAGLE-2 与 EAGLE-3 #
EAGLE-1:预测特征,同时引入 token 条件 #
EAGLE 将起草转移到目标模型的隐藏特征空间。预测特征时,引入已经采样、提前一步的 token,消除“这段特征应该对应哪种后续选择”的不确定性。轻量自回归草稿网络再借助目标模型的输出头生成候选,原始方案使用固定验证树。参见 EAGLE 论文。
它与 Medusa 的关键区别,是草稿状态会随着已选 token 演进,后续预测能够依赖前面的草稿选择。代价则是沿着草稿路径继续执行串行的小模型前向。
EAGLE-2:动态分配候选树预算 #
EAGLE-2 保留了草稿模型思路,重点改变候选构造:按路径累计置信度扩展有希望的分支,再对候选重新排序,选择最终验证树。树的深度和宽度随上下文变化,不必每轮重复同一个固定形状。参见 EAGLE-2 论文。
它提高了节点预算的利用效率,但树节点依然有成本。高负载下,更宽的树可能一边提高接受长度,一边降低整个服务的吞吐。
EAGLE-3:改进草稿模型的学习目标 #
EAGLE-3 移除了显式回归目标特征的约束,以 token 预测作为训练目标;融合目标模型低、中、高层特征,并通过 training-time test,让训练过程接触草稿模型自己生成的多步状态,从而缓解训练时“干净特征”与推理时递归状态之间的偏差。它仍然可以使用 EAGLE-2 风格的树。参见 EAGLE-3 论文。
EAGLE-3 的起草仍然是自回归的。它的进步在于更好地使用特征和训练数据,而不是一次前向生成整个 block。另外,框架能够加载 EAGLE 家族的 checkpoint,也不意味着复现了论文里的全部建树策略。
5. DFlash、DDTree 与 DSpark #
DFlash:一次并行草稿前向 #
DFlash 使用轻量 block diffusion 草稿模型,将 anchor token 与未来的 mask 位置一起处理,并通过 KV injection,把融合后的目标模型多层特征引入草稿层。原始方案一次前向就生成草稿 block,不需要长时间反复去噪;目标模型依然是自回归模型,负责验证候选。参见 论文 与 作者实现。
这样用一次更宽的并行计算,替代多次串行的小模型计算。但“隐藏状态一起计算”不等于“后面的位置能够看到前面已经采样出的 token”。不同位置可能做出互不兼容的选择,导致后半段难以被接受。扩大 block 仍会增加注意力、logits 和缓存资源消耗。
DDTree:从并行边缘分布构造树 #
DDTree 复用 DFlash 等 block 草稿模型,从每个位置的概率分布构造多条候选路径。对于前缀 \(u\),使用因子化代理分布评分:
\[ Q(u)=\prod_{i=1}^{|u|}q_i(u_i). \]
通过 best-first heap,在节点预算内选择前缀;树节点按深度分配位置编码,只能看到自身及祖先路径。验证沿着目标模型选中的 token 行走,找不到对应子节点时,该目标 token 成为下一轮的额外 token,KV cache 只保留接受路径。这里的最优性是相对于因子化代理目标,并不是对未知目标模型分布的全局最优。参见 DDTree 论文。
DDTree 改变候选集合,不要求重新训练草稿模型。工程上要回答的是:接受长度增加,能否抵消建树、更多验证位置和 KV 压缩的开销。官方实现 是研究基准代码,不能据此认定 vLLM 或 SGLang 已提供对应内置方法。
DSpark:补充依赖,再分配验证预算 #
DSpark 将并行主干与轻量串行输出组件结合,例如低秩 Markov head 或 RNN head。昂贵的特征计算仍然并行,token 选择则补上 block 内依赖;另一个置信度头估计条件接受概率,经过校准的前缀存活概率用于指导硬件感知调度器。参见 DSpark 论文。
对于条件置信度 \(c_i\),前缀一直接受到位置 \(j\) 的估计概率为 \(s_j=\prod_{i=1}^{j}c_i\)。验证长度为 \(k\) 时,预计推进量是 \(1+\sum_{j=1}^{k}s_j\)。调度器因此可以具体判断:多验证一个位置,值不值得它增加的成本?
线上要获得收益,缩短逻辑窗口以后,引擎必须真的少执行计算。SGLang 的紧凑变长验证和 CUDA Graph 处理解决了这一落地问题;vLLM 也提供基于置信度的自适应验证。参见 SGLang 集成说明 和 vLLM 自适应验证文档。
6. 按机制横向比较 #
下表归纳前述论文。“主要约束”是工程分析,不是实测排名。
| 方法 | 草稿来源 | 草稿内部依赖 | 主要改进 | 主要约束 |
|---|---|---|---|---|
| Medusa | 并行的未来位置预测头 | 各头不以已采样前缀为条件 | 起草便宜 | 远端预测准确度、接受规则 |
| DeepSeek 风格 MTP | 原生辅助模块 | 串行 | 模型内置的草稿能力 | checkpoint 支持、串行草稿成本 |
| EAGLE-1 | 特征自回归 | 串行 | 利用目标特征提高草稿质量 | 递归误差、固定树 |
| EAGLE-2 | EAGLE 草稿模型 | 串行 | 动态候选树 | 建树和验证成本 |
| EAGLE-3 | 多层特征、token 目标训练 | 串行 | 更好的多步训练 | 草稿权重和串行延迟 |
| DFlash | 并行 block 草稿模型 | 不以 block 内已采样前缀为条件 | 减少串行草稿前向 | 后缀一致性、block 成本 |
| DDTree | block 草稿的边缘分布 | 用分支覆盖不同选择 | 一次草稿前向提供更多路径 | 代理分布准确度、节点预算 |
| DSpark | 并行主干加串行输出头 | 轻量串行修正 | 更好的后缀与选择性验证 | 校准和引擎成本模型 |
这些方法并不是一条“新方法完全替代旧方法”的单线演进。EAGLE-2 和 DDTree 主要决定验证哪些候选分支;DSpark 还进一步决定当前负载下,每个请求值得获得多少验证预算。如果目标模型自带可用权重,原生 MTP 依然是很有价值的基线。
论文中的加速数字应该怎么读 #
| 来源与设置 | 作者报告的结果 | 正确理解方式 |
|---|---|---|
| EAGLE-2,Llama-3-Instruct 8B,MT-Bench,温度 0 | EAGLE-2 为 3.46 倍,EAGLE-1 为 2.72 倍 | 这是该论文同一设置内的比较 |
| EAGLE-3 论文 | 最高 6.5 倍,相比 EAGLE-2 约提升 1.4 倍 | 最大值不能直接当成部署预期 |
| DDTree,Qwen3-8B,AIME 2024,温度 0 | DFlash 为 5.38 倍,DFlash + DDTree 为 7.35 倍 | 表格按数据集、模型和温度选择最佳节点预算 |
| DSpark,DeepSeek-V4-Flash 真实流量 | 总吞吐相当时,单用户生成速度比 MTP-1 高 60%-85% | 比较的是生产服务的吞吐/延迟边界,并非通用 kernel 加速比 |
这些数字来自前面链接的原始论文,不是本文统一跑出的横评。跨行直接比较会混入不同模型、硬件、任务、调参预算以及基线实现。
7. vLLM 与 SGLang 的支持情况 #
本文核对的源码快照为 vLLM f2e2936f91a7 和 SGLang febb36051987。它们用于固定核查依据,不是经过本文 GPU 测试的版本推荐。
| 方法 | vLLM | SGLang |
|---|---|---|
| Medusa | method: "medusa",有 V1 proposer |
检查到的内置注册表没有 MEDUSA |
| MTP | method: "mtp",具体支持依赖模型 |
常经 --speculative-algorithm EAGLE 使用原生 MTP 加载逻辑 |
| EAGLE-1/2 家族 | method: "eagle",没有独立 eagle2 选项 |
文档将 EAGLE 作为 EAGLE-2 入口 |
| EAGLE-3 | method: "eagle3" |
--speculative-algorithm EAGLE3 |
| DFlash | method: "dflash" |
--speculative-algorithm DFLASH |
| DDTree | 未找到同名内置方法 | 未找到同名内置方法 |
| DSpark | method: "dspark",自适应验证需另行配置 |
DSPARK,有专用 V2 worker 与变长验证 |
依据为 vLLM 配置、SGLang 算法注册与分派,以及后文链接的官方使用文档。表格没有列出的能力,不代表第三方插件和分支也不存在。
有两个细节值得注意。第一,检查到的 vLLM Medusa proposer 是将每个预测头的 argmax 堆成序列,并非原始论文的多分支建树过程。第二,SGLang 概览文档尚未列出 DSpark,但其 worker 与官方集成文章已经存在。文档、主分支和本地安装包的更新速度可能不同。
8. 在 vLLM 中开始使用 #
先安装支持对应模型和方法的构建版本,并记录 vllm --version、容器 digest 或 Git SHA,以及模型 revision。下面假设机器有足够 GPU 显存,tensor parallel 和上下文长度需按机器调整;受限的 Llama 权重还需要提前获得访问权限。
EAGLE-3 #
草稿必须与目标模型匹配。下面这组配对来自 草稿模型卡,配置接口参见 EAGLE 文档。
vllm serve meta-llama/Llama-3.1-8B-Instruct \
--host 127.0.0.1 --port 8000 \
--max-model-len 8192 \
--speculative-config '{"method":"eagle3","model":"RedHatAI/Llama-3.1-8B-Instruct-speculator.eagle3","num_speculative_tokens":3}'
对于支持原生 MTP 的目标模型,对应配置可以从 {"method":"mtp","num_speculative_tokens":1} 开始。这属于另一条模型路径,不能直接加到上面的 Llama 示例里。具体配置应结合模型部署说明和 MTP 文档。
DFlash 与 DSpark #
方法与模型的接口可以写成下面的模板:
# Set TARGET_MODEL and DRAFT_MODEL to a verified matching pair.
vllm serve "$TARGET_MODEL" \
--host 127.0.0.1 --port 8000 \
--speculative-config "{\"method\":\"dflash\",\"model\":\"$DRAFT_MODEL\",\"num_speculative_tokens\":$DRAFT_TOKENS}"
DRAFT_TOKENS 必须符合 checkpoint 的 block/anchor 定义和运行时约束。DSpark 则使用 method: "dspark" 并配套 DSpark 权重。DeepSpec 列出了 Qwen3-8B 的公开配对,如 deepseek-ai/dflash_qwen3_8b_block7 和 deepseek-ai/dspark_qwen3_8b_block7。其中发布的 Qwen 草稿在 non-thinking 模式下训练,选择测试任务时要注意这一点。还需检查架构元数据:DFlash 权重可以使用兼容 DSpark 的模型类,同时关闭 Markov 和置信度组件,不能只看仓库名称判断加载方法。
启用自适应验证的 DSpark 配置具有如下形式:
{
"method": "dspark",
"model": "deepseek-ai/dspark_qwen3_8b_block7",
"num_speculative_tokens": 7,
"draft_sample_method": "probabilistic",
"enable_adaptive_verification": true
}
自适应验证默认关闭。核查到的 vLLM 文档要求该路径具有置信度头、兼容的注意力后端和完整 CUDA Graph,并排除 eager 执行、LoRA 和 pipeline parallelism。仅仅选择 dspark 不等于已经开启自适应验证。完整的硬件相关启动配置参见 自适应验证文档。
9. 在 SGLang 中开始使用 #
EAGLE-3 与原生 MTP #
下面的 EAGLE-3 配对来自 SGLang 文档:
python3 -m sglang.launch_server \
--model-path meta-llama/Llama-3.1-8B-Instruct \
--speculative-algorithm EAGLE3 \
--speculative-draft-model-path jamesliu1/sglang-EAGLE3-Llama-3.1-Instruct-8B \
--speculative-num-steps 3 \
--speculative-eagle-topk 4 \
--speculative-num-draft-tokens 16 \
--mem-fraction-static 0.7 \
--host 127.0.0.1 --port 30000
其中 num-steps 控制草稿深度,eagle-topk 控制候选宽度,num-draft-tokens 控制验证容量。16 个验证位置不代表一定接受 16 个输出 token。草稿的 topk 也不是请求采样里的 top_k。
对于支持原生 MTP 的模型,例如文档使用的 XiaomiMiMo/MiMo-7B-RL,短路径设置是 EAGLE、一步草稿、top-k 为一、两个验证位置。这里的 EAGLE 是推理执行路径名称,不意味着该 MTP checkpoint 按照 EAGLE 论文训练。
DFlash #
python3 -m sglang.launch_server \
--model-path meta-llama/Llama-3.1-8B-Instruct \
--speculative-algorithm DFLASH \
--speculative-draft-model-path z-lab/LLaMA3.1-8B-Instruct-DFlash-UltraChat \
--host 127.0.0.1 --port 30000
首次启动让支持该权重的运行时从 checkpoint 推断 block size。不要把 EAGLE 的深度和宽度参数直接搬到 DFlash 的线性 block 上。调度和并行模式限制应以安装版本为准,概览文档与更新后的源码并不完全同步。
DSpark #
SGLang 使用 --speculative-algorithm DSPARK。官方复现说明 使用 deepseek-ai/DeepSeek-V4-Flash-DSpark,在 H200 上配置四路 data-parallel attention,并提供了镜像和固定实现版本。这是多 GPU 配置,不应作为普通单卡示例直接照搬。
在该文档的配置中,SGLANG_RAGGED_VERIFY_MODE=static 验证完整窗口;compact 实际执行每个请求选中的变长窗口;cap-accept 保留完整验证计算用于诊断,但限制实际提交长度。SPS 成本表通过 --speculative-dspark-sps-table-path 指定,应按自己的部署进行 profiling,而不是复制另一种 GPU 的成本。压测标签应区分“运行 DSpark 草稿模型”和“同时使用校准后的成本感知裁剪”。
10. 压测整个服务系统 #
下面是建议的评测流程,不是本文已经完成的实验:
- 分别建立两个引擎的非投机基线,固定目标权重、精度、输入、上下文长度和采样设置。
- 分开测试聊天、代码和推理任务,加入长上下文与预期生产混合流量,并固定 thinking 模式和 chat template。
- 扫描并发,例如 1、8、32、128;再扫描请求到达率,观察开放到达负载下的排队行为。
- 扫描少量有效的草稿长度或节点预算。DSpark 单独比较自适应验证开关,并记录 CUDA Graph、attention backend 与 scheduler 配置。
- 报告 TTFT、token 间延迟/TPOT、总输出 tokens/s、p50/p95/p99 延迟、接受草稿长度、每轮验证位置数和峰值显存,并明确接受长度是否包含额外 token。
- 独立验证质量:数值条件允许时检查贪心 token 一致性,并对随机采样进行任务评测和分布敏感检查。只比较相同 seed 的文本,不能证明随机采样正确性。
两个引擎都提供 OpenAI 兼容接口,可以先做 API 冒烟检查。端口和模型名需与运行中的服务一致:
curl -sS http://127.0.0.1:8000/v1/chat/completions \
-H 'Content-Type: application/json' \
-d '{"model":"meta-llama/Llama-3.1-8B-Instruct","messages":[{"role":"user","content":"Explain why speculative decoding can reduce decode latency."}],"temperature":0,"max_tokens":128}'
请求成功只证明基本服务可用,不能证明投机解码已启用或获得收益,还要检查启动日志和接受指标。如果树验证了大量无用节点,或者草稿 KV cache 降低了显存能容纳的并发请求数,即使接受前缀很长,整体表现也可能更差。
11. 如何选择起点 #
我的工程建议是围绕实际瓶颈和可获得的权重进行选择:
- 目标模型原生支持 MTP:先建立短 MTP 基线,现成的权重与集成能降低比较成本。
- 有匹配良好的 EAGLE-3 草稿:先测交互延迟,再检查优势能否维持到真实服务并发。
- 串行起草成为主要成本:测试 DFlash,选匹配任务的权重,从较小且受支持的 block 开始。
- DFlash 单条路径错过其他合理延续:如果仍有验证算力预算,可以研究 DDTree。
- 请求接受情况与负载变化明显:分别测 DSpark 的串行修正和自适应验证,再评估组合收益。
- 已有 Medusa 权重:以引擎实际的 proposer 和接受规则为准,不默认它等同于原始论文实现。
最终要比较的是单位服务成本能够提交多少有效输出。更多预测头、更深草稿、更宽候选树和更长 block,只有在满足应用延迟与吞吐要求的同时改善这个指标,才有实际价值。
参考资料 #
- 基础算法:Fast Inference from Transformers via Speculative Decoding。
- 多头与原生预测:Medusa、Multi-token Prediction、DeepSeek-V3。
- 特征草稿:EAGLE、EAGLE-2、EAGLE-3。
- 并行与半自回归草稿:DFlash、DDTree、DSpark。
- 服务框架:vLLM 投机解码、SGLang 投机解码、DSpark in SGLang。
- 训练与权重:DeepSpec、DFlash 实现、DDTree 实现。