一、前言

GLM(General Language Model)是由清华大学与智谱AI联合研发的通用语言模型,其核心创新在于“自回归空白填充”预训练框架,巧妙融合了自编码与自回归的优势,在自然语言理解与生成任务上均展现出强大能力。

在当前的AI大模型浪潮中,GLM系列模型以其独特的架构设计和卓越的中文处理能力,成为了开源社区的重要力量。从最初的GLM-6B到如今的GLM-4,这一技术路线不断演进,为开发者提供了强大的基础模型支持。

二、核心原理:自回归空白填充

GLM的核心创新在于其预训练目标——自回归空白填充(Autoregressive Blank Infilling)。这一设计旨在解决传统预训练框架的局限性。

🔍 技术实现三步曲

1. 随机掩码与片段重组

从原始文本中随机采样多个连续片段,用[MASK]标记替换,然后打乱这些片段的顺序。模型需要以自回归方式预测原始顺序的片段内容。

2. 二维位置编码

引入两个位置编码维度:Position1表示片段在原始文本中的索引,Position2表示片段内部的相对位置。这种设计确保模型在重建时能准确感知片段的长度和顺序信息。

3. 自注意力掩码机制

PartA(未掩码部分)的词语可以相互看到,形成双向编码;PartB(掩码部分)的词语只能看到PartA和PartB中已生成的部分,形成单向解码。这种混合注意力机制同时支持理解和生成任务。

与BERT的MLM目标相比,GLM能够捕获masked token之间的相互依赖性;与T5相比,GLM共享编码器-解码器的位置编码,避免了哨兵token的浪费;与XLNet相比,GLM不需要双流自注意力机制,训练效率更高。

三、多任务预训练策略

GLM通过调整掩码策略来适应不同类型的任务,实现了单一模型的多任务能力:

  • 文档级掩码:采样单个长片段(占原文50%-100%),适用于长文本生成任务

  • 句子级掩码:采样多个完整句子片段(覆盖15%词数),适用于seq2seq任务

  • 词级掩码:采样多个短片段(平均长度最短),适用于NLU任务

这种灵活的设计使得GLM能够在自然语言理解、条件生成和无条件生成三大类任务中均取得优异表现。

四、实战项目:GLM微调文本摘要

以下是一个基于GLM-large-chinese模型进行文本摘要任务微调的完整代码示例,包含详细注释说明每个步骤的作用和原理。

import torch
from datasets import Dataset
from transformers import AutoTokenizer, AutoModelForSeq2SeqLM, Seq2SeqTrainer, Seq2SeqTrainingArguments

device = "cuda" if torch.cuda.is_available() else 'cpu'  # 自动检测GPU设备

# 1. 加载模型和分词器
model_dir = '/path/to/glm-large-chinese'  # 模型本地路径
tokenizer = AutoTokenizer.from_pretrained(model_dir, trust_remote_code=True)
model = AutoModelForSeq2SeqLM.from_pretrained(model_dir, trust_remote_code=True).to(device)

# 2. 数据预处理函数
def process_func(examples):
    """
    将原始文本转换为GLM模型需要的输入格式
    核心步骤:添加任务前缀 + [MASK]标记,构建二维位置编码
    """
    contents = ["摘要生成:\n" + e + tokenizer.mask_token for e in examples["content"]]
    
    # 第一步:基础tokenization
    inputs = tokenizer(contents, max_length=384, truncation=True, 
                      padding="max_length", return_tensors="pt")
    
    # 第二步:为生成任务构建完整输入(包含位置编码)
    inputs = tokenizer.build_inputs_for_generation(
        inputs, 
        targets=examples['title'],  # 摘要目标文本
        padding=True,
        max_gen_length=64  # 最大生成长度
    )
    return inputs

# 3. 加载并处理数据集
ds = Dataset.load_from_disk("./nlpcc_2017/")  # 中文摘要数据集
ds = ds.train_test_split(100, seed=42)  # 划分训练集和测试集
tokenized_ds = ds.map(process_func, batched=True, remove_columns=ds["train"].column_names)

# 4. 配置训练参数
args = Seq2SeqTrainingArguments(
    output_dir="./summary_glm",          # 输出目录
    per_device_train_batch_size=1,       # 每个设备的训练批次大小
    per_device_eval_batch_size=4,        # 评估批次大小
    gradient_accumulation_steps=8,       # 梯度累积步数(解决显存不足)
    logging_steps=8,                     # 日志记录频率
    num_train_epochs=1,                  # 训练轮数
)

# 5. 创建训练器并开始训练
trainer = Seq2SeqTrainer(
    args=args,
    model=model,
    train_dataset=tokenized_ds["train"],
    tokenizer=tokenizer,
)
trainer.train()

# 6. 推理函数示例
def predict(model, input_text):
    """使用微调后的模型生成摘要"""
    # 构建符合GLM格式的输入
    inputs = tokenizer("摘要生成:\n" + input_text + tokenizer.mask_token, 
                      return_tensors="pt")
    inputs = tokenizer.build_inputs_for_generation(inputs, max_gen_length=64)
    inputs = inputs.to(device)
    
    # 生成摘要
    output = model.generate(
        **inputs,
        max_new_tokens=64,              # 最大新生成token数
        eos_token_id=tokenizer.eop_token_id,  # 结束符ID
        do_sample=True,                 # 使用采样策略
        pad_token_id=tokenizer.eop_token_id   # 填充符ID
    )
    return tokenizer.decode(output[0].tolist())

# 7. 使用示例
if __name__ == '__main__':
    input_text = "足球从未高于生死...埃里克森时隔1100天再次为国征战欧洲杯..."
    summary = predict(model, input_text)
    print(f"生成摘要: {summary}")

这段代码展示了GLM微调的核心流程:从数据预处理(添加任务前缀和MASK标记)、模型加载、训练配置到最终推理。特别需要注意的是tokenizer.build_inputs_for_generation()方法,它会自动构建GLM特有的二维位置编码,这是模型能够正确理解文本结构的关键。

五、GLM-4指令微调实战

对于更新的GLM-4模型,指令微调(Instruction Tuning)成为提升模型遵循指令能力的关键技术。以下是一个完整的文本分类指令微调示例:

📊 数据格式转换

指令微调需要将传统数据集转换为对话格式,每个样本包含instruction、input、output三个字段:

{
  "instruction": "你是一个文本分类专家...",
  "input": "文本: {content}, 类型选项: {category}",
  "output": "{label}"
}

微调过程中使用LoRA(Low-Rank Adaptation)技术,只训练模型的部分参数,大幅降低显存需求。关键配置包括目标模块选择(query_key_value、dense等)、秩大小(r=8)和缩放系数(lora_alpha=32)。

六、架构细节与优化

GLM在标准Transformer基础上进行了多项重要改进:

改进项 具体实现 优势
层归一化顺序 Post-LayerNorm改为Pre-LayerNorm 避免梯度消失/爆炸,训练更稳定
额外归一化层 在最后一个自注意力层后增加LayerNorm 提升输出稳定性
激活函数 ReLU替换为GeLU 更好的梯度特性
输出层 单一线性层进行词预测 参数效率更高

这些优化使得GLM在相同参数量下能够达到更好的性能表现,特别是在中文理解和生成任务上展现出独特优势。

七、应用场景与优势

GLM的创新架构设计使其在多个应用场景中表现出色:

(1)文本分类任务

GLM将分类任务重新制定为填空生成问题。例如情感分类可以表述为“{句子}。这真的是[MASK]”,将标签映射到填空答案(如“positive”→“good”)。

(2)文本生成任务

给定上下文作为PartA,末尾附加[MASK]符号,模型自回归生成PartB内容。这种统一框架支持无条件生成和条件生成任务。

(3)代码生成与理解

GLM-4增强了代码解释器能力,能够理解复杂指令并调用工具完成任务,大大扩展了应用边界。

GLM的成功不仅在于技术创新,更在于其开源生态的构建。从GLM-6B到GLM-4,智谱AI持续推出不同规模的模型,满足从研究到生产的各种需求,特别是对中文场景的深度优化,使其在国内开发者社区中获得了广泛认可。

八、写在最后的话

GLM的创新之处在于它不满足于“要么理解,要么生成”的二选一困境,而是通过自回归空白填充这一巧妙的桥梁,让模型同时掌握了两种语言能力——这就像一位既精通文学批评又能创作小说的全能作家。

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐