扩散式文本大模型技术实践:GPT 一个字一个字写,Diffusion LLM 能同时修改整段文字?
摘要: 我们熟悉的 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 GitHub
- LLaDA-8B-Instruct Hugging Face
- Dream GitHub
- DreamOn GitHub
- DreamOn-7B Hugging Face
- LLaDA2.X GitHub
下面通过两个案例来实践。
三、实践案例一:使用 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 预测的文本生成机制。
本文通过两个案例进行了实践:
- LLaDA-8B: 使用多轮掩码恢复完成结构化文本生成,并通过采样步数控制生成过程。
- DreamOn-7B: 根据代码前后文补全中间内容,并利用动态长度调整处理不同规模的缺失代码。
如果把它与传统大语言模型放在一起,可以得到下面的对比:
| 维度 | 自回归 LLM | 扩散式 LLM |
|---|---|---|
| 生成方式 | 逐 Token 预测 | 多轮去噪或去掩码 |
| 生成顺序 | 通常从左到右 | 可采用非顺序生成 |
| 中间修订 | 需要额外生成或编辑机制 | 部分模型天然支持 |
| 推理生态 | 非常成熟 | 正在快速发展 |
| 性能表现 | 已广泛验证 | 高度依赖模型与采样算法 |
| 典型研究方向 | 长上下文、推理、Agent | 并行生成、文本编辑、可控补全 |
对开发者来说,目前最值得关注的,可能还不是扩散模型能否全面取代 GPT。
而是它为语言模型提供了另一种处理文本的方式:
传统自回归:
先写第一句,再写第二句,最后写第三句。
扩散式生成:
先建立一组待生成位置,
再根据上下文逐步填充、修订和完善。
当然,以上只是帮助理解的简化比喻,具体机制仍取决于模型的训练目标和采样算法。
扩散式文本模型最值得期待的能力,是让语言生成从单向续写,进一步发展为灵活的全局编辑与修订。
未来,如果这些模型能够持续降低采样成本,并解决动态长度、缓存和推理引擎等问题,它们可能在代码编辑、结构化生成、受约束输出等领域形成独特优势。
但在真正部署之前,仍然需要拿它们与同等规模的自回归模型做一次公平测试。
因为对实际应用来说,模型采用什么生成原理固然有趣,最终还是要看三个问题:
回答是否正确、生成是否足够快、部署成本是否合理。
- 点赞
- 收藏
- 关注作者
评论(0)