カスタム AI 最適化 A3 Edge GKE クラスタを作成する

このページでは、A3 Edge 仮想マシン(VM)を使用して AI と ML のワークロードをサポートする、AI 最適化された Google Kubernetes Engine(GKE)クラスタを作成する方法について説明します。A3 Edge マシンは、ターゲットを絞ったワークロード配置、コンパクト配置、高度なクラスタ メンテナンス制御、TAS などの機能を使用して、大規模な AI クラスタと ML クラスタを実行できるように設計されています。詳細については、クラスタ管理の概要をご覧ください。

GKE は、組織の多様なワークロードを実行するための単一のプラットフォーム サーフェスを提供し、複数のプラットフォームを管理する運用上の負担を軽減します。高性能な分散事前トレーニング、モデルのファインチューニング、モデルの推論、アプリケーションのサービング、サポート サービスなどのワークロードを実行できます。

このページでは、GPUDirect-TCPX、gVNIC、マルチネットワーキングを使用して Google Kubernetes Engine(GKE)Standard クラスタと Autopilot クラスタを作成する方法について説明します。

このページは、ML ワークロードを利用する ML エンジニアとプラットフォーム管理者を対象としています。 Google Cloud のコンテンツで使用されている一般的なロールとタスクの例の詳細については、一般的な GKE ユーザーのロールとタスクをご覧ください。

人工知能(AI)、ML、ハイ パフォーマンス コンピューティング(HPC)アプリケーションでは、ジョブの完了時間を短縮してパフォーマンスを最適化するために、強力なアクセラレーションが必要となります。たとえば、会話型 AI と画像生成に焦点を当てた ML モデルには、高いスケーラビリティとコンピューティング能力が求められます。

このページでは、ネットワーク インターフェース カード(NIC)や TCP などのネットワーク テクノロジーと、NVIDIA Collective Communications Library(NCCL)などのアクセラレータ テクノロジーに精通していることを前提としています。

Google Cloud GPU スーパーコンピュータについて

Google Cloud には、スケーラブルで大規模なモデル用に構築され、アクセラレータ用に最適化されたスーパーコンピュータがあります。これらの GPU マシンタイプでは、最大 3,600 Gbps のネットワーク帯域幅を使用できます。

GKE ワークロードでは、単一ノードで使用可能なすべての GPU とセカンダリ NIC を使用し、使用可能な帯域幅の大半を使用する必要があります。このドキュメントで説明するソリューションは、高パフォーマンス、高スループット、低レイテンシを必要とするワークロード向けに設計されています。

帯域幅を最大化するために必要な機能

GPU スーパーコンピュータ ノードのネットワーク帯域幅を最大化するには、次の機能を使用する必要があります。

  • GPUDirect ネットワーキング スタック: A3 Edge は、カスタムのリモート ダイレクト メモリ アクセス(RDMA)用に 3 つのネットワーキング スタックをサポートしています。A3 Edge マシンは、GPUDirect-TCPX を使用して、GPU との間のパケット ペイロードの転送に必要なオーバーヘッドを削減します。GPUDirect を使用しない GPU と比較すると、スループットが大幅に向上します。
  • gVNIC: パケット ヘッダー分割、フロー ステアリング、バッファ管理などの GPUDirect 機能を有効にします。GPUDirect-TCPX を使用するには、gVNIC が必要です。gVNIC の詳細については、GPU ノードのネットワーク トラフィック速度を上げるをご覧ください。

また、次の機能を有効にして構成する必要があります。

  • マルチネットワーキング: アクセラレータ最適化マシンにセカンダリ NIC を追加します。競合を避けるため、各 NIC はそれぞれの VPC 内の個別のサブネットに関連付けられます。マルチネットワーク サポートの詳細については、Pod のマルチネットワーク サポートを設定するをご覧ください。
  • 配置ポリシー: リソース配置ポリシーを使用して、特定のワークロードのすべての GPU ノードを物理的に近いサーバーに配置し、レイテンシを最小限に抑えます。詳細については、GKE ノードのコンパクト プレースメントを定義するをご覧ください。

手順の概要

GPUDirect-TCPX、gVNIC、マルチネットワーキング、コンパクト プレースメント ポリシーを一緒に使用するには、次の操作を行います。

  1. Virtual Private Cloud(VPC)とサブネットを作成する
  2. GKE 環境を作成する
  3. GPUDirect バイナリと NCCL プラグインをインストールする
  4. NRI デバイス インジェクタ プラグインをデプロイする
  5. テスト ワークロードをデプロイして GPUDirect の設定を確認する
  6. 独自のワークロードに GPUDirect を採用する

始める前に

作業を始める前に、次のタスクが完了していることを確認してください。

  • Google Kubernetes Engine API を有効にする。
  • Google Kubernetes Engine API を有効化
  • このタスクに Google Cloud CLI を使用する場合は、gcloud CLI をインストールして初期化します。gcloud CLI をインストール済みの場合は、gcloud components update コマンドを実行して最新のバージョンを取得します。以前のバージョンの gcloud CLI では、このドキュメントのコマンドを実行できない場合があります。
  • A3 Edge VM の容量があることを確認します。この容量を取得するには、まず使用オプションから選択します。このページの手順に沿って操作するには、オンデマンド容量、オンデマンド予約、または最大 90 日間の将来の予約(カレンダー モード)を使用します。使用オプションを選択したら、それぞれの指示に従って、選択した使用オプションを使用して容量を取得します。
  • H100 GPU に十分な割り当てがあることを確認します。割り当ての増加をリクエストするには、GPU 割り当てをご覧ください。

要件

GPUDirect-TCPX には次の要件が適用されます。

標準

  • GPUDirect-TCPX は、特定のパッチ バージョンを使用する利用可能なすべての GKE マイナー バージョンでサポートされています。
    • GKE バージョン 1.30~1.33 の場合は、任意のパッチ バージョンを使用します。
    • GKE バージョン 1.34 の場合は、パッチ バージョン 1.34.5-gke.1153000 以降を使用します。
    • GKE バージョン 1.35 の場合は、パッチ バージョン 1.35.2-gke.1485000 以降を使用します。
    • GKE バージョン 1.36 以降の場合は、任意のパッチ バージョンを使用します。
  • GKE ノードで Container-Optimized OS(COS)ノードイメージが使用されている必要があります。Ubuntu と Windows のノードイメージはサポートされません。
  • GPU ノードで NVIDIA ドライバ バージョン 535 以降が使用されている必要があります。
  • GKE Dataplane V2 を使用する必要があります。
  • GKE バージョン 1.34 以降では、GPUDirect-TCPX インストーラのバージョン 3.1.9 以降と、GPUDirect-TCPX サイドカーのバージョン 2.0.12 以降を使用する必要があります。インストーラとサイドカーのバージョンは 1 対 1 で対応している必要があります。たとえば、インストーラ バージョン 3.1.12 はサイドカー バージョン 2.0.15 に対応します。インストーラとサイドカーのバージョンについては、GPUDirect-TCPX リリースノートをご覧ください。
  • 複数のノードプール間で実行される GPUDirect-TCPX ワークロードの場合、すべてのノードプールが同じ Compute Engine ゾーンに存在し、同じネットワーク セット(VPC やサブネットなど)を使用する必要があります。

Autopilot

  • GPUDirect-TCPX を使用するには、クラスタで次の最小 GKE パッチ バージョンを実行する必要があります。
    • GKE バージョン 1.31 の場合は、パッチ バージョン 1.31.1-gke.1621000 以降を使用します。
    • GKE バージョン 1.32 ~ 1.33 の場合は、任意のパッチ バージョンを使用します。
    • GKE バージョン 1.34 の場合は、パッチ バージョン 1.34.5-gke.1153000 以降を使用します。
    • GKE バージョン 1.35 の場合は、パッチ バージョン 1.35.2-gke.1485000 以降を使用します。
    • GKE バージョン 1.36 以降の場合は、任意のパッチ バージョンを使用します。
  • GPU ノードでは、NVIDIA ドライバ バージョン 535 以降を使用する必要があります。
  • GKE Dataplane V2 を使用する必要があります。
  • GKE バージョン 1.34 以降では、GPUDirect-TCPX インストーラのバージョン 3.1.9 以降と、GPUDirect-TCPX サイドカーのバージョン 2.0.12 以降を使用する必要があります。インストーラとサイドカーのバージョンは 1 対 1 で対応している必要があります。たとえば、インストーラ バージョン 3.1.12 はサイドカー バージョン 2.0.15 に対応します。インストーラとサイドカーのバージョンの詳細については、GPUDirect-TCPX リリースノートをご覧ください。
  • 複数のノードプール間で実行される GPUDirect-TCPX ワークロードの場合、すべてのノードプールが同じ Compute Engine ゾーンに存在し、同じネットワーク セット(VPC やサブネットなど)を使用する必要があります。

制限事項

次の制限が適用されます。

VPC とサブネットを作成する

ノードに追加する仮想 NIC ごとに、プロジェクト内に個別の VPC ネットワークを作成します。各 VPC ネットワークには、内部ネットワーク トラフィックを許可するサブネットとファイアウォール ルールが必要です。

  1. 帯域幅を最大にするため、4 つの新しいネットワークを作成することをおすすめします。

    for N in $(seq 1 4); do
    gcloud compute networks create PREFIX-net-$N \
        --subnet-mode=custom \
        --mtu=8244
    
    gcloud compute networks subnets create PREFIX-sub-$N \
        --network=PREFIX-net-$N \
        --region=REGION \
        --range=SUBNET_RANGE
    
    gcloud compute firewall-rules create PREFIX-internal-$N \
    --network=PREFIX-net-$N \
    --action=ALLOW \
    --rules=tcp:0-65535,udp:0-65535,icmp \
    --source-ranges=SOURCE_RANGE
    done
    

    次のように置き換えます。

    • PROJECT_ID: 実際の Google Cloud プロジェクト ID。
    • REGION: 各サブネットの Compute Engine リージョン。
    • SUBNET_RANGE: 各サブネットの IP アドレス範囲(CIDR 表記)。この例のコマンドは 4 つのサブネットに対して繰り返し使用します。このため、変数を使用して各サブネットの IP アドレスを変更します。たとえば、最初のサブネットで 192.168.1.0/24 を使用し、2 番目のサブネットで 192.168.2.0/24 を使用するように 192.168.$N.0/24 を指定します。
    • SOURCE_RANGE: 上り(内向き)トラフィックを許可するファイアウォール ルールの送信元 IP アドレス範囲(CIDR 表記)。例: 192.168.0.0/16
  2. ネットワークが作成されたことを確認します。

    gcloud compute networks list
    

GKE 環境を作成する

マルチネットワーキング(プレビュー)を使用する新しい GKE クラスタを作成し、次の特性を持つ GPU ノードプールを作成します。

  • gVNIC が有効
  • 各セカンダリ NIC に指定されたマルチネットワーキング サブネット
  • ノードをバッキングする H100 GPU を備えた A3 Edge マシンシリーズ
  • 最新の NVIDIA ドライバのインストール

マルチネットワーキングを使用するように既存のクラスタを更新することはできません。

  1. クラスタを作成します。

    標準

    gcloud beta container clusters create CLUSTER_NAME \
      --enable-dataplane-v2 \
      --enable-ip-alias \
      --location=CONTROL_PLANE_LOCATION \
      --enable-multi-networking \
      --cluster-version=VERSION \
      --no-enable-autoupgrade \
      --project=PROJECT_ID
    

    次のように置き換えます。

    • CLUSTER_NAME: 新しいクラスタの名前。
    • CONTROL_PLANE_LOCATION: クラスタのコントロール プレーンの Compute Engine のロケーション。リージョン クラスタの場合はリージョン、ゾーンクラスタの場合はゾーンを指定します。
    • VERSION: 要件で説明されているように、GPUDirect-TCPX をサポートする GKE バージョン。

    Autopilot

    gcloud beta container clusters create-auto CLUSTER_NAME \
        --project=PROJECT_ID \
        --location=CONTROL_PLANE_LOCATION \
        --cluster-version=VERSION \
        --enable-multi-networking \
        --workload-policies=allow-net-admin
    

    次のように置き換えます。

    • CLUSTER_NAME: 新しいクラスタの名前。
    • CONTROL_PLANE_LOCATION: クラスタのコントロール プレーンの Compute Engine のリージョン
    • VERSION: 要件で説明されているように、GPUDirect-TCPX をサポートする GKE バージョン。
  2. 作成した VPC ネットワークとサブネットワークに対応する Network リソースと GKENetworkParamSet リソースをクラスタに作成します。

    kubectl apply -f - <<EOF
    apiVersion: networking.gke.io/v1
    kind: Network
    metadata:
      name: vpc1
    spec:
      parametersRef:
        group: networking.gke.io
        kind: GKENetworkParamSet
        name: vpc1
      type: Device
    ---
    apiVersion: networking.gke.io/v1
    kind: Network
    metadata:
      name: vpc2
    spec:
      parametersRef:
        group: networking.gke.io
        kind: GKENetworkParamSet
        name: vpc2
      type: Device
    ---
    apiVersion: networking.gke.io/v1
    kind: Network
    metadata:
      name: vpc3
    spec:
      parametersRef:
        group: networking.gke.io
        kind: GKENetworkParamSet
        name: vpc3
      type: Device
    ---
    apiVersion: networking.gke.io/v1
    kind: Network
    metadata:
      name: vpc4
    spec:
      parametersRef:
        group: networking.gke.io
        kind: GKENetworkParamSet
        name: vpc4
      type: Device
    ---
    apiVersion: networking.gke.io/v1
    kind: GKENetworkParamSet
    metadata:
      name: vpc1
    spec:
      vpc: PREFIX-net-1
      vpcSubnet: PREFIX-sub-1
      deviceMode: NetDevice
    ---
    apiVersion: networking.gke.io/v1
    kind: GKENetworkParamSet
    metadata:
      name: vpc2
    spec:
      vpc: PREFIX-net-2
      vpcSubnet: PREFIX-sub-2
      deviceMode: NetDevice
    ---
    apiVersion: networking.gke.io/v1
    kind: GKENetworkParamSet
    metadata:
      name: vpc3
    spec:
      vpc: PREFIX-net-3
      vpcSubnet: PREFIX-sub-3
      deviceMode: NetDevice
    ---
    apiVersion: networking.gke.io/v1
    kind: GKENetworkParamSet
    metadata:
      name: vpc4
    spec:
      vpc: PREFIX-net-4
      vpcSubnet: PREFIX-sub-4
      deviceMode: NetDevice
    EOF
    

    これらのリソースは、パススルー モードで GPU トラフィックの NIC を構成するように GKE に指示します。このトラフィックには、eBPF を使用した組み込みネットワーキング プログラミングは適用されません。

GPU ノードプールを作成する(Standard のみ)

  1. H100 GPU 用のノードプールを作成します。

    gcloud container node-pools create NODE_POOL_NAME \
        --cluster=CLUSTER_NAME \
        --location=CONTROL_PLANE_LOCATION \
        --machine-type=a3-edgegpu-8g \
        --accelerator=type=nvidia-h100-80gb,count=8,gpu-driver-version=LATEST \
        --additional-node-network=network=PREFIX-net-1,subnetwork=PREFIX-sub-1 \
        --additional-node-network=network=PREFIX-net-2,subnetwork=PREFIX-sub-2 \
        --additional-node-network=network=PREFIX-net-3,subnetwork=PREFIX-sub-3 \
        --additional-node-network=network=PREFIX-net-4,subnetwork=PREFIX-sub-4 \
        --enable-gvnic \
        --no-enable-autoupgrade \
        --placement-policy=POLICY_NAME \
        --reservation-affinity=specific \
        --reservation=projects/PROJECT_ID/reservations/RESERVATION_NAME/reservationBlocks/BLOCK_NAME
    

    NODE_POOL_NAME は、ノードプールの名前に置き換えます。

    予約を使用するには、--placement-policy--reservation-affinity--reservation フラグを使用します。これらのフラグを指定して、ノードプールのポリシー名と予約を構成します。予約にリソース ポリシーが必要ない場合は、--placement-policy フラグを省略します。

    --reservation-affinity フラグは、specific または any の値を取ることができます。ただし、高パフォーマンスの分散 AI ワークロードには、特定の予約を使用することをおすすめします。予約の名前や予約内の特定のブロックの名前など、予約に関する情報を確認できます。オンデマンド予約のこれらの値を確認するには、予約の一覧を表示するか、将来の予約リクエストを表示するをご覧ください。

    予約を使用するには、次のように置き換えます。

    • PROJECT_ID: 省略可。 Google Cloudプロジェクト ID。予約が現在のプロジェクトにある場合(共有予約ではない場合)、予約値の projects/PROJECT_ID/reservations/ を省略できます。
    • RESERVATION_NAME: 予約の名前。
    • BLOCK_NAME: 省略可。予約内の特定のブロックの名前。特定のブロックを使用しない場合は、/reservationBlocks/BLOCK_NAME を省略します。

    このコマンドが失敗した場合、プロジェクトに十分な H100 GPU 割り当てがない可能性があります。割り当てがあることを確認してから、コマンドを再試行してください。

  2. ノードプールを作成した後に、各ノードに GPU がアタッチされていることを確認します。

    1. クラスタ内のノードのリストを取得します。

      kubectl get nodes
      
    2. 各 GPU ノードに 8 つの GPU があることを確認します。

      kubectl describe node NODE_NAME
      

      NODE_NAME は、記述するノードの名前に置き換えます。

      出力は次のようになります。

      Capacity:
        ...
        nvidia.com/gpu:             8
      Allocatable:
        ...
        nvidia.com/gpu:             8
      

GPUDirect バイナリと NCCL プラグインをインストールする

このセクションでは、DaemonSet を使用して GPUDirect-TCPX バイナリと特定の NCCL ライブラリ バージョンをインストールする方法について説明します。

この DaemonSet は次の処理を行います。

  1. NCCL ライブラリと GPUDirect-TCPX バイナリをノードにインストールします。
  2. ライブラリとバイナリを VM の /home/kubernetes/bin/nvidia/lib64 ディレクトリに保存します。デフォルトでは、このディレクトリは NCCL と GPUDirect-TCPX を使用する必要のある GPU コンテナの /usr/local/nvidia/lib64 パスにマウントされます。

バイナリをインストールして NCCL を構成する手順は次のとおりです。

標準

  1. GitHub の nccl-tcpx-installer.yaml Daemonset マニフェストを確認します。

  2. DaemonSet をデプロイします。

    kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/container-engine-accelerators/master/gpudirect-tcpx/nccl-tcpx-installer.yaml
    

    NCCL プラグインの実行が開始するまで 2 分ほどかかります。

  3. DaemonSet Pod のステータスを確認します。

    kubectl get pods -n=kube-system -l=name=nccl-tcpx-installer
    

    出力は次のようになります。

    nccl-tcpx-installer-6c2pv                    1/1     Running   0          2m11s
    nccl-tcpx-installer-qgg82                    1/1     Running   0          2m11s
    

Autopilot

  1. GitHub の nccl-tcpx-installer-autopilot.yaml Daemonset マニフェストを確認します。

  2. 専用の Namespace を作成します。

    kubectl create ns gpudirect-system
    
  3. DaemonSet をデプロイします。

    kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/container-engine-accelerators/master/gpudirect-tcpx/nccl-tcpx-installer-autopilot.yaml
    

    NCCL プラグインの実行が開始するまでに 2 分ほどかかります。

NRI デバイス インジェクタ プラグインをデプロイする

このセクションでは、DaemonSet を使用して NRI デバイス インジェクタをインストールする方法について説明します。このプラグインは次の処理を行います。

  1. H100 GPU を搭載したノードで Node Resource Interface(NRI)を有効にします。GKE バージョン 1.29 以降では、NRI はデフォルトで有効になっています。
  2. Pod アノテーションで指定されたコンテナに GPU デバイスを挿入する NRI デバイス インジェクタ プラグイン コンテナをデプロイします。

プラグインのインストールは、次のようにします。

標準

  1. GitHub の nri-device-injector.yaml Deployment マニフェストを確認します。

  2. DaemonSet をデプロイします。

    kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/container-engine-accelerators/master/nri_device_injector/nri-device-injector.yaml
    

    NCCL プラグインの実行が開始するまで 2 分ほどかかります。

  3. DaemonSet Pod のステータスを確認します。

    kubectl get pods -n=kube-system -l=name=device-injector
    

    出力は次のようになります。

    # Output
    device-injector-md6hb                         1/1     Running   0       4h54m
    device-injector-vh9bm                         1/1     Running   0       4h54m
    

Autopilot

  1. GitHub の nri-device-injector-autopilot.yaml Deployment マニフェストを確認します。

  2. DaemonSet をデプロイします。

    kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/container-engine-accelerators/master/nri_device_injector/nri-device-injector-autopilot.yaml
    

    NCCL プラグインの実行が開始するまでに 2 分ほどかかります。

テスト ワークロードをデプロイする

このセクションでは、サンプル ワークロードをデプロイし、NCCL と GPUDirect-TCPX が期待どおりに動作することを確認します。このサンプル ワークロードは、次のことを行います。

  1. 2 つの Pod をデプロイします。各 Pod は、H100 GPU を備えたノードで実行されます。
  2. 各 Pod にサイドカー コンテナをデプロイして、これらの Pod が GPUDirect-TCPX を使用できるようにします。

このワークロードには、Pod が GPUDirect-TCPX を使用できるようにするサービスを実行する tcpx-daemon というサイドカー コンテナが含まれています。このサイドカー コンテナは、GPUDirect-TCPX を使用する独自の環境の Pod に追加する必要があります。マニフェストに追加する必須フィールドのスニペットについては、マニフェストに GPUDirect を追加するをご覧ください。

  1. GitHub の nccl-config.yaml ConfigMap マニフェストを確認します。このマニフェストでは、NCCL Allgather テストを初期化し、NCCL 固有の構成を設定するスクリプトをデプロイします。

  2. クラスタモードに応じて、次の操作を行います。

  3. ConfigMap とテスト ワークロードをデプロイします。

    標準

    kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/container-engine-accelerators/master/gpudirect-tcpx/nccl-config.yaml
    kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/container-engine-accelerators/master/gpudirect-tcpx/nccl-test-latest.yaml
    

    Autopilot

    kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/container-engine-accelerators/master/gpudirect-tcpx/nccl-config.yaml
    kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/container-engine-accelerators/master/gpudirect-tcpx/nccl-test-latest-autopilot.yaml
    
  4. Pod が実行され、準備ができていることを確認します。イメージはサイズが大きく(約 5 GB)、ダウンロードに数分かかることがあります。

    kubectl get pods -w
    

    このコマンドは更新をモニタリングし、Pod のステータスが変更されると新しい行を出力します。出力は次のようになります。

    NAME               READY   STATUS              RESTARTS   AGE
    nccl-test-host-1   0/2     ContainerCreating   0          23s
    nccl-test-host-2   2/2     Running             0          23s
    nccl-test-host-1   2/2     Running             0          46s
    

    すべての Pod の STATUS メッセージが Running になり、READY の値が 2/2 になるまで待ってから、次のステップに進みます。

  5. 次のコマンドを実行して、ノードの NCCL all-gather テストをトリガーします。

    kubectl exec \
      --stdin --tty --container=nccl-test nccl-test-host-1 \
      -- /configs/allgather.sh nccl-host-1 nccl-host-2
    

    出力は次のようになります。

    標準

      #                                                              out-of-place                       in-place
      #        size         count      type   redop    root     time   algbw   busbw #wrong     time   algbw   busbw #wrong
      #         (B)    (elements)                               (us)  (GB/s)  (GB/s)            (us)  (GB/s)  (GB/s)
                  0             0     float    none      -1     0.24    0.00    0.00      0     0.18    0.00    0.00      0
                  0             0     float    none      -1     0.19    0.00    0.00      0     0.17    0.00    0.00      0
                  0             0     float    none      -1     0.17    0.00    0.00      0     0.17    0.00    0.00      0
                  0             0     float    none      -1     0.17    0.00    0.00      0     0.17    0.00    0.00      0
                  0             0     float    none      -1     0.17    0.00    0.00      0     0.17    0.00    0.00      0
                256             4     float    none      -1    235.2    0.00    0.00      0    235.1    0.00    0.00      0
                512             8     float    none      -1    241.0    0.00    0.00      0    236.1    0.00    0.00      0
               1024            16     float    none      -1    236.3    0.00    0.00      0    233.3    0.00    0.00      0
               2048            32     float    none      -1    234.1    0.01    0.01      0    233.4    0.01    0.01      0
               4096            64     float    none      -1    237.1    0.02    0.02      0    235.3    0.02    0.02      0
               8192           128     float    none      -1    236.2    0.03    0.03      0    235.2    0.03    0.03      0
              16384           256     float    none      -1    236.6    0.07    0.06      0    238.5    0.07    0.06      0
              32768           512     float    none      -1    237.9    0.14    0.13      0    238.8    0.14    0.13      0
              65536          1024     float    none      -1    242.3    0.27    0.25      0    239.4    0.27    0.26      0
             131072          2048     float    none      -1    263.0    0.50    0.47      0    275.1    0.48    0.45      0
             262144          4096     float    none      -1    279.2    0.94    0.88      0    269.9    0.97    0.91      0
             524288          8192     float    none      -1    273.5    1.92    1.80      0    273.5    1.92    1.80      0
            1048576         16384     float    none      -1    315.1    3.33    3.12      0    314.1    3.34    3.13      0
            2097152         32768     float    none      -1    319.2    6.57    6.16      0    311.5    6.73    6.31      0
            4194304         65536     float    none      -1    331.8   12.64   11.85      0    331.3   12.66   11.87      0
            8388608        131072     float    none      -1    356.3   23.54   22.07      0    353.8   23.71   22.23      0
           16777216        262144     float    none      -1    409.1   41.01   38.45      0    405.2   41.40   38.81      0
           33554432        524288     float    none      -1    451.4   74.34   69.69      0    447.7   74.94   70.26      0
           67108864       1048576     float    none      -1    713.4   94.07   88.19      0    713.8   94.01   88.13      0
          134217728       2097152     float    none      -1   1122.1  119.62  112.14      0   1116.3  120.23  112.72      0
          268435456       4194304     float    none      -1   1785.8  150.32  140.92      0   1769.2  151.72  142.24      0
          536870912       8388608     float    none      -1   2859.7  187.74  176.00      0   2852.6  188.20  176.44      0
         1073741824      16777216     float    none      -1   5494.1  195.44  183.22      0   5568.2  192.83  180.78      0
         2147483648      33554432     float    none      -1    10841  198.09  185.71      0    10798  198.88  186.45      0
         4294967296      67108864     float    none      -1    21453  200.21  187.70      0    21490  199.86  187.37      0
         8589934592     134217728     float    none      -1    42603  201.63  189.03      0    42670  201.31  188.73      0
      # Out of bounds values : 0 OK
      # Avg bus bandwidth    : 45.7587
      #
      ```
    

    Autopilot

    #                                                              out-of-place                       in-place
    #       size         count      type   redop    root     time   algbw   busbw #wrong     time   algbw   busbw #wrong
    #        (B)    (elements)                               (us)  (GB/s)  (GB/s)            (us)  (GB/s)  (GB/s)
        1048576         16384     float    none      -1    696.8    1.50    1.41      0    729.0    1.44    1.35      0
        2097152         32768     float    none      -1    776.4    2.70    2.53      0    726.7    2.89    2.71      0
        4194304         65536     float    none      -1    774.3    5.42    5.08      0    805.1    5.21    4.88      0
        8388608        131072     float    none      -1    812.1   10.33    9.68      0    817.6   10.26    9.62      0
       16777216        262144     float    none      -1   1035.2   16.21   15.19      0   1067.8   15.71   14.73      0
       33554432        524288     float    none      -1   1183.3   28.36   26.59      0   1211.8   27.69   25.96      0
       67108864       1048576     float    none      -1   1593.4   42.12   39.49      0   1510.5   44.43   41.65      0
      134217728       2097152     float    none      -1   2127.8   63.08   59.13      0   2312.7   58.03   54.41      0
      268435456       4194304     float    none      -1   3603.0   74.50   69.85      0   3586.2   74.85   70.17      0
      536870912       8388608     float    none      -1   7101.7   75.60   70.87      0   7060.9   76.03   71.28      0
    # Out of bounds values : 0 OK
    # Avg bus bandwidth    : 29.8293
    

独自のワークロードに GPUDirect を採用する

サンプル テスト ワークロードでクラスタ ネットワーキングが正常に機能していることを確認したら、次のステップとして、実際のワークロードに GPUDirect を採用します。GPUDirect を採用するには、NCCL 設定と Kubernetes Pod マニフェストを更新する必要があります。

必要な NCCL 構成設定を使用してパフォーマンスを改善する

次の Key-Value ペアは、GPUDirect-TCPX に必要な NCCL 構成設定です。NCCL を使用するワークロードをデプロイする場合は、パフォーマンスを最適化するために環境変数として設定します。

"LD_LIBRARY_PATH=\"${LD_LIBRARY_PATH}:/usr/local/nvidia/lib64\"",
"NCCL_SOCKET_IFNAME=\"eth0\"",
"NCCL_ALGO=Ring",
"NCCL_PROTO=Simple",
"NCCL_CROSS_NIC=0",
"NCCL_NET_GDR_LEVEL=PIX",
"NCCL_P2P_PXN_LEVEL=0",
"NCCL_GPUDIRECTTCPX_SOCKET_IFNAME=eth1,eth2,eth3,eth4",
"NCCL_GPUDIRECTTCPX_CTRL_DEV=eth0",
"NCCL_DYNAMIC_CHUNK_SIZE=524288",
"NCCL_P2P_NET_CHUNKSIZE=524288",
"NCCL_P2P_PCI_CHUNKSIZE=524288",
"NCCL_P2P_NVL_CHUNKSIZE=1048576",
"NCCL_BUFFSIZE=4194304",
"NCCL_NSOCKS_PERTHREAD=4",
"NCCL_SOCKET_NTHREADS=1",
"NCCL_GPUDIRECTTCPX_TX_BINDINGS=\"eth1:8-21,112-125;eth2:8-21,112-125;eth3:60-73,164-177;eth4:60-73,164-177\"",
"NCCL_GPUDIRECTTCPX_RX_BINDINGS=\"eth1:22-35,126-139;eth2:22-35,126-139;eth3:74-87,178-191;eth4:74-87,178-191\"",
"NCCL_GPUDIRECTTCPX_PROGRAM_FLOW_STEERING_WAIT_MICROS=500000"

マニフェストに GPUDirect を追加する

このセクションでは、Pod で GPUDirect を使用するために Kubernetes マニフェストに追加する必要がある必須フィールドについて説明します。

クラスタモードに応じて、次の操作を行います。

標準

  1. Pod メタデータに次のアノテーションを追加します。これらのアノテーションがないと、Pod には hostNetwork:true が必要になり、tcpx-daemon コンテナには privileged:true が必要になります。

    metadata:
      annotations:
        devices.gke.io/container.tcpx-daemon: |+
          - path: /dev/nvidia0
          - path: /dev/nvidia1
          - path: /dev/nvidia2
          - path: /dev/nvidia3
          - path: /dev/nvidia4
          - path: /dev/nvidia5
          - path: /dev/nvidia6
          - path: /dev/nvidia7
          - path: /dev/nvidiactl
          - path: /dev/nvidia-uvm
        networking.gke.io/default-interface: 'eth0'
        networking.gke.io/interfaces: |
          [
            {"interfaceName":"eth0","network":"default"},
            {"interfaceName":"eth1","network":"vpc1"},
            {"interfaceName":"eth2","network":"vpc2"},
            {"interfaceName":"eth3","network":"vpc3"},
            {"interfaceName":"eth4","network":"vpc4"},
          ]
    
  2. 次のフィールドを Pod 仕様に追加します。

    spec:
      volumes:
      - name: libraries
        hostPath:
          path: /home/kubernetes/bin/nvidia/lib64
      - name: sys
        hostPath:
          path: /sys
      - name: proc-sys
        hostPath:
          path: /proc/sys
    
  3. マニフェストに次のコンテナを追加して、tcpx-daemon サービスを実行します。

    - name: tcpx-daemon
      image: us-docker.pkg.dev/gce-ai-infra/gpudirect-tcpx/tcpgpudmarxd-dev:v2.0.9
      command:
        - /tcpgpudmarxd/build/app/tcpgpudmarxd
        - --gpu_nic_preset
        - a3vm
        - --gpu_shmem_type
        - fd
        - --uds_path
        - /run/tcpx
        - --setup_param
        - \"--verbose 128 2 0 \"
      securityContext:
        capabilities:
            add:
              - NET_ADMIN
      volumeMounts:
        - name: libraries
          mountPath: /usr/local/nvidia/lib64
        - name: tcpx-socket
          mountPath: /run/tcpx
        - name: sys
          mountPath: /hostsysfs
        - name: proc-sys
          mountPath: /hostprocsysfs
      env:
        - name: LD_LIBRARY_PATH
          value: /usr/local/nvidia/lib64
    
  4. GPU をリクエストするコンテナに次のボリューム マウントを追加します。

    volumeMounts:
    - name: tcpx-socket
      mountPath: /tmp
    - name: libraries
      mountPath: /usr/local/nvidia/lib64
    
  5. 環境変数を追加して NCCL オプションを構成します。詳細については、このドキュメントの推奨される NCCL 構成設定を使用してパフォーマンスを改善するをご覧ください。

  6. すべての GPU コンテナに次の環境変数を追加します。

    env:
    - name: LD_LIBRARY_PATH
      value: /usr/local/nvidia/lib64
    

完成した Pod 仕様の例については、GitHub の nccl-test-latest.yaml マニフェストをご覧ください。

Autopilot

Autopilot モードでは、GKE がハードウェアをプロビジョニングできるように、Pod マニフェストで適切な GPU を選択する必要があります。

次のノードセレクタを Pod に追加します。

nodeSelector:
  cloud.google.com/gke-accelerator: a3-edgegpu-8g
  cloud.google.com/gke-gpu-driver-version: latest

また、予約済み容量を使用する場合は、予約に関する情報を提供できます。詳細については、Autopilot クラスタで容量予約を使用するの予約の使用に関するサブセクションをご覧ください。

  1. Pod メタデータに次のアノテーションを追加します。

    metadata:
      annotations:
        devices.gke.io/container.tcpx-daemon: |+
          - path: /dev/nvidia0
          - path: /dev/nvidia1
          - path: /dev/nvidia2
          - path: /dev/nvidia3
          - path: /dev/nvidia4
          - path: /dev/nvidia5
          - path: /dev/nvidia6
          - path: /dev/nvidia7
          - path: /dev/nvidiactl
          - path: /dev/nvidia-uvm
        networking.gke.io/default-interface: 'eth0'
        networking.gke.io/interfaces: |
          [
            {"interfaceName":"eth0","network":"default"},
            {"interfaceName":"eth1","network":"vpc1"},
            {"interfaceName":"eth2","network":"vpc2"},
            {"interfaceName":"eth3","network":"vpc3"},
            {"interfaceName":"eth4","network":"vpc4"},
          ]
    
  2. 次のフィールドを Pod 仕様に追加します。

    spec:
      volumes:
      - name: libraries
        hostPath:
          path: /home/kubernetes/bin/nvidia/lib64
      - name: sys
        hostPath:
          path: /sys
      - name: proc-sys
        hostPath:
          path: /proc/sys
    
  3. マニフェストに次のコンテナを追加して、tcpx-daemon サービスを実行します。

    - name: tcpx-daemon
      image: us-docker.pkg.dev/gce-ai-infra/gpudirect-tcpx/tcpgpudmarxd-dev:v2.0.9
      command:
        - /tcpgpudmarxd/build/app/tcpgpudmarxd
        - --gpu_nic_preset
        - a3vm
        - --gpu_shmem_type
        - fd
        - --uds_path
        - /run/tcpx
        - --setup_param
        - \"--verbose 128 2 0 \"
      securityContext:
        capabilities:
            add:
              - NET_ADMIN
      volumeMounts:
        - name: libraries
          mountPath: /usr/local/nvidia/lib64
        - name: tcpx-socket
          mountPath: /run/tcpx
        - name: sys
          mountPath: /hostsysfs
        - name: proc-sys
          mountPath: /hostprocsysfs
      env:
        - name: LD_LIBRARY_PATH
          value: /usr/local/nvidia/lib64
    
  4. GPU をリクエストするコンテナに次のボリューム マウントを追加します。

    volumeMounts:
    - name: tcpx-socket
      mountPath: /tmp
    - name: libraries
      mountPath: /usr/local/nvidia/lib64
    
  5. 環境変数を追加して NCCL オプションを構成します。詳細については、このドキュメントの推奨される NCCL 構成設定を使用してパフォーマンスを改善するをご覧ください。

完成した Pod 仕様の例については、GitHub の nccl-test-latest-autopilot.yaml マニフェストをご覧ください。

NCCL のデバッグログを収集する

NCCL エラーをロギングするには、次の NCCL 構成を追加することをおすすめします。

NCCL_DEBUG=INFO
NCCL_DEBUG_SUBSYS=INIT,NET,ENV,COLL,GRAPH
NCCL_DEBUG_FILE=/DIRECTORY/FILE_NAME.%h.%p
  • NCCL_DEBUG=INFO: デバッグ情報を出力します。
    • 大規模なワークロード(64 個以上のノード)では、広範なロギングが発生する可能性があります。このシナリオを回避するには、NCCL_DEBUG_FILE を指定していない限り、NCCL_DEBUG=WARN を設定してログをエラーのみに制限することをおすすめします。
  • NCCL_DEBUG_SUBSYS: NCCL がデバッグ情報を収集するサブシステムをフィルタします。次のサブシステムのログを収集することをおすすめします。

    • INIT: NCCL の初期化フェーズ。
    • NET: NCCL ネットワーク。
    • ENV: NCCL が使用する環境変数。
    • COLL: コレクティブ オペレーション。
    • GRAPH: トポロジの検出とグラフ検索。

    異なるサブシステムのログを収集する場合は、NCCL ドキュメントの NCCL_DEBUG_SUBSYS で、使用可能な値のリストをご覧ください。

  • NCCL_DEBUG_FILE(省略可): NCCL デバッグ ロギング出力を指定したファイルに転送します。この変数は NCCL ログを標準ファイルに書き込みます。これにより、ログ出力がアプリケーション出力と混在するのを防ぐことができます。また、この変数は、異なる NCCL ランクのログを異なるファイルに書き込むため、ログが混在することはありません。

    ファイル名の形式は次のようにします。

    /DIRECTORY/FILE_NAME.%h.%p
    

    次のように置き換えます。

    • DIRECTORY: ログファイルを保存するディレクトリ。
    • FILE_NAME: ログファイルの名前。

    プレースホルダ %h はノードのホスト名に解決され、%p はログを生成するプロセスのプロセス ID(PID)に解決されます。

NCCL ログのデバッグの詳細については、GKE での GPU のトラブルシューティングをご覧ください。

次のステップ