Skip to content

预训练工程实战:Checkpoint、容错与训练稳定性 ​

摘要: 预训练不是"把代码跑起来"——是在万卡集群上跑几个月不出事。Checkpoint 怎么写才能既保进度又不拖慢训练?节点挂了怎么最快恢复?Loss 曲线异常怎么排查?本文给出工程答案:Checkpoint 策略、容错流程、Loss 异常排查清单。

0. 实验目标 ​

  • 设计 Checkpoint 策略:周期、异步、分片三要素
  • 掌握节点故障恢复流程:从发现到重启训练的可执行步骤
  • 建立 Loss 异常排查清单:先查数据、再查代码、最后查集群
  • 理解训练稳定性的工程护栏(watchdog、健康检查、日志审计)

1. Checkpoint 三要素:周期 / 异步 / 分片 ​

python
# 训练框架里的 Checkpoint 配置(Megatron/DeepSpeed 等语义)
checkpoint = {
    "interval": 500,          # 每 500 步存一次
    "async_save": True,       # 异步保存:不阻塞训练
    "shard": True,            # 分片存储:每卡只存自己的分片
    "keep_last": 3,           # 保留最近 3 个(磁盘成本控制)
    "save_optimizer": True,   # 存优化器状态(否则恢复后动量丢失)
}

逐段拆解:

  • 周期(interval):步数间隔。太频繁拖慢训练(同步保存阻塞),太稀损失进度。经验值:500-2000 步,配合硬件故障概率权衡。
  • 异步保存(async_save):保存到本地磁盘先落盘,再后台拷贝到共享存储——保存不阻塞训练步,是大规模训练标配。
  • 分片(shard):每个 rank 只存自己的权重分片(Megatron 的 distributed_optimizer),避免"一个 checkpoint 文件几百 GB、集中写挂掉"。
  • 保存优化器状态:只存权重 = 恢复后优化器动量清零,收敛曲线会倒退。训练中断恢复必须存 optimizer state。

2. 容错:节点挂了怎么办 ​

bash
# 故障发现:训练进程 watchdog(挂掉即报警并拉日志)
# 常见信号:rank 心跳超时、NCCL 超时、OOM、节点无响应

# 恢复流程(可执行步骤):
# 1) 定位故障节点:scontrol show job + 集群监控(DCGM/IB 状态)
# 2) 隔离故障节点:slurm 置 DRAIN / K8s cordon,防止再次分配
# 3) 硬件处置:坏 GPU/网卡换件;IB 故障检查(本知识库 [IB 运维](/guide/03-network/ib-admin-guide) 篇)
# 4) 重启训练:从最近的 checkpoint 恢复
srun --nodes=N --ntasks-per-node=8 \
  python train.py --resume-from /share/ckpt/latest/

工程启示(容错要点):

  • 检查点是恢复的唯一依赖:重启 = 从最近 checkpoint 恢复,所以"checkpoint 写坏了"比"节点挂了"严重得多——恢复后先校验 checkpoint 完整性(权重 hash)再继续。
  • 故障分级处理:单节点故障(最常见)→ 重启恢复即可;大面积故障(网络分区)→ 先别急着恢复,排查根因,否则重启了还会再挂。
  • 保存与恢复要可审计:每个 checkpoint 记录步数、loss、配置 hash;恢复日志里确认"从第 N 步恢复",防止静默恢复到旧版本。

3. Loss 异常排查清单(按顺序排查) ​

现象第一嫌疑排查动作
Loss 突增/发散(NaN/Inf)数据问题检查最近数据批次:重复、异常 token、清洗规则误杀
Loss 缓慢不降学习率/配比检查 LR schedule、数据混合配比(数据管线 篇)
重启后 Loss 反弹checkpoint 缺失 optimizer state确认恢复含优化器状态
多卡 Loss 不一致通信/并行配置检查 DDP/TP 配置、NCCL 拓扑
偶发 NaN数值稳定性AMP 检查、梯度裁剪、BF16 溢出

原理讲解:

  • 排查顺序铁律:先数据、再代码、后集群。预训练数据是 TB 级,清洗规则一个 bug 可能污染整段训练(本知识库 数据管线 篇强调"loss 异常先查数据报告")。
  • 重启后 Loss 反弹是最常见的"假异常":只存了权重没存 optimizer state,恢复后等于"换了个优化器起点"——查 checkpoint 是否含 optimizer。
  • 偶发 NaN:大模型 BF16 训练中,梯度 underflow/overflow 是常态风险;loss_scaler(AMP)与梯度裁剪(max_grad_norm)是两道防线。

4. 训练稳定性护栏(长期运行的关键) ​

python
# 1) Watchdog:训练进程健康探活 + 自动重启 + 日志留存
# 2) 指标审计:每 N 步记录 loss/吞吐/GPU 利用率到时序库
# 3) 配置版本化:训练脚本 hash 进日志,恢复时校验一致
# 4) 定时校验:每个 checkpoint 保存后做一次权重 hash + 可加载性测试
# 5) 熔断机制:连续 N 步 loss 异常 → 自动暂停 + 报警,避免"带病训练"跑几天

工程启示:

  1. Checkpoint 三要素:周期 500-2000 步、异步保存、分片存储 + optimizer state。
  2. 故障恢复流程化:定位 → 隔离 → 处置 → 恢复,恢复后先校验 checkpoint。
  3. 排查顺序铁律:先数据、再代码、后集群。
  4. 重启反弹 ≠ 训练坏了:先查 checkpoint 是否含 optimizer state。
  5. 熔断机制:连续 loss 异常自动暂停,别让坏训练浪费算力。
  6. 配置版本化:恢复日志核对"从第几步、哪个配置恢复"。
  7. 健康检查进集群:watchdog + DCGM/IB 探活,故障自动 DRAIN。

5. 延伸阅读 ​

AI-HPC 智算超算专家 · Contact: openaihpc@gmail.com