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%。

根因排查三步法:

  1. 确认显存峰值:在gpu_mem字段中找最高值,如23.8GB/24.0GB → 已达极限;
  2. 检查batch配置:per_device_train_batch_size=1 + gradient_accumulation_steps=16 → 等效batch=16,对7B模型偏大;
  3. 验证优化器开销:使用--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)上续训。

可行性: 支持,但需满足两个条件:

  1. 模型权重兼容:LoRA权重(pytorch_model.bin)与基础模型架构一致(Qwen2.5-7B不变);
  2. 训练配置一致:--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星图镜像广场,提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,支持一键部署。

Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐