
llamafactory sft微调坑 继续训练 ,为什么save_steps: 40没有生效实际 100 步才保存这是一个很典型的问题让我帮你排查。核心怀疑是从 checkpoint 恢复训练时save_steps被旧 checkpoint 里的training_args覆盖了。让我先检查一下你的 checkpoint 目录和配置文件Sandbox 里没有你的实际文件让我写一个你可以在本机运行的诊断脚本同时先给你分析最可能的原因分析为什么save_steps: 40没有生效实际 100 步才保存你的配置看起来没问题save_steps: 40写得很清楚。问题最可能出在resume_from_checkpoint上。以下是排查思路 最可能的原因旧 checkpoint 里的training_args覆盖了新配置你的checkpoint-600很可能是之前用save_steps: 100训练保存的600 ÷ 100 6恰好整除。当使用resume_from_checkpoint时HuggingFace Trainer / LLaMA-Factory 可能会从 checkpoint 目录下的training_args.json读取旧的训练参数包括save_steps: 100覆盖你新配置的40。验证方法在你本机运行上面的诊断脚本重点看第 3 步的输出checkpoint-600/training_args.json 里的 save_steps 是多少如果是100→ 确认是旧配置覆盖了如果是40→ 需要看其他原因 其他可能原因#可能原因说明1命令行参数覆盖如果启动时用了--save_steps 100命令行参数会覆盖 YAML 配置文件2LLaMA-Factory 版本行为某些版本的 LLaMA-Factory 在 resume 时会从 checkpoint 恢复完整的 TrainingArguments3save_strategy未显式设置虽然 HF 默认save_steps设了就自动用steps但某些版本需要显式指定✅ 解决方案按推荐顺序方案 1删除旧 checkpoint 中的training_args文件推荐# 删除旧的 training_args强制使用新配置rm/mnt/workspace/output/train_1024_0/checkpoint-600/training_args.jsonrm/mnt/workspace/output/train_1024_0/checkpoint-600/training_args.bin2/dev/null# 但保留 trainer_state.json里面保存了 global_step 等恢复信息然后重新启动训练新配置的save_steps: 40应该会生效。方案 2显式添加save_strategy在 YAML 配置中加上save_strategy:stepssave_steps:40方案 3检查启动命令确认启动命令中没有通过命令行覆盖# ❌ 如果有这样的命令行参数会覆盖 YAML--save_steps100# ✅ 确保只通过 YAML 文件配置llamafactory-cli train your_config.yaml方案 4如果以上都不行 — 手动修改 checkpoint 的 step 计数importjson# 修改 trainer_state.json让 global_step 对齐到 40 的倍数path/mnt/workspace/output/train_1024_0/checkpoint-600/trainer_state.jsonwithopen(path)asf:statejson.load(f)# 600 已经是 40 的倍数 (600/4015)所以这里不需要改# 但确认 save_steps 字段state[save_steps]40# 强制写入withopen(path,w)asf:json.dump(state,f,indent2)print(已修改 trainer_state.json 中的 save_steps 为 40) 快速诊断清单请在你的机器上运行以下命令把结果发给我# 1. 看旧 checkpoint 的训练参数cat/mnt/workspace/output/train_1024_0/checkpoint-600/trainer_state.json|python-mjson.tool|grep-Esave_steps|global_step|logging_steps# 2. 看 training_args.jsoncat/mnt/workspace/output/train_1024_0/checkpoint-600/training_args.json|python-mjson.tool|grep-Esave_steps|logging_steps|eval_steps# 3. 看启动命令检查是否有命令行覆盖# 确认你的启动方式是否额外传了 --save_steps 参数最关键的一步看checkpoint-600/training_state.json里的save_steps值。如果它是 100那就是罪魁祸首——修改这个文件再重启训练即可。直接删除training_state.json可能会报错导致训练无法启动。因为 HuggingFace Trainer 或 LLaMA-Factory 在恢复训练时可能会尝试读取这个文件如果找不到可能会抛出FileNotFoundError。更安全、更推荐的做法是直接修改里面的值而不是删除。我们可以直接把旧 checkpoint 里的save_steps强制改成 40这样既不影响恢复训练优化器状态、步数等依然保留又能让新配置生效。你可以直接在终端运行这段 Python 脚本来“安全打补丁”importjsonimportos ckpt_dir/mnt/workspace/output/train_1024_0/checkpoint-600# 1. 修改 training_state.jsonta_pathos.path.join(ckpt_dir,training_state.json)ifos.path.exists(ta_path):withopen(ta_path,r)asf:tajson.load(f)ta[save_steps]40ta[logging_steps]20# 顺便确保日志也是你要的频率withopen(ta_path,w)asf:json.dump(ta,f,indent2)print(f✅ 已修改{ta_path}中的 save_steps 为 40)# 2. 修改 trainer_state.json HuggingFace 的状态文件里也会存一份ts_pathos.path.join(ckpt_dir,trainer_state.json)ifos.path.exists(ts_path):withopen(ts_path,r)asf:tsjson.load(f)ts[save_steps]40ts[logging_steps]20withopen(ts_path,w)asf:json.dump(ts,f,indent2)print(f✅ 已修改{ts_path}中的 save_steps 为 40)总结一下哪些文件能动哪些不能动在checkpoint-600文件夹里❌绝不能删adapter_model.bin或pytorch_model.bin模型权重、optimizer.bin优化器状态、scheduler.pt学习率调度器、rng_state.pth随机数种子。删了等于没法接着训练了。⚠️不要直接删建议修改training_state.json、trainer_state.json。删了可能报错按上面的脚本改成你想要的数值最稳妥。✅可以删training_state.bin如果存在的话这是旧版遗留文件一般没用。你先跑一下这个脚本打补丁然后再用原本的 YAML 配置启动训练这次 40 步应该就会乖乖保存了