大模型修炼秘籍 第六章:闭关修炼——预训练之实战
第六章:闭关修炼——预训练之实战
分布式训练万剑宗,混合精度阴阳通。

【本章导读】
预训练是大模型修炼的核心阶段,如同闭关修炼内功。此阶段耗时最长、耗费最大,决定了模型的上限。本章将揭示大规模训练的核心技术。
一、预训练总览
【预训练目标】
预训练的核心目标:让模型学习预测下一个Token。
通过海量数据的训练,模型学会:
- 语言规律(语法、语义)
- 世界知识(事实、概念)
- 推理能力(逻辑、因果)
【预训练流程】
准备好的数据
↓
构建数据加载器
↓
┌─────────────────────────────────────┐
│ 训练循环(重复数百万步) │
│ │
│ 1. 采样一个batch的数据 │
│ 2. 前向传播,计算损失 │
│ 3. 反向传播,计算梯度 │
│ 4. 更新参数 │
│ 5. 记录指标 │
│ │
└─────────────────────────────────────┘
↓
保存检查点
↓
预训练模型
二、分布式训练:万剑归宗
【分布式心法】
大模型训练需要数千张GPU协同工作,如同万剑归宗,合力一击。
【并行策略】
| 策略 | 原理 | 适用场景 |
|---|---|---|
| 数据并行 | 多卡处理不同数据 | 数据量大 |
| 张量并行 | 切分模型层内参数 | 单层参数大 |
| 流水线并行 | 切分模型层间参数 | 模型层数多 |
| 序列并行 | 切分长序列 | 序列长度大 |
【数据并行(Data Parallelism)】
最简单的并行方式:
GPU 0: 处理 Batch 0 的前向和后向
GPU 1: 处理 Batch 1 的前向和后向
GPU 2: 处理 Batch 2 的前向和后向
...
所有GPU: 同步梯度,更新参数
【张量并行(Tensor Parallelism)】
将单个层的参数切分到多张卡:
原始: 一个大矩阵乘法
↓
切分: 每张卡计算部分结果
↓
合并: 汇总得到完整结果
【流水线并行(Pipeline Parallelism)】
将模型的不同层放到不同卡:
GPU 0: Layer 0-15
GPU 1: Layer 16-31
GPU 2: Layer 32-47
GPU 3: Layer 48-63
【3D并行】
结合三种并行策略:
张量并行
↓
┌───┬───┬───┬───┐
│GPU│GPU│GPU│GPU│ 流水线并行
│ 0 │ 1 │ 2 │ 3 │ ↓
├───┼───┼───┼───┤
│GPU│GPU│GPU│GPU│
│ 4 │ 5 │ 6 │ 7 │
└───┴───┴───┴───┘
↓
数据并行
【ZeRO优化】
DeepSpeed提出的ZeRO(Zero Redundancy Optimizer)技术:
| 阶段 | 切分内容 | 内存节省 |
|---|---|---|
| ZeRO-1 | 优化器状态 | 4x |
| ZeRO-2 | + 梯度 | 8x |
| ZeRO-3 | + 模型参数 | N倍(N为GPU数) |
三、混合精度训练:阴阳调和
【混合精度心法】
传统训练使用FP32(32位浮点数),精度高但速度慢、内存大。混合精度训练结合FP16和FP32,阴阳调和,效率倍增。
【精度对比】
| 精度 | 位数 | 数值范围 | 精度 | 速度 |
|---|---|---|---|---|
| FP32 | 32 | ±3.4×10^38 | 高 | 慢 |
| FP16 | 16 | ±65504 | 低 | 快 |
| BF16 | 16 | ±3.4×10^38 | 低 | 快 |
| FP8 | 8 | 更小 | 更低 | 更快 |
【混合精度策略】
┌─────────────────────────────────────┐
│ 混合精度训练流程 │
├─────────────────────────────────────┤
│ │
│ 模型参数: FP32(主副本) │
│ ↓ │
│ 前向传播: FP16(快速计算) │
│ ↓ │
│ 损失计算: FP32(保持精度) │
│ ↓ │
│ 梯度计算: FP16(快速计算) │
│ ↓ │
│ 梯度缩放: 防止下溢 │
│ ↓ │
│ 参数更新: FP32(保持精度) │
│ │
└─────────────────────────────────────┘
【BF16的优势】
BF16(Brain Float 16)由Google提出:
- 与FP32相同的数值范围
- 不需要损失缩放
- A100及更新的GPU支持
现代大模型普遍使用BF16。
四、梯度累积:厚积薄发
【梯度累积心法】
大模型训练需要大batch size,但GPU内存有限。梯度累积如同厚积薄发,多次小batch的梯度累积后,再更新参数。
【原理】
目标batch size: 1024
GPU内存只能放: 32
方案: 梯度累积
- 每次处理32个样本
- 累积梯度,不更新参数
- 累积32次后(32×32=1024)
- 更新参数,清零梯度
【代码实现】
accumulation_steps = 32
optimizer.zero_grad()
for i, batch in enumerate(dataloader):
# 前向传播
outputs = model(batch)
loss = outputs.loss / accumulation_steps # 缩放损失
# 反向传播
loss.backward()
# 累积足够的步数后更新
if (i + 1) % accumulation_steps == 0:
optimizer.step()
optimizer.zero_grad()
五、学习率调度:修炼节奏
【学习率心法】
学习率如同修炼节奏,太大则走火入魔,太小则进展缓慢。需要精心调度。
【学习率调度策略】
1. 预热(Warmup)
训练初期,参数随机,学习率应从小到大:
学习率
│
│ ┌────────────────────
│ /
│ /
│ /
│ /
│───┘
└───────────────────────────── 步数
预热期
2. 余弦衰减(Cosine Decay)
预热后,学习率按余弦曲线衰减:
学习率
│
│ ╭──╮
│ ╱ ╲
│ ╱ ╲
│ ╱ ╲
│ ╱ ╲
│───╯ ╲
└───────────────────────────── 步数
【学习率选择】
| 模型规模 | 学习率 | 预热步数 |
|---|---|---|
| 小(<1B) | 1e-4 ~ 6e-4 | 总步数的1-5% |
| 中(1B-10B) | 1e-4 ~ 3e-4 | 总步数的1-2% |
| 大(>10B) | 5e-5 ~ 1e-4 | 总步数的0.5-1% |
六、损失函数:心魔之镜
【交叉熵损失】
语言模型使用交叉熵损失:
L=−∑t=1TlogP(xt∣x<t)L = -\sum_{t=1}^{T} \log P(x_t | x_{<t})L=−t=1∑TlogP(xt∣x<t)
【困惑度】
困惑度是损失的指数形式,更直观:
PPL=eL\text{PPL} = e^LPPL=eL
解释: 困惑度表示模型在每个位置上的"困惑程度"——平均有多少个候选词。
| 困惑度 | 含义 |
|---|---|
| 100 | 模型在100个词中猜测 |
| 10 | 模型在10个词中猜测 |
| 1 | 模型完全确定 |
七、检查点与容错
【检查点内容】
checkpoint = {
'step': global_step,
'model_state_dict': model.state_dict(),
'optimizer_state_dict': optimizer.state_dict(),
'scheduler_state_dict': scheduler.state_dict(),
'loss': current_loss,
'config': model_config,
}
torch.save(checkpoint, f'checkpoint_{global_step}.pt')
【容错策略】
- 定期保存:每1000步保存一次
- 多副本存储:保存到多个位置
- 验证检查点:定期验证检查点可恢复
- 弹性训练:支持节点故障后自动恢复
八、训练监控:洞察修炼进程
【关键指标】
| 指标 | 含义 | 正常范围 |
|---|---|---|
| 训练损失 | 模型在训练集上的损失 | 持续下降 |
| 验证损失 | 模型在验证集上的损失 | 下降后稳定 |
| 学习率 | 当前学习率 | 按调度变化 |
| 梯度范数 | 梯度的大小 | 稳定,不爆炸 |
| GPU利用率 | GPU使用效率 | >80% |
| 内存使用 | GPU内存占用 | <95% |
【异常检测】
| 异常 | 表现 | 原因 | 解决 |
|---|---|---|---|
| 损失爆炸 | 损失突然变大 | 学习率过大 | 降低学习率 |
| 损失NaN | 损失变为NaN | 梯度爆炸 | 梯度裁剪 |
| 过拟合 | 训练损失下降,验证损失上升 | 模型过大或数据不足 | 正则化、增加数据 |
| 训练缓慢 | 损失下降太慢 | 学习率过小 | 增大学习率 |
九、本章心法总结
【口诀】
分布式训练万剑宗,混合精度阴阳通。
梯度累积厚薄发,学习率调节奏中。
损失函数心魔镜,检查点存防断功。
【要点回顾】
| 技术 | 作用 | 关键点 |
|---|---|---|
| 分布式训练 | 多卡并行 | 3D并行 + ZeRO |
| 混合精度 | 加速训练 | BF16为主流 |
| 梯度累积 | 大batch训练 | 累积后更新 |
| 学习率调度 | 训练稳定 | 预热 + 余弦衰减 |
| 损失函数 | 衡量差距 | 交叉熵 + 困惑度 |
| 检查点 | 容错恢复 | 定期保存 |
【下一章预告】
下一章,我们将深入探讨预训练的核心任务——Next Token Prediction,理解语言模型如何学习预测下一个词。
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐
所有评论(0)