Warning: Undefined variable $position in /home/pystyles/pystyle.info/public_html/wp/wp-content/themes/lionblog/functions.php on line 4897

nvidia-smi で GPU の使用状況を確認する方法

nvidia-smi で GPU の使用状況を確認する方法

概要

GPU の使用状況を確認する nvidia-smi コマンドの使い方について解説します。

nvidia-smi

nvidia-smi コマンドで以下の情報が確認できます。公式ドキュメントは nvidia-smi.txt にあります。

  • GPU の種類 (GPU Name)
  • Nvidia ドライバのバージョン (Driver Version)
  • CUDA のバージョン (CUDA Version)
  • GPU のファンの回転率 (Fan)
  • GPU の温度 (Temp)
  • 電源使用量 (Pwr:Usage/Cap)
  • GPU 利用率 (GPU-Util)
Thu Dec 16 02:45:58 2021       
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 450.119.03   Driver Version: 450.119.03   CUDA Version: 11.0     |
|-------------------------------+----------------------+----------------------+
| 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  GeForce GTX 1080    Off  | 00000000:01:00.0 Off |                  N/A |
| 27%   30C    P8     6W / 180W |     36MiB /  8117MiB |      0%      Default |
|                               |                      |                  N/A |
+-------------------------------+----------------------+----------------------+

+-----------------------------------------------------------------------------+
| Processes:                                                                  |
|  GPU   GI   CI        PID   Type   Process name                  GPU Memory |
|        ID   ID                                                   Usage      |
|=============================================================================|
+-----------------------------------------------------------------------------+

csv 形式で出力する

--format=csv 引数を指定し、--query-gpu に表示するカラム名の一覧をカンマ区切りで記載することで、CSV 形式で出力できます。

$ nvidia-smi --query-gpu=index,name,memory.total --format=csv,noheader,nounits
0, GeForce GTX 1080, 8117
カラム名 意味
timestamp タイムスタンプ
driver_version ドライバのバージョン
count GPU の数
name or gpu_name GPU の製品名
serial or gpu_serial GPU のシリアルナンバー
index GUI ID
fan.speed ファンの回転スピード
memory.total GPU の合計メモリ量
memory.used GPU の使用中のメモリ量
memory.free GPU の未使用のメモリ量
utilization.gpu GPU の使用率
utilization.memory GPU メモリの使用率
temperature.gpu GPU の温度
temperature.memory GPU メモリの温度

GPU の使用状況を CSV で記録する Python スクリプト

Python で nvidia-smi で取得した情報を逐次 CSV に出力するスクリプトを作成しました。 実行すると、<GPU_NO>_<GPU_NAME>.csv という名前の CSV ファイルに指定した FPS で使用状況が出力されます。

In [ ]:
import subprocess
import time
from io import StringIO

import pandas as pd

##################################################
# 設定
##################################################

# FPS
fps = 5.0

# CSV に出力するカラム一覧
keys = [
    "timestamp",
    "memory.total",
    "memory.free",
    "memory.used",
    "utilization.gpu",
    "utilization.memory",
    "temperature.gpu",
]


def get_gpu_specs():
    spec_keys = [
        "index",
        "name",
        "memory.total",
    ]

    output = get_gpu_info(spec_keys)
    output = pd.read_csv(StringIO(output), names=spec_keys)

    return output


def get_gpu_info(keys=keys, no_units=True):
    queries = ",".join(keys)
    output_fmt = "csv,noheader"
    if no_units:
        output_fmt += ",nounits"

    cmd = f"nvidia-smi --query-gpu={queries} --format={output_fmt}"
    output = subprocess.check_output(cmd, shell=True).decode()
    output = output.replace(", ", ",")  # カンマの後の空白を削除する

    return output


# GPU の一覧を取得する。
gpu_specs = get_gpu_specs()

files = []
for spec in gpu_specs.itertuples():
    name = f"{spec.index}_{spec.name}.csv"
    f = open(name, "w")
    files.append(f)

    # ヘッダーを書き込む。
    f.write(",".join(keys) + "\n")


while True:
    start_time = time.time()

    # GPU の情報を取得する。
    output = get_gpu_info(keys)

    # ファイルに追記する。
    for f, line in zip(files, output.splitlines()):
        f.write(line + "\n")
        f.flush()

    elapsed_time = time.time() - start_time
    wait_time = 1 / fps - elapsed_time
    time.sleep(wait_time)