1.1 为什么需要开源GPU监控:AI训练、推理、渲染与HPC场景
我最早接触GPU监控,是训练任务排队排到崩溃。nvidia-smi 看一眼,卡是满的,显存也快爆了。可谁在用、用了多久、是不是僵尸进程,全靠猜。有一回一张 A100 的显存被一个 python 进程占着,任务早停了,进程没退。半夜被同事电话叫醒,那种感觉真不想再来一次。开源GPU监控给我最大的帮助,就是让这些事变得有迹可循。
推理场景又是另一套脾气。流量忽高忽低,GPU利用率像过山车。白天忙时卡不够,夜里闲时卡空转。渲染农场和HPC集群更看重稳定性,一个任务跑几十小时,温度、功耗抖一下,进度就可能受影响。开源方案能把利用率、显存、温度、功耗这些指标持续抓出来,设好告警发到群里。我不用半夜一台台登录机器去翻。
开源GPU监控的好处很实在:能改、能扩、数据在自己手里。商业工具功能全,预算和授权流程有时让人头疼。开源社区迭代快,遇到怪问题搜 issue、看源码,通常能找到线索。我们团队把 DCGM Exporter、Prometheus、Grafana 串起来,成本可控,心里踏实。这套组合不算完美,胜在灵活,能跟着业务一起长。
1.2 开源GPU监控的核心对象:利用率、显存、温度、功耗、带宽与进程
我盯的核心指标有利用率、显存、温度、功耗、带宽和进程。利用率不是一个数字。SM 利用率、显存控制器利用率、编解码器利用率要分开看。做训练时 SM 忙,做视频转码时编解码器忙。只盯 GPU-Util,很容易把瓶颈判错。我吃过这个亏,以为卡没干活,实际是显存带宽先满了。
显存要看 used、free、reserved。温度看 GPU 核心和显存结温。功耗看瞬时值和平均值。带宽看 mem copy util,这个指标容易被忽略。进程信息能定位到容器、用户和 PID。多卡多进程场景,MIG 会把一张卡切碎,监控粒度也要跟着变。一张卡上的几个实例,指标混在一起看,排查会很痛苦。
这些指标拼成一套指标体系。采集频率、标签维度、聚合规则都要提前想。频率太高存储压力大,太低会漏掉尖峰。我习惯按场景定指标集,训练和推理分开。指标不在多,够用、能告警、能追查就行。有些团队一上来抓几百个指标,真出问题时反而不知道看哪个。
1.3 总分式内容框架:总览、工具推荐、NVIDIA显存监控、落地实践与趋势
这份内容我按总分式来组织。开头把开源 GPU 监控的需求和指标体系讲清楚。后面聊工具推荐与选型对比。再深入 NVIDIA 显存利用率监控方法。落地实践和最佳实践单独展开。末尾看选型建议和未来趋势。你如果赶时间,可以按自己关心的部分跳着读。
工具推荐会覆盖采集层、存储告警层、可视化层、云原生和集群方案。选型维度包括指标覆盖、部署成本、扩展性、社区活跃度。NVIDIA 显存监控会从 nvidia-smi 讲到 NVML、DCGM Exporter,还会区分显存利用率和显存带宽利用率。多卡、多进程、MIG 场景也会提。这些内容偏实战,我会尽量把踩过的坑写出来。
落地实践部分有架构设计、部署示例、告警规则、性能成本优化、常见问题排查。趋势聊 eBPF、GPU 直通、MIG、多厂商异构监控。我写这些内容,想帮你在开源 GPU 监控选型和落地时少走弯路。你可以按自己的场景挑着看,不必从头读到尾。
2.1 采集层工具:NVIDIA DCGM、NVML、nvidia-smi、gpustat、nvitop与nvtop
采集层是整条监控链路的源头。我在不同场合用过这六样工具,感受差别挺大。nvidia-smi 属于必备款,装完驱动就有,敲一条命令看快照。做临时排查够用,想拿历史数据或做程序化采集就力不从心。它输出的格式改过好几回,脚本解析容易踩坑。我早期拿它写定时任务,机器一多就乱套。
NVML 是这些工具的老底子。nvidia-smi、gpustat、DCGM 底层都在调它。C 和 Python 都能用,PyNVML 封装了一层。想精确抓显存、温度、功耗,NVML 最直接。代码量不小,指标含义得对着文档啃。我拿 PyNVML 写过小采集器,跑几十张卡还行,上千张卡就得考虑封装和并发。DCGM 是 NVIDIA 给数据中心场景做的。指标全、有 hostengine、支持健康检查和字段分组。DCGM 的采集开销比裸 NVML 低,适合规模化部署。DCGM Exporter 是它在 Prometheus 生态里的出口,后面会细聊。
gpustat、nvitop、nvtop 属于社区里的顺手工具。gpustat 偏轻量,一条命令看多卡概况,输出干净,适合日常瞄一眼。nvitop 是这几年的新欢,交互式界面,能看进程、用户、显存、利用率,还支持按用户过滤。nvtop 更像 top 的 GPU 版,实时刷新,曲线和条形图都有。我调试单机训练任务时最常开 nvitop,多卡排序、进程树一目了然。这三个工具做个人排查很舒服,做集群集中采集不行,它们不提供长期存储和远程汇聚。
选采集工具得看场景。单机开发用 nvidia-smi 加 nvitop 组合就挺舒服。想写程序采集用 PyNVML 或 DCGM API。生产集群建议 DCGM 打底,DCGM Exporter 暴露指标,社区工具留给运维人员手工排查。别指望一个工具包打天下,混着用才是常态。
2.2 存储与告警层:Prometheus、VictoriaMetrics与Alertmanager
存储层决定了你能查多久、查多细。Prometheus 是这圈子里默认的答案。拉模式、PromQL、生态齐全,跟 DCGM Exporter 天生一对。我大部分项目都用它。Prometheus 的短板在长期存储和高基数指标。GPU 指标标签多,card、modelName、UUID、container、pod 全算上,series 数量涨得比想象中快。默认本地 TSDB 撑不了多久,得配远程存储或降采样。VictoriaMetrics 是我用过的替代方案。兼容 PromQL,写性能和压缩率比 Prometheus 好不少。单机版部署简单,集群版能横向扩。大规模 GPU 集群我倾向用 VM 做长期存储,Prometheus 做短周期查询,两边分工。
Alertmanager 负责告警路由。它本身不产生告警,只处理 Prometheus 发来的 alert。分组、抑制、静默、路由这几件事设计得挺细。我见过团队直接把告警写进 Grafana,简单场景没问题,复杂规则还是 Alertmanager 稳。显存泄漏、温度越界、利用率长时间为零,这些规则可以按 severity 分级。P0 打电话,P1 发钉钉,P2 进工单。路由配得好,半夜不会被无关告警吵醒。我踩过的坑是分组没设好,一张卡掉线触发几百条告警,手机直接炸了。
这三件套的关系是 Prometheus 抓、VM 存、Alertmanager 发。规模小的时候一个 Prometheus 包办也行。上千张 GPU 的集群,拆开部署更稳妥。选型时想清楚数据保留多久、查询频率多高、告警规则多复杂,答案会自然浮现。
2.3 可视化与仪表盘:Grafana、Netdata与Zabbix开源方案
Grafana 是可视化层的事实标准。接 Prometheus、VM、Elasticsearch 都顺。GPU 仪表盘社区里有现成模板,NVIDIA DCGM 官方也提供。我一般会把总览、单卡详情、进程列表、温度功耗趋势拆成几个面板。变量用起来方便,选 cluster、选 node、选 GPU,一张图就能切。告警也能写在 Grafana 里,简单阈值够用。复杂逻辑还是走 Alertmanager 更省心。Grafana 的短板是它只管展示,采集和存储得靠别人。
Netdata 走的是另一条路。装完就有图,开箱即用,实时性很好。单机场景下几乎零配置,CPU、内存、GPU 指标自动发现。它也有 GPU 插件,能读 nvidia-smi。做单机性能调优时我挺喜欢开 Netdata 看实时曲线。大规模集群它不如 Prometheus 体系灵活,中心化和告警能力偏弱。Zabbix 是传统运维的老朋友。Agent 模式采集,模板丰富,告警和资产管理成熟。GPU 监控靠自定义脚本或模板,社区有一些 nvidia-smi 方案。Zabbix 适合已经用它管服务器和网络的团队,加 GPU 监控不用另起炉灶。指标粒度不如 DCGM 细,实时性和 PromQL 的灵活度也差一截。
可视化的选型跟团队习惯强相关。习惯云原生就用 Grafana。想要开箱即用看单机,Netdata 很舒服。老牌运维团队用 Zabbix,学习成本最低。我一般推荐 Grafana 打底,Netdata 当补充。Zabbix 在有历史包袱的环境里继续用也没问题。
2.4 云原生与集群方案:NVIDIA GPU Operator、DCGM Exporter与Kubernetes GPU监控
Kubernetes 上管 GPU,跟裸机是两回事。我最早在 K8s 里跑训练任务,节点上装驱动、装 device plugin、装监控,全靠手工,版本一升级就乱。NVIDIA GPU Operator 把这堆东西打包了。驱动、container toolkit、device plugin、DCGM Exporter、GFD 全用它管。装完一个 Helm chart,节点自动就绪。Operator 会跟着驱动版本走,升级路径清晰。我们集群换卡、换驱动,靠它省了很多事。Operator 的代价是组件多,排查问题要懂它的分层。
DCGM Exporter 是 K8s GPU 监控的核心。它把 DCGM 采到的指标转成 Prometheus 格式,通过 ServiceMonitor 被 Prometheus 抓走。指标里带 pod、namespace、container 标签,跟 K8s 元数据对上。做多租户 GPU 配额和成本分摊靠这套标签。Exporter 支持指标裁剪,只要关心的字段可以配。默认全开指标很多,集群规模大了要调。我见过忘了配裁剪,Prometheus 内存飙升,查半天才发现是 GPU 指标基数太大。
K8s 里还有几个细节。MIG 模式下要开 MIG 监控选项,指标粒度按实例走。共享 GPU 场景要配 time-slicing 或 MPS,Exporter 得能识别。GPU 直通和 vGPU 的监控方式又不一样。这些场景下建议先小规模验证,指标齐不齐、标签对不对,跑通了再上生产。K8s GPU 监控这条线,Operator 加 Exporter 加 Prometheus 加 Grafana 是目前最顺的组合,社区文档也最全。
2.5 开源GPU监控工具推荐对比维度:指标覆盖、部署成本、扩展性与社区活跃度
选工具我习惯从四个维度打分。指标覆盖是第一维。DCGM 覆盖最全,利用率、显存、温度、功耗、带宽、ECC、健康状态都有。nvidia-smi 覆盖基础指标。gpustat 和 nvitop 偏使用侧,指标少但够看。Prometheus 和 Grafana 本身不产生 GPU 指标,只做传输和展示。指标覆盖要看采集端,展示端看灵活性。
部署成本是第二维。nvidia-smi 零成本。DCGM Exporter 要装 hostengine 或容器,配 Prometheus 抓取。GPU Operator 成本最高,换来的是自动化。VictoriaMetrics 单机部署比 Prometheus 集群省事。Netdata 单机安装几乎无痛。团队人少就选成本低的,人多且集群大就选自动化程度高的。我见过小队上来就搞 Operator 加集群版 VM,维护量把自己拖垮。
扩展性排第三。Prometheus 联邦、VM 集群、Grafana 多数据源都支持横向扩。Zabbix 大集群要靠 proxy 分层。DCGM 的 hostengine 模式有单点风险,得多实例或嵌入式模式。社区活跃度是第四维。DCGM、Prometheus、Grafana 背后是 NVIDIA 和 CNCF,更新快、issue 响应及时。nvitop 这类个人项目活跃度看作者精力,胜在轻。选型时去 GitHub 看看最近提交和 issue 回复速度,比看文档实在。
这四个维度没有绝对权重,看场景。单机开发重部署成本和顺手程度。训练集群重指标覆盖和扩展性。混合云重社区活跃度和跨平台支持。我的习惯是先列需求清单,再拿这四个维度给候选工具打分,分数接近就选自己熟的。工具是给人用的,用得顺比参数漂亮更重要。
3.1 命令行快速查看:nvidia-smi显存占用与利用率查询
我最开始接触显存监控,就是从 nvidia-smi 开始的。装完驱动,终端敲一下,一排表格就出来了。显存那一栏分两块,一块是 Used / Total,一块是每个进程的占用明细。想快速知道显存有没有爆,有没有进程偷偷吃掉几个 G,这一条命令基本就够。我调试训练任务卡在 OOM 的时候,第一时间就是开着 nvidia-smi 反复刷。默认刷新是快照,加个 -l 1 就能每秒刷一次,配合 watch 也行。
命令的用法其实不复杂。nvidia-smi 不带参数看总览。nvidia-smi --query-gpu=memory.used,memory.total,utilization.gpu --format=csv 能直接出 CSV,适合脚本里解析。nvidia-smi --query-compute-apps=pid,process_name,used_memory --format=csv 看进程级别占用。这两个查询组合起来,临时排查一张卡的显存分布够了。我见过有人写 shell 脚本每隔几秒采一次,写进 csv 做简单趋势图。这种方式在单机场景下确实能用。
不过 nvidia-smi 有几个坑。它的显存数值是估算的,跟 cudaMalloc 的真实占用有差距。进程列表里有些进程名显示不完整,PID 复用的情况下对不上人。多卡机器上默认只显示一张卡的概况,要看全部得加 -i 参数循环。还有一点,nvidia-smi 采一次的延迟不低,卡多的时候一条命令要等好几秒。做临时查看很好,做高频采集要谨慎。
我个人的用法是,nvidia-smi 留在终端里当仪表盘用,需要程序化采集的时候换 NVML 或者 DCGM。它有它的位置,别让它扛太多。
3.2 编程接口采集:NVML、PyNVML与DCGM API获取显存指标
想要自己写采集程序,NVML 是绕不开的。它是 NVIDIA 提供的底层 C 库,nvidia-smi 和 DCGM 都在调它。显存相关的方法有 nvmlDeviceGetMemoryInfo,返回 total、free、used 三个值。还有 nvmlDeviceGetComputeRunningProcesses,拿每个进程的显存占用。我拿 PyNVML 写过一个小采集器,跑几十张卡问题不大。代码不长,初始化、遍历设备、取指标、写日志,一两百行搞定。
PyNVML 有个细节要注意。它的句柄和设备顺序跟 nvidia-smi 不一定一致。CUDA_VISIBLE_DEVICES 设了之后,PyNVML 看到的是全部物理卡还是过滤后的卡,跟调用方式有关。我踩过一次坑,训练脚本里设了可见卡,监控程序按 NVML 索引拿数据,对不上号,排查了半天。稳妥的做法是用 UUID 做关联键,而不是靠索引。NVML 还分 MIG 模式和非 MIG 模式,MIG 下要拿实例句柄去取子设备的显存,用错了拿的是整卡数值。
DCGM API 是另一条路。它在 NVML 之上做了一层封装,字段分组、健康检查、批量采集都有。DCGM 的 dcgmFieldGet 系列接口能取显存相关的字段,比如 DCGM_FI_DEV_MEM_COPY_UTIL、DCGM_FI_DEV_FB_USED、DCGM_FI_DEV_FB_FREE。用 C 或 Go 调 DCGM 比较常见。Python 侧有 dcgm 的绑定,但不如 PyNVML 顺手。我们集群里做集中采集用的是 DCGM,单机小工具用 PyNVML,两套各管一摊。
编程接口的优点是灵活,想采什么采什么,想怎么聚合怎么聚合。代价是自己要处理错误、重试、并发、资源释放。我写采集器的时候最怕句柄没释放,跑几天进程就卡住了。生产环境里推荐直接用 DCGM 或者 DCGM Exporter,自己造轮子容易出细节问题。
3.3 Prometheus指标暴露:DCGM Exporter显存相关指标解读
DCGM Exporter 是把显存指标送进 Prometheus 的常用通道。它暴露的指标名都带 DCGM_FI_DEV_ 前缀,显存相关的核心有几个。DCGM_FI_DEV_FB_USED 是已用显存,单位 MiB。DCGM_FI_DEV_FB_FREE 是空闲显存。DCGM_FI_DEV_FB_TOTAL 是总显存,有的版本不带这个指标,得自己算。DCGM_FI_DEV_MEM_COPY_UTIL 是显存拷贝利用率,单位百分比,这个指标容易跟显存占用混。DCGM_FI_DEV_MEMORY_TEMP 是显存温度,做散热和降频排查用得上。
这些指标上打的标签也很重要。默认会带 gpu、UUID、modelName、Hostname。K8s 环境下还会带 pod、namespace、container。做多卡聚合的时候按 Hostname 或 gpu 分组,做租户成本分摊按 namespace 分组。我发现很多人不看标签直接写 PromQL,结果多卡机器的数值被加总了,明明是单卡问题看成整机问题。写查询前先用 Grafana 的 explore 看一眼标签结构,能省不少事。
Exporter 有个指标裁剪的配置。默认全量导出字段很多,集群规模一上来 series 数量会爆。显存监控其实只需要那几个 FB 和 MEM 字段加上利用率。裁剪的做法是在启动参数里配 --collectors,或者在 DCGM 的 configmap 里指定 field group。我们生产集群裁剪后 series 数量降了一个数量级,Prometheus 内存压力小了很多。裁剪要小心,别把告警依赖的字段裁掉了。
还有一个坑是采集间隔。DCGM Exporter 默认 30 秒采一次,Prometheus 抓取间隔也设 30 秒的时候节奏刚好。把抓取间隔调到 5 秒,Exporter 内部还是 30 秒才更新一次数据,Prometheus 拿到的还是旧值,只是重复存了六遍。查指标更新频率的时候看 Exporter 的日志,别只看 Prometheus 的 scrape 配置。
3.4 显存利用率与显存带宽利用率的区别:used、free、reserved与mem copy util
显存"利用率"这个词在 GPU 监控里经常被混用,实际指两样东西。一样是显存占用率,就是 used 除以 total,反映的是有多少显存被分配出去了。另一样是显存带宽利用率,也就是 mem copy util,反映的是显存读写通道有多忙。这两者完全是两回事。我见过显存占用 90% 的卡,带宽利用率只有 5%,任务在等 CPU 喂数据。也见过显存占用 20% 的卡,带宽跑到 95%,那是小 batch 高频率的推理场景。
used、free 这两个值从 nvidia-smi 和 NVML 都能拿到。reserved 是另一层概念。深度学习框架里,PyTorch 的 caching allocator 会从 CUDA 申请一大块显存留在池子里。nvidia-smi 看到的 used 是 CUDA 层的占用,包含 reserved 的部分。框架内部看到的 allocated 内存可能比 used 小很多。我调 OOM 的时候经常遇到 nvidia-smi 显示还有空闲显存,PyTorch 却报 out of memory,原因就在 reserved 和 allocated 之间的碎片。排查这类问题要用 torch.cuda.memory_summary(),光看 nvidia-smi 不够。
mem copy util 这个指标反映的是显存控制器的工作负载。它高说明数据在显存和 SM 之间搬得频繁,或者在做大量 host-to-device、device-to-device 拷贝。带宽利用率长期打满,任务性能基本到顶了,加卡或者改数据流水线才是出路。带宽利用率极低而 GPU 利用率也低,多半是数据加载瓶颈。带宽低而 GPU 利用率高,说明计算密集,显存访问不频繁。
把这两个指标放一起看,能大致判断任务卡在哪。占用高、带宽低,显存泄漏或者 batch 太大。占用低、带宽高,数据传输密集,可能在做大量拷贝或者推理请求太碎。占用高、带宽也高,正常的高负载训练。我习惯在 Grafana 里把这两个曲线画在同一张图上,看一眼就知道当前任务的状态。
3.5 多卡、多进程与MIG场景下的显存监控要点
多卡场景最麻烦的是对齐。一台机器八张卡,每张卡的显存占用、进程、利用率都要单独看。PromQL 里用 by (gpu) 分组,Grafana 里用 $gpu 变量切换。我一般做一个总览面板看八张卡的 used 曲线,再做一个单卡详情面板看进程。八卡机器上经常出现一张卡爆显存其他卡空着的情况,数据并行没配好或者某个 rank 的 batch 偏大。这种问题靠总览图一眼就能发现。
多进程的情况更复杂。一张卡上跑多个进程,PyTorch 的 torchrun、推理服务的多 worker、共享 GPU 的 time-slicing 场景都会遇到。nvidia-smi 的进程列表能看每个 PID 的占用,但 PID 到具体服务、具体用户的映射要自己建。DCGM Exporter 在 K8s 环境下靠 container 和 pod 标签能自动对上。裸机环境里要看采集程序有没有把 PID 和进程信息一起采进去。我做过一个映射表,PID 到用户到任务名,查起来方便很多。
MIG 是这几年的重点。把一张 A100 或 H100 切成多个实例,每个实例有独立的显存和计算单元。MIG 下的显存监控不能按整卡看,要按 MIG 实例看。DCGM 有专门的 MIG 字段,DCGM_FI_DEV_FB_USED 在 MIG 模式下会返回每个实例的数值。nvidia-smi 加 -mig 参数能看到实例划分。监控系统要能识别 MIG 实例的 UUID,跟整卡的 UUID 区分开。我们集群切了 MIG 之后,一开始 Grafana 面板的显存加总对不上整卡,后来发现是把实例和整卡混在一起算了。
MIG 的监控粒度细,成本也高。实例数量多的时候 series 数量翻几倍,Prometheus 压力上来。裁剪指标和调整采集间隔这两招在 MIG 环境下更要重视。我一般建议 MIG 场景单独建一套 Prometheus 或者用 VictoriaMetrics 扛基数,别跟整卡监控混在一个实例里。
4.1 监控架构设计:采集、传输、存储、告警与展示闭环
GPU 监控的架构,拆开看就五块。采集、传输、存储、告警、展示。少一块链路就是断的。我在团队里搭第一套 GPU 监控的时候,直接上 DCGM Exporter + Prometheus + Grafana,中间跳过了告警环节,结果显存泄漏跑了三天才被人肉发现。后来补了 Alertmanager,才算把闭环合上。
采集这块,选择其实就几个。每台机器上跑一个 DCGM Exporter,或者用 Node Exporter 配合自定义采集脚本,再或者在大规模集群里用 DCGM 的代理模式做中心采集。我测过三种。Exporter 模式部署简单,Pod 或者 DaemonSet 搞定,指标自动暴露 /metrics。中心采集模式适合超大规模,一台汇聚节点拉所有卡的指标,能省很多 sidecar 资源,代价是汇聚节点的网络和并发压力大。
传输基本走 Prometheus 的拉模型。Exporter 暴露 HTTP 端点,Prometheus 按时抓。集群规模过千卡的时候,单台 Prometheus 撑不住,要上联邦或者多实例分片。存储层选择看数据量和保留周期。Prometheus 自带 TSDB 适合中短期,长期存储推到 Thanos、VictoriaMetrics 或者远端对象存储。告警依赖 Alertmanager,规则写在 Prometheus 侧,告警路由和收敛在 Alertmanager 侧。展示就是 Grafana。五个环节能串起来,用起来才顺手。
4.2 部署示例:DCGM Exporter + Prometheus + Grafana监控NVIDIA GPU
部署这套东西,我从一个最小示例讲起。裸机环境用 docker compose 就能跑起来。三样东西。dcgm-exporter 容器,prometheus 容器,grafana 容器。dcgm-exporter 需要挂载 NVIDIA 驱动和运行时,compose 里配好 runtime: nvidia 和 NVIDIA_VISIBLE_DEVICES。暴露 9400 端口。Prometheus 的 scrape 配置里加一个 job,target 指向 exporter 的 9400,间隔 30 秒。Grafana 加一个 Prometheus 数据源,导入 DCGM 官方提供的 dashboard 模板。
Kubernetes 环境更顺。NVIDIA GPU Operator 会把 driver、container toolkit、device plugin、DCGM Exporter 全部装好,不用手动折腾。Exporter 以 DaemonSet 形式跑在每个 GPU 节点上,Prometheus 用 ServiceMonitor 或者 PodMonitor 自动发现。Grafana 用 sidecar 模式自动加载 dashboard configmap,改完配置不用重启。我们生产用的就是这个组合。
部署的时候有几个细节要注意。Exporter 的版本要跟驱动匹配,太老的 exporter 认不了新卡的字段。Prometheus 的抓取间隔和 exporter 的采集间隔要一致,不然存的是重复数据。Grafana 的 dashboard 变量设计,要能按主机、GPU 索引、MIG 实例切换。我一般是做三层面板,集群总览、单机视图、单卡详情。点一下钻一层,排查效率高很多。
4.3 告警规则设计:显存泄漏、利用率异常、温度与功耗阈值
告警规则这门手艺,写太松天天被烦,写太紧漏掉真问题。GPU 监控里最常配的几类规则,我一样一样说。显存泄漏是最值得做的。表现是某张卡的 FB_USED 持续单调上升,任务没换但占用一直涨。规则可以用 predict_linear 做趋势预测,比如预测 4 小时后显存会用完就提前告警。比阈值告警有用得多,阈值只能等真爆了才响。
利用率异常也常配。GPU 利用率长时间低于 5%,说明卡空着但还在占资源,可能是任务卡死或者调度出问题。反过来利用率 100% 持续特别久,可能任务死循环或者散热跟不上触发了降频。我一般设一个窗口期,比如 15 分钟平均值低于某条线或者高于某条线才告警,避免瞬时抖动触发。
温度和功耗阈值属于硬约束。GPU 温度超过 85°C 要关注,超过 90°C 基本会降频,超过 95°C 有停卡风险。功耗看的是有没有超出设计功耗,长时间跑在功耗墙上说明散热或者供电可能有问题。这两类告警我建议挂到不同的告警等级,温度走 critical,利用率走 warning。Alertmanager 的路由按等级分流,温度告警直接推电话,利用率走企业微信或者 lark,处理优先级不一样。
告警规则写完之后先静默观察一周。看看误报率多高,规则是不是切得太细,有没有重复告警。调完再放到生产。这个环节很多人跳过,直接上生产,结果被告警风暴淹没。
4.4 性能与成本优化:采集频率、指标裁剪与长期存储
GPU 监控跑起来不难,跑久了才知道成本在哪里。最大的成本是 Prometheus 的 series 数量和存储。一张卡导出几十个指标,一千张卡就是几万个 series。加上多进程和 MIG,能到十几万。单台 Prometheus 内存几个 G,磁盘一天几十 G,一年下来存储成本不低。
第一招是裁剪指标。DCGM Exporter 支持 field group 配置,只采你真正用的字段。显存监控的核心就是 FB_USED、FB_FREE、GPU_UTIL、MEM_COPY_UTIL、TEMP、POWER 这几个,其他字段按需开。我们裁剪过一轮,series 数量降了九成。第二招是调采集频率。训练集群 15 到 30 秒够用,推理集群可以放宽到 60 秒,排查问题时临时调低频率采样。第三招是分等级存储。高频数据保留 15 天,降采样到 1 分钟或者 5 分钟的数据保留一年。
长期存储的选择看团队规模。中小规模用 VictoriaMetrics 单机版,压缩比和查询性能都不错,运维复杂度低。大规模用 Thanos 或者 Cortex,对象存储做后端,成本能压下来。低成本场景也可以把关键指标定期导出到 ClickHouse 或者对象存储,做离线分析。
采样频率这件事有个反直觉的点。不是采得越密越好。高频采样带来的是更多的存储成本和更大的 Prometheus 内存压力,真正有用的信息大多在分钟级窗口里。我见过团队把频率设成 1 秒一次,结果 Prometheus 天天 OOM,实际排查还是看的 5 分钟曲线。
4.5 常见问题排查:指标缺失、权限、驱动兼容与容器环境
指标缺失是遇到最多的。Exporter 起来了,Prometheus 就是抓不到。这种问题我一般按链路查。先 curl exporter 的 /metrics 端点,有数据说明采集和暴露没问题,往下查网络和抓取配置。没数据说明 exporter 本身有问题,看日志里有没有驱动报错。K8s 环境还要看 ServiceMonitor 的 label selector 有没有对上。
权限问题在容器环境里很典型。Exporter 需要访问 /dev/nvidia* 设备和驱动库。容器没挂对设备、没加 SYS_ADMIN 能力、或者 runc 配置不对,就会报权限错误。我用过的坑还包括 SELinux 拦住了设备访问,日志里只有一句 permission denied,看不到具体原因。排查的时候 strace 或者 dmesg 能帮上忙。
驱动兼容是另一个维度。Exporter 的版本、DCGM 的版本、NVIDIA 驱动的版本三者要对得上。驱动升级之后 exporter 可能报字段不支持,或者某些 NVML 方法直接失败。我习惯把这三个版本记录在监控系统自己的元数据里,出问题的时候一眼能查。容器化的环境还有个特殊点,容器里的驱动版本是宿主机挂进来的,镜像里的版本号仅供参考。
MIG 和 vGPU 环境下问题更隐蔽。MIG 实例的指标要用实例 UUID 关联,用整卡 UUID 会拿不到数据。vGPU 的指标暴露方式跟物理卡不一样,有些字段直接没有。这类环境我建议先在小范围验证,跑通了再铺开。出问题的时候优先看 exporter 和 DCGM 的官方兼容性矩阵,能省很多摸索时间。
5.1 不同场景选型:单机开发、训练集群、推理服务与混合云
单机开发这个场景,选型不用复杂。一台工作站插两张卡,跑实验的时候想知道显存还剩多少、利用率稳不稳。nvitop 开一个终端窗口就够了。它的界面比 nvidia-smi 舒服,进程、显存、利用率、温度一屏全显示,支持键盘交互刷新。我日常本地调试基本就用这个,偶尔配个 gpustat 写进脚本里做记录。真要长期看曲线,本地跑一个 DCGM Exporter + Prometheus + Grafana 三件套,docker compose 十分钟能起。
训练集群是另一个量级。几十台到几千台机器,每台八张卡,监控的核心诉求变成了批量视图和任务关联。这个场景我推荐 DCGM Exporter + Prometheus + Grafana + Alertmanager 的标准组合,走 Kubernetes 部署就用 GPU Operator 统一管理。指标采集要按任务维度打标签,把 pod name、namespace、job id 映射到 GPU 指标上,方便定位是哪个训练任务把卡占满了。集群规模上去之后,Prometheus 做联邦或者直接上 Thanos,别单机硬撑。
推理服务的监控重点跟训练不一样。推理对延迟敏感,GPU 利用率的波动模式也不同。训练是长时间高占用,推理是脉冲式,请求来了利用率冲上去,请求走了掉下来。这种场景监控要看得更细,采集频率得压到 10 秒甚至 5 秒级别,不然曲线全是平的看不出问题。Kubernetes 里的推理服务还要监控冷启动和扩缩容行为,GPU 从空闲到满载的过渡时间直接关系到服务质量。
混合云场景最麻烦。本地机房有卡,公有云上也有,不同厂商、不同卡型、不同驱动版本混在一起。我建议在这种环境里做两层抽象。底层用 DCGM Exporter 统一采集,不同云厂商的 GPU 实例都跑同一个 exporter 版本。上层用统一的标签体系,比如 cloud_provider、gpu_model、region 打标,Grafana 里按这些标签切面板。跨云的 Prometheus 用 remote write 推到中心存储,避免查询的时候满世界拉数据。
5.2 开源与商业方案边界:何时自建、何时补充商业能力
开源这套东西覆盖了 GPU 监控八成以上的需求。DCGM 提供指标,Prometheus 做存储和查询,Grafana 做展示,Alertmanager 做告警。四样都是开源的,拼起来能跑。我见过很多团队从零搭到生产,没花一分钱软件费用。这个事实很重要,说明 GPU 监控不是一个必须买商业产品才能解决的问题。
什么时候该考虑商业方案。我的判断标准是三个。团队规模小、没有专职运维、GPU 节点数不超过一百台,开源方案完全够。团队有 SRE 但人手紧张、集群规模上到几百上千卡、需要跨地域统一管理,这时候商业方案的价值开始显现。商业产品省的是运维成本和集成成本,不是功能成本。它们能做的事开源都能做,只是自己做要花时间和人力。
还有一个维度是合规和审计。金融、医疗、政府这些行业,监控数据的留存、访问控制、审计日志有硬性要求。开源方案要自己搭 RBAC、自己保证数据完整性、自己做审计链路。商业方案通常直接提供这些能力,省心。我认识一个做自动驾驶的团队,训练集群几千张卡,最后选了商业方案,原因就是他们的合规团队不愿意为开源方案的审计能力背书。
混合策略其实是大多数团队的真实选择。核心监控链路用开源搭,数据采集、存储、告警都自己控制。在特定环节补充商业能力,比如长期存储用云厂商的对象存储服务而不是自建 Thanos,告警通道用 PagerDuty 而不是自己维护 Alertmanager 的高可用。这种组合既保住了灵活性和成本优势,又在关键环节获得了商业产品带来的稳定性。
5.3 未来趋势:eBPF、GPU直通、MIG与多厂商异构监控
eBPF 在 GPU 监控里的角色越来越清晰。传统的 GPU 指标采集走 NVML 或者 DCGM API,拿到的是卡级别的宏观数据。eBPF 能从内核层面追踪 GPU 相关的系统调用和驱动交互,看到更细的粒度。比如哪个进程在什么时间发起了显存分配、CUDA kernel 的调度延迟、GPU 内存的页错误行为。这些信息 NVML 拿不到。现在已经有团队在用 eBPF 做 GPU 进程级别的行为分析,配合传统的卡级指标做关联。
GPU 直通和虚拟化场景给监控带来了新问题。虚拟机里跑 GPU 直通,宿主机看不到卡内部的详细信息,只能看到直通设备的宏观状态。vGPU 和 SR-IOV 方案下,一张物理卡切给多个虚拟机,监控要能区分哪些指标是物理卡层面的、哪些是虚拟实例层面的。这个领域目前的开源工具支持还不够好,DCGM 有 vGPU 支持但覆盖不全,很多字段拿不到。我判断未来一两年会有专门针对虚拟化 GPU 监控的开源项目出现。
MIG 的普及让监控粒度变细了。一张 A100 切成七个 MIG 实例,每个实例有独立的显存和计算单元,监控要能按实例维度采集和展示。现在 DCGM Exporter 已经支持 MIG 指标,但 Prometheus 的标签设计和 Grafana 的面板配置要根据 MIG 的拓扑来调整。MIG 实例的动态创建和销毁也是监控难点,实例 UUID 会变,需要有一个映射机制把实例和任务关联起来。
多厂商异构是最大的趋势。NVIDIA 之外,AMD 的 ROCm 生态在成长,Intel 的 GPU 产品线在扩展,国产 GPU 厂商也在发力。开源监控工具要能跨厂商采集指标,这件事现在还没有标准答案。DCGM 只管 NVIDIA,ROCm 有自己的 profiler 和 API,各家都有自己的指标格式。OpenTelemetry 的 GPU 语义约定还在早期,但我看好这个方向。未来两三年内,能统一采集不同厂商 GPU 指标的开源层会出现,可能是 Prometheus exporter 的形式,也可能是 OTel collector 的插件。
5.4 总结:构建可持续演进的开源GPU监控体系
搭一套 GPU 监控不难,让它跑三年五年不烂掉才难。我见过太多团队一开始搭得很漂亮,半年后没人维护,告警天天响没人看,dashboard 打不开因为数据源挂了。可持续演进的核心不是技术选型多先进,是体系设计的时候有没有为变化留余地。
我的经验是三层分离。采集层用标准协议暴露指标,不绑定具体存储。存储层用统一的时序数据库,不绑定具体展示工具。展示层用配置化的 dashboard,不把业务逻辑写死。这样任何一层想换,替换成本都只在那一个层面,不会牵一发动全身。我现在的团队就是按这个原则搭的,采集层换过两次 exporter,存储层从单机 Prometheus 迁到 VictoriaMetrics,展示层从自建 Grafana 迁到云托管 Grafana,每次迁移都只动了一层。
指标命名和标签规范要早定。这个是很多团队忽略的事。GPU 监控的指标数量多,标签维度也多。如果一开始不定义好命名规则和标签体系,半年后指标列表会变成一团乱麻,查一个指标要找半天,写告警规则的时候不知道用哪个标签。我习惯在项目初期就写一份指标字典,每个指标的含义、单位、采集频率、标签维度都列清楚。新加的指标必须先更新字典再上线。
最后一点心得。开源 GPU 监控的价值不在于省了多少钱,在于你对自己的基础设施有了完整的可见性和控制力。这份控制力在排查疑难问题的时候特别值钱。生产环境出 GPU 相关的问题,第一反应永远是先看监控曲线。曲线能告诉你的信息,比日志和 strace 加起来都多。把监控体系建好,等于给自己和团队配了一双眼睛,这双眼睛能看见的东西,决定了你能解决的问题范围。