AI 快讯扩散语言模型实战入门
实战教程

扩散语言模型实战入门

2026-08-31T06:04:49.533Z
扩散语言模型实战入门

扩散语言模型正在成为自回归 LLM 之外的另一条生成路线。本文从掩码训练、反向采样、低置信度重掩码和块扩散入手,带你从零理解并搭建一个可运行的文本生成系统。

扩散语言模型实战入门:从零搭建非自回归文本生成系统

截至 2026 年 8 月 31 日,扩散语言模型仍没有取代 GPT、Llama、Qwen 这类自回归模型,但它已经从论文里的新奇范式,进入了可以实际训练、采样和评估的工程阶段。

扩散语言模型(Diffusion Language Model,简称 dLLM)是通过反复“遮盖、预测、修正”序列中的 token 来生成文本的模型,而不是像自回归模型那样从左到右一次生成一个 token。

这一区别看起来只是解码顺序不同,实际上会改变模型的训练目标、注意力结构、推理流程和适用场景。对于代码重构、文档编辑、局部改写、补全和需要反复纠错的任务,扩散式生成有机会比严格的左到右生成更自然;但在长文本低延迟生成、成熟部署工具链和稳定性方面,自回归模型仍然占据优势。

本文不把扩散语言模型包装成“下一代 LLM”,而是把它当成一种可以动手实现的生成范式:先用最小模型理解原理,再讨论如何复用自回归模型权重、如何选择采样步数,以及什么时候采用纯扩散、块扩散或半自回归策略。

扩散语言模型从全量 MASK 经过多轮预测、重掩码和纠错,最终生成完整文本的流程图

一、自回归和扩散生成,差别到底在哪里

自回归语言模型(Autoregressive Language Model,简称 ARM)是按照固定顺序预测下一个 token 的模型。给定前文 x1, x2, ..., xt,模型估计下一个 token xt+1,然后把它追加到上下文中,继续预测下一个位置。

这种方式的优势非常明确:训练目标简单,Transformer 可以使用成熟的因果注意力,KV Cache 能够减少重复计算,推理服务和硬件优化也已经相当成熟。但它有一个硬约束:后面的 token 必须等待前面的 token。

扩散语言模型则把文本看成一个需要逐步恢复的离散序列。生成开始时,目标区域通常全部被替换为 [MASK];模型在每个时间步同时预测所有被遮盖的位置,再根据置信度决定哪些 token 保留、哪些 token 重新遮盖。

| 对比维度 | 自回归 LLM | 扩散语言模型 | |---|---|---| | 基本生成方式 | 从左到右逐 token 生成 | 从全 MASK 或部分 MASK 逐步恢复 | | 单步预测范围 | 通常是下一个位置 | 可以同时预测多个位置 | | 注意力结构 | 使用因果掩码 | 通常使用双向注意力 | | 是否能修改已生成内容 | 默认不能,除非重新生成 | 可以通过重掩码反复修正 | | 推理次数 | 通常与输出 token 数相关 | 通常与采样 steps 相关 | | 低延迟短文本 | 工具链成熟,表现稳定 | 取决于步数和并行效率 | | 局部编辑 | 需要额外设计 | 天然适合局部填空和改写 | | 训练难度 | 工程经验丰富 | 需要设计掩码和采样策略 |

扩散模型的核心价值不是简单地“并行生成更多 token”,而是允许模型在生成过程中回头修改答案。自回归模型一旦确定前面的 token,后续生成就只能在这个前缀上继续;扩散模型则可以把低置信度区域重新变成 [MASK],让下一轮预测覆盖旧结果。

二、最小可行版本:把文本变成掩码恢复任务

要从零构建一个扩散语言模型,第一步不是设计复杂的噪声调度器,而是把训练任务改成“根据被破坏的文本恢复原文”。

离散扩散中的前向过程(Forward Process)是按照一定比例随机替换 token 的过程。与图像扩散常见的连续高斯噪声不同,文本扩散通常直接在 token 空间操作。

假设一条训练样本经过 tokenizer 后得到长度为 L 的序列 x0。我们采样一个时间变量 t,再根据 t 决定遮盖比例。t 越大,输入越接近全 MASK;t 越小,输入中保留的原始 token 越多。

最简单的训练流程如下:

  1. 从数据集中取一段 token 序列。
  2. 随机采样 t,例如从 [0, 1] 均匀采样。
  3. 根据噪声日程计算掩码概率 p_mask(t)
  4. 独立地把每个 token 替换为 [MASK]
  5. 将被破坏的序列输入 Transformer。
  6. 只在被遮盖的位置计算交叉熵损失。
  7. 让模型恢复原始 token。

对应的训练伪代码可以写成:

# x0: [batch, seq_len],原始 token
# mask_id: tokenizer 中 [MASK] 的编号
# model: 双向 Transformer 掩码预测器

t = torch.rand(x0.size(0), device=x0.device)
mask_prob = schedule(t).unsqueeze(1)
random_value = torch.rand_like(x0, dtype=torch.float32)
mask = random_value < mask_prob

x_t = x0.clone()
x_t[mask] = mask_id
logits = model(x_t, time=t)

loss = cross_entropy(
    logits[mask],
    x0[mask],
    ignore_index=-100,
)
loss.backward()
optimizer.step()
optimizer.zero_grad()

这段代码表达了最核心的训练目标,但真实系统还需要处理几个工程问题。第一,不能让某个 batch 恰好没有任何 MASK,否则损失为空;通常会设置最小掩码比例。第二,时间变量 t 是否显式输入模型,需要根据架构决定;最简单的做法是把时间嵌入加到每层隐藏状态中。第三,训练时的随机掩码分布必须覆盖推理阶段会遇到的噪声水平,否则模型可能只会处理中等比例的遮盖,面对全 MASK 输入时表现很差。

三、模型结构:Transformer 还在,但因果掩码不见了

扩散语言模型通常仍然使用 Transformer,但它的 Transformer 不再强制每个位置只能看左侧上下文。由于输入中的可见 token 和 MASK token 都可能参与恢复,模型需要使用双向注意力,让每个位置看到整个序列。

这带来一个直接变化:训练阶段可以并行计算所有位置的预测,前向计算效率与序列长度相关,而不是像推理阶段那样逐 token 展开。代价是,模型必须学会在不同破坏程度下恢复文本,训练目标比标准 next-token prediction 更复杂。

在实现上,一个可用的最小模型至少包括以下组件:

  • 一个普通 tokenizer,以及专门的 [MASK] token。
  • 双向 Transformer 编码器或去掉因果掩码的 Decoder Block。
  • 时间步嵌入,用于告诉模型当前输入处于哪一个去噪阶段。
  • token 分类头,将隐藏状态映射回词表概率。
  • 掩码位置损失,只惩罚模型实际需要恢复的位置。

如果直接使用没有 [MASK] 设计的自回归模型,不能只把注意力掩码改成双向就结束。原模型的词表、位置编码、归一化方式和训练分布都围绕“预测下一个 token”建立,强行修改后可能出现训练不稳定、重复率升高或全 MASK 输入无法恢复的问题。

四、反向生成:从全 MASK 逐步得到文本

反向过程(Reverse Process)是扩散语言模型真正与自回归模型拉开差距的地方。推理时,系统从 t=1 的高噪声状态开始,逐步走向 t=0 的完整序列。

最简单的采样器可以这样工作:

  1. 把目标长度的所有位置初始化为 [MASK]
  2. 模型预测每个位置的 token 分布。
  3. 为每个位置选出候选 token,并记录最大概率作为置信度。
  4. 根据当前时间步决定本轮保留多少 token。
  5. 对低置信度位置重新设置为 [MASK]
  6. 重复执行,直到达到最后一个时间步。

伪代码如下:

x = torch.full((1, target_length), mask_id)

for step in range(num_steps):
    t = 1.0 - step / num_steps
    logits = model(x, time=t)
    prob = logits.softmax(dim=-1)
    token_prob, token_id = prob.max(dim=-1)

    x = token_id
    keep_ratio = schedule_keep(t)
    keep_count = int(target_length * keep_ratio)

    # 只保留置信度最高的位置,其余位置继续 MASK
    _, keep_index = token_prob.topk(keep_count, dim=-1)
    next_x = torch.full_like(x, mask_id)
    next_x.scatter_(1, keep_index, token_id.gather(1, keep_index))
    x = next_x

实际使用时,不能简单地每轮保留固定数量的 token。更合理的策略是根据置信度动态决定保留范围,同时为已经稳定的高置信度 token 设置保护机制。否则模型可能在最后几步反复改写大量内容,导致采样速度和文本稳定性都变差。

低置信度重掩码(Low-Confidence Remasking)是扩散语言模型常见的纠错策略。它会检查历史步骤生成的 token,如果当前模型对这些 token 的信心下降,就再次把它们遮盖。比如模型第一轮把一句话的主语预测错了,后续位置的语义冲突可能让主语位置置信度降低,重掩码机制就能给模型一次修正机会。

这也是扩散生成最值得关注的能力之一:模型生成的不是一条不可回头的 token 链,而是一张不断被填充和修改的序列草稿。

五、纯扩散、块扩散和半自回归怎么选

块扩散(Block Diffusion)是把长序列切成多个块,并在块内使用扩散采样的混合生成方式。它位于纯扩散和自回归之间,适合在质量、延迟和显存之间做折中。

block_size 是块扩散中每个块包含的 token 数量。它有一个很直观的连续变化:当 block_size 等于整个生成长度时,模型接近纯扩散;当 block_size=1 时,模型退化为逐 token 的自回归式生成;介于两者之间时,则是半自回归采样。

| 采样策略 | block_size | 主要特点 | 适合场景 | |---|---:|---|---| | 纯扩散 | 等于生成长度 | 全序列并行修复,迭代次数较少但控制难度高 | 短文本、整体改写、填空 | | 块扩散 | 例如 16、32、64 | 块之间保持顺序,块内并行修正 | 代码、长文档、结构化输出 | | 半自回归 | 较小块 | 更接近成熟解码流程,质量相对稳定 | 线上服务、延迟敏感任务 | | 逐 token | 1 | 行为接近自回归模型 | 需要严格顺序的生成任务 |

从实践角度看,block_size=32 是值得优先测试的起点。相关开源实践显示,适当大小的块可以保留纯扩散的纠错能力,同时降低长序列全局重算的成本。但这不是通用最优值:代码生成通常更依赖语法连续性,块太大可能造成括号、缩进或变量依赖错误;短问答则可能从更大的块中获益。

采样步数同样重要。步数过少,模型没有足够机会修正低置信度区域;步数过多,质量提升会迅速递减,却会增加 Transformer 前向次数。工程上应当固定输出长度和硬件环境,对 steps=8、16、32、64 做延迟与质量曲线,而不是只比较单次结果。

六、如何复用自回归模型权重

复用自回归模型权重训练扩散语言模型,是 dLLM 工程化中最有吸引力的路线之一。它的基本思路是保留词嵌入、注意力层和前馈层的大部分知识,再通过掩码恢复任务进行持续训练或适配。

但“复用权重”不等于“换一个 attention mask 就能直接运行”。至少有三类差异需要处理:

  1. 训练目标不同。 自回归模型学习的是下一个 token,扩散模型学习的是任意位置的被遮盖 token。
  2. 上下文分布不同。 自回归模型几乎总能看到完整前缀,而扩散模型需要适应从少量可见 token 到全 MASK 的输入。
  3. 位置关系不同。 双向注意力会改变隐藏状态的统计分布,原有的位置编码和归一化参数未必直接适配。

比较稳妥的迁移流程是先冻结大部分骨干网络,只训练掩码相关组件和输出头;模型能够稳定恢复后,再逐渐解冻 Transformer 层。训练数据可以混合原始文本、代码和指令数据,避免模型只擅长普通填空而不会遵循指令。

对于指令微调,通常只对回复区域进行随机掩码,提示词区域保持可见。这样训练目标会集中在“根据指令恢复答案”,而不是让模型无差别地重建整段对话。这个策略和普通监督微调相似,但损失计算位置发生了变化。

七、扩散语言模型到底快不快

“可以并行生成”不等于“实际一定更快”。扩散模型每一步可以预测多个位置,但每一步都可能需要完整运行一次 Transformer;自回归模型虽然逐 token 生成,却可以通过 KV Cache 避免重复计算。

可以用一个简化公式理解两者的成本。自回归生成长度为 L 的文本,大致需要 L 次增量解码;扩散采样则需要 S 次序列级前向计算,其中 S 是采样步数。当 S 远小于 L,且硬件能够高效处理整段序列时,扩散模型才有明显的吞吐优势。

因此评测至少要记录以下指标:

  • 首 token 延迟和完整请求延迟。
  • 每秒生成 token 数,而不是只看单步推理速度。
  • 不同输出长度下的延迟曲线。
  • 在相同硬件、批大小和精度下的显存占用。
  • 采样步数变化对困惑度、代码通过率和人工偏好的影响。
  • 重掩码比例变化对重复、幻觉和格式错误的影响。

如果只拿一个扩散模型的最佳吞吐数字,与自回归模型的默认配置比较,结论通常没有参考价值。对于交互式聊天,自回归模型的首 token 延迟和流式输出体验仍然很重要;对于一次生成整段代码、表格或文档,扩散模型的整段并行预测可能更有优势。

八、从零实验时最容易踩的坑

全 MASK 恢复能力不足。 训练期间如果很少出现高掩码比例,推理从全 MASK 开始时模型会完全失去方向。解决办法是覆盖完整的 t 区间,并对高噪声样本保持足够训练比例。

采样结果反复变化。 每轮都对所有位置重新采样,会让已经正确的 token 被破坏。可以结合置信度阈值、top-k 保留和温度退火,只对不稳定位置进行重掩码。

输出长度难以控制。 自回归模型通过 EOS token 自然结束,扩散模型如果一次性固定长度,容易产生尾部空白或重复内容。可以加入长度预测头、特殊结束标记,或者采用块扩散逐块决定是否结束。

代码格式容易崩溃。 代码中的缩进、括号和变量依赖具有强顺序性。纯扩散一次修改整段代码,可能让局部修复破坏全局语法。工程上应优先采用较小的 block,并在每轮采样后运行轻量级语法检查。

只看语言流畅度。 扩散模型可能生成读起来通顺、但结构不一致的答案。评测代码时要看编译率和单元测试通过率,评测数学任务时要检查最终答案与中间推导,不能只使用 BLEU 或人工主观评分。

九、一个可执行的实验路线

如果目标是学习原理而不是立刻部署千亿参数模型,可以按以下顺序推进:

  1. 使用一个小词表和长度为 128 的文本数据集,训练数千万参数规模的双向 Transformer。
  2. 先实现固定比例随机 MASK,再加入随机时间步和掩码调度。
  3. 让模型从全 MASK 恢复短句,验证采样循环能够收敛。
  4. 加入置信度记录和低置信度重掩码,观察文本是否减少重复。
  5. 比较纯扩散与 block_size=16、32、64 的质量和速度。
  6. 扩展到指令数据,只计算回复区域的掩码损失。
  7. 最后再尝试从开源自回归模型迁移权重,并逐步解冻骨干网络。

这个路线的重点是先确认每一个机制真的在工作。可视化每个时间步的序列状态尤其重要:如果模型从第一步到最后一步几乎不改变,通常是掩码比例、损失位置或采样更新逻辑有问题;如果每一步都大幅修改整段文本,则说明置信度筛选过于激进。

十、结论:它更像“可反复编辑的生成器”

扩散语言模型的现实价值,在于它把文本生成从单向接龙变成了多轮草稿修复。它不必严格按照字符或 token 顺序完成答案,而是可以先确定高置信度骨架,再补全细节,并在发现冲突后重新处理局部区域。

但截至 2026 年 8 月,扩散语言模型还不能简单替代自回归 LLM。自回归模型在训练配方、推理优化、流式交互和长文本部署方面拥有更成熟的生态;扩散模型的优势则集中在并行恢复、局部编辑和可控纠错。两者不是“谁马上淘汰谁”的关系,而是针对不同生成约束的两种解法。

对于开发者,最值得投入的不是追逐某个单一榜单数字,而是建立一套可复现实验:固定模型规模和硬件,比较不同采样步数、块大小、重掩码策略与任务指标。只要把这些变量拆开,扩散语言模型就不再是概念演示,而是一种可以被测量、调试和用于真实文本任务的系统。

参考来源

相关推荐

查看全部