训练完发现保存目录里是一堆 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 内存的机器上也可能被系统杀掉。监控比日志更早给出信号,事后回看经常能提前半小时发现异常。