2、显存监控工具:nvidia-smi详解、dcgmi工具使用、pyNVML库编程、自定义监控脚本
做压测的时候,我最怕什么?不是代码报错,而是显存悄悄爆了,程序直接 OOM 挂掉。你想想看,跑了一晚上的压测,早上来一看进程没了,那感觉...嗯,所以监控工具必须玩透。
这一章,我带你把这四个工具吃透。从命令行到编程接口,从基础监控到深度诊断,一条龙搞定。
2.1 nvidia-smi:你每天都在用,但你真的会用吗?
说实话,nvidia-smi 是每个做 GPU 开发的人最先接触的命令。但我见过太多人只会敲个 nvidia-smi 看看显存占用就完事了。其实它的能力远不止这些。
2.1.1 基础用法
先来个最基础的:
# 查看基本信息
nvidia-smi
# 每秒刷新一次,持续监控
nvidia-smi -l 1
# 只看某个 GPU
nvidia-smi -i 0
我个人习惯用 -l 1 配合压测脚本一起跑。开个终端窗口专门跑这个,显存变化一目了然。
2.1.2 进阶参数
这里有几个我压测时必用的参数:
| 参数 | 作用 | 我的使用场景 |
|---|---|---|
--query-gpu |
查询指定字段 | 只抓显存和温度,减少输出干扰 |
--format=csv |
输出 CSV 格式 | 配合脚本做数据采集 |
--loop-ms |
毫秒级刷新 | 需要高精度监控时用 |
举个例子,压测时我只关心显存和功耗:
nvidia-smi --query-gpu=index,memory.used,power.draw --format=csv -l 1
这样输出干净多了,不会一堆进程信息刷屏。
2.1.3 避坑指南
-l 参数时,如果 GPU 数量多,输出会非常慢。有一次我监控 8 卡机器,刷新间隔设了 0.5 秒,结果 nvidia-smi 自己就占了 5% 的 CPU。后来我改成 2 秒刷新一次,问题解决。
2.2 dcgmi:数据中心级别的监控利器
如果你管理的是多卡集群,nvidia-smi 就不够用了。这时候 dcgmi 上场。它是 NVIDIA Data Center GPU Manager 的命令行工具,能监控更细粒度的指标。
2.2.1 安装与启动
# 安装 DCGM
sudo apt-get install datacenter-gpu-manager
# 启动服务
sudo systemctl start nvidia-dcgm
# 查看是否运行正常
dcgmi discovery -l
我第一次用 dcgmi 是在一个 32 卡的大规模压测项目里。nvidia-smi 根本看不过来,dcgmi 的组监控功能帮了大忙。
2.2.2 核心命令
这几个命令我压测时必用:
# 查看所有 GPU 的健康状态
dcgmi health -g 0
# 监控指定组的显存带宽利用率
dcgmi dmon -e 1001,1002,1003 -d 1000
# 查看历史统计
dcgmi stats -g 0
其中 dcgmi dmon 是我最常用的。它能监控到显存带宽利用率、PCIe 吞吐量这些 nvidia-smi 看不到的指标。
| 事件 ID | 指标含义 | 压测中的意义 |
|---|---|---|
| 1001 | GPU 利用率 | 看计算单元是否跑满 |
| 1002 | 显存带宽利用率 | 看是否带宽瓶颈 |
| 1003 | PCIe 读写速率 | 看数据传输是否卡脖子 |
2.3 pyNVML:用 Python 写自己的监控工具
命令行工具虽好,但有时候我们需要更灵活的监控方案。比如压测过程中自动记录显存变化,或者触发告警。这时候 pyNVML 就派上用场了。
2.3.1 安装与初始化
pip install nvidia-ml-py
注意,这个库叫 nvidia-ml-py,不是 pyNVML。我第一次装的时候就搞混了,找了半天。
import pynvml
# 初始化
pynvml.nvmlInit()
# 获取 GPU 数量
device_count = pynvml.nvmlDeviceGetCount()
print(f"检测到 {device_count} 块 GPU")
2.3.2 实战:显存监控脚本
这是我压测时用的一个简化版脚本:
import pynvml
import time
import sys
pynvml.nvmlInit()
def monitor_memory(gpu_id=0, interval=1):
handle = pynvml.nvmlDeviceGetHandleByIndex(gpu_id)
try:
while True:
mem_info = pynvml.nvmlDeviceGetMemoryInfo(handle)
util_info = pynvml.nvmlDeviceGetUtilizationRates(handle)
used_gb = mem_info.used / 1024**3
total_gb = mem_info.total / 1024**3
util_percent = util_info.gpu
print(f"显存: {used_gb:.1f}/{total_gb:.1f} GB | GPU利用率: {util_percent}%")
# 告警逻辑
if used_gb / total_gb > 0.9:
print("⚠️ 显存使用超过 90%,注意!")
time.sleep(interval)
except KeyboardInterrupt:
print("\n监控结束")
pynvml.nvmlShutdown()
if __name__ == "__main__":
monitor_memory()
2.3.3 更多实用 API
pyNVML 能拿到的信息比 nvidia-smi 多得多:
nvmlDeviceGetTemperature()- 获取温度,我用来监控散热是否跟得上nvmlDeviceGetPowerUsage()- 获取功耗,看是否被限频nvmlDeviceGetComputeRunningProcesses()- 获取正在跑的进程,排查谁在占显存
2.4 自定义监控脚本:把一切串起来
工具学了一堆,最终要落地到实际压测中。我一般会写一个综合监控脚本,把 nvidia-smi、dcgmi 和 pyNVML 的优势结合起来。
2.4.1 脚本设计思路
我的脚本长这样:
- 数据采集层:用 pyNVML 采集显存、温度、功耗
- 数据存储层:写入 CSV 文件,方便后续分析
- 告警层:超过阈值时打印警告并记录日志
- 可视化层:实时打印进度条或简单图表
2.4.2 完整示例
import pynvml
import time
import csv
from datetime import datetime
pynvml.nvmlInit()
def comprehensive_monitor(gpu_ids=[0], interval=2, output_file="gpu_monitor.csv"):
handles = [pynvml.nvmlDeviceGetHandleByIndex(i) for i in gpu_ids]
with open(output_file, 'w', newline='') as f:
writer = csv.writer(f)
writer.writerow(["时间", "GPU", "显存使用(GB)", "显存总量(GB)",
"GPU利用率(%)", "温度(°C)", "功耗(W)"])
try:
while True:
timestamp = datetime.now().strftime("%H:%M:%S")
for idx, handle in enumerate(handles):
mem = pynvml.nvmlDeviceGetMemoryInfo(handle)
util = pynvml.nvmlDeviceGetUtilizationRates(handle)
temp = pynvml.nvmlDeviceGetTemperature(handle, 0)
power = pynvml.nvmlDeviceGetPowerUsage(handle) / 1000
used_gb = mem.used / 1024**3
total_gb = mem.total / 1024**3
writer.writerow([timestamp, idx, f"{used_gb:.2f}",
f"{total_gb:.2f}", util.gpu, temp, f"{power:.1f}"])
# 实时告警
if used_gb / total_gb > 0.85:
print(f"[{timestamp}] GPU {idx}: 显存告警!{used_gb:.1f}/{total_gb:.1f} GB")
if temp > 80:
print(f"[{timestamp}] GPU {idx}: 温度告警!{temp}°C")
time.sleep(interval)
except KeyboardInterrupt:
print(f"\n监控数据已保存至 {output_file}")
if __name__ == "__main__":
comprehensive_monitor(gpu_ids=[0, 1, 2, 3])
2.5 本章知识体系
说了这么多,我画了张图帮你理清思路:
说白了,这四个工具各有侧重。nvidia-smi 适合快速查看,dcgmi 适合大规模集群,pyNVML 适合深度定制,自定义脚本则是把前三个的优势整合起来。我建议你从 nvidia-smi 入手,逐步过渡到 pyNVML 编程,最后形成自己的监控体系。
嗯,工具就介绍到这里。下一节我们聊聊压测中的显存分配策略,那才是真正考验功底的地方。