なぜGPUメモリの断片化によってローカルAIモデルがブロックされるのか?

エヴァ・ウォン は テクニカルライター であり ZimaSpaceの常駐ティンカーでもあります。 生涯のオタクであり、 ホームラボとオープンソースソフトウェアに情熱を持っています。彼女は複雑な技術的概念をわかりやすく、 実践的なガイドに翻訳することを専門としています。エヴァはセルフホスティングは楽しくあるべきで、怖がるものではないと信じています。彼女のチュートリアルを通じて、コミュニティが ハードウェアのセットアップを解明する手助けをしています。初めてのNAS構築からDockerコンテナの習得まで。

GPUメモリのフラグメンテーションは、空き容量が複数の領域に分割され、ランタイムが次に必要とする割り当てパターンを満たせなくなることで、ローカルAIモデルの実行を妨げる場合があります。

この問題は、モデルの切り替え、コンテキスト長の変更、画像処理と自然言語処理のワークロードの同時実行、または一時テンソルのサイズが増減するリクエストの処理後に発生することがよくあります。モニタリング上は未使用のVRAMが残っていても、既存のブロックを解放または再編成しない限り、アロケーターが大きなワークスペース、モデルシャード、またはKVキャッシュの拡張領域を配置できないことがあります。以下のセクションでは、実際の容量不足とアロケーターのフラグメンテーションを区別し、ランタイムを再起動すると同じモデルが一時的に再び収まる理由を説明します。

VRAMの総空き容量と、実際に利用可能な割り当て領域は同じではない

メモリモニターは合計容量を表示しますが、アロケーターは管理対象のブロックや仮想マッピングを通じてリクエストを満たす必要があります。複数の小さな空き領域の合計が要求サイズを上回っていても、連続した割り当てが必要な場合は利用できないことがあります。

LLM運用に関する分析では、KVキャッシュや可変サイズのテンソルによって、次のリクエストより小さな空き領域が残ることで発生する空きメモリの不一致について説明しています。したがって、表示されるOOMは総バイト数だけでなく、メモリの配置にも関係します。

ドライバーやフレームワークによって、デバイスの空きメモリ、予約済みメモリ、割り当て済みメモリ、非アクティブメモリの報告方法が異なる場合もあります。1つの見出し数値だけを信頼せず、ランタイムアロケーターの表示とデバイスレベルの使用状況を比較してください。

テンソルサイズの変化が時間とともに空き領域を生み出す

AIワークロードでは、プロンプト、バッチ、画像のサイズ、アテンション用ワークスペース、一時的な変換処理のために、異なるサイズのテンソルが繰り返し割り当てられ、解放されます。キャッシュアロケーターは、ドライバーへ毎回返却するコストが高いため、再利用に備えてブロックを保持します。

GMLakeの研究では、不規則な割り当てによって分割ベースのメモリプールが劣化し、大規模モデルで大幅なフラグメンテーションが発生する可能性が示されています。同じサイズを再利用するのは効率的ですが、サイズの合わないブロックを繰り返し分割・結合するのはより困難です。

モデルを切り替えて使用するホームサーバーは、言語、拡散、ビジョン、音声の各ランタイムが同じGPUに対して大きく異なる形状のブロックを要求するため、特に影響を受けやすくなります。

フラグメンテーションは、メモリリークがなくても蓄積します。すべての割り当てが最終的にプールへ解放されても、プールの形状が次のワークロードに適合しない状態のままになることがあります。

増加するKVキャッシュによって推論時のフラグメンテーションが動的に変化する

LLMの重みは読み込み後に比較的安定していますが、KVキャッシュはアクティブなユーザー数、プロンプトの長さ、生成トークン数に応じて増加します。また、リクエストの終了時刻も異なるため、サイズの不均一な空き領域が生じます。

PagedAttentionは、最終的なシーケンス長が不明な状態で大きな連続領域を予約するのではなく、リクエストの状態を小さなブロックに分けて保存することで、KVキャッシュのフラグメンテーションを軽減するために設計されました。

この問題は、フレームワークの一般的なテンソルアロケーターにおけるフラグメンテーションとは異なりますが、両方が同時に発生することもあります。ページング方式のKV管理機構は、モデルのワークスペースや別のプロセスが所有する割り当てを自動的にコンパクションすることはできません。

ZimaSpaceの同時コンテキストに関する解説では、1人のユーザーには収まるモデルでも、複数の会話が同時に拡大するとメモリ容量の境界を超える理由を説明しています。

予約済みメモリによって障害がメモリリークのように見えることがある

フレームワークのアロケーターは、後続のリクエストを高速化するため、解放済みのブロックを保持することがよくあります。デバイス監視ツールでは、現在のモデルがそのすべてにアクティブなテンソルを保持していなくても、これらのブロックがプロセスによって使用中としてカウントされます。

実用的なOOMガイドでは、予約済みメモリと、アクティブなモデルおよびキャッシュの要件を区別しています。大きな差がある場合は、再利用可能なアロケーターブロック、フラグメンテーション、または現在よりもピーク時の使用量が大きかったワークロードを示している可能性があります。

キャッシュをクリアすると、一部のブロックがドライバーへ返却されることはありますが、使用中の重み、アクティブなKV状態、別のプロセスのコンテキスト、または次の処理に必要なワークスペースを解放することはできません。

安定した割り当て形状とページングによって再発を減らす

1つのモデル、固定したコンテキスト上限、固定したバッチサイズ、競合するAIサービスなしという条件で障害を再現してください。プロセス単位の割り当て済みメモリと予約済みメモリ、デバイスレベルの空きメモリ、最大リクエストサイズ、OOMの前に実行されていたワークロードの順序を記録します。

vAttentionは、仮想メモリマッピングを使用して、連続した仮想KV領域と物理メモリの割り当てを分離します。同様のページング方式やセグメント割り当て方式により、物理的に連続した1つの領域への依存を減らせます。

ホームサーバーで実践できる対策には、VRAMに余裕を残すこと、モデルの切り替えを制限すること、コンテキストとバッチの上限を安定させること、1つのランタイムでサービスを調整すること、そしてユーザーのリクエストが失敗してからではなく、メンテナンス中にフラグメンテーションしたプロセスを再起動することが含まれます。

クリーンな再起動を行ってもモデルが収まらない場合、主な問題は蓄積したフラグメンテーションではなく、実際の容量不足である可能性が高いでしょう。モデルサイズ、量子化によるメモリ使用量、コンテキスト、バッチ、または競合する割り当てを減らしてください。

テック&AIハブ

もっと読む

Get More Builds Like This

Stay in the Loop

Get updates from Zima - new products, exclusive deals, and real builds from the community.

Stay in the Loop preferences

We respect your inbox. Unsubscribe anytime.