GPUメモリとは何か、なぜLLM推論に重要なのか
本記事では、LLM推論におけるGPUメモリ(VRAM)の役割を詳しく解説。モデル重み、KVキャッシュ、オーバーヘッドなどのメモリ消費要因を説明し、メモリ見積もり式を提供。さらに、量子化、分散推論、KVキャッシュ最適化などの戦略を紹介し、BentoML推論プラットフォームがこれらの最適化をいかに簡素化するかを示します。
GPUメモリ(VRAM)は、大規模言語モデル(LLM)の推論において、スループット、レイテンシ、コンテキスト長、同時実行能力を左右する重要なリソースです。多くのチームは、モデルの重みがVRAMに収まっているにもかかわらず、推論開始後にOOM(メモリ不足)エラーに遭遇します。本記事はBentoMLの技術ブログに基づき、GPUメモリの動作原理、LLM推論におけるメモリ消費パターン、および最適化戦略を解説します。
GPUメモリの基礎 GPUメモリは通常、専用のVRAM(HBM3やGDDR6Xなど)を指し、非常に高い帯域幅(例:NVIDIA H200は4.8 TB/s)を持ちます。VRAMはGPU専用で、CPUと共有されず、モデル重み、活性化値、KVキャッシュの格納に使用されます。統合GPU(Intel IrisやApple Mシリーズなど)はシステムメモリを共有する場合がありますが、データセンターGPU(A100やH200)は専用VRAMに完全に依存します。共有GPUメモリとは、VRAM不足時にシステムRAMから動的に割り当てられるメモリですが、LLM推論では通常、専用VRAMのみを考慮します。
LLM推論におけるメモリ消費 推論中、GPUメモリは主に以下の3つで消費されます:
- モデル重み:すべてのパラメータを読み込むのに必要なメモリ。たとえば、70BパラメータのFP16モデルには140 GBが必要です。重みメモリはパラメータ数×パラメータあたりのバイト数で概算できます。
- KVキャッシュ:プリフィルおよびデコード段階で、各トークンごとにキーと値のベクトルを生成・保存します。KVキャッシュのサイズは、シーケンス長、バッチサイズ、層数に比例して増加し、計算式は「2 × batch_size × seq_len × num_layers × hidden_dim × bytes_per_parameter / 1024³」です。
- フレームワークとCUDAのオーバーヘッド:CUDAカーネル、PyTorchアロケータの断片化、一時的な活性化メモリなどが含まれ、フレームワークやGPUに依存します。
なぜモデルが「理論上」収まってもOOMになるのか? 以前は、小さなNLPモデルを扱うことが多く、単一GPUで複数モデルを簡単にホストできました。しかしLLMは、重みをロードするだけでなく、実行時にメモリが動的に増加します。重みがVRAMに収まっても、KVキャッシュがプロンプトと生成トークンごとに拡大します。例えば、重みが60 GBのモデルを80 GBのGPUで実行する場合、長いコンテキスト(32kトークンなど)ではKVキャッシュが残りのメモリを消費し、OOMが発生します。また、高並列シナリオでは複数リクエストのKVキャッシュが積み重なり、メモリを急速に消費します。したがって、本当のボトルネックは重みではなく、実行時メモリの増加です。
GPUメモリ使用量の最適化戦略 これらの問題に対して、以下の最適化戦略が効果的です:
- 量子化:重みの精度を下げる(FP16→INT4など)と、メモリ使用量を4分の1に削減。現代的な量子化手法(GPTQ、AWQ)は精度低下を最小限に抑え、チャットボットやRAGなどのワークロードに適しています。
- 分散推論:テンソル並列化によりモデルを複数GPUに分割しますが、通信オーバーヘッドに注意が必要です。
- KVキャッシュ最適化:プレフィックスキャッシュ(共通プロンプトの再利用)、KVアウェアルーティング(同一リクエストのトークンを同一GPUに割り当て、キャッシュヒット率向上。テストではスループットが12倍向上)、KVキャッシュオフローディング(使用頻度の低いブロックをCPUメモリやディスクに移動)などがあります。
BentoML推論プラットフォームはこれらの最適化を標準機能として統合しており、ユーザーは手動で設定することなく効率的な推論を実現できます。