登録して招待リンクを共有すると、動画再生報酬と紹介報酬を獲得できます。

yibie
@yibie
参加 November 2008
2.5K フォロー中    4.9K ファン
投机解码的 drafter 从来都是一个 token 一个 token 地猜。做出 DFlash 的推理公司 Inco AI 说这没必要:正确的 token 本来就在候选列表里,整块并行预测之后挑出一条连贯路径,输出不变,每次验证多赚一个完整的 token。 《DFlash 2:保持并行起草》 推理是 agent 时代的瓶颈。agent 会读、会规划、会调用工具,常常一跑就是几小时甚至几天。它们消耗 token 的速度,是聊天场景从未达到过的。而每一个 token 都要在模型上跑一次完整的前向传播。在 Inco AI,我们在构建一套面向未来 token 经济学的推理栈。这篇文章是一次预览。 我们的团队 1 月发布了 DFlash(论文: SGLang、vLLM、TensorRT-LLM 和 llama.cpp 里。NVIDIA 在 Blackwell GPU 上用它测到了最高 15 倍的吞吐;Google 报告在 TPU 上每秒 token 数提升 3 倍;CoreWeave 生产环境的 Kimi K2.7 Code 端点(Artificial Analysis 上该模型最快的端点)默认就跑 DFlash。生态已经在它之上构建:NVIDIA、Red Hat、Modal 都发布了 DFlash drafter;Meta(Muse Glimmer)、Poolside(Laguna)、小米(MiMo-V2.5-Pro)、NVIDIA(Nemotron 3.5 Lightning)随自家模型发布官方 drafter。在 Hugging Face 上,DFlash 模型被下载了超过 350 万次(截至 2026 年 8 月)。 投机解码是现代推理栈的核心组件之一。一个小 drafter 模型猜出一整块 token,目标模型在一次前向传播里验证整块。猜得好,一次前向变成多个 token;猜得差,丢掉重来。但多年来,起草本身一直是自回归的:一次一个 token。DFlash 让它也变成了一次通过:整块、每个位置,并行预测。 (演示视频:DFlash 2 在 Apple M5 Max 上用 oMLX 为 Qwen3.8-27B 起草,与自回归解码并排对比。 DFlash 2 把并行起草又往前推了一步:每次验证通过多产出 20% 以上的输出,增加的周期延迟只有约 1%,而输出可证明不变。跨基准测试的增益在 16–25%。配合今天发布的 Qwen3.8-27B drafter,SGLang 在 batch size 1 下达到自回归解码 2.7–3.4 倍的吞吐。每个位置独立预测,留下两处空间:选对 token,以及在块的末尾守住准确率。DFlash 2 把这两处都拿了回来,同时没有放弃一次性通过的设计。 现在就能跑 DFlash 2 已经跑在主流推理引擎里。 SGLang: pip install -U "sglang[all] @ git+" python -m sglang.launch_server \ --model-path Qwen/Qwen3.8-27B \ --speculative-algorithm DFLASH \ --speculative-draft-model-path incoai/Qwen3.8-27B-DFlash2 \ --speculative-num-draft-tokens 8 vLLM: pip install -U "vllm @ git+" vllm serve Qwen/Qwen3.8-27B \ --speculative-config '{ "method": "dflash", "model": "incoai/Qwen3.8-27B-DFlash2", "num_speculative_tokens": 7 }' llama.cpp: git clone cd llama.cpp git fetch origin pull/27342/head:pr-27342 git switch pr-27342 NVIDIA CUDA cmake -B build -DCMAKE_BUILD_TYPE=Release -DGGML_CUDA=ON cmake --build build -j Apple Silicon cmake -B build -DCMAKE_BUILD_TYPE=Release -DGGML_METAL=ON cmake --build build -j ./build/bin/llama-server \ -hf ggml-org/Qwen3.8-27B-GGUF:Q4_K_M \ -hfd incoai/Qwen3.8-27B-DFlash2-GGUF:Q4_K_M \ --spec-type draft-dflash \ --spec-draft-n-max 7 oMLX:下载安装支持 DFlash 2 的预构建版( 在 oMLX 里跑 Qwen3.8-27B 加 DFlash 2: 1. 打开 oMLX 的 Model Downloader,下载 mlx-community/Qwen3.8-27B-4bit 和 incoai/Qwen3.8-27B-DFlash2。 2. 打开 Model Manager,编辑 mlx-community/Qwen3.8-27B-4bit,配置 DFlash: • DFlash:enabled • Draft model:incoai/Qwen3.8-27B-DFlash2 • Draft quantization:enabled • Runtime block size:5 • Verify mode:dflash 3. 保存设置,加载目标模型。 对的 token 早就在候选里 DFlash 每个位置独立、并行地预测。每个选择单独看都合理,但没有什么让它们彼此咬合,一个不连贯的块会在验证时被截断。近期的方法如 Domino 和 DSpark,用顺序的 Markov head 重写每个位置的完整词表分布来买连贯性。但真的需要这种昂贵的自回归纠错吗? 不需要。证据就在 DFlash 自己的候选列表里。拿第一个位置来说:DFlash 的第一选择 85.4% 的情况下是对的,但正确的 token 99.5% 的情况下都在前 16 个候选里。即使第一选择错了,对的 token 通常也在列表上。 表 1:Recall@1(第一选择正确的概率)与 Recall@16(正确 token 出现在前 16 候选里的概率),按起草位置统计,条件是前面每个位置都正确。GSM8K 上的五层 Qwen3-4B DFlash。接受长度包含验证器产出的下一个 token。 • 位置 0:Recall@1 85.4%,Recall@16 99.5% • 位置 1:80.3%,97.3% • 位置 2:79.4%,94.8% • 位置 3:78.3%,92.6% • 位置 4:77.5%,90.8% • 位置 5:75.9%,89.4% • 位置 6:72.9%,87.8% • 接受长度:4.27(只看第一选择);6.79(从前 16 里选) 一个总能从前 16 个候选里挑对的那个 oracle,会把接受长度从 4.27 抬到 6.79。这个差距是纯粹的选择空间。我们只需要在候选里选出一条正确的路径。 图 1:一个周期里的选择器。只用 DFlash,每个位置保留自己的第一选择;这里两个相邻位置选了同一个词,结巴在验证时死掉。DFlash 2 保留每个位置的 top 候选,选择器在候选之间走出一条连贯路径;这里整块都活了下来。 一个轻量的路径选择器 连贯性大体是局部的:一个候选合不合适,主要取决于它前面的那个 token,所以给相邻对打分应该就够了。DFlash 2 保留每个位置前 16 个候选,给每一对相邻候选打分。对前一个 token a 和当前候选 b: S_t(a,b) = U_t(b) + ⟨A(a)⊙H(h_t), B(b)⟩ 分数分两部分。第一部分 U_t(b) 是 DFlash 自己的 logit:drafter 本身有多喜欢 b。第二部分问 b 接在 a 后面有多顺:A 和 B 给每个 token 一个紧凑的 256 维嵌入,两个嵌入在一个上下文门控 H(h_t) 下匹配,门控决定匹配的哪些部分算数。本质上,这是对相邻候选做的低秩双线性注意力。 打分全程并行。每个位置的每一对相邻候选一次性全部算完,不需要额外的 backbone 或 LM head 前向。唯一串行的部分,是最后在预计算好的分数上走一遍:从最后一个已验证 token 出发,贪心地跟着每一步最好的后继走,采样从同样的分数里抽取,拒绝采样恢复出精确的目标分布。 表 2:只加路径选择(不加卷积)的接受长度,GSM8K 上的五层 Qwen3-4B。开销相对纯 DFlash:drafter 增加的参数、起草-验证周期增加的延迟。 • DFlash:T=0 下 4.27,T=1 下 3.78 • + DSpark 纠错:+77.8M 参数,+9.6% 延迟;4.49,4.08 • + 路径选择(我们的):+2.0M 参数,+0.6% 延迟;4.61,4.25 选择器在 T=0 下给 DFlash 加 0.34 个 token,T=1 下加 0.47。两个设置下都超过 DSpark 的纠错,参数少约 40 倍,延迟开销低 16 倍。选择比预测便宜。而且还有空间:oracle 能到 6.79。成对打分是我们能想到的最简单的选择器,我们相信这里还有很多可探索的。 后缀衰减是个局部问题 我们还注意到上面两行 recall 都在块尾下滑。连 oracle 都在衰减:即使选择完美,准确率仍然从第一个位置的 99.5% 掉到最后一个位置的 87.8%。没有选择器能修这个,因为候选自己就不够了。我们把这个叫后缀衰减,它是 backbone 的问题。 一个嫌疑是容量:五层 backbone 可能太小,撑不住横跨整块的依赖。如果真是这样,深度应该在靠后的位置帮上最多的忙。事实也如此:3 层、5 层、15 层的 DFlash 模型在第一个位置上几乎一样,越往块尾分得越开。但深度不加区分:多十层 attention block 到处加容量,连那些没什么可赚的靠前位置也加,把 DFlash 吸引人的那部分效率磨掉了。 图 2:GSM8K 上 Qwen3-4B 的 Recall@1(T=0),条件是前面每个位置都正确。所有 drafter 在相同设置下训练;卷积模型评估时不带选择器。它的卷积增加 3% 参数和 0.7% 周期延迟;15 层模型多出的十层增加 15.2%。 我们要一个有针对性的修法,而 DFlash 的 attention 指出了修哪里。它有两份工作:读块之前的上下文,以及建模块内部的依赖。但它在第二份上花的越来越少:块内注意力占比从第 1 层的 30% 掉到第 5 层的 8%,剩下的还集中在越来越少的一小撮 head 里。所以我们把两份工作拆开:一个专用模块承担块内工作,attention 继续读上下文。 图 3:五层 Qwen3-4B DFlash 的块内注意力按 head 分布。越亮的格子代表在起草块上花注意力越多的 head;靠后的层里,块内质量收缩、集中到少数几个 head。 一个轻量的局部卷积 块内工作本来就是短程的:一个块只有 4 到 16 个 token,最紧的依赖坐在相邻位置之间。自然的算子是短卷积:两个抽头,一个在当前位置,一个够到前一个位置,权重随内容自适应。跟随 Canon Layers、Dynamic Short Convolutions 和 Convolution for Large Language Models 的做法,我们在每个 attention 和 feed-forward 子层前后插入这个双抽头动态深度卷积: Conv_k(x)_t = k_{t,0}⊙x_t + k_{t,1}⊙x_{t-1} 每个系数由一个可学习的基核加上从当前隐藏状态算出的一个小修正组成;每 16 个通道共享一个修正。第一个位置读最后一个已验证 token 的表示,之后的每个位置读它前一个的。信息穿过整块,同时所有位置仍然并行计算。 图 4:双抽头动态卷积。每个 drafter 层的每个 attention 和 MLP 子层前后各有一个。内部:每个位置把自己的表示和前一个的混合;第一个位置读最后一个已验证 token。 卷积是块局部的、无状态的,所以能无缝插进 DFlash,不用动 attention、LM head 或验证。 只加 16.5M 参数(3%),带卷积的五层 DFlash 就逼近了 15 层 DFlash,大幅减轻后缀衰减。卷积给起草-验证周期延迟加 0.7%;多十层 Transformer 层加 15.2%。第 4、5 层的平均块内注意力从 9.4% 降到 0.5%,与卷积吸收局部工作、attention 回到读上下文一致。一个只够到前一个位置的核,买回了十层额外层的大部分收益:后缀衰减大体是个局部问题。 合在一起 到目前为止,选择器和卷积是分开测的;下面的完整对比把它们放在一起。DFlash 和 DSpark drafter 是我们在对齐的设置下自己训练的,MTP 随模型发布。 表 3:Qwen3.5-4B 每请求平均接受长度。采样:thinking 开启,温度 1.0,top-p 0.95,top-k 20,presence penalty 1.5,无损拒绝采样。 • GSM8K:MTP 4.78,DFlash 4.99,DSpark 5.69,DFlash 2 6.20 • MATH-500:5.04,5.42,6.20,6.76 • HumanEval:4.84,5.43,5.80,6.28 • MBPP:4.16,4.49,4.96,5.41 • MT-Bench:3.90,4.26,4.77,5.20 • 平均:4.54,4.92,5.49,5.97 DFlash 2 在每项基准上都领先。平均下来,它比 DFlash 多 1.05 个 token(21%),比 DSpark 多 0.48。升级仍然便宜:选择器和卷积加起来,只给五层 DFlash 的起草-验证周期延迟加了 1.3%。 在 MATH-500 上,增益逐位置可见:DFlash 2 到最后一个位置都稳在 86% 附近,而每个基线在块尾都比它低 6 到 9 个点。 图 5:MATH-500 上 Qwen3.5-4B 的条件接受率,采样同上。 两个 drafter,今天发布 我们今天发布两个 DFlash 2 drafter:一个给 Qwen3.8-27B( Meta 的 Muse Glimmer( Qwen3.8-27B,我们对比模型原生的 MTP 路径和一个社区 DSpark drafter。 表 4:Qwen3.8-27B 每请求平均接受长度,模型默认采样、块大小 8,对比原生 MTP 路径和社区 DSpark drafter。 • GSM8K:MTP 5.02,DSpark 4.36,DFlash 2 5.46 • MATH-500:4.72,3.92,5.28 • HumanEval:3.91,3.30,4.39 • MBPP:3.99,3.51,4.79 • MT-Bench:3.74,3.01,4.10 • 平均:4.28,3.62,4.80 对 Meta 的 Muse Glimmer,我们对比随模型发布的官方 DFlash drafter 和一个社区 DSpark drafter。 表 5:Muse Glimmer 每请求平均接受长度,模型默认采样、块大小 16。DFlash 是 Meta 随模型发布的官方 drafter;DSpark 是社区 drafter。 • GSM8K:DFlash 5.43,DSpark 5.45,DFlash 2 6.57 • MATH-500:5.39,5.01,6.56 • HumanEval:4.11,4.33,5.66 • MBPP:3.74,4.02,5.30 • MT-Bench:3.52,3.59,4.42 • 平均:4.44,4.48,5.70 差距很大:在两个模型上,DFlash 2 平均比 DSpark 多出超过一个完整的 token。它也超过每个模型的官方 drafter:Qwen3.8-27B 的 MTP、Muse Glimmer 的 DFlash。换算成吞吐,Qwen3.8-27B 上达到自回归解码的 2.7–3.4 倍,Muse Glimmer 上 3.1–4.6 倍。模型卡( 底线 agent 一个下午写出来的东西,聊天机器人要写一个月,而每一个 token 底下都坐着解码。DFlash 2 以接近自回归解码 3 倍的速度解码,每个 token 约三分之一的算力,输出相同。 七个月里,DFlash 从我们的论文变成了行业标准,超过 350 万次下载。在同一个设计内部,DFlash 2 每次通过多解码一个完整的 token,免费。那还只是服务栈的一个组件。推理离它的地板还很远。 在 Inco AI,我们在构建一套端到端的服务栈,把这个地板继续往下压。DFlash 2 是第一块。两个 drafter 今天发布在 Hugging Face。 如果你在规模化地服务 agent,想在你的栈里评估 DFlash 2,或者想为你跑的模型(包括你自己的微调)要一个 drafter,写信给我们:contact@inco.ai。 我们也在招人。如果你想一起构建这套栈,联系我们。 把候选连起来。起草,继续并行。 脚注:Modal 的 Speculation Is All You Need 指出,投机解码是对低延迟服务最重要的优化。我们是他们工作的超级粉丝,感谢他们自 DFlash 发布以来的支持和讨论。 本文引用格式:@misc{inco2026dflash2, title={DFlash 2: Keep Drafting Parallel}, year={2026}, month={August}, url={ 原文: #DFlash# #投机解码# #LLM推理#
もっと見る