GLM 模型结构分析:从双向注意力到自回归填空
1. 引言
GLM(General Language Model)是智谱 AI 与清华大学联合提出的通用语言模型框架。与传统的 GPT 式单向自回归模型和 BERT 式双向掩码语言模型不同,GLM 通过一种统一的预训练范式——自回归填空(Autoregressive Blank Infilling),同时兼顾了自然语言理解(NLU)与自然语言生成(NLG)任务。本文从基础架构出发,深入分析 GLM 模型的核心结构设计,并对比其与主流 Transformer 变体的差异。
2. GLM 基础架构全景
GLM 的架构可以概括为“双向编码器 + 自回归解码器”的混合体。下图展示了其整体流程:
flowchart TD
A[原始文本] --> B[随机掩盖连续片段]
B --> C[构造 Part A & Part B]
C --> D[双向编码器处理 Part A]
D --> E[自回归生成 Part B 中被掩盖的片段]
E --> F[输出完整填空文本]
GLM 的输入被划分为两个部分:
- Part A:未被掩盖的文本片段,作为上下文;
- Part B:被掩盖的连续片段,由模型自回归地逐一生成。
3. 核心结构组件
3.1 统一的注意力掩码设计
GLM 在单个 Transformer 模型中实现了两种注意力模式:
- 双向注意力:Part A 中的 token 可以相互看到(类似 BERT 的 encoder),从而充分捕获上下文;
- 自回归注意力:Part B 中的每个 mask 片段内部采用从左到右的自回归生成,且不同 mask 片段之间相互独立(互不可见),但都能看到完整的 Part A。
这种掩码通过自定义的二维注意力矩阵实现,将上下文的双向编码能力和生成任务的自回归特性统一到了一起,避免了过去需要分别训练 NLU 和 NLG 模型的问题。
3.2 位置编码与二维位置信息
GLM 为每个 token 附加了两套位置编码:
- 全局位置编码:记录 token 在原始文本中的绝对位置;
- 块内位置编码:记录 token 在所属 mask 片段(或 Part A)中的相对位置。
这种二维位置设计帮助模型在空白填充时准确区分不同 span 的边界,显著提升了长跨度文本的生成质量。
3.3 自回归填空预训练目标
GLM 的预训练目标不是预测单个 [MASK] 标记,而是自回归地生成被掩盖的连续片段。损失函数由每个 mask 片段内部的自回归交叉熵损失之和构成。这使得模型天然适合处理:
- 文本填空(cloze test);
- 条件生成(如摘要、问题回答);
- 自由文本续写(通过将整段作为 Part B 实现)。
4. 与 GPT/BERT 的结构对比
下表对比了 GLM 与两类主流模型在核心结构上的差异:
| 特性 | GPT | BERT | GLM |
|---|---|---|---|
| 注意力模式 | 单向(因果) | 双向 | 双向 + 自回归混合 |
| 预训练目标 | 下一个 token 预测 | 掩码 token 预测 | 自回归填空 |
| 生成能力 | 天然支持 | 需适应(如 BART) | 天然支持 |
| 理解能力 | 需通过单向上下文理解 | 强 | 强 |
| 长序列效率 | KV 缓存可复用 | 无需缓存 | 部分生成需缓存 |
5. 最新演进:GLM-4 到 GLM 5.2 的结构优化
随着模型规模的扩大,GLM 系列在保持核心结构思想的同时进行了多项工程级改进:
- 分组查询注意力(GQA):在解码部分引入 GQA,大幅降低长文本生成时的 KV 缓存占用,使 128K 上下文成为可能。
- MoE 混合专家结构:部分版本采用稀疏 MoE 设计,在总参数量增加的同时保持激活参数量不变,显著提升训练和推理效率。
- 多阶段对齐与工具调用:在结构上新增了 Function Call 和代码解释器专用 token,使模型能够与外部工具深度交互。
6. 示例:GLM 的填空演示
以下伪代码展示了 GLM 如何处理一个填空任务:
text = "北京是中国的首都,[MASK]是最大的城市之一。"
# Part A: "北京是中国的首都,"
# Part B: "[MASK]是最大的城市之一。"
# 模型需要自回归生成 MASK 位置的内容,例如 "上海"
通过加载 GLM 模型,我们可以直接传入文本并获得填空结果:
from transformers import AutoModel, AutoTokenizer
model = AutoModel.from_pretrained("THUDM/glm-10b-chinese")
tokenizer = AutoTokenizer.from_pretrained("THUDM/glm-10b-chinese")
inputs = tokenizer("北京是中国的首都,[MASK]是最大的城市之一。", return_tensors="pt")
outputs = model.generate(**inputs, max_new_tokens=5)
print(tokenizer.decode(outputs[0], skip_special_tokens=True))
7. 总结
GLM 通过“自回归填空”这一统一范式,巧妙地在同一结构内融合了 BERT 式的强理解能力和 GPT 式的强生成能力。其二维注意力掩码和位置编码设计是理解该模型的关键。随着 GLM-4 和 GLM 5.2 的发布,工程化优化进一步释放了结构潜力,使 GLM 系列成为开源社区中兼顾研究与落地的重要基座选项。
更多推荐
所有评论(0)