第一次接触nvidia-smi是在调试深度学习模型的时候。当时模型训练突然卡住,导师让我"看看GPU状态",我一脸茫然地输入这个命令,屏幕上跳出的信息表格让我瞬间找到了问题——显存被占满了。这个黑底绿字的命令行工具,从此成了我每天打交道最多的伙伴。
nvidia-smi全称NVIDIA System Management Interface,是NVIDIA显卡驱动的标配工具。无论是Linux还是Windows系统,只要安装了官方驱动,这个工具就会自动装好。它的核心功能可以概括为三个方面:实时监控(查看GPU状态)、动态调整(修改运行参数)和数据记录(生成监控报告)。对于深度学习开发者、高性能计算工程师或者普通运维人员来说,掌握nvidia-smi就相当于拥有了GPU系统的听诊器。
与市面上各种图形化监控工具相比,nvidia-smi有几个不可替代的优势:首先是零成本集成,不需要额外安装;其次是低资源消耗,在服务器上运行几乎不占性能;最重要的是脚本友好,所有操作都能通过命令行完成,非常适合自动化运维。我见过很多资深的AI工程师,他们可能不记得PyTorch的API,但nvidia-smi的参数却用得炉火纯青。
在终端直接输入nvidia-smi,你会看到一个类似这样的表格:
bash复制+-----------------------------------------------------------------------------+
| NVIDIA-SMI 470.57.02 Driver Version: 470.57.02 CUDA Version: 11.4 |
|-------------------------------+----------------------+----------------------+
| GPU Name Persistence-M| Bus-Id Disp.A | Volatile Uncorr. ECC |
| Fan Temp Perf Pwr:Usage/Cap| Memory-Usage | GPU-Util Compute M. |
|===============================+======================+======================|
| 0 Tesla V100-SXM2... On | 00000000:00:04.0 Off | 0 |
| N/A 34C P0 24W / 300W | 0MiB / 16160MiB | 0% Default |
+-------------------------------+----------------------+----------------------+
这个表格包含了几十个关键参数,我们先来看最重要的几个:
表格最下方通常会显示进程列表:
code复制+-----------------------------------------------------------------------------+
| Processes: |
| GPU GI CI PID Type Process name GPU Memory |
| ID ID Usage |
|=============================================================================|
| 0 N/A N/A 1623 G /usr/lib/xorg/Xorg 4MiB |
| 0 N/A N/A 2175 G gnome-shell 8MiB |
| 0 N/A N/A 385987 C python3 16024MiB |
+-----------------------------------------------------------------------------+
这里的信息对排查问题特别有用:
kill -9 PID结束异常进程我经常用这个功能找出"显存泄漏"的元凶——有些程序结束后没有释放显存,这里会显示为"僵尸进程"。
基础命令只能看瞬时状态,要监控长时间运行的任务,需要加上-l参数:
bash复制nvidia-smi -l 2 # 每2秒刷新一次
但真正实用的还是记录到文件的功能。这个命令会把监控数据保存为CSV:
bash复制nvidia-smi -l 1 --format=csv --filename=gpu_log.csv \
--query-gpu=timestamp,name,utilization.gpu,memory.used,temperature.gpu
参数解析:
-l 1:每秒记录一次--format=csv:保存为Excel可打开的格式--query-gpu:自定义记录的字段(时间戳、GPU型号、使用率等)我曾经用这个功能发现过一个有趣的现象:模型训练初期GPU使用率会周期性波动,原来是数据加载跟不上计算速度。后来增加了数据预读取线程,训练效率提升了30%。
nvidia-smi支持近百种查询字段,通过这个命令查看全部选项:
bash复制nvidia-smi --help-query-gpu
比如想监控PCIe带宽利用率:
bash复制nvidia-smi -q -d pcie # -q表示详细查询,-d指定查询维度
输出会包含这样的信息:
code复制PCIe
Max Link Speed:8.0 GT/s
Current Link Speed:8.0 GT/s
Max Link Width:16x
Current Link Width:16x
这对诊断数据传输瓶颈特别有帮助。有一次我发现GPU使用率很低但训练速度慢,查到这里显示Link Width只有4x,原来是主板插槽没接好。
服务器上通常有多块GPU,-i参数可以指定某块卡:
bash复制nvidia-smi -i 1 # 只查看第二块GPU(编号从0开始)
要一次性查看所有GPU的概要:
bash复制nvidia-smi -L # 列出所有GPU的UUID和型号
更复杂的场景比如设置计算模式(适合多用户共享服务器):
bash复制nvidia-smi -i 0 -c 1 # 将0号GPU设为独占进程模式
模式说明:
很多人不知道nvidia-smi还能直接调整GPU设置:
bash复制nvidia-smi -pm 1 # 启用持久模式(减少启动延迟)
nvidia-smi -pl 250 # 设置功率上限为250瓦
nvidia-smi -rgc # 重置GPU时钟(解决降频问题)
最实用的要数风扇控制。服务器在机房噪音大没关系,但我的工作站风扇全速转起来像飞机起飞:
bash复制nvidia-smi -i 0 -fan 70 # 设置0号GPU风扇速度为70%
注意:修改功率和时钟等操作需要管理员权限,且可能影响稳定性
原始文章给的脚本有个小问题——超时控制不够优雅。这是我改进后的版本:
bash复制#!/bin/bash
# gpu_monitor.sh [duration_seconds] [output_file]
timeout=$1
log_file=${2:-"gpu_log_$(date +%Y%m%d).csv"}
nvidia-smi -l 1 --format=csv --filename=$log_file \
--query-gpu=timestamp,name,utilization.gpu,memory.used,power.draw &
pid=$!
sleep $timeout
kill -15 $pid # 温和地终止进程
echo "监控数据已保存到 $log_file"
使用方式:
bash复制chmod +x gpu_monitor.sh
./gpu_monitor.sh 3600 training_log.csv # 监控1小时
结合crontab和邮件工具,可以打造GPU监控系统:
bash复制# 在crontab中添加(每小时检查一次)
0 * * * * nvidia-smi --query-gpu=utilization.gpu,temperature.gpu --format=csv | awk -F',' '{if($1>90||$2>80) print "警报: GPU过载!"}' | mail -s "GPU告警" admin@example.com
这个命令会在GPU使用率>90%或温度>80℃时发邮件告警。我曾经靠这个及时发现了一个失控的训练任务,避免了服务器宕机。
有时候nvidia-smi会卡住,通常是因为:
sudo systemctl restart nvidia-*sudo lsof /dev/nvidia*查看占用进程sudo rmmod nvidia_uvm nvidia_drm nvidia_modeset nvidia后重新加载如果发现GPU使用率显示为0%,但实际明显在计算:
nvidia-smi -a | grep "Driver Version"nvidia-smi -q -d utilizationnvtop或dcgm有次我遇到GPU-Util始终显示0%,后来发现是Docker容器内的驱动版本不匹配。升级容器镜像后问题解决。
通过subprocess模块可以轻松集成:
python复制import subprocess
def get_gpu_util():
cmd = "nvidia-smi --query-gpu=utilization.gpu --format=csv,noheader,nounits"
output = subprocess.check_output(cmd.split()).decode('utf-8')
return float(output.strip())
while True:
util = get_gpu_util()
if util > 80:
print(f"警告: GPU使用率 {util}%")
time.sleep(5)
通过nvidia_gpu_exporter可以将监控数据接入Prometheus:
bash复制docker run -d --name nvidia_exporter \
--runtime=nvidia \
-v /run/prometheus:/run/prometheus \
nvidia/gpu-monitoring-tools:2.0
然后在Grafana中就能看到漂亮的GPU监控面板了。