在接触 NVIDIA GPU 工具生态时,很多人都会被一系列概念绕晕:
nvml、nvidia-smi、DCGM、dcgmi、DCGM Exporter......
如果你正在做 GPU 集群、分布式训练或者可观测性相关的工作,这些工具几乎是绕不开的。最近因为在学习 GPU 集群相关知识,同时也在参与 GPU 可观测性系统的开发, 借此机会系统性地梳理了一下 NVIDIA 的这一套工具链,希望能帮助到大家。
在这篇文章中,我将从 DCGM 出发,系统性地回答以下几个问题:
- 这些工具在 GPU 生态中分别扮演什么角色?
- 为什么 NVML 和 NVIDIA-SMI 不足以支撑 GPU 集群管理?
- DCGM 是什么,它解决了哪些核心问题?
- DCGM 的内部结构是怎样的,它是如何工作的?
- 在实际工程中,我们应该如何使用 DCGM 以及相关工具?
没有 DCGM 之前的世界
在理解 DCGM 之前,我们需要先搞清楚一个更基础的概念:什么是 GPU 节点(GPU Node)。
GPU 节点本质上是一台运行 Linux 操作系统的计算实例,它可以是:
- 裸金属服务器(Bare Metal)
- 虚拟机(VM)
- 或者容器宿主机
在这台机器上,安装了 NVIDIA 驱动,因此系统能够识别到一张或多张 GPU 设备。
从这个角度来看,“节点”其实是一个操作系统层面的概念。也就是说,我们说的“节点”本质上就是一台运行着操作系统的机器,而不是某个具体的软件或硬件组件。
理解了 GPU 节点之后,我们就可以引出一个非常重要的基础组件:NVML(NVIDIA Management Library)。
NVML 是 NVIDIA 提供的一个底层管理库,用于访问和管理 GPU 设备的状态与信息。而大家熟悉的命令行工具 nvidia-smi,其实就是基于 NVML 构建的。
NVML 的设计初衷是支持多 GPU(Multi-GPU aware)环境,它可以在单台机器上管理多个 GPU,例如:
- 查询 GPU 利用率
- 查看显存使用情况
- 获取温度、功耗等指标
但 NVML 也有一个明显的局限性:
它提供的是“设备级 API”,而不是“系统级管理能力”。
换句话说,NVML 更像是一套“查询与控制接口”。你可以用它获取每一张 GPU 的状态,但如果你希望对多个 GPU 执行统一的操作,例如批量配置、统一监控、统一管理,就需要在上层额外编写逻辑。
例如,如果你想对一台机器上的 8 张 GPU 同时执行某个操作,使用 NVML 或 nvidia-smi,通常需要逐个设备调用。这意味着:
- 需要编写额外代码来管理 GPU 列表
- 需要自己处理批量操作逻辑
- 缺乏统一的抽象层
DCGM:对 GPU Group 的统一管理
正是在这样的背景下,DCGM(Data Center GPU Manager)应运而生。它在 NVML 之上提供了一层更高层的抽象,其中一个非常关键的概念是:GPU Group(GPU 分组)。
通过 GPU Group,你可以将:
- 一台节点上的全部 GPU
- 或者其中一部分 GPU
组织成一个逻辑上的“组”。
之后,无论是进行配置、状态查询还是健康检查,都可以直接以“组”为单位进行操作,而不需要逐个 GPU 手动处理。
这带来了一个重要变化:
GPU 管理从“单设备操作”,升级为“集合级管理”。
这也是 DCGM 相比 NVML 的核心价值之一。
那么一个很自然的问题是:DCGM 和 NVML 之间到底是什么关系?
从架构上来看,DCGM 包括其核心库 libdcgm.so,本质上是构建在 NVML 之上的。
NVML 提供访问 GPU 状态的底层能力,例如利用率、温度、功耗等。而 DCGM 并没有重新实现这些能力,而是通过调用 NVML 来获取基础数据。
但 DCGM 的价值并不只是对 NVML 的简单封装,它在此基础上引入了一整套更高层机制,包括:
- GPU 分组(GPU Group)
- 指标集合管理(Field Group)
- 周期性采集与缓存(Watch / Cache)
- 健康检查与策略(Health / Policy)
- 多客户端访问模型(HostEngine)
换句话说:
NVML 更像是一个函数库,而 DCGM 则是一个长期运行的管理系统。
如果用一个更直观的类比来理解:
- NVML:每次调用函数,向 GPU 询问当前状态
- DCGM:在后台持续采集和维护 GPU 状态,并向多个组件提供统一的数据视图
这种从“即时查询(pull)”到“持续观测(watch + cache)”的转变,也是 DCGM 能够支撑数据中心级 GPU 管理和可观测性的关键所在。
DCGM 的核心构成
对于 DCGM 的具体功能,这里不逐项展开,感兴趣的读者可以继续查阅 NVIDIA DCGM 的官方文档。这里更值得重点理解的是它的几个核心组件。
从整体架构上看,DCGM 并不是一个单一的库,而是一套由多个组件组成的系统。这些组件共同协作,提供了 GPU 的管理、监控和可观测性能力。
DCGM 生态主要由以下部分组成:
libdcgm.so
这是 DCGM 最底层的动态链接库,也是其核心实现。它主要负责两件事:
- 调用 NVML 获取 GPU 数据
- 提供统一的 API 接口,实现指标采集、错误检测等基础能力
Host Engine(服务层)
Host Engine 也就是我们平常使用的 nv-hostengine。它是基于 libdcgm.so 构建的,也是 DCGM 最关键的组件。
Host Engine 是一个常驻进程(Daemon),主要负责:
- 初始化和管理 DCGM 生命周期
- 统一访问 GPU,避免多线程或多进程访问冲突
- 周期性采集 GPU 指标
- 提供 IPC 接口和 HTTP API 供外部访问
我们可以把 Host Engine 理解为 DCGM 的控制平面加数据平面。
上层应用(Client 层)
因为 Host Engine 是服务层,所以所有上层应用本质上都是 Client。这其中包括:
dcgmi:最常见的命令行工具(DCGM Interface)dcgm-exporter:面向 Kubernetes 场景的指标导出组件- 自定义程序:基于 Host Engine 或
libdcgm.so构建的第三方或自研工具
一般来说,这些上层程序都不会直接调用 libdcgm.so,而是通过 Host Engine 来访问 GPU 数据。
为了更好地理解 NVML、libdcgm.so、nv-hostengine 与 dcgmi 的关系,可以参考下面这张依赖关系图:
在工程中如何使用 DCGM
对于普通用户或一般的 GPU Cluster 运维团队来说,我们其实只需要使用到 NV Host Engine 这一层就够了。
在大部分场景下,比如一个 Kubernetes GPU 集群,我们通常会在每一台 GPU 节点上安装完整的 DCGM 套件。这其中往往包括:
libdcgm.sonv-hostenginedcgmi- NVML 相关运行时能力
通常的使用方式如下:
- 在每一台 GPU 节点上启动一个
nv-hostengine - 让所有 DCGM Client 连接到这个 Host Engine
- 由 Host Engine 在后台周期性采样 GPU 状态
这种部署关系可以简化成下面的结构:
然后,我们可以通过不同形式的 Client 获取数据或执行操作,例如:
- 以 DaemonSet 的形式在 K8s 集群每个节点上部署
dcgm-exporter,把指标暴露给 Prometheus - 直接登录节点,使用
dcgmi访问 Host Engine - 基于
nv-hostengine作为服务端,开发自定义 Client
其中,dcgmi 既可以读取状态,也可以基于组来统一做配置和管理。
为什么多个 Client 最好共享同一个 Host Engine
这里有一个非常容易被忽略但又很重要的工程细节。
如果你正在使用 dcgm-exporter,它默认可能会在内部启用 embedded Host Engine。这意味着,如果你已经在节点级别单独启动了一个 Host Engine,那么系统里实际上可能同时存在两个不同的数据源。
这会带来一个典型问题:你通过 dcgmi 看到的 GPU 状态,与 dcgm-exporter 导出的指标状态不一致。
出现这种现象的根本原因并不复杂:它们连接的不是同一个 Host Engine,因此采样时间、缓存内容与采集路径都可能不同,最终导致监控结果不一致。
所以根据 NVIDIA 官方建议,在存在多个 Client 的场景下,更合理的做法通常是:
- 在节点级别部署一个统一的
nv-hostengine - 所有 Client,包括
dcgmi、dcgm-exporter和自定义程序,都连接到这个实例
这样做的价值在于:
- 消除因采样时间不同导致的数据偏差
- 减少重复采集带来的资源浪费
- 提供更统一、更可预测的数据视图
总结:什么时候该用 DCGM
在单机环境下,使用 nvidia-smi 或 NVML 已经可以满足很多场景需求。但当系统规模扩大到 GPU 集群,尤其是在 Kubernetes 等云原生环境中时,问题会立刻复杂起来:
- 如何统一管理多张 GPU?
- 如何保证多组件访问 GPU 数据的一致性?
- 如何高效地进行指标采集与监控?
DCGM 正是为了解决这些问题而设计的。
它通过 Host Engine 提供统一的服务入口,通过 GPU Group、Field Group 与 Watch 机制优化指标采集,通过 Exporter 打通云原生可观测体系,使 GPU 从“单机资源”演变为“可管理的集群资源”。
在实际工程中,一个典型的最佳实践通常是:
- 在每个 GPU 节点上部署一个 Host Engine
- 所有 Client 统一连接该 Host Engine
- 通过 Prometheus + Grafana 构建完整的 GPU 可观测体系
这样既能保证数据一致性,也能最大程度发挥 DCGM 的能力。