サーバのどのGPUが空いてるか調べたい→プログラムからGPU使用率とか取れないのかな〜と思ってちょっと調べたらいつも使っているnvidia-smi
コマンドはオプション次第でマシンリーダブルな出力を出してくれそうなことがわかりました。
--query-gpuオプション
--query-gpu
オプションは欲しい情報を並べるとそれをとってきて--format
オプションで指定した出力スタイルに加工して出力してくれます。
たとえば以下のような情報を指定することができるようです。
- index: 0からはじまるハードウェアのマシン上の番号, "0"とか"1"とか
- memory.free: 空きGPUメモリ量, "5123 MiB" とか
- memory.used: 使用GPUメモリ量, "3451 MiB" とか
- memory.total: GPUに搭載されているメモリ量, "8113 MiB" とか
- utilization.gpu: GPU使用率, "12 %" とか
- utilization.memory: GPUメモリ使用率, "49 %" とか
- timestamp: nvidia-smiコマンドが実行された時間, "2016/12/16 22:05:43.771" とか
- uuid: グローバルにユニークな変化しないID。GPUに貼られてる番号とかは関係ないらしい, "GPU-92275dc5-b7cc-1a5f-0348-f389e3040f2b" とか
他にもいろいろキーがあるのでnvidia-smi --help-query-gpu
で確かめてみてください。
--formatオプション
--query-gpu
で指定した情報をCSVに吐き出すために使用します。--format=csv
が一番シンプルな呼び出し方ですが、noheader
とnounits
も指定することができます。
-
noheader
: CSVの一番最初の行としてヘッダ行が出てこなくなる -
nounits
: たとえばGPU利用率(utlization.gpu)を取得したとき "10 %" となるのが "10" になる
これらを組み合わせて --format=csv,noheader
とか --format=csv,noheader,nounits
とできます。
Pythonでnvidia-smiの情報を取得する関数
import subprocess
import json
DEFAULT_ATTRIBUTES = (
'index',
'uuid',
'name',
'timestamp',
'memory.total',
'memory.free',
'memory.used',
'utilization.gpu',
'utilization.memory'
)
def get_gpu_info(nvidia_smi_path='nvidia-smi', keys=DEFAULT_ATTRIBUTES, no_units=True):
nu_opt = '' if not no_units else ',nounits'
cmd = '%s --query-gpu=%s --format=csv,noheader%s' % (nvidia_smi_path, ','.join(keys), nu_opt)
output = subprocess.check_output(cmd, shell=True)
lines = output.decode().split('\n')
lines = [ line.strip() for line in lines if line.strip() != '' ]
return [ { k: v for k, v in zip(keys, line.split(', ')) } for line in lines ]
import pprint
pprint.pprint(get_gpu_info())
こんな感じで動きました。
- 第一引数(
nvidia_smi_path
):nvidia-smi
コマンドのパスを絶対パスなどで指定したい場合にセットしてください。デフォルトでは'nvidia-smi'
になっています。 - 第二引数(
keys
): 取得したい情報を各要素が文字列のlist
またはtuple
オブジェクトで指定してください。デフォルトではコード中のDEFAULT_ATTRIBUTES
にリストされている内容になっています。 - 第三引数(
no_units
) : 各キーの値に単位を含めたいかどうかをbool
でセットしてください。デフォルトではTrue
になっており、単位は省かれます。 - 返り値:
- GPUユニット個数分の
dict
要素を持つlist
オブジェクト -
dict
の各キーは第二引数で指定したもの -
dict
の各値はバイト文字列(index
やutilization.gpu
を数値として扱いたい場合はint()
かけてください)
- GPUユニット個数分の
これでslack
などでbot gpu status
とかたずねるとGPU利用状況を教えてくれるbotが簡単に作れそうですね。
Enjoy!