训练中断怎么办?ms-swift断点续训机制使用说明
在大模型微调实践中,训练过程动辄持续数小时甚至数天,却常因显存溢出、网络波动、集群调度抢占、意外断电或人为误操作而突然中止。此时若从头开始重训,不仅浪费大量计算资源和时间成本,更可能因随机种子、数据加载顺序等不可复现因素导致结果偏差。如何让训练“断而不断”,成为工程落地的关键能力。
ms-swift 框架原生内置的断点续训(Checkpoint Resumption)机制,正是为此而生——它不是简单的权重保存,而是一套覆盖训练状态、优化器参数、学习率调度、数据迭代位置、随机数生成器状态的全量快照系统。无论你使用 LoRA 微调 7B 模型,还是用 Megatron 并行训练 70B 多模态大模型,只要训练中途暂停,下次启动时就能精准回到中断前的毫秒级状态,继续推进。
本文不讲抽象原理,只聚焦一个目标:让你在 15 分钟内真正掌握 ms-swift 断点续训的完整操作链路——从配置要点、中断恢复、常见陷阱到生产级避坑建议,全部基于真实命令行与日志反馈,拒绝空泛描述。
1. 断点续训的核心前提:理解 checkpoint 的构成
在 ms-swift 中,“能续训”不等于“有 checkpoint 文件夹”。很多用户误以为只要--save_steps设置了,生成了checkpoint-xxx目录,就一定能恢复训练。这是最大的认知误区。
真正的断点续训依赖三类关键状态文件,缺一不可:
模型权重文件(
pytorch_model.bin或model.safetensors)
存储当前模型参数,LoRA 权重单独保存在adapter_model.bin中。训练状态字典(
trainer_state.json)
包含当前 step 数、global_step、epoch、loss 曲线历史、learning_rate 调度器当前值等——这是续训能否对齐进度的核心依据。优化器与调度器状态(
optimizer.pt、scheduler.pt)
保存 AdamW 等优化器的state_dict,包括每个参数的exp_avg和exp_avg_sq,直接影响梯度更新方向。
正确做法:ms-swift 默认在每次
--save_steps时,自动同步写入以上三类文件。但前提是你的--output_dir具有可写权限,且磁盘空间充足(尤其optimizer.pt在 7B 模型上可达 2–3GB)。
❌ 常见错误:手动删除
checkpoint-xxx下的optimizer.pt或scheduler.pt;使用--save_only_model true参数;将output_dir挂载为只读 NFS;磁盘满导致写入失败(日志中会出现OSError: No space left on device)。
验证 checkpoint 是否完整,只需执行:
ls -lh output/checkpoint-100/ # 应看到至少以下文件(LoRA 训练为例): # adapter_model.bin # LoRA 权重 # pytorch_model.bin # 基座模型(若启用 full finetune 则为完整权重) # trainer_state.json # 关键!必须存在 # optimizer.pt # 关键!必须存在 # scheduler.pt # 关键!必须存在 # config.json # 模型配置 # args.json # 启动参数快照(用于 infer/export 自动复用)若缺失trainer_state.json或optimizer.pt,该 checkpoint无法用于续训,仅可用于推理或导出。
2. 两种续训方式:命令行直连 vs 配置文件接管
ms-swift 提供两种主流续训路径,适用不同场景。不要混用,否则会引发状态冲突。
2.1 方式一:命令行参数直连(推荐新手 & 单卡调试)
这是最直观的方式:完全复用原始训练命令,仅替换--output_dir为 checkpoint 路径,并添加--resume_from_checkpoint标志。
假设你最初运行的是:
CUDA_VISIBLE_DEVICES=0 swift sft \ --model Qwen/Qwen2.5-7B-Instruct \ --train_type lora \ --dataset 'AI-ModelScope/alpaca-gpt4-data-zh#500' \ --output_dir output \ --num_train_epochs 3 \ --per_device_train_batch_size 1 \ --gradient_accumulation_steps 16 \ --save_steps 50 \ --learning_rate 1e-4 \ --lora_rank 8训练至checkpoint-120时中断。要从中断点继续,请执行:
CUDA_VISIBLE_DEVICES=0 swift sft \ --model Qwen/Qwen2.5-7B-Instruct \ --train_type lora \ --dataset 'AI-ModelScope/alpaca-gpt4-data-zh#500' \ --output_dir output/checkpoint-120 \ # 关键:指向 checkpoint 目录本身 --num_train_epochs 3 \ --per_device_train_batch_size 1 \ --gradient_accumulation_steps 16 \ --save_steps 50 \ --learning_rate 1e-4 \ --lora_rank 8 \ --resume_from_checkpoint true # 必须显式声明为什么
--output_dir要设为checkpoint-120而非output?
因为 ms-swift 的续训逻辑是:以--output_dir为根目录,自动查找其中的trainer_state.json并加载其记录的global_step和epoch。若仍设为output,框架会新建checkpoint-121,而非从120继续。
小技巧:
--resume_from_checkpoint true可简写为-r true,但首次使用建议写全称避免歧义。
2.2 方式二:配置文件接管(推荐多机 & 生产环境)
当训练涉及 DeepSpeed、FSDP 或 Megatron 多机并行时,命令行参数易出错。此时应使用args.json配置文件接管。
ms-swift 在每个 checkpoint 目录下自动生成args.json,完整记录本次训练的所有参数(包括--deepspeed zero2等分布式配置)。续训时只需指定该文件路径:
CUDA_VISIBLE_DEVICES=0,1,2,3 NPROC_PER_NODE=4 \ swift sft \ --config_file output/checkpoint-120/args.json \ # 加载完整配置 --resume_from_checkpoint true优势:
- 100% 还原原始环境,避免参数遗漏(如
--deepspeed,--fsdp,--megatron等);- 支持跨机器续训(只要 checkpoint 文件完整,新机器无需重新下载模型);
args.json中的output_dir字段会被自动忽略,框架仍以你传入的--config_file所在目录为工作根路径。
注意:若修改过
args.json内容(如调整learning_rate),需确保逻辑自洽。例如,若原训练已进行 2 个 epoch,你将num_train_epochs改为 1,则框架会报错终止。
3. 数据加载一致性:为什么 resume 后 loss 突然飙升?
这是续训中最令人困惑的现象:明明trainer_state.json显示global_step=120,恢复后前几个 step 的 loss 却比中断前高 30%。根本原因在于数据迭代器(DataLoader)未同步重置。
ms-swift 默认使用IterableDataset流式加载(尤其--streaming true时),其内部状态(如当前 shard、sample index)不保存在trainer_state.json中。因此,单纯恢复训练状态,数据加载会从头开始,导致样本重复或错位。
正确解法:启用--dataloader_drop_last false+--seed 42(固定随机种子),并确保--dataset参数完全一致。对于流式数据集,ms-swift 会在trainer_state.json中额外记录data_load_state字段(v1.10+ 版本),包含:
"data_load_state": { "shard_idx": 3, "sample_offset": 1247, "epoch": 1 }只要该字段存在且非空,续训时数据加载器将自动跳转至对应位置。
❌ 错误操作:
- 使用
--shuffle true但未设--seed→ 每次重启数据顺序不同; - 更改
--dataset路径或采样比例(如#500改为#1000)→ 数据集结构变化; - 在
--streaming true下手动删除cache_dir→ shard 索引丢失。
验证数据是否对齐:查看日志中Resuming from checkpoint后的首条Step X / Y输出,对比中断前最后一条Step 120 / 1000的loss值。若差异 < 5%,则数据加载正常;若 > 20%,请检查上述配置。
4. 分布式训练续训:DeepSpeed / FSDP / Megatron 的特殊处理
单卡续训逻辑清晰,但多机多卡场景下,各节点的 checkpoint 必须严格一致,否则会导致梯度同步失败。
4.1 DeepSpeed ZeRO 续训(最常用)
DeepSpeed 的 checkpoint 是分片存储的:主节点(rank 0)保存zero_pp_rank_0/...,其他节点保存各自分片。ms-swift 已封装此逻辑,你只需确保:
- 所有节点挂载同一共享存储(如 NFS、Lustre),且
output_dir路径完全一致; - 启动命令中
--deepspeed参数与原始训练完全相同(如--deepspeed zero2); --resume_from_checkpoint true由所有节点统一传入。
验证方法:在任意节点执行
ls -d output/checkpoint-120/zero_pp_rank_*/ # 应看到 rank_0, rank_1, ... 目录 cat output/checkpoint-120/zero_pp_rank_0/trainer_state.json | jq '.global_step' # 所有 rank 的值必须相同
4.2 FSDP 续训
FSDP 要求--fsdp参数(如--fsdp full_shard)与原始训练严格一致。ms-swift 会自动从checkpoint-120中加载pytorch_model_fsdp_0.bin等分片文件。关键点:
- 不要手动合并分片(
--fsdp_use_orig_params false时,分片不可直接加载); - 若使用
--fsdp_offload_params true,需确保offload_dir路径可访问。
4.3 Megatron-SWIFT 续训
Megatron 的 checkpoint 结构与 PyTorch 原生不同,包含mp_rank_00/、tp_rank_00/等目录。ms-swift 通过megatron sft命令自动识别:
NPROC_PER_NODE=2 CUDA_VISIBLE_DEVICES=0,1 megatron sft \ --config_file output/checkpoint-120/args.json \ --resume_from_checkpoint true重要限制:Megatron 续训不支持跨 TP/PP 组合变更。例如,原始训练用
--tensor-model-parallel-size 2,续训时不能改为4,否则会报KeyError: 'module.language_model.embedding.word_embeddings.weight'。
5. 实战排障:5 个高频问题与一键修复方案
| 问题现象 | 根本原因 | 修复命令/操作 |
|---|---|---|
ValueError: Cannot resume from checkpoint: trainer_state.json not found | checkpoint 目录不完整,或--output_dir指向父目录而非 checkpoint 本身 | ls -l output/checkpoint-120/trainer_state.json→ 若不存在,换用更早的 checkpoint;若存在,检查--output_dir是否写错 |
RuntimeError: Expected all tensors to be on the same device | 模型权重与优化器状态设备不匹配(如权重在 cuda:0,optimizer 在 cpu) | 删除output/checkpoint-120/optimizer.pt,重新运行原命令(框架会重建 optimizer);或升级 ms-swift 至 v1.12+(自动设备对齐) |
OSError: [Errno 17] File exists: 'output/checkpoint-121' | --output_dir设为output而非checkpoint-120,框架尝试新建 checkpoint | 修改命令,将--output_dir明确设为output/checkpoint-120 |
Loss spikes at step 121, then slowly recovers | 数据加载未同步,样本重复或错位 | 添加--seed 42 --dataloader_drop_last false,并确认args.json中data_load_state字段存在且有效 |
Loading checkpoint failed: size mismatch for ... | 模型结构变更(如修改--lora_rank或--target_modules) | 不可续训!必须从头训练。修改参数后,旧 checkpoint 的权重维度与新模型不兼容 |
终极保底方案:若多次尝试失败,可利用 ms-swift 的
--load_args false+--adapters推理能力,先验证 checkpoint 是否能成功加载并生成合理输出:swift infer --adapters output/checkpoint-120 --max_new_tokens 32 # 若能输出通顺文本,说明权重完好,问题必在训练配置
6. 生产环境最佳实践:让续训真正可靠
在企业级训练平台中,断点续训不是“能用就行”,而是“必须零故障”。以下是经过千卡级集群验证的硬性规范:
6.1 checkpoint 策略配置(写入训练脚本)
# 推荐组合(平衡可靠性与磁盘占用) --save_steps 100 \ --save_total_limit 3 \ # 只保留最近 3 个 checkpoint,防磁盘爆满 --save_on_each_node false \ # 多机时仅主节点保存,避免重复写入 --overwrite_output_dir false \ # 防止误覆盖已有 checkpoint --logging_steps 10 \ # 日志频率高于 save_steps,便于定位中断点6.2 磁盘健康监控(运维必备)
在训练脚本前加入磁盘空间检查:
#!/bin/bash DISK_FREE=$(df /path/to/output | awk 'NR==2 {print $4}') if [ "$DISK_FREE" -lt 10000000 ]; then # 小于 10GB echo "ERROR: Disk space low! $(df -h /path/to/output)" exit 1 fi # 后续执行 swift sft ...6.3 自动化续训脚本(示例)
#!/bin/bash # resume.sh:自动检测最新可用 checkpoint 并续训 OUTPUT_DIR="output" LATEST_CKPT=$(ls -t ${OUTPUT_DIR}/checkpoint-* 2>/dev/null | head -n1) if [ -z "$LATEST_CKPT" ]; then echo "No checkpoint found. Starting fresh training..." exec swift sft "$@" else echo "Resuming from $LATEST_CKPT" exec swift sft --resume_from_checkpoint true --output_dir "$LATEST_CKPT" "$@" fi运行方式:bash resume.sh [original_args...]
获取更多AI镜像
想探索更多AI镜像和应用场景?访问 CSDN星图镜像广场,提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,支持一键部署。