在第 7 章中,我们处理了“喂什么数据”;在第 8.1–8.3 节中,我们配置了“怎么跑训练”。但大模型预训练绝不是设定好超参数后就可以去喝咖啡的活儿——一次千卡集群的训练任务通常持续数周,任何细微的异常(一次 loss spike、一轮梯度爆炸、一处显存泄漏)如果未被及时发现,都可能造成数百万乃至上千万元的算力浪费。
本节聚焦工程师在训练现场必须盯死的四项核心指标。它们分别对应模型的学习状态(损失)、数值稳定性(梯度)、硬件边界(显存)和资源效率(吞吐量)。学会读懂这四张“心电图”,是你从“能跑训练”进阶到“能稳训练”的关键。
一、损失曲线(Loss Curve):最直观的健康指标
损失(Loss)是模型在预测下一个 Token 时与真实值的差距,通常用交叉熵(Cross-Entropy)计算(见 4.3 节)。它是训练过程中最先被观察、也最敏感的信号。
1.1 正常长什么样?
在预训练(Pre-training)阶段,典型的 loss 曲线呈现单调递减、斜率逐渐平缓的形态:
| 阶段 | Loss 范围(示意,因模型/数据而异) | 特征 |
|------|----------------------------------|------|
| 初始 Warmup(<1% 步数) | 从极高值快速跌落 | 学习率从 0 线性爬升,参数剧烈调整 |
| 快速下降期 | 逐日明显下降 | 模型在记忆高频模式、习得基础语法 |
| 平台期(>80% 步数) | 降幅极小,缓慢收敛 | 学习率进入余弦退火,模型学习稀有知识 |
对于 SFT(监督微调),由于数据量小、任务聚焦,loss 通常会在数百到数千步内就降至 1.0 以下,随后快速过拟合——这时验证集 loss 比训练集 loss 更重要。
1.2 必须警惕的异常形态
- Loss Spike(尖刺):曲线突然跳升,甚至从一个稳定值瞬间翻倍。常见原因:数据并行时某张卡读到了脏数据(如超长文本、乱码、异常 Unicode)、学习率过高、或者某个数据批次的分布与整体差异过大(数据配比失衡,见 7.3 节)。
- Loss NaN/Inf:数值溢出。几乎总是混合精度训练(FP16/BF16)中梯度爆炸或激活值过大导致。出现 NaN 后,当前 step 的更新必须丢弃,否则权重会被污染。
- Loss Plateau(平台/僵局):长时间不下降。可能是学习率太小、数据重复率过高、或者 batch size 相对于模型规模过小,导致优化器陷入平坦区域。
- Loss 发散(Divergence):持续上升。通常是学习率设置过大、权重初始化异常,或分布式训练中某张卡的梯度未同步(梯度不同步的“静默错误”)。
实用建议:不要只看全局平滑曲线。大模型训练建议记录每步(per-step)的 raw loss,并开一个 100–500 步的滑动平均窗口。尖刺在滑动平均后可能被掩盖,但在 raw loss 中一目了然。
二、梯度范数(Gradient Norm):训练的“脉搏”
损失告诉你“模型学得好不好”,梯度范数(Global Gradient Norm)告诉你“模型能不能稳定地学”。它是所有参数梯度拼接成向量后的 L2 范数。
2.1 正常区间与工程经验
梯度范数没有放之四海而皆准的“标准值”,但在大语言模型预训练中,全局梯度范数稳定在 0.1–10.0 之间通常被认为是健康区间。具体落点取决于:
- 模型深度与宽度;
- 是否使用了梯度裁剪(Gradient Clipping,常见阈值 1.0);
- 混合精度训练中的 Loss Scaling 系数。
如果使用了梯度裁剪(clip_grad_norm),你会看到曲线被“削顶”——范数在达到阈值(如 1.0)后被硬截断。这是正常的保护机制。
2.2 异常解读
| 梯度范数表现 | 可能原因 | 应对措施 |
|-------------|---------|----------|
| 突然飙升至数百/数千 | 数据批次中有极端异常值、梯度爆炸 | 检查该 step 的输入数据;启用/调低梯度裁剪阈值 |
| 持续趋近于 0 | 梯度消失;学习率过小;层归一化/激活函数异常 | 检查深层网络的梯度流;尝试更大学习率或更换初始化 |
| 剧烈震荡 | 学习率过高;数据分布极不稳定;Batch Size 过小 | 减小学习率;增大 batch size 或使用梯度累积 |
| 各卡之间差异极大 | 分布式梯度聚合失败(如某卡未参与 AllReduce) | 检查 NCCL 通信;确认无掉队节点 |
实用建议:在 DeepSpeed、Megatron-LM 等框架中,务必在日志中打印 grad_norm。很多训练失败不是从 loss 先暴露的,而是从梯度范数先开始跳舞。特别是使用 FP16 时,Loss Scaler 的动态调整会直接影响梯度幅度,建议把 Loss Scale 值也同步打印出来。
三、显存占用(Memory Usage):工程瓶颈的“晴雨表”
大模型训练中的 Out-Of-Memory(OOM)是工程师的噩梦。更隐蔽的是显存碎片化导致的 OOM——明明总量够,但找不到连续大块空间分配。
3.1 显存都去哪儿了?
以 AdamW 优化器 + 混合精度训练为例,单卡显存占用大致分为:
| 占用项 | 估算比例 | 说明 |
|--------|---------|------|
| 模型参数 | ~2×参数字节数(FP16/BF16 主权重 + FP32 副本) | 可经 ZeRO 优化切分到多卡/CPU(见 9.5 节) |
| 梯度 | ~2×参数字节数 | 同样可被 ZeRO 分散 |
| 优化器状态 | ~8–12×参数字节数(Adam 的动量/方差) | 这是显存的大头,ZeRO-2/3 主要优化此处 |
| 激活值(Activations) | 与序列长度、Batch Size、模型深度成正比 | 激活检查点(Activation Checkpointing)用计算换显存 |
| 临时缓冲区 | 不定 | 通信缓冲区、CUDA Kernel 临时分配、显存碎片 |
3.2 监控哪些指标?
不要只看 nvidia-smi 里的“已用显存”,训练框架内部通常提供更细粒度的指标:
- Allocated Memory:PyTorch 张量实际占用的显存;
- Reserved Memory:CUDA 缓存池已预留的显存(含碎片);
- Active Memory:当前正向/反向传播中真正活跃的显存;
- Peak Memory:本 step 内的显存峰值。
关键认知:nvidia-smi 显示的已用显存 ≈ Reserved Memory,它不会随着张量释放立即下降(CUDA 缓存机制)。如果 Reserved 长期逼近物理上限,即使 Allocated 不高,也可能因为碎片或峰值波动而 OOM。
实用建议:
- 在日志中每 10–100 步打印一次
torch.cuda.memory_summary()中的 peak memory; - 如果显存占用随训练步数缓慢线性增长,警惕显存泄漏(如某处梯度累积未清空、日志张量未 detach);
- 开启 PyTorch 的
memory profiling或 DeepSpeed 的memory_breakdown,定位哪一层是显存大户。
四、吞吐量(Throughput):算力效率的“血压计”
吞吐量(Throughput)衡量单位时间内处理的 Token 数量,通常以 Tokens/s 或 Samples/s 表示。它是连接“算力投入”与“训练进度”的桥梁。
4.1 如何定义与计算?
- Tokens/s:全局所有 GPU 每秒处理的 Token 总数。最直观,便于估算总训练时间;
- Samples/s:每秒处理的样本(序列)数。受序列长度波动影响大;
- MFU(Model FLOPs Utilization):实际测得的吞吐量 / 理论峰值吞吐量。这是衡量集群效率的黄金指标。
MFU 的行业参考值:
- < 30%:存在严重瓶颈,需立即排查;
- 30%–50%:常见水平,仍有优化空间;
- 50%–60%:优秀水平,工程团队调优到位;
- > 60%:顶尖水平,通常在特定架构(如 H100 + 最优并行策略)下才能达到。
4.2 吞吐突降的排查树
当你在监控面板看到 Tokens/s 突然腰斩,按以下顺序排查:
- 数据加载瓶颈:CPU 预处理(Tokenizer、数据增强)跟不上 GPU。观察
data_loader队列是否空转,或top查看 CPU 负载。解法:增加 DataLoader 的num_workers,使用内存映射(mmap)数据集,或启用预取(prefetch)。 - 通信瓶颈:分布式训练中 AllReduce/AllGather 耗时占比过高。常见于节点间网络(InfiniBand/RoCE)抖动或 NCCL 参数配置不当。解法:检查网络带宽利用率,调整 bucket size,或优化并行策略(见 9.7 节)。
- Checkpoint 阻塞:保存 checkpoint 时,部分框架会阻塞训练流。如果 checkpoint 过大(千亿模型可达 TB 级)且写入慢吞吐(存储带宽不足),会出现周期性“心跳暂停”。
- GPU 降频/过热:硬件故障或散热不足导致 GPU 从全速降频到 P2/P3 状态。观察
nvidia-smi中的功耗与温度。 - 长序列涌现:动态长度数据中突然进入一批超长序列(如 128K context),导致单步计算量剧增。解法:在数据端做长度分桶(bucketing)或截断。
实用建议:不要只监控平均吞吐,要记录每步的实时吞吐。大模型训练中,吞吐的方差比均值更能暴露问题。
五、监控体系搭建:从肉眼到自动化
5.1 工具链选择
| 层级 | 工具 | 适用场景 |
|------|------|----------|
| 单机调试 | TensorBoard | 本地可视化 loss/grad_norm,零配置 |
| 团队协作 | Weights & Biases (WandB) | 自动对比多组实验,支持离线同步 |
| 生产集群 | Prometheus + Grafana | 大规模集群的 GPU/网络/训练指标统一大盘 |
| 日志追踪 | ELK (Elasticsearch/Logstash/Kibana) | 多机日志聚合,关键字告警 |
5.2 告警阈值设置建议
- Loss:连续 50 步上升,或单步增幅 > 20%,触发告警;
- Grad Norm:超过裁剪阈值 3 倍以上,或低于 1e-3 持续 100 步;
- 显存:Reserved Memory > 物理显存的 90%,提前告警;
- 吞吐:单步 Tokens/s 低于近 100 步均值 30%,持续 3 步即告警;
- GPU 温度:> 85°C 告警;> 90°C 自动保护性暂停。
5.3 训练现场的“黑匣子”
大模型训练出问题后,最难的是复现现场。建议每步或每固定步数记录:
- 当前 global step、随机种子、数据文件偏移量;
- 该 step 的输入样本 ID 或哈希(便于定位脏数据);
- 优化器状态摘要(学习率、Loss Scale、Grad Norm);
- 各卡显存峰值。
一旦触发自动熔断(如 Loss NaN),程序应自动保存故障现场 checkpoint 与对应日志切片,而不是直接崩溃退出。
六、小结
训练监控不是“锦上添花”的可视化,而是大模型工程中的生命线工程。
关键 takeaway:
- Loss 看趋势,Grad Norm 看稳定:Loss 降得慢可以忍,Grad Norm 暴走必须立即熔断;
- 显存看峰值与碎片:平均占用是假象,峰值和 Reserved Memory 才是 OOM 的真凶;
- 吞吐看方差:均值骗得了老板,方差骗不了集群;
- 监控要自动化:千卡集群不可能靠人肉盯屏,阈值告警 + 自动熔断 + 现场保留是标配。
在 8.5 节中,我们将讨论训练中断后的恢复机制——Checkpoint 的保存策略、断点续训的工程细节,以及如何在尽量不丢进度的前提下,把监控中发现的问题修复后接回训练。而在第 9 章,这些监控指标将在分布式训练的语境下被进一步放大:梯度范数会涉及全局归一化,显存会被 ZeRO 策略重塑,吞吐则直接受制于网络带宽与并行拓扑。