预训练集群故障后如何恢复?
简化版
预训练集群恢复要先区分瞬时通信、单机硬件、存储/数据和数值故障,不能一律原地重试。协调器停止全体 rank、隔离坏节点,选择最新完整 Checkpoint,按新拓扑恢复模型、优化器、RNG 与数据游标;先跑健康检查和少量验证 step,确认 loss、学习率及样本连续后再放量,并保留故障证据做根因分析。
详细版
同步训练中一个 rank 掉线通常会让整个 collective 阻塞,因此需要 watchdog、心跳和 collective timeout 快速发现,再由作业控制器统一重启,避免残留 rank 形成 split brain。恢复点必须有 manifest、完成标记和校验和;坏分片、正在写入的版本或导致 NaN 的 checkpoint 应自动回退。
弹性恢复要处理 GPU 数或 TP/PP/DP 拓扑变化,并确保数据不大面积重复。节点重新加入前检查 GPU ECC/Xid、网络、磁盘和容器版本;恢复后跑 20~100 step 的 loss/梯度/吞吐探针。关键指标包括 MTBF、MTTR、有效训练时间占比、重算 Token、故障类型与重复发生率。
告警 -> 冻结/终止全体 rank -> 收集诊断 -> 隔离坏资源
-> 选择并校验 checkpoint -> 重组拓扑 -> 小步验证 -> 恢复训练
完整版教学
一、先判断故障属于哪一层
GPU Xid/ECC、机器掉电、NCCL timeout、对象存储抖动、坏数据和 loss NaN 的处理完全不同。网络瞬断可以有限重试,持续 ECC 应下线设备,坏数据需隔离样本,数值发散则回滚到更早版本并调整训练状态。盲目重启会把确定性故障反复播放。
告警应关联 job、rank、host、GPU UUID、step、最后成功 collective 和数据 shard。分布式错误常由一个最早失败的 rank 引起,其余 rank 只是随后超时;根因分析要按时间线找第一异常,而不是把所有 timeout 当独立故障。
二、为什么需要全局协调
同步数据并行依赖所有 rank 参与同一 collective。一个 rank 退出,其余进程可能永远等待;若部分 rank 自行继续,会对不同 step 的梯度做通信,状态不可用。因此 watchdog 发现成员变化后,应通过 rendezvous/调度器终止旧 world,再以一致成员集启动。
记忆钩子:分布式训练的恢复单位不是“坏掉的那张卡”,而是共享同一训练状态的整个 worker group。
弹性框架可以保留健康资源并重新编组,但仍需加载共同 checkpoint。控制面也要高可用,避免训练节点正常却因单点协调器故障无法恢复。
三、恢复点如何判定健康
每个 rank 写完分片不代表全局版本完成。只有 manifest 列出的分片全部存在、大小与 checksum 正确,并写入最终完成标记,恢复器才可选择。latest 指针只是便利索引,不能替代完整性检查。
| 检查项 | 防止的问题 |
|---|---|
| COMPLETED 标记 | 读到写一半版本 |
| 分片清单 | 漏 rank 文件 |
| checksum | 静默损坏 |
| step 一致 | 混入不同训练步 |
| 训练状态版本 | 新旧代码不兼容 |
| 快速 loss 探针 | 已保存 NaN/坏状态 |
若最新版本不健康,应自动回退前一个,而不是人工临时拼文件。至少保留多个代际和异地副本。
四、拓扑变化怎么处理
原作业可能 TP=8、PP=4、DP=16,恢复时少了 32 张 GPU。若框架支持弹性,可保持 TP/PP 不变、缩小 DP;若连 TP 也改变,则需根据全局张量 shape 和 shard offset 重分片。Pipeline 层数划分变化还涉及 optimizer state 的重新归属。
重分片会产生额外网络和内存峰值,应在离线工具或流式加载中完成,避免先在单机聚合完整模型。新拓扑会改变全局 Batch;要通过梯度累积补齐,或显式调整学习率与 scheduler,不能静默继续。
五、数据进度如何恢复
模型回到 step 50000,数据也必须回到该状态。保存每源 sampler epoch、随机种子、shard 列表、文件 offset 和累计有效 Token,可减少重读。精确一次语义在大规模流式系统很贵,工程上可以接受小窗口 at-least-once,但要量化重复上限。
例如 Checkpoint 每 2 小时一次、吞吐每小时 10 亿 Token,故障最坏重算近 20 亿 Token,平均约 10 亿。若流式游标独立提交到 step 之后,可能跳过数据;所以游标应与 checkpoint 形成同一个逻辑事务或从 checkpoint 恢复。
recoverable_state = model + optimizer + scheduler + RNG + sampler_cursor
这条清单可直接作为恢复验收条件,任一项缺失都要明确其可接受的重复或偏差范围。
六、节点重新加入前要隔离验证
机器重启成功不代表健康。对故障节点检查 GPU 内存、ECC/Xid、NVLink/NIC、磁盘读写与温度,并跑短压力测试。软件侧比较驱动、CUDA、NCCL、容器镜像和配置哈希,防止单节点版本漂移造成慢节点或数值差异。
恢复作业先做通信带宽测试和数据可读性探针,再加载大状态。持续出现同一错误的节点进入 quarantine,不应被调度器立即再次分配给训练任务。坏节点比例超过阈值时宁可缩容恢复,也不要反复拖垮整组。
七、恢复后的验证与指标
先运行 20~100 个观察 step,比较 checkpoint 前的 loss 滑动均值、梯度范数、学习率、吞吐和溢出计数。若偏差超阈值,自动暂停并保留现场。通过后再恢复正常日志频率和 checkpoint 周期。
若一次训练总墙钟 1000 小时,其中故障检测 5 小时、排队 10 小时、恢复加载 15 小时、重算 20 小时,则有效时间占比约 95%,但故障损失 50 小时。MTTR 要拆成发现、调度、加载、验证各阶段,才能知道优化 watchdog、备用容量还是存储带宽。
八、常见误区与追问
- 误区:所有 timeout 都是网络问题。 最早的 GPU、数据或数值异常也会让其他 rank 最终通信超时。
- 误区:只重启失败 rank 就能续跑。 同步 collective 需要整个 group 对成员与 step 达成一致。
- 误区:恢复成功等于进程启动成功。 还要验证状态完整、loss 连续和数据游标正确。
- 追问:如何降低 MTTR? 提前校验 checkpoint、保留热备资源、并行加载并自动化健康检查。
- 追问:故障后能否缩卡继续? 可以,但需支持重分片,并保持或显式调整全局 Batch 与优化配置。
- 追问:如何处理反复坏样本? 记录稳定样本 ID,在确认确定性复现后隔离并审计,而非无限重试。
九、加强记忆
集群恢复可记成“识、停、隔、载、验”:识别第一故障层,全局停止旧 worker,隔离坏资源,加载最近完整且可重分片的状态,再用小步训练验证数值与数据连续。配合 MTBF/MTTR、重算 Token 和故障复发率,恢复系统才能从“自动重启”升级为真正的预训练容错。