Llama-Factory如何设置保存频率?按epoch或step自由设定
Llama-Factory如何设置保存频率?按epoch或step自由设定
在大模型微调的实践中,最让人“又爱又怕”的莫过于漫长的训练过程。爱的是模型逐渐收敛、性能提升的成就感;怕的是一旦断电、显存溢出或者远程连接中断,几天的心血可能付诸东流。这时候,一个灵活可靠的检查点(Checkpoint)保存机制就成了救命稻草。
Llama-Factory 作为当前最受欢迎的开源大模型微调框架之一,不仅支持 LLaMA、Qwen、Baichuan 等主流架构的全参数微调与 LoRA/QLoRA 高效微调,还在训练控制上做到了极致精细——尤其是对模型保存频率的自由配置,真正实现了“想什么时候保存就什么时候保存”。
从一次崩溃说起:为什么保存频率如此重要?
设想这样一个场景:你正在对 Qwen-7B 进行指令微调,数据集有 10 万条,batch size 设为 4,梯度累积步数为 8,预计要跑 2 万 step 才能收敛。训练到第 1.5 万步时,服务器突然重启,而你的模型只在初始和最终各保存了一次……这意味着什么?意味着你得重跑至少 75% 的训练量。
这正是传统训练脚本的通病:要么不保存,要么固定每 1000 步才保存一次,缺乏灵活性。而 Llama-Factory 提供了两种粒度级别的保存策略:save_steps 和 save_epochs,让用户可以根据任务需求自主选择。
按步保存 vs 按轮保存:本质区别在哪?
save_steps:以训练步为单位,精准掌控进度
一个 step 对应一个 batch 的前向传播 + 反向传播 + 参数更新。如果你设置了 per_device_train_batch_size=4,gradient_accumulation_steps=8,那么每 8 个物理 batch 才构成一个有效的参数更新 step。
当你设置:
save_steps: 500 就意味着:每完成 500 个有效训练 step,就自动保存一次模型检查点。这对于长周期、大规模训练尤其友好。例如 max_steps=3000 时,你会得到 checkpoint-500、checkpoint-1000、…、checkpoint-3000 共 6 个版本,随时可以回滚或评估。
这种模式适合:
- 数据集极大,单个 epoch 耗时过长;
- 希望高频监控模型变化趋势;
- 实验性调试,需要细粒度对比不同阶段的表现。
save_epochs:以完整遍历数据为节奏,关注学习进程
相比之下,save_epochs 更贴近人类直觉。一个 epoch 表示模型已经看过一遍整个训练集。当你的数据集较小(比如几千条),每个 epoch 几分钟就能跑完,这时用“每轮保存一次”显然更合理。
配置如下:
save_epochs: 1 表示每个 epoch 结束后保存一次。如果训练 3 个 epoch,就会生成 checkpoint-epoch-1、checkpoint-epoch-2、checkpoint-epoch-3。
这种模式更适合:
- 小样本实验,强调“知识轮回”后的提升;
- 学习率调度器基于 epoch 设计(如 StepLR);
- 希望清晰观察 loss 和 metric 随 epoch 的演化曲线。
值得注意的是,这两个参数是互斥的——你只能选其一。框架会根据全局计数器判断是否触发保存逻辑,避免重复写入。
内部机制揭秘:它是怎么做到的?
Llama-Factory 构建于 Hugging Face Transformers 的 Trainer 之上,但做了大量增强。其保存逻辑并非简单轮询,而是通过回调系统(Callback System)集成进训练循环的核心路径中。
具体流程如下:
graph TD A[开始训练] --> B{进入下一个 step/epoch} B --> C[执行 forward/backward/update] C --> D{global_step % save_steps == 0 ?} D -- 是 --> E[调用 _save_checkpoint()] D -- 否 --> F[继续训练] E --> G[写入 model, optimizer, scheduler state] G --> H[生成 checkpoint-step_xxx 目录] H --> I{超出 keep_save_n_checkpoints?} I -- 是 --> J[删除最旧检查点] I -- 否 --> K[保留] K --> L[进入下一循环] 关键点包括:
- 主进程保护:在多 GPU 或分布式训练中,仅 rank=0 的进程执行保存操作,防止文件冲突;
- 状态完整性:不仅保存模型权重,还包括优化器状态、学习率调度器、训练步数等元信息,确保可完全恢复训练;
- 智能清理:配合
keep_save_n_checkpoints: 3使用,自动保留最近 N 个检查点,避免磁盘爆满; - 命名规范化:所有检查点采用统一格式
checkpoint-step_1000或checkpoint-epoch-2,便于脚本批量加载或分析。
此外,该机制还与评估模块深度联动。例如你可以这样配置:
evaluation_strategy: steps eval_steps: 500 save_steps: 1000 即每 500 步评估一次,每 1000 步保存一次。这样每次保存的模型都经过两次验证,选出的往往是性能更稳定的版本。
实战配置:YAML 文件怎么写?
下面是一个典型的训练配置文件示例(train_config.yaml):
model_name_or_path: meta-llama/Llama-3-8b-instruct train_file: data/train.json validation_file: data/dev.json output_dir: ./output/lora-qwen7b # 保存策略:每 1000 步保存一次 save_steps: 1000 # 或者使用 save_epochs: 1 logging_steps: 10 evaluation_strategy: steps eval_steps: 500 per_device_train_batch_size: 4 gradient_accumulation_steps: 8 max_steps: 10000 learning_rate: 2e-4 lr_scheduler_type: cosine warmup_ratio: 0.1 weight_decay: 0.01 max_grad_norm: 1.0 # 仅保留最近 3 个检查点 keep_save_n_checkpoints: 3 启动命令也很简洁:
python src/train_bash.py \ --config train_config.yaml \ --stage sft \ --do_train \ --fp16 框架会自动解析 save_steps 并注册对应的保存回调函数。无需手动干预,也不用手动加 hook。
图形化操作:WebUI 让非程序员也能轻松配置
对于不熟悉代码的用户,Llama-Factory 还提供了 WebUI 界面。在【训练参数】页签下,可以直接填写“保存步数”或勾选“每个 epoch 保存”。

图:Llama-Factory WebUI 中的保存频率设置界面
这种方式特别适合教学、演示或快速原型开发。即使是产品经理或业务分析师,也能独立完成基础微调实验的设计与执行。
不只是“保存”,更是工程鲁棒性的体现
其实,保存频率设置背后反映的是整个训练系统的成熟度。一个好的微调框架,不仅要能让模型训得出来,更要保证它“不会丢”。
Llama-Factory 在这方面考虑得非常周全:
✅ 断点续训无忧
只要检查点存在,就可以通过 --resume_from_checkpoint 参数从中断处恢复训练。无论是意外中断还是主动暂停,都不再意味着归零。
✅ 存储效率可控
通过 keep_save_n_checkpoints 控制最大保留数量,避免 SSD 被海量 checkpoint 占满。比如训练 10 万步、每 1000 步保存一次,原本会产生 100 个检查点(数十 GB),现在只需保留最新的 3 个即可。
✅ I/O 性能优化建议
虽然框架本身无法改变硬件限制,但它鼓励用户使用 NVMe SSD 而非机械硬盘或网络存储(NFS),因为频繁写盘会对训练速度造成显著影响。尤其是在 QLoRA 场景下,由于模型本身轻量化了,I/O 开销反而可能成为瓶颈。
✅ 与评估形成闭环
理想的做法是让 eval_steps ≤ save_steps,确保每一次保存的模型都已经过充分验证。结合 TensorBoard 或 WandB,你可以直观看到哪一轮/哪一步的模型在验证集上表现最佳,从而做出科学决策。
典型应用场景解析
场景一:长期训练防丢失
某团队在 A100 上对 Baichuan2-13B 进行全参微调,总步数约 15,000。为防意外,设置 save_steps=1000。即使在第 12,345 步崩溃,也能从 checkpoint-12000 恢复,节省超过 80% 的计算资源。
场景二:超参搜索快速对比
研究人员测试三种不同的 learning rate(1e-4, 2e-4, 5e-4),每组只训练 600 步观察趋势。此时设置 save_steps=200,可在 step 200、400、600 分别保存模型,后期统一评估哪个 lr 收敛更快。
场景三:小数据集周期性观察
医疗问答任务仅有 3,000 条标注数据,每个 epoch 约 200 步。用户更关心“学完一遍数据后有没有进步”,于是设置 save_epochs: 1,并绘制每个 epoch 的 loss 下降曲线,辅助判断是否过拟合。
工程建议与避坑指南
尽管功能强大,但在实际使用中仍需注意以下几点:
| 注意事项 | 建议 |
|---|---|
| 不要盲目高频保存 | 如无特殊需求,save_steps 不建议小于 100,否则 I/O 压力大且浪费空间 |
| 合理规划磁盘容量 | 一个 Llama-3-8B 的 LoRA 检查点约 200MB~500MB,全参微调可达数 GB,提前预留足够空间 |
| 避免 eval_steps > save_steps | 否则可能出现“保存了却没评估”的情况,失去选模依据 |
| 分布式训练注意权限 | 多节点环境下确保共享存储路径一致,并仅由主节点写入 |
| 恢复训练需匹配配置 | 继续训练时,必须使用相同的 tokenizer、max_length 等预处理设置 |
另外,如果你使用的是云服务(如 AWS、阿里云),建议将输出目录挂载到高性能云盘(如 EBS io2 或本地 NVMe),而不是普通 HDD 或低速 NAS。
结语:灵活保存,不只是便利,更是生产力
Llama-Factory 的 save_steps 与 save_epochs 功能看似只是一个小小的配置项,实则承载着现代 AI 工程实践的核心理念:可控、可复现、可持续。
它让开发者不再提心吊胆地守着训练日志,也让自动化流水线得以构建——CI/CD for AI 不再是空谈,而是可以通过“定期保存 + 自动评估 + 最佳模型部署”串联起来的真实工作流。
未来,我们或许会看到更多智能化的保存策略,比如:
- 基于 loss 平台期动态保存;
- 增量式差分保存(只存变化部分);
- 根据 GPU 利用率自适应调整保存频率。
而 Llama-Factory 当前的设计,已经为这些高级特性打下了坚实的基础。它的价值,不仅在于“能做什么”,更在于“让普通人也能安全高效地做”。