扩散式文本大模型技术实践:GPT 一个字一个字写,Diffusion LLM 能同时修改整段文字?

举报
yd_54922183 发表于 2026/10/31 17:27:18 2026/10/31
【摘要】 本文介绍文本扩散的基本原理,并以开源 LLaDA 和 DreamOn 为例,通过结构化文本生成与代码自动补全两个案例,探索这种模型的实际能力与应用潜力。

摘要: 我们熟悉的 GPT、Qwen、Llama 等大语言模型,大多采用自回归(Autoregressive)方式逐 Token 生成文本。但近年来,一条新的技术路线正在快速发展:扩散式语言模型(Diffusion Language Model,dLLM)。它通过对文本进行掩码、预测和多轮修订,实现非自回归生成。本文介绍文本扩散的基本原理,并以开源 LLaDA 和 DreamOn 为例,通过结构化文本生成与代码自动补全两个案例,探索这种模型的实际能力与应用潜力。

一、扩散模型也能生成文字?

上一期我们研究了扩散式图像超分辨率模型。

它可以从带有噪声的图像出发,经过多轮去噪,逐渐得到清晰图片。

那么,一个很自然的问题出现了:

既然图像可以通过扩散过程生成,文字为什么不可以?

传统大语言模型,例如 GPT,采用自回归生成:

用户输入
   │
   ▼
预测第1个Token
   │
   ▼
预测第2个Token
   │
   ▼
预测第3个Token
   │
   ▼
......
   │
   ▼
完整回答

后面的 Token 依赖前面已经生成的内容。

这有一个特点:模型写下前面的文字后,通常不会在同一轮生成中回过头修改它。

扩散式语言模型采用了不同的策略。

例如,LLaDA 使用 Masked Diffusion(掩码扩散):

用户输入
   │
   ▼
[MASK] [MASK] [MASK] [MASK]
   │
   ▼
预测所有被掩码的位置
   │
   ▼
保留较可信的Token
其余位置继续使用MASK
   │
   ▼
再次预测和修订
   │
   ▼
最终回答

它的核心思路是:通过多轮去掩码,让模型逐渐形成完整文本。

1.1 为什么文本扩散和图像扩散不太一样?

图像是连续数值组成的,扩散模型可以直接在像素或潜空间中添加高斯噪声。

但文本由离散 Token 组成。

例如:

今天 天气 很 好

我们不能简单地给“天气”加上一点数学噪声,让它变成“半个天气”。

因此,许多文本扩散模型使用离散扩散机制。

训练时随机遮住部分 Token:

原始文本:
今天 天气 很 好

加噪后:
今天 [MASK] 很 [MASK]

模型预测:
今天 天气 很 好

通过大量训练,模型逐渐学会根据上下文恢复被遮住的内容。

与 BERT 的掩码语言建模有相似之处,但扩散语言模型使用不同的训练目标和迭代采样过程,以支持完整文本生成。

1.2 数学上如何理解?

传统自回归模型将序列概率分解为:

[
P(x_1,\ldots,x_n)=
\prod_{i=1}^{n}P(x_i\mid x_{<i})
]

也就是根据前面的 Token 预测下一个 Token。

而掩码扩散模型则学习一个去噪分布:

[
P_\theta(x_0\mid x_t)
]

其中:

  • (x_0):完整的原始文本。
  • (x_t):经过随机掩码后的文本状态。
  • (P_\theta):模型学习到的条件预测分布。

推理时,模型通过多步状态更新,从大量 [MASK] 逐渐恢复出完整文本。

这里最重要的区别是:扩散模型可以同时参考一个位置左右两侧的上下文,而不必严格按照从左到右的顺序生成。

这使它在代码补全、文本修订和受约束生成等任务上具有值得研究的潜力。


二、有哪些开源的扩散文本大模型?

截至 2026 年 10 月,比较有代表性的项目包括:

模型 规模 主要特点
LLaDA-8B 8B 从零训练的掩码扩散语言模型
Dream 7B 7B 基于自回归模型初始化,支持灵活的扩散采样
DreamOn-7B 7B 专门研究可变长度代码中间补全
iLLaDA-8B 约 8B 改进 LLaDA 的训练和生成效率
LLaDA2 系列 16B~100B 级 MoE、Token 编辑及 Agent 方向的进一步探索

其中,LLaDA 是较早引起广泛关注的开源扩散语言模型之一。

2025 年 2 月,研究团队发布了 LLaDA-8B,证明了非自回归扩散架构也能够训练到数十亿参数,并在通用语言任务上取得有竞争力的表现。

Dream 则采用另一条路线:从已有的自回归语言模型出发,通过进一步训练,使其具备扩散式生成能力。

2026 年,LLaDA2.1、LLaDA2.2 等模型继续探索 Token 编辑、生成效率和智能体任务。

官方项目:

下面通过两个案例来实践。

三、实践案例一:使用 LLaDA 生成结构化客服处理建议

3.1 业务场景

假设我们正在开发一个客服辅助系统。

用户输入:

我昨天买的耳机还没发货,如果今天不能发出,我就申请退款。

系统希望生成一段结构化结果:

{
  "main_intent": "物流催发货",
  "secondary_intent": "条件性退款",
  "suggestion": "优先核实发货时间"
}

传统 LLM 可以完成这个任务。

我们使用 LLaDA,主要是观察:当输出长度和格式相对明确时,扩散模型能否通过多轮去掩码生成符合要求的文本。

3.2 环境准备

首先安装官方项目:

git clone https://github.com/ML-GSAI/LLaDA.git
cd LLaDA

pip install "transformers==4.38.2" torch accelerate

这里使用官方建议的 Transformers 版本,避免自定义模型代码出现兼容性问题。

LLaDA-8B 在 BF16 精度下仅模型权重就需要约 16GB 显存,建议使用 24GB 或更大显存的 GPU。

8GB 显卡如果希望运行,需要进一步探索量化或 CPU Offload 等方案。

3.3 Python 实现

在官方仓库根目录创建 demo.py:

import torch
from transformers import AutoModel, AutoTokenizer
from generate import generate

# 1. 加载模型
model_id = "GSAI-ML/LLaDA-8B-Instruct"

tokenizer = AutoTokenizer.from_pretrained(
    model_id,
    trust_remote_code=True
)

model = AutoModel.from_pretrained(
    model_id,
    trust_remote_code=True,
    torch_dtype=torch.bfloat16
).to("cuda").eval()

# 2. 构造用户任务
prompt = """
请分析以下客服消息:

我昨天买的耳机还没发货,
如果今天不能发出,我就申请退款。

请只输出JSON,包含:
main_intent、secondary_intent、suggestion。
内容简短,不要额外解释。
"""

messages = [
    {"role": "user", "content": prompt}
]

# 3. 应用聊天模板
text = tokenizer.apply_chat_template(
    messages,
    add_generation_prompt=True,
    tokenize=False
)

inputs = tokenizer(
    text,
    return_tensors="pt",
    add_special_tokens=False
).input_ids.to("cuda")

# 4. 扩散式文本生成
with torch.no_grad():
    output = generate(
        model,
        inputs,
        steps=64,
        gen_length=64,
        block_length=64,
        temperature=0.0,
        remasking="low_confidence"
    )

# 5. 解码生成结果
answer = tokenizer.decode(
    output[0, inputs.shape[1]:],
    skip_special_tokens=True
)

print(answer)

如果模型按照要求完成任务,输出可能类似:

{
  "main_intent": "物流催发货",
  "secondary_intent": "条件性退款",
  "suggestion": "优先核实发货时间"
}

这里是期望输出示例,实际内容需要运行模型得到。生成的 JSON 也应通过程序进行格式校验。

3.4 最重要的参数:Steps

steps=64
gen_length=64
block_length=64

三个参数分别表示:

参数 含义
gen_length 预设生成区域的 Token 数量
steps 扩散采样步数
block_length 每个生成块的长度

例如:

gen_length = 64
steps = 64

表示模型在 64 个采样步骤中,逐渐填充一个长度为 64 Token 的生成区域。

如果将步骤数减少:

steps=16

每一步就需要确定更多 Token。

理论上,这可能减少推理计算,但也可能降低生成质量。

值得注意,gen_length 是 Token 数量,不是字符数量。中文内容的实际长度还取决于 Tokenizer 的编码方式。

实验时可以固定输入和其他参数,分别比较 16、32、64 个采样步骤下的输出正确率与耗时。


四、实践案例二:使用 DreamOn 自动补全缺失代码

第一个案例展示了文本扩散模型也能够生成普通回答。

但说实话,单纯为了输出一段 JSON,我们已经有大量成熟的自回归模型可用。

扩散模型更值得研究的一项能力是:同时利用前文和后文,推测中间缺失的内容。

4.1 业务场景

假设我们正在维护一个 Python 项目。

代码中有一个函数:

def unique_keep_order(items):
    """去重并保持原始顺序"""
    result = []
    seen = set()

    # 这里缺少实现

    return result

我们希望 AI 根据前后代码,补齐缺失部分。

理想结果是:

for item in items:
    if item not in seen:
        seen.add(item)
        result.append(item)

这种任务称为 Fill-in-the-Middle(FIM,中间补全)。

它在代码编辑器、自动修复和代码重构中非常常见。

自回归模型也可以通过专门的 FIM 训练实现这一能力。

而 DreamOn 则从扩散模型的角度研究它,允许模型根据前后文直接生成中间部分,还能动态调整填充长度。

4.2 DreamOn 为什么特殊?

早期掩码扩散模型通常需要预先确定生成区域长度。

例如:

def add(a, b):
    [MASK] [MASK] [MASK] [MASK]

如果需要的代码长度超出了原先分配的掩码数量,就可能出现问题。

DreamOn 引入了两种特殊操作:

  • expand:扩展需要生成的 Token 数量。
  • delete:删除多余的 Token。

因此,模型能够在去掩码过程中动态调整生成长度。

已有代码前缀
      │
      ▼
[MASK] [MASK] [MASK]
      │
      ▼
预测与长度调整
      │
      ▼
生成缺失代码
      │
      ▼
已有代码后缀

它可以同时利用代码前缀和后缀,预测中间最合适的实现。

4.3 环境准备

建议创建一个独立虚拟环境,避免 Dream 与前面 LLaDA 使用的 Transformers 版本冲突。

git clone https://github.com/DreamLM/DreamOn.git
cd DreamOn

pip install "torch==2.5.1" "transformers==4.46.2"

PyTorch 还需要与本机 CUDA 环境兼容。

Dream 系列官方基础实现建议使用至少 20GB GPU 显存,以下示例也建议从 24GB 显卡开始测试。

4.4 Python 实现

在官方项目目录创建 demo_fim.py:

import torch
from transformers import AutoModel, AutoTokenizer

# 1. 加载DreamOn模型
model_id = "Dream-org/DreamOn-v0-7B"

tokenizer = AutoTokenizer.from_pretrained(
    model_id,
    trust_remote_code=True
)

model = AutoModel.from_pretrained(
    model_id,
    torch_dtype=torch.bfloat16,
    trust_remote_code=True
).to("cuda").eval()

# 2. 代码前缀
prefix = '''
def unique_keep_order(items):
    """去重并保持原始顺序"""
    result = []
    seen = set()
'''

# 3. 代码后缀
suffix = '''
    return result
'''

# 4. 在前后文之间插入MASK
prefix_ids = [
    tokenizer.bos_token_id
] + tokenizer.encode(
    prefix,
    add_special_tokens=False
)

suffix_ids = tokenizer.encode(
    suffix,
    add_special_tokens=False
) + [tokenizer.eos_token_id]

mask_ids = [
    tokenizer.mask_token_id
] * 8

input_ids = torch.tensor(
    [prefix_ids + mask_ids + suffix_ids],
    dtype=torch.long,
    device="cuda"
)

# 5. 扩散式中间补全
with torch.no_grad():
    output = model.diffusion_generate(
        input_ids,
        temperature=0.2,
        alg="entropy",
        alg_temp=0,
        top_p=0.9,
        max_new_tokens=64,
        number_transfer_tokens=1,
        return_dict_in_generate=True,
        output_history=False
    )

# 6. 提取完整代码
code = tokenizer.decode(
    output.sequences[0],
    skip_special_tokens=True
)

print(code)

这里与普通文本生成最大的区别,是我们在输入序列中明确保留了:

代码前缀 + MASK区域 + 代码后缀

DreamOn 会根据上下文生成中间代码。

max_new_tokens=64 在这里控制填充的最大生成 Token 数量,而 number_transfer_tokens=1 是官方重点测试过的采样设置。

4.5 这个案例真正有价值的地方

假设我们正在修改一个大型项目。

普通代码补全通常关注光标后面的内容。

但实际上,开发人员经常需要修改函数中间的几行代码,同时保留函数其他部分。

此时,FIM 就很有价值:

已有函数开头
       │
       ▼
需要重新实现的部分
       │
       ▼
已有函数结尾

DreamOn 的实验重点就是探索如何在这种前后文约束下,自动生成长度合理的缺失代码。

不过,生成结果仍需要语法检查、单元测试和运行验证。能够同时参考前后代码,并不保证一定生成正确实现。


五、扩散文本模型真的比 GPT 更快吗?

这是这个技术方向最容易产生误解的地方。

很多人看到“并行生成”,就会认为扩散语言模型一定比自回归模型更快。

实际情况要复杂得多。

例如:

  • 自回归模型生成 128 个 Token,通常需要约 128 次逐步解码。
  • 扩散模型生成 128 个 Token,如果设置 steps=32,理论上可以通过 32 轮迭代填充多个位置。

看起来扩散模型很有优势。

但每一步的计算成本可能不同。

扩散模型在每轮迭代时,可能需要对整个生成区域重新执行 Transformer 计算。

而传统自回归模型已经拥有成熟的 KV Cache、PagedAttention 和高吞吐推理优化。

因此,扩散模型的性能优势取决于采样步数、上下文长度、模型架构及推理引擎。

LLaDA 原始论文的官方实现也明确指出,其采样速度在当时仍慢于部分自回归基线。

2026 年的 LLaDA2 系列、Token 编辑方法和缓存优化,则正在尝试改善这些问题。

5.1 实际应该测试哪些指标?

指标 用途
Accuracy / Pass@1 判断生成答案或代码是否正确
End-to-End Latency 用户请求到完整结果的耗时
Tokens/s 单位时间生成的有效 Token 数量
GPU 显存 模型部署资源需求
Steps 扩散采样步数
首次可用输出延迟 衡量实时交互体验

对于代码补全,还应关注:

  • 代码能否通过语法检查。
  • 是否保留原有前缀和后缀。
  • 是否通过单元测试。
  • 补全部分是否过长或重复。

对于结构化输出,应关注 JSON 合法率和字段准确率。

此外,扩散模型的 Token/s 需要结合实际采样过程计算,不能直接拿每轮处理的所有 Token 数量去比较自回归模型的解码速度。


六、总结:文本扩散模型会取代自回归 LLM 吗?

目前还很难下这个结论。

扩散语言模型真正有意思的地方,在于它提供了一种不同于逐 Token 预测的文本生成机制。

本文通过两个案例进行了实践:

  1. LLaDA-8B: 使用多轮掩码恢复完成结构化文本生成,并通过采样步数控制生成过程。
  2. DreamOn-7B: 根据代码前后文补全中间内容,并利用动态长度调整处理不同规模的缺失代码。

如果把它与传统大语言模型放在一起,可以得到下面的对比:

维度 自回归 LLM 扩散式 LLM
生成方式 逐 Token 预测 多轮去噪或去掩码
生成顺序 通常从左到右 可采用非顺序生成
中间修订 需要额外生成或编辑机制 部分模型天然支持
推理生态 非常成熟 正在快速发展
性能表现 已广泛验证 高度依赖模型与采样算法
典型研究方向 长上下文、推理、Agent 并行生成、文本编辑、可控补全

对开发者来说,目前最值得关注的,可能还不是扩散模型能否全面取代 GPT。

而是它为语言模型提供了另一种处理文本的方式:

传统自回归:
先写第一句,再写第二句,最后写第三句。

扩散式生成:
先建立一组待生成位置,
再根据上下文逐步填充、修订和完善。

当然,以上只是帮助理解的简化比喻,具体机制仍取决于模型的训练目标和采样算法。

扩散式文本模型最值得期待的能力,是让语言生成从单向续写,进一步发展为灵活的全局编辑与修订。

未来,如果这些模型能够持续降低采样成本,并解决动态长度、缓存和推理引擎等问题,它们可能在代码编辑、结构化生成、受约束输出等领域形成独特优势。

但在真正部署之前,仍然需要拿它们与同等规模的自回归模型做一次公平测试。

因为对实际应用来说,模型采用什么生成原理固然有趣,最终还是要看三个问题:

回答是否正确、生成是否足够快、部署成本是否合理。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。