GKE の時間共有 GPU


このページでは、Google Kubernetes Engine(GKE)の時間共有 GPU について説明します。ノードで時間共有 GPU を有効にして構成する方法については、時間共有を使用して GPU を複数のワークロードと共有するをご覧ください。

このページは、PodノードDeployment、Namespace などの Kubernetes のコンセプトと、ノードプール、自動スケーリング、自動プロビジョニングなどの GKE のコンセプトを理解していることを前提としています。

Kubernetes での GPU リクエストの仕組み

Kubernetes では、アプリケーションが機能するために必要なリソース量を正確にリクエストできます。アプリケーション用にフラクショナル CPU ユニットはリクエストできますが、フラクショナル GPU ユニットはリクエストできません。Pod マニフェストは GPU リソースを整数でリクエストする必要があります。つまり、コンテナが正常に機能してもリソースの一部しか必要でない場合でも、物理 GPU 全体が 1 つのコンテナに割り当てられます。これは非効率であり、特に GPU の要件が低い複数のワークロードを実行している場合に、コストがかかる可能性があります。

時間共有とは

時間共有は、ノードに接続された単一の物理 GPU を複数のコンテナで共有できるようにする GKE 機能です。GKE で GPU 時間共有を使用すると、接続された GPU をより効率的に使用し、運用コストを削減できます。

GPU 時間共有の仕組み

GPU が接続された新しいノードプールを作成するときに、物理 GPU の共有を許可するコンテナの最大数を指定できます。ノードプール内のすべての GPU は、ノードプール レベルで指定した設定に基づいて共有されます。

次に GKE はノード上の各 GPU の共有を許可するコンテナの最大数を指定するノードラベルと、使用する共有戦略を指定するノードラベルを追加します。たとえば、ノードプールの作成時に最大数 3 を指定した場合、ノードラベルは次のようになります。

cloud.google.com/gke-max-shared-clients-per-gpu: "3"
cloud.google.com/gke-gpu-sharing-strategy: time-sharing

GPU ドライバは、物理 GPU を複数の GPU ユニットとしてノード上の kubelet に提示します。kubelet は、リクエストに応じてこれらの GPU ユニットをコンテナに割り当てます。物理 GPU で複数のコンテナを実行している場合、GPU ハードウェアとドライバは、使用状況に基づいてコンテナ間でコンテキストを切り替えることで、GPU リソースへの時間共有アクセスを容易にします。kubelet は、時間共有 GPU を使用可能な複数の GPU として認識するため、Pod マニフェストのリクエストを変更する必要はありません。

時間共有 GPU の数は、ワークロードが取得する物理的な GPU コンピューティング能力の測定値ではありません。コンテキストの切り替えにより、各コンテナが GPU リソースにアクセスするタイミングのロジックを処理するドライバと GPU ハードウェアを使用して、すべてのコンテナが基盤となる物理 GPU のすべての機能にアクセスできます。

時間共有 GPU を使用するタイミング

任意の NVIDIA GPU で時間共有 GPU を構成できます。時間共有 GPU は、次に示すように、大量の GPU リソースを常時使用する必要のないワークロードの実行に最適です。

  • GPU リクエストが少ない同種ワークロード
  • バースト可能な GPU ワークロード

これらのタイプのワークロードの例は次のとおりです。

  • レンダリング
  • 推論
  • 小規模な ML モデルのトレーニング

GKE にはマルチインスタンス GPU も用意されています。これは、物理 GPU を最大 7 個の個別のインスタンスに分割し、それぞれのインスタンスにハードウェア レベルで他のアプリケーションから隔離されます。マルチインスタンス GPU のインスタンスを使うコンテナでは、そのインスタンスで利用可能な CPU とメモリリソースのみにアクセスできます。マルチインスタンス GPU には NVIDIA Tesla A100 アクセラレータが必要です。

ワークロードに次のような要件がある場合は、マルチインスタンス GPU を使用する必要があります。

  • 同じ物理 GPU 上の他のコンテナからハードウェアが分離されている。
  • 他のコンテナが他のインスタンスでリソース使用量を飽和させている場合でも、並列ワークロードのスループットとレイテンシが予測可能である。

GPU 使用率を最大化させたい場合は、各マルチインスタンス GPU のパーティション分割に時間共有を構成できます。コンテナがそのパーティションのリソースに対するアクセスを共有している状態で、各パーティションで複数のコンテナを実行できます。

ワークロードで時間共有 GPU をリクエストする

時間共有 GPU の使用を開始するには、クラスタ管理者は、時間共有を使用して GPU を複数のワークロードと共有するの手順に沿って時間共有を有効にした GPU クラスタを作成する必要があります。物理 GPU を共有するコンテナの最大数を指定する前に、ワークロードのリソースニーズと基盤となる GPU の容量を考慮する必要があります。

クラスタまたはノードプールで時間共有 GPU を有効にすると、アプリケーション デベロッパーがワークロード内の GPU をリクエストできます。デベロッパーは、次のラベルを使用して nodeSelector を指定することで、GKE に時間共有 GPU ノードでワークロードをスケジュールできます。

  • cloud.google.com/gke-max-shared-clients-per-gpu: 基盤となる GPU を特定の数のクライアントが共有できるようにするノードを選択します。
  • cloud.google.com/gke-gpu-sharing-strategy: GPU の時間共有戦略を使用するノードを選択します。

手順については、時間共有 GPU を使用するワークロードをデプロイするをご覧ください。

時間共有 GPU を使用したスケジューリング動作

時間共有 GPU にワークロードをデプロイするデベロッパーは、マニフェストの nodeSelector ラベルと GPU リクエストに基づいてスケジューリング動作がどのように変化するかを理解している必要があります。

次の表は、マニフェストで指定したノードラベルに基づいてスケジューリング動作がどのように変化するかを示しています。

ノードラベル
cloud.google.com/gke-max-shared-clients-per-gpu

および

cloud.google.com/gke-gpu-sharing-strategy

GKE は、両方のラベルに一致する使用可能なノードにワークロードをスケジュールします。

使用可能なノードがない場合、GKE は自動スケーリングとノードの自動プロビジョニングを使用して、両方のラベルに一致する新しいノードまたはノードプールを作成します。

cloud.google.com/gke-max-shared-clients-per-gpu のみ GKE は、ラベルに一致する使用可能なノードにワークロードをスケジューリングします。

使用可能なノードがない場合、GKE は自動スケーリングとノードの自動プロビジョニングを使用して、ラベルに一致する新しいノードまたはノードプールを作成します。デフォルトでは、自動プロビジョニングされるノードにも cloud.google.com/gke-gpu-sharing-strategy=time-sharing ラベルが付けられます。

cloud.google.com/gke-gpu-sharing-strategy のみ

GKE は、時間共有を使用する使用可能なノードにワークロードをスケジューリングします。

cloud.google.com/gke-max-shared-clients-per-gpu の値が異なる時間共有ノードプールが複数ある場合は、使用可能な任意のノードでワークロードをスケジュールできます。

使用可能なノードがいずれのノードプールにもない場合、クラスタ オートスケーラーは cloud.google.com/gke-max-shared-clients-per-gpu の値が最も低いノードプールをスケールアップします。

すべてのノードプールの容量が上限に達した場合、ノードの自動プロビジョニングによって、デフォルト値の cloud.google.com/gke-max-shared-clients-per-gpu=2 で新しいノードプールが作成されます。

時間共有 GPU のリクエストの上限

時間共有 GPU ノードで動作する GPU アプリケーションを開発している場合、コンテナごとにリクエストできる時間共有 GPU は 1 つだけです。GKE は、予期せぬ動作を回避するために、コンテナ内で複数の時間共有 GPU のリクエストを拒否します。リクエストされる時間共有 GPU の数は、コンテナで使用可能な計算能力の測定値ではありません。

次の表は、特定の量の GPU をリクエストした場合の動作を示しています。

時間共有 GPU リクエスト
コンテナごとに 1 の時間共有 GPU GKE がリクエストを許可します。
コンテナごとに複数の時間共有 GPU

GKE がリクエストを拒否します。

この動作には、コンテナ内で複数のマルチインスタンス GPU インスタンスを要求することも含まれます。各 GPU インスタンスが独立した物理 GPU とみなされるからです。

GKE がワークロードを拒否すると、次のようなエラー メッセージが表示されます。

status:
  message: 'Pod Allocate failed due to rpc error: code = Unknown desc = [invalid request
    for sharing GPU (time-sharing), at most 1 nvidia.com/gpu can be requested on GPU nodes], which is unexpected'
  phase: Failed
  reason: UnexpectedAdmissionError

時間共有 GPU ノードをモニタリングする

Cloud Monitoring を使用して、時間共有 GPU のパフォーマンスをモニタリングします。GKE は、時間共有 GPU デバイスの各指標を Cloud Monitoring に送信します。これらの指標は、時間共有されない通常の GPU の指標とは異なります。

Cloud Monitoring では、時間共有 GPU デバイスごとに次の指標を確認できます。

  • デューティ サイクル(node/accelerator/duty_cycle: 前回のサンプル期間(10 秒)において、時間共有 GPU デバイスがアクティブに処理されていた時間の割合。値の範囲は 1%~100% です。
  • メモリ使用量(node/accelerator/memory_used: 時間共有 GPU デバイスごとに割り当てられるアクセラレータ メモリの量(バイト単位)。
  • メモリ容量(node/accelerator/memory_total: 時間共有 GPU デバイスごとのアクセラレータ メモリの合計(バイト単位)。

時間共有 GPU の指標と通常の物理 GPU の指標の主な違いは、時間共有指標はノードレベルに適用されるのに対し、通常の物理 GPU の指標はコンテナレベルに適用される点です。

制限事項

  • GKE では、物理 GPU を共有するコンテナ間で、メモリ(アドレス空間)の分離、パフォーマンスの分離、障害の分離が適用されます。ただし、時間共有 GPU にはメモリ上限は適用されません。メモリ不足(OOM)の問題を回避するには、アプリケーションで GPU メモリの上限を設定します。セキュリティの問題を回避するには、同じ信頼境界内にあるワークロードのみを時間共有 GPU にデプロイします。
  • GKE は、容量割り当て中の予期しない動作を防ぐために、特定の時間共有 GPU リクエストを拒否することがあります。詳細については、時間共有 GPU のリクエストの上限をご覧ください。
  • 1 つの物理 GPU を共有できるコンテナの最大数は 48 です。時間共有の構成を計画する場合は、ワークロードのリソースのニーズと基盤となる物理 GPU の容量を考慮して、パフォーマンスと応答性を最適化してください。

次のステップ