ホストが空きメモリを報告しているのに、コンテナ化されたAIモデルが再起動するのはなぜですか?

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

ホストの空きメモリが十分にあるにもかかわらず、コンテナ化されたAIモデルが再起動することがあります。これは、コンテナのcgroup、アクセラレーター、またはスーパーバイザーの制限が、マシン全体のRAM表示より狭いためです。

ホームサーバーのダッシュボードには数GBの空き容量があるように表示されているのに、推論コンテナが消えて新しいプロセスIDで戻ってくることがあります。コンテナが独自のメモリ上限に達したり、メモリ回収中にヘルスチェックに失敗したり、GPUメモリを使い果たしたり、割り当てエラーの後に終了したりする可能性があります。その後、再起動ポリシーによって、その局所的な障害が一見自然発生したモデル再起動に変わります。

コンテナにはホストとは異なるメモリ境界がある

Linuxのコントロールグループは、選択したプロセスグループのメモリを追跡・制限します。コンテナは、関係のないホストRAMがカーネルで利用可能な状態でも、memory.maxまたはランタイムの制限に達することがあります。そのため、マシン全体の空き容量は、そのサービスに適用される割り当て境界を示しません。

cgroupのメモリ accountingに関する詳しい説明では、匿名メモリ、マッピングされたファイル、コントロールグループに課金されるキャッシュが区別されています。この仕組みにより、ディスクからマッピングされた重み、一時的なモデルバッファ、ページキャッシュが、単純なプロセスRSS表示では小さく見える場合でも、コンテナの予算を消費する理由が分かります。

制限は入れ子になることもあります。モデルコンテナがcomposeサービス、systemdスライス、仮想マシン、またはオーケストレーションのグループ内に配置される場合です。最も狭い有効な境界によって、物理ホストが全体的なメモリ不足に近づく前に、メモリ回収やOOMキルが発生する可能性があります。

メモリ圧迫により、OOMキルの前にヘルスチェックが停止することがある

制限に近づくと、カーネルはキャッシュを回収し、メモリを走査し、割り当てをスロットリングすることがあります。モデルが稼働し続けていても、ヘルスプローブに対する応答が遅くなりすぎると、スーパーバイザーがモデルを終了して代替プロセスを起動することがあります。その場合、コンテナレベルのOOMキルは記録されないことがあります。

Pressure Stall Informationフレームワークは、使用率だけに依存せず、タスクがメモリ、CPU、I/Oの圧力によって待機して失われた時間を測定します。Pressure Stall Informationにより、積極的なメモリ回収中に空きバイト数とサービスの応答性が一致しなくなる理由を説明できます。

AIの読み込みでは、急激なピークが発生します。デシリアライズ中は圧縮された重みと展開済みの重みが一時的に同時に保持されることがあり、量子化ではスクラッチ領域が割り当てられ、並列ワーカーがバッファを複製することもあります。そのため、読み込み後の安定したメモリ使用量だけでは、失敗したプローブと重なる短時間のピークを過小評価してしまいます。

GPU障害と再起動ポリシーがホストのOOMに見えることがある

ホストRAMの指標には通常、専用VRAMは含まれません。重み、KVキャッシュ、カーネル、別のワークロードがアクセラレーターを占有していると、モデルはGPUへの割り当てに失敗することがあります。その後、アプリケーションエラーで終了しても、ホストは十分なシステムメモリがあると報告し続けます。

リソース管理の指針では、コンテナのメモリ制限とノード全体のメモリ不足を区別しています。また、制限はダッシュボードの空きメモリというラベルではなく、ランタイムとカーネルによって適用されると説明しています。したがって、再起動はメモリ測定そのものではなく、ワークロードの再起動ポリシーによって決まります。

新しいコンテナIDが生成されたことは、すべてOOMイベントの証拠だと考えるのが誤りです。イメージの更新、ウォッチドッグのタイムアウト、手動での再デプロイ、デバイスのリセット、アプリケーションのクラッシュでも、同じ表面的な症状が発生します。メモリが原因だと判断する前に、終了理由、カーネルログ、cgroupイベント、GPUエラーが一致している必要があります。

すべてのメモリ境界で終了理由を照合する

1回のモデル読み込みを再現し、同じ時刻を基準に、コンテナのmemory.current、memory.max、memory.events、プロセスのRSSとマッピング済みファイル、ホストのMemAvailable、Pressure Stallの合計値、GPUメモリ、ヘルスプローブのレイテンシ、プロセスの終了コード、スーパーバイザーの再起動回数を記録します。

コンテナ間の競合を状況の手がかりとして使い、同じモデルを、より高いコンテナ制限、無効にした再起動ポリシー、競合するアクセラレーターのワークロードなしという条件で再度実行します。元の障害が成功した再起動によって隠れないよう、1回の実行につき変更する境界は1つだけにします。

制限を変更する前に、そのイベントをcgroup OOM、グローバルOOM、GPU割り当て失敗、ヘルスチェックによる終了、アプリケーション終了のいずれかに分類します。ピークが正当なものであれば余裕を確保します。プローブがメモリ回収中の正常なモデルを終了させている場合は、実際のハングを見逃さないようにしながら、プローブのタイミングを調整します。

テック&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.