作者:Tanishq Kumar, Tri Dao, Avner May
机构:Stanford University, Princeton University, Together AI
链接:arXiv:2603.03251v1
一句话总结
标准推测解码(SD)中,小模型猜完草稿后必须等大模型验证完才能开始下一轮。SSD 让小模型在等待期间提前为多种可能的验证结果准备好下一轮草稿,缓存命中时零等待,比标准 SD 再快最多 2 倍。
前置知识:推测解码(SD)是什么
LLM 自回归生成是逐 token 串行的,大模型每生成一个 token 要跑一次完整的 forward pass(约 18ms),GPU 算力严重闲置。推测解码的核心思想是:让小模型先猜,大模型来批改。
为什么大模型能并行验证
Transformer 的因果注意力掩码(causal mask)保证每个位置的输出只依赖它前面的 token。因此把 K 个猜测 token 一次性喂给大模型,它可以在一次 forward pass 中同时输出每个位置的概率分布:
一次 forward, 输入: [今天, 天, 气, 真, 好]
位置1 输出: P(·|今天) → 验证 "天"
位置2 输出: P(·|今天, 天) → 验证 "气"
位置3 输出: P(·|今天, 天, 气) → 验证 "真"
位置4 输出: P(·|今天, 天, 气, 真) → 验证 "好"
每个位置的计算互不干扰,大模型验证 K 个 token 的耗时约等于验证 1 个 token。
接受-拒绝机制
大模型逐位置检查草稿 token ,以概率 接受。被拒绝时,从残差分布中采样一个奖励 token:
残差分布的含义是:大模型认为应该给、但小模型给少了的那部分概率。通过这种方式,最终输出的分布严格等于大模型的分布——加速是无损的。
整体接受率为:
如果拒绝后直接从 采样,被小模型“猜过头”的 token()的最终概率会超标。残差分布恰好只把概率补偿给“被亏待的 token”,确保最终分布精确等于 。
标准 SD 的瓶颈
每一轮验证结束后,小模型才知道从哪个位置接着猜、奖励 token 是什么。在大模型验证的整段时间里( 18ms),小模型完全空闲:
小模型: [猜K个token] [空闲等待...] [猜K个token] [空闲等待...]
大模型: [空闲等待...] [验证~18ms] [空闲等待...] [验证~18ms]
SSD 的目标就是填满这段空闲时间。
SSD 的核心思想
把小模型部署在独立 GPU 上,让它在大模型验证的同时,预测验证结果并为多种结果预先准备下一轮草稿:
小模型: [猜K个] [预推测: 建缓存, 为12种结果各准备K个续写]
大模型: [等待.] [验证~18ms]
↓ 验证结果出来
→ 查缓存 → 命中!零等待提交下一轮
不管大模型接受了几个草稿 token,验证结束后都会额外采样一个奖励 token。即使全部接受,大模型也会在最后一个位置之后采样一个新 token。因此小模型必须猜这个奖励 token 是什么才能继续。
验证结果 定义为一个二元组 : 个草稿 token 被接受, 是奖励 token。小模型提前为多个可能的 各准备一套续写草稿,存入推测缓存 。
SSD 的加速比公式:
其中 为缓存命中率,、 为命中/未命中时的期望生成 token 数,、 为主/备用推测器延迟。
Saguaro 优化一:缓存构建与几何扇出度
问题:缓存预算有限
可能的验证结果空间为 ( 个位置 个词表 token),不可能全部预推测。给定预算 个结果,需要决定每个位置分配多少个候选奖励 token——这就是扇出度(Fan-out)。
怎么猜奖励 token
小模型在生成草稿时,每个位置已经算出了完整的词表分布。直接取排除已采样 token 后的 top- 个 logits 作为奖励 token 的猜测。实验表明准确率高达 90%。
最优扇出度分配
验证器接受 个 token 的概率服从几何分布:(),。
总缓存未命中率为(缓存未命中率随扇出度呈幂律下降,指数为 ):
在约束 下,用拉格朗日乘子法求解:
对 求导令其为零:,解得:
代入 (),常数因子吸收进 :
扇出度正比于该位置被拒绝概率的 次方。概率高的位置多分配分支。全接受()的概率通常最高(如 时 ),所以 最大。
数值示例
, , , 预算 。每个位置 :
| 位置 | (取整) | ||
|---|---|---|---|
| 0.200 | 0.447 | 3 | |
| 0.160 | 0.400 | 3 | |
| 0.128 | 0.358 | 3 | |
| 0.102 | 0.320 | 2 | |
| (全接受) | 0.410 | 0.640 | 5 |
| 合计 | 16 |
Saguaro 优化二:Saguaro 采样
问题:奖励 token 难以预测
被拒绝后大模型从残差分布 采样奖励 token,这个分布在验证完成前无法精确知道。
解法:操纵草稿分布
残差分布是 的函数。 控制不了,但可以修改 。
Saguaro 采样方案:只把缓存中的 个 token 的草稿概率乘以 ,其余不变:
效果:缓存 token 在草稿分布中的概率被压低 → 变大 → 该 token 在残差分布中的占比上升 → 大模型更可能采样到它 → 缓存命中率提高。
权衡
| 值 | 效果 | 代价 |
|---|---|---|
| (压得狠) | 缓存命中率大幅提高 | 小模型不太会猜缓存里的 token,草稿接受率下降 |
| (不压) | 退化为标准采样 | 缓存命中率不可控 |
| 最优 | 命中率和接受率的最佳平衡 | 通过实验确定 |
C 对整条草稿链的影响
需要注意, 的影响不限于当前位置。小模型是自回归生成草稿的,位置 的采样结果会成为位置 的输入上下文。一旦某个位置因为 压低概率而采到了不同的 token,后续所有位置的 logits 和采样结果都会跟着改变:
正常(C=1): "好" → "啊" → "我" → "想" (跟大模型接近,接受率高)
压低(C=0.1): "棒" → "极" → "了" → "吧" (偏离大模型,接受率低)
这意味着 越小,整条草稿序列与大模型的偏离越大,接受的 token 数会减少。但在 SSD 中要算总账:每轮少接受若干 token,换来的是大幅减少等待轮次。实验表明存在一个最优 使得总吞吐量最大化。
关于逐位置 的思考
论文中 是全局统一的超参数。但理论上不同位置的最优 应当不同:扇出度大、缓存覆盖广的位置可以用较大的 (不需要压太多),扇出度小的位置可以用较小的 (多压一些提高命中率)。论文未探索这一方向,可能是因为:(1)扇出度 已经在逐位置调整“缓存多广”, 负责的是“整体压多少”,两个旋钮各管一个维度;(2)统一 已经实现了 90% 命中率和 2× 加速,逐位置优化的边际收益可能有限。这是一个潜在的改进方向。
不管 怎么设,最终输出分布永远等于大模型分布。接受-拒绝 + 残差采样机制对任意草稿分布都成立。Saguaro 只是把“猜中”的功劳从第一步(直接接受)转移到了第二步(拒绝后缓存命中)。
Saguaro 优化三:自适应回退策略
问题:大 batch 下缓存未命中不可避免
大模型需要等整个 batch 中所有序列的草稿都就绪才能一起验证。缓存未命中的序列如果用慢推测器生成草稿,会拖慢整个 batch。
全部命中的概率随 batch 大小指数衰减:
, 时 ,即 92% 的轮次至少有一个序列未命中。
解法:根据 batch 大小切换备用推测器
| 场景 | 备用推测器 | 原因 |
|---|---|---|
| 慢但准确的神经推测器 | 未命中是偶发事件,偶尔等一下不影响全局 | |
| 极快的推测器(如随机 token) | 任何一个序列的等待都会拖慢整个 batch |
临界值 有解析解(定理 17)。
在批量大小 下,SSD 的加速比为:
当 时,分母中 ,加速比趋近于 ,此时备用推测器的延迟 直接决定性能。
随机 token 的草稿质量很差,大模型可能全部拒绝,那一轮只产出 1 个 token。但它不拖后腿——其他命中的序列不受影响。未命中的序列下一轮会重新建缓存,命中率恢复正常。
实现细节:缓存怎么建
并行生成所有分支
小模型把所有缓存分支组成一个 batch,在独立 GPU 上并行生成续写:
12 个分支, 每个续写 K=4 个 token
串行: 12 × 4 = 48 次 forward
batch 并行: 4 次 forward (每次 batch_size=12)
小模型(1B)每次 forward ≈ 0.5ms
batch 并行: 4 × ~1ms = ~4ms
大模型验证: ~18ms
4ms << 18ms, 小模型在大模型验证完成前就建好了缓存
两层 batch
实际部署中存在两层 batch:
| 外层 batch | 内层 batch | |
|---|---|---|
| 含义 | 同时处理的用户请求数 | 每个请求的缓存分支数 |
| 大小 | 如 | 如 12 个分支 |
| 谁决定 | 服务端并发量 | 扇出度分配策略 |
| 影响什么 | 回退策略的选择 | 小模型的计算量 |
小模型实际的总 batch size = 外层 内层 = 。
实验结果
端到端性能
| 模型 | AR tok/s | SD tok/s | SSD tok/s | SSD/SD |
|---|---|---|---|---|
| Llama-3.1-70B (HumanEval) | 54.7 | 176 | 283 | 1.60× |
| Llama-3.1-70B (GSM8k) | 54.7 | 188 | 301 | 1.60× |
| Llama-3.1-70B (平均) | 54.7 | 161.8 | 255.8 | 1.58× |
| Qwen-3-32B (平均) | 88.8 | 136.8 | 203.8 | 1.49× |
Llama-3.1-70B 在 GSM8k 上达到 301 tok/s,相比自回归的 54.7 tok/s 实现 5.5× 加速。
消融实验
- 几何 vs 均匀扇出度:几何策略在高温度下优势显著,缓存命中率更高
- Saguaro 采样:最优 值在接受率和命中率之间取得平衡
- 备用推测器选择:快速备用在 时开始优于神经备用,符合理论预测
- 草稿 GPU 扩展:增加草稿 GPU 可线性提升缓存大小和命中率
总结
SSD 的核心贡献是将推测解码中最后的顺序瓶颈——草稿生成与验证的串行依赖——也并行化了。其思想类比 CPU 的推测执行:提前为多个分支预计算结果,猜对了直接用,猜错了回退。
Saguaro 算法在三个维度上做了针对性优化:
- 缓存构建(几何扇出度):用拉格朗日优化将有限预算分配到最可能发生的验证结果上
- 采样策略(Saguaro 采样):通过操纵草稿分布控制残差分布,提高缓存命中率
- 回退策略(自适应备用推测器):小 batch 用高质量推测器,大 batch 用低延迟推测器,避免木桶效应
代价是多用一块 GPU 跑小模型,收益是消除了草稿与验证之间的串行等待。在 Llama-3 和 Qwen-3 上实现了比标准 SD 最高 2× 加速、比自回归 最高 5× 加速。