py3nvml实现GPU相关信息读取的案例分析

目录
  • 技术背景
  • 常规信息读取
  • py3nvml的安装与使用
    • py3nvml绑定GPU卡
    • 查看空闲GPU
    • 命令行信息获取
    • 单独查看驱动版本和显卡型号
    • 单独查看显存信息
  • 总结概要
  • 版权声明
  • 参考链接

在深度学习或者其他类型的GPU运算过程中,对于GPU信息的监测也是一个非常常用的功能。如果仅仅是使用系统级的GPU监测工具,就没办法非常细致的去跟踪每一步的显存和使用率的变化。如果是用profiler,又显得过于细致,而且环境配置、信息输出和筛选并不是很方便。此时就可以考虑使用py3nvml这样的工具,针对于GPU任务执行的过程进行细化的分析,有助于提升GPU的利用率和程序执行的性能。

技术背景

随着模型运算量的增长和硬件技术的发展,使用GPU来完成各种任务的计算已经渐渐成为算法实现的主流手段。而对于运行期间的一些GPU的占用,比如每一步的显存使用率等诸如此类的信息,就需要一些比较细致的GPU信息读取的工具,这里我们重点推荐使用py3nvml来对python代码运行的一个过程进行监控。

常规信息读取

一般大家比较常用的就是nvidia-smi这个指令,来读取GPU的使用率和显存占用、驱动版本等信息:

$ nvidia-smi
Wed Jan 12 15:52:04 2022
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 470.42.01    Driver Version: 470.42.01    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. |
|                               |                      |               MIG M. |
|===============================+======================+======================|
|   0  Quadro RTX 4000     On   | 00000000:03:00.0  On |                  N/A |
| 30%   39C    P8    20W / 125W |    538MiB /  7979MiB |     16%      Default |
|                               |                      |                  N/A |
+-------------------------------+----------------------+----------------------+
|   1  Quadro RTX 4000     On   | 00000000:A6:00.0 Off |                  N/A |
| 30%   32C    P8     7W / 125W |      6MiB /  7982MiB |      0%      Default |
|                               |                      |                  N/A |
+-------------------------------+----------------------+----------------------+

+-----------------------------------------------------------------------------+
| Processes:                                                                  |
|  GPU   GI   CI        PID   Type   Process name                  GPU Memory |
|        ID   ID                                                   Usage      |
|=============================================================================|
|    0   N/A  N/A      1643      G   /usr/lib/xorg/Xorg                412MiB |
|    0   N/A  N/A      2940      G   /usr/bin/gnome-shell               76MiB |
|    0   N/A  N/A     47102      G   ...AAAAAAAAA= --shared-files       35MiB |
|    0   N/A  N/A    172424      G   ...AAAAAAAAA= --shared-files       11MiB |
|    1   N/A  N/A      1643      G   /usr/lib/xorg/Xorg                  4MiB |
+-----------------------------------------------------------------------------+

但是如果不使用profile仅仅使用nvidia-smi这个指令的输出的话,是没有办法非常细致的分析程序运行过程中的变化的。这里顺便推荐一个比较精致的跟nvidia-smi用法非常类似的小工具:gpustat。这个工具可以直接使用pip进行安装和管理:

$ python3 -m pip install gpustat
Collecting gpustat
  Downloading gpustat-0.6.0.tar.gz (78 kB)
     |████████████████████████████████| 78 kB 686 kB/s
Requirement already satisfied: six>=1.7 in /home/dechin/.local/lib/python3.8/site-packages (from gpustat) (1.16.0)
Collecting nvidia-ml-py3>=7.352.0
  Downloading nvidia-ml-py3-7.352.0.tar.gz (19 kB)
Requirement already satisfied: psutil in /home/dechin/.local/lib/python3.8/site-packages (from gpustat) (5.8.0)
Collecting blessings>=1.6
  Downloading blessings-1.7-py3-none-any.whl (18 kB)
Building wheels for collected packages: gpustat, nvidia-ml-py3
  Building wheel for gpustat (setup.py) ... done
  Created wheel for gpustat: filename=gpustat-0.6.0-py3-none-any.whl size=12617 sha256=4158e741b609c7a1bc6db07d76224db51cd7656a6f2e146e0b81185ce4e960ba
  Stored in directory: /home/dechin/.cache/pip/wheels/0d/d9/80/b6cbcdc9946c7b50ce35441cc9e7d8c5a9d066469ba99bae44
  Building wheel for nvidia-ml-py3 (setup.py) ... done
  Created wheel for nvidia-ml-py3: filename=nvidia_ml_py3-7.352.0-py3-none-any.whl size=19191 sha256=70cd8ffc92286944ad9f5dc4053709af76fc0e79928dc61b98a9819a719f1e31
  Stored in directory: /home/dechin/.cache/pip/wheels/b9/b1/68/cb4feab29709d4155310d29a421389665dcab9eb3b679b527b
Successfully built gpustat nvidia-ml-py3
Installing collected packages: nvidia-ml-py3, blessings, gpustat
Successfully installed blessings-1.7 gpustat-0.6.0 nvidia-ml-py3-7.352.0

使用的时候也是跟nvidia-smi非常类似的操作:

$ watch --color -n1 gpustat -cpu 

返回结果如下所示:

Every 1.0s: gpustat -cpu                   ubuntu2004: Wed Jan 12 15:58:59 2022

ubuntu2004           Wed Jan 12 15:58:59 2022  470.42.01
[0] Quadro RTX 4000  | 39'C,   3 % |   537 /  7979 MB | root:Xorg/1643(412M) de
chin:gnome-shell/2940(75M) dechin:slack/47102(35M) dechin:chrome/172424(11M)
[1] Quadro RTX 4000  | 32'C,   0 % |     6 /  7982 MB | root:Xorg/1643(4M)

通过gpustat返回的结果,包含了GPU的型号、使用率和显存使用大小和GPU当前的温度等常规信息。

py3nvml的安装与使用

接下来正式看下py3nvml的安装和使用方法,这是一个可以在python中实时查看和监测GPU信息的一个库,可以通过pip来安装和管理:

$ python3 -m pip install py3nvml
Collecting py3nvml
  Downloading py3nvml-0.2.7-py3-none-any.whl (55 kB)
     |████████████████████████████████| 55 kB 650 kB/s
Requirement already satisfied: xmltodict in /home/dechin/anaconda3/lib/python3.8/site-packages (from py3nvml) (0.12.0)
Installing collected packages: py3nvml
Successfully installed py3nvml-0.2.7

py3nvml绑定GPU卡

有一些框架为了性能的最大化,在初始化的时候就会默认去使用到整个资源池里面的所有GPU卡,比如如下使用Jax来演示的一个案例:

In [1]: import py3nvml

In [2]: from jax import numpy as jnp

In [3]: x = jnp.ones(1000000000)

In [4]: !nvidia-smi
Wed Jan 12 16:08:32 2022
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 470.42.01    Driver Version: 470.42.01    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. |
|                               |                      |               MIG M. |
|===============================+======================+======================|
|   0  Quadro RTX 4000     On   | 00000000:03:00.0  On |                  N/A |
| 30%   41C    P0    38W / 125W |   7245MiB /  7979MiB |      0%      Default |
|                               |                      |                  N/A |
+-------------------------------+----------------------+----------------------+
|   1  Quadro RTX 4000     On   | 00000000:A6:00.0 Off |                  N/A |
| 30%   35C    P0    35W / 125W |    101MiB /  7982MiB |      0%      Default |
|                               |                      |                  N/A |
+-------------------------------+----------------------+----------------------+

+-----------------------------------------------------------------------------+
| Processes:                                                                  |
|  GPU   GI   CI        PID   Type   Process name                  GPU Memory |
|        ID   ID                                                   Usage      |
|=============================================================================|
|    0   N/A  N/A      1643      G   /usr/lib/xorg/Xorg                412MiB |
|    0   N/A  N/A      2940      G   /usr/bin/gnome-shell               75MiB |
|    0   N/A  N/A     47102      G   ...AAAAAAAAA= --shared-files       35MiB |
|    0   N/A  N/A    172424      G   ...AAAAAAAAA= --shared-files       11MiB |
|    0   N/A  N/A    812125      C   /usr/local/bin/python            6705MiB |
|    1   N/A  N/A      1643      G   /usr/lib/xorg/Xorg                  4MiB |
|    1   N/A  N/A    812125      C   /usr/local/bin/python              93MiB |
+-----------------------------------------------------------------------------+

在这个案例中我们只是在显存中分配了一块空间用于存储一个向量,但是Jax在初始化之后,自动占据了本地的2张GPU卡。根据Jax官方提供的方法,我们可以使用如下的操作配置环境变量,使得Jax只能看到其中的1张卡,这样就不会扩张:

In [1]: import os

In [2]: os.environ["CUDA_VISIBLE_DEVICES"] = "1"

In [3]: from jax import numpy as jnp

In [4]: x = jnp.ones(1000000000)

In [5]: !nvidia-smi
Wed Jan 12 16:10:36 2022
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 470.42.01    Driver Version: 470.42.01    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. |
|                               |                      |               MIG M. |
|===============================+======================+======================|
|   0  Quadro RTX 4000     On   | 00000000:03:00.0  On |                  N/A |
| 30%   40C    P8    19W / 125W |    537MiB /  7979MiB |      0%      Default |
|                               |                      |                  N/A |
+-------------------------------+----------------------+----------------------+
|   1  Quadro RTX 4000     On   | 00000000:A6:00.0 Off |                  N/A |
| 30%   35C    P0    35W / 125W |   7195MiB /  7982MiB |      0%      Default |
|                               |                      |                  N/A |
+-------------------------------+----------------------+----------------------+

+-----------------------------------------------------------------------------+
| Processes:                                                                  |
|  GPU   GI   CI        PID   Type   Process name                  GPU Memory |
|        ID   ID                                                   Usage      |
|=============================================================================|
|    0   N/A  N/A      1643      G   /usr/lib/xorg/Xorg                412MiB |
|    0   N/A  N/A      2940      G   /usr/bin/gnome-shell               75MiB |
|    0   N/A  N/A     47102      G   ...AAAAAAAAA= --shared-files       35MiB |
|    0   N/A  N/A    172424      G   ...AAAAAAAAA= --shared-files       11MiB |
|    1   N/A  N/A      1643      G   /usr/lib/xorg/Xorg                  4MiB |
|    1   N/A  N/A    813030      C   /usr/local/bin/python            7187MiB |
+-----------------------------------------------------------------------------+

可以看到结果中已经是只使用了1张GPU卡,达到了我们的目的,但是这种通过配置环境变量来实现的功能还是着实不够pythonic,因此py3nvml中也提供了这样的功能,可以指定某一系列的GPU卡用于执行任务:

In [1]: import py3nvml

In [2]: from jax import numpy as jnp

In [3]: py3nvml.grab_gpus(num_gpus=1,gpu_select=[1])
Out[3]: 1

In [4]: x = jnp.ones(1000000000)

In [5]: !nvidia-smi
Wed Jan 12 16:12:37 2022
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 470.42.01    Driver Version: 470.42.01    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. |
|                               |                      |               MIG M. |
|===============================+======================+======================|
|   0  Quadro RTX 4000     On   | 00000000:03:00.0  On |                  N/A |
| 30%   40C    P8    20W / 125W |    537MiB /  7979MiB |      0%      Default |
|                               |                      |                  N/A |
+-------------------------------+----------------------+----------------------+
|   1  Quadro RTX 4000     On   | 00000000:A6:00.0 Off |                  N/A |
| 30%   36C    P0    35W / 125W |   7195MiB /  7982MiB |      0%      Default |
|                               |                      |                  N/A |
+-------------------------------+----------------------+----------------------+

+-----------------------------------------------------------------------------+
| Processes:                                                                  |
|  GPU   GI   CI        PID   Type   Process name                  GPU Memory |
|        ID   ID                                                   Usage      |
|=============================================================================|
|    0   N/A  N/A      1643      G   /usr/lib/xorg/Xorg                412MiB |
|    0   N/A  N/A      2940      G   /usr/bin/gnome-shell               75MiB |
|    0   N/A  N/A     47102      G   ...AAAAAAAAA= --shared-files       35MiB |
|    0   N/A  N/A    172424      G   ...AAAAAAAAA= --shared-files       11MiB |
|    1   N/A  N/A      1643      G   /usr/lib/xorg/Xorg                  4MiB |
|    1   N/A  N/A    814673      C   /usr/local/bin/python            7187MiB |
+-----------------------------------------------------------------------------+

可以看到结果中也是只使用了1张GPU卡,达到了跟上一步的操作一样的效果。

查看空闲GPU

对于环境中可用的GPU,py3nvml的判断标准就是在这个GPU上已经没有任何的进程,那么这个就是一张可用的GPU卡:

In [1]: import py3nvml

In [2]: free_gpus = py3nvml.get_free_gpus()

In [3]: free_gpus
Out[3]: [True, True]

当然这里需要说明的是,系统应用在这里不会被识别,应该是会判断守护进程。

命令行信息获取

nvidia-smi非常类似的,py3nvml也可以在命令行中通过调用py3smi来使用。值得一提的是,如果需要用nvidia-smi来实时的监测GPU的使用信息,往往是需要配合watch -n来使用的,但是如果是py3smi则不需要,直接用py3smi -l就可以实现类似的功能。

$ py3smi -l 5
Wed Jan 12 16:17:37 2022
+-----------------------------------------------------------------------------+
| NVIDIA-SMI                        Driver Version: 470.42.01                 |
+---------------------------------+---------------------+---------------------+
| GPU Fan  Temp Perf Pwr:Usage/Cap|        Memory-Usage | GPU-Util Compute M. |
+=================================+=====================+=====================+
|   0 30%   39C    8   19W / 125W |   537MiB /  7979MiB |       0%    Default |
|   1 30%   33C    8    7W / 125W |     6MiB /  7982MiB |       0%    Default |
+---------------------------------+---------------------+---------------------+

+-----------------------------------------------------------------------------+
| Processes:                                                       GPU Memory |
| GPU        Owner      PID      Uptime  Process Name                   Usage |
+=============================================================================+
+-----------------------------------------------------------------------------+

可以看到略有区别的是,这里并不像nvidia-smi列出来的进程那么多,应该是自动忽略了系统进程。

单独查看驱动版本和显卡型号

在py3nvml中把查看驱动和型号的功能单独列了出来:

In [1]: from py3nvml.py3nvml import *
In [2]: nvmlInit()
Out[2]: <CDLL 'libnvidia-ml.so.1', handle 560ad4d07a60 at 0x7fd13aa52340>
In [3]: print("Driver Version: {}".format(nvmlSystemGetDriverVersion()))
Driver Version: 470.42.01
In [4]: deviceCount = nvmlDeviceGetCount()
   ...: for i in range(deviceCount):
   ...:     handle = nvmlDeviceGetHandleByIndex(i)
   ...:     print("Device {}: {}".format(i, nvmlDeviceGetName(handle)))
   ...:
Device 0: Quadro RTX 4000
Device 1: Quadro RTX 4000
In [5]: nvmlShutdown()

这样也不需要我们自己再去逐个的筛选,从灵活性和可扩展性上来说还是比较方便的。

单独查看显存信息

这里同样的也是把显存的使用信息单独列了出来,不需要用户再去单独筛选这个信息,相对而言比较细致:

In [1]: from py3nvml.py3nvml import *
In [2]: nvmlInit()
Out[2]: <CDLL 'libnvidia-ml.so.1', handle 55ae42aadd90 at 0x7f39c700e040>
In [3]: handle = nvmlDeviceGetHandleByIndex(0)
In [4]: info = nvmlDeviceGetMemoryInfo(handle)
In [5]: print("Total memory: {}MiB".format(info.total >> 20))
Total memory: 7979MiB
In [6]: print("Free memory: {}MiB".format(info.free >> 20))
Free memory: 7441MiB
In [7]: print("Used memory: {}MiB".format(info.used >> 20))
Used memory: 537MiB

如果把这些代码插入到程序中,就可以获悉每一步所占用的显存的变化。

总结概要

在深度学习或者其他类型的GPU运算过程中,对于GPU信息的监测也是一个非常常用的功能。如果仅仅是使用系统级的GPU监测工具,就没办法非常细致的去跟踪每一步的显存和使用率的变化。如果是用profiler,又显得过于细致,而且环境配置、信息输出和筛选并不是很方便。此时就可以考虑使用py3nvml这样的工具,针对于GPU任务执行的过程进行细化的分析,有助于提升GPU的利用率和程序执行的性能。

版权声明

本文首发链接为:https://www.cnblogs.com/dechinphy/p/py3nvml.html

作者ID:DechinPhy

更多原著文章请参考:https://www.cnblogs.com/dechinphy/

打赏专用链接:https://www.cnblogs.com/dechinphy/gallery/image/379634.html

腾讯云专栏同步:https://cloud.tencent.com/developer/column/91958

参考链接

https://zhuanlan.zhihu.com/p/31558973 “留一手”加剧内卷,“讲不清”浪费时间。

到此这篇关于py3nvml实现GPU相关信息读取的文章就介绍到这了,更多相关py3nvml GPU信息读取内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • py3nvml实现GPU相关信息读取的案例分析

    目录 技术背景 常规信息读取 py3nvml的安装与使用 py3nvml绑定GPU卡 查看空闲GPU 命令行信息获取 单独查看驱动版本和显卡型号 单独查看显存信息 总结概要 版权声明 参考链接 在深度学习或者其他类型的GPU运算过程中,对于GPU信息的监测也是一个非常常用的功能.如果仅仅是使用系统级的GPU监测工具,就没办法非常细致的去跟踪每一步的显存和使用率的变化.如果是用profiler,又显得过于细致,而且环境配置.信息输出和筛选并不是很方便.此时就可以考虑使用py3nvml这样的工具,针

  • Delphi实现获取进程列表及相关信息的实例

    Delphi实现获取进程列表及相关信息的实例 前言: 闲着没事,看着任务管理器好玩,查资料先简单实现一下,代码中没有加入获取CPU占用率的代码,这个代码网上很多,只是不喜欢那种写法,这里就不写了.以后继续完善,对于System Process和System的信息还没法获得,那位兄弟知道可以提个醒.  代码如下 unit Main; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls,

  • PHP获取音频文件的相关信息

    项目需求:现在有一个音频文件上传的功能,在上传后PHP需要获取这个音频文件的相关信息,例如:时长等,由于这个文件是放在买的空间上的,没有像ffmpeg这样的扩展来处理,那么PHP能不能获取到这些信息? 下面是之前在项目中用到的一个用PHP进行音频文件头部信息的读取与写入操作的实现,主要针对 WMA 和 MP3 两种格式,供参考. <?php // AudioExif.class.php // 用PHP进行音频文件头部信息的读取与写入 // 目前只支持 WMA 和 MP3 两种格式, 只支持常用的

  • php+ffmpeg如何获取视频缩略图、视频分辨率等相关信息

    目录 前言 下面介绍使用ffmpeg获取视频首帧的方法. FFmpeg获得视频文件的缩略图 Fmpeg读取视频信息 Fmpeg获得视频文件的总长度时间和创建时间 总结 前言 ffmpeg是一款开源.跨平台的视频处理程序,可用在Windows.mac.linux等平台,可以方便的运用多种语言脚本来调用其执行视频的操作. 下面介绍使用ffmpeg获取视频首帧的方法. <?php //待处理视频 $in_file = 'http://cdn.fintechuni.cn/video/2019/12/25

  • python利用winreg生成桌面路径及实现扫描二维码图片返回相关信息

    目录 一.winreg生成桌面路径 二.实现扫描二维码图片返回相关信息 1.模块准备 2.代码解析 3.代码展示 前言: 在平时敲代码过程中,我们会经常读取或者保存文件到桌面,你自己一个人使用倒还好,如果你将你的代码给别人使用,别人在使用过程中就很有可能因为找不到路径而报错,接着就要去更改路径相关的代码,这就显得比较麻烦. 这次分享一个桌面路径获取的函数,以后只要复制并调用这个函数就好. 一.winreg生成桌面路径 代码如下: import winreg def desktop_path():

  • JavaScript获取上传文件相关信息示例详解

    目录 前题场景 处理方式 图片文件 音频文件 判断处理 分析总结 前题场景 在开发过程中,文件上传是再熟悉不过的场景了,但是根据实际使用情况对上传文件的限制又各有不同.需要对本地上传文件进行相应的限制处理,防止不符合规则或者要求的文件上传到云存储中,从而造成云盘资源空间浪费. 与此同时,也在给客户端使用文件信息之前做了一次数据过滤处理,减少客户端对文件资源的处理和校验. 处理方式 因为客户端使用后台管理上传的图片文件和音频文件时,为了优化展示效果和加载的速度,所以在后台管理系统上传处希望依据图片

  • Go语言扫描目录并获取相关信息的方法

    本文实例讲述了Go语言扫描目录并获取相关信息的方法.分享给大家供大家参考.具体分析如下: 前言:最近看到Go里面有一个func很容易就可以扫描整个目录,并且可以得到相应的目录和文件信息,所以我将其进行了封装,拿到file info的所有信息 这样就可以方便的做其它用途了. 直接上代码,代码基于Go version 1 复制代码 代码如下: package main import (     "path/filepath"     "os"     "fla

  • Extjs 点击复选框在表格中增加相关信息行

    功能效果:点击复选框在表格中自动增加相关信息行,复选框取消则表格中内容自动删除 初始效果大概是这样~~~~~ // 定义初始 存放表格数据 var gridItems = []; //省份复选框 var $provinceCheckbox01 = new Ext.form.CheckboxGroup({ xtype: 'checkboxgroup', fieldLabel: '省份选择', labelWidth: 60, columns: 9, vertical: true, margin: '

  • IOS 通讯录信息读取兼容的实现方法

    IOS 通讯录信息读取兼容的实现方法 项目中有一个功能需要读取通讯录中联系人的手机.在iOS8以前都是可用的,主要使用如下三个代理方法来实现 - (void) peoplePickerNavigationControllerDidCancel:(ABPeoplePickerNavigationController *)peoplePicker - (BOOL) peoplePickerNavigationController:(ABPeoplePickerNavigationController

  • Android实现获取应用程序相关信息列表的方法

    本文所述为Androdi获取手机应用列表的方法,比如获取到Android应用的软件属性.大小和应用程序路径.应用名称等,获取所有已安装的Android应用列表,包括那些卸载了的,但没有清除数据的应用程序,同时在获取到应用信息的时候,判断是不是系统的应用程序,这是一个应用管理器所必需具备的功能. 具体实现代码如下: //AppInfoProvider.java package com.xh.ui; import java.util.ArrayList; import java.util.List;

随机推荐