Skip to content

DCGM 指标与 GPU 健康检查:从 diag 四级到 Prometheus 遥测 ​

一句话:把 GPU 交付上线,不能靠"跑个训练没报错"就算过——DCGM 提供的是三件不同的事:一个能在 2.5 秒内回答"这台机器现在能不能接活"的主动诊断、一套不打扰作业的被动健康监控、以及一个把 GPU 指标变成 Prometheus 时间序列的 exporter。三者分工不清,最容易出现"监控图很好看、故障照样炸"的局面。

一、DCGM 是什么,以及它明确不做什么 ​

DCGM(Data Center GPU Manager)是一个轻量的用户态库与 agent,定位是给 GPU 主机提供统一的管理平面:监控 GPU 行为、配置管理、策略监督、健康与诊断、记账与进程统计,以及 NVSwitch 的配置与监控。它有两种运行形态:

  • Standalone:由 nv-hostengine 守护进程常驻,dcgmi 命令作为客户端连上去;
  • Embedded:被第三方 agent 嵌进自己的进程里(dcgm-exporter 的容器模式就是这种)。

这个 host engine 不是"命令分发器",它持有实体命名空间、field watch、保留的采样、可复用的 group、模块状态与作业记录。所以它是长期驻留的:多个客户端可以共享同一份采集流。

一个版本相关的硬事实:v2.x 起 DCGM 不再内置 Fabric Manager。NVSwitch 系统必须另外安装 FM,DCGM 只观测 fabric,不负责配置它,也不管 FM 的生命周期。

官方同时明确划了边界——DCGM 诊断不做这四件事:

  1. 不提供全面硬件诊断;
  2. 不主动修复问题;
  3. 不替代厂商现场诊断工具(field diagnostics);
  4. 不参与 RMA 流程。

这四条决定了它在运维流程里的位置:它是筛子,不是判官。它说"这台机器有问题",下一步是隔离并送修;它说"通过",不等于这张卡永远没问题。

二、实体与 field:先把 ID 从运行时读出来 ​

DCGM 的世界由 entity(实体)和 field(字段)组成。实体不只是 GPU,还可能是 MIG 实例、NVSwitch、NVLink 端口、NVIDIA CPU 及其核心、ConnectX 网卡。

bash
# 盘点本机 host engine 当前管理的实体
$ dcgmi discovery --list

# 用 GPU UUID / PCI bus ID 与资产、调度系统对齐
$ dcgmi discovery --info a --gpuid 0

# MIG 机器上读父子层级
$ dcgmi discovery --compute-hierarchy

必须记住的一条:实体 ID 是当前这个 host engine 的本地编号,不是可以跨机器复制的稳定标识。写进工单、写进 CMDB 的应该是 GPU UUID 或 PCI bus ID。

field 是 DCGM 对硬件的观测项,分库存值、gauge、counter、事件四类。watch 告诉 host engine"哪些实体的哪些 field、以多长间隔采集、保留多少历史":

bash
$ dcgmi dmon --list                 # 列出当前 DCGM 版本支持的 field 目录
$ dcgmi dmon --field-id 150,155 --count 5   # 温度(150) 与功耗(155),采 5 次

dmon 建的是临时 watch,默认对所有 GPU 打印已保留的采样。读一个采样通常不会重新查询硬件,时间戳是 DCGM 采集它的时刻——这点在做跨指标关联时很重要。

另外:field 在目录里存在,不代表每张卡都支持。输出里的 N/A 可能是"不支持"、"当前不可用"、"没权限"或"还没采到",不要一律当硬件故障。

三、diag 四个级别:时间预算是选级的唯一依据 ​

dcgmi diag 的四个运行级别是留给不同场景的,官方把耗时写得很清楚(Hopper 平台实测):

级别名称时间预算
-r 1Quick / System Validation< 2.5 秒
-r 2Medium / Extended System Validation4 卡 < 2.5 分钟;8 卡 < 10.5 分钟
-r 3Long / System HW Diagnostics4 卡 < 10 分钟;8 卡 < 35 分钟
-r 4Extended4 卡 < 45 分钟;8 卡 < 2.25 小时

高层级包含低层级的全部测试。插件与级别的对应关系(同一张官方表):

插件r1r2r3r4
software✓✓✓✓
pcie(含 NVLink)✓✓✓
memory✓✓✓
memory_bandwidth✓✓✓
diagnostic✓✓
targeted_stress✓✓
targeted_power✓✓
nvbandwidth✓✓
nccl_tests✓✓
memtest✓
pulse(Input EDPp)✓

这张表直接决定选级策略:

  • r1 是门禁。2.5 秒跑完,适合放在作业启动的 prologue 里——每次分配前跑一遍,成本可以忽略;
  • r2 是失败作业的收尾检查。作业莫名挂了、卡已空闲,用它把内存与 PCIe/NVLink 扫一遍;
  • r3 是管理员定位。真正做加压力测试(诊断、定向压力、定向功耗、NVLink 带宽、NCCL),要停机或至少把卡从调度里摘出来;
  • r4 是归修前的长跑。memtest 与 pulse 只在 r4 出现,45 分钟到 2 小时以上的代价意味着它属于维护窗口,不属于日常。

四、参数与判定阈值:默认值是"能跑",不是"该用" ​

bash
# 指定实体跑某级
$ dcgmi diag -r 2 --entity-id gpu:0 --json

# 只跑指定插件(逗号分隔)
$ dcgmi diag -r "pcie,diagnostic"

# 覆盖单个插件参数
$ dcgmi diag -r 3 -p diagnostic.test_duration=300.0

几个高频参数与它们的默认值:

参数默认说明
diagnostic.test_duration180.0秒;加压力测试的持续时长
diagnostic.matrix_dim2048.0(Blackwell 起 8192.0)GEMM 起始维度
diagnostic.gflops_tolerance_pcnt0.0低于全体均值多少比例判失败;0 表示关闭比较
pcie.max_pcie_replays80.0单卡在整个插件时长内允许的 PCIe 重放上限
pcie.max_latency100000微秒;超时判失败
pcie.min_pci_width1.016x 要写成 16.0
memory.minimum_allocation_percentage75.0显存测试分配比例

三条实操结论:

  1. gflops_tolerance_pcnt 是横向比较,不是绝对性能承诺。它比较的是"这台机器上各卡之间的均值",所以一台 8 卡机器里有一张卡明显蔫了才抓得到;单卡机器上这个参数没有输入意义;
  2. min_pci_width 不设等于不检查。默认 1.0 意味着 x16 的卡降速到 x1 也能通过。要抓"插错槽位/降速"这类问题,必须显式写 16.0;
  3. temperature_max 的行为已变。老版本用它卡测试期间的温度上限;较新版本(DCGM 4.6)改用 GPU 自报的最高工作温度做公共错误监控,这个参数只为兼容保留——不要再用它设站点自己的低温阈值,该在外部监控里做。

另外,--fail-early 值得单独提:开启后 targeted_power、targeted_stress、diagnostic 会在测试运行期间每 5 秒检查一次失败条件(--check-interval 可调 1–300 秒),而不是等测试跑完才判定。跑 r3 这种 10 分钟起的测试,早失败能省下大量墙钟时间。

五、退出码与日志:自动化必须读对这两样 ​

dcgmi 的退出码是 dcgmReturn_t 的无符号 8 位补码表示(负值转成正数),信号则是 128 + 信号值。常用的几个:

值符号含义
0DCGM_ST_OK成功
255DCGM_ST_BADPARAM参数错误(注意:-1 也映射成 255)
226DCGM_ST_NVVS_ERROR诊断成功执行,但报告了错误(这是最需要区分的一档)
217DCGM_ST_DIAG_ALREADY_RUNNING已有一个诊断在跑
237DCGM_ST_RESET_REQUIREDGPU 需要复位
227DCGM_ST_REQUIRES_ROOThost engine 非 root 运行,做不了这个操作

226 是最容易被误判的:它不代表"命令没执行",而代表"执行完了,结果里判了失败"。只看退出码会漏掉具体是哪张卡哪个插件挂了,所以自动化脚本应该同时读 -j 的 JSON 输出,把 test 名、entity 结果、错误码一起落库。

日志默认在 /var/log/nvidia-dcgm/nvvs.log。要在事后复盘,这个文件和 JSON 结果比一次退出码有价值得多——官方也要求升级问题时保留完整命令、目标选择、完整输出、debug 日志与插件统计数据。

六、多节点诊断:门槛比单机高得多 ​

dcgmi mndiag 用 MPI 在所有节点上同时跑一个叫 mnubergemm 的 GEMM 压力应用,验证跨机互联、内存与算力。它能抓的东西单机诊断抓不到(跨节点带宽不达标、NCCL 初始化失败)。

bash
# 在一台节点上发起,hostList 里包含它自己
$ dcgmi mndiag --hostList "node1;node2;node3"

# 自定义时长(默认 3600 秒)
$ dcgmi mndiag --hostList "node1;node2" -p "mnubergemm.time_to_run=600"

# JSON 输出
$ dcgmi mndiag --hostList "node1;node2" -j

但它有一串硬前提,缺一个就跑不起来:

  • DCGM 4.3.0 起才支持,且当前只支持 GB200 NVL / GB300 NVL;
  • 所有节点装 OpenMPI,全部节点同一驱动版本;
  • 节点间 passwordless SSH,且私钥必须以不加密形式落盘——ssh-agent 不管用,因为 SSH 会话是由 nv-hostengine 进程拉起的,继承不到你的 shell 环境;
  • 每个节点都要有 nv-hostengine 在跑;
  • 多节点 NVLink 系统必须先把 IMEX channel 配好,否则 NCCL 初始化直接失败,报 unhandled system error;
  • 运行超时限制是默认 1 小时 + 60 秒。

最后两条最值得记:mndiag 失败很多时候不是硬件问题,而是 IMEX 没配或 SSH 密钥加密了。

七、被动健康监控:不打扰作业的那一层 ​

主动诊断要占卡,日常不可能一直跑。日常靠的是 health watch——它只评估普通运行期间采集的遥测,不施加任何负载:

bash
$ dcgmi group --create fabric-adapters --add cx:0
$ dcgmi health --set x --group <group-id>
$ dcgmi health --check --group <group-id>

几点语义要注意:

  • dcgmi health --set a --group s 里的 s 是内置的"全部 NVSwitch"组,a 是包含 NVSwitch 检查在内的全量 watch 选择器;
  • watch 需要时间积累采样,刚开启就 check 往往还没数据;
  • 诊断与健康监控是两套证据,不能互替:一台机器可能被动监控零告警,主动诊断却失败;也可能健康里留着历史告警,而后续主动测试全过。两者一起看,才是这台机器当前状态的完整叙述。

八、dcgm-exporter:把指标接进 Prometheus ​

dcgm-exporter 是 Go 写的指标导出器,把 GPU 指标以 /metrics 暴露给 Prometheus 类系统:

bash
$ docker run -d --rm --gpus all --net host --cap-add SYS_ADMIN \
    nvcr.io/nvidia/k8s/dcgm-exporter:<tag>-ubuntu20.04 \
    -f /etc/dcgm-exporter/dcp-metrics-included.csv

$ curl localhost:9400/metrics

默认行为与常见改动:

项默认说明
监听地址:9400-a 可改
采集间隔30000 ms-c 可改;30 秒对排障偏粗
采集项清单/etc/dcgm-exporter/default-counters.csv-f 指定自定义 CSV
连接已有 host engine未启用-r localhost:5555(DGX 这类已自带 DCGM 的机器必须用)
设备选择f(MIG 关=全部 GPU,MIG 开=全部实例)-d g:0,1 / -d i:0,2-4

版本兼容性有一条硬约束:exporter 镜像里带的是自己的 libdcgm.so,它要和宿主 nv-hostengine 用私有协议通信,所以exporter 基于的 DCGM 版本必须 ≥ 宿主 DCGM 版本。用 nv-hostengine --version 对照镜像 tag 即可。

关键指标及其运维含义:

指标含义什么时候看
DCGM_FI_DEV_GPU_TEMP / DCGM_FI_DEV_MEMORY_TEMP核心温度 / 显存温度散热异常、降频排查
DCGM_FI_DEV_POWER_USAGE板卡功耗与 TDP 对照,判断是否被功耗墙限制
DCGM_FI_DEV_SM_CLOCKSM 时钟与标称对照,抓降频
DCGM_FI_DEV_PCIE_REPLAY_COUNTERPCIe 重放计数链路质量问题的最早信号之一
DCGM_FI_DEV_XID_ERRORS最近一次 Xid 值与内核日志关联,是 GPU 级故障的入口
DCGM_FI_DEV_FB_FREE / FB_USED显存空闲/已用泄漏、碎片、调度是否真的隔离
DCGM_FI_DEV_NVLINK_BANDWIDTH_TOTALNVLink 带宽总量P2P 路径是否在工作
DCGM_FI_PROF_PIPE_TENSOR_ACTIVETensor 管线活跃度(0~1)判断算力是否真被喂饱
DCGM_FI_PROF_DRAM_ACTIVE显存带宽活跃度判断瓶颈在算力还是访存
DCGM_FI_PROF_PCIE_TX_BYTES / RX_BYTESPCIe 收发字节数据加载路径是否成为瓶颈

两张 0~1 的 PROF 指标(Tensor 活跃、DRAM 活跃)是判断"GPU 利用率虚高"的关键:利用率 95% 但 Tensor 活跃度只有 0.3,说明显式算力没跑满、瓶颈在数据或同步上。

MIG 场景下,指标会同时带 GPU_I_PROFILE / GPU_I_ID 标签,粒度落到 GPU 实例级;此时不能按 GPU 聚合,否则会把多个实例的使用叠在一张图上。

还有一条安全边界:host engine 的 TCP 协议不带认证、授权与加密,所以 5555 端口只能放在受信管理网内,别暴露到业务网。

九、三层栈怎么配合:一张决策表 ​

场景用哪一层具体动作
作业分配前,2 秒内判断能否接活主动诊断 r1dcgmi diag -r 1 --entity-id gpu:N
作业挂了,卡已空闲主动诊断 r2-r 2 --json,把失败实体与错误码落库
怀疑某子系统(PCIe / 内存 / 通信)指定插件-r "pcie,diagnostic",配合 --iterations
日常运行期被动 health watchhealth --set + 定时 --check
集群级基准与验收多节点诊断mndiag --hostList,先确认 IMEX 与 SSH
长期趋势、容量、告警exporter + Prometheus30 秒以下间隔,重点抓 PCIe replay、Xid、降频
送修前取证r3/r4 + JSON + 日志保留命令、输出、nvvs.log、插件统计

上线验收清单 ​

  1. dcgmi discovery --list 的实体数量与物理卡数一致,MIG 机器上父子层级正确;
  2. dcgmi diag -r 1 全卡通过且耗时在 3 秒内,已接入 prologue 或交付流水线;
  3. dcgmi diag -r 2 -j 在至少一台样机上跑通,JSON 能被脚本解析出 test/entity/错误码;
  4. 关键插件参数按站点策略显式设定(尤其 pcie.min_pci_width=16.0),不是全用默认;
  5. dcgmi health --set a 已开启,--check 的输出有告警分级;
  6. dcgm-exporter 版本 ≥ 宿主 DCGM 版本,-r 指向宿主 5555,:9400/metrics 可抓;
  7. Prometheus 侧对 DCGM_FI_DEV_PCIE_REPLAY_COUNTER、DCGM_FI_DEV_XID_ERRORS、DCGM_FI_PROF_PIPE_TENSOR_ACTIVE 建了告警/看板;
  8. nvvs.log 有轮转策略,别在需要取证时发现日志被覆盖。

收口三句 ​

  • 三层职责不能混:diag 是主动取证(要停机或摘卡)、health 是被动观察(不影响作业)、exporter 是长期时间序列——用其中一个去替代另一个,必然留下盲区;
  • 默认值是"能跑",不是"该用":min_pci_width=1.0、gflops_tolerance_pcnt=0.0 这类默认等于把检查关掉,站点必须显式定策略;
  • 退出码 226 与 JSON 必须一起读:诊断跑完但判失败,是最容易被流水线当成"执行成功"放过的一档。

延伸阅读 ​

AI-HPC 智算超算专家 · Contact: openaihpc@gmail.com