训练完发现保存目录里是一堆 model-00001-of-00008.bin 加上零散的分片文件,直接用 Transformers 加载失败,报缺少参数。

一开始怀疑是「合并脚本用的世界大小与实际不一致」,查了一圈,方向不对。

原因不止一个,得分开看。ZeRO-3 默认按数据并行维度保存分片。少数情况下是没有设置 stage3_gather_16bit_weights_on_model_save。

另外,保存时只有部分 rank 落盘,文件不全。

第一件事是在配置里开启保存前聚合

{"zero_optimization":{"stage":3,"stage3_gather_16bit_weights_on_model_save":true}}

接着用官方脚本执行合并

python zero_to_fp32.py . ./pytorch_model.bin

然后确认合并后文件大小与参数量匹配

python -c "import os;print(round(os.path.getsize('pytorch_model.bin')/1e9,2),'GB')"

等前面都确认过,再用 Transformers 加载验证

python -c "from transformers import AutoModelForCausalLM as M;print(M.from_pretrained('.').config.model_type)"

中途换过一次思路,把范围缩到最小的那一层,反而快了。

恢复的判定其实很直接。合并得到单个完整权重文件,能被 Transformers 正常加载并推理,输出与训练结束时一致。

容易忽略的是,合并时不需要 GPU,但需要足够的内存容纳完整权重,70B 模型在 128G 内存的机器上也可能被系统杀掉。监控比日志更早给出信号,事后回看经常能提前半小时发现异常。

作者 9823189