なぜGPUメモリ帯域幅の測定がLLMコスト最適化の第一歩なのか
LLM(大規模言語モデル)を運用していると、GPU Utilizationが30〜40%で頭打ちになるケースが多々あります。「GPUが遊んでいる?」と思いきや、実際はメモリ帯域幅がボトルネックとなり、演算ユニットがデータを待っている状態です。特にマルチGPU環境でモデル並列化やテンソル並列化を適用する場合、GPU間のデータ転送速度が推論レイテンシを決定づけます。
そこで役立つのがNVIDIAが公開したNVbandwidthです。これはCUDAベースのベンチマークツールで、GPUシステムのメモリ転送特性を精密に診断できます。本ツールで以下の測定が可能です:
- CPU → GPU (Host to Device, H2D)
- GPU → CPU (Device to Host, D2H)
- GPU ↔ GPU (Device to Device, D2D)
- 単方向/双方向/マルチノード転送
本記事ではNVbandwidthのインストールから実戦活用までをコード付きでステップバイステップに解説します。併せてLLM推論コスト爆弾?NVIDIA RunaiとNIMでGPU利用率を2倍にする方法もご参照ください。

NVbandwidthのインストールと基本使用法
システム要件
- CUDA 11.x以上(シングルノード)、CUDA 12.3 + ドライバ550+(マルチノード)
- C++17対応コンパイラ(GCC 7.x以上)
- CMake 3.20+(3.24推奨)
- Boost program optionsライブラリ
ビルド手順
# リポジトリをクローン
git clone https://github.com/NVIDIA/nvbandwidth.git
cd nvbandwidth
# CMakeビルド
mkdir build && cd build
cmake .. -DCMAKE_BUILD_TYPE=Release
make -j$(nproc)
# 実行ファイル確認
./nvbandwidth --help
基本実行:システム全体の帯域幅測定
# 全テスト実行(デフォルト)
./nvbandwidth
# 特定テストのみ実行:Device to Device(Copy Engine、単方向)
./nvbandwidth -t device_to_device_memcpy_read_ce -b 1024 -i 10 -j
オプション解説:
-t: テスト名(全一覧は--help)-b: バッファサイズ(MiB単位、デフォルト256)-i: 繰り返し回数(デフォルト5)-j: JSON形式で出力
出力例の読み方
Running host_to_device_memcpy_ce.
memcpy CE CPU(row) -> GPU(column) bandwidth (GB/s)
0 1
0 55.63 55.64
SUM host_to_device_memcpy_ce 111.27
COEFFICIENT_OF_VARIATION host_to_device_memcpy_ce 0.00
55.63 GB/s: GPU 0への単一ストリーム帯域幅SUM 111.27: 2ストリーム合計(双方向ではなく単純合計)COEFFICIENT_OF_VARIATION: 変動係数(0に近いほど安定)
💡 実務のコツ: LLMサービングではモデル並列化時のGPU間P2P帯域幅が重要です。
device_to_device_memcpy_read_ceテストでNVLink帯域幅を確認しましょう。もしPCIe経由でデータが流れていると帯域幅が半分以下に低下する可能性があります。

高度な活用:マルチノードおよび双方向テスト
双方向帯域幅の測定
双方向テストはデータが同時に双方向に流れるときの実効帯域幅を測定します。LLM学習時のgradient all-reduceなどcollective communicationの性能予測に必須です。
# Device to Device 双方向(Copy Engine)
./nvbandwidth -t device_to_device_memcpy_bidirect_ce -b 1024 -i 10
マルチノード設定(MNNVL環境)
NVIDIA Multi-Node NVLink(MNNVL)システムでノード間帯域幅を測定するには追加設定が必要です。
# 1. IMEXサービスの起動
sudo systemctl start nvidia-imex.service
# 2. ノード設定ファイル作成(/etc/nvidia-imex/nodes_config.cfg)
node1 slots=4
node2 slots=4
# 3. MPI実行
mpirun --allow-run-as-root --map-by ppr:4:node --bind-to core \
-np 8 --report-bindings \
-q -mca btl_tcp_if_include enP5p9s0 \
--hostfile /etc/nvidia-imex/nodes_config.cfg \
./nvbandwidth -p multinode
マルチノード出力例(8GPU、2ノード):
memcpy CE GPU(row) -> GPU(column) bandwidth (GB/s)
0 1 2 3 4 5 6 7
0 N/A 397.4 397.4 397.6 397.5 397.5 397.7 397.6
1 397.7 N/A 397.4 397.5 397.5 397.5 397.5 397.6
...
⚠️ 注意点: マルチノードテストは同一NVLinkドメインに属するノード間でのみ実行可能です。IMEXサービスが正常に動作していないとPCIe経由のフォールバックが発生し、帯域幅が急減します。また、マルチノードモードはCUDA 12.3以上でのみサポートされます。

実務適用:NVbandwidthでLLMインフラを診断する
ステップ1:ベースライン測定
新しいGPUクラスタを導入したときやドライバ/ファームウェアを更新した際は、変更前後でNVbandwidthを実行し帯域幅の変化を記録しましょう。想定より低い数値が出た場合はハードウェア障害やドライバ設定ミスを疑えます。
ステップ2:ボトルネックの特定
LLMサービング中にGPU Utilizationが低い場合、以下をチェック:
- モデル並列化使用時: GPU間P2P帯域幅は十分か?(NVLink vs PCIe)
- データローディングボトルネック: H2D帯域幅がCPUメモリ帯域幅より低いか?
- マルチノード: ノード間帯域幅が単一ノード内NVLink帯域幅の1/10以下ならネットワークトポロジの再検討が必要
ステップ3:最適化の方向性
NVbandwidthの結果に基づき、以下の最適化を検討:
- Copy Engine vs SM Copy: SM copyは演算ユニットを使用するため学習中は避け、推論専用ノードでのみ使用
- バッファサイズ調整: 小バッファ(1MB以下)ではレイテンシが支配的になるため、大きなバッチを使用して帯域幅の利用効率を向上
- GPUフレンドリなデータレイアウト:
cudaMemcpyAsyncとストリームを活用しデータ転送と演算をオーバーラップ
合わせて読みたい記事
次のステップ
NVbandwidthで帯域幅を測定したら、次はNVIDIA Nsight Computeでカーネルレベルのメモリアクセスパターンを分析し、NCCLのall-reduce性能をプロファイリングすることをお勧めします。実際のLLM学習/推論パイプラインにおけるエンドツーエンドの性能最適化へと進みましょう。