【第四章:大模型(LLM)】05.LLM实战: 实现GPT2-(7)模型训练与微调
第四章:大模型(LLM)
第五部分:LLM实战: 实现GPT2
第六节:模型训练与微调
1. 前置回顾
在上一节中,我们已经完成了:
Token → Embedding
分词器(Tokenizer)
Attention 与 Multi-Head Attention
残差(Residual)与前馈网络(FFN)
输出层(logits 生成)
采样方法(贪婪、temperature、top-k/top-p)
现在,我们的 GPT-2 模型架构已经搭好,接下来要让它学会语言模式,必须通过 训练 或 微调(fine-tuning)。
2. 模型训练的目标
训练过程的核心思想:
让模型根据上下文预测下一个 token,并不断调整参数以降低预测错误率(loss)。
数学形式:
N — token 序列长度
— 真实 token
— 模型参数下的预测概率分布
GPT-2 的训练实际上就是一个大规模 自回归语言建模 任务。
3. 数据准备
3.1 语料来源
预训练:使用大规模公开数据集(Wiki, WebText, Books)。
微调:使用领域数据(法律、医疗、金融、对话数据等)。
3.2 分词 & 编码
from transformers import GPT2Tokenizertokenizer = GPT2Tokenizer.from_pretrained('gpt2')
text = "今天是个好日子。"
tokens = tokenizer.encode(text, return_tensors='pt') # shape: (1, seq_len)
注意:
GPT-2 分词器是 BPE(Byte Pair Encoding),中英文都能处理。
返回是 token ID 张量,用于模型输入。
4. 训练流程
4.1 核心步骤
批量化数据(batching)
前向传播(forward pass)
计算损失(loss)
反向传播(backpropagation)
优化器更新参数(optimizer step)
重复多个 epoch
4.2 代码示例(PyTorch)
from torch.optim import AdamW
from transformers import GPT2LMHeadModel, GPT2Tokenizer# 1. 加载模型与分词器
model = GPT2LMHeadModel.from_pretrained('gpt2')
tokenizer = GPT2Tokenizer.from_pretrained('gpt2')
tokenizer.pad_token = tokenizer.eos_token# 2. 数据
texts = ["今天是个好日子。", "机器学习正在改变世界。"]
encodings = tokenizer(texts, return_tensors='pt', padding=True, truncation=True)# 3. 优化器
optimizer = AdamW(model.parameters(), lr=5e-5)# 4. 训练循环
model.train()
for epoch in range(3):optimizer.zero_grad()outputs = model(**encodings, labels=encodings['input_ids'])loss = outputs.lossloss.backward()optimizer.step()print(f"Epoch {epoch + 1} Loss: {loss.item():.4f}")
运行结果
Epoch 1 Loss: 5.1916
Epoch 2 Loss: 3.5485
Epoch 3 Loss: 2.6843
5. 微调(Fine-tuning)
5.1 与预训练的区别
预训练:从零开始,参数随机初始化,需要巨量数据和算力。
微调:在已有的预训练模型上继续训练,数据规模小得多,但能快速适应特定任务/领域。
5.2 微调策略
全参数微调:更新所有权重(适合算力充足)
部分层微调:仅训练最后几层
参数高效微调(PEFT):如 LoRA、Prefix-Tuning,只更新少量参数
5.3 LoRA 示例
from peft import get_peft_model, LoraConfigconfig = LoraConfig(r=8, lora_alpha=32, target_modules=["c_attn"],lora_dropout=0.1, bias="none", task_type="CAUSAL_LM"
)
model = get_peft_model(model, config)
6. 超参数选择
参数 | 说明 | GPT-2 经验值 |
---|---|---|
batch_size | 每次梯度更新的样本数 | 8~64 |
learning_rate | 学习率 | 5e-51e-4(微调),1e-45e-4(预训练) |
max_seq_len | 序列最大长度 | 512~1024 |
epochs | 训练轮数 | 3~10(视数据量) |
warmup_steps | 学习率预热步数 | 总步数的 1~5% |
7. 训练技巧
梯度累积(gradient accumulation):显存不够时,将多个小 batch 的梯度累积起来再更新。
混合精度(FP16)训练:提升速度、降低显存。
梯度裁剪(clip gradients):避免梯度爆炸。
定期保存检查点(checkpoint):防止中途训练中断丢失进度。
8. 推理(Inference)
微调完成后,即可用模型生成文本:
model.eval()
prompt = "人工智能的未来是"
inputs = tokenizer(prompt, return_tensors='pt')
output_ids = model.generate(**inputs,max_length=50,temperature=0.7,top_k=50,top_p=0.9,do_sample=True
)
print(tokenizer.decode(output_ids[0], skip_special_tokens=True))
9. 可视化 & 监控
loss 曲线:观察收敛情况
生成样例:每隔 N step 输出模型生成文本
权重变化:可用 TensorBoard 监控梯度分布
10. 本节总结
GPT-2 训练目标:最小化下一个 token 的负对数似然损失
微调是让通用语言模型快速适配特定任务的高效方式
训练过程需注意数据准备、超参数设置、优化策略
推理阶段可用采样策略(temperature、top-k、top-p)控制生成多样性