speculative-decoding

投机解码:用草稿模型或 n-gram 预测加速 LLM 解码。

补充说明

投机解码先由廉价草稿源生成多个候选 token,再由目标模型一次并行验证,接受匹配部分。正确实现下它不改变目标模型的输出分布,但收益取决于接受率和并发形态。

常见方法:draft model、EAGLE/EAGLE3、n-gram(prompt lookup)。草稿模型必须与目标模型共享 tokenizer 和词表。

安装与启动

pip install -U vllm

先分别确认目标模型和草稿模型能独立加载,并记录无投机时的吞吐、TTFT 和 TPOT 基线。

常用示例

草稿模型方式,适合有同系列小模型的场景:

vllm serve meta-llama/Llama-3.1-8B-Instruct \
  --speculative-config '{"method":"draft_model","model":"meta-llama/Llama-3.2-1B-Instruct","num_speculative_tokens":5}' \
  --max-model-len 8192

n-gram 方式,适合代码改写、摘要、RAG 引用等大量复制输入的任务:

vllm serve meta-llama/Llama-3.1-8B-Instruct \
  --speculative-config '{"method":"ngram","num_speculative_tokens":5,"prompt_lookup_max":4,"prompt_lookup_min":2}'

EAGLE3 方式,需要与目标模型严格匹配的 EAGLE 权重:

vllm serve meta-llama/Llama-3.3-70B-Instruct \
  --speculative-config '{"method":"eagle3","model":"nvidia/Llama-3.3-70B-Instruct-Eagle3","num_speculative_tokens":3}' \
  --tensor-parallel-size 4

查看草稿数和接受 token 数:

curl -s localhost:8000/metrics \
  | grep -E 'spec_decode_num_(drafts|draft_tokens|accepted_tokens)'

用 PromQL 计算接受率,低于 50% 通常不值得继续:

# accepted / draft
rate(vllm:spec_decode_num_accepted_tokens_total[5m])
  / rate(vllm:spec_decode_num_draft_tokens_total[5m])

同一数据集分别压测有、无投机配置:

vllm bench serve --backend openai-chat --base-url http://localhost:8000 \
  --endpoint /v1/chat/completions --model llama-8b \
  --dataset-name random --random-input-len 1024 --random-output-len 256 \
  --num-prompts 500

易错点与排错

读完自测

合上页面,先回答,再展开对照。

  1. 投机解码为什么能加速而不改变输出?
  2. 什么任务最适合 n-gram 投机?
  3. 接受率多高才值得开启?
答案
  1. 草稿源先提出多个 token,目标模型并行打分验证;被接受的 token 与目标模型自己采样的结果一致,被拒绝的部分回退重采样。正确实现下等价于目标模型的采样分布。
  2. 输出大量复制或改写输入的任务,例如代码编辑、摘要、RAG 引用和格式化转换。开放创作类任务命中率低,收益有限。
  3. 没有固定阈值,但接受率长期低于约 50% 时,草稿开销往往抵消收益。应以同一压测集对比吞吐、TTFT 和 TPOT,而不是只看接受率。

相关条目