首页
/ vLLM 并行起草(PARD)投机解码:配置、在线离线用法与源码实现详解

vLLM 并行起草(PARD)投机解码:配置、在线离线用法与源码实现详解

2026-09-06 14:11:44作者:伍霜盼Ellen

本文以 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.mddocs/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:

  1. dflash_config.mask_token_id(DFlash 专用);
  2. 顶层 mask_token_id
  3. dspark_noise_token_id(DSpark);
  4. pard_token(PARD 专用)
  5. 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 系列目标模型。

相关仓库内文档与测试,便于进一步深入:

小结

PARD 通过 speculative_config 中的 parallel_drafting: truedraft_model 方法上启用,将 K 次串行的起草前向压缩为 1 次并行前向,代价是调度器需为每请求额外分配 K 个 draft 槽位,且草稿权重必须是训练支持并行起草的 PARD 模型。离线 LLM(...) 与在线 vllm serve --speculative-config 两种用法共享同一套 JSON 配置键,读者可直接复用本文第 3、4 节的完整示例,并结合第 2、5 节的源码证据(槽位表、掩码 token 解析、单次前向标志)来核对部署行为是否符合预期。

登录后查看全文
热门项目推荐
相关项目推荐