文章总结: 本文提供了一套系统化的nvidia-smi实战排查流程,用于诊断GPU利用率与显存占用异常。文章强调不能仅凭单次截图下结论,需理解利用率与显存是不同指标,并建议优先使用GPUUUID进行长期关联。核心步骤包括记录驱动版本、定位占用显存的计算进程、在容器和Kubernetes环境中映射进程归属、检查温度功耗与限频原因、以及判断OOM与显存碎片。文章还提供了处理异常任务和检查ECC、PCIe与NVLink状态的具体命令。关键结论是,排查需结合多种工具(如dmon、pmon)和日志(如Xid)进行交叉验证,避免误判。可操作建议包括在结束进程前确认业务影响,并优先使用SIGTERM信号。 综合评分: 88 文章分类: 实战经验,安全运营,解决方案
nvidia-smi 实战:排查 GPU 利用率与显存占用异常
点击关注 👉 点击关注 👉
马哥Linux运维
2026年7月19日 18:00 广东
在小说阅读器读本章
去阅读
nvidia-smi 实战:排查 GPU 利用率与显存占用异常
GPU 利用率突然 100%、显存被占满、进程列表为空但设备持续繁忙、某张卡温度和功耗异常,这些现象不能只靠一张 nvidia-smi 截图下结论。nvidia-smi 展示的是驱动和 NVML 在采样时刻提供的状态:利用率是时间窗口内引擎忙碌比例,显存是设备内存分配,进程表则受权限、容器命名空间、MIG、驱动状态和采样时刻影响。三者不一致并不自动等于“幽灵进程”。
本文适用于 Linux 与 NVIDIA 数据中心 GPU。
一、先记录驱动、GPU 和工具版本
排障报告首先要说明驱动版本、CUDA Driver API 版本、GPU 型号、UUID 和固件状态。CUDA Version 字段表示驱动最高支持的 CUDA 版本,不等于当前 Python 环境实际安装的 CUDA Toolkit。
bash
#!/usr/bin/env bash
set -euo pipefail
nvidia-smi
nvidia-smi --query-gpu=index,uuid,name,driver_version,pci.bus_id,memory.total --format=csv,noheader
uname -a
GPU index 可能在重启、设备筛选或 MIG 变化后改变。长期关联应优先使用 GPU UUID 或 PCI Bus ID,而不是只写“GPU 0”。
列出设备与 MIG 实例,确认操作对象。
bash
nvidia-smi -L
nvidia-smi --query-gpu=index,uuid,pci.bus_id,display_active,persistence_mode --format=csv
二、理解利用率和显存不是同一指标
GPU utilization 通常表示一个采样窗口内是否有 kernel 在 GPU 上执行;memory utilization 是显存读写引擎活跃度,不是显存占用百分比。FB memory used 则表示已分配设备内存。模型加载后可能显存很高但 GPU 利用率接近 0,这是等待请求的正常状态。
按固定字段采集一份当前快照。
bash
nvidia-smi --query-gpu=index,uuid,name,utilization.gpu,utilization.memory,memory.used,memory.free,memory.total,temperature.gpu,power.draw,pstate --format=csv
单次快照容易错过瞬时峰值。dmon 适合按秒观察功耗、利用率、时钟、显存、ECC 和吞吐;支持的字段组以当前版本 nvidia-smi dmon –help 为准。
bash
nvidia-smi dmon -s pucvmet -d 1 -o DT
观察至少覆盖一个真实业务请求或一个异常周期。持续 100% 利用率只有与吞吐下降、时延升高、温度/功率限制、Xid 或队列增长同时出现时才是故障线索。
三、定位占用显存的计算进程
先通过 NVML 查询计算进程。used_memory 在部分 MIG 或驱动模式下可能显示 N/A,不能强行解释为 0。
bash
nvidia-smi --query-compute-apps=gpu_uuid,pid,process_name,used_memory --format=csv
再将 PID 对应到系统用户、父进程、启动时间和完整命令。命令行可能包含令牌或模型路径,输出应按敏感信息处理。
bash
PID="<进程PID>"
ps -o user,pid,ppid,lstart,etime,stat,%cpu,%mem,args -p "$PID"
pstree -aps "$PID"
cat "/proc/$PID/cgroup"
pmon 按采样显示 GPU 上活动进程的 SM、显存引擎、编码与解码使用情况,适合判断“占显存但是否真正计算”。
bash
nvidia-smi pmon -i <GPU编号> -s um -d 1
短 kernel 可能在两次采样间完成,因此 pmon 没有进程不代表从未执行。应同时对照应用日志、调度器和 dmon 时间线。
四、容器和 Kubernetes 中映射进程归属
宿主机 nvidia-smi 显示的是宿主 PID。Docker 环境可从 cgroup 和容器进程列表反查归属。
bash
PID="<进程PID>"
cat "/proc/$PID/cgroup"
docker ps --no-trunc --format '{{.ID}} {{.Names}} {{.Status}}'
docker top <容器ID> -eo pid,ppid,user,etime,args
不要仅根据进程名 python 就结束进程;同一节点可能同时运行训练、推理、监控和平台守护程序。
Kubernetes 中先找出节点上的 GPU Pod,再核对容器 ID。所有 kubectl 命令显式指定 namespace。
bash
kubectl get pod -n <命名空间> -o wide \
--field-selector spec.nodeName=<节点名>
kubectl get pod <Pod名> -n <命名空间> \
-o jsonpath='{range .status.containerStatuses[*]}{.name}{"\t"}{.containerID}{"\n"}{end}'
如果不知道业务 namespace,应通过平台资产或调度记录查找,不要执行无边界的集群导出。设备插件与 GPU Operator 组件通常位于平台 namespace,需要单独按其实际 namespace 检查。
查看 Pod 声明的 GPU 资源和状态事件。
bash
kubectl get pod <Pod名> -n <命名空间> -o json \
| jq '{node:.spec.nodeName,containers:[.spec.containers[]|{name,resources}],status:.status.phase}'
kubectl get events -n <命名空间> \
--field-selector involvedObject.name=<Pod名> --sort-by=.lastTimestamp
五、进程列表为空但显存或利用率异常
先检查设备文件是否仍被某个进程打开。fuser 与 lsof 需要足够权限,且可能在高进程数主机上耗时。
bash
sudo fuser -v /dev/nvidia* 2>/dev/null || true
sudo lsof /dev/nvidia0 /dev/nvidiactl /dev/nvidia-uvm 2>/dev/null || true
如果 nvidia-smi 显示利用率 100% 但显存 0 MiB、进程表为空,应连续采样 dmon/pmon,并检查 Xid、驱动日志、容器退出残留和虚拟化层。一次快照可能正好处于上下文销毁或遥测延迟窗口。
bash
for i in $(seq 1 20); do
date -Is
nvidia-smi --query-gpu=index,utilization.gpu,memory.used,pstate,power.draw --format=csv,noheader
sleep 1
done
若连续采样仍异常,检查内核和驱动日志。Xid 是诊断方向,不同错误码含义不同,不能看到 Xid 就直接宣布硬件损坏。
bash
sudo journalctl -k --since '-30 min' --no-pager | grep -Ei 'NVRM|Xid|nvidia|nvlink|pcie' || true
dmesg -T | grep -Ei 'NVRM|Xid' | tail -n 100 || true
六、检查温度、功耗、时钟和限频原因
性能下降时要看 GPU 是否处于低 P-State、是否触发功率或热限制、SM/显存时钟是否符合负载。查询字段随驱动版本变化,先列出帮助中的可查询字段。
bash
nvidia-smi --help-query-gpu | less
nvidia-smi -q -d TEMPERATURE,POWER,CLOCK,PERFORMANCE -i <GPU编号>
温度高不一定已经降频,功耗接近上限也不一定异常。只有时钟下降、限制原因激活、吞吐下降与温度/功率同时变化,才能建立证据链。
连续记录关键字段便于与业务吞吐对齐。
bash
nvidia-smi --query-gpu=timestamp,index,pstate,temperature.gpu,power.draw,power.limit,clocks.sm,clocks.mem,utilization.gpu --format=csv -l 1
七、检查 ECC、PCIe 与 NVLink
数据中心 GPU 的 ECC、PCIe replay 和 NVLink 错误可能导致性能或稳定性问题。具体支持字段取决于 GPU 型号和驱动。
bash
nvidia-smi -q -d ECC,PAGE_RETIREMENT -i <GPU编号>
nvidia-smi --query-gpu=index,ecc.errors.corrected.volatile.total,ecc.errors.uncorrected.volatile.total --format=csv
累计 ECC 非零不等于当前故障,应观察 volatile/aggregate、增长时间和 Xid。不可纠正错误需要按 NVIDIA 和硬件厂商流程处理。
查看 GPU 拓扑,判断多卡任务是否跨 NUMA、PCIe Switch 或低带宽路径。
bash
nvidia-smi topo -m
nvidia-smi topo -p2p r
numactl --hardware
NVLink 状态命令只在支持 NVLink 的设备上有效;不支持时返回错误不能当作链路故障。
bash
nvidia-smi nvlink --status -i <GPU编号>
nvidia-smi nvlink --capabilities -i <GPU编号>
八、检查 MIG 与设备切分
MIG 开启后,一个物理 GPU 被切为多个 GPU Instance 和 Compute Instance。显存、利用率和进程需要按 MIG 设备解释,容器可见的 UUID 也可能是 MIG UUID。
bash
nvidia-smi -q -d MIG
nvidia-smi mig -lgi
nvidia-smi mig -lci
创建、销毁或禁用 MIG 会影响该物理 GPU 上所有实例,通常需要先排空工作负载。普通排障只读查看,不应为了“刷新状态”修改 MIG 布局。
九、检查驱动模块和设备健康
确认 NVIDIA 模块版本、设备节点和持久化守护进程。宿主机驱动与容器 CUDA 用户态不兼容时,应用日志通常出现 CUDA 初始化或符号错误。
bash
modinfo nvidia | grep -E '^(version|filename):'
lsmod | grep '^nvidia'
ls -l /dev/nvidia*
systemctl status nvidia-persistenced --no-pager 2>/dev/null || true
容器内验证驱动可见性,应使用已批准且与环境兼容的 CUDA 基础镜像。
bash
docker run --rm --gpus all <受信任CUDA镜像> nvidia-smi --query-gpu=index,uuid,name,driver_version --format=csv
宿主机成功而容器失败时,优先检查 NVIDIA Container Toolkit、Docker device request、CDI 配置和容器权限,不要重装驱动碰运气。
十、判断 OOM 与显存碎片
CUDA OOM 不一定意味着 nvidia-smi 显存达到 100%。框架缓存、预留内存、显存碎片、上下文、通信缓冲和瞬时峰值都会造成分配失败。先保存应用完整错误栈,再采集进程和 GPU 状态。
bash
PID="<进程PID>"
nvidia-smi --query-gpu=index,memory.used,memory.free,memory.total --format=csv
grep -E 'VmRSS|VmSwap|Threads' "/proc/$PID/status"
journalctl -k --since '-15 min' --no-pager | grep -Ei 'oom|killed process' || true
系统 OOM Killer 与 CUDA OOM 是不同层次。前者通常有内核日志并杀死主机进程;后者由 CUDA/框架返回设备内存分配错误。根因结论必须引用对应日志。
十一、谨慎结束异常任务
确认 PID、用户、容器、作业 ID、checkpoint 和业务影响后,优先让调度器或应用正常停止。SIGTERM 允许程序处理退出;超时后才考虑 SIGKILL。
bash
PID="<进程PID>"
ps -fp "$PID"
sudo kill -TERM "$PID"
for i in $(seq 1 30); do
kill -0 "$PID" 2>/dev/null || exit 0
sleep 1
done
echo "process did not exit after SIGTERM" >&2
exit 1
SIGKILL 会立即终止进程,可能损坏输出、丢失 checkpoint 或让分布式其他 rank 卡死。只有在确认无法优雅退出且有恢复方案时才使用。
bash
sudo kill -KILL <进程PID>
nvidia-smi --query-compute-apps=gpu_uuid,pid,process_name,used_memory --format=csv
十二、持久化模式和 GPU reset 的边界
持久化模式可减少无客户端时驱动状态初始化开销,但不会修复正在卡死的 kernel。修改它会改变设备运行策略,应记录原值并可回滚。
bash
nvidia-smi --query-gpu=index,persistence_mode --format=csv
sudo nvidia-smi -pm 1 -i <GPU编号>
nvidia-smi --query-gpu=index,persistence_mode --format=csv
若变更不符合预期,恢复原状态。
bash
sudo nvidia-smi -pm 0 -i <GPU编号>
nvidia-smi --query-gpu=index,persistence_mode --format=csv
GPU reset 会终止或破坏该 GPU 上全部上下文,某些 NVLink 拓扑、MIG、显示设备或虚拟化环境不支持单卡 reset。执行前必须排空任务、确认无进程占用、保存数据并准备节点重启方案。
bash
sudo fuser -v /dev/nvidia<GPU编号> 2>/dev/null || true
sudo nvidia-smi --gpu-reset -i <GPU编号>
nvidia-smi -i <GPU编号>
reset 失败时不要循环执行,也不要卸载正在使用的驱动模块。应保留 Xid、拓扑、进程和驱动日志,按平台流程隔离节点或维护重启。
十三、自动采集故障快照
下面脚本创建时间目录,保存 GPU 总览、查询字段、拓扑、进程、内核日志和系统信息。它只读,不会结束进程或重置 GPU。
bash
#!/usr/bin/env bash
set -euo pipefail
OUT_DIR="<诊断目录>/gpu-$(date +%Y%m%d-%H%M%S)"
install -d -m 0700 "$OUT_DIR"
nvidia-smi > "$OUT_DIR/nvidia-smi.txt"
nvidia-smi -q > "$OUT_DIR/nvidia-smi-q.txt"
nvidia-smi topo -m > "$OUT_DIR/topology.txt"
nvidia-smi --query-compute-apps=gpu_uuid,pid,process_name,used_memory --format=csv > "$OUT_DIR/processes.csv"
journalctl -k --since '-60 min' --no-pager > "$OUT_DIR/kernel.log"
uname -a > "$OUT_DIR/uname.txt"
诊断目录可能包含用户名、命令、容器和内部拓扑,应限制权限并按故障数据策略交接。
十四、监控而不是依赖人工截图
生产 GPU 监控通常使用 DCGM Exporter 或 NVML 采集器。Prometheus 指标名称以实际 exporter 暴露的指标为准,应同时观察 GPU 利用率、显存、温度、功耗、时钟、Xid、ECC、PCIe/NVLink 和业务吞吐。
低频巡检脚本可输出机器可解析 CSV,并在 GPU 数量与预期不符时返回非零。
bash
#!/usr/bin/env bash
set -euo pipefail
EXPECTED_GPUS="<预期GPU数量>"
ACTUAL_GPUS="$(nvidia-smi --query-gpu=index --format=csv,noheader | wc -l)"
nvidia-smi --query-gpu=timestamp,index,uuid,utilization.gpu,memory.used,memory.total,temperature.gpu,power.draw,pstate --format=csv
if [[ "$ACTUAL_GPUS" -ne "$EXPECTED_GPUS" ]]; then
echo "GPU count mismatch: expected=$EXPECTED_GPUS actual=$ACTUAL_GPUS" >&2
exit 2
fi
最终判断应把 GPU 指标与应用阶段对应起来:模型加载时显存增长、推理时 SM 活跃、通信阶段 NVLink/PCIe 活跃、等待数据时 GPU 空闲都可能正常。只有状态与预期工作阶段不一致,并有进程、日志、Xid、温度或性能证据支持,才称得上异常。
十五、不同工作负载下的正常形态
训练任务通常表现为显存长期稳定、高 SM 利用率、周期性通信和 checkpoint 阶段的 I/O 波动;推理服务则可能在模型加载后长期占用大部分显存,却只有请求到来时才提高利用率。视频编解码任务主要使用 Encoder/Decoder 引擎,GPU-Util 不一定能完整体现负载;多进程共享服务还可能在不同进程间快速切换。排障前应先明确应用当前处于加载、预热、计算、通信、等待数据、保存还是空闲阶段。
某张卡利用率明显低于同组其他卡时,先看它是否是流水线边界、是否等待最慢 rank、输入 batch 是否不均、数据加载是否卡在 CPU,或者分布式任务是否处于同步点。仅凭一张卡 0% 不能认定设备掉线;如果同卡显存、进程和 NVLink 都存在,应用日志可能更能解释它在等待什么。反过来,利用率持续 100% 但业务吞吐为零,则要检查 kernel 卡死、通信重试、错误恢复循环和驱动 Xid。
十六、识别显存持续增长
显存增长可能是正常的缓存预热、KV Cache 扩展、CUDA Graph 捕获,也可能是请求未释放、张量引用泄漏或异常任务残留。应以固定请求集重复测试,记录每轮结束后的 used memory、框架缓存统计和活动请求数。若业务回到空闲后显存没有回落,也不能立即称为泄漏,因为 PyTorch 等框架会保留缓存池供后续复用;真正的判断要看可复用缓存、分配失败、请求数和多轮趋势。
当显存增长最终触发 OOM 时,保留首次错误栈尤其重要。后续 OOM 可能只是级联结果,例如一个 rank 先失败,其他 rank 在通信处报错。不要在日志中只截最后一行 CUDA out of memory;应保存最先出现异常的 rank、分配大小、当时的 free memory、输入长度和并发数。
十七、驱动升级与节点隔离
驱动升级会影响所有 GPU 任务、内核模块和容器兼容性,不能作为普通故障的第一反应。只有在错误码、兼容矩阵、已知缺陷或厂商建议支持时,才应进入升级流程。升级前排空节点、保存作业 checkpoint、记录当前驱动与固件、验证新驱动对应的 CUDA 和容器镜像,并准备回退包与维护重启。
如果同一 GPU 重复出现不可纠正 ECC、Xid、PCIe/NVLink 错误或 reset 后再次异常,应优先隔离节点并阻止新任务调度,而不是让调度器持续重试。隔离结论必须引用 GPU UUID、时间、错误码、内核日志和受影响作业;设备恢复后还应完成压力验证,不能只看 nvidia-smi 能重新打开。
十八、告警阈值必须结合业务基线
GPU 利用率高不适合单独告警,因为训练和高吞吐推理本来就希望设备持续繁忙;更有效的告警是业务吞吐下降或队列增长,同时 GPU 利用率、时钟、温度、功耗或错误状态偏离基线。显存使用率同样不能只按固定百分比处理:模型服务常常预分配 KV Cache,长期高显存可以是设计行为,而显存突然下降则可能意味着 worker 退出或模型被卸载。
温度、功率和 ECC 阈值应依据具体 GPU 数据手册、机房环境和硬件团队策略确定。Prometheus 指标名称以实际 exporter 暴露的指标为准,不同 DCGM Exporter、NVML 采集器和 GPU 型号的字段与标签可能不同。上线告警前应在监控系统直接查询真实时间序列,验证 GPU UUID、节点、Pod 和容器标签能够正确关联,避免因标签缺失把多张卡聚合成一个错误结论。
故障恢复也应设置判断窗口。进程退出后显存释放、驱动遥测和调度器状态同步可能需要时间;如果告警在单个采样点立即恢复,容易掩盖抖动。建议把 GPU 指标、应用请求、作业状态、节点事件和 Xid 放在同一时间线上,并在恢复记录中说明采取了停止任务、reset、节点重启还是仅等待负载结束。
文末阅读福利
仅目前来说,无论是运维人转型提升,还是零基础想转行IT,最好的岗位就是云计算运维&SRE岗位。
为了帮助大家早日快速入门云计算运维领域,给大家整理了一套【最新运维资料】高级运维工程师必备技能资料包(文末一键免费领取),内容有多详实丰富看下图!
1.38张最全工程师技能图谱
2.面试大礼包
3.Linux书籍
内容比较多,就不一一展示了
以上所有资料获取请扫码:
识别上方二维码
备注:2026最新运维资料
100%免费领取
(是扫码领取,不是在公众号后台回复,别看错了哦)
免责声明:
本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。
任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。
本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我。
本文转载自:马哥Linux运维 点击关注 👉 点击关注 👉《nvidia-smi 实战:排查 GPU 利用率与显存占用异常》
版权声明
本站仅做备份收录,仅供研究与教学参考之用。
读者将信息用于其他用途的,全部法律及连带责任由读者自行承担,本站不承担任何责任。









评论