第六章:闭关修炼——预训练之实战

分布式训练万剑宗,混合精度阴阳通。

在这里插入图片描述

【本章导读】

预训练是大模型修炼的核心阶段,如同闭关修炼内功。此阶段耗时最长、耗费最大,决定了模型的上限。本章将揭示大规模训练的核心技术。


一、预训练总览

【预训练目标】

预训练的核心目标:让模型学习预测下一个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=1Tlog⁡P(xt∣x<t)L = -\sum_{t=1}^{T} \log P(x_t | x_{<t})L=t=1TlogP(xtx<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')

【容错策略】

  1. 定期保存:每1000步保存一次
  2. 多副本存储:保存到多个位置
  3. 验证检查点:定期验证检查点可恢复
  4. 弹性训练:支持节点故障后自动恢复

八、训练监控:洞察修炼进程

【关键指标】

指标 含义 正常范围
训练损失 模型在训练集上的损失 持续下降
验证损失 模型在验证集上的损失 下降后稳定
学习率 当前学习率 按调度变化
梯度范数 梯度的大小 稳定,不爆炸
GPU利用率 GPU使用效率 >80%
内存使用 GPU内存占用 <95%

【异常检测】

异常 表现 原因 解决
损失爆炸 损失突然变大 学习率过大 降低学习率
损失NaN 损失变为NaN 梯度爆炸 梯度裁剪
过拟合 训练损失下降,验证损失上升 模型过大或数据不足 正则化、增加数据
训练缓慢 损失下降太慢 学习率过小 增大学习率

九、本章心法总结

【口诀】

分布式训练万剑宗,混合精度阴阳通。
梯度累积厚薄发,学习率调节奏中。
损失函数心魔镜,检查点存防断功。

【要点回顾】

技术 作用 关键点
分布式训练 多卡并行 3D并行 + ZeRO
混合精度 加速训练 BF16为主流
梯度累积 大batch训练 累积后更新
学习率调度 训练稳定 预热 + 余弦衰减
损失函数 衡量差距 交叉熵 + 困惑度
检查点 容错恢复 定期保存

【下一章预告】

下一章,我们将深入探讨预训练的核心任务——Next Token Prediction,理解语言模型如何学习预测下一个词。

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐