vLLM 并行起草(PARD)投机解码:配置、在线离线用法与源码实现详解
本文以 vLLM 的 parallel_drafting(并行起草)投机解码功能为主线,围绕 PARD(Parallel Draft Models)方案,完整讲解其离线与在线服务的配置方法、关键参数的源码语义、调度器槽位分配规则以及并行起草在 vLLM 内部的工作机制。读完本文,你将能够正确启用 PARD 投机解码,并理解其相比自回归式 draft model 的架构差异与适用前提。
1. PARD 是什么:从串行起草到并行起草
vLLM 的投机解码(speculative decoding)核心思路是用一个轻量的 draft(草稿)模型先生成若干候选 token,再由目标模型(target model)一次前向并行验证,从而在保持采样分布一致性的前提下减少解码步数。在 method="draft_model" 的传统形态下,draft 模型是自回归式的:它逐个 token 地串行生成 K 个投机 token,draft 阶段本身需要 K 次小模型前向。
PARD(Parallel Draft Models)则把起草过程改造为并行式:draft 模型以掩码/噪声 token 填充 K 个草稿位置,在一次前向中同时给出全部 K 个投机 token 的预测。vLLM 通过 speculative_config 中的 parallel_drafting: true 开启该模式,并要求 draft 模型在训练时就支持并行起草。
这一模式在 vLLM 配置层有明确定义(见 vllm/config/speculative.py):
# Alternative drafting strategies
parallel_drafting: bool = False
"""Enable parallel drafting, where all speculative tokens are generated
in parallel rather than sequentially. This can improve performance but
requires the speculative model be trained to support parallel drafting.
Only compatible with EAGLE and draft model methods."""
从这段字段文档可以看到三条硬约束:
- 所有投机 token 并行生成而非串行生成;
- 投机模型必须经过专门训练以支持并行起草(PARD 权重即属此类);
- 仅与 EAGLE 和 draft model 两种 method 兼容——本文聚焦
draft_model + parallel_drafting的 PARD 组合。
2. 调度器槽位:PARD 为什么需要 K 个额外位置
并行起草不只是"快一点"的优化,它对 vLLM 调度器的每请求槽位预算(slot budget)提出了不同要求。vLLM 源码在 max_num_new_slots_for_drafting 的文档字符串中给出了一张算法对照表(见 vllm/config/speculative.py):
| Algorithm | Method | Parallel | Additional slots |
|---|---|---|---|
| EAGLE3 | eagle3 | No | 0 |
| P-EAGLE | eagle3 | Yes | K - 1 |
| DFlash | dflash | Yes | K |
| DSpark | dspark | Yes | K - 1 |
| MTP | mtp | No | 0 |
| N-gram | ngram | No | 0 |
| Draft model | draft_model | No | 1 |
| PARD | draft_model | Yes | K |
其中 K 为 num_speculative_tokens。实现逻辑可以归纳为:
- 普通自回归 draft model:draft 输入保留一个未切分的 token,只需 1 个额外槽位;
- PARD(parallel_drafting + draft_model):由于 PARD 不滑动(shift)已有输入,全部 K 个查询位置都需要额外槽位,因此返回
num_draft_tokens(K 个); - 其余并行方法(如 P-EAGLE)复用已有查询位置,只需 K-1 个新槽位。
理解这张表的意义在于:配置 num_speculative_tokens: 12 时,调度器会为每个请求额外预留 12 个 draft 槽位,max_num_batched_tokens、KV cache 等预算都会据此计算。若你对投机解码的接受率与吞吐权衡感兴趣,可继续阅读 docs/features/speculative_decoding/README.md 与 docs/features/speculative_decoding/acceptance_metrics.md。
3. 离线模式:Python API 配置示例
以下示例来自 vLLM 官方文档 docs/features/speculative_decoding/parallel_draft_model.md,配置 vLLM 使用 PARD(amd/PARD-Qwen3-0.6B)作为草稿模型,对 Qwen/Qwen3-8B 做离线批量生成:
from vllm import LLM, SamplingParams
prompts = ["The future of AI is"]
sampling_params = SamplingParams(temperature=0.8, top_p=0.95)
llm = LLM(
model="Qwen/Qwen3-8B",
tensor_parallel_size=1,
speculative_config={
"model": "amd/PARD-Qwen3-0.6B",
"num_speculative_tokens": 12,
"method": "draft_model",
"parallel_drafting": True,
},
)
outputs = llm.generate(prompts, sampling_params)
for output in outputs:
prompt = output.prompt
generated_text = output.outputs[0].text
print(f"Prompt: {prompt!r}, Generated text: {generated_text!r}")
各参数要点:
"model": "amd/PARD-Qwen3-0.6B":草稿模型权重。该 PARD 模型与 Qwen3 系列同词表,满足后文第 6 节的词表一致性校验;"num_speculative_tokens": 12:每次投机验证最多提出 12 个候选 token;按第 2 节规则,这将为每个请求增加 12 个 draft 槽位;"method": "draft_model":以独立草稿模型作为提议器(proposer);"parallel_drafting": True:开启并行起草,使 draft 模型单次前向产出全部 12 个投机 token。
4. 在线模式:vllm serve 启动命令
同一套配置也可以通过 --speculative-config JSON 字符串传给在线服务,官方文档给出的命令如下:
vllm serve Qwen/Qwen3-4B \
--host 0.0.0.0 \
--port 8000 \
--seed 42 \
-tp 1 \
--max-model-len 2048 \
--gpu-memory-utilization 0.8 \
--speculative-config '{"model": "amd/PARD-Qwen3-0.6B", "num_speculative_tokens": 12, "method": "draft_model", "parallel_drafting": true}'
参数解读:
--speculative-config:JSON 形式的投机解码配置,键名与离线LLM(speculative_config={...})完全一致(注意 JSON 中布尔值为小写true);-tp 1/--max-model-len 2048/--gpu-memory-utilization 0.8:单卡部署、2048 上下文、80% 显存预算,是 4B 目标模型加 0.6B PARD 草稿模型的小型化演示配置,实际容量请依据目标模型与 PARD 权重的显存需求调整;--seed 42:固定随机种子,便于复现实验。
启动后即为标准 OpenAI 兼容 API 服务,客户端无需任何额外改动即可享受投机解码加速——验证与拒绝逻辑在引擎内部完成,输出分布与不使用投机解码保持一致。
5. 源码透视:PARD 的掩码 token 与单次前向机制
parallel_drafting 开启后,vLLM 的提议器(proposer)会执行若干关键初始化。
5.1 从草稿模型 config.json 解析掩码 token
并行起草要求 draft 模型在推理时把 K 个草稿位置填充为特定掩码 token。vLLM 在 _init_parallel_drafting_params 中按优先级依次探测草稿模型 HuggingFace config:
dflash_config.mask_token_id(DFlash 专用);- 顶层
mask_token_id; dspark_noise_token_id(DSpark);pard_token(PARD 专用);ptd_token_id(PTD)。
若均缺失则抛出 ValueError,提示必须在 config.json 中指定上述字段之一。PARD 权重携带 pard_token 字段,因此能被自动识别——这也是"必须使用训练好的 PARD 权重"的落地检查点。
5.2 额外槽位与单次前向
在同一提议器中(vllm/v1/spec_decode/llm_base_proposer.py),extra_slots_per_request 被设为 num_speculative_tokens(并行起草时),与非并行时的 1 形成对比,与第 2 节的调度器槽位表相互印证。此外在 llm_base_proposer.py 附近可以看到:
only_one_forward_pass = is_graph_capturing or self.parallel_drafting
即开启 parallel_drafting 时,draft 阶段确实只需一次前向传播即可产出全部 K 个候选 token,这正是 PARD 相对自回归 draft model(K 次串行前向)的核心性能收益来源。
6. 适用前提与限制条件
从源码可以确认以下使用前提,配置 PARD 前建议逐项核对:
- 词表一致性:verify_equal_vocab_size_if_draft_model 会在初始化时校验目标模型与草稿模型的词表大小必须相同,否则抛出
ValueError(不同 tokenizer 会导致投机解码时的越界错误)。PARD 权重与对应目标模型同系列,天然满足该条件; - M-RoPE 不支持:llm_base_proposer.py 中明确对"投机解码 + draft model / 并行起草 + M-RoPE"组合抛出
NotImplementedError,即多模态 M-RoPE 目标模型暂不能搭配该模式; - 方法兼容性:
parallel_drafting仅与 EAGLE 和 draft model 方法兼容(字段文档,见第 1 节); - 权重要求:草稿模型必须为训练支持并行起草的 PARD 类权重,其 config.json 需包含
pard_token等掩码 token 字段,否则初始化即失败。
7. 预训练 PARD 权重与延伸阅读
官方文档列出 AMD 维护的预训练 PARD 权重集合(Hugging Face 上的 amd/pard 集合),其中包含本文示例使用的 amd/PARD-Qwen3-0.6B,适配 Qwen3 系列目标模型。
相关仓库内文档与测试,便于进一步深入:
- docs/features/speculative_decoding/README.md:投机解码总览与各方法选型;
- docs/features/speculative_decoding/draft_model.md:自回归 draft model 用法,可与本文 PARD 对照;
- tests/v1/e2e/spec_decode/draft_model/test_draft_model.py:draft model / PARD 的端到端测试;
- vllm/v1/spec_decode/llm_base_proposer.py:统一承载 EAGLE、draft model 与并行起草的提议器实现。
小结
PARD 通过 speculative_config 中的 parallel_drafting: true 在 draft_model 方法上启用,将 K 次串行的起草前向压缩为 1 次并行前向,代价是调度器需为每请求额外分配 K 个 draft 槽位,且草稿权重必须是训练支持并行起草的 PARD 模型。离线 LLM(...) 与在线 vllm serve --speculative-config 两种用法共享同一套 JSON 配置键,读者可直接复用本文第 3、4 节的完整示例,并结合第 2、5 节的源码证据(槽位表、掩码 token 解析、单次前向标志)来核对部署行为是否符合预期。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0624
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00