Speculative Decoding 生产实战:用 Draft-Verify 机制降低大模型解码延迟
背景:大模型解码为什么慢
在大模型在线服务中,Prefill 负责处理输入上下文,Decode 负责逐 token 生成输出。对于聊天、代码补全、Agent 工具调用解释、RAG 问答这类交互式场景,用户体感不只取决于首 token 时间(TTFT),更取决于后续 token 是否连续、稳定、低抖动。
标准自回归解码的主要瓶颈在于:每一步只能基于已生成的 token 预测下一个 token。即使单次前向计算很快,长回答也会把延迟累积起来。GPU 在每一步都要读取大模型权重、访问 KV Cache,并等待下一个 token 进入下一轮。Speculative Decoding 要解决的就是这个串行瓶颈。
它的核心思想很直接:让一个更快的草稿机制先猜出多个后续 token,再由目标大模型一次性验证这些 token。被目标模型接受的前缀可以直接输出,被拒绝的位置回退到目标模型自己的结果。这样可以在不更换目标模型的前提下,减少目标模型的解码轮数。
核心原理:Draft-Verify 不是简单的「小模型替大模型」
Speculative Decoding 容易被误解为「小模型先生成,大模型只做审核」。这个理解太粗糙。生产系统真正要关注的是 proposal → verification → acceptance 三个环节的组合。
1. Draft:快速提出候选 token
Draft 阶段可以由多种机制完成:
| 方法 | 特点 | 适用场景 |
|---|---|---|
| 独立 draft model | 用小模型预测后续 k 个 token | 有同族小模型的团队 |
| EAGLE | 使用目标模型隐藏状态做特征层预测 | 减少独立模型维护成本 |
| Medusa | 多个 decoding heads 并行预测 | 需框架与权重联合支持 |
| MTP | 目标模型原生支持多 token prediction | 模型内置多 token 能力 |
| n-gram / suffix decoding | 不引入额外模型,基于上下文重复模式 | 代码、模板化文本等低风险试点 |
2. Verify:目标模型并行验证候选
目标模型并非逐个 token 检查,而是对「已有上下文 + 草稿 token 序列」做一次或少数几次并行验证,判断草稿 token 中哪些前缀可以接受。遇到不一致的位置,停止接受后续草稿,回到目标模型自己的输出。
关键点:大模型仍然是最终分布的定义者。草稿机制只负责减少目标模型调用次数,不能绕过验证环节。
3. Accept / Reject:接受率决定收益上限
生产环境最重要的指标之一是 acceptance rate。收益由以下因素共同决定:
- 草稿机制与目标模型的分布接近程度
- 任务输出的稳定性(代码、结构化回答通常更易猜)
- 采样参数的保守程度(高 temperature 降低可预测性)
- 并发是否已让 GPU 饱和
- speculative token 数是否合理(过少收益有限,过多增加拒绝浪费)
工程落地:三种典型接入方案
方案一:vLLM 中启用 draft model
vLLM 支持通过 --speculative-config 传入配置:
vllm serve meta-llama/Llama-3.1-70B-Instruct \
--tensor-parallel-size 4 \
--speculative-config '{
"method": "draft_model",
"model": "meta-llama/Llama-3.2-1B-Instruct",
"num_speculative_tokens": 5
}'
落地前需验证 tokenizer、chat template、system prompt、stop tokens、采样参数是否完全一致,否则接受率会明显下降。
方案二:EAGLE / Medusa / MTP 等模型内草稿机制
独立 draft model 的维护成本较高(需额外管理模型、显存和版本)。替代方案包括:
- Medusa:多个 decoding heads 并行预测 + tree attention 验证
- EAGLE:利用目标模型隐藏状态做特征层预测,减少独立模型维护
- MTP:适合目标模型原生支持多 token prediction 的场景
这些方案要求框架、模型权重和部署引擎共同支持,评估时不能只看论文中的 speedup。
方案三:n-gram / suffix decoding 作为低风险试点
如果没有合适的 draft model,可先在代码补全、SQL 生成、日志摘要、模板化客服回复等场景中测试 n-gram 或 suffix decoding。部署复杂度低,不需要新增模型权重。但文本高度开放、重复结构少时,命中率会下降。
适用场景与边界
适合上的场景
- 交互式长回答:用户关心流式输出连贯性,accepted tokens per step 提升明显时体验更顺滑
- 代码补全与结构化生成:JSON、SQL、配置文件、模板化文档的局部可预测性强
- 中低 QPS、decode memory-bound 服务:目标模型 decode 阶段仍有并行验证空间
- 对质量稳定性要求高但不想换小模型:目标模型仍负责最终验证,能力边界不变
需要谨慎的场景
| 场景 | 风险 |
|---|---|
| 高并发吞吐型离线任务 | 额外 draft model 抢占算力和显存,整体吞吐不升反降 |
| 高创意、高 temperature 输出 | token 分布发散,draft token 被频繁拒绝 |
| 主模型本身很小 | decode 单步成本不高,优化空间有限 |
| 缺少验收指标的系统 | 难以判断优化是否真正有效 |
常见误区
- 只看平均 latency,不看尾延迟:上线评估必须覆盖 p50 / p95 / p99
- 接受率越高越好,忽略草稿成本:应同时关注 acceptance rate 与 draft overhead
- 论文 speedup 可以直接套用:论文结果基于特定条件,生产环境需用自己的真实请求分布做 benchmark
- 只在单请求下测试:需覆盖低/中/高 QPS 及不同输出长度
- 没有 fallback 开关:接受率可能因模型版本、prompt 模板变化而快速下降,必须支持按路由关闭
上线检查清单
1. 基线性能
上线前记录无 speculative decoding 的完整基线:
- TTFT p50 / p95 / p99
- TPOT 或 ITL p50 / p95 / p99
- tokens/s、request/s
- GPU utilization、GPU memory usage
- error rate、cost per 1K output tokens
2. 草稿机制验证
- draft 与 target tokenizer、chat template 一致性
- system prompt、tool schema、stop tokens 一致性
- speculative token 数经过 sweep
- 不同任务类型的 acceptance rate 稳定性
3. 质量回归
准备覆盖真实业务的回归集:普通问答、长上下文问答、代码生成、JSON/SQL/配置生成、多轮对话、工具调用前后的解释文本、高风险业务场景。重点比较格式漂移、拒答变化、事实性退化、代码可运行性下降等问题。
4. 分阶段灰度
- 离线 replay 历史请求
- 影子流量只记录指标,不返回结果
- 小比例 canary
- 按路由扩大到适合场景
- 设置自动 fallback 条件
5. 自动回退条件
speculative_decoding_guardrails:
min_acceptance_rate: 0.55
max_tpot_p95_regression: "10%"
max_error_rate: "1%"
max_quality_regression_cases: 0
fallback_action: "disable_speculative_decoding_for_route"
可执行的评估方法
Step 1:按任务类型切分样本
不要把所有请求混在一起算平均值。建议按以下维度拆分:
- 任务类型:问答 / 代码 / 摘要 / RAG / Agent / 结构化输出
- 输出长度区间
- temperature 区间
- prompt 长度区间
- 是否包含固定系统提示词
Step 2:做 speculative token sweep
测试不同 num_speculative_tokens(k = 1, 2, 3, 5, 8),观察每个 k 下的 acceptance rate、accepted tokens per step、TTFT、TPOT/ITL、throughput、GPU memory、error rate。若 k 增大后 acceptance rate 下降、尾延迟上升,说明已超过合理区间。
Step 3:做并发压力测试
至少测试 concurrency = 1, 4, 8, 16, 32, 64。若高并发下 draft overhead 明显上升,可只对低 QPS 路由、长回答路由或特定租户启用。
Step 4:做质量等价检查
保守采样场景可比较 exact match、结构化解析成功率、单元测试通过率;开放式回答使用人工抽检、LLM-as-a-Judge、事实性检查和业务规则检查的组合,不要只依赖单一自动分数。
FAQ
Speculative Decoding 和 KV Cache 优化是什么关系?
二者解决的问题不同。KV Cache 优化降低每步解码的显存和访问成本,Speculative Decoding 试图减少目标模型解码步数。它们可以组合,但组合后更需要观察显存、通信和调度开销。
是否应该所有模型默认开启?
不建议。应该按模型、任务、路由和流量特征逐步开启。更合理的策略是:先 benchmark,再 canary,然后按收益稳定的场景扩大覆盖。
参考资料
- Google Research: Looking back at speculative decoding
- vLLM Documentation: Speculative Decoding
- NVIDIA TensorRT-LLM: Speculative Sampling
- SpecInfer: Accelerating Generative Large Language Model Serving with Tree-based Speculative Inference and Verification
- Medusa: Simple LLM Inference Acceleration Framework with Multiple Decoding Heads
- EAGLE: Speculative Sampling Requires Rethinking Feature Uncertainty
- EAGLE-2: Faster Inference of Language Models with Dynamic Draft Trees
- BentoML LLM Inference Handbook: Speculative decoding