随着AI模型规模的爆炸式增长,GPU资源成为了AI基础设施中最昂贵的组成部分。对于共享的AI训练平台,缺乏精细化的GPU使用率和成本监控机制,会导致资源滥用和难以实现合理的项目/用户级别的费用分摊(Chargeback)。
本文将深入探讨如何利用NVIDIA DCGM Exporter、Prometheus和Grafana构建一个实时的GPU成本监控系统,从而实现对GPU训练资源的精细化计费。
Contents
1. 架构概览
我们的核心架构是一个标准的监控栈:
- NVIDIA DCGM Exporter (数据采集层): 部署在每个GPU节点上,负责收集GPU的各项指标(如利用率、温度、显存使用)。
- Prometheus (存储与聚合层): 周期性地抓取DCGM Exporter的Metrics。
- Grafana (展示与计费层): 通过PromQL查询Prometheus中的数据,并应用成本公式进行实时可视化和计费计算。
2. 部署 DCGM Exporter
DCGM Exporter是官方推荐的NVIDIA GPU指标导出工具。它需要访问底层的NVIDIA驱动和DCGM库。
在目标GPU节点上,通过Docker部署DCGM Exporter(确保已安装NVIDIA Container Toolkit):
1
2
3
4
5
6
7
8
9 # 运行 DCGM Exporter
docker run -d --rm \
--gpus all \
--net=host \
--name dcgm-exporter \
nvidia/dcgm-exporter:latest
# 验证 metrics 是否可用 (默认端口 9400)
curl http://localhost:9400/metrics | grep dcgm_gpu_utilization
如果是在Kubernetes环境中,推荐使用DaemonSet部署,并使用
1 | hostNetwork: true |
或配置适当的服务暴露。
3. 配置 Prometheus 抓取任务
将GPU节点(或DCGM Exporter的暴露地址)添加到Prometheus的抓取配置中。为了计费,我们必须确保每个指标都带有清晰的实例(
1 | instance |
,即节点IP)和集群(
1 | cluster |
)标签。
1
2
3
4
5
6
7
8 # prometheus.yml 配置示例
scrape_configs:
- job_name: 'ai-infra-gpu-metrics'
# 如果是多节点,可以使用 service discovery 或 static_configs
static_configs:
- targets: ['<gpu_node_ip_1>:9400', '<gpu_node_ip_2>:9400']
labels:
cluster: 'training-a'
重启 Prometheus 使配置生效。
4. Grafana 实现精细化成本核算 (PromQL)
这是实现计费的核心步骤。精细化计费不仅需要知道GPU是否被占用(100%),还需要知道其实际利用率。
假设我们定义了以下费率标准:
* 单张满载(100%利用率)GPU的小时成本: 5.00 USD/小时。
* 关键指标:
1 | dcgm_gpu_utilization |
(GPU核利用率,范围 0-100)。
* 计费目标: 实时计算每个项目/节点的每秒消耗成本。
我们使用PromQL来计算实时的成本流量:
4.1 实时成本消耗率 (USD/秒)
该查询计算当前时刻,基于实际利用率的每秒成本。
1
2
3
4
5
6
7 # 核心公式: (利用率 / 100) * (每小时成本 / 3600)
sum by (instance, gpuNumber) (
dcgm_gpu_utilization
* 5 # $5.00 USD (每满载GPU小时成本)
/ 100 # 归一化利用率 (0-1)
/ 3600 # 转换为每秒成本
)
在 Grafana 中使用 Graph 面板展示这个结果,可以实时监控每个 GPU 的成本消耗速度。将结果按
1 | instance |
或
1 | gpuNumber |
分组,便于查看哪个资源正在产生费用。
4.2 计算周期总账单 (Chargeback)
对于月度或季度计费,我们需要计算特定时间范围内的总消耗。我们通过对实时成本速率进行求和来完成时间积分。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 # 计算过去 30 天的总成本 (假设监控采集间隔为 15s)
# 'rate' 配合 'sum_over_time' 在这里不适用,因为我们已经有了速率公式。
# 正确做法是对成本速率进行积分 (irate/rate 只能用于计数器)
# 使用求和函数对时间序列进行求和,近似积分
sum_over_time(
(
dcgm_gpu_utilization
* 5
/ 100
/ 3600
)[30d:]
)
# 提示: 如果需要更精确的计费,建议使用 'increase' 函数配合一个稳定的计数器,或者将上述瞬时成本函数保存为 Recording Rule,再对该 Rule 进行积分。
# 实践中,更常见的方法是使用第三方工具(如 Thanos/Cortex)进行长时存储,并通过数据分析脚本对历史 Utilization 数据进行离线计算。
4.3 计费与项目标签的关联
在实际的AI基础设施中,GPU的使用者是用户或项目(Project ID),而不是节点IP。要将成本与租户关联起来,需要额外的标签注入机制:
- Kubernetes 平台: 使用 Prometheus Operator 或 Kube State Metrics 抓取 Pod 的标签,并将 Project ID 注入到
1dcgm_gpu_utilization
相同的标签集中。
- VM 平台: 确保启动训练任务时,通过环境变量或配置,将 Project ID 作为额外的标签添加到 DCGM Exporter 的指标中(如果DCGM Exporter支持自定义标签)。
一旦标签注入完成,即可按项目(
1 | project_id |
)聚合成本:
1
2
3
4
5
6
7 # 按项目聚合总成本速率
sum by (project_id) (
dcgm_gpu_utilization
* 5
/ 100
/ 3600
)
通过这种方式,您可以在 Grafana 中构建一个实时仪表板,显示每个项目消耗的 GPU 成本百分比和绝对金额,为资源回收和财务决策提供可靠的数据支持。
汤不热吧