nvidia-smi实战:排查GPU利用率与显存占用异常

admin 2026-07-22 06:39:11 网络安全文章 来源:ZONE.CI 全球网 0 阅读模式

文章总结: 本文提供了一套系统化的nvidia-smi实战排查流程,用于诊断GPU利用率与显存占用异常。文章强调不能仅凭单次截图下结论,需理解利用率与显存是不同指标,并建议优先使用GPUUUID进行长期关联。核心步骤包括记录驱动版本、定位占用显存的计算进程、在容器和Kubernetes环境中映射进程归属、检查温度功耗与限频原因、以及判断OOM与显存碎片。文章还提供了处理异常任务和检查ECC、PCIe与NVLink状态的具体命令。关键结论是,排查需结合多种工具(如dmon、pmon)和日志(如Xid)进行交叉验证,避免误判。可操作建议包括在结束进程前确认业务影响,并优先使用SIGTERM信号。 综合评分: 88 文章分类: 实战经验,安全运营,解决方案


cover_image

nvidia-smi 实战:排查 GPU 利用率与显存占用异常

点击关注 👉 点击关注 👉

马哥Linux运维

2026年7月19日 18:00 广东

在小说阅读器读本章

去阅读

nvidia-smi 实战:排查 GPU 利用率与显存占用异常

GPU 利用率突然 100%、显存被占满、进程列表为空但设备持续繁忙、某张卡温度和功耗异常,这些现象不能只靠一张 nvidia-smi 截图下结论。nvidia-smi 展示的是驱动和 NVML 在采样时刻提供的状态:利用率是时间窗口内引擎忙碌比例,显存是设备内存分配,进程表则受权限、容器命名空间、MIG、驱动状态和采样时刻影响。三者不一致并不自动等于“幽灵进程”。

本文适用于 Linux 与 NVIDIA 数据中心 GPU。、<进程PID>、<容器ID>、<命名空间>、 是占位符,需要替换为真实对象。修改持久化模式、功率限制、MIG 配置、结束进程或 GPU reset 都会影响业务,必须在只读证据完整后再执行。

一、先记录驱动、GPU 和工具版本

排障报告首先要说明驱动版本、CUDA Driver API 版本、GPU 型号、UUID 和固件状态。CUDA Version 字段表示驱动最高支持的 CUDA 版本,不等于当前 Python 环境实际安装的 CUDA Toolkit。

bash

#!/usr/bin/env bash
set&nbsp;-euo pipefail

nvidia-smi
nvidia-smi --query-gpu=index,uuid,name,driver_version,pci.bus_id,memory.total &nbsp; --format=csv,noheader
uname&nbsp;-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 &nbsp; --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 &nbsp; --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 &nbsp; --format=csv

再将 PID 对应到系统用户、父进程、启动时间和完整命令。命令行可能包含令牌或模型路径,输出应按敏感信息处理。

bash

PID="<进程PID>"

ps -o user,pid,ppid,lstart,etime,stat,%cpu,%mem,args -p&nbsp;"$PID"
pstree -aps&nbsp;"$PID"
cat&nbsp;"/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&nbsp;"/proc/$PID/cgroup"
docker ps --no-trunc --format&nbsp;'{{.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 \
&nbsp; --field-selector spec.nodeName=<节点名>
kubectl get pod <Pod名> -n <命名空间> \
&nbsp; -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 \
&nbsp; | jq&nbsp;'{node:.spec.nodeName,containers:[.spec.containers[]|{name,resources}],status:.status.phase}'
kubectl get events -n <命名空间> \
&nbsp; --field-selector involvedObject.name=<Pod名> --sort-by=.lastTimestamp

五、进程列表为空但显存或利用率异常

先检查设备文件是否仍被某个进程打开。fuser 与 lsof 需要足够权限,且可能在高进程数主机上耗时。

bash

sudo&nbsp;fuser -v /dev/nvidia* 2>/dev/null ||&nbsp;true
sudo&nbsp;lsof /dev/nvidia0 /dev/nvidiactl /dev/nvidia-uvm 2>/dev/null ||&nbsp;true

如果 nvidia-smi 显示利用率 100% 但显存 0 MiB、进程表为空,应连续采样 dmon/pmon,并检查 Xid、驱动日志、容器退出残留和虚拟化层。一次快照可能正好处于上下文销毁或遥测延迟窗口。

bash

for&nbsp;i&nbsp;in&nbsp;$(seq&nbsp;1 20);&nbsp;do
&nbsp;&nbsp;date&nbsp;-Is
&nbsp; nvidia-smi --query-gpu=index,utilization.gpu,memory.used,pstate,power.draw &nbsp; &nbsp; --format=csv,noheader
&nbsp;&nbsp;sleep&nbsp;1
done

若连续采样仍异常,检查内核和驱动日志。Xid 是诊断方向,不同错误码含义不同,不能看到 Xid 就直接宣布硬件损坏。

bash

sudo&nbsp;journalctl -k --since&nbsp;'-30 min'&nbsp;--no-pager &nbsp; | grep -Ei&nbsp;'NVRM|Xid|nvidia|nvlink|pcie'&nbsp;||&nbsp;true
dmesg -T | grep -Ei&nbsp;'NVRM|Xid'&nbsp;|&nbsp;tail&nbsp;-n 100 ||&nbsp;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 &nbsp; --format=csv -l 1

数据中心 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 &nbsp; --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&nbsp;'^(version|filename):'
lsmod | grep&nbsp;'^nvidia'
ls&nbsp;-l /dev/nvidia*
systemctl status nvidia-persistenced --no-pager 2>/dev/null ||&nbsp;true

容器内验证驱动可见性,应使用已批准且与环境兼容的 CUDA 基础镜像。

bash

docker run --rm&nbsp;--gpus all <受信任CUDA镜像> &nbsp; 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 &nbsp; --format=csv
grep -E&nbsp;'VmRSS|VmSwap|Threads'&nbsp;"/proc/$PID/status"
journalctl -k --since&nbsp;'-15 min'&nbsp;--no-pager | grep -Ei&nbsp;'oom|killed process'&nbsp;||&nbsp;true

系统 OOM Killer 与 CUDA OOM 是不同层次。前者通常有内核日志并杀死主机进程;后者由 CUDA/框架返回设备内存分配错误。根因结论必须引用对应日志。

十一、谨慎结束异常任务

确认 PID、用户、容器、作业 ID、checkpoint 和业务影响后,优先让调度器或应用正常停止。SIGTERM 允许程序处理退出;超时后才考虑 SIGKILL。

bash

PID="<进程PID>"

ps -fp&nbsp;"$PID"
sudo&nbsp;kill&nbsp;-TERM&nbsp;"$PID"
for&nbsp;i&nbsp;in&nbsp;$(seq&nbsp;1 30);&nbsp;do
&nbsp;&nbsp;kill&nbsp;-0&nbsp;"$PID"&nbsp;2>/dev/null ||&nbsp;exit&nbsp;0
&nbsp;&nbsp;sleep&nbsp;1
done
echo&nbsp;"process did not exit after SIGTERM"&nbsp;>&2
exit&nbsp;1

SIGKILL 会立即终止进程,可能损坏输出、丢失 checkpoint 或让分布式其他 rank 卡死。只有在确认无法优雅退出且有恢复方案时才使用。

bash

sudo&nbsp;kill&nbsp;-KILL <进程PID>
nvidia-smi --query-compute-apps=gpu_uuid,pid,process_name,used_memory &nbsp; --format=csv

十二、持久化模式和 GPU reset 的边界

持久化模式可减少无客户端时驱动状态初始化开销,但不会修复正在卡死的 kernel。修改它会改变设备运行策略,应记录原值并可回滚。

bash

nvidia-smi --query-gpu=index,persistence_mode --format=csv
sudo&nbsp;nvidia-smi -pm 1 -i <GPU编号>
nvidia-smi --query-gpu=index,persistence_mode --format=csv

若变更不符合预期,恢复原状态。

bash

sudo&nbsp;nvidia-smi -pm 0 -i <GPU编号>
nvidia-smi --query-gpu=index,persistence_mode --format=csv

GPU reset 会终止或破坏该 GPU 上全部上下文,某些 NVLink 拓扑、MIG、显示设备或虚拟化环境不支持单卡 reset。执行前必须排空任务、确认无进程占用、保存数据并准备节点重启方案。

bash

sudo&nbsp;fuser -v /dev/nvidia<GPU编号> 2>/dev/null ||&nbsp;true
sudo&nbsp;nvidia-smi --gpu-reset -i <GPU编号>
nvidia-smi -i <GPU编号>

reset 失败时不要循环执行,也不要卸载正在使用的驱动模块。应保留 Xid、拓扑、进程和驱动日志,按平台流程隔离节点或维护重启。

十三、自动采集故障快照

下面脚本创建时间目录,保存 GPU 总览、查询字段、拓扑、进程、内核日志和系统信息。它只读,不会结束进程或重置 GPU。

bash

#!/usr/bin/env bash
set&nbsp;-euo pipefail

OUT_DIR="<诊断目录>/gpu-$(date +%Y%m%d-%H%M%S)"
install -d -m 0700&nbsp;"$OUT_DIR"

nvidia-smi >&nbsp;"$OUT_DIR/nvidia-smi.txt"
nvidia-smi -q >&nbsp;"$OUT_DIR/nvidia-smi-q.txt"
nvidia-smi topo -m >&nbsp;"$OUT_DIR/topology.txt"
nvidia-smi --query-compute-apps=gpu_uuid,pid,process_name,used_memory &nbsp; --format=csv >&nbsp;"$OUT_DIR/processes.csv"
journalctl -k --since&nbsp;'-60 min'&nbsp;--no-pager >&nbsp;"$OUT_DIR/kernel.log"
uname&nbsp;-a >&nbsp;"$OUT_DIR/uname.txt"

诊断目录可能包含用户名、命令、容器和内部拓扑,应限制权限并按故障数据策略交接。

十四、监控而不是依赖人工截图

生产 GPU 监控通常使用 DCGM Exporter 或 NVML 采集器。Prometheus 指标名称以实际 exporter 暴露的指标为准,应同时观察 GPU 利用率、显存、温度、功耗、时钟、Xid、ECC、PCIe/NVLink 和业务吞吐。

低频巡检脚本可输出机器可解析 CSV,并在 GPU 数量与预期不符时返回非零。

bash

#!/usr/bin/env bash
set&nbsp;-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 &nbsp; --format=csv

if&nbsp;[[&nbsp;"$ACTUAL_GPUS"&nbsp;-ne&nbsp;"$EXPECTED_GPUS"&nbsp;]];&nbsp;then
&nbsp;&nbsp;echo&nbsp;"GPU count mismatch: expected=$EXPECTED_GPUS&nbsp;actual=$ACTUAL_GPUS"&nbsp;>&2
&nbsp;&nbsp;exit&nbsp;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 利用率与显存占用异常》

自写c2单文件对抗EDR 网络安全文章

自写c2单文件对抗EDR

文章总结: 本文作者分享自写C2单文件在联网环境下对抗多种EDR的实战经验,测试了天擎、某山终端、某步、某融信、某盟等主流EDR产品,病毒库更新至近期。结果显示
评论:0   参与:  0