GPU 集群可观测性:DCGM 监控体系与告警设计
说明:本篇为综述/无第一手实验数据,采用公开文档与常见生产实践路线。
实验目标
集群从 8 卡到 512 卡后,故障排查从"人工挨个看 nvidia-smi"变成了"找不到哪张卡在偷懒"。本篇目标是把 GPU 集群的可观测性建成三层闭环:指标采集(DCGM)→ 存储与查询(Prometheus)→ 告警与容量水位。读完后你能回答三个问题:每张卡的带宽、功耗、SM 利用率、温度从哪里统一拿?哪些指标必须设告警而哪些只是噪音?怎么判断"集群还塞得下下一个训练任务"?
代码逐段拆解
第一段:DCGM 指标出口(dcgm-exporter)
# docker-compose 片段:把 DCGM 指标暴露给 Prometheus
services:
dcgm-exporter:
image: nvcr.io/nvidia/k8s-dcgm-exporter:3.3.5
command: ["-f", "/etc/dcgm-exporter/dcp-metrics-included.csv"]
volumes:
- ./dcp-metrics.csv:/etc/dcgm-exporter/dcp-metrics-included.csv
environment:
- DCGM_EXPORTER_COLLECT_INTERVAL=5000 # 5s 采集周期
ports:
- "9400:9400"要点:
-f指定指标白名单 CSV:dcgm-exporter 默认吐全量几百个指标,用 CSV 白名单只保留需要的字段,降低 Prometheus 存储压力。文件每行格式:# HELP 指标名 单位; 类型或指标名, 类型, 帮助, 单位。COLLECT_INTERVAL=5000:GPU 指标默认 10s,训练任务中 5s 足够捕捉功耗/带宽抖动,又不会把 prometheus tsdb 撑爆(每卡每 5s 约 20-30 个序列)。- 端口 9400:标准 exporter 端口,Prometheus 的
scrape_configs按此抓取。
第二段:Prometheus 抓取与核心告警规则
# prometheus.yml 片段
scrape_configs:
- job_name: 'dcgm'
metrics_path: '/metrics'
static_configs:
- targets: ['gpu-node-01:9400', 'gpu-node-02:9400']
labels: { cluster: 'train-prod' }
# 告警规则(关键 4 条)
groups:
- name: gpu
rules:
- alert: GPUMemoryECCErrorRate
expr: rate(dcgm_memory_correctable_errors_total[5m]) > 0.5
for: 5m
labels: { severity: warning }
- alert: GPUClockThrottle
expr: dcgm_clocks_throttle_reasons_active{reason!="GpuIdle"} == 1
for: 10m
labels: { severity: warning }
- alert: GPUHighTemperature
expr: dcgm_temperature_gpu > 90
for: 10m
labels: { severity: warning }
- alert: GPUUtilizationAnomaly
expr: avg(dcgm_sm_utilization) by (instance) < 30
and on(instance) (time() - process_start_time_seconds{job="dcgm"} > 300)
for: 15m
labels: { severity: info }逐条说明:
dcgm_memory_correctable_errors_total:HBM 可纠正 ECC 错误计数器。出现持续增长说明显存颗粒开始劣化,是"即将坏卡"的前兆信号,用rate(...[5m])看速率而不是绝对值。dcgm_clocks_throttle_reasons_active:时钟被降频的原因位掩码(Power/ Thermal / Software / Sync / HwSlowdown 等)。训练中 SM 利用率高但吞吐不涨,十有八九是这里某一位被置 1。过滤掉GpuIdle,否则空载机器全天告警。dcgm_temperature_gpu > 90:H 级卡的节流阈值一般在 95°C 附近,90 预警留出余量。- SM 利用率异常:训练作业中利用率持续低于 30% 且进程已跑 5 分钟以上,说明脚本卡在 I/O 或通信,而不是 GPU 不够快。
原理讲解
DCGM 是什么
DCGM(Data Center GPU Manager)是 NVIDIA 的 GPU 管理库,它把 nvidia-smi 那种"手动看单卡"的能力变成"程序化批量采集":指标分为五类——设备基础(型号/序列号/PCIe 拓扑)、利用率(SM / 显存 / 编码器 / 解码器)、功耗与热(瞬时功耗、温度、散热风扇)、显存与 ECC(已用/总量、可纠正/不可纠正错误)、时钟与节流(当前频率、节流原因位图)。dcgm-exporter 只是它的 Prometheus 适配器。
采集链路与数据模型
GPU (DCGM 库) → dcgm-exporter (每个节点一个, :9400)
→ Prometheus (scrape 5s, 保留 15d)
→ Grafana (看板) + Alertmanager (告警)每个指标带上 instance(节点)、gpu(卡序号)、UUID 等标签,Prometheus 里就能按"节点×卡"做二维下钻:dcgm_sm_utilization{instance="gpu-node-03"} 查看单卡,avg(...) by (cluster) 看集群水位。
容量水位怎么算
集群可观测性的终局是"容量管理":判断一个 64 卡训练任务能不能立刻排进去。做法是把显存总量、SM 总量、带宽总量建成三个水位线:
可用显存 = Σ(dcgm_mem_used < 阈值) 的卡 × 卡容量
排队条件 = 任务峰值显存 ≤ 空闲显存 && 任务带宽需求 ≤ 空闲带宽估算带宽水位最难:没有"空闲带宽"这个现成指标,只能用显存利用率(dcgm_fb_used)和 SM 利用率做代理——高 SM + 高显存利用率说明卡在满负荷训练;低 SM + 高显存利用率说明卡被"塞满但没在算"(如大模型仅加载未推理),这类卡最容易误判为空闲。
实验结果
以一个 16 卡节点为例给出典型指标基线与告警阈值(估算口径,供参考):
| 指标 | 正常基线 | 告警阈值 | 判定含义 |
|---|---|---|---|
| SM 利用率(训练中) | 85%-98% | < 30% 持续 15m | 卡没在算,查 I/O/通信 |
| 显存利用率 | 70%-90% | > 97% | 接近 OOM,查显存泄漏 |
| GPU 温度 | 55-75°C | > 90°C | 液冷/风冷异常 |
| 可纠正 ECC | 偶发 < 0.1/s | rate > 0.5/s | 显存劣化前兆 |
| 功耗 | 训练期贴功耗墙 | 训练期 < 30% 墙 | 卡被限制/降频 |
工程启示
- 告警宁缺毋滥:5 条核心告警(ECC 速率、节流、温度、SM 异常、显存水位)覆盖 90% 故障,不要一上来建 50 条规则制造告警疲劳。
- 可观测性是训练调优的输入:MFU(模型 FLOP 利用率)的分子是算力,分母里"实际 SM 利用率"就来自 DCGM——没有监控,谈 MFU 优化就是空谈。
- 与调度器打通:监控发现的"坏卡"(高 ECC / 持续节流)应能自动标记为
excluded,让 SLURM/K8s 不再往它上面排任务,这是集群健康闭环的最后一环。 - 存储同理:GPU 的 I/O 等待通常体现在 SM 利用率低 + 网络/存储侧忙,所以集群可观测性必须与存储监控(下一篇主题)放在同一张 Grafana 看板里对比。
下一篇预告:本篇建立了"算力侧可观测性",但训练中断恢复的另一半在存储——"Checkpoint 存储与快速恢复:从本地盘到并行文件系统的两级设计"。