View a markdown version of this page

Amazon EKS を使用して GPU で AI モデル推論を自動スケーリングする - Amazon EKS

このページの改善にご協力ください

このユーザーガイドに貢献するには、すべてのページの右側のペインにある「GitHub でこのページを編集する」リンクを選択してください。

Amazon EKS を使用して GPU で AI モデル推論を自動スケーリングする

ヒント

今後開催予定の Amazon EKS AI/ML ワークショップに登録してください。

このセクションでは、Amazon EKS を使用して GPU で AI 推論ワークロードを自動スケーリングする概念と手順について説明します。

前の Load & Serve Models セクションでデプロイした単一の vLLM モデルレプリカは、新しいリクエストが待機を開始する前に、限られた数の同時リクエストを処理できるため、レイテンシーが増加し、リクエストのタイムアウトが発生する可能性があります。トラフィックに対応するために、デプロイを水平方向に自動的にスケーリングできます。自動スケーリングは、需要の増加に応じてワークロードレプリカを追加し、需要の減少に応じてワークロードレプリカを削除するため、GPU キャパシティのオーバープロビジョニングを回避できます。

推論の自動スケーリングは 2 つの段階で行われます。

  • ノードスケーリング – Kubernetes スケジューラに既存のノードに新しいポッドを配置するスペースがない場合、ポッドは Pending のままになります。Karpenter は、Pending ポッドに合わせて GPU ノードをプロビジョニングすることでポッドに応答し、ワークロードレプリカがスケールダウンするとノードを削除します。

  • ポッドスケーリングHorizontal Pod Autoscaler (HPA) は、設定されたメトリクスを監視します。そのメトリクスが設定されたしきい値を超えると、HPA はワークロードレプリカ数を増やし、新しい vLLM ポッドが作成されます。

ノードスケーリングステージは、ワークロードレプリカの実行に必要な GPU キャパシティを提供します。ポッドスケーリングステージは、選択したメトリクスをターゲットの近くに保持するようにワークロードレプリカの数を調整します。

Karpenter を使用した GPU ノードのプロビジョニング

Karpenter はノードのライフサイクルを管理し、ワークロードが必要なときにノードをプロビジョニングするか、必要でないときにノードを統合または削除します。Kubernetes スケジューラを置き換えるのではなく、それと連携して動作します。スケジューラはノードにポッドを配置します。Karpenter は、スケジューラが適合できないポッドのキャパシティをプロビジョニングし、ノードが Ready になるとスケジューラがそれらをバインドできるようにします。

Karpenter は、CPU ノードのフリートとは異なる方法で GPU ノードを処理します。

GPU はユニット全体でリクエストされます

タイムスライシングや MIG などの GPU 共有手法を使用しない限り、ポッドは CPU やメモリのように一部ではなく、1 つ以上の GPU 全体を取得します。各 GPU には独自の専用メモリがあるため、同じノード上のレプリカは GPU メモリを共有しません。これがノードにどのようにマッピングされるかは、インスタンスタイプによって異なります。

  • 単一 GPU インスタンス (g6.xlarge など) – ノードは 1 つのレプリカのみを保持します。レプリカ、GPU、ノードは 1 対 1 でスケールし、各レプリカは独自のインスタンスで分離されます。

  • マルチ GPU インスタンス (4 つの GPU を持つ g6.12xlarge など) – デバイスプラグインは全 GPU 数をアドバタイズするため、Karpenter は複数のレプリカを GPU ごとに 1 つのノードにパックできます。

  • マルチ GPU ポッド — ポッドは複数の GPU をリクエストできます。例えば、大きなモデルを 2 つの GPU 全体にシャードするように nvidia.com/gpu: 2 を設定すると、Karpenter はその数の GPU が空いているノードにポッドを配置します。

Karpenter が GPU の可用性とコストを最適化

Karpenter は、不十分な GPU キャパシティのランディングを費用対効果の高い実行に対してバランスを取ります。

  • インスタンスの選択 柔軟な NodePool の場合、Karpenter は Pending ポッドに適した最も低コストのインスタンスタイプを選択します。起動がキャパシティ不足になると、他のインスタンスタイプとアベイラビリティーゾーンが自動的に再試行されるため、GPU キャパシティを確保できる可能性が高まります。

  • 統合 – 需要が低下し、レプリカがスケールインすると、Karpenter は解放されたノードを再利用します。WhenEmptyOrUnderutilized は空のノードを削除し、レプリカをより少ないノードに再パックしますが、WhenEmpty はスケジュールされていないノードのみを再利用します。

  • 進行中のポッドの保護 – 統合中にポッドが中断されないようにするには、karpenter.sh/do-not-disrupt 注釈を追加するか、PodDisruptionBudget を設定するか、consolidateAfter 設定を使用して統合を遅延させます。

Karpenter に GPU キャパシティが設定されると、ポッドスケーリングステージが引き継がれます。HPA は、設定したメトリクスに基づいてレプリカを追加および削除します。このセクションの残りの部分では、推論ワークロードのスケーリングメトリクスを選択する方法について説明します。

GPU と CPU の自動スケーリング

Kubernetes では、従来の CPU ベースのワークロードはすぐに自動スケーリングされますが、GPU ベースの推論は自動スケーリングされません。主な違いは 3 つあります。

自動スケーリングのメトリクス可用性

Kubernetes は CPU とメモリのメトリクスを HPA にすぐに提供します

各ノードの kubelet は CPU とメモリの使用状況を Kubernetes メトリクス API にレポートするため、HPA はこれらの値を直接読み取り、追加のコンポーネントなしでワークロードをスケーリングできます。

高速ワークロードには、追加のメトリクスのセットアップ、エクスポーター、アダプターが必要です

kubelet は GPU または推論メトリクスをレポートしません。GPU ベースの推論をスケールするには、DCGM エクスポーターからの vLLM アプリケーションメトリクスや GPU メトリクスなどの関連シグナルを発行するエクスポーターと、それらのメトリクスを HPA に公開するアダプターを追加する必要があります。

リソースの割り当てと共有

従来のワークロードは CPU とメモリを分数で共有します

Linux cgroups は CPU とメモリを分数リソースに分割し、複数のポッドが同じノードを共有できるようにします。ポッドは、100 ミリコアの CPU や 512 MiB のメモリなど、ノードのキャパシティの一部をリクエストできます。

高速ワークロードは、GPU 割り当てフレームワークを通じて GPU を割り当て、共有します。

GPU は CPU やメモリなどの cgroup を通じては共有されません。現在の最も一般的な Kubernetes セットアップでは、NVIDIA デバイスプラグインを使用して GPU 全体をポッド (nvidia.com/gpu: 1 など) に割り当てます。Dynamic Resource Allocation (DRA) は、リソースクレームを通じて GPU を割り当てる新しい Kubernetes API であり、より柔軟なスケジューリングとリソース管理を提供します。デバイスプラグインと DRA の両方が GPU 共有手法をサポートできます。タイムスライシングを使用すると、複数のポッドが時間の経過とともにアクセスをインターリーブすることで GPU を共有できます。一方、マルチインスタンス GPU (MIG) は NVIDIA A100 や H100 などのサポートされている GPU をハードウェア分離された GPU インスタンスにパーティション化します。

スケーリングシグナル

従来のワークロードは通常、CPU とメモリの使用率に応じてスケールします。

使用率は、CPU およびメモリワークロードの標準的な自動スケーリングシグナルです。これは、ワークロードが既に負荷を受けた後にのみ上昇するため、遅行指標ですが、多くの従来のアプリケーションではスケーリングの決定を促進するのに十分です。

高速ワークロードは GPU 使用率ではなく、先行指標メトリクスに基づいてスケールする必要があります

GPU 使用率 (DCGM_FI_DEV_GPU_UTIL) は、GPU がビジー状態かどうかを示すものであり、どの程度ビジー状態かを示すものではありません。vLLM などの推論サーバーは、さまざまな受信リクエストで 100% 近くに留まる可能性があるため、使用率は信頼性の低い自動スケーリングシグナルです。代わりに、リクエストキューの深度、最初のトークンまでの時間 (TTFT)、リクエストレイテンシーなど、需要がキャパシティに近づくにつれて増加する先行指標に基づいてスケールします。

上記の 3 つの違いのうち、スケーリングシグナルを慎重に検討してください。GPU 使用率は残りの推論キャパシティの信頼性の高いシグナルではないため、モデル推論サーバーへの実際の需要を追跡するシグナルを特定して収集する必要があります。

次のセクションでは、スケーリングメトリクスとして使用するシグナルと、それらがどのように連携するかについて説明します。

スケーリングメトリクスの選択

モデル推論レプリカをスケールするタイミングを伝える単一のメトリクスはないため、推論サーバーからのシグナルの組み合わせに基づいてスケールします。これらのシグナルは連携して機能し、それぞれが前のシグナルを基に構築されることで、単一のメトリクスよりも早く確実に需要を捉えます。

シグナル メトリクス スケーリングにおける役割

キュー

リクエストキューの深度 (処理を待機しているリクエストの数)

キューは需要がキャパシティを超えた瞬間に形成されるため、先行指標と最適なデフォルトトリガーです。

レイテンシー

リクエストレイテンシー (p95 レイテンシーまたは TTFT)

キューがまだ構築されていない場合でもレスポンスが遅いときにスケーリングをトリガーし、ユーザー側のレイテンシーをターゲット内に維持します。

GPU メモリ

KV キャッシュ使用率 (GPU のリクエストメモリの使用状況)

GPU メモリの不足から保護します。制限に近づくと、サーバーはリクエストの拒否またはキューイングを開始します。

これらを組み合わせて防御レイヤーを形成します。リクエストキューの深度は、需要がキャパシティを上回った瞬間に発生する主なトリガーであり、リクエストレイテンシーはキューが形成される前にレスポンスが遅いかどうかをチェックし、KV キャッシュ使用率は GPU メモリの不足を防ぐバックストップです。

すべてを実践する

以下のサブセクションでは、これらのシグナルを特定のオートスケーラーと連携させる方法を示します。

  • スケーリングメトリクスのしきい値を検索する。単一の vLLM レプリカの負荷テストを行い、キャパシティの上限とスケールオンするキューの深度とレイテンシーのしきい値を検索します。ここから開始します。

  • HPA と KEDA を使用してスケールする。スケーリングシグナルとしてリクエストキューの深度とエンドツーエンドレイテンシーを使用して、KEDA と Horizontal Pod Autoscaler で vLLM レプリカを自動スケーリングします。