音乐
暂未播放
DFlash 块扩散解码:以并行扩散替代自回归草稿,实现无损 6 倍推理加速

背景与问题定义#
大语言模型的推理有一个根本性矛盾:transformer 的并行计算能力在预填充阶段可以充分利用,但在解码阶段却几乎完全被浪费。
自回归解码的本质决定了每个 token 的生成都依赖前一个 token。对于 batch size 为 1 的交互式场景,每次前向传播只产生一个 token,GPU 的数千个计算核心大部分时间在等待数据搬运。以一台搭载 H100 的推理服务器为例,解码阶段的 MFU(Model FLOPs Utilization)通常不到 5%——95% 以上的算力在闲置。
这个问题催生了投机解码:用一个小型草稿模型快速预测多个候选 token,然后让目标模型一次性验证整个候选块。被接受的 token 直接使用,被拒绝的从分歧点重新采样。理想情况下,“草稿+验证”的耗时远小于逐个生成,就能实现显著的端到端加速。
投机解码已有三代代表性工作:
- 第一代——独立草稿头(Medusa):在目标模型上附加多个独立分类头,每个头直接预测未来第 k 个 token。不需要单独的草稿模型,但因为各头之间没有条件依赖,预测质量差,接受率低。
- 第二代——自回归草稿模型(EAGLE 系列,含 EAGLE-3):用一个轻量级自回归 transformer 作为草稿模型,每次预测一个 token,逐步构建候选序列。EAGLE-3 能达到 2-3 倍加速,但草稿过程仍然是逐 token 的:预测 8 个草稿 token 需要 8 次前向传播。
- 第三代——DSpark 半自回归草稿:之前文章已经详细讲过。DSpark 把草稿生成做成”一次并行预测 + 置信度校验”,在半自回归框架下实现了最高 85% 的生成加速。但 DSpark 的草稿仍然是在序列维度上的一次性预测,缺乏迭代纠错机制。
一个自然的追问是:能不能让草稿模型也像图像的扩散模型那样,一次性并行生成整个候选块?
这就是 DFlash 要回答的问题。
核心思想#
DFlash(Block Diffusion for Flash Speculative Decoding)的核心思路只有一句话:
用轻量级块扩散模型替代自回归草稿模型,将整个草稿块的所有 token 在一次前向传播中并行生成,然后用目标模型一次性验证。
这里的关键词是”块扩散”。不同于图像扩散模型在连续的高斯噪声空间中迭代去噪,DFlash 的”扩散”发生在离散 token 空间:一个候选块中,除第一个锚点 token 外的所有位置被初始化为 [MASK] token,等效于”全噪声”状态;草稿模型的一次前向传播完成从”全噪声”到”预测 token”的去噪过程。
打个比方:自回归草稿模型像一个打字员,逐字敲出草稿;DFlash 像一个填字游戏玩家,看着上下文和空格位置,一眼把整个空填完。
DFlash 与已有方法的本质区别:
| 方法 | 草稿生成方式 | 草稿耗时 | 块大小可扩展性 |
|---|---|---|---|
| EAGLE-3 | 自回归逐 token | 线性增长 O(k) | 差,k>8 后延时代价超过收益 |
| DSpark | 半自回归并行 | 接近常数 | 中等,受置信度调度影响 |
| DFlash | 块扩散并行 | 接近常数 | 优,k 增长几乎不增加草稿耗时 |
这个本质区别的代价是:每个 token 位置的条件依赖被削弱了。自回归生成中,第 k 个 token 显式地以第 1 到第 k-1 个 token 为条件;块扩散中,所有位置同时预测,只能以锚点 token 和目标模型的隐藏状态为条件。这会导致单 token 预测准确率下降——但 DFlash 通过一个关键设计弥补了这一点:KV 注入。
原理详解#
投机解码的通用框架#
在深入 DFlash 之前,先回顾投机解码的通用流程。
设目标模型为 T,草稿模型为 D,块大小为 k。给定前缀序列 x<t:
- 草稿阶段:D 生成候选序列 x^t,x^t+1,…,x^t+k−1。
- 验证阶段:T 对 (x<t,x^t,…,x^t+k−1) 做一次前向传播,得到每个位置的输出分布 pT(⋅∣x<t,x^<t+i)。
- 接受/拒绝:从第一个位置开始,逐一比较草稿 token x^t+i 与目标模型在该位置的采样结果。找到第一个不匹配的位置 t+j,接受前 j 个 token,在该位置重新采样,丢弃后面的所有 token。
关键性质:无论草稿模型如何,验证后的输出分布严格等于目标模型的自回归分布。投机解码是”无损加速”——加速多少取决于草稿模型与目标模型的一致程度,但正确性不会妥协。
实际加速比可以写为:
speedup=tdraft+tverifyk⋅ttarget其中 ttarget 是目标模型生成一个 token 的耗时,tdraft 是草稿阶段耗时,tverify 是验证阶段耗时。tverify 通常接近 ttarget(只多了一点注意力计算开销),所以加速比主要由两个因素决定:(1)草稿模型的预测精度(影响有效接受的 token 数),(2)草稿耗时相对于目标模型耗时的比例。
块扩散:从逐 token 到全块并行#
DFlash 的草稿阶段完全抛弃了自回归结构。给定锚点 token(即上一轮目标模型产生的 bonus token),草稿块构建如下:
- 将锚点 token 放在位置 0。
- 位置 1 到 k−1 全部填充为
[MASK]token。 - 整个块通过草稿模型做一次前向传播。
- 所有
[MASK]位置的输出 logits 直接用作预测 token。

图源:NVIDIA Technical Blog《Boost Inference Performance up to 15x on NVIDIA Blackwell Using DFlash Speculative Decoding》
草稿模型内部使用双向(非因果)注意力。这意味着位置 3 的预测可以同时看到位置 1、2、4、5 的信息——这在自回归草稿中是不可能的。双向注意力允许模型利用”全局一致性”来生成更连贯的草稿块;例如在生成代码时,如果位置 2 预测了 for,位置 5 可以同时”知道”这个上下文并预测 range,而不需要等位置 2 先生成出来。
但这里有一个微妙之处:双向注意力的”全局一致性”有利有弊。好处是跨位置的信息交换;坏处是各个位置的预测实际上互相影响,可能导致”集体错觉”——一个位置的错误预测通过注意力扩散到其他位置,造成整个块的系统性偏差。这也是为什么后续工作 JetSpec 将注意力改回因果结构的动机之一。
草稿耗时的分析如下。设草稿模型的一次前向传播耗时为 td,目标模型的一次前向传播耗时为 tT。对于自回归草稿模型(如 EAGLE-3),生成 k 个草稿 token 的耗时为 k⋅td;对于 DFlash,无论 k 多大,耗时都是 td。
取一组典型数据:5 层 DFlash 草稿模型的 td≈0.01tT(即目标模型耗时的 1%)。EAGLE-3 单层草稿模型的每步耗时约为 0.02tT。生成 16 个草稿 token 时,DFlash 只需 0.01tT,EAGLE-3 需要 16×0.02tT=0.32tT——差了 32 倍。
这就是为什么即使 DFlash 的单 token 预测准确率低于 EAGLE-3,它的端到端加速比仍然更高:草稿开销低到几乎可以忽略,使得更大的块成为可能。
KV 注入:让每个草稿层直接感知目标模型#

图源:DFlash 论文 Figure 2(arXiv:2602.06036)
这是 DFlash 最关键的设计决策。要理解为什么需要它,先看 EAGLE-3 的做法。
EAGLE-3 将目标模型最后一层的隐藏状态拼接到草稿模型的输入嵌入中。这个设计有一个根本局限:目标模型的特征信号只在输入层注入,经过多个 transformer 层的变换后,信号逐渐被稀释。深层草稿层几乎看不到目标模型的原始特征,只能依赖前面层传来的、经过多次变换的间接信号。
DFlash 的做法完全不同:
-
从目标模型的多个中间层提取隐藏状态。默认选取 5 层,均匀分布在目标模型的第 2 层到倒数第 3 层之间(例如在 28 层模型中取第 [1, 8, 14, 20, 27] 层)。这些层捕获了不同粒度的语义信息——浅层有更多局部句法特征,深层有更多全局语义特征。
-
融合提取的隐藏状态。通过一个线性投影层,将来自不同层的隐藏状态(各自维度为 dmodel)拼接后映射到一个紧凑的”目标上下文特征”向量:
hctx=Wf⋅[hl1;hl2;…;hlm]+bf其中 Wf∈Rdmodel×(m⋅dmodel) 是投影矩阵,m 是选中的目标模型层数。
-
将融合特征注入每个草稿层的 KV 缓存。对草稿模型的每一层,hctx 被分别投影为 Key 投影和 Value 投影,写入该层注意力模块的 KV 缓存中:
Kctx(l)=hctx⋅WK(l),Vctx(l)=hctx⋅WV(l)其中 l 是草稿层索引。在注意力计算中,草稿 token 的 Query 不仅对草稿 token 自身的 Key/Value 做注意力,也对注入的 Kctx(l)/Vctx(l) 做注意力:
Attention(Qdraft,[Kdraft;Kctx],[Vdraft;Vctx]) -
跨轮复用。同一个草稿步骤中,hctx 只需要提取一次,然后在所有草稿层、多个草稿轮次中复用(存储在 KV 缓存中)。
这个设计的核心优势:每个草稿层都能直接接触到目标模型的多粒度语义特征。浅草稿层能看到目标浅层的句法信息,深草稿层能看到目标深层的语义信息。这种”深度耦合”远比只在输入层注入一条信号有效。
实验数据也印证了这一点。在 GSM8K 数学推理任务上,同等 5 层草稿模型的条件下:
- 仅输入层融合(EAGLE-3 方式):平均接受长度 τ=3.5
- 逐层 KV 注入(DFlash 方式):平均接受长度 τ=4.2
20% 的接受长度提升,完全来自特征注入方式的改变。这直接转化为约 20% 的额外加速。
训练策略:随机锚点采样与衰减加权损失#
DFlash 的训练有三个关键设计。
随机锚点采样
推理时,草稿模型需要在任意位置启动扩散过程——本轮可能的锚点 token 可以出现在回复序列的任何位置。训练必须覆盖这种多样性。
具体做法:在每条训练样本的回复序列中,随机采样多个有效位置作为锚点(只采样 loss_mask > 0.5 的位置,排除填充和提示部分)。每个锚点标记一个块的起始位置,其后的 k−1 个位置被 mask 为预测目标。多个块被拼接成一条训练序列,通过 Flex Attention 的稀疏掩码隔离:
- 块内双向可见:同一块内的所有位置可以互相看到(双向注意力)。
- 目标特征始终可见:所有位置都能注意到 KV 注入的 hctx。
- 块间完全隔离:不同块之间不可见,防止信息泄漏。
每个训练序列最多包含 512 个锚点,这意味着每个样本可以提供多达 512 个独立的草稿训练信号。这种高密度采样极大地提高了训练效率——DFlash 用 EAGLE-3 约 1/5 的训练数据量就超越了它的表现。

图源:DFlash 论文 Figure 4(arXiv:2602.06036)
指数衰减位置权重
投机解码的验证过程是逐位置顺序进行的:一旦在位置 j 发现草稿 token 与目标模型不一致,位置 j 之后的所有 token 都被丢弃。这意味着早期位置的准确率远比晚期位置重要——位置 1 的错误直接浪费整个块,位置 15 的错误只浪费最后一个 token。
DFlash 用一个指数衰减权重来体现这个优先级。对块内第 i 个预测位置(i=1,2,…,k−1,i=0 是锚点不计 loss),权重为:
wi=exp(−γi−1)其中 γ 是衰减因子。当 γ 较小时(如 γ=3),早期位置的权重远大于晚期位置;当 γ 较大时(如 γ=10),权重分布更均匀。论文中的默认设置倾向于较小的 γ,以强约束早期位置精度。
最终训练损失为加权交叉熵:
LDFlash=i=1∑k−1wi⋅CE(p^i,yi)其中 p^i 是草稿模型在位置 i 的预测分布,yi 是目标模型在该位置的真实 token。
D-PACE 变体(Dynamic Position-Aware Cross-Entropy)
标准 DFlash 损失对所有训练样本使用固定的衰减权重。D-PACE 更进一步:动态估计每个位置的学习难度,对困难位置分配更高权重。
具体做法:维护每个位置的平均历史损失 ℓˉi。对当前批次,计算:
wiDPACE=wi⋅ℓˉiℓi如果一个位置的损失显著高于历史平均,说明该位置对当前样本特别困难,应获得更高权重。这使得训练更聚焦于每个样本的”瓶颈 token”——那些草稿模型反复预测错误的关键位置。
验证流程#
验证阶段保持投机解码的标准流程,没有任何变化:
- 目标模型接收
[前缀; 锚点; 草稿1; 草稿2; ...; 草稿k-1]的完整序列。 - 一次前向传播后,得到每个位置的条件概率分布 pT(⋅∣前缀,锚点,草稿<i)。
- 从位置 1 开始,逐一比较草稿 token 与目标模型的贪婪采样结果(或温度采样结果)。
- 找到第一个不匹配的位置,接受之前的所有 token,在该位置用目标模型重新采样作为 bonus token。
- 返回步骤 1,以新 bonus token 作为锚点开始下一轮。
整个过程保证了最终输出分布严格等于目标模型的自回归分布——这是”无损加速”的含义。
架构与实现细节#
草稿模型架构#
DFlash 草稿模型是一个极轻量级的 Qwen3 风格 decoder-only transformer。一个典型的 5 层草稿模型参数约 340M,主要配置如下:
| 参数 | 值 | 说明 |
|---|---|---|
| 层数 | 5 | 远少于目标模型(通常 28-40 层) |
| 隐藏维度 | 与目标模型相同 | 保证特征维度对齐 |
| 注意力头数 | 22(Q)/ 22(KV) | 与目标模型匹配 |
| 头维度 | 128 | 标准配置 |
| 中间层维度 | 9728 | FFN 膨胀比约 3.5 |
| 词表大小 | 与目标模型相同 | 共享嵌入层和 LM Head |
| 块大小 | 8 或 16 | 高并发场景用 8,低并发用 16 |
草稿模型共享目标模型的嵌入层(embed_tokens)和输出投影层(lm_head),且这两部分在训练和推理中都是冻结的。这意味着草稿模型不需要存储两份词表,节省了大量显存。
为什么用 5 层?这是精度与速度的权衡。层数越多,预测精度越高,但草稿耗时也线性增加。论文的消融实验显示:2 层草稿在接受长度上显著弱于 5 层;8 层相比 5 层的接受长度提升很小(<5%),但耗时增加了近 60%。5 层是 experimentally found sweet spot。
目标特征提取与融合#
目标模型中间层特征的提取在目标模型预填充阶段完成,不需要额外的目标模型前向传播。具体流程:
- 目标模型处理输入前缀,逐层计算直到最后一层。
- 在预设的中间层位点(如 [1, 8, 14, 20, 27])处,hook 该层的隐藏状态输出。
- 将 hook 到的隐藏状态保存到 KV 缓存中,供后续草稿轮次使用。
一个重要的实现细节:选定的是哪些层? 默认策略是从目标模型的第 2 层到倒数第 3 层之间均匀采样 5 层。为什么跳过了第一层和最后两层?第一层的隐藏状态太接近输入嵌入,语义信息太少;最后两层的隐藏状态已经高度压缩,包含过多任务特定信息,用于草稿模型的通用预测时反而可能引入噪声。
关键伪代码#
以下伪代码展示了 DFlash 推理的核心流程:
1def dflash_generate(target_model, draft_model, prefix, block_size=16):2 # 1. 预填充:目标模型处理前缀3 # target_features 是从多个中间层 hook 的隐藏状态4 logits, target_features = target_model.prefill(5 prefix,6 hook_layers=[1, 8, 14, 20, 27]7 )8 # bonus_token 是预填充的输出 token9 bonus_token = sample(logits[-1])10 generated = [bonus_token]11
12 # 2. 将目标特征融合并注入草稿模型的所有层13 context_feature = draft_model.fuse_features(target_features)14 draft_model.inject_kv_context(context_feature) # 注入所有草稿层15
16 while not done:17 # 3. 构建草稿块:[anchor, MASK, MASK, ..., MASK]18 anchor_id = token_to_id(bonus_token)19 draft_block = [anchor_id] + [MASK_TOKEN_ID] * (block_size - 1)20
21 # 4. 块扩散:一次前向传播预测所有 MASK 位置22 draft_logits = draft_model.forward(23 draft_block,24 attention_mask="bidirectional", # 块内双向注意力25 use_kv_context=True # 使用注入的目标特征26 )27 # 取每个 MASK 位置的 argmax 作为草稿 token28 draft_tokens = [argmax(logits[i]) for i in range(1, block_size)]29
30 # 5. 验证:目标模型一次性检查整个块31 full_seq = generated + draft_tokens32 target_logits = target_model.forward(full_seq)33
34 # 6. 接受/拒绝35 accepted = []36 for i, draft_tok in enumerate(draft_tokens):37 target_tok = argmax(target_logits[len(generated) + i])38 if draft_tok == target_tok:39 accepted.append(draft_tok)40 else:41 # 分歧点:用目标模型的 token 作为新 bonus42 bonus_token = target_tok43 accepted.append(bonus_token)44 break45 else:46 # 全部接受:最后一个位置的预测作为 bonus47 bonus_token = sample(target_logits[-1])48
49 generated.extend(accepted)50
51 return generated训练流程#
训练数据以对话形式的指令微调数据为主。每条样本包含指令、上下文和期望回复。训练流程:
- 数据准备:用目标模型对训练数据做一次完整的前向传播,在每个位置的隐藏状态都保存下来(这一步最耗时,但只做一次)。
- 锚点采样:在每条回复中随机采样多达 512 个锚点位置。
- 块构建与掩码:为每个锚点构建
[anchor, MASK, ..., MASK]的草稿块,块大小等于训练块大小(通常 16)。 - 多块拼接:将所有块按 Flex Attention 稀疏掩码拼接成一条长序列,块间互不可见。
- 前向+损失:草稿模型前向传播,计算衰减加权交叉熵损失。
- 优化:AdamW 优化器,学习率 6×10−4,线性衰减。
训练数据量因模型而异。以 Qwen3-Coder-30B-A3B 的 DFlash 草稿模型为例,训练数据包括:
- NVIDIA Nemotron-Post-Training-Dataset-v2(代码部分):约 200K 样本
- evol-codealpaca-v1:约 50K 样本
- Cline 执行轨迹:约 39K 样本
- 合计约 289K 样本
相比之下,EAGLE-3 的训练使用了约 1.4M 样本的 open-perfect-blend 数据集。DFlash 用约 1/5 的数据量就超越了 EAGLE-3 的加速比,数据效率显著更高。原因在于:
- 每个样本通过多锚点采样提供了数百个训练信号,而非自回归方法的一个。
- KV 注入提供了更强的条件信号,降低了模型对数据量的依赖。
性能表现#
主要基准测试#
以下数据来自 DFlash 论文和社区验证,涵盖不同模型规模、不同硬件、不同工作负载。

图源:DFlash 论文 Figure 1(arXiv:2602.06036)
Qwen3-8B 上的加速比(greedy decoding):
| 任务 | 基准 (tok/s) | EAGLE-3 加速 | DFlash 加速 |
|---|---|---|---|
| MATH-500 | 28 | 2.4× | 6.08× |
| HumanEval | 25 | 2.3× | 5.52× |
| GSM8K | 22 | 2.1× | 4.32× |
| MT-Bench | 30 | 1.9× | 3.14× |
| ShareGPT | 32 | 1.7× | 2.71× |
代码和数学类任务加速最显著(4-6×),因为这类文本的结构性强、可预测性高,块扩散能充分利用全局一致性。开放域对话的加速较小(2-3×),但仍然是显著的。
Qwen3.6-35B-A3B(MoE 模型,GB10 平台):
| 基准 | 无投机 (tok/s) | DFlash (tok/s) | 加速比 |
|---|---|---|---|
| GSM8K | 22 | 95 | 4.3× |
| HumanEval | 25 | 110 | 4.4× |
| MT-Bench | 28 | 86 | 3.1× |
| ShareGPT | 30 | 82 | 2.7× |
MoE 模型由于稀疏激活的特性,单 token 生成的计算量相对更大,投机解码的相对收益更高。
Gemma 4 26B-A4B(RTX 5090,三种方法的直接对比):
| 方法 | 解码速度 (tok/s) | 加速比 | 接受长度 | 单 token 接受率 |
|---|---|---|---|---|
| 无投机 | 192 | 1.00× | — | — |
| EAGLE-3 | 325 | 1.69× | 2.44 | 48% |
| DFlash (k=15) | 422 | 2.19× | 3.45 | 16% |
| MTP | 411 | 2.13× | 3.85 | 71% |
注意这个表中一个反直觉的数据点:DFlash 的单 token 接受率只有 16%,远低于 EAGLE-3 的 48%,但接受长度(3.45)和端到端加速(2.19×)都更高。这是因为 DFlash 一次并行生成 15 个草稿 token,即使大部分被拒绝,只要平均有 3.45 个被接受,就已经值得了——生成这 15 个草稿的开销几乎和 EAGLE-3 生成 3 个草稿差不多。
按工作负载分解(Gemma 4,DFlash vs EAGLE-3 加速比):
| 工作负载 | EAGLE-3 | DFlash |
|---|---|---|
| 散文/叙事 | 1.30× | 1.04× |
| 问答 | 1.50× | 1.32× |
| 代码 | 1.75× | 1.55× |
| JSON 输出 | 2.01× | 2.68× |
| 重复性文本 | 1.88× | 4.37× |
DFlash 在不同工作负载上的表现差异极大——从散文叙事的几乎无加速,到重复性文本的 4.37 倍加速。这种”冰火两重天”的特征需要在实际部署中认真评估。如果你的应用主要是开放域闲聊,DFlash 可能不是最佳选择;如果是结构化 JSON 输出或代码补全,DFlash 的收益是压倒性的。
NVIDIA Blackwell 上的表现#
DFlash 在 Blackwell GPU 上的优势尤为突出,因为 Blackwell 的设计恰好契合了 DFlash 将串行工作转为并行工作的思想。
在 DGX B300(8× B300 GPU)上使用 TensorRT-LLM + DFlash 部署 gpt-oss-120b 模型:
- 无投机基准:~40 tok/s/用户
- DFlash(k=16):500-600 tok/s/用户,约 15 倍吞吐量提升
- 相比 EAGLE-3:1.5 倍额外吞吐量提升
这个 15 倍的数字需要理解其条件:它测量的是高并发下的吞吐量增益,不是单用户的延迟改善。当数百个用户同时请求时,DFlash 通过将解码从内存带宽瓶颈转变为计算瓶颈,充分利用了 Blackwell 的 15 PFLOPS NVFP4 算力。单用户 batch size 为 1 时,加速比在 2-4 倍之间。

图源:NVIDIA Technical Blog《Boost Inference Performance up to 15x on NVIDIA Blackwell Using DFlash Speculative Decoding》
在 vLLM 部署中(同等工作负载、相同并发数):
- Coding 数据集:DFlash 2.6× vs EAGLE-3 1.8×
- RAG 数据集:DFlash 2.3× vs EAGLE-3 1.7×
- Reasoning 数据集:DFlash 2.3× vs EAGLE-3 1.8×
在 SGLang 部署中:DFlash 实现了约 5.1 倍的吞吐量提升。
消融实验#
DFlash 论文中的关键消融实验揭示了几个设计选择的重要性:
KV 注入 vs 输入拼接
取 5 层 DFlash 草稿模型,在 GSM8K 上对比两种特征注入方式:
| 注入方式 | 接受长度 τ |
|---|---|
| 输入层拼接(EAGLE-3 方式) | 3.5 |
| 逐层 KV 注入(DFlash 方式) | 4.2 |
KV 注入将接受长度提升了 20%。这种优势随草稿模型加深而放大:层数越多,输入层信号被稀释的效应越明显,逐层注入的优势越大。
草稿模型深度
在 Qwen3-8B 上,保持其他配置不变,改变草稿模型层数:
| 层数 | 接受长度 | 草稿耗时 (ms) | 端到端加速 |
|---|---|---|---|
| 2 | 3.1 | 0.8 | 1.9× |
| 5 | 4.2 | 1.5 | 2.7× |
| 8 | 4.3 | 2.6 | 2.1× |
8 层草稿的接受长度几乎不增长(4.2 → 4.3),但草稿耗时近乎翻倍(1.5 → 2.6 ms),导致端到端加速反而下降。这表明草稿模型的深度存在一个”饱和点”,超过之后边际收益为负。
块大小
| 块大小 k | 接受长度 | 端到端加速 |
|---|---|---|
| 4 | 2.8 | 1.8× |
| 8 | 3.5 | 2.3× |
| 16 | 4.2 | 2.7× |
| 32 | 4.8 | 2.5× |
k=32 时加速开始下降,因为虽然接受长度仍在增长(4.8),但验证阶段需要处理更长序列,验证耗时的增加开始超过额外接受 token 的收益。
集成与部署生态#
DFlash 论文发表于 2026 年 2 月,被 ICML 2026 接收。到 2026 年 6 月,NVIDIA 正式宣布将 DFlash 集成到其推理生态中,并开源了 20 个预训练草稿模型 checkpoint 在 Hugging Face 上。
推理框架集成#
DFlash 目前支持的推理框架:
| 框架 | 集成方式 | 状态 |
|---|---|---|
| vLLM | speculators 插件,--speculative-model 指定 DFlash 草稿模型 | 生产可用 |
| SGLang | SpecForge 子项目,原生支持 DFlash 算法 | 生产可用 |
| TensorRT-LLM | NVIDIA 原生集成,Blackwell 优化 | 生产可用 |
| llama.cpp | --spec-type draft-dflash | 实验性 |
vLLM 中的使用方式(来自 vLLM Speculators 文档):
1vllm serve Qwen/Qwen3-8B \2 --speculative-model z-lab/Qwen3-8B-DFlash \3 --speculative-config '{4 "method": "dflash",5 "block_size": 16,6 "target_layer_ids": [1, 8, 14, 20, 27]7 }'SGLang 中的使用方式:
1python -m sglang.launch_server \2 --model Qwen/Qwen3-8B \3 --speculative-algorithm dflash \4 --speculative-draft-model z-lab/Qwen3-8B-DFlash \5 --speculative-block-size 16支持的模型家族#
截至 2026 年 8 月,Hugging Face 上已有覆盖以下模型族的 DFlash 草稿模型:
- Qwen3.x / Qwen3.5 / Qwen3.6 系列(8B、14B、32B、35B-A3B、Coder 30B-A3B 等)
- Gemma 4 系列(26B-A4B 等)
- Llama 3.1 系列(8B 等)
- gpt-oss 系列(120B 等)
- Kimi K2.6 / K2.7 系列
- Alpamayo-1.5(NVIDIA,自动驾驶 VLA)
训练自己的 DFlash 草稿模型#
NVIDIA 提供了 TensorRT-Model-Optimizer(modelopt>=0.43.0)中的 DFlash 训练工具链:
1from modelopt.speculative import DFlashTrainer2
3trainer = DFlashTrainer(4 target_model_path="Qwen/Qwen3-8B",5 block_size=16,6 num_draft_layers=5,7 target_layer_ids=[1, 8, 14, 20, 27],8 gamma=3.0, # 衰减因子9 max_anchors=512, # 每样本最大锚点数10)11trainer.train(12 dataset="your-dataset",13 output_path="./my-dflash-drafter",14 learning_rate=6e-4,15 max_steps=10000,16)训练硬件需求相对亲民:Pilot 品质的草稿模型(5K 样本)可以在单张 RTX PRO 6000 Blackwell(96GB)上完成;生产品质(2M+ 样本)需要多 GPU 训练。
草稿模型的 top-1 匹配率随训练数据量的增长情况:
| 训练数据量 | 预期 top-1 匹配率 |
|---|---|
| 5K(pilot) | ~25% |
| 50K | ~55% |
| 500K | 接近收敛 |
| 2M+(生产级) | 收敛到最优 |
局限与未解决的问题#
工作负载敏感性强#
DFlash 在不同类型的文本上表现差异极大。在散文和叙事性文本上,加速比接近 1×(几乎无加速甚至轻微退化),因为这类文本的 token 间依赖关系复杂,块扩散无法有效捕获。在高度结构化的输出(JSON、代码、数学推导)上,加速比可达 4-6×。
这意味着在实际部署中需要做动态策略选择:根据请求类型(或观察到的接受率)在 DFlash、EAGLE-3 和无投机解码之间切换。NVIDIA 的 ModeSwitch-LLM 和 SGLang 的请求级路由已经在探索这个方向。
草稿模型需要逐模型定制#
每个目标模型都需要训练一个对应的 DFlash 草稿模型。草稿模型的隐藏维度、注意力头配置、词表都必须与目标模型对齐。这意味着:
- 不能像 EAGLE-3 那样部分复用草稿架构
- 模型生态中每增加一个新目标模型,都需要额外的草稿模型训练工作
- 微调过的目标模型需要重新训练或至少重新校准草稿模型
高并发场景下的接受率下降#
DFlash 论文中的多数加速数字来自低并发(batch size ≤ 8)或单请求场景。在高并发(batch size ≥ 32)条件下,由于目标模型的 KV 缓存压力增大、批处理效率下降,实际接受的草稿 token 数可能减少。
社区报告显示,在 32 并发时,Qwen3.6-35B-A3B 的 DFlash 加速比从 4.3× 下降到约 2.9×——仍然显著,但下降幅度值得注意。
块扩散的双向注意力问题#
DFlash 的块内双向注意力使得每个位置的预测互相影响。这种”全局一致性”在某些场景下是优势(如 JSON 结构生成),但在需要严格因果关系的场景下会导致系统性错误(如数学证明中的逐步推导)。
这正是后续工作 JetSpec(2026 年 6 月,arXiv:2606.18394)要解决的问题。JetSpec 在 DFlash 的基础上做了两个关键改动:
- 块内注意力改为因果结构:位置 i 只能看到位置 0 到 i,保证每个位置的预测显式以前面所有位置的预测为条件。
- 前向 KL 蒸馏损失:用温度缩放的前向 KL 散度替代硬标签交叉熵,让草稿模型学习目标模型的完整软分布,而非仅仅 top-1 token。
JetSpec 将加速比继续推高至最高 9.64 倍。
视觉语言模型支持有限#
当前的 DFlash 实现在视觉语言模型上支持有限。当输入包含视觉信息时,DFlash 的草稿过程被抑制(退化为无投机解码),因为草稿模型无法有效利用视觉特征。这是未来工作的一个方向。
小结#
DFlash 代表了投机解码的一次范式转移:用块扩散的并行生成取代自回归的逐 token 生成。
这个思路的关键洞察是:在投机解码中,草稿模型的单 token 准确率不是唯一重要的指标。推理加速由”接受长度 / 草稿耗时”决定,而 DFlash 通过将草稿耗时压到接近常数,使得在单 token 准确率显著低于自回归方法的情况下,仍然实现了更高的端到端加速比。
KV 注入是让这个设计可行的关键技术。通过将目标模型的中间层隐藏状态注入草稿模型的每一个 transformer 层,DFlash 在缺乏显式因果条件的情况下仍能维持可接受的预测精度。
这篇工作的工程影响已经显现:NVIDIA 的全面集成、vLLM 和 SGLang 的原生支持、20+ 个预训练草稿模型的发布,意味着 DFlash 正在从一篇论文变成生产推理栈的标准组件。
对于关注推理加速的从业者,有几个值得跟进的方向:
- JetSpec 的因果树草稿(arXiv:2606.18394):将加速比继续推高至接近 10×。
- D-PACE 的动态难度感知训练:进一步优化草稿模型在”瓶颈 token”上的精度。
- 请求级自适应路由:根据负载类型在 DFlash/EAGLE-3/无投机之间动态切换。
参考资料#
- DFlash: Block Diffusion for Flash Speculative Decoding — Jian Chen, Yesheng Liang, Zhijian Liu, ICML 2026
- DFlash GitHub 仓库 — z-lab
- Boost Inference Performance up to 15x on NVIDIA Blackwell Using DFlash Speculative Decoding — NVIDIA Technical Blog
- vLLM Speculators: DFlash Algorithm — vLLM Project
- SGLang SpecForge: DFlash Training Pipeline — SGLang Project
- JetSpec: Breaking the Scaling Ceiling of Speculative Decoding with Parallel Tree Drafting — Hao AI Lab, 2026
- EAGLE-3: Scaling up Inference Acceleration of Large Language Models via Training-Time Test — Yuhui Li et al., NeurIPS 2025,对比基线方法
- DSpark:半自回归生成与置信度调度的投机解码 — 本系列前作
- NVIDIA TensorRT-Model-Optimizer DFlash Documentation — NVIDIA NeMo AutoModel
- DFlash Hugging Face Models — z-lab on Hugging Face
文章分享
如果这篇文章对你有帮助,欢迎分享给更多人!
部分内容可能已过时
评论区
分享你的想法,与大家交流讨论
音乐
暂未播放



