nvidia-smi

## 1. はじめに：`nvidia-smi`とは何か？

`nvidia-smi` は、NVIDIA GPUの監視と管理を行うためにNVIDIAが提供しているコマンドラインツールです。NVIDIAドライバパッケージに同梱されており、Linux、Windows、macOS (NVIDIAドライバがサポートする範囲で) など、主要なオペレーティングシステムで利用可能です。

技術者にとって `nvidia-smi` が不可欠な理由は多岐にわたります：
*   **GPUの健康状態の確認**: 温度、消費電力、エラー状況などを把握し、ハードウェアの問題を早期に発見できます。
*   **パフォーマンスのモニタリング**: GPU使用率やメモリ使用量をリアルタイムで監視し、アプリケーションのパフォーマンスボトルネックを特定する手がかりを得られます。
*   **リソース割り当ての最適化**: 複数のGPUが搭載されたシステムで、各GPUの負荷状況を確認し、効率的なリソース割り当てを支援します。
*   **トラブルシューティング**: GPUが期待通りに動作しない場合の原因究明に役立ちます。

## 2. 基本的な使い方：一目でわかるGPUステータス

最も基本的な使い方は、ターミナルまたはコマンドプロンプトで単に `nvidia-smi` と入力することです。

```bash
nvidia-smi
```

これにより、システムに搭載されているNVIDIA GPUに関するサマリー情報が表示されます。以下は典型的な出力例とその主要項目の解説です。

```
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 510.47.03    Driver Version: 510.47.03    CUDA Version: 11.6     |
|-------------------------------+----------------------+----------------------+
| 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  NVIDIA GeForce ...  On   | 00000000:01:00.0 Off |                  N/A |
| 30%   35C    P8    15W / 170W |    243MiB /  8192MiB |      0%      Default |
|                               |                      |                  N/A |
+-------------------------------+----------------------+----------------------+
|   1  NVIDIA A100-SXM...  On   | 00000000:81:00.0 Off |                    0 |
| N/A   40C    P0    55W / 400W |   1024MiB / 40960MiB |     10%      Default |
|                               |                      |                  N/A |
+-------------------------------+----------------------+----------------------+

+-----------------------------------------------------------------------------+
| Processes:                                                                  |
|  GPU   GI   CI        PID   Type   Process name                  GPU Memory |
|        ID   ID                                                   Usage      |
|=============================================================================|
|    0   N/A  N/A      1234      G   /usr/lib/xorg/Xorg                  10MiB |
|    0   N/A  N/A      2345      C   python                            220MiB |
|    1   N/A  N/A      3456      C   ./my_cuda_app                    1000MiB |
+-----------------------------------------------------------------------------+
```

**主要項目の解説:**

*   **Driver Version**: インストールされているNVIDIAドライバのバージョン。
*   **CUDA Version**: ドライバがサポートする最新のCUDAバージョン。これは、実際にシステムにインストールされているCUDA Toolkitのバージョンとは異なる場合があります。アプリケーションが必要とするCUDA Toolkitバージョンがこれ以下であれば、基本的には動作可能です。
*   **GPU**: GPUのインデックス番号 (0から始まる)。
*   **Name**: GPUのモデル名 (例: `NVIDIA GeForce RTX 3080`, `NVIDIA A100`)。
*   **Persistence-M**: 永続モード (Persistence Mode) の状態 (On/Off)。詳細は後述。
*   **Bus-Id**: GPUが接続されているPCIバスID。
*   **Disp.A**: ディスプレイがこのGPUに接続され、アクティブかどうか (On/Off)。 (一部ヘッドレスサーバー用GPUではN/A)。
*   **Fan**: ファンスピード (%)。 (水冷モデルや一部サーバーGPUではN/A)。
*   **Temp**: GPUコアの現在温度 (摂氏)。
*   **Perf**: パフォーマンス状態 (P-State)。P0 (最大性能) から P12 (最小アイドル電力) などの値を取ります。負荷に応じて動的に変化します。
*   **Pwr:Usage/Cap**: 現在の消費電力 (Usage) と、GPUの定格最大消費電力 (Cap) (ワット単位)。
*   **Memory-Usage**: 現在使用中のGPUメモリ量と、総GPUメモリ量 (例: `243MiB / 8192MiB`)。
*   **GPU-Util**: GPUコアの使用率 (%)。
*   **Compute M.**: コンピュートモード (Default, Exclusive_Process, Prohibitedなど)。詳細は後述。
*   **Processes**: 現在そのGPUを使用しているプロセスの一覧。PID、プロセスタイプ (G: Graphics, C: Compute)、プロセス名、使用GPUメモリ量などが表示されます。

この基本表示だけで、GPUの全体的な状態や負荷状況を素早く把握できます。

## 3. 詳細情報の照会：`query` オプションでピンポイントに

`nvidia-smi` は、`-q` または `--query` オプションを使用することで、より詳細な情報をピンポイントで取得できます。

### 特定のGPUの情報を表示

複数のGPUが搭載されているシステムで、特定のGPUの情報のみを表示したい場合は、`-i <gpu_index>` オプションを使用します。

```bash
nvidia-smi -i 0 -q
```
上記はGPUインデックス0番のGPUに関する全情報を表示します。

### 表示項目を指定して情報を取得

`--query-gpu=<params>` と `--format=<format_options>` を組み合わせることで、必要な情報だけを整形して出力できます。これはスクリプト処理やログ取得に非常に便利です。

**例：GPU名、温度、使用率、メモリ使用量（合計、空き、使用中）をCSV形式でヘッダなし、単位なしで表示**
```bash
nvidia-smi --query-gpu=name,temperature.gpu,utilization.gpu,memory.total,memory.free,memory.used --format=csv,noheader,nounits
```
出力例:
```
NVIDIA GeForce RTX 3080,35,0,8192,7949,243
NVIDIA A100-SXM4-40GB,40,10,40960,39936,1024
```

**主要なクエリパラメータ (抜粋):**
*   `timestamp`: タイムスタンプ
*   `driver_version`: ドライババージョン
*   `name` or `gpu_name`: GPU名
*   `pci.bus_id` or `gpu_bus_id`: PCIバスID
*   `temperature.gpu`: GPU温度
*   `utilization.gpu`: GPU使用率
*   `utilization.memory`: メモリ帯域使用率
*   `memory.total`: 総GPUメモリ
*   `memory.free`: 空きGPUメモリ
*   `memory.used`: 使用中GPUメモリ
*   `power.draw`: 消費電力
*   `power.limit`: 最大消費電力設定
*   `clocks.gr` (Graphics Clock), `clocks.sm` (SM Clock), `clocks.mem` (Memory Clock): 各クロック周波数
*   `pstate`: パフォーマンス状態
*   ECC関連: `ecc.errors.corrected.volatile.device_memory` (訂正可能ECCエラー数)など

利用可能な全パラメータは `nvidia-smi --help-query-gpu` で確認できます。

### XML形式での出力

`-x` または `--xml-format` オプションを使用すると、情報をXML形式で出力します。プログラムでパースする際に便利です。

```bash
nvidia-smi -q -x
```

### カテゴリ指定での情報表示

`-d <TYPE>` オプションで、特定のカテゴリの情報（例: `MEMORY`, `UTILIZATION`, `TEMPERATURE`, `CLOCK`, `POWER`, `ECC`など）をまとめて表示できます。

```bash
nvidia-smi -q -d MEMORY,POWER
```

## 4. リアルタイムモニタリング：GPUの動向をライブで把握

GPUの負荷状況や温度変化をリアルタイムで追跡したい場合、`nvidia-smi` のループ機能が役立ちます。

*   **`-l <seconds>` または `--loop=<seconds>`**: 指定した秒数ごとに情報を更新表示します。
    ```bash
    nvidia-smi -l 1  # 1秒ごとに更新
    ```
*   **`-lms <milliseconds>` または `--loop-ms=<milliseconds>`**: ミリ秒単位で更新表示します。より高頻度な監視が可能です。
    ```bash
    nvidia-smi -lms 500  # 500ミリ秒 (0.5秒) ごとに更新
    ```

これらループオプションは、前述の `--query-gpu` や `--format` と組み合わせることができます。

**例：1秒ごとにGPU使用率と使用メモリ量をCSV形式で `gpu_stats.csv` に追記**
```bash
nvidia-smi --query-gpu=timestamp,utilization.gpu,memory.used,temperature.gpu --format=csv,noheader -l 1 >> gpu_stats.csv
```
※ `>>` で追記。初回は `>` で新規作成が良いでしょう。

LinuxやmacOSでは、`watch` コマンドと組み合わせる方法も一般的です。
```bash
watch -n 1 nvidia-smi  # 1秒ごとに nvidia-smi の出力を更新
```

## 5. GPUの管理と設定変更 (限定的)：管理者権限が必要な操作

`nvidia-smi` は主にモニタリングツールですが、いくつかのGPU設定を変更する機能も持っています。これらの操作の多くは管理者権限（Linuxでは `sudo`）が必要です。

*   **永続モード (Persistence Mode)**
    GPUドライバがアンロードされないように、常にロードされた状態を維持するモードです。これにより、GPUを使用するアプリケーションの起動が高速化されることがあります。特にサーバー環境で推奨されます。
    ```bash
    sudo nvidia-smi -pm 1  # 永続モードを有効化
    sudo nvidia-smi -pm 0  # 永続モードを無効化 (デフォルト)
    ```
    現在の状態は `nvidia-smi` の基本出力 (`Persistence-M` の項目) で確認できます。

*   **コンピュートモード (Compute Mode)**
    GPUをCUDAアプリケーションでどのように使用するかを設定します。
    ```bash
    sudo nvidia-smi -c <MODE_ID>
    ```
    `<MODE_ID>` の主な値:
    *   `0` (Default): 複数のプロセス/コンテキストがGPUを共有可能。
    *   `3` (Exclusive_Process): 1つのプロセスのみがGPU上でコンテキストを保持可能。他のプロセスからの利用を排他する。HPC環境などで特定ジョブにGPUを専有させたい場合に利用。
    *   `2` (Prohibited): CUDAコンテキストの作成を禁止。GPUをグラフィックス専用にする。

    現在の設定は `nvidia-smi -q -d COMPUTE` または基本出力 (`Compute M.` の項目) で確認できます。

*   **アプリケーションクロックの設定 (一部GPU、上級者向け)**
    特定のアプリケーション実行中にGPUのグラフィックスクロックとメモリクロックを固定値に設定できます。
    ```bash
    sudo nvidia-smi -ac <mem_clock>,<graphics_clock>  # 例: sudo nvidia-smi -ac 2000,1500
    sudo nvidia-smi -rac  # アプリケーションクロック設定をリセット
    ```
    **注意**: 通常、GPU Boost機能が自動的にクロックを最適化するため、専門的な知識なしにこの設定を変更することは推奨されません。パフォーマンスが悪化する可能性もあります。

*   **Power Limit の設定 (一部GPU)**
    GPUの最大消費電力を制限できます。
    ```bash
    sudo nvidia-smi -pl <power_limit_watts>  # 例: sudo nvidia-smi -pl 150
    ```
    設定可能な範囲は `nvidia-smi -q -d POWER` で確認できます (`Min Power Limit`, `Max Power Limit`)。電力供給が限られている環境や、熱管理のために意図的にパフォーマンスを抑制したい場合に利用します。

*   **GPUリセット**
    GPUがハングアップしたり、不安定になったりした場合の最終手段として、GPUをリセットできます。
    ```bash
    sudo nvidia-smi --gpu-reset -i <gpu_index>
    ```
    **注意**: この操作はGPU上で実行中のすべてのアプリケーションを強制終了させます。データ損失の可能性があるため、慎重に使用してください。

## 6. 実践的活用シナリオとトラブルシューティング

`nvidia-smi` は、日々の運用や開発における様々なシナリオで役立ちます。

*   **GPUの正常性確認**:
    *   `nvidia-smi` を実行し、目的のGPUがリストに表示されるか？
    *   ドライババージョンは適切か？
    *   温度 (`Temp`) が異常に高くないか？ (一般的に80-85℃以上が連続する場合は冷却や負荷の見直しを検討)
    *   ECCエラー (表示があれば `Volatile Uncorr. ECC`) が発生していないか？ (訂正不可能なエラーはハードウェア障害の可能性)
*   **パフォーマンスボトルネックの調査**:
    *   機械学習のトレーニングや推論実行中に `GPU-Util` が低い場合: CPUバウンド (データ前処理が追いついていない)、I/Oバウンド (ディスクからのデータ読み込みが遅い)、データローダのパイプラインに問題がある可能性などが考えられます。
    *   `Memory-Usage` が常に上限に近い場合: バッチサイズを小さくする、モデルのサイズを見直す、不要なテンソルを解放するなどの対策が必要です。
    *   `Perf` (P-State) が負荷をかけてもP0 (最大性能) にならない場合: 電力設定 (`Pwr:Usage/Cap` を確認)、温度スロットリング、ドライバの問題などを疑います。
*   **メモリリークの特定**:
    長時間アプリケーションを実行中に `Memory-Usage` が徐々に増加し続け、最終的にメモリ不足エラーで停止する場合、アプリケーションコード内のメモリリークが疑われます。`nvidia-smi` でプロセスごとのメモリ使用量を確認し、原因となるプロセスを特定します。
*   **複数GPU環境でのリソース管理**:
    `CUDA_VISIBLE_DEVICES` 環境変数で特定のGPUをプロセスに割り当てる際、`nvidia-smi` で各GPUの現在の負荷状況 (`GPU-Util`, `Memory-Usage`) を確認し、空いているGPUを選択するのに役立ちます。
*   **Dockerコンテナ内でのGPU利用確認**:
    NVIDIA Container Toolkit (`nvidia-docker2`) を使用してDockerコンテナにGPUを割り当てた後、コンテナ内で `nvidia-smi` を実行することで、コンテナからGPUが正しく認識され、利用されているかを確認できます。

## 7. `nvidia-smi`の限界と関連ツール

`nvidia-smi` は非常に便利ですが、万能ではありません。より詳細な分析やGUIでの操作には、他のツールを検討しましょう。

*   **詳細なパフォーマンスプロファイリング**:
    `nvidia-smi` はGPU全体のサマリー情報を提供しますが、個々のCUDAカーネルの実行時間、API呼び出しのトレース、レイテンシの詳細など、アプリケーションレベルの深い分析には不向きです。
    *   **NVIDIA Nsight Systems**: アプリケーション全体のパフォーマンスをシステムレベル (CPU, GPU, OSイベント) で分析し、ボトルネックを特定します。
    *   **NVIDIA Nsight Compute**: CUDAカーネルの非常に詳細なパフォーマンスメトリクスを収集し、カーネルレベルの最適化を支援します。
*   **グラフィカルな設定ツール**:
    *   **`nvidia-settings`** (Linux): X Window System 環境で、クロック周波数、ファン制御 (対応GPUのみ)、ディスプレイ設定などをGUIで行えるツールです。
*   **NVML (NVIDIA Management Library)**:
    `nvidia-smi` は、このNVMLライブラリのラッパーとして機能しています。NVMLはC言語のAPIを提供し、Pythonバインディング (例: `pynvml`) も存在するため、自作の監視スクリプトや管理ツールからプログラム的にGPU情報を取得・制御することが可能です。

## 8. まとめ：`nvidia-smi`を使いこなすために

`nvidia-smi` によりGPUの健康状態の把握、パフォーマンスの監視、基本的なトラブルシューティング、さらにはリソース管理まで、幅広いタスクに対応できます。