Profiling:指标与工具
优化之前先测量。"训练慢"是一个没有信息量的描述——慢在计算、通信、数据还是等待?每种的解法完全不同。本章给一套完整的 profiling 方法论:从最快的"利用率曲线"到逐 kernel 的深度分析,按成本递增。
第一层:利用率曲线(零成本,每天看)
Section titled “第一层:利用率曲线(零成本,每天看)”nvidia-smi dmon / DCGM 的利用率曲线是第一手的健康信号:
健康训练: GPU util ████████████████████████████ 平稳 95%+数据饥饿: GPU util ████░█████░███░█████░ 锯齿(断粮,见[数据加载](/storage-data/01-pipeline/data-loading/))同步等待: GPU util ██░░██████░░██░░████ 周期性塌陷(all-reduce 等待)降频: util 平稳但 SM clock 低 → 看频率曲线四种形态对应四类问题,每天看一眼曲线,问题发现早一周。
第二层:step 时间分解(最重要的常规分析)
Section titled “第二层:step 时间分解(最重要的常规分析)”把一个 step 的墙钟时间分解成四段,是最重要的常规 profiling:
| 段 | 内容 | 测量 |
|---|---|---|
| 计算 | 前向 + 反向的 kernel 时间 | profiler / torch 事件 |
| 通信 | all-reduce/all-gather/all-to-all | NCCL 计时 / profiler |
| 数据等待 | DataLoader 阻塞 | profiler 的数据加载段 |
| 其他 | 检查点、同步、CPU 开销 | 差值 |
step 时间 1000 ms = 计算 700 ms(70%)+ 通信 200 ms(20%)+ 数据 50 ms + 其他 50 ms分解结果直接指出优化方向:计算占比低 → 看MFU;通信高 → 看 NCCL 与重叠;数据高 → 看数据加载。没有分解的优化都是猜。
第三层:逐 kernel 分析(PyTorch profiler)
Section titled “第三层:逐 kernel 分析(PyTorch profiler)”torch.profiler 给出每个 kernel 的耗时排名:
from torch.profiler import profile, ProfilerActivitywith profile(activities=[ProfilerActivity.CUDA], record_shapes=True) as prof: step()print(prof.key_averages().table(sort_by="cuda_time_total", row_limit=20))按收益排序的解读方法:
- Top kernel 是什么:GEMM 占大头是正常的(见GEMM);意外的小 kernel 集群(launch 开销)→ 融合
- 小 kernel 密集:成千上万个微小 kernel(几 μs 级)→ launch 开销主导 → torch.compile/CUDA Graph
- 意外的大头:不该慢的算子(LayerNorm、逐元素)进了 top → 没融合,看算子融合
- 计算与通信的重叠:时间线视图(profiler 的 trace)看 all-reduce 与计算是否重叠——没重叠的通信是直接的可省时间
第四层:深度工具(按需)
Section titled “第四层:深度工具(按需)”| 工具 | 用途 | 场景 |
|---|---|---|
| Nsight Systems(nsys) | 时间线全景(kernel/CPU/NCCL/IO) | 系统级重叠分析 |
| Nsight Compute(ncu) | 单 kernel 深度(occupancy、roofline) | 手写内核优化 |
| DCGM | 集群级 GPU 遥测(温度/功耗/XID) | 集群监控 |
| NCCL_DEBUG + 计时 | 集合通信的时间与算法选择 | 通信优化 |
| PyTorch memory profiler | 显存分配轨迹 | OOM 分析 |
使用阶梯:先 nsys(时间线),后 ncu(单 kernel)——ncu 很重(replay 模式),只对值得优化的 kernel 用。
生产集群的遥测体系
Section titled “生产集群的遥测体系”profiling 是逐实例的,生产监控是全集群的。DCGM + Prometheus 的标准指标:
| 指标 | 告警条件 |
|---|---|
| GPU 利用率 / SM 时钟 | 长期 <80% 或降频(热,见功耗) |
| 显存 ECC 错误 / XID | 任何 XID 致命错误 |
| NVLink/PCIe 错误计数 | 增长趋势 |
| 温度 / 风扇 | 超阈值 |
| step time 的分布 | 毛刺频率(见抖动) |
集群级的"step time 分布"是最有价值的单一指标:它同时捕捉数据饥饿(均值高)、抖动(方差大)、straggler(长尾)、降频(整体抬升)。
一个实用的 profiling 流程
Section titled “一个实用的 profiling 流程”- 看利用率曲线(形态判断问题类别)
- step 时间分解(四段占比,指出方向)
- 逐 kernel top 榜(意外的大头)
- nsys 时间线(重叠与间隙)
- 优化后回归验证(同一套流程对比前后)
每一步都有数字,每一步都是对比——没有数字的优化是玄学,有了数字的优化是工程。
- 利用率曲线的四种形态(平稳/锯齿/周期塌陷/降频)对应四类问题,每天看一眼。
- step 时间四段分解(计算/通信/数据/其他)是最重要的常规分析,直接指出优化方向。
- 逐 kernel 榜单找"意外的大头":小 kernel 密集(launch 开销)、未融合的访存算子。
- nsys 看时间线重叠,ncu 看单 kernel 深度——先 nsys 后 ncu,ncu 只对值得的 kernel 用。
- 集群级 step time 分布是最有价值的单一指标:均值捕捉饥饿,方差捕捉抖动,长尾捕捉 straggler。
- SLO 与容量规划 — 下一章:指标之上的容量
- MFU 与利用率 — 计算效率的量化
- 数据加载性能 — 断粮的诊断
- NCCL 与集合通信算法 — 通信段的优化