如果你曾盯着闪烁的光标等待大语言模型 (LLM) 完成一个段落,你就已经体会到了自回归生成固有的瓶颈。这些模型一次生成一个 token (词元) ,而对于每一个 token,模型都必须将海量的参数从内存搬运到计算单元。
在 GPU 加速的世界里,这被称为“内存带宽受限 (memory bandwidth bound) ”。生成的速度并非取决于 GPU 做数学运算有多快,而是取决于它移动数据的速度有多快。
针对这个问题,一个流行的解决方案是投机采样 (Speculative Sampling) 。 这项技术使用一个较小的“草稿 (draft) ”模型来猜测未来的 token,然后由较大的“目标 (target) ”模型并行地验证这些猜测。虽然这减少了所需的前向传播次数,但验证步骤本身涉及复杂的概率计算,仍然可能限制性能。
在这篇深度文章中,我们将探讨一篇近期的研究论文 “Optimized Speculative Sampling for GPU Hardware Accelerators” (针对 GPU 硬件加速器优化的投机采样) , 该论文提出了两种优化这一验证阶段的新颖方法。我们将了解重新分配 GPU 工作负载如何产生更快——但在数学上完全相同——的结果,以及如何用 Sigmoid 函数近似概率分布,从而以微小的精度损失换取巨大的速度提升。
背景: 为什么采样很慢?
要理解解决方案,我们首先需要了解硬件限制。现代 GPU,如 NVIDIA A100,拥有分层的内存结构:
- HBM (高带宽内存) : 容量巨大 (例如 80GB) ,但访问速度相对较慢。这是模型权重存放的地方。
- SRAM (静态随机存取内存) : 容量极小 (每个流式多处理器只有几百 KB) ,但速度极快。这是片上内存,通常用作可编程缓存或“共享内存”。
在标准的自回归解码中,GPU 会花费大量时间在 HBM 和 SRAM 之间读写中间矩阵。投机采样试图通过提前预测 \(K\) 个 token 来缓解这一问题。我们不再按顺序运行大模型 \(K\) 次,而是运行一次来并行验证所有 \(K\) 个 token。
然而,本文的作者注意到,验证逻辑本身——即用于接受或拒绝这些草稿 token 的数学运算——在标准实现中并非最优。它涉及了太多针对 HBM 的读写操作。
背景知识: 投机采样的数学原理
在优化硬件之前,让我们先看看我们要计算的数学公式。
在投机采样中,我们有一个目标分布 \(p(x)\) (大模型) 和一个草稿分布 \(q(x)\) (小模型) 。当草稿模型猜测一个 token \(x_{i+c}\) 时,我们要根据接受概率 \(\tau_c\) 来决定是否保留它。
标准的拒绝标准定义为:

这里,\(r_c\) 是从均匀分布 \(U(0,1)\) 中抽取的随机数。如果 \(r_c \le \tau_c\),则接受该 token。
如果 token 被拒绝,我们必须从一个校正后的分布中重新采样一个新的 token,以确保最终输出严格遵循目标模型的分布。这个校正分布定义为:

函数 max_norm 对分布差值进行归一化,确保概率为正且总和为 1:

计算这些值需要对整个词表 (通常包含 30,000+ 个 token) 进行逐元素操作。标准方法是从 HBM 加载 \(p\) 和 \(q\) 的概率,计算差值,写回 HBM,再次读取进行归一化,依此类推。这种“内存流量”正是研究人员试图消除的。
方法 1: 通过内核融合进行精确优化
该论文的第一个贡献是精确优化 (Exact Optimization) 。 “精确”意味着数学输出与基准线是位级一致的 (bit-wise identical,或在浮点误差范围内) 。它产生完全相同的文本生成结果,但速度更快。
策略: 分块 (Tiling) 与 SRAM
核心洞察在于,对于词表的各个块 (chunk) ,\(\tau\) (接受率) 和重采样分布的计算在很大程度上是独立的。研究人员没有全局处理整个词表,而是将工作负载分解为多个“分块 (tiles) ”。
他们编写了一个自定义的 GPU 内核 (Kernel) ,将工作负载重新分配给 GPU 线程和线程块。过程如下:
- 加载到 SRAM: 一个线程块将一部分 \(p(x)\) 和 \(q(x)\) 的概率从慢速 HBM 加载到快速 SRAM 中。
- 并行计算: 线程完全在 SRAM 内计算接受概率 \(\tau\) 和重采样方程 (公式 3) 的分子。
- 并行归约: 公式 3 中的分母 (所有概率之和) 是唯一棘手的部分,因为它需要全局求和。内核在 SRAM 内的块中执行部分求和。
- 写回: 只有必要的部分结果才会被写回 HBM。
通过将中间值保留在 SRAM 中,GPU 避免了多次昂贵的 HBM 访问。

图 1: 我们的精确优化方法概览。我们利用快速 SRAM 并行计算投机采样所需的大部分结果,并在其中读写中间结果。我们最大化每个块的线程数,以便在不耗尽可用片上内存的情况下,对尽可能多的元素进行并行计算。
这种方法最大化了并行性。通过对内核进行分块,GPU 可以饱和其计算核心,而无需等待内存读取。因为它忠实地实现了标准方程 (1、2 和 3) ,所以精度没有任何损失 。
方法 2: 通过 Sigmoid 进行近似优化
研究人员并没有止步于“精确”。他们问: 如果我们用极小的精度代价换取巨大的速度提升会怎样?
精确方法——实际上也是几乎所有 Transformer 操作——的瓶颈在于 Softmax 函数。

看看上面 Softmax 方程中的分母。要计算哪怕单个 token 的概率,你也需要对词表中每一个 token 的指数进行求和。这创建了一个跨越所有线程块的依赖关系,使其难以完全并行化。
切换到 Sigmoid
作者建议使用逐元素的 Sigmoid 近似来替换 Softmax。与 Softmax 不同,Sigmoid 独立处理每个 Logit。它不关心其他 Logit 在做什么。
为了实现这一点,Logits (原始模型输出,\(z\)) 首先使用常数 \(\alpha\) 和 \(\beta\) 进行缩放,以适应 Sigmoid 函数的有效范围。近似概率 \(\hat{p}\) 和 \(\hat{q}\) 计算如下:

因为 \(\hat{p}\) 和 \(\hat{q}\) 是通过 Sigmoid 计算的,严格来说它们不是有效的概率分布 (它们的和不完全等于 1) 。但是,它们保留了 token 的相对排名,这对于投机采样来说通常已经足够了。
使用这些近似概率,接受标准和重采样逻辑更新为:


融合内核
由于 Sigmoid 是逐元素的,它可以直接融合到采样内核中。在检查 token 是否被接受之前,不需要等待全局求和来归一化数值。

图 2: Sigmoid 近似在每个线程块内的计算概览。每组 Logits 由最小常数 \(\alpha\) 和最大常数 \(\beta\) 缩放。然后计算 Sigmoid 激活值 \(\sigma\) 并将草稿和目标 Logits 的每个片段存储在 SRAM 中。随后,中间值 \(\hat{f}_k(x)\),\(\hat{a}_k(x)\),\(\hat{b}_k\) 和 \(\hat{\tau}_{c_k}(x)\) 的计算类似于图 1。生成的输出随后用于更新 HBM 中的 \(\hat{\tau}_c(x), \hat{a}(x)\) 和 \(\hat{b}\)。
这种方法明显更快,因为它绕过了 Softmax 所需的昂贵全局同步。然而,它是“非精确的”,意味着生成的文本可能与标准模型不同。
实验与结果
为了验证这些方法,研究人员在两个任务上进行了广泛的基准测试:
- 自动语音识别 (ASR): 使用 Whisper (Target) 和 Distil-Whisper (Draft)。
- 文本摘要: 使用 Llama 2、Qwen 和 Gemma 模型。
他们使用Profiling 时间 (采样函数的原始 GPU 执行时间) 和准确率 (ASR 的词错误率,摘要的 ROUGE 分数) 来衡量性能。
性能提升
结果显示了明显的速度层级。基准线 (Baseline) 最慢,精确优化 (Exact Optimization) 提供了稳健的提升,而 Sigmoid 近似 (Sigmoid Approximation) 则快得惊人。

例如,在CNN/DM摘要任务中,使用 Llama2 13B 时,精确方法将 Profiling 时间缩短了 10.1% , 而 Sigmoid 方法缩短了 37.2% 。
Sigmoid 方法足够准确吗?
Sigmoid 方法的权衡在准确率指标中显而易见。
- ASR: 词错误率 (WER) 略有增加 (例如,在 LibriSpeech Clean 上从 0.08 增加到 0.09) 。这是一种轻微的退化。
- 摘要: ROUGE-1 分数小幅下降 (例如,从 0.31 降至 0.29) 。
虽然是“非精确的”,但模型通常保持连贯。研究人员发现接受率 (draft token 被接受的频率) 仍然相对较高,表明 Sigmoid 近似密切反映了真实分布的决策。
稳定性与内存
对于系统架构师来说,一个重要的问题是这些优化是否会引入不稳定性或内存开销。
研究人员绘制了每个解码步骤的执行时间与初始草稿 token 数量 (\(\gamma\)) 的关系图。

关于内存,这些优化非常高效。因为它们依赖 SRAM 进行中间存储,所以不会导致 HBM 使用量膨胀。

结论与启示
这篇论文强调了现代 AI 系统中的一个关键教训: 算法必须是硬件感知的。
如果仅仅将投机采样的数学运算视为“黑盒”,标准实现就会错失性能提升的机会。通过理解 GPU 的内存层次结构 (HBM 与 SRAM) 以及函数的属性 (Softmax 与 Sigmoid) ,我们可以榨取出显著的收益。
- “精确”方法对于需要保证保真度的生产系统来说是必然之选。它在采样步骤上提供了约 10% 的免费加速,且没有任何负面影响。
- “Sigmoid”方法提供了一个更激进的选择。对于可以接受 1-2% 指标性能下降的应用 (例如,延迟至上的实时聊天机器人) ,采样内核中近 2 倍的加速是具有变革意义的。
随着大语言模型不断增长,“内存墙”只会变得更高。像这样优化数据移动而不仅仅是计算的技术,对于让下一代 AI 变得更易用、响应更迅速至关重要。
](https://deep-paper.org/en/paper/2406.11016/images/cover.png)