自回归不是物理定律:扩散语言模型买到了什么,亏在哪里

从左往右生成不是语言的性质,而是一个可以被换掉的建模选择。这篇把投机解码与扩散语言模型放进同一个框架,手算清楚扩散省下的步数是从哪儿借的,再用 Gemini Diffusion 官方评测表验证这笔账。

你用过的每一个大模型,都是从左往右一个 token 一个 token 写出来的。用久了很容易把这当成语言模型的天性——“语言本来就是一个字一个字说的”。

它不是。从左往右是一个建模选择,而且是一个可以被换掉的选择。 换掉它的模型 2026 年已经在卖 API 了:ByteDance 的 Seed Diffusion 论文报到 2146 token/秒,Google 的 Gemini Diffusion 报到 1479 token/秒——比同级自回归模型快一个数量级。

但这篇不想只讲”哇好快”。快是结果,我想弄清楚的是那些省下来的步数是从哪里借的——因为天下没有免费的并行。

前置阅读:这篇假设你已经知道”扩散”大致是怎么回事。如果没有,先读 扩散模型说人话:从擦掉噪点到造出新东西——那篇用一个能手算的一维例子把扩散从头讲一遍,读完再回来,这篇会顺很多。

名词速查

术语一句话解释
自回归(AR)生成方式:每次只预测下一个 token,把已写出的部分当条件,循环 N 次写出 N 个 token
掩码扩散另一种生成方式:先把整句话全变成”待填空”,再分若干步把空填回来,每步可以同时填好几个位置
去噪步数扩散模型填完整句话用了几次前向计算。步数越少越快,越多越准
双向注意力每个位置能同时看到左边和右边(BERT 那种)。自回归只能看左边
块扩散折中架构:句子切成小块(常见 32 token),块与块之间自回归,块内部用扩散并行填
infilling挖空填词:给定前后文,补中间。自回归原生不擅长,扩散天然会
KV cache注意力中间结果的缓存,让已生成 token 不必重算。详见站内 KV cache 那笔账

一句话主线

自回归用 N 次前向换来了一个数学上精确的概率分解;扩散语言模型把这个分解换掉,用”一次前向填多个空”换速度,代价是它在同一步里填的那几个空之间,看不见彼此。 这篇要把这句话手算清楚。

一、先看清自回归到底选了什么

自回归模型算的是这个东西:

p(x1,x2,,xN)=i=1Np(xix1,,xi1)p(x_1, x_2, \dots, x_N) = \prod_{i=1}^{N} p(x_i \mid x_1, \dots, x_{i-1})

这里有个容易被忽略的事实:这条式子是链式法则,它是恒等式,不是近似。 任何一个联合分布都可以这样拆,拆的时候没有丢任何信息。这是自回归最大的优点,也是它统治了整个领域的原因——你只需要学好”预测下一个词”这一件事,理论上就能表达任意复杂的语言分布。

代价写在式子里:乘号有 N 个,你就得跑 N 次前向。

而这 N 次前向贵在哪里,站内 Decode 速度上限公式 那篇已经用实测数据算过了:解码慢不是算力问题,是搬运问题。每生成一个 token,都要把整份模型权重从显存搬一遍进计算单元。

拿那篇的实测数字接着往下算(Qwen2.5-7B,4.677 GB 权重,llama-bench 实测 16.99 tok/s,反推带宽约 79.5 GB/s):

每次前向产出每秒前向次数速度上限
1 token(标准自回归)17.017.0 tok/s
2 token17.034.0 tok/s
4 token17.068.0 tok/s
8 token17.0135.9 tok/s

带宽一点没变,速度翻了 8 倍。这张表就是整个”快速解码”研究领域的全部动机:既然瓶颈是”每 token 搬一次权重”,那么想快,唯一的出路是让一次搬运多产出几个 token。

于是分出两条路——这是我想让你从这篇带走的框架:

flowchart TD
    A["根本约束:解码是内存带宽瓶颈<br/>每个 token 要搬一遍全部权重"] --> B["想快,只能让一次前向多产出 token"]
    B --> C1["路线一:保留自回归分解<br/>猜 + 验证"]
    B --> C2["路线二:换掉自回归分解<br/>并行填空"]
    C1 --> D1["投机解码<br/>Medusa / EAGLE"]
    C2 --> D2["扩散语言模型<br/>LLaDA / Mercury / Gemini Diffusion"]
    D1 --> E1["输出分布严格不变<br/>靠验证步兜底"]
    D2 --> E2["输出分布变了<br/>同步填的位置互相看不见"]

路线一是投机解码:用小模型或额外的头猜出好几个 token,再用大模型一次前向验证这几个猜测。关键在于它保留了链式法则——验证步保证最终输出分布和逐 token 生成严格一致,猜错了就丢掉重来。它是纯粹的工程加速,不改变模型说什么。

路线二就是这篇的主角:干脆不要那个分解了。

二、掩码扩散在做什么(人话版)

扩散模型在图像领域的做法是”加噪声再去噪”。文本是离散的 token,没法直接加高斯噪声,所以要换一个”加噪”的定义。

关键的一步来自 2021 年的 D3PM(arXiv:2107.03006,NeurIPS 2021)。这篇论文系统研究了离散数据该怎么”加噪”,其中一种选择叫吸收态(absorbing state):加噪就是按一定概率把 token 替换成 [MASK],而 [MASK] 一旦进去就不再变化。论文明确指出,这个选择”在扩散模型与自回归、掩码式生成模型之间建立了联系”。

这个联系值得停一下,因为它让整件事忽然变得不神秘了:

掩码扩散 = 掩码比例可变的完形填空。 BERT 训练时固定挖掉 15% 的词让模型填;掩码扩散把挖掉的比例从 0% 到 100% 随机取,然后让模型学会在任意掩码比例下填空。训练完成后,生成就是从”全是 [MASK]”出发,反复填空,直到没有 [MASK]

没有微分方程,没有噪声调度的玄学——就是一个学会了在任意残缺程度下补全句子的 BERT。

2025 年的 LLaDA(arXiv:2502.09992)证明了这条路能撑到真正的大模型规模:8B 参数、从零开始按”预训练 + SFT”的标准范式训练,在通用任务、数学、代码上与作者自建的同规模自回归基线可比,论文称其在上下文学习能力上”与 LLaMA3 8B 这样的强模型有竞争力”。这篇的结论句说得很直接:大语言模型的核心能力并非内在地绑定于自回归

采样循环长这样:

# 伪代码:掩码扩散的采样主干
# 依据 LLaDA (arXiv:2502.09992) 与块扩散 (arXiv:2503.09573) 论文描述的过程简化,
# 非某份源码的逐行对应;省略:温度/top-p 采样细节、EOS 与变长处理
sequence = [MASK] * length          # 起点:整句都是空
for step in range(num_steps):       # num_steps 就是"去噪步数"这个旋钮
    logits = model(sequence)        # 双向注意力,一次看全序列(注意:没有 KV cache 可用)
    confidence, candidate = logits.softmax(-1).max(-1)
    masked_positions = [i for i, t in enumerate(sequence) if t == MASK]

    # 这一步要填多少个空:总空数 / 剩余步数。步数越少,每步填得越多
    k = ceil(len(masked_positions) / (num_steps - step))

    # 只填模型最有把握的 k 个位置——把不确定的留给后面几步(此时上下文更全)
    for i in top_k_by(confidence, masked_positions, k):
        sequence[i] = candidate[i]  # ← 这 k 个位置是同时定下来的,彼此看不见
    # 省略:部分实现允许"重新掩码"已填错的位置
return sequence

请盯住最后那行注释。整篇文章的账,都在那一行上。

三、那些省下的步数是从哪儿借的

借款一:同一步填的空,互相看不见

自回归的链式法则是恒等式,不丢信息。而当你在一步里同时填 k 个空时,你实际上是从 k 个边缘分布里各自独立采样,再把结果拼起来。而边缘分布的乘积,不等于联合分布。

这句话听起来抽象,手算一个最小例子就清楚了。假设有个句子,模型学到的分布只允许两种填法,各占一半:

  • 「我要去北京,因为北京是我的家乡」——概率 0.5
  • 「我要去上海,因为上海是我的家乡」——概率 0.5

两个空必须一致,这是语义要求。现在看模型在这两个位置上的边缘分布:

位置P(北京)P(上海)
第一个空0.50.5
第二个空0.50.5

如果这两个空在同一步被独立填上,你得到的联合分布是:

采样结果独立采样概率模型真实概率
(北京,北京)0.250.5
(北京,上海)0.250
(上海,北京)0.250
(上海,上海)0.250.5

一半的采样结果落在了模型自己认为概率为 0 的组合上,比如「我要去北京,因为上海是我的家乡」——每个词都合理,合起来自相矛盾。(这两张表的数字我用脚本验算过:边缘各 0.5,独立乘积各 0.25,落在零概率组合上的总质量恰好 0.5。)

这就是那笔借款的本息。去噪步数正是你为”抓住依赖关系”付的钱:极端情况下每步只填一个空,那么每个位置都能看到之前所有已定下的位置,模型就退化成了一个”任意顺序的自回归模型”——依赖关系全抓住了,但 N 步一步没省下,速度优势归零。(这个退化关系是我的理解,不同实现的训练目标权重有差异,严格等价性我没有逐式核对。)

反过来说,扩散语言模型的速度,本质上是在赌”这几个位置之间的依赖弱到可以忽略”。 什么时候这个赌注成立?代码缩进、样板结构、格式化输出、局部编辑——这些地方相邻 token 的依赖确实高度局部。什么时候不成立?需要跨越长距离保持一致的推理链。

借款二:KV cache 没了

第二笔账更工程。掩码扩散用的是双向注意力——每个位置都要看全序列(包括右边还没填的空)。而 KV cache 能生效的前提,恰恰是”已经算过的位置不会再变”,这是自回归的因果掩码给的保证。

块扩散论文把这个问题说得很明白:离散扩散”在生成过程中使用双向上下文,因此无法通过 KV cache 复用之前的计算”(arXiv:2503.09573,ICLR 2025 Oral,Cornell Tech / Kuleshov 组)。也就是说,扩散每一步都在重算整个序列——它省的是步数,不是每步的成本。

同一篇论文给出的解法,也是今天生产架构收敛到的样子:块扩散(BD3-LM)。把序列切成块,块与块之间保持自回归(于是 KV cache 回来了,也支持变长生成),块内部用扩散并行填。论文的原话是,通过调节块大小,可以在自回归与扩散之间插值,并明确这引入了”质量与采样效率之间的权衡”。

所以块大小就是那个旋钮:块 = 1 就是自回归,块 = 整句就是纯扩散。生产上常见取 32 左右——站内 五条主线 那篇提到过这个工程收敛,这里补上它背后的机制:32 不是调参调出来的幸运数字,它是”依赖强度随距离衰减”和”KV cache 想要因果性”两个约束谈判的结果。

四、账对不对?看两份独立证据

上面全是机制推演。机制推演最容易犯的错,是推得很顺、但现实不买账。所以要去看评测数字——而且要看能反驳我的数字。

我的机制推演给出一个可证伪的预测:扩散语言模型应该在局部依赖强的任务(代码、格式、编辑)上接近甚至超过自回归,在需要长距离一致性的任务(知识问答、多跳推理)上明显掉队。

Google 官方的 Gemini Diffusion 模型页给了完整对照表(对比同级自回归模型 Gemini 2.0 Flash-Lite,均为 pass@1、无多数投票):

基准Gemini Diffusion2.0 Flash-Lite差值
HumanEval(代码)89.6%90.2%−0.6
MBPP(代码)76.0%75.8%+0.2
LiveCodeBench v630.9%28.5%+2.4
LBPP v256.8%56.0%+0.8
AIME 2025(数学)23.3%20.0%+3.3
BigCodeBench45.4%45.8%−0.4
SWE-Bench Verified22.9%28.5%−5.6
GPQA Diamond(科学推理)40.4%56.5%−16.1
Global MMLU Lite(多语知识)69.1%79.0%−9.9
BIG-Bench Extra Hard15.0%21.0%−6.0

速度是 1479 token/秒(官方标注为”各项评测的平均采样速度,不含开销”,另有 0.84 秒开销)。

这张表和预测吻合得相当好:代码和数学基本打平或小胜,科学推理掉 16 分、多语知识掉 10 分。 Google 自己的措辞也承认这个形状——他们强调这种方式适合”编辑类工作,尤其是数学和代码”。

第二份证据来自 ByteDance 的 Seed Diffusion(arXiv:2508.02193)。它的价值在于论文里同时列了自家的自回归兄弟模型,属于难得的同门对照:

基准Seed Diffusion PreviewSeed-Coder-8B-Instruct(自回归)
Aider(tries=2)44.457.1
MBXP(13 语言均值)72.675.3
NaturalCodeBench42.249.6

速度 2146 token/秒(H20 GPU,跨八个开源代码基准)。即使在最有利的代码领域,它相对自家自回归兄弟仍然是净亏的——Aider 差 12.7 分不算小。论文自己也提醒跨模型速度对比不可靠(Mercury 用 H100 和私有数据集、Gemini 的数字来自混合任务且硬件未公开),并且承认报告速度”会受益于约束格式的系统提示”。这种自我设限的诚实值得记一笔。

至于 Inception Labs 的 Mercury,我去官网核实时发现:官方页面的速度对比图只标了”Tokens/sec”轴,没有给具体数字,硬件也未注明。官方给的可引用口径是定性的——“匹配速度优化型前沿模型的质量,首 token 延迟低于 300ms,吞吐高 5–7 倍,单任务成本最多低 70%“,定价 Mercury 2 为每百万 token 输入 $0.25 / 输出 $0.75。所以社区流传的那些精确 tok/s 数字都是二手的,我这里不采用。

五、被速度掩盖了的那件事:任意顺序生成

如果扩散语言模型只是”快但笨一点”,它大概只是个成本优化手段。但它还带来一个自回归结构上做不到的东西,我认为这比速度更值得关注。

自回归的因果掩码规定了信息只能从左往右流。这意味着”给定前后文补中间”(infilling)对它是别扭的——今天的代码补全能做到这件事,靠的是训练时的数据改造技巧(把后文搬到前面去),而不是模型的原生能力。

掩码扩散不需要任何技巧:它训练时就是在随机位置填空,“从哪儿开始生成”根本不是一个约束。 挖空的位置在中间、在两头、还是零散分布,对它都一样。

一个漂亮的证据:LLaDA 论文报告它在”反向诗句补全”任务上超过了 GPT-4o。这里指的是所谓 reversal curse——自回归模型学了「A 是 B」之后往往答不出「B 是什么」,因为它只在一个方向上见过这条信息。双向训练的扩散模型天然没有这个方向性偏见。

这解释了产品落点:Mercury 的产品线里专门有个 Mercury Edit——编辑,而不是从零续写,才是这个范式的原生主场。

六、灰度:这东西现在该怎么看

我不认为扩散会替代自回归,也不认为它只是噪音。按目前的证据,我的判断是:

场景值不值得看扩散理由
延迟敏感的交互(语音、实时副驾、端侧)值得速度差一个数量级,质量损失在可接受范围
代码编辑、格式化输出、结构化填充值得局部依赖为主,且 infilling 是原生能力
知识问答、多跳推理、Agent 长链决策暂时不值得GPQA 掉 16 分是机制性的,不是训练不足
长文创作待观察变长生成靠块扩散才刚补上
想省显存不值得它省的是步数,每步仍在重算全序列

一个怀疑读者到这里应该会问:那些差距是范式的极限,还是只是投入不够? 诚实的答案是我不知道,而且这是当前最关键的未知。支持”投入不够”的证据是这条线的绝对投入量还很小,且工程路线刚刚收敛(用自回归模型初始化 + 切换扩散目标继续训练,比从零训练省算力)。支持”机制性”的证据是第三节那笔账——独立采样丢失联合分布,是数学事实而非工程缺陷,只能靠增加步数来赎回,而增加步数就是放弃速度优势。

我倾向于后者更根本:扩散语言模型的速度上限和质量上限,被同一个旋钮反向锁在一起。 这不排除它在”依赖本就局部”的任务上长期胜出——那恰恰是它的正确定位,而不是它的过渡阶段。

带得走的东西

如果这篇只留一句,我希望是这句:看到任何”让 LLM 更快”的方案,先问它是在保留链式法则的前提下加速(投机解码那类,输出分布不变),还是在替换链式法则(扩散那类,输出分布变了)。 前者是纯工程账,后者是能力账——两者不能用同一把尺子量。

这把尺子还能量别的:多 token 预测、并行解码、Jacobi 解码,都能用”分解变没变”这一问归位。

诚实的提醒

这篇里所有的速度和评测数字都属于”核实过的来源”档——来自官方模型页和 arXiv 原文,我一个都没有亲手复现过。第一节的带宽推算来自站内旧文的实测数据,第三节的两张概率表我用脚本验算过。第二节末尾”多步扩散退化为任意顺序自回归”是我的理解,未逐式核对。

成本最低的亲手验证实验:LLaDA-8B-Instruct 是开源权重(HuggingFace 上 GSAI-ML 组织下),单卡可跑。拿它做一件事——固定 prompt,只把去噪步数从序列长度(每步填一个空)逐步降到长度的 1/8,记录 GSM8K 准确率和墙钟时间。 你会亲手画出那条”步数—质量”曲线,也就亲手摸到了第三节那笔借款的利率。如果曲线比预期平坦,那说明”依赖弱到可以忽略”的赌注比我估计的更成立——这个结果会直接反驳本文第六节的判断,值得写一篇。

参考来源

官方与工程实践

arXiv 论文

  • arXiv:2107.03006 — Structured Denoising Diffusion Models in Discrete State-Spaces(D3PM,NeurIPS 2021):离散扩散的奠基,吸收态与掩码式生成的联系
  • arXiv:2502.09992 — Large Language Diffusion Models(LLaDA):8B 从零训练,反向诗句补全超过 GPT-4o
  • arXiv:2503.09573 — Block Diffusion(ICLR 2025 Oral):KV cache 缺失问题与块扩散插值方案
  • arXiv:2508.02193 — Seed Diffusion(ByteDance Seed / 清华 AIR):2146 token/秒,含与自家自回归模型的同门对照

站内相关