Prometheus与Grafana监控LLM:GPU利用率、SM活跃度与NVLink带宽的可视化大屏

Prometheus与Grafana监控LLM:GPU利用率、SM活跃度与NVLink带宽的可视化大屏

大家好!今天我们来探讨如何使用Prometheus和Grafana监控大型语言模型(LLM)的GPU性能,特别是GPU利用率、SM(Streaming Multiprocessor)活跃度和NVLink带宽。通过搭建这样一个可视化大屏,我们可以更好地了解LLM训练和推理过程中的GPU瓶颈,从而优化模型和硬件配置。

1. 监控指标的重要性

在深入技术细节之前,我们先来了解一下这几个指标的重要性:

  • GPU利用率: 衡量GPU计算资源的整体使用情况。高利用率意味着GPU在充分工作,低利用率则可能表明存在瓶颈,例如数据加载缓慢、CPU瓶颈或代码效率低下。

  • SM活跃度: SM是GPU中执行实际计算的核心单元。SM活跃度反映了每个SM在给定时间内实际执行指令的比例。高SM活跃度意味着计算密集型任务在高效运行,而低SM活跃度可能表明存在线程束发散、内存访问瓶颈或指令依赖性等问题。

  • NVLink带宽: NVLink是NVIDIA GPU之间的高速互联技术。在多GPU训练或推理中,GPU之间需要频繁地交换数据。NVLink带宽直接影响数据传输速度,是多GPU性能的关键因素。

2. Prometheus监控数据的来源

Prometheus本身并不直接监控GPU指标。我们需要借助一些exporter来采集GPU数据,并将其转换为Prometheus可以理解的格式。常用的选择包括:

  • NVIDIA DCGM Exporter: NVIDIA Data Center GPU Manager (DCGM) 提供了丰富的GPU监控接口。dcgm-exporter 将这些接口暴露为Prometheus metrics,是监控GPU指标的首选方案。

  • NVIDIA SMI (System Management Interface): nvidia-smi 是一个命令行工具,可以查询GPU的各种信息。我们可以编写脚本定期运行nvidia-smi,并将输出转换为Prometheus metrics。这种方法比较灵活,但需要自己处理数据解析和格式转换。

我们推荐使用 dcgm-exporter,因为它提供了更全面的监控指标,并且易于集成到Prometheus生态系统中。

3. 安装和配置 NVIDIA DCGM Exporter

首先,确保你的系统上安装了NVIDIA驱动程序和DCGM。安装 dcgm-exporter 可以通过多种方式,例如使用Docker:

docker pull nvcr.io/nvidia/k8s/dcgm-exporter:3.1.7-3.1

docker run --rm --net=host --gpus all -v /var/run/dcgm:/var/run/dcgm nvcr.io/nvidia/k8s/dcgm-exporter:3.1.7-3.1

这个命令会拉取并运行 dcgm-exporter Docker镜像。 --net=host 允许exporter访问宿主机的网络, --gpus all 允许exporter访问所有的GPU, -v /var/run/dcgm:/var/run/dcgm 将宿主机的DCGM socket 挂载到容器中。

运行后,dcgm-exporter 默认会在端口 9400 上暴露 Prometheus metrics。你可以通过浏览器访问 http://localhost:9400/metrics 来查看这些metrics。

4. 配置 Prometheus 抓取 GPU Metrics

接下来,我们需要配置Prometheus来抓取 dcgm-exporter 暴露的metrics。修改Prometheus的配置文件 prometheus.yml,添加以下内容:

scrape_configs:
  - job_name: 'gpu'
    static_configs:
      - targets: ['localhost:9400'] # 替换为你的 dcgm-exporter 地址

重启Prometheus服务,使配置生效。

5. 关键 Prometheus Metrics 和 PromQL 查询

现在,Prometheus应该能够抓取到GPU metrics了。以下是一些关键的metrics和PromQL查询,用于监控GPU利用率、SM活跃度和NVLink带宽:

  • GPU利用率:

    • Metric: DCGM_FI_DEV_GPU_UTIL
    • PromQL: DCGM_FI_DEV_GPU_UTIL{gpu="0"} (替换 "0" 为你的GPU ID)
    • 含义:GPU 0 的利用率百分比。
  • SM活跃度:

    • Metric: DCGM_FI_PROF_SM_ACTIVE
    • PromQL: DCGM_FI_PROF_SM_ACTIVE{gpu="0"} (替换 "0" 为你的GPU ID)
    • 含义:GPU 0 的 SM活跃度百分比。需要注意的是,启用 SM 活跃度指标需要开启 DCGM 的 profiling 功能。
  • NVLink带宽 (发送):

    • Metric: DCGM_FI_PROF_NVLINK_TX_BYTES
    • PromQL: rate(DCGM_FI_PROF_NVLINK_TX_BYTES{gpu="0"}[5m]) * 8 (替换 "0" 为你的GPU ID)
    • 含义:GPU 0 在过去 5 分钟内通过 NVLink 发送的平均带宽 (单位: bits/秒)。 rate() 函数用于计算速率, * 8 将字节转换为比特。
  • NVLink带宽 (接收):

    • Metric: DCGM_FI_PROF_NVLINK_RX_BYTES
    • PromQL: rate(DCGM_FI_PROF_NVLINK_RX_BYTES{gpu="0"}[5m]) * 8 (替换 "0" 为你的GPU ID)
    • 含义:GPU 0 在过去 5 分钟内通过 NVLink 接收的平均带宽 (单位: bits/秒)。
  • GPU Memory 使用量 (已使用):

    • Metric: DCGM_FI_DEV_MEM_USED
    • PromQL: DCGM_FI_DEV_MEM_USED{gpu="0"} (替换 "0" 为你的GPU ID)
    • 含义:GPU 0 当前使用的显存大小 (单位: bytes)。
  • GPU Memory 总量:

    • Metric: DCGM_FI_DEV_MEM_TOTAL
    • PromQL: DCGM_FI_DEV_MEM_TOTAL{gpu="0"} (替换 "0" 为你的GPU ID)
    • 含义:GPU 0 的总显存大小 (单位:bytes)。

6. Grafana 大屏设计

现在,我们可以使用Grafana来创建一个可视化大屏,展示这些GPU指标。

  • 数据源配置: 在Grafana中添加Prometheus数据源,指向你的Prometheus服务器。

  • 面板创建: 创建各种类型的面板来展示不同的指标。常用的面板类型包括:

    • Graph: 用于展示时间序列数据,例如GPU利用率、SM活跃度和NVLink带宽的变化趋势。
    • Gauge: 用于展示当前值,例如GPU温度、显存使用量。
    • Stat: 用于展示统计数据,例如最大值、最小值、平均值。
  • 面板配置: 在每个面板中,配置PromQL查询、数据格式、显示选项等。

以下是一些面板配置的示例:

  • GPU 利用率 (Graph):

    • Title: GPU 0 Utilization
    • Query: DCGM_FI_DEV_GPU_UTIL{gpu="0"}
    • Y-axis Format: percent (0-100)
  • SM 活跃度 (Graph):

    • Title: GPU 0 SM Activity
    • Query: DCGM_FI_PROF_SM_ACTIVE{gpu="0"}
    • Y-axis Format: percent (0-100)
  • NVLink 带宽 (发送, Graph):

    • Title: GPU 0 NVLink TX Bandwidth
    • Query: rate(DCGM_FI_PROF_NVLINK_TX_BYTES{gpu="0"}[5m]) * 8
    • Y-axis Format: bytes/s
    • Unit: bits/s
  • GPU 内存使用量 (Gauge):

    • Title: GPU 0 Memory Usage
    • Query: DCGM_FI_DEV_MEM_USED{gpu="0"}
    • Unit: bytes
    • Thresholds: 80% (红色), 90% (黄色) (根据你的GPU内存大小调整阈值)
  • GPU 温度 (Gauge):

    • Title: GPU 0 Temperature
    • Query: DCGM_FI_DEV_GPU_TEMP{gpu="0"}
    • Unit: °C
    • Thresholds: 70°C (黄色), 80°C (红色) (根据你的GPU型号调整阈值)
  • 多GPU监控: 如果你的系统有多个GPU,可以在每个面板中添加多个查询,分别监控每个GPU的指标。例如,要监控GPU 0 和 GPU 1 的利用率,可以使用以下查询:

    • DCGM_FI_DEV_GPU_UTIL{gpu="0"}
    • DCGM_FI_DEV_GPU_UTIL{gpu="1"}

7. 优化建议

通过监控GPU指标,我们可以发现潜在的性能瓶颈,并采取相应的优化措施:

  • GPU利用率低:

    • 数据加载瓶颈: 检查数据加载速度是否足够快。考虑使用更快的存储介质 (例如 SSD, NVMe),优化数据预处理流程,使用数据并行技术。
    • CPU瓶颈: 检查CPU是否成为瓶颈。考虑使用更多的CPU核心,优化CPU代码。
    • 代码效率低下: 检查GPU代码是否高效。考虑使用更优化的算法、减少内存访问、避免线程束发散。
  • SM活跃度低:

    • 线程束发散: 线程束发散会导致部分线程空闲,降低SM活跃度。检查代码是否存在分支语句,尽量减少分支语句的使用,使用共享内存来减少全局内存访问。
    • 内存访问瓶颈: 频繁的全局内存访问会降低SM活跃度。考虑使用共享内存来缓存数据,减少全局内存访问。
    • 指令依赖性: 指令之间的依赖性会导致SM等待,降低SM活跃度。考虑使用指令级并行技术,减少指令之间的依赖性。
  • NVLink带宽瓶颈:

    • 数据传输优化: 减少GPU之间的数据传输量。考虑使用模型并行技术,将模型分割到多个GPU上,减少数据交换。
    • 数据压缩: 压缩数据可以减少传输量,提高NVLink带宽的利用率。

8. 代码示例:Python脚本生成Prometheus Metrics

虽然推荐使用 dcgm-exporter,但为了展示如何从 nvidia-smi 获取数据并转换为 Prometheus metrics,这里提供一个简单的 Python 脚本示例:

import subprocess
import time
import prometheus_client
from prometheus_client import Gauge

# 定义 Prometheus Metrics
gpu_utilization = Gauge('gpu_utilization', 'GPU Utilization Percentage', ['gpu_id'])
gpu_memory_used = Gauge('gpu_memory_used', 'GPU Memory Used (Bytes)', ['gpu_id'])
gpu_memory_total = Gauge('gpu_memory_total', 'GPU Memory Total (Bytes)', ['gpu_id'])

def get_gpu_metrics():
    try:
        # 执行 nvidia-smi 命令
        command = "nvidia-smi --query-gpu=index,utilization.gpu,memory.used,memory.total --format=csv,noheader,nounits"
        process = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE)
        output, error = process.communicate()

        if error:
            print(f"Error executing nvidia-smi: {error.decode()}")
            return

        lines = output.decode().strip().split('n')
        for line in lines:
            try:
                gpu_id, utilization, memory_used, memory_total = line.split(',')
                gpu_id = gpu_id.strip()
                utilization = float(utilization.strip())
                memory_used = int(memory_used.strip()) * 1024 * 1024 # Convert MB to Bytes
                memory_total = int(memory_total.strip()) * 1024 * 1024 # Convert MB to Bytes

                # 设置 Prometheus Metrics 的值
                gpu_utilization.labels(gpu_id=gpu_id).set(utilization)
                gpu_memory_used.labels(gpu_id=gpu_id).set(memory_used)
                gpu_memory_total.labels(gpu_id=gpu_id).set(memory_total)

            except ValueError as e:
                print(f"Error parsing nvidia-smi output: {e}")

    except Exception as e:
        print(f"An error occurred: {e}")

if __name__ == '__main__':
    # 启动 Prometheus HTTP 服务器
    prometheus_client.start_http_server(8000)
    print("Prometheus metrics server started on port 8000")

    while True:
        get_gpu_metrics()
        time.sleep(5)  # 每 5 秒更新一次 metrics

这个脚本会定期执行 nvidia-smi 命令,解析输出,并将GPU利用率和内存使用量转换为Prometheus metrics。你可以通过访问 http://localhost:8000/metrics 来查看这些metrics。

然后,你需要修改Prometheus的配置文件来抓取这些metrics:

scrape_configs:
  - job_name: 'custom_gpu'
    static_configs:
      - targets: ['localhost:8000']

9. 表格:常用Prometheus Metrics和PromQL查询总结

指标名称 Metric PromQL 示例 描述 单位
GPU 利用率 DCGM_FI_DEV_GPU_UTIL DCGM_FI_DEV_GPU_UTIL{gpu="0"} GPU 的利用率百分比 百分比
SM 活跃度 DCGM_FI_PROF_SM_ACTIVE DCGM_FI_PROF_SM_ACTIVE{gpu="0"} SM 的活跃度百分比 百分比
NVLink 带宽 (发送) DCGM_FI_PROF_NVLINK_TX_BYTES rate(DCGM_FI_PROF_NVLINK_TX_BYTES{gpu="0"}[5m]) * 8 通过 NVLink 发送的平均带宽 bits/秒
NVLink 带宽 (接收) DCGM_FI_PROF_NVLINK_RX_BYTES rate(DCGM_FI_PROF_NVLINK_RX_BYTES{gpu="0"}[5m]) * 8 通过 NVLink 接收的平均带宽 bits/秒
GPU 内存使用量 (已使用) DCGM_FI_DEV_MEM_USED DCGM_FI_DEV_MEM_USED{gpu="0"} 当前使用的显存大小 bytes
GPU 内存总量 DCGM_FI_DEV_MEM_TOTAL DCGM_FI_DEV_MEM_TOTAL{gpu="0"} 总显存大小 bytes
GPU 温度 DCGM_FI_DEV_GPU_TEMP DCGM_FI_DEV_GPU_TEMP{gpu="0"} GPU 温度 °C
PCIe 发送带宽 (bytes) DCGM_FI_PROF_PCIE_TX_BYTES rate(DCGM_FI_PROF_PCIE_TX_BYTES{gpu="0"}[5m]) * 8 PCIe 发送带宽 bits/秒
PCIe 接收带宽 (bytes) DCGM_FI_PROF_PCIE_RX_BYTES rate(DCGM_FI_PROF_PCIE_RX_BYTES{gpu="0"}[5m]) * 8 PCIe 接收带宽 bits/秒

10. 持续优化和监控带来的益处

通过搭建Prometheus和Grafana监控LLM的GPU性能大屏,我们可以实时了解GPU的使用情况,及时发现潜在的性能瓶颈,并通过优化模型和硬件配置,提升LLM的训练和推理效率。

总结几句:

Prometheus和Grafana是强大的监控工具,结合DCGM Exporter可以有效监控LLM的GPU性能;通过监控GPU利用率、SM活跃度和NVLink带宽等关键指标,我们可以及时发现性能瓶颈并进行优化;持续的监控和优化可以提升LLM的训练和推理效率。

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注