文章

Speculative Decoding 实战:让大模型少跑几次前向也能保持输出一致

系统拆解 Speculative Decoding 的 draft、verify、accept/reject 流程,覆盖 LLM 推理加速的适用场景、关键工程指标、draft model 选型策略与常见误区,帮助工程团队在生产环境中落地推理加速。

Speculative Decoding 实战:让大模型少跑几次前向也能保持输出一致

大模型推理慢,很多时候不是因为每一步计算特别复杂,而是因为生成过程天然是串行的:模型先生成第 1 个 token,再把它放回上下文里生成第 2 个 token,如此循环。即使 GPU 算力再强,输出长文本时也会被一次次前向计算拖慢节奏。

Speculative Decoding(也称 Assisted Decoding)是一种已被主流推理框架广泛采用的加速思路:先让一个更小、更快的 draft model 猜出后面几个 token,再让大的 target model 一次性验证这些候选 token——验证通过的 token 直接进入输出,验证失败的位置再按目标模型的分布重新采样。这样既减少了大模型的串行前向次数,又尽量保持了与原目标模型一致的输出分布。


一、为什么 LLM 解码会慢

训练阶段可以把大量 token 并行送进模型,但生成阶段完全不同。自回归模型必须知道前一个 token,才能预测下一个 token——这个依赖链导致生成阶段很难简单地把所有输出 token 一次算完。

对于在线问答、代码助手、智能客服这类场景,用户最直接感受到的是两个关键指标:

指标全称含义
TTFTTime To First Token首个 token 的生成延迟
TPOTTime Per Output Token后续每个 token 的平均生成延迟

KV Cache 可以减少重复计算历史上下文,PagedAttention 可以改善显存管理,但它们并没有改变「逐 token 解码」的基本形态。Speculative Decoding 解决的是另一个问题:能不能让大模型一次前向验证多个候选 token,从而减少大模型的调用次数?


二、核心流程:draft → verify → accept / reject

Speculative Decoding 的基本流程可以拆成四个阶段。以下用伪代码表示其核心逻辑:

# 伪代码:Speculative Decoding 单轮流程
def speculative_decode(context, target_model, draft_model, K):
    # Step 1: Draft - 小模型快速生成 K 个候选 token
    draft_tokens = draft_model.generate(context, max_tokens=K)
    
    # Step 2: Verify - 大模型一次前向验证所有候选 token
    target_logits = target_model.forward(context + draft_tokens)
    
    # Step 3: Accept / Reject - 按采样校正规则逐个判定
    accepted = []
    for i, token in enumerate(draft_tokens):
        if acceptance_check(token, target_logits[i]):
            accepted.append(token)
        else:
            # 从此位置回退,按 target 分布重新采样
            corrected_token = sample_from(target_logits[i])
            accepted.append(corrected_token)
            break  # 后续候选 token 作废
    
    # Step 4: 已接受的 token 成为新上下文,进入下一轮
    return context + accepted

分步拆解:

  1. Draft(草稿生成):轻量 draft model 根据当前上下文快速生成若干候选 token,例如一次猜 4 个或 8 个。
  2. Verify(并行验证):target model 不再只验证一个 token,而是把 draft model 给出的多个候选 token 放到同一次前向计算里并行验证。
  3. Accept / Reject(接受或拒绝):如果候选 token 与 target model 的分布一致(满足采样校正规则),就接受;如果某个 token 不通过,则从该位置回退,由 target model 按原始分布重新采样。
  4. 进入下一轮:已接受的 token 成为新上下文,再继续下一轮 draft 和 verify。

这个流程的关键不是「小模型替代大模型」,而是「小模型提出草稿,大模型集中验收」。大模型仍然是最终裁判,在正确实现时可以保持目标模型的输出分布不变。


三、它为什么能加速

普通解码中,如果要生成 4 个 token,大模型通常要串行跑 4 次前向计算。Speculative Decoding 让小模型先快速生成 4 个候选 token,然后大模型用 1 次前向验证这 4 个 token。

传统解码:  [Target → token1] → [Target → token2] → [Target → token3] → [Target → token4]
           (4 次大模型前向)

推测解码:  [Draft → tok1, tok2, tok3, tok4] → [Target 一次验证全部]
           (1 次小模型前向 + 1 次大模型前向)

如果接受率较高(比如 draft model 提出的 4 个 token 中有 3 个经常被接受),系统平均每轮就能推进多个 token,而不是每次只推进一个 token,大模型的昂贵前向次数就会显著下降。

加速收益主要来自三个条件:

  • draft model 足够快:额外开销不能吃掉收益;
  • 接受率足够高:否则频繁回退会浪费计算;
  • 低 batch / 低延迟场景:大模型串行解码瓶颈更明显。

这也是为什么很多推理框架强调:Speculative Decoding 更适合低 batch、长输出、对延迟敏感的场景。在高并发大 batch 场景里,它未必一定比成熟的连续批处理更划算。


四、工程落地要看哪些指标

落地 Speculative Decoding 时,不建议只看平均 tokens/s。更实用的指标组合如下:

维度指标说明
延迟TTFT首 token 延迟是否受影响
延迟TPOT每个输出 token 平均延迟是否下降
效率Acceptance Ratedraft token 被 target model 接受的比例
效率Accepted Length每轮平均接受多少个 token
成本Draft Overheaddraft model 本身带来的额外耗时
资源GPU Utilizationtarget model 是否真的减少了空转和串行等待
资源Memory Overhead同时加载 draft model 是否增加显存压力
质量Quality Parity输出质量是否与不启用时保持一致

其中最核心的是 Acceptance RateDraft Overhead:一个很强但不够快的 draft model 可能拖慢整体流程;一个很快但预测太差的 draft model 又会导致大量拒绝。工程上通常要在「快」和「准」之间找平衡。


五、draft model 怎么选

draft model 不一定越大越好。它的目标不是独自生成高质量答案,而是尽可能低成本地猜中 target model 接下来会接受的 token。

选型优先级建议:

优先级考量因素原因
🔴 高与 target model 使用相同 tokenizer减少 token 对齐和重编码成本
🔴 高模型结构和训练语料尽量接近 target model提升预测准确度
🟡 中延迟足够低,明显快于 target model保证加速收益不被开销吃掉
🟡 中目标业务语料上接受率稳定避免频繁回退浪费计算
🟢 低部署后不显著挤占 target model 显存控制整体资源成本

如果 tokenizer 不一致,候选 token 的对齐和重编码成本会增加,接受率也可能明显下降。Hugging Face 的 Universal Assisted Generation 尝试缓解不同 tokenizer 的限制,但常规工程落地中,优先选择 tokenizer 一致的 draft / target 组合仍然更稳妥。


六、常见误区

误区一:Speculative Decoding 一定会提速

实际收益取决于 draft model 延迟、接受率、batch size、输出长度和采样策略。短输出、高随机采样(如 temperature 较高)、高 batch 推理都可能让收益变小甚至为负。

误区二:draft model 越强越好

强模型通常更慢。如果它的前向成本接近 target model,就失去了「低成本草稿」的意义。draft model 追求的是性价比,不是绝对质量。

误区三:它会改变模型能力

Speculative Decoding 本质是推理调度和采样校正方法,不是训练方法。它不会让目标模型变得更聪明,只是让目标模型少做一部分串行工作。输出分布理论上与原始目标模型一致。

误区四:只要 tokens/s 变高就够了

在线服务还要看 P95 / P99 延迟、显存占用、失败回退机制、监控告警和灰度策略。单一的吞吐指标在在线场景中不足以衡量用户体验。


七、适合的使用场景

适合 ✅不适合 ❌
单请求或小 batch 的低延迟生成极短输出(收益不显著)
输出较长的问答、总结、代码生成高 batch 已把 GPU 打满的吞吐型服务
target model 很大,draft model 很小且预测稳定draft / target tokenizer 难以对齐的组合
可以接受额外加载一个 draft model强随机采样(temperature 高)导致候选 token 难以被接受
有能力监控接受率和回退成本显存紧张、无法同时加载两个模型的场景

八、上线建议

如果要在生产系统中启用 Speculative Decoding,推荐按以下路径分阶段推进:

第一阶段(离线评估)
├── 选择真实业务 prompt
├── 对比关闭 vs 开启的 TTFT、TPOT、吞吐、接受率
└── 验证输出一致性

第二阶段(小流量灰度)
├── 只对低 batch、长输出、稳定任务类型启用
└── 不要一开始全量打开

第三阶段(动态开关)
├── 按模型、任务类型、输出长度、服务负载决定是否启用
└── 避免在不适合的请求上硬开

第四阶段(持续监控)
├── Acceptance Rate 趋势
├── Draft Overhead 占比
├── P95 / P99 延迟
├── GPU 利用率
└── 错误回退率

参考资料

常见问题

Speculative Decoding 会不会降低回答质量?
正确实现时,target model 仍然负责验证和采样校正,目标是保持与原模型一致的输出分布。但工程实现、tokenizer 对齐和采样策略都需要认真验证。
它和 KV Cache 是替代关系吗?
不是。KV Cache 减少历史上下文重复计算,Speculative Decoding 减少 target model 的串行前向次数。两者可以同时使用。
为什么低 batch 场景更适合?
低 batch 时,大模型逐 token 解码的串行延迟更明显。高 batch 场景下,连续批处理本身已经能提升 GPU 利用率,Speculative Decoding 的额外收益可能被 draft 开销抵消。
draft model 要不要单独训练?
不一定。可以先用同系列小模型做 draft model。但如果业务场景固定,专门优化 draft model 可能进一步提升接受率和延迟收益。