Modal · 官方

你只需要投机

Speculation Is All You Need

二〇二六年六月二十日 · 英文原文

Modal 与 Z Lab 合作,在 Hugging Face 上发布了针对 Qwen 3.5/3.6 系列(35B-A3B、4B、9B、27B、122B-A10B 等)的 DFlash 推测器(speculator)草稿模型,在现有基线上实现额外 5-20% 加速,使 Qwen 3.5 122B-A10B 在 B200 节点上以并发 1 达到超过 1000 tok/s。文章解释了推测解码(speculative decoding)通过并行处理草稿 token 实现无损加速,其效果远超 kernel 优化(2-3 倍 vs 2-3%),并基于 roofline 模型和 SGLang 模拟论证接受长度(acc_len)是加速关键。

我们全力押注推测解码,以下是原因

但首先:我们是 Z Lab DFlash 草稿模型架构的忠实粉丝。正因如此,我们本周发布了针对 Qwen 3.5 397B-A17B 的最先进 DFlash 推测器,并与 SGLang 紧密合作,确保其性能达到世界领先水平

这也是我们与 Z Lab 合作,为 Qwen 系列更多模型训练最先进推测器的原因——今天我们将在 Hugging Face 上发布这些模型:

在现有 DFlash 推测器的强大基线之上,这些新草稿模型在多种工作负载上实现了额外 5-20% 的加速。

这足以让 Qwen 3.5 122B-A10B 在 B200 节点上以并发 1 达到超过 1000 tok/s 的速度。以下是我们使用 LLM Engineer's Almanac 中的 token timing simulator 模拟的大致效果,与无推测运行时 250 tok/s 的对比:

此外,它们在超长上下文任务(如 agentic 软件工程)上能更好地保持接受长度。

下面,我们将解释为何我们看好推测解码用于 LLM 推理加速——以及它作为 AI 应用持续改进循环的一部分。但首先,一个包含高层要点的 tl;dr

首要的是,推测解码是实现高交互性下最先进推理性能的唯一重要引擎优化。昂贵的 CUDA 工程师花费数日进行艰苦的 kernel 优化工作,或仔细 profiling 并消除主机端瓶颈,带来的加速仅以几个百分点计。这是一场苦战和寸进之争。许多推理提供商浪费了大量工程时间,构建了充满这些优化的专有引擎

推测解码带来的加速要大得多——以 2 倍或 3 倍这样的整数倍衡量,而非 2% 或 3%。下图展示了我们在训练的推测器以及内置 MTP 基线中观察到的加速,作为推测器质量的函数。如果你对细节感兴趣,可以在 Modal Notebook 中探索数据。

Image 1

因此,对推测解码的恰当支持比其他优化更重要。SGLang 和 vLLM 等开源推理引擎已经意识到这一点,并且根据我们的经验,它们已经缩小了与专有引擎的差距。推测解码通常也能与推理引擎性能的其他工作协同作用。

最后,当推测解码针对应用的领域特定数据进行定制时,它能带来真正无可匹敌的加速。这意味着推测解码遵循了 Bitter Lesson 的原则:因为推测解码底层依赖机器学习,当你投入更多数据和算力时,加速效果就会提升——无需顶尖的 kernel 工程师。这意味着它可以与它所加速的 AI 应用一样,受益于硬件、算法、autoresearch 和规模的持续指数级改进。

推测解码对当代自托管推理的成功至关重要,你甚至可以说推测就是一切

什么是推测解码,为什么它如此重要?

简要回顾:推测解码(又称 "spec dec")以无损方式加速 LLM 推理的"解码"阶段,即根据输入生成输出 token 的过程。

Image 2

这是一个串行操作,因为 Transformer(及类似架构)语言模型是_自回归_地生成输出 token——基于自身的输出。

推测解码通过传入由另一个系统(推测器,又称 "drafter" 或 "draft model")生成的一组 token,将串行工作转化为并行工作。目标模型可以并行处理这些 token,就像模型在"预填充阶段"并行处理输入 token 一样。

目标模型计算这些 token 自身的输出概率,并应用重采样技术(对于'heads,通常是顺序拒绝采样)。对于确定性/贪婪解码(即 temperature 0),这意味着接受目标模型本来自回归输出的 token 前缀,拒绝之后的所有 token,并插入目标模型预测的一个 token。

Image 3

重申一下,这种加速是_无损的_。推测解码从与目标模型相同的分布中生成样本序列(除了浮点累加重排序等非确定性来源)。

推测解码的核心直觉与微处理器中的推测执行相同:串行执行代价如此之高,以至于并行执行可能被丢弃的工作仍然是值得的。

每次解码传递都类似于数据库中的顺序扫描。每次传递,你都需要从 GPU 内存将所有活跃权重(数 GB)加载到 GPU SM 中,就像每次扫描必须将整个表加载到处理器中一样。推测解码则类似于在数据库中利用另一次顺序扫描来急切地构建物化视图。如果没有查询读取该视图,工作就被浪费了,但通常你受限于 I/O 带宽,因此浪费的工作在边际上是"免费"的。

问题在于你需要创建这个推测器模型。早期的方法要么使用经典 ML(例如 n-gram 模型),导致接受的 token 很少;要么使用另一个神经网络,导致草稿生成成本很高。两者都降低了推测带来的加速,我们将在下面更精确地建模和模拟。当代架构,如 MTPEAGLE-3DFlash,使用的推测器模型依赖于目标模型过去的计算。

这些推测器模型轻量级,能实现高接受长度,并且相对容易训练。

但"相对"在这里起了很大作用。众所周知,机器学习项目难以管理且容易失败。幸运的是,最难的问题并不在于推测器训练。

训练推测器是 ML 的简单模式

在机器学习中,我们创建一台机器来模仿世界中的某个数据生成过程。我们称那台机器为 ML 模型——除非它在某些人类付费的工作上足够出色,那时我们称它为"AI"。

这个设置中最棘手的部分之一是"世界中"的部分。世界随意地生成数据,但几乎所有这些信息都丢失了。只有一小部分被计算机系统捕获,而观察世界的过程会扰动数据生成过程。此外,你能收集到的数据与你真正想要建模的底层过程之间几乎总是存在巨大差距。

在推测器训练中,差距被消除了,数据也很充足,因为_数据生成过程就是另一个 ML 模型_!收集更多数据、重塑数据或在训练过程中动态生成数据都极其容易。无需将你的软件工程师重新分配Macrodata Refinement。还有一个几乎不受 Goodhart 定律影响的目标指标:目标模型的接受率和目标推理系统的加速。

ML 的基础设施很困难,但幸运的是我们了解基础设施。通过重新架构和优化开源训练代码以适配 Modal,我们能够将推测器训练速度提升 40 倍。你可以在这里尝试一个类似的系统,专为训练后强化学习设计:gym.modal.dev

训练自定义推测器很有用,因为在应用使用产生的数据集规模(数万或数十万 token)上,接受长度(进而加速)的指针可以被有意义地移动。我们已经看到微调后的模型将接受长度从基线的 3 提高到超过 9。这相当于 25% 加速与 3 倍加速之间的差异,如下所示。

从三个简单模型理解接受长度的重要性

为了理解为什么提高接受长度如此重要,让我们用三种方式对推测解码建模:

每种技术都让我们能够理解、评估并针对高接受长度带来的加速进行工程设计,而无需进行大量昂贵、耗时的 ML 训练。

在 SGLang 中模拟推测

在决定投入资源训练推测器之前,我们想了解推测可能带来什么样的加速。

对于其他加速推理的方法,如 kernel 优化,我们可以轻松模拟工作负载。例如,在 SGLang 中,你可以传递 --load-format=dummy 来获取随机权重,并在基准测试期间发送随机 token ID。这可能会对行为产生一些微小影响,尤其是在数值不稳定的 kernel 上。但它足够接近生产环境,可以加速大量优化工作。

模拟将算法开发与数据语义解耦。这有很多好处。例如,不需要将数 TB 的模型权重或数据集从存储移动到开发服务器。它们甚至不需要从磁盘加载或经过 CPU RAM——可以直接在设备上生成!

模拟推测则更棘手。推测器本身是一个 ML 模型,因此你不能仅仅在随机张量上运行它,否则接受长度会骤降。推测器处于分布外!这似乎排除了使用虚拟权重的可能性。输入数据甚至更棘手,因为它需要与实际系统将看到的数据紧密匹配,尤其是对于微调后的推测器。下周会有更多相关内容!

SGLang 包含一个鲜为人知的环境变量来解决这个问题:SGLANG_SIMULATE_ACC_LEN。设置此标志会模拟接受行为,即直接接受生成的 token 直到某个长度,而不考虑目标模型的概率。使用随机权重的推测器和目标模型仍会产生大致相同的工作量,因此花费大致相同的时间。

与任何对复杂数值代码的扰动一样,这当然会导致与实际工作负载的偏差。然而,它为我们提供了另一种检查模型和预测更好训练的推测器收益的方法。

如果我们在 B200 上以并发 1 对 Qwen 3.5 27B 进行基准测试,输入 4Ki token,输出 4Ki token 的随机数据,并模拟接受长度在 1(自回归)到 8 之间,我们会看到显著的加速。

接受长度 输出 tok/s 加速
1 75 1x
2 140 1.86x
4 268 3.57x
8 422 5.62x

我们可以添加更多证据,并通过数学建模来培养对加速来源以及如何提高加速的直觉,接下来我们将进行此操作。

推测的玩具模型

让我们从我们能想到的最简单的推测解码模型开始。在这个模型中,我们会看到推测带来的加速等于接受长度。

首先,定义 speedup

我们可以轻松地将吞吐量建模为以下参数的函数:

我们将自回归解码建模为"预测一个 token draft_len 次,得到 draft_len 个 token"。我们将推测解码建模为"一次传入 draft_len 个 token,得到 acc_len 个 token"。

首先,假设模型对于 1 个 token 的延迟与 draft_len 个 token 的延迟相同。代入这些值:

如果我们在本地白板上展开,我们会注意到许多项相互抵消——draft_len / draft_lenmodel.latency(1) / model.latency(1)。实际上,我们得到:

这种等延迟假设并不总是成立,而且可能严重错误。请耐心等待——我们将很快证明它在何时近似成立并改进我们的模型。

但这个简单模型出奇地有用。例如,以下是我们本周发布的所有推测器在 SGLang 推理引擎中观察到的加速,其中非常简单的 speedup == acc_len 模型以虚线绘制。尽管加速一直被高估,但在观察到的接受长度上可以看到线性趋势。

Image 4

因此,我们有一个有用的经验法则来根据实际值范围内的接受长度估计加速——线性,而非二次、平方根或对数。然而,它实际上不能用于估计加速。

高估的发生是因为我们做了许多有利于推测解码的假设:

现在让我们修复这些问题。

使用 roofline 进行更好的建模

注意:本节中的模型是使用 DoublewordFergus Finn这篇博客文章中提出的 DeepSeek-V4 Flash 推测模型开发的。该模型的数字被用作我们实现最优草稿长度计算的参考。

为了将目标前向传递的延迟作为负载(包括草稿 token)的函数纳入考虑,我们基于一些简化假设构建了一个简单的前向传递模型:

  1. 加速器的内存带宽算术带宽始终被完全利用
  2. 内存传输和计算可以完美重叠,所有延迟被隐藏,并且
  3. 主机向加速器提供工作的速度快于加速器完成工作的速度,从而避免开销

这些假设对于更大的模型、更长的序列长度和更大的批次大小更准确。

基于这些假设,我们可以根据模型需要读取的字节数、需要执行的浮点运算次数(flops)以及在全内存和算术带宽下执行这些操作所需的时间来估计模型延迟。我们只需取两个延迟中较高的一个(计算下界内存下界)。这是一个性能的 roofline 模型

Image 5

从机制上讲,这个计算按层进行最容易,因为 attention 和矩阵乘法看起来非常不同。我们忽略其他层,因为它们通常要么非常快,要么可以通过 epilogues 或其他 kernel 融合与运行时间较长的操作重叠。

这意味着这个建模代码看起来像这样

请注意,对于少量 query token,attention 和密集 MLP 模块加载的字节数在 query_tokens_per_seq 上大致恒定。这证明了我们简单模型中的核心近似是合理的——只要计算延迟的界限不高于内存延迟的界限,我们在此模型中计算的延迟对于单个 query token 和多个 query token 大致相同。

相关的架构数据可以从 Hugging Face 配置读取,并结合一些简单的逻辑来计算执行的 flops 和读取的字节数

我们选择将推测器的前向传递延迟建模为目标模型的一个固定百分比——大约 5% 到 20% 似乎很常见。对于自回归的 drafter,这每个草稿 token 支付一次。对于像 DFlash 这样生成块的 drafter,这每个块支付一次

这些计算非常快,因此我们可以动态地进行——在浏览器中,使用 JavaScript,无需 GPU。你可以在这里尝试:modal.com/llm-almanac/spec-dec-roofline

下面我们逐步介绍该模型的示例输出。

Image 6

该图表比较了在单个 B200 节点上部署的 DeepSeek-V4 Pro 处理特定工作负载时,推测解码相对于自回归基线的解码加速。本例中的工作负载是短序列长度(约 4k token/序列)和高并发(32 个序列的批次)。顶部的图表显示了在多种草稿长度下,几种 drafter 的预测加速因子,以及最高加速因子。该加速是在模型认为的最优草稿长度(或 16,取较低者)下实现的。

比较了三种 drafter。金色的是"Ideal" drafter。这个 drafter 具有近乎完美的接受率,并且瞬间完成前向传递。这为此工作负载和硬件上的推测提供了一个上限,至少根据 roofline 的考虑。蓝色的 drafter 代表典型的自回归 MTP drafter,接受长度较短。绿色的 drafter 代表典型的训练良好的块 drafter(如 DFlash),它实现了更高的接受长度。

使用更快的 drafter 并将接受长度从约 3 提高到约 8,会显著改变预测的可实现加速。它从 20%(仅仅是体面)变为 3 倍,这足以开辟新的应用或市场。进一步提高接受长度将允许更大的块大小。

这个模拟器并不完美——由于上述 roofline 模型的局限性,以及它没有尝试模拟跨 GPU 的张量通信。然而,我们发现它比简单的玩具模型更正确。例如,它正确预测了对于混合专家模型(如 DeepSeek-V4 Pro),推测器加速作为批次大小的函数是非单调的("U 形"),而对于密集模型(如 Qwen 3.5 27B)则是单调的。你可以在这里通过首先查看图表的默认版本,然后选择 Qwen 3.5 27B 来看到这一点。

下一步是什么?

在本文中,我们考虑了开源推测解码的当前生产级最先进技术。未来会是什么样子?

我们预计以下趋势:

自适应推测器训练

首先,我们认为它涉及更多自定义推测器。生产数据会经历漂移。用户行为随时间变化,推理系统(包括推测器)需要适应。Together 在这方面有出色的前期工作。我们正在试验自适应推测器训练,并期待将其部署给我们的用户。

但自适应推测并不像"定期检查接受长度"那么简单。用户行为的一些变化是季节性的,而非持久的。例如,一家在 Modal 上构建自适应推测的公司有两个不同的用户群,位于地球两端,各自使用自己的(混合)语言。这限制了固定容量推测器的加速。更糟糕的是,一个实现不佳的自适应推测器系统每次用户群转移时都会触发重新训练,每天两次,而它本可以维护两个"区域推测器",并更少频率地重新训练。

更好的推测器架构

其次,我们认为它涉及更多关于推测器架构的工作。DFlash 引入了两个我们喜欢的新想法(正如我们在 LMSys Org 博客上详细解释的那样)。KV 注入技术允许更深、更智能的 drafter。DFlash 的单步扩散/"如果你眯眼看就是 BERT"方法也更适合高算术强度的硬件。

但如今扩散模型中最热门的新技巧是使用 flow maps。扩散模型通过其去噪操作诱导出一个向量场,典型的推理方法逐步跟随该场。Flow maps 接收初始状态和步数,并输出最终状态——就像一个积分查找表,而不是一个顺序积分器。通过一些巧妙的数学,你可以写出目标来同时训练一个多步扩散模型和一个用于所有多步"跳跃"(包括单步去噪器)的积分器。对于推测,这为你提供了一个额外的旋钮来权衡接受长度和 drafter 延迟,而无需重新训练 drafter。

更好的推测器实现

第三,我们认为推测器的实现将会改进。在将 DFlash 与 SGLang 集成时,我们发现需要为 KV 注入步骤编写一个融合 kernel,以提高利用率和吞吐量。

这里有一个通用教训:推测器必须比目标运行得更快,这通常意味着它们更小。较小的模型难以饱和内存和算术带宽,并且在运行于对较大模型最优的相同硬件上时更容易产生主机开销。推测器和目标的分离很有趣,但我们预计通信延迟会将其限制在少数小众用例中。

kernel 融合的极限是 megakernel——一个运行整个模型的单一 kernel。由于 megakernel 编写的工程成本很高(这使得普通的 kernel 编写看起来像 bash 脚本),这些以前很少见。当代的 megakernel 方法,如 Hazy Research 的这项工作,使用设备上的"解释器"以最大并发和最大重用执行来自高级程序的指令,取得了令人印象深刻的结果。随着编码 agent 的兴起,工程成本正在下降,包括在 kernel 编写方面。请参阅我们客户 Recursive Superintelligence 的这篇博客文章,了解有趣的早期结果(以及关于奖励黑客的警示故事)。

有损推测解码

由于推测解码是无损的,它是提供从特定模型返回样本的 API 的通用推理提供商的绝佳选择。但这种无损保证是有约束的

鉴于最近专有推理领域的事件,越来越多的组织正在考虑拥有自己的推理并使用开放模型。当你拥有自己的推理时,你可以根据自己的需求进行优化——包括用模型行为的一些变化来换取延迟的巨大改进。

飞轮的愿景

让我们勾勒出推测器和内部推理如何协同工作,以提供一个在质量、延迟和成本上持续改进的系统。

典型的组织使用通用基础模型(通常通过专有提供商)来原型化推理应用。

一旦应用原型化,你就可以投入工程工作来托管推理。在 Modal,我们正在使其尽可能简单——下周会有更多内容。原型化期间开发的 traces 和 evals 使这种过渡无缝。通用的预训练推测器模型确保成本和延迟得到控制,且不影响质量。

一旦你从这个自托管推理中获得了数万个样本,你就可以训练一个自定义推测器。自定义推测器可用于在固定延迟下降低成本,或在固定成本下降低延迟。

一旦你有了更多样本,你可以将部署的目标模型蒸馏(硬或软)成一个更小的模型,进一步降低延迟和/或成本,而不损害质量。关键是,你用于构建 evals 和训练推测器的相同数据源可以用于蒸馏。

现在你重复这个过程——以更小的模型作为新的基线。

由于整个堆栈基于计算和数据,算法、模型和硬件的改进都会加速它。这意味着来自蒸馏和推测的质量、成本降低和性能的复合循环,是建立在你组织内外许多改进的复合循环之上的。

如果你对此感兴趣,请联系我们。如果你对构建支持此功能的基础设施感兴趣,我们正在招聘

译自 Modal · 官方 · 录于 二〇二六年六月二十日