このページでは、Google Kubernetes Engine(GKE)ノード内の 1 つの NVIDIA® GPU ハードウェア アクセラレータに対するアクセスを GPU タイム シェアリングによって複数のワークロードに許可する方法について説明します。GKE で GPU タイム シェアリングを使用すると、接続された GPU をより効率的に使用して運用コストを削減できます。
このページは、ワークロードを設計して GKE クラスタにデプロイするデベロッパーのほか、GKE クラスタの作成と管理、インフラストラクチャとリソース要件の計画、クラスタ パフォーマンスのモニタリングを行う管理者とアーキテクトを対象としています。 Google Cloud のコンテンツで使用されている一般的なロールとタスクの例の詳細については、一般的な GKE ユーザーのロールとタスクをご覧ください。
このページを読む前に、GPU タイム シェアリングを使用する必要がある状況や制限事項など、GKE でのタイム シェアリングの仕組みを理解しておく必要があります。
要件
- GKE バージョン: GKE バージョン 1.23.7-gke.1400 以降を実行している GKE Standard クラスタで GPU タイム シェアリングを有効にできます。GKE バージョン 1.29.3-gke.1093000 以降を実行している GKE Autopilot クラスタで GPU タイム シェアリングを使用できます。
- GPU のタイプ: すべての NVIDIA GPU モデルで GPU タイム シェアリングを有効にできます。
始める前に
作業を始める前に、次のタスクが完了していることを確認してください。
- Google Kubernetes Engine API を有効にする。 Google Kubernetes Engine API の有効化
- このタスクに Google Cloud CLI を使用する場合は、gcloud CLI をインストールして初期化する。すでに gcloud CLI をインストールしている場合は、gcloud components updateコマンドを実行して最新のバージョンを取得します。以前のバージョンの gcloud CLI では、このドキュメントのコマンドを実行できない場合があります。
- NVIDIA GPU モデルの割り当てが十分であることを確認する。追加の割り当てが必要な場合は、割り当ての増加をリクエストするをご覧ください。
- ワークロードのリソースニーズと基盤となる GPU の容量に基づいて GPU の容量を計画します。
- GPU タイム シェアリングの制限事項を確認します。
GKE クラスタとノードプールで GPU タイム シェアリングを有効にする
デベロッパーが GPU を使用するワークロードをデプロイできるようにするには、プラットフォーム管理者が GKE Standard クラスタで GPU タイム シェアリングを有効にする必要があります。GPU タイム シェアリングを有効にするには、次の操作を行う必要があります。
バージョン 1.29.3-gke.1093000 以降を実行する Autopilot クラスタでは、デフォルトで GPU タイム シェアリングが有効になっています。Autopilot クラスタのタイム シェアリングはワークロードの仕様で構成されています。詳細については、GPU タイム シェアリングを使用するワークロードをデプロイするをご覧ください。
GKE Standard クラスタで GPU タイム シェアリングを有効にする
GKE Standard クラスタを作成するときに、GPU タイム シェアリングを有効にできます。クラスタ内のデフォルトのノードプールでこの機能が有効になっています。クラスタで新しいノードプールを手動で作成する場合も、GPU タイム シェアリングを有効にする必要があります。
gcloud container clusters create CLUSTER_NAME \
    --location=CONTROL_PLANE_LOCATION \
    --cluster-version=CLUSTER_VERSION \
    --machine-type=MACHINE_TYPE \
    --accelerator=type=GPU_TYPE,count=GPU_QUANTITY,gpu-sharing-strategy=time-sharing,max-shared-clients-per-gpu=CLIENTS_PER_GPU,gpu-driver-version=DRIVER_VERSION
次のように置き換えます。
- CLUSTER_NAME: 新しいクラスタの名前。
- CONTROL_PLANE_LOCATION: クラスタのコントロール プレーンの Compute Engine のロケーション。リージョン クラスタの場合はリージョン、ゾーンクラスタの場合はゾーンを指定します。
- CLUSTER_VERSION: クラスタ コントロール プレーンとノードの GKE バージョン。GKE バージョン 1.23.7-gke.1400 以降を使用します。または、- --release-channel=RELEASE_CHANNELフラグを使用して、その GKE バージョンのリリース チャンネルを指定します。
- MACHINE_TYPE: ノードの Compute Engine マシンタイプ。アクセラレータ最適化マシンタイプを選択することをおすすめします。
- GPU_TYPE: GPU のタイプ。NVIDIA GPU プラットフォーム(- nvidia-tesla-v100など)である必要があります。
- GPU_QUANTITY: デフォルトのノードプール内の各ノードに接続する物理 GPU の数。
- CLIENTS_PER_GPU: 各物理 GPU を共有できるコンテナの最大数。
- DRIVER_VERSION: インストールする NVIDIA ドライバのバージョン。次のいずれか 1 つを指定できます。- default: GKE バージョンのデフォルトのドライバ バージョンをインストールします。
- latest: お使いの GKE バージョン向けの最新のドライバ バージョンをインストールします。Container-Optimized OS を使用するノードでのみ使用できます。
- disabled: ドライバの自動インストールをスキップします。ノードプールを作成した後に、手動でドライバをインストールする必要があります。- gpu-driver-versionを省略すると、これがデフォルトのオプションになります。
 
GKE ノードプールで GPU タイム シェアリングを有効にする
GKE クラスタで新しいノードプールを手動で作成するときに、GPU タイム シェアリングを有効にできます。
gcloud container node-pools create NODEPOOL_NAME \
    --cluster=CLUSTER_NAME \
    --location=CONTROL_PLANE_LOCATION \
    --machine-type=MACHINE_TYPE \
    --accelerator=type=GPU_TYPE,count=GPU_QUANTITY,gpu-sharing-strategy=time-sharing,max-shared-clients-per-gpu=CLIENTS_PER_GPU,gpu-driver-version=DRIVER_VERSION
次のように置き換えます。
- NODEPOOL_NAME: 新しいノードプールの名前。
- CLUSTER_NAME: クラスタの名前。GKE バージョン 1.23.7-gke.1400 以降を実行する必要があります。
- CONTROL_PLANE_LOCATION: クラスタのコントロール プレーンの Compute Engine のロケーション。リージョン クラスタの場合はリージョン、ゾーンクラスタの場合はゾーンを指定します。
- MACHINE_TYPE: ノードの Compute Engine マシンタイプ。アクセラレータ最適化マシンタイプを選択することをおすすめします。
- GPU_TYPE: GPU のタイプ。NVIDIA GPU プラットフォーム(- nvidia-tesla-v100など)である必要があります。
- GPU_QUANTITY: ノードプール内の各ノードに接続する物理 GPU の数。
- CLIENTS_PER_GPU: 各物理 GPU を共有できるコンテナの最大数。
- DRIVER_VERSION: インストールする NVIDIA ドライバのバージョン。次のいずれか 1 つを指定できます。- default: GKE バージョンのデフォルトのドライバ バージョンをインストールします。
- latest: お使いの GKE バージョン向けの最新のドライバ バージョンをインストールします。Container-Optimized OS を使用するノードでのみ使用できます。
- disabled: ドライバの自動インストールをスキップします。ノードプールを作成した後に、手動でドライバをインストールする必要があります。- gpu-driver-versionを省略すると、これがデフォルトのオプションになります。
 
NVIDIA GPU デバイス ドライバをインストールする
先に進む前に、次のコマンドを実行してクラスタに接続します。
gcloud container clusters get-credentials CLUSTER_NAME
クラスタの作成時にドライバの自動インストールを無効にすることを選択した場合、または 1.27.2-gke.1200 より前の GKE バージョンを使用している場合は、物理 GPU の GPU タイム シェアリング分割を管理するために互換性のある NVIDIA ドライバを手動でインストールする必要があります。ドライバをインストールするには、ドライバを設定する GKE インストール DaemonSet をデプロイします。
手順については、NVIDIA GPU デバイス ドライバのインストールをご覧ください。
クラスタでノードの自動プロビジョニングを使用する場合は、GKE が GPU デバイス ドライバをインストールできるようにするスコープを使用して、ノードの自動プロビジョニングも構成する必要があります。手順については、ノードの自動プロビジョニングでの GPU の使用をご覧ください。
ノードで使用可能な GPU リソースを確認する
ノードに表示される GPU の数が、GPU タイム シェアリングを有効にしたときに指定した数と一致することを確認するには、ノードの説明を入力します。
kubectl describe nodes NODE_NAME
出力は次のようになります。
...
Capacity:
  ...
  nvidia.com/gpu:             3
Allocatable:
  ...
  nvidia.com/gpu:             3
この出力例では、ノード上の GPU リソースの数は 3 個です。これは、max-shared-clients-per-gpu に指定された値が 3 で、ノードに接続された物理 GPU の count が 1 であったためです。別の例として、物理 GPU の count が 2 だった場合、出力には、割り当て可能な GPU リソースが 6 個(物理 GPU ごとに 3 個)表示されます。
GPU タイム シェアリングを使用するワークロードをデプロイする
GPU ワークロードをデプロイするアプリケーションの運用者は、マニフェストの nodeSelector に適切なノードラベルを指定することで、GPU タイム シェアリングを有効にできます。リクエストを計画するときは、リクエストの上限を確認して、GKE でデプロイが拒否されないようにしてください。
GPU タイム シェアリングを使用するワークロードをデプロイする手順は次のとおりです。
- ワークロードのマニフェストに次のラベルの - nodeSelectorを追加します。- cloud.google.com/gke-gpu-sharing-strategy: time-sharing: GPU タイム シェアリングを使用するノードを選択します。
- cloud.google.com/gke-max-shared-clients-per-gpu: "CLIENTS_PER_GPU": 基盤となる GPU を特定の数のコンテナが共有できるようにするノードを選択します。
 
- spec.containers.resources.limitsのコンテナ仕様に- nvidia.com/gpu=1GPU リソース リクエストを追加します。
たとえば、次の手順では、GPU タイム シェアリング ノードプールに 3 つの Pod をデプロイする方法を説明します。GKE は、各コンテナを同じ物理 GPU に割り当てます。コンテナは、そのコンテナに接続されている GPU の UUID を出力します。
- 次のマニフェストを gpu-timeshare.yamlとして保存します。
Autopilot
apiVersion: apps/v1 kind: Deployment metadata: name: cuda-simple spec: replicas: 3 selector: matchLabels: app: cuda-simple template: metadata: labels: app: cuda-simple spec: nodeSelector: cloud.google.com/gke-accelerator: "GPU_TYPE" cloud.google.com/gke-gpu-sharing-strategy: "time-sharing" cloud.google.com/gke-max-shared-clients-per-gpu: "CLIENTS_PER_GPU" cloud.google.com/gke-accelerator-count: "GPU_COUNT" containers: - name: cuda-simple image: nvidia/cuda:11.0.3-base-ubi7 command: - bash - -c - | /usr/local/nvidia/bin/nvidia-smi -L; sleep 300 resources: limits: nvidia.com/gpu: 1
次のように置き換えます。
- GPU_TYPE: GPU タイプ。
- CLIENTS_PER_GPU: この GPU を使用するワークロードの数。この例では、- 3を使用します。
- GPU_COUNT: ノードに接続する GPU の数この例では、- 1を使用します。
Standard
apiVersion: apps/v1 kind: Deployment metadata: name: cuda-simple spec: replicas: 3 selector: matchLabels: app: cuda-simple template: metadata: labels: app: cuda-simple spec: nodeSelector: cloud.google.com/gke-gpu-sharing-strategy: "SHARING_STRATEGY" cloud.google.com/gke-max-shared-clients-per-gpu: "CLIENTS_PER_GPU" containers: - name: cuda-simple image: nvidia/cuda:11.0.3-base-ubi7 command: - bash - -c - | /usr/local/nvidia/bin/nvidia-smi -L; sleep 300 resources: limits: nvidia.com/gpu: 1
次のように置き換えます。
- SHARING_STRATEGYを「time-sharing」に設定して、GPU のタイム シェアリングをリクエストします。
- CLIENTS_PER_GPU: この GPU を使用するワークロードの数。この例では、- 3を使用します。
- 次のようにマニフェストを適用します。 - kubectl apply -f gpu-timeshare.yaml
- すべての Pod が実行されていることを確認します。 - kubectl get pods -l=app=cuda-simple
- Pod のログを調べて、GPU の UUID を表示します。 - kubectl logs POD_NAME- 出力は次のようになります。 - GPU 0: Tesla V100-SXM2-16GB (UUID: GPU-0771302b-eb3a-6756-7a23-0adcae8efd47)
- ノードに物理 GPU が 1 つ接続されている場合は、同じノード上の他の Pod のログを調べて、GPU UUID が同じであることを確認します。 - kubectl logs POD2_NAME- 出力は次のようになります。 - GPU 0: Tesla V100-SXM2-16GB (UUID: GPU-0771302b-eb3a-6756-7a23-0adcae8efd47)
マルチインスタンス GPU で GPU タイム シェアリングを使用する
プラットフォーム管理者は、複数の GKE GPU 機能を組み合わせることができます。GPU タイム シェアリングは、1 つの物理 GPU を最大 7 つのスライスにパーティショニングするマルチインスタンス GPU で動作します。これらのパーティションは互いに分離されています。マルチインスタンス GPU パーティションごとに GPU タイム シェアリングを構成できます。
たとえば、gpu-partition-size を 1g.5gb に設定すると、基盤となる GPU が 7 つのパーティションに分割されます。また、max-shared-clients-per-gpu を 3 に設定すると、各パーティションは最大 3 つのコンテナをサポートするため、合計 21 個の GPU タイム シェアリング デバイスをその物理 GPU に割り当てることができます。gpu-partition-size を実際のパーティションに変換する方法については、マルチインスタンス GPU パーティションをご覧ください。
GPU タイム シェアリングを有効にしてマルチインスタンス GPU クラスタを作成するには、次のコマンドを実行します。
Autopilot
Autopilot では、両方のノードセレクタ セットを使用して、GPU タイム シェアリングとマルチインスタンス GPU を一緒に使用できます。
apiVersion: apps/v1
kind: Deployment
metadata:
  name: cuda-simple
spec:
  replicas: 7
  selector:
    matchLabels:
      app: cuda-simple
  template:
    metadata:
      labels:
        app: cuda-simple
    spec:
      nodeSelector:
        cloud.google.com/gke-gpu-partition-size: 1g.5gb
        cloud.google.com/gke-gpu-sharing-strategy: time-sharing
        cloud.google.com/gke-max-shared-clients-per-gpu: "3"
        cloud.google.com/gke-accelerator: nvidia-tesla-a100
        cloud.google.com/gke-accelerator-count: "1"
      containers:
      - name: cuda-simple
        image: nvidia/cuda:11.0.3-base-ubi7
        command:
        - bash
        - -c
        - |
          /usr/local/nvidia/bin/nvidia-smi -L; sleep 300
        resources:
          limits:
            nvidia.com/gpu: 1
Standard
Standard では、次のコマンドを実行して、GPU タイム シェアリング マルチ インスタンス クラスタを作成する必要があります。
gcloud container node-pools create NODEPOOL_NAME \
    --cluster=CLUSTER_NAME \
    --location=CONTROL_PLANE_LOCATION \
    --machine-type=MACHINE_TYPE \
    --accelerator=type=nvidia-tesla-a100,count=GPU_QUANTITY,gpu-partition-size=PARTITION_SIZE,gpu-sharing-strategy=time-sharing,max-shared-clients-per-gpu=CLIENTS_PER_GPU,gpu-driver-version=DRIVER_VERSION
PARTITION_SIZE は、必要なマルチインスタンス GPU パーティション サイズ(1g.5gb など)に置き換えます。
制限事項
- GPU タイム シェアリングを使用すると、GKE は物理 GPU を共有するコンテナ間でアドレス空間の分離、パフォーマンスの分離、エラーの分離を適用します。ただし、GPU にはメモリ上限は適用されません。メモリ不足(OOM)の問題を回避するには、ワークロードで GPU メモリの上限を設定します。セキュリティの問題を回避するには、同じ信頼境界内にあるワークロードのみを GPU タイム シェアリングにデプロイします。
- GKE は、容量割り当て中に予期しない動作が発生しないように、特定の GPU タイム シェアリング リクエストを拒否することがあります。詳細については、GPU タイム シェアリングの GPU リクエストをご覧ください。
- 1 つの物理 GPU でタイム シェアリングを使用できるコンテナの最大数は 48 です。GPU タイム シェアリングの構成を計画する場合は、ワークロードのリソースのニーズと基盤となる物理 GPU の容量を考慮して、パフォーマンスと応答性を最適化してください。
次のステップ
- GKE で利用可能な GPU 共有戦略の詳細を確認する。
- GPU について学習する。
- マルチインスタンス GPU の実行の詳細を確認する。
- NVIDIA GPU のコンピューティング プリエンプションの詳細については、NVIDIA Pascal 調整ガイドをご覧ください。