このページでは、Google Kubernetes Engine(GKE)ノード内の 1 つの NVIDIA® GPU ハードウェア アクセラレータに対する GPU タイム シェアリング アクセスを複数のワークロードに許可する方法について説明します。GPU タイム シェアリングの仕組み、制限事項、GPU タイム シェアリングを使用する必要がある場合の例については、GKE での GPU タイム シェアリングをご覧ください。
概要
GPU タイム シェアリングは、ノードに接続された単一の物理 GPU を複数のコンテナで共有できるようにする GKE 機能です。GKE で GPU タイム シェアリングを使用すると、接続された GPU をより効率的に使用し、運用コストを削減できます。
このガイドの対象者
このガイドは、次のいずれかのユーザーを対象としています。
- プラットフォーム管理者: GKE クラスタの作成と管理、インフラストラクチャとリソース要件の計画、クラスタのパフォーマンスのモニタリングを行います。
- アプリケーション デベロッパー: GKE クラスタにワークロードを設計してデプロイします。GPU タイム シェアリングをリクエストする手順については、GPU タイム シェアリングを使用するワークロードをデプロイするをご覧ください。
要件
- 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
を実行して最新のバージョンを取得する。
- 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 \
--region=COMPUTE_REGION \
--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
: 新しいクラスタの名前。COMPUTE_REGION
: 新しいクラスタの Compute Engine のリージョン。ゾーンクラスタの場合は、--zone=COMPUTE_ZONE
を指定します。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 \
--machine-type=MACHINE_TYPE \
--region=COMPUTE_REGION \
--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 以降を実行する必要があります。COMPUTE_REGION
: クラスタの Compute Engine のリージョン。ゾーンクラスタの場合は、--zone=COMPUTE_ZONE
を指定します。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=1
GPU リソース リクエストを追加します。
たとえば、次の手順では、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 \
--machine-type=MACHINE_TYPE \
--region=COMPUTE_REGION \
--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 調整ガイドをご覧ください。