如何在 Python 中获取每秒的 GPU 使用情况



我有一个由tensorflow-gpu运行的模型,我的设备是nvidia。我想列出每秒的GPU使用情况,这样我就可以测量平均/最大GPU使用情况。我可以手动打开两个终端,一个是运行模型,另一个是通过nvidia-smi -l 1进行测量。当然,这不是一个好办法。我还试着用Thread来做这件事,就在这里。

import subprocess as sp
import os
from threading import Thread
class MyThread(Thread):
def __init__(self, func, args):
super(MyThread, self).__init__()
self.func = func
self.args = args
def run(self):
self.result = self.func(*self.args)
def get_result(self):
return self.result
def get_gpu_memory():
output_to_list = lambda x: x.decode('ascii').split('n')[:-1]
ACCEPTABLE_AVAILABLE_MEMORY = 1024
COMMAND = "nvidia-smi -l 1 --query-gpu=memory.used --format=csv"
memory_use_info = output_to_list(sp.check_output(COMMAND.split()))[1:]
memory_use_values = [int(x.split()[0]) for i, x in enumerate(memory_use_info)]
return memory_use_values
def run():
pass
t1 = MyThread(run, args=())
t2 = MyThread(get_gpu_memory, args=())
t1.start()
t2.start()
t1.join()
t2.join()
res1 = t2.get_result()

然而,这并不会返回每秒的使用情况。有好的解决方案吗?

在命令nvidia-smi -l 1 --query-gpu=memory.used --format=csv

-l代表:

-l,--loop=按指定的秒间隔探测到Ctrl+C

因此命令:

COMMAND = 'nvidia-smi -l 1 --query-gpu=memory.used --format=csv'
sp.check_output(COMMAND.split())

永远不会终止和返回。

如果您将命令(nvidia-smi(中的事件循环删除到python中,它就会起作用。

这是代码:

import subprocess as sp
import os
from threading import Thread , Timer
import sched, time
def get_gpu_memory():
output_to_list = lambda x: x.decode('ascii').split('n')[:-1]
ACCEPTABLE_AVAILABLE_MEMORY = 1024
COMMAND = "nvidia-smi --query-gpu=memory.used --format=csv"
try:
memory_use_info = output_to_list(sp.check_output(COMMAND.split(),stderr=sp.STDOUT))[1:]
except sp.CalledProcessError as e:
raise RuntimeError("command '{}' return with error (code {}): {}".format(e.cmd, e.returncode, e.output))
memory_use_values = [int(x.split()[0]) for i, x in enumerate(memory_use_info)]
# print(memory_use_values)
return memory_use_values

def print_gpu_memory_every_5secs():
"""
This function calls itself every 5 secs and print the gpu_memory.
"""
Timer(5.0, print_gpu_memory_every_5secs).start()
print(get_gpu_memory())
print_gpu_memory_every_5secs()
"""
Do stuff.
"""

这里有一种获得输出的更基本的方法,但同样有效——我认为更容易理解。我添加了一个小的10值缓存,以获得良好的最近平均值,并将检查时间增加到每秒。它输出最后10秒的平均值和每秒的当前值,因此可以识别导致使用的操作(我认为最初的问题是什么(。

import subprocess as sp
import time
memory_total=8192 #found with this command: nvidia-smi --query-gpu=memory.total --format=csv
memory_used_command = "nvidia-smi --query-gpu=memory.used --format=csv"
isolate_memory_value = lambda x: "".join(y for y in x.decode('ascii') if y in "0123456789")
def main():
percentage_cache = []
while True:
memory_used = isolate_memory_value(sp.check_output(memory_used_command.split(), stderr=sp.STDOUT))
percentage = float(memory_used)/float(memory_total)*100
percentage_cache.append(percentage)
percentage_cache = percentage_cache[max(0, len(percentage_cache) - 10):]
print("curr: " + str(percentage) + " %", "navg:  " + str(sum(percentage_cache)/len(percentage_cache))[:4] + " %n")
time.sleep(1)
main()

尝试pip install nvidia-ml-py3:

import nvidia_smi
nvidia_smi.nvmlInit()
deviceCount = nvidia_smi.nvmlDeviceGetCount()
for i in range(deviceCount):
handle = nvidia_smi.nvmlDeviceGetHandleByIndex(i)
util = nvidia_smi.nvmlDeviceGetUtilizationRates(handle)
mem = nvidia_smi.nvmlDeviceGetMemoryInfo(handle)
print(f"|Device {i}| Mem Free: {mem.free/1024**2:5.2f}MB / {mem.total/1024**2:5.2f}MB | gpu-util: {util.gpu/100.0:3.1%} | gpu-mem: {util.memory/100.0:3.1%} |")

参考:如何通过代码获得GPU使用率?

最新更新