跳到主要内容

投机解码实战:那顿并非免费的午餐

· 阅读需 11 分钟
Tian Pan
Software Engineer

你的 700 亿参数模型在推理时大部分时间都在等待内存读取,而非进行计算。现代 GPU 每从内存读取一个字节就能执行数百次算术运算,但自回归 Transformer 解码每加载一个字节只进行寥寥数次运算。硬件在空转,而你的用户在等待。投机解码利用了这一差距:让一个小而快的模型提前起草多个 token,然后让大模型在一次并行传递中一并验证。承诺是延迟降低 2-3 倍,且输出质量在数学上完全一致。但现实远没有这么简单。

经过两年在 Google 搜索、编程助手和开源服务框架中的生产部署,投机解码已经从研究新奇事物毕业为标准优化手段。但"标准"并不意味着"即插即用"。该技术在草稿模型选择、批处理大小敏感性和内存开销方面有许多尖锐的边界条件,它们决定了你是获得 3 倍加速还是净减速。

投机解码的实际工作原理

核心思想借鉴自 CPU 分支预测。不是每次都从昂贵的目标模型逐个生成 token,而是先运行一个廉价的草稿模型向前推进 K 步,产生 K 个候选 token。然后目标模型在一次前向传递中处理所有 K 个候选——这大约与生成单个 token 的成本相同,因为瓶颈在于从内存加载权重,而非计算本身。

验证步骤使用了一种改进的拒绝采样方案。对于每个起草的 token,目标模型将自身的概率分布与草稿模型的进行比较。如果目标模型对该起草 token 赋予了相同或更高的概率,则接受。否则,以目标概率与草稿概率之比的比例接受,其余情况拒绝。当一个 token 被拒绝时,所有后续的草稿 token 都被丢弃,目标模型从调整后的分布中采样一个修正 token。

这种拒绝采样机制正是保证成立的关键:输出分布在数学上与目标模型独立生成的结果完全一致。你没有在近似或蒸馏。你生成的是完全相同的分布,只是更快。

每轮验证中预期接受的 token 数遵循一个简洁的公式,基于接受率 α 和投机 token 数 γ:τ = (1 - α^(γ+1)) / (1 - α)。当 α = 0.8、γ = 5 时,平均每轮大约接受 4.5 个 token。由于每轮大约消耗一次目标模型前向传递,这意味着昂贵的前向传递次数减少了 4.5 倍。

草稿模型选择难题

草稿模型的选择正是"免费午餐"说法站不住脚的地方。这个选择决定了你的接受率,而接受率决定了投机解码是帮助还是拖累。而且大多数人最初的直觉——选最小的但预测能力还不错的模型——是不完整的。

最近的大规模基准测试揭示了一个反直觉的发现:草稿模型的语言建模准确度(困惑度)与其对投机解码吞吐量的贡献几乎没有相关性。草稿模型的延迟才是端到端加速的更强决定因素。一个稍微不那么精确但运行快 3 倍的模型会胜过一个更精确但更慢的草稿模型,因为验证步骤本来就会捕获错误。

大小比例很重要。 在实践中,草稿模型应该是目标模型的 1/10 到 1/50。Llama 3.2-1B 为 Llama 3.1-70B 起草之所以效果很好,正是因为同系列模型共享分词和训练分布,比同等大小的通用小模型产生更高的接受率。

领域特异性比规模更重要。 现成的草稿模型往往在特定领域任务或超长上下文上表现不佳。在你的生产查询分布上微调草稿模型可以将接受率提高 20-40%。对于高流量工作负载,这项投资很快就能收回。生产团队的一个实用经验是:精心策划数据混合——平衡对话、指令跟随和代码领域——比单纯扩大数据集规模对草稿质量的影响更大。

接受率阈值大约在 0.55-0.60。 低于此值,验证开销会吞噬并行 token 生成带来的收益。当接受率达到 0.6 或更高且投机 token 数为 5 个以上时,你可以可靠地期望 2-3 倍的加速。低于 0.5 时,完全不使用投机解码可能反而更好。

投机解码何时适得其反

该技术有一个明确的失效模式,直接映射到硬件利用率。投机解码用额外的计算来换取更少的内存传输。在低批处理大小(1-10 个并发请求)下,GPU 受内存带宽限制——在权重加载之间处于空闲状态——因此将计算花在起草-验证上纯粹是收益。但随着批处理大小增加,GPU 变成计算瓶颈,投机解码额外的验证工作开始争夺此时已成为瓶颈的算力资源。

生产基准测试的具体数据:

  • 批处理大小 1-10:2-3 倍加速,最佳区间
  • 批处理大小 10-30:收益递减,通常 1.3-1.8 倍
  • 批处理大小 32+:通常比标准解码更慢

这意味着投机解码非常适合交互式、对延迟敏感的应用——聊天机器人、代码补全、实时助手——在这些场景下你服务的是单个用户,关心的是首 token 时间和 token 间延迟。对于批量处理工作负载(如批量文档摘要或离线评估),它是适得其反的,因为你已经用大批量饱和了 GPU 算力。

还有一些场景也会适得其反:

  • 非常短的回复:如果你的典型输出不到 20 个 token,没有足够的生成量来摊销草稿开销。
  • 高温度的创意生成:高温度的随机采样产生的分布草稿模型很难预测,接受率暴跌。
  • 内存受限的部署:草稿模型的权重(1-8 GB)、其 KV 缓存以及验证张量分配都消耗 GPU 显存,这些显存本可用于更大的批处理或更长的上下文窗口。

框架格局:vLLM、SGLang 和 TensorRT-LLM

2025 年,投机解码在所有主流服务框架中从实验性过渡到了生产就绪状态。每个框架各有优势。

vLLM 是最容易上手的起点。它开箱即用地支持草稿模型投机解码、EAGLE 和基于 n-gram 的投机。配置只需几个命令行参数。社区庞大,bug 发现和修复很快,连续批处理集成也很成熟。

SGLang 在中等并发下性能略好,并通过其 SpecForge 工具提供更强的草稿模型训练支持。然而,生产团队发现 SGLang 在投机批次的 token 计数中存在 bug,导致测量吞吐量偏低约 35%——服务器错误地计算了输出 token 数,使基准测试看起来比实际更差。教训是:始终用服务端指标验证投机解码基准测试,而不仅仅依赖客户端计时。

TensorRT-LLM 在 NVIDIA 硬件上提供最高的原始性能,特别是在 H200 GPU 上使用 FP8 量化时(报告称吞吐量提升 3.6 倍)。但它需要通过 NVIDIA 的构建流水线进行模型转换,实验灵活性较低。

一个跨框架通用的生产经验:在验证工作中,官方 EAGLE3 模型发布中发现了三个 bug,其中一个导致生成静默产生截断输出——服务器返回看起来有效但比请求长度短的响应,没有错误或警告。投机解码中的静默失败尤其危险,因为该技术的正确性保证只在实现无 bug 时才成立。

超越草稿模型:EAGLE、Medusa 和自投机方法

草稿模型方法是经过最充分验证的,但该领域已经开发出了做不同权衡的替代方案。

EAGLE 和 EAGLE-3 将一个轻量级自回归预测头直接附加到目标模型的内部层,从低、中、高层提取嵌入。这完全消除了单独的草稿模型。EAGLE-3 使用动态草稿树同时探索多条生成路径,生成更长的可预测文本分支。典型接受率可达 80%,产生 2.5-2.8 倍加速。缺点是你需要针对特定模型的预训练 EAGLE 变体,而这些并不总是可用的。

Medusa 向目标模型添加多个预测头,每个头预测未来的一个 token 位置。它避免了草稿模型开销,但需要修改和重新训练目标模型本身——这是一项重大投资,除非你控制整个模型生命周期,否则大多数团队无法证明其合理性。

自投机解码(SWIFT) 通过在草稿阶段跳过某些层,使用目标模型本身作为草稿。这完全不需要额外的模型工件。代价是加速幅度有限(1.3-1.6 倍),因此在 GPU 显存不足以容纳单独草稿模型时最具吸引力。

N-gram 投机 是最简单的方法:它查看提示或先前生成的文本中的模式,基于字符串匹配起草 token。它完全不需要神经网络,对结构化输出(如 JSON、SQL 或模板化文本)效果出奇地好。对于非结构化自然语言,它提供的收益极小。

从第一天就将投机解码设计进架构

生产团队最重要的实践洞察是架构性的:投机解码必须尽早纳入设计。将其改造到现有服务管道中非常痛苦,因为它涉及批处理逻辑、内存管理、KV 缓存分配和监控。

将投机解码视为一等架构原语的团队报告了更清晰的容量规划和更可预测的尾延迟。这对非流式产品尤其如此——搜索结果、文档分析、工具使用代理——在这些场景下用户看不到中间 token。在这些情况下,所有感知延迟都集中在后端,而投机解码降低解码阶段延迟的能力直接转化为更好的用户体验。

在监控方面,你需要将接受率作为一等指标来跟踪,与通常的延迟和吞吐量指标并列。接受率漂移是分布偏移的早期预警信号——如果你的用户开始问不同类型的问题,你的草稿模型的对齐度会静默退化。一个今天提供基线增益的通用草稿模型,明天可能随着查询分布演变而成为瓶颈。

在线投机解码(OSD)等自适应系统通过在服务期间使用知识蒸馏持续微调草稿模型以适应不断演变的查询分布来解决这个问题。这是前沿方向:将投机解码视为一个适应你流量的活系统,而非一次性配置后就遗忘的静态优化。

决策框架

在启用投机解码之前,按以下清单检查:

  • 工作负载类型:交互式且对延迟敏感?推荐使用。批量离线处理?大概率跳过。
  • 批处理大小:每个 GPU 通常少于 10 个并发请求?强烈推荐。经常超过 32?可能适得其反。
  • 输出长度:典型回复超过 50 个 token?适合。低于 20 个 token?收益边际。
  • 接受率:在真实生产查询上对你的草稿模型做基准测试。低于 0.55?不要启用。高于 0.65?期待显著收益。
  • 内存余量:能腾出 2-8 GB 给草稿模型权重加上 KV 缓存开销吗?如果不能,考虑自投机或 n-gram 方法。
  • 框架成熟度:你在用 vLLM、SGLang 或 TensorRT-LLM 吗?有一等支持。自定义服务栈?预计需要大量集成工作。

投机解码是当今可用于交互式 LLM 推理的单一最具影响力的优化。Google 在搜索的 AI 概览中在生产环境使用它。它不仅降低延迟,还降低能耗和硬件需求——更少的昂贵前向传递意味着相同流量需要更少的机器。但它要求仔细的草稿模型选择、在实际工作负载上的诚实基准测试,以及对服务管道的架构投资。午餐是真的。账单以工程时间的形式到来。

References:Let's stay in touch and Follow me for more thoughts and updates