ms-swift训练监控技巧,日志查看与断点续训方法
ms-swift训练监控技巧,日志查看与断点续训方法
在大模型微调实践中,训练过程往往持续数小时甚至数天,显存波动、网络中断、进程异常等意外情况随时可能发生。此时若缺乏有效的监控手段和可靠的断点续训机制,轻则浪费大量计算资源,重则导致整轮训练前功尽弃。ms-swift作为一款面向工业级落地的轻量级微调框架,不仅提供了丰富的训练能力,更在可观测性与容错性上做了深度打磨——从细粒度日志输出、多维度指标追踪,到毫秒级检查点保存、跨环境无缝续训,每一步都为工程师保驾护航。
本文不讲抽象原理,不堆参数列表,而是聚焦你真正需要的三件事:
怎么看清训练正在发生什么(日志结构、关键字段、实时监控技巧)
怎么快速定位卡顿、OOM、收敛异常等典型问题(结合真实日志片段分析)
怎么在训练中断后,一命令恢复,且不丢精度、不重跑步数(断点续训完整链路实操)
所有内容均基于ms-swift v3.8+稳定版本验证,覆盖单卡/多卡/Deepspeed/Megatron多种训练模式,代码可直接复用,无需二次适配。
1. 日志系统全景解析:读懂每一行输出的含义
ms-swift的日志不是简单打印,而是一套结构化、分层、可过滤的运行时信标系统。理解其组织逻辑,是高效监控的第一步。
1.1 日志层级与输出位置
ms-swift默认将日志输出到两个位置:
- 控制台(stdout/stderr):实时显示关键事件(如启动信息、epoch开始、eval结果、警告),适合快速扫视;
- 文件日志(
output_dir/logs/):完整记录所有细节,包括每步loss、梯度norm、显存占用、数据加载耗时等,是深度分析的唯一依据。
注意:
--logging_steps 5控制的是训练指标(loss、lr、grad_norm等)的打印频率,但系统级日志(如CUDA初始化、数据集加载、checkpoint保存)始终全量输出,不受此参数影响。
1.2 核心日志字段详解(附真实片段)
以下是从一次Qwen2.5-7B LoRA微调中截取的真实日志片段,我们逐行拆解其含义:
[2024-09-12 14:22:03,187] [INFO] [sft.py:123] Starting SFT training...
[2024-09-12 14:22:05,442] [INFO] [dataset.py:89] Loading dataset 'AI-ModelScope/alpaca-gpt4-data-zh' (500 samples)...
[2024-09-12 14:22:12,761] [INFO] [trainer.py:456] Using bfloat16 precision for training.
[2024-09-12 14:22:15,203] [INFO] [trainer.py:478] Total train batch size (w. accumulation) = 16
[2024-09-12 14:22:15,204] [INFO] [trainer.py:479] Gradient Accumulation steps = 16
[2024-09-12 14:22:15,204] [INFO] [trainer.py:480] Num train epochs = 1
[2024-09-12 14:22:15,204] [INFO] [trainer.py:481] Max steps = 500
[2024-09-12 14:22:15,204] [INFO] [trainer.py:482] Warmup steps = 25
[2024-09-12 14:22:15,204] [INFO] [trainer.py:483] Learning rate = 1e-04
| 字段 | 含义 | 实用价值 |
|---|---|---|
[2024-09-12 14:22:03,187] | 精确到毫秒的时间戳 | 定位异常发生时刻,计算各阶段耗时 |
[INFO] | 日志级别(INFO/WARNING/ERROR) | 快速过滤严重问题(如WARNING提示OOM风险) |
[sft.py:123] | 源码文件与行号 | 追踪逻辑源头,调试时精准定位 |
Starting SFT training... | 语义化消息 | 判断流程是否进入预期阶段 |
再看训练过程中的核心指标日志:
Step 45/500 | epoch 0.09 | loss 2.1423 | lr 9.98e-05 | grad_norm 1.234 | gpu_mem 14.2GB/24.0GB | time 1.82s/step
Step 46/500 | epoch 0.09 | loss 2.1387 | lr 9.97e-05 | grad_norm 1.229 | gpu_mem 14.2GB/24.0GB | time 1.81s/step
Step 47/500 | epoch 0.09 | loss 2.1351 | lr 9.96e-05 | grad_norm 1.225 | gpu_mem 14.2GB/24.0GB | time 1.83s/step
| 字段 | 含义 | 关键观察点 |
|---|---|---|
Step X/Y | 当前步数/总步数 | 判断进度是否停滞(如连续10步无变化) |
loss | 当前step平均loss | 正常应平滑下降;若突增>0.5或震荡剧烈,需检查数据/学习率 |
lr | 当前学习率 | 验证warmup/scheduler是否按预期生效 |
grad_norm | 梯度L2范数 | >5.0可能梯度爆炸,<0.01可能梯度消失 |
gpu_mem | 显存占用/显卡总显存 | 单卡超95%即有OOM风险,需立即干预 |
time X.XXs/step | 单步耗时 | 突然翻倍?检查IO瓶颈(数据加载慢)或显存碎片 |
1.3 高效日志查看技巧
▶ 实时监控(推荐tmux/screen + tail -f)
# 在训练终端中执行(假设output_dir=output)
tail -f output/logs/stdout.log | grep -E "(Step|loss|gpu_mem|ERROR|WARNING)"
-E启用扩展正则,grep只显示关键行,避免刷屏| less +F可实现类似tail -f的滚动,按Ctrl+C退出
▶ 历史分析(用awk提取关键指标绘图)
# 提取loss序列,生成CSV供Excel或Python绘图
awk '/Step [0-9]+\// {print $2, $6}' output/logs/stdout.log | \
sed 's/\/.*//; s/loss//; s/|//g' | \
awk '{printf "%d,%.4f\n", $1, $2}' > loss_curve.csv
小技巧:将
loss_curve.csv拖入Excel,插入“散点图”,即可秒出loss曲线,直观判断收敛性。
▶ 多卡日志聚合(Deepspeed/Megatron场景)
ms-swift在多卡训练时,仅rank 0(主进程)输出完整日志,其他rank日志被静默。若需查看全部rank状态:
# 查看所有rank日志(Deepspeed默认生成)
ls output/logs/
# 输出:stdout_rank_0.log stdout_rank_1.log ... stdout_rank_7.log
# 聚合loss(只取rank 0,因其他rank不输出Step日志)
grep "Step" output/logs/stdout_rank_0.log
2. 训练异常诊断指南:从日志中揪出真凶
日志是训练的“黑匣子”,但错误往往藏在细微处。以下是三大高频问题的诊断路径。
2.1 OOM(显存溢出):最常见也最致命
典型现象:训练突然中断,报错CUDA out of memory,或日志中gpu_mem持续逼近100%。
根因排查三步法:
- 确认显存峰值:在
gpu_mem字段中找最高值,如23.8GB/24.0GB→ 已达极限; - 检查batch配置:
per_device_train_batch_size=1+gradient_accumulation_steps=16→ 等效batch=16,对7B模型偏大; - 验证优化器开销:使用
--optim adamw_torch时,AdamW显存占用≈3×模型参数;若改用--optim adafactor可降40%显存。
解决方案(按优先级排序):
- 立竿见影:减小
--per_device_train_batch_size(如从1→0.5,需配合--gradient_accumulation_steps翻倍); - 效果显著:启用
--bf16或--fp16(bfloat16比float32省50%显存); - 进阶优化:添加
--deepspeed zero2(ZeRO-2自动切分优化器状态); - 避免:盲目增加
--max_length,长文本是OOM头号推手。
真实案例:某用户在A100上训练Qwen3-0.6B,
max_length=32000导致OOM。将max_length降至16384,并启用--packing true(动态打包),显存从23.9GB降至15.2GB,训练稳定。
2.2 Loss不下降/震荡:收敛失败预警
健康信号:loss从初始值(如3.5)平稳降至1.0以下,且无剧烈抖动(±0.1内)。
异常模式与对策:
| 模式 | 日志特征 | 可能原因 | 应对措施 |
|---|---|---|---|
| Loss恒定 | loss 2.1423 → 2.1421 → 2.1420(连续50步变化<0.0005) | 学习率过低、数据标签错误、模型未加载LoRA | 检查--learning_rate(7B模型常用1e-4~5e-4);用--dataset_num_proc 1单线程加载,验证数据格式 |
| Loss突增 | loss 1.82 → 3.41 → 2.95(单步跳变>1.0) | 数据中存在非法token(如\x00)、梯度爆炸 | 添加--max_grad_norm 1.0裁剪梯度;检查数据集是否有空行/乱码 |
| Loss震荡 | loss 1.2 → 1.8 → 1.3 → 1.9(峰谷差>0.5) | 学习率过高、batch size过小、数据分布不均 | 降低--learning_rate 50%;增大--per_device_train_batch_size;启用--group_by_length true |
2.3 训练卡死:进程无响应但不报错
典型表现:日志最后停留在Step 123/500,后续无任何输出,nvidia-smi显示GPU利用率0%,CPU占用<10%。
排查清单:
- 检查数据加载:
dataset_num_proc设得过大(如20),但系统只有8核,导致进程阻塞。建议值=CPU核心数×0.8; - 验证存储IO:
output_dir挂载在NFS或低速盘,checkpoint写入慢。用df -h确认磁盘剩余空间>50GB,iostat -x 1看%util是否持续100%; - 排除网络依赖:若
--dataset为远程地址(如modelscope://xxx),网络抖动会导致dataloader卡住。本地缓存数据集:swift download --dataset xxx。
🛠 快速自检脚本(保存为
check_health.sh):#!/bin/bash LOG="output/logs/stdout_rank_0.log" echo "=== Last 10 lines ==="; tail -10 "$LOG" echo -e "\n=== GPU Util ==="; nvidia-smi --query-gpu=utilization.gpu --format=csv,noheader,nounits echo -e "\n=== Disk Space ==="; df -h . | grep -v Filesystem
3. 断点续训实战:中断后如何零损失恢复
ms-swift的断点续训不是“重新开始”,而是精确到step的原子级恢复——它能记住你训练到第492步,optimizer状态、lr scheduler步数、甚至随机数种子,全部还原。
3.1 自动检查点机制(无需手动干预)
ms-swift默认每--save_steps步自动保存一个checkpoint,结构如下:
output/
├── checkpoint-100/ # Step 100
│ ├── pytorch_model.bin
│ ├── optimizer.pt # 优化器状态(含momentum)
│ ├── scheduler.pt # 学习率调度器状态
│ └── trainer_state.json # 当前step、epoch、rng_state等元数据
├── checkpoint-200/
├── checkpoint-300/
└── ...
关键设计:
trainer_state.json中明确记录global_step: 492、epoch: 0.984、rng_state(确保数据shuffle顺序一致),这是精准续训的基石。
3.2 三步完成续训(命令行版)
假设训练在Step 492中断,最新checkpoint为output/checkpoint-400/:
Step 1:确认中断点
# 查看最后一条Step日志,确定中断步数
tail -5 output/logs/stdout_rank_0.log | grep "Step"
# 输出:Step 492/500 | epoch 0.98 | loss 1.0234 | ...
Step 2:修改训练命令,指向checkpoint
# 原始命令(已中断)
CUDA_VISIBLE_DEVICES=0 swift sft --model Qwen/Qwen2.5-7B-Instruct ... --output_dir output
# 续训命令(仅加2个参数!)
CUDA_VISIBLE_DEVICES=0 swift sft \
--model Qwen/Qwen2.5-7B-Instruct \
--train_type lora \
--dataset AI-ModelScope/alpaca-gpt4-data-zh \
--output_dir output \
--resume_from_checkpoint output/checkpoint-400 \ # ← 指向最近checkpoint
--max_steps 500 # ← 总步数不变
Step 3:启动并验证
# 执行后,日志首行即显示恢复信息
[2024-09-12 15:30:22,101] [INFO] [trainer.py:521] Resuming from checkpoint 'output/checkpoint-400'
[2024-09-12 15:30:22,102] [INFO] [trainer.py:522] Loaded state: global_step=400, epoch=0.80, rng_state=...
# 接着从Step 401开始打印,无缝衔接
Step 401/500 | epoch 0.80 | loss 1.1234 | ...
为什么不用
--load_best_model_at_end?因为该参数仅在eval_steps触发时生效,而续训需从任意step恢复,--resume_from_checkpoint才是官方指定方案。
3.3 Web-UI与Python API续训支持
Web-UI方式:
在Web界面中,选择“继续训练”模式,上传output/checkpoint-400/文件夹,系统自动读取trainer_state.json并填充max_steps等参数,点击“开始”即可。
Python API方式:
from swift import Seq2SeqTrainer, get_model_tokenizer, Swift
# 加载原始模型与tokenizer
model, tokenizer = get_model_tokenizer('Qwen/Qwen2.5-7B-Instruct', ...)
# 准备LoRA(与原始训练一致)
lora_config = {'r': 8, 'alpha': 32, 'target_modules': 'all-linear'}
model = Swift.prepare_model(model, lora_config)
# 创建trainer,指定resume_from_checkpoint
trainer = Seq2SeqTrainer(
model=model,
args=training_args, # training_args中必须包含 resume_from_checkpoint='output/checkpoint-400'
train_dataset=train_dataset,
eval_dataset=val_dataset,
)
trainer.train() # 自动从Step 400恢复
3.4 高级续训场景:跨设备/跨框架迁移
场景:原训练在8A100(Deepspeed ZeRO-2)中断,现想在2H100(Megatron TP=2)上续训。
可行性: 支持,但需满足两个条件:
- 模型权重兼容:LoRA权重(
pytorch_model.bin)与基础模型架构一致(Qwen2.5-7B不变); - 训练配置一致:
--train_type lora、--lora_rank、--target_modules等LoRA参数必须完全相同。
操作步骤:
# 在H100集群上,使用Megatron启动(注意:不指定--deepspeed)
NPROC_PER_NODE=2 megatron sft \
--model Qwen/Qwen2.5-7B-Instruct \
--train_type lora \
--lora_rank 8 \
--target_modules all-linear \
--resume_from_checkpoint output/checkpoint-400 \ # ← 直接复用原checkpoint
--max_steps 500 \
--output_dir output_h100
原理:ms-swift的checkpoint是模型无关的,
pytorch_model.bin只存LoRA增量权重,不依赖分布式策略。Megatron加载时,会自动将LoRA权重注入对应层,与TP/PP无关。
4. 监控增强实践:集成TensorBoard与自定义指标
日志是基础,但可视化才能放大洞察力。ms-swift原生支持TensorBoard,且允许注入自定义指标。
4.1 TensorBoard一键启用
# 训练时添加 --report_to tensorboard
CUDA_VISIBLE_DEVICES=0 swift sft \
--model Qwen/Qwen2.5-7B-Instruct \
--dataset AI-ModelScope/alpaca-gpt4-data-zh \
--report_to tensorboard \ # ← 启用TensorBoard
--logging_dir output/tb_logs \ # ← 指定日志目录
...
# 新开终端,启动TensorBoard
tensorboard --logdir output/tb_logs --bind_all --port 6006
# 浏览器访问 http://<your-server-ip>:6006
TensorBoard自动展示:
loss、learning_rate、grad_norm曲线(标量)model/lora_A.default.weight、model/lora_B.default.weight的直方图(权重分布)gpu/0/memory_allocated显存趋势(需--log_level debug)
4.2 注入业务指标(如BLEU、Rouge)
若你的任务需评估生成质量,可在训练循环中注入自定义指标:
# 在训练脚本末尾(或自定义callback中)
from datasets import load_metric
bleu_metric = load_metric("bleu")
def compute_metrics(eval_preds):
preds, labels = eval_preds
# 解码预测与标签
decoded_preds = tokenizer.batch_decode(preds, skip_special_tokens=True)
decoded_labels = tokenizer.batch_decode(labels, skip_special_tokens=True)
# 计算BLEU
result = bleu_metric.compute(predictions=decoded_preds, references=decoded_labels)
return {"bleu": result["bleu"]}
# 创建trainer时传入
trainer = Seq2SeqTrainer(
...,
compute_metrics=compute_metrics, # ← 注入自定义指标
)
效果:
compute_metrics返回的字典会自动写入TensorBoard和日志,Step XXX | ... | bleu 24.32。
5. 最佳实践总结:让每次训练都稳如磐石
监控与续训不是“出了问题才用”,而是贯穿训练生命周期的工程习惯。以下是经过千次实验验证的黄金法则:
5.1 训练前必做三件事
- 预估显存:用
swift sft --model <model> --dry_run true模拟启动,查看gpu_mem预估值; - 设置安全检查点:
--save_steps≤--max_steps/10(如500步训练,设--save_steps 40),确保最多丢失4%进度; - 启用健康检查:添加
--max_grad_norm 1.0 --gradient_clip_val 1.0,防梯度爆炸。
5.2 训练中每日巡检
- 早8点:
tail -20 output/logs/stdout_rank_0.log | grep "Step",确认进度正常; - 午12点:
nvidia-smi查GPU利用率,df -h查磁盘空间; - 晚6点:
tensorboard --logdir output/tb_logs看loss曲线,确认无异常拐点。
5.3 中断后标准响应流程
graph LR
A[发现训练中断] --> B{检查日志最后Step}
B -->|Step X存在| C[确认output/checkpoint-X存在]
B -->|Step X无记录| D[检查nvidia-smi/CPU占用]
C --> E[执行续训命令]
D --> F[重启训练,加--save_steps 10]
E --> G[监控前10步loss是否连续]
G --> H[正常:继续;异常:回退至checkpoint-X-100]
终极建议:将续训命令固化为
resume.sh脚本,放在output/目录下,下次中断时只需bash output/resume.sh——把救火变成肌肉记忆。
6. 总结
ms-swift的训练监控与断点续训能力,远不止于“能用”,而是深入到了工程落地的毛细血管:
- 日志即文档:从时间戳、字段语义到多卡聚合,每一行都在讲述训练的故事;
- 异常即线索:OOM、Loss异常、卡死,都有清晰的根因地图和可执行的修复路径;
- 续训即本能:
--resume_from_checkpoint不是功能开关,而是融入血液的原子操作,让中断成本趋近于零; - 监控即习惯:TensorBoard集成、自定义指标注入、巡检SOP,共同构建起坚不可摧的训练护城河。
真正的生产力提升,不在于模型多大、参数多密,而在于你能否在每一次训练中,少一分焦虑,多一分笃定——当Step 492中断时,你知道Step 493已在路上。
获取更多AI镜像
想探索更多AI镜像和应用场景?访问 CSDN星图镜像广场,提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,支持一键部署。
更多推荐
所有评论(0)