为什么这个问题值得单独看
Speculative decoding 已经成为 LLM 推理加速中最常见的工程手段之一。它的基本想法很直接:先让一个更轻量的 draft mechanism 预测多个后续 token,再让目标大模型一次性并行验证这些 token。如果验证通过,就可以减少标准自回归解码中「一次 forward pass 只生成一个 token」的串行开销。
但生产环境的问题不在于「单请求能不能快」,而在于:当服务端同时处理多个请求,并把它们放入 batch 或 continuous batching 系统后,speculative decoding 是否仍然保持输出正确。
这正是 Batch Speculative Decoding 的核心难点。
一句话理解 speculative decoding
传统解码流程是:
Target Model → token 1 → Target Model → token 2 → Target Model → token 3
投机解码流程是:
Draft Model proposes several tokens
→ Target Model verifies them in one forward pass
→ Accept the longest valid prefix
→ Rollback from the first mismatch
它的本质不是「用小模型替代大模型」,而是用小模型或轻量预测头提前提出候选,再由目标模型验证。只要实现正确,最终结果应与目标模型标准解码保持一致。
核心知识结构
可以把相关知识拆成 4 层:
| 层次 | 关注点 | 核心问题 |
|---|---|---|
| 解码层 | draft token、target verification、accept / reject | 为什么一次能生成多个 token |
| 批处理层 | batch size、continuous batching、ragged tensor | 为什么单请求能跑不代表批量也正确 |
| 状态同步层 | position IDs、attention masks、KV-cache state | batch speculative decoding 的正确性核心 |
| 系统优化层 | ITL、TTFT、throughput、alignment overhead、KV-cache fragmentation | 生产收益是否真实 |
Batch 场景里的 ragged tensor 问题
单请求 speculative decoding 中,一条序列接受几个 token,只影响自己。
但在 batch 中,假设有 3 条序列:
- Seq A accepts 4 draft tokens
- Seq B accepts 1 draft token
- Seq C accepts 0 draft tokens
此时 batch 内序列长度开始不一致。输入 token、attention mask、position IDs、KV-cache 对应关系都会变得不规则,这就是 ragged tensor problem。
如果系统只是简单 padding,却没有同步更新所有状态,就可能出现:
- position IDs 错位
- attention mask 覆盖错误
- KV-cache 中 token 与位置不匹配
- 被拒绝 token 没有正确 rollback
- 输出出现重复 token、乱码或分布偏移
这类错误不一定在 batch_size = 1 时暴露,但在 batch_size > 1 后会迅速放大。
正确流程:Draft、Verify、Accept、Rollback、Sync
一个更接近生产环境的 batch speculative decoding 流程应当包含:
- Scheduler collects active requests
- Draft mechanism proposes multiple tokens per sequence
- Target model verifies draft tokens in parallel
- Each sequence accepts a different prefix length
- Rejected tokens are rolled back
- Position IDs are recalculated
- Attention masks are rebuilt
- KV-cache is shifted, trimmed, or realigned
- Scheduler forms the next valid batch
这里真正关键的是第 6 到第 8 步。没有这几步,系统可能得到更高吞吐量,但这个吞吐量不再代表有效推理能力。
为什么只看吞吐量会误导
很多推理优化文章会直接比较 tokens/s,但 batch speculative decoding 至少需要同时看 7 类指标:
1. Output equivalence
在 greedy decoding 下,输出是否与标准 autoregressive decoding 完全一致;在 sampling 场景下,输出分布是否保持一致。
2. Acceptance length
平均每轮接受多少 draft token。接受越多,越可能减少 target model forward pass 次数。
3. Draft cost
draft model 或预测头本身也会消耗算力。如果 draft 太慢,整体不一定变快。
4. Inter-token latency (ITL)
面向交互式应用时,ITL 往往比整体吞吐量更重要。
5. Time to First Token (TTFT)
如果系统为了投机解码引入额外排队、分组或缓存移动,TTFT 可能变差。
6. Alignment overhead
batch 内不同序列接受长度不同后,需要重新对齐状态。这个开销在 batch 增大时可能非线性增长。
7. KV-cache fragmentation
Speculative decoding 会产生很多很短的候选序列。如果 KV-cache page size 过大,会造成明显内部碎片,降低实际可用缓存容量。
工程落地建议
建议一:先判断 workload 是否适合
Speculative decoding 更适合 memory-bound、中低 QPS、对 inter-token latency 敏感的场景。如果系统已经被高 QPS batch 打满,收益可能被调度和同步开销抵消。
建议二:把正确性测试放到性能测试前面
不要先压测 tokens/s。先做:
# pseudo test structure
for batch_size in [1, 2, 4, 8]:
baseline = run_autoregressive(prompts, batch_size=batch_size)
speculative = run_speculative(prompts, batch_size=batch_size)
assert_equivalent_or_same_distribution(baseline, speculative)
测试集应覆盖:
- greedy decoding
- sampling decoding
- 不同 prompt 长度
- 不同输出长度
- 多轮对话历史
- 代码生成
- 工具调用 JSON
- 中英文混合文本
建议三:监控 KV-cache 状态,而不只是 GPU 利用率
至少记录以下指标:
| 类别 | 监控指标 |
|---|---|
| 接受与回滚 | 每轮 accepted token count、rollback token count |
| 缓存操作 | KV-cache block move / trim 次数、page fragmentation ratio |
| 缓存效率 | cache hit rate、prefix reuse rate |
| 对齐开销 | attention mask rebuild cost、position ID recompute cost |
建议四:把 speculative decoding 放进整体推理架构看
生产级推理优化通常不是单点技术。更合理的组合是:
Prefill / Decode Disaggregation + Continuous Batching + KV Cache Reuse + KV Cache Quantization / Offload + Speculative Decoding + Kernel / Page Size Optimization + Correctness Regression Suite
也就是说,speculative decoding 不是替代 vLLM、SGLang、TensorRT-LLM 这类 serving stack,而是需要被 serving stack 正确调度、缓存和验证。
可复用 Checklist
上线前建议逐项检查:
- 是否证明
batch_size > 1时仍保持输出等价 - 是否正确处理 position IDs
- 是否正确重建 attention masks
- 是否正确 rollback rejected draft tokens
- 是否维护 KV-cache token-position 对应关系
- 是否监控 acceptance length,而不是只看
tokens/s - 是否单独统计 alignment overhead
- 是否评估 KV-cache page fragmentation
- 是否覆盖长上下文、代码生成、JSON 输出、工具调用等高风险任务
- 是否与 continuous batching、prefix cache、prefill/decode disaggregation 联合测试
结论
Batch speculative decoding 的难点不是「让小模型先猜」,而是「在批量服务中猜错后仍能保持大模型原本的输出」。
如果只看吞吐量,很容易把错误实现误判为高性能实现。真正可上线的方案必须同时满足三点:
- 输出等价:不能改变目标模型行为。
- 状态同步:position IDs、attention masks、KV-cache 必须一致。
- 系统收益:ITL、TTFT、吞吐量、缓存碎片与对齐开销都要综合评估。
对工程团队来说,最稳妥的判断标准是:先证明它是正确的 speculative decoding,再证明它是更快的 speculative decoding。