推論のコールドスタートを40倍削減: 真にサーバーレスなGPUの背後にあるエンジニアリング
現在のAI時代において、推論の需要は極端な変動性を特徴としています。予測可能で安定したトレーニングワークロードとは異なり、推論は外部ユーザーの行動によって駆動され、需要がスパイクするパターンになります。エンジニアにとっては、Quality of Service(QoS)とコストの間に緊張関係が生まれます。ピークに対応するためにGPUを過剰にプロビジョニングすると「GPU Allocation Utilization」が極端に低くなり、逆に不足するとレイテンシスパイクや503エラーが発生します。
「真にサーバーレス」なGPUを実現するためには、リクエストから実行中のレプリカへのスケールに要する時間を分から秒へと短縮する必要があります。Modalは、Cloud Buffers、カスタム遅延ファイルシステム(FUSE)、CPU Checkpoint/Restore、CUDA Checkpoint/Restoreという4つの主要な最適化を実装し、コールドスタートを最大40倍(約2,000秒から約50秒)短縮しました。
1. インスタンス割り当てをホットパスから除外する
スケーリングの最初のボトルネックは、新しい仮想マシンを起動しヘルスチェックを行う時間で、数分かかることがあります。Modalは、cloud buffer と呼ばれるアイドル状態でヘルシーなGPUのプールを多数のアプリケーション間で共有することで、これをクリティカルパスから除外します。
新しいレプリカを事前に温められたユニットにスケジューリングし、バッファを非同期で補充することで、初期割り当てレイテンシを排除します。この管理は、Googleの GLOP ソルバーを用いた線形計画問題として扱われ、コスト、要求された容量、観測されたクラウドプロバイダーの供給量をバランスさせます。
重要なのは、GPUのヘルスチェックを積極的に行う点です。GPUは標準的なサーバーハードウェアよりも故障が頻繁なため、Modalは2段階のヘルスチェックを実装しています:起動時の短いアクティブチェックと、週次で実行する dcgmi diag などの集中的な診断です。
2. ImageFSによる遅延コンテナロード
標準的なコンテナ起動は、数ギガバイトに及ぶルートファイルシステムデータの取得と解凍がボトルネックになります。Modalは、ImageFS と呼ばれるカスタムファイルシステム(libfuse 使用)でコンテナランチャーとイメージ配信を分離し、この問題を解決します。
遅延ロードとコンテンツアドレッシング
イメージ全体をロードする代わりに、ImageFS は起動時にメタデータ(インデックス)だけをロードし、これには100ms未満しかかかりません。実際のファイル内容は、アプリケーションが要求したときに遅延的にロードされます。多くのコンテナはロケールやタイムゾーンデータなど、ファイルシステムの大部分にアクセスしないため、イメージの大半が転送されません。
アクセスされるデータを最適化するため、Modalは階層化されたコンテンツアドレスドキャッシュを使用します:
- Page Cache: 最頻ヒットに対してマイクロ秒レベルのレイテンシ。
- Local SSD: 頻繁に使用されるコンテンツ向けの高スループットストレージ。
- Regional CDN/Blob Storage: ロングテールデータ向けの無限容量。
パスベースやレイヤーベースのキャッシュではなくコンテンツアドレッシングを採用することで、異なるイメージ間で共有されるバイトはレイヤーに関係なく一度だけ保存されます。
3. CPUスナップショットでホスト起動を高速化
コンテナが起動した後でも、アプリケーションは初期化が必要です。Python中心のAIスタックでは、単純な import torch だけで数千のシステムコールと数秒のオーバーヘッドが発生します。
ModalはCheckpoint/Restore(C/R) を利用してこれを回避します。gVisor の runsc ランタイムを使用し、コンテナを状態機械として扱います。プロセス(ヒープ、スレッド状態、ファイルディスクリプタテーブルを含む)のメモリスナップショットを作成し、ディスクに保存します。
新しいレプリカが必要になると、システムはこのスナップショットをメモリに直接復元します。これによりアプリケーションは「高速転送」され、ホスト側の起動時間が約10倍短縮されます。ただし、スナップショットは基盤となるCPU命令セットと互換性が必要で、特定のAWSインスタンスタイプでサポートされていない命令を含むことはできません。
4. CUDAチェックポイントでデバイス初期化を排除
最後に、そしてしばしば最も重要なボトルネックはGPU側の初期化です。これには主に2つのタスクがあります:
- Weight Loading: 数十億のパラメータをストレージからGPU VRAMへ転送。
- Inference Engine Setup: CUDAグラフのキャプチャやTorchコンパイラの実行など、計算集約的なタスク。
Weight Loading は主にネットワーク/ディスク速度に制限されるスループットボトルネックであるのに対し、エンジンセットアップは計算ボトルネックです。Modalは最新のNvidiaドライバ機能を活用し、デバイスメモリをホストメモリにチェックポイントします。
ホスト側とデバイス側のスナップショットを組み合わせることで、ModalはCUDAコンテキスト全体を復元できます。vLLMやSGLangのようなLLMサーバーでは、これにより起動レイテンシが大幅に削減されます。たとえば、1 GiBモデルのテストでは、スナップショット有効時のvLLM起動レイテンシは平均約95秒から約13秒に低下しました。
レイテンシ削減の概要
| 最適化 | 対象コンポーネント | レイテンシへの影響 |
|---|---|---|
| Cloud Buffers | Machine Management | 分 → 秒 |
| ImageFS (FUSE) | Local SSD / Network | 分 → 秒 |
| CPU Snapshots | CPU / RAM | 数十秒 → 秒 |
| CUDA Snapshots | GPU / VRAM | 分 → 数十秒 |
実際の適用例: Reducto
これらの最適化により、ピーク対平均比が高いワークロードでも効率的にスケールできるようになります。文書処理プラットフォームの Reducto は、ビジョン・ランゲージモデルを用いて大規模な企業データセットを処理します。短時間で数千GPUにスケールする必要があるため、GPUメモリのスナップショットを活用することで、コールドスタートを約70秒から約12秒に削減し、コストのかかるアイドル容量を維持せずに「キロGPU」ワークロードを真にサーバーレスで実行できるようになりました。
技術的な反論と考慮点
Modal のアプローチは非常に効果的ですが、コミュニティからは以下のような技術的トレードオフが指摘されています:
- FUSE Overhead:
libfuseの使用はユーザー空間とカーネル空間間のコンテキストスイッチを追加します。スループット重視のAIワークロードでは無視できる程度ですが、レイテンシに敏感なファイル操作ではボトルネックになる可能性があります。 - Snapshot Fragility: メモリスナップショットはホスト環境に非常に敏感です。特定のCPU命令を含むスナップショットは、その命令をサポートしないマシンでは復元できず、異種クラスター向けに複数のスナップショットを用意する必要があります。
- Multi-GPU Complexity: マルチGPUプログラムのスナップショットは困難です。
ncclなどの通信ライブラリは一時停止を想定しておらず、復元時にデッドロックする可能性があります。