なぜ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倍にする方法もご参照ください。

NVIDIA GPU server rack with NVLink interconnect cables for high-bandwidth memory transfer

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経由でデータが流れていると帯域幅が半分以下に低下する可能性があります。

Developer running NVbandwidth CLI tool on terminal showing bandwidth measurement results in GB/s Technical Structure Concept

高度な活用:マルチノードおよび双方向テスト

双方向帯域幅の測定

双方向テストはデータが同時に双方向に流れるときの実効帯域幅を測定します。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以上でのみサポートされます。

Diagram of multi-node GPU cluster with NVLink and PCIe interconnects for distributed LLM inference Dev Environment Setup

実務適用: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学習/推論パイプラインにおけるエンドツーエンドの性能最適化へと進みましょう。

本コンテンツは、信頼性の高い情報源をもとにAIツールを活用して作成され、編集者によるレビューを経て公開されています。専門家によるアドバイスの代替となるものではありません。