怎么用脚本获取显卡显存

wen 实用脚本 2

从零到一:用脚本精准获取显卡显存(VRAM)的终极指南(含Python/Shell实战)


📚 目录导读(Table of Contents)

  1. 为什么需要脚本获取显存? —— 监控、调优与自动化场景解析
  2. 底层原理:显存信息藏在哪里? —— 深入理解GPU查询接口(NVML/Sysfs/Windows WMI)
  3. Windows平台(NVIDIA/AMD/Intel)脚本获取 —— 利用nvidia-smi与PowerShell/WMI
  4. Linux平台(通用)脚本获取 —— 解析/proc/driver/nvidiarocm-smiintel_gpu_top
  5. 跨平台Python终极方案 —— 使用pynvmlpsutil封装优雅截图
  6. 常见问题FAQ(附带代码排查) —— 权限不足、多GPU识别、虚拟化环境下的坑
  7. 脚本之外,显存监控的未来趋势

✍️ 文章正文

为什么需要脚本获取显存?

在深度学习训练、视频渲染或大规模科学计算中,显存(VRAM)是比CPU内存更稀缺的资源,当您半夜跑模型时,程序因CUDA Out Of Memory崩溃,却不知道是哪个进程吃满了显存——这时候,一条简单的脚本命令就能让您即时定位“显存杀手”

怎么用脚本获取显卡显存

更重要的是,对于运维自动化(如K8s调度GPU Pod)或性能调优(如监控温度与频率联动),手动打开任务管理器/htop已完全不够用,脚本化获取显存是构建监控大盘、实现动态扩缩容的基础。


底层原理:显存信息藏在哪里?

  • NVIDIA GPU:官方驱动自带NVML(NVIDIA Management Library),命令行工具为nvidia-smi,所有Linux发行版和Windows均支持。
  • AMD GPU:Linux下依赖sysfs接口(位于/sys/class/drm/card*/device/mem_info_vram_total)或rocm-smi工具;Windows可调用WMIWin32_VideoControllerAdapterRAM属性(虽不精确但可用)。
  • Intel核显:Linux下推荐intel_gpu_top/sys/class/drm/card0/gt_cur_freq_mhz;Windows用dxdiag查询不直观,脚本可依赖wmic path win32_VideoController get AdapterRAM

核心思想:所有脚本的本质都是解析命令行输出读取内核暴露的文件描述符


实战一:Windows平台脚本获取(一网打尽)

1 纯CMD一行流(适合批处理)

@echo off
nvidia-smi --query-gpu=name,memory.total,memory.used,memory.free --format=csv,noheader,nounits

若为AMD显卡,使用PowerShell:

Get-CimInstance -ClassName Win32_VideoController | Select-Object Name, AdapterRAM

注意AdapterRAM是32位值,超过4GB显存会溢出(显示错误值),需改查注册表:

(Get-ItemProperty "HKLM:\SYSTEM\CurrentControlSet\Control\Class\{4d36e968-e325-11ce-bfc1-08002be10318}\0000").HardwareInformation.qwMemorySize

2 进阶:定时记录到日志(任务计划程序配合)

$loop = $true
while($loop){
    $mem = nvidia-smi --query-gpu=memory.used --format=csv,noheader,nounits
    Add-Content "C:\gpu_log.txt" "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss'), $mem MB"
    Start-Sleep -Seconds 5
}

问答Q1:为什么我的Windows脚本总是权限不足? nvidia-smi需要管理员权限读取NVML驱动接口,请右键“以管理员身份运行”命令提示符,或在任务计划程序中勾选“使用最高权限运行”。


实战二:Linux平台脚本获取(极致简洁)

1 NVIDIA用户(最常用)

#!/bin/bash
# 一行获取总显存与已用显存(单位MiB)
nvidia-smi --query-gpu=memory.total,memory.used,memory.free --format=csv

解析多GPU:循环遍历所有索引

for i in $(seq 0 $(nvidia-smi -L | wc -l)); do
  nvidia-smi -i $i --query-gpu=memory.used --format=csv,noheader,nounits
done

2 AMD用户(避免安装额外工具)

# 直接读取sysfs,速度极快
VENDOR=$(lspci | grep VGA | awk '{print $NF}')
if [[ $VENDOR =~ "AMD" ]]; then
  total=$(cat /sys/class/drm/card0/device/mem_info_vram_total)
  used=$(cat /sys/class/drm/card0/device/mem_info_vram_used)
  echo "Total: $((total/1024/1024)) MB, Used: $((used/1024/1024)) MB"
fi

3 集成监控脚本(配合cron定时任务)

*/5 * * * * /usr/bin/python3 /opt/gpu_watch.py >> /var/log/gpu_mem.log 2>&1

问答Q2:在Docker容器中运行nvidia-smi报错couldn't find libnvidia-ml.so怎么办? :必须挂载宿主的驱动目录,运行容器时添加参数:-v /usr/lib/x86_64-linux-gnu/libnvidia-ml.so.1:/usr/lib/x86_64-linux-gnu/libnvidia-ml.so.1 以及 -v /usr/bin/nvidia-smi:/usr/bin/nvidia-smi,更推荐使用NVIDIA官方容器工具包(nvidia-container-toolkit)。


实战三:跨平台Python终极方案(推荐)

Python最大的优势是跨平台逻辑统一,且能轻松对接数据分析与告警系统。

1 安装依赖库

pip install pynvml psutil  # pynvml仅支持NVIDIA,AMD需用amdsmi

2 优雅的封装代码(同时支持NVIDIA + AMD回退)

import os
import psutil
def get_gpu_memory():
    """返回列表,每个GPU一个字典:{name, total_mb, used_mb, free_mb}"""
    gpu_info = []
    try:
        from pynvml import nvmlInit, nvmlDeviceGetHandleByIndex, nvmlDeviceGetMemoryInfo, nvmlDeviceGetName, nvmlShutdown
        nvmlInit()
        for i in range(int(os.popen("nvidia-smi -L | wc -l").read().strip())):
            handle = nvmlDeviceGetHandleByIndex(i)
            mem = nvmlDeviceGetMemoryInfo(handle)
            gpu_info.append({
                "name": nvmlDeviceGetName(handle).decode(),
                "total_mb": mem.total // 1024**2,
                "used_mb": mem.used // 1024**2,
                "free_mb": mem.free // 1024**2
            })
        nvmlShutdown()
    except Exception:
        # 回退到读取sysfs(适配AMD)
        for card in ["card0", "card1"]:
            base = f"/sys/class/drm/{card}/device"
            if os.path.exists(f"{base}/mem_info_vram_total"):
                total = int(open(f"{base}/mem_info_vram_total").read()) // 1024**2
                used = int(open(f"{base}/mem_info_vram_used").read()) // 1024**2
                gpu_info.append({"name": card, "total_mb": total, "used_mb": used, "free_mb": total-used})
    return gpu_info
if __name__ == "__main__":
    for gpu in get_gpu_memory():
        print(f"型号: {gpu['name']} | 总显存: {gpu['total_mb']}MB | 已用: {gpu['used_mb']}MB | 剩余: {gpu['free_mb']}MB")

代码优势:自动检测驱动类型,无需手动指定GPU厂商。

问答Q3pynvml获取的显存单位是什么?精度如何? :单位为字节(Bytes),代码中除1024**2转为兆字节(MiB),精度与nvidia-smi完全一致(底层同一NVML接口),但注意memory.free可能不包含“保留内存”,因此free + used ≠ total


常见问题FAQ(附排查方案)

Q4:脚本获取的显存数值比任务管理器小,为什么?

:Windows任务管理器默认显示专用GPU内存,而nvidia-smi显示的包括了共享GPU内存,如需一致,在脚本中增加--query-gpu=memory.total,memory.used --format=csv即可。

Q5:虚拟化平台(如VMware ESXi)下,显存显示为0?

:虚拟机不会直通物理GPU显存,若为vGPU,需在宿主机安装NVIDIA vGPU驱动,并在虚拟机内挂载nvidia-smi对应版本,否则,只能获取主机分配的虚拟显存大小(通常为配置固定值)。

Q6:如何用脚本检测显存温度并触发降频?

:在Python代码中增加nvmlDeviceGetTemperature(handle, NVML_TEMPERATURE_GPU),当温度>85℃时,通过subprocess调用nvidia-smi -pl 250(功率限制)或nvidia-smi -lgc 1000,1500(锁定频率)。


脚本之外,显存监控的未来趋势

脚本化获取显存是基础能力,但现代GPU监控已向可观测性演进,例如NVIDIA DCGM(Data Center GPU Manager)能提供细粒度的显存带宽、ECC错误率等指标,并通过Prometheus导出,对于个人开发者,建议将上述脚本集成到Grafana + Prometheus生态中,实现可视化告警。

最终建议:在您的生产环境中,优先使用官方工具(nvidia-smi),但将脚本封装成独立模块(如get_vram()函数),方便在自动化流水线中复用,无论您用的是Windows还是Linux,请务必定期更新驱动版本,因为NVML接口会随驱动迭代而增强。

打开您的终端,运行第一行代码,看看您的“显存地图”吧!

抱歉,评论功能暂时关闭!