Autopilot モードのクラスタで GPU ネットワーク帯域幅を最大にする


このページでは、GPUDirect-TCPXO、GPUDirect-TCPX、gVNIC、マルチネットワーキングを使用して、Google Kubernetes Engine(GKE)Autopilot クラスタで高性能 GPU ワークロードのネットワーク帯域幅とスループットを最大にする方法について説明します。Standard クラスタを使用している場合は、Standard モードのクラスタで GPU ネットワーク帯域幅を最大にするをご覧ください。

このページは、ML ワークロードを利用する ML エンジニアとプラットフォーム管理者を対象としています。このページを読む前に、ネットワーク インターフェース カード(NIC)や TCP などのネットワーク テクノロジーと、NVIDIA Collective Communications Library(NCCL)などのアクセラレータ テクノロジーに精通している必要があります。

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

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

Google Cloud には、スケーラブルで大規模なモデル用に構築され、アクセラレータ用に最適化されたスーパーコンピュータがあります。このマシンには次のような利点があります。

  • 1 マシンあたり 8 個の NVIDIA H100 GPU。
  • プライマリ NIC で最大 200 Gbps の帯域幅。
  • セカンダリ NIC(A3 Mega マシンタイプでは最大 8 つ、A3 High マシンタイプでは最大 4 つ)。それぞれが GPU データ転送用に最大 200 Gbps の帯域幅をサポートします。

利点の詳細については、Compute Engine ドキュメントの A3 マシンシリーズをご覧ください。

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

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

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

  • GPUDirect ネットワーキング スタック: A3 マシンシリーズは、カスタムのリモート ダイレクト メモリ アクセス(RDMA)用に 2 つのネットワーキング スタックをサポートしています。
    • A3 High マシンタイプと NVIDIA H100 GPU では、GPUDirect-TCPX を使用して、GPU との間のパケット ペイロードの転送に必要なオーバーヘッドを削減します。GPUDirect を使用しない GPU と比較すると、スループットが大幅に向上します。
    • A3 Mega マシンタイプと NVIDIA H100 Mega GPU では、GPU から VM への通信をさらに改善する GPUDirect-TCPXO を使用します。
  • gVNIC: パケット ヘッダー分割、フロー ステアリング、バッファ管理などの GPUDirect 機能を有効にします。GPUDirect-TCPX または GPUDirect-TCPXO を使用するには、gVNIC が必要です。gVNIC の詳細については、GPU ノードのネットワーク トラフィック速度を上げるをご覧ください。
  • マルチネットワーキング: アクセラレータ最適化マシンにセカンダリ NIC を追加します。競合を避けるため、各 NIC はそれぞれの VPC 内の個別のサブネットに関連付けられます。マルチネットワーク サポートの詳細については、Pod のマルチネットワーク サポートを設定するをご覧ください。
  • 配置ポリシー: リソース配置ポリシーを使用して、特定のワークロードのすべての GPU ノードを物理的に近いサーバーに配置し、レイテンシを最小限に抑えます。詳細については、GKE ノードのコンパクト プレースメントを定義するをご覧ください。

手順の概要

これらの機能をすべて一緒に使用する手順は次のとおりです。

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

始める前に

作業を始める前に、次のことを確認してください。

  • Google Kubernetes Engine API を有効にする。
  • Google Kubernetes Engine API の有効化
  • このタスクに Google Cloud CLI を使用する場合は、gcloud CLI をインストールして初期化する。すでに gcloud CLI をインストールしている場合は、gcloud components update を実行して最新のバージョンを取得する。
  • H100 GPU に十分な割り当てがあることを確認します。追加の割り当てをリクエストするには、GPU 割り当てをご覧ください。

要件

特に明記されていない限り、次の要件は GPUDirect-TCPX と GPUDirect-TCPXO の両方に適用されます。

  • クラスタは、GKE バージョン 1.31.1-gke.1621000 以降を使用する必要があります。
  • GPU ノードでは、NVIDIA ドライバ バージョン 535 以降を使用する必要があります。
  • GKE Dataplane V2 を使用する必要があります。

制限事項

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

  • GPUDirect-TCPX と GPUDirect-TCPXO は、マルチインスタンス GPUGPU タイムシェアリングNVIDIA MPS ではサポートされていません。
  • NCCL FastSocket は使用できません。
  • GKE ワークロードでは、単一ノードで使用可能な GPU とセカンダリ NIC をすべて使用する必要があります。複数の Pod が単一のノードで GPUDirect-TCPX または GPUDirect-TCPXO を使用できません。
  • 使用できるマシンタイプは a3-highgpu-8ga3-megagpu-8g のみです。他の A3 マシンタイプはサポートされていません。

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

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

  1. プロジェクトに GPUDirect の VPC ネットワークを作成し、それぞれにサブネットとファイアウォール ルールを設定します。GPUDirect-TCPX のタブ(A3 High マシンタイプの場合)または GPUDirect-TCPXO のタブ(A3 Mega マシンタイプの場合)を選択して、手順を完了します。

    GPUDirect-TCPXO

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

    for N in $(seq 1 8); 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 表記)。この例のコマンドは 8 つのサブネットに対して繰り返し使用します。このため、変数を使用して各サブネットの 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

    GPUDirect-TCPX

    帯域幅を最大にするため、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 クラスタを作成します。マルチネットワーキングを使用するように既存のクラスタを更新することはできません。

GPUDirect-TCPXO

  1. GPUDirect-TCPXO をサポートする利用可能な GKE バージョンを選択します。バージョンを一覧取得するには、次のコマンドを実行します。

    gcloud container get-server-config \
        --format="yaml(validMasterVersions)" \
        --region=REGION \
        --project=PROJECT_ID
    

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

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

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

    以下を置き換えます。

    • CLUSTER_NAME: 新しいクラスタの名前。
    • VERSION: 要件で説明されているように、GPUDirect-TCPXO をサポートする GKE バージョン。
    • LOCATION: クラスタの Compute Engine のロケーション。
  3. 作成した 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: Network
    metadata:
      name: vpc5
    spec:
      parametersRef:
        group: networking.gke.io
        kind: GKENetworkParamSet
        name: vpc5
      type: Device
    ---
    apiVersion: networking.gke.io/v1
    kind: Network
    metadata:
      name: vpc6
    spec:
      parametersRef:
        group: networking.gke.io
        kind: GKENetworkParamSet
        name: vpc6
      type: Device
    ---
    apiVersion: networking.gke.io/v1
    kind: Network
    metadata:
      name: vpc7
    spec:
      parametersRef:
        group: networking.gke.io
        kind: GKENetworkParamSet
        name: vpc7
      type: Device
    ---
    apiVersion: networking.gke.io/v1
    kind: Network
    metadata:
      name: vpc8
    spec:
      parametersRef:
        group: networking.gke.io
        kind: GKENetworkParamSet
        name: vpc8
      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
    ---
    apiVersion: networking.gke.io/v1
    kind: GKENetworkParamSet
    metadata:
      name: vpc5
    spec:
      vpc: PREFIX-net-5
      vpcSubnet: PREFIX-sub-5
      deviceMode: NetDevice
    ---
    apiVersion: networking.gke.io/v1
    kind: GKENetworkParamSet
    metadata:
      name: vpc6
    spec:
      vpc: PREFIX-net-6
      vpcSubnet: PREFIX-sub-6
      deviceMode: NetDevice
    ---
    apiVersion: networking.gke.io/v1
    kind: GKENetworkParamSet
    metadata:
      name: vpc7
    spec:
      vpc: PREFIX-net-7
      vpcSubnet: PREFIX-sub-7
      deviceMode: NetDevice
    ---
    apiVersion: networking.gke.io/v1
    kind: GKENetworkParamSet
    metadata:
      name: vpc8
    spec:
      vpc: PREFIX-net-8
      vpcSubnet: PREFIX-sub-8
      deviceMode: NetDevice
    EOF
    

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

GPUDirect-TCPX

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

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

    以下を置き換えます。

    • CLUSTER_NAME: 新しいクラスタの名前。
    • VERSION: 要件で説明されているように、GPUDirect-TCPX をサポートする GKE バージョン。
    • LOCATION: クラスタの Compute Engine のロケーション。
  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 を使用した組み込みネットワーキング プログラミングは適用されません。

GPUDirect バイナリをインストールして NCCL を構成する

このセクションでは、A3 マシンタイプ(A3 High の場合は GPUDirect-TCPX、A3 Mega の場合は GPUDirect-TCPXO)に基づいて GPUDirect バイナリをインストールする方法と、DaemonSet を使用して特定の NCCL ライブラリ バージョンをインストールする方法について説明します。

GPUDirect-TCPXO

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

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

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

  1. GitHub の nccl-tcpxo-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-tcpxo/nccl-tcpxo-installer-autopilot.yaml
    

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

GPUDirect-TCPX

この 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-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 デバイス インジェクタをインストールする方法について説明します。どちらの H100 GPU マシンタイプも、同じ NRI デバイス インジェクタ プラグインをインストールします。このプラグインは次の処理を行います。

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

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

  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 または GPUDirect-TCPXO が期待どおりに動作することを確認します。このサンプル ワークロードは、次のことを行います。

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

このサンプル ワークロードをデプロイする手順は次のとおりです。

GPUDirect-TCPXO

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

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

  2. テスト ワークロードを含む 2 つの Pod をデプロイします。

    kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/container-engine-accelerators/master/gpudirect-tcpxo/nccl-test-latest-autopilot.yaml
    
  3. Pod がデプロイされたら、all-gather テストをトリガーします。

    kubectl exec --stdin --tty --container=nccl-test nccl-test-host-1 -- /scripts/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
    #
    

GPUDirect-TCPX

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

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

  2. GitHub の nccl-test-latest-autopilot.yaml Deployment マニフェストを確認します。

  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-autopilot.yaml
    
  4. 次のコマンドを実行して、ノードの 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)
        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
    

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

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

GPUDirect-TCPXO

## required

"NCCL_FASTRAK_CTRL_DEV=eth0",
"NCCL_FASTRAK_IFNAME=eth1,eth2,eth3,eth4,eth5,eth6,eth7,eth8",
"NCCL_SOCKET_IFNAME=eth0",
"NCCL_CROSS_NIC=0",
"NCCL_ALGO=Ring,Tree",
"NCCL_PROTO=Simple",
"NCCL_MIN_NCHANNELS=4",
"NCCL_TUNER_PLUGIN=libnccl-tuner.so",
"NCCL_TUNER_CONFIG_PATH=/usr/local/nvidia/lib64/a3plus_tuner_config.textproto",
"NCCL_SHIMNET_GUEST_CONFIG_CHECKER_CONFIG_FILE=/usr/local/nvidia/lib64/a3plus_guest_config.textproto",
"NCCL_DYNAMIC_CHUNK_SIZE=524288",
"NCCL_P2P_NET_CHUNKSIZE=524288",
"NCCL_P2P_PCI_CHUNKSIZE=524288",
"NCCL_P2P_NVL_CHUNKSIZE=1048576",
"NCCL_FASTRAK_NUM_FLOWS=2",
"NCCL_FASTRAK_USE_SNAP=1",
"NCCL_FASTRAK_PLUGIN_ACCEPT_TIMEOUT_MS=600000",
"NCCL_FASTRAK_ENABLE_CONTROL_CHANNEL=0",
"NCCL_BUFFSIZE=8388608",
"CUDA_VISIBLE_DEVICES=0,1,2,3,4,5,6,7",
"NCCL_NET_GDR_LEVEL=PIX",
"NCCL_FASTRAK_ENABLE_HOTPATH_LOGGING=0",
"NCCL_FASTRAK_USE_LLCM=1",
"NCCL_NVLS_ENABLE=0"
## recommended, to log NCCL errors
"NCCL_DEBUG=WARN",
"NCCL_DEBUG_SUBSYS=INIT,NET,ENV,COLL,GRAPH"

必要に応じて、次の手順ですべての構成を一度に設定できます。

  1. ワークロード コンテナ マニフェストに、次の Key-Value ペアを環境変数として追加します。

    NCCL_LIB_DIR="/usr/local/nvidia/lib64"
    
  2. ワークロード コンテナの起動時に nccl-env-profile.sh スクリプトが実行されるようにします。たとえば、Pod 仕様でコンテナのコマンドをオーバーライドして、次のものを含めることで、この操作を行うことができます。

    source ${NCCL_LIB_DIR}/nccl-env-profile.sh
    

GPUDirect-TCPX


"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 マニフェストに追加する必要がある必須フィールドについて説明します。

Autopilot モードでは、GKE がハードウェアをプロビジョニングできるように、Pod マニフェストで適切な GPU を選択する必要があります。H100 Mega GPU の場合は、GPUDirect-TCPXO を使用します。H100 GPU の場合は、GPUDirect-TCPX を使用します。

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

nodeSelector:
  cloud.google.com/gke-accelerator: GPU_NAME
  cloud.google.com/gke-gpu-driver-version: latest

GPU_NAME は、GPU の名前に置き換えます。サポートされている値は次のとおりです。

  • nvidia-h100-mega-80gb
  • nvidia-h100-80gb

GPUDirect のタイプに応じて、次の操作を行います。

GPUDirect-TCPXO

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

    metadata:
      annotations:
        devices.gke.io/container.tcpxo-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
          - path: /dev/dmabuf_import_helper
        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"},
            {"interfaceName":"eth5","network":"vpc5"},
            {"interfaceName":"eth6","network":"vpc6"},
            {"interfaceName":"eth7","network":"vpc7"},
            {"interfaceName":"eth8","network":"vpc8"}
          ]
    
  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
      - name: aperture-devices
        hostPath:
          path: /dev/aperture_devices
    
  3. マニフェストに次のコンテナを追加して、tcpxo-daemon サービスを実行します。(TCPXO_DAEMON_IMAGE)は、最新のイメージ us-docker.pkg.dev/gce-ai-infra/gpudirect-tcpxo/tcpgpudmarxd-dev:v1.0.12 に置き換えます。

    - name: tcpxo-daemon
      image: TCPXO_DAEMON_IMAGE
      imagePullPolicy: Always
      command: ["/bin/sh", "-c"]
      args:
        - |
          set -ex
          chmod 755 /fts/entrypoint_rxdm_container.sh
          /fts/entrypoint_rxdm_container.sh --num_hops=2 --num_nics=8 --uid= --alsologtostderr
      securityContext:
        capabilities:
          add:
            - NET_ADMIN
            - NET_BIND_SERVICE
      volumeMounts:
        - name: libraries
          mountPath: /usr/local/nvidia
        - name: sys
          mountPath: /hostsysfs
        - name: proc-sys
          mountPath: /hostprocsysfs
      
    
  4. すべての GPU コンテナに次の環境変数を追加します。

    env:
    
    - name: NCCL_FASTRAK_LLCM_DEVICE_DIRECTORY
      value: /dev/aperture_devices
    
  5. すべての GPU コンテナに次の volumeMount を追加します。aperture_devices が設定されていない場合、GPU コンテナには privileged:true が必要です。

    volumeMounts:
      - name: aperture-devices
        mountPath: /dev/aperture_devices
    
  6. 環境変数を追加して NCCL オプションを構成します。詳細については、推奨される NCCL 構成設定を使用してパフォーマンスを改善するをご覧ください。

完成した Pod 仕様は次のようになります。

apiVersion: v1
kind: Pod
metadata:
name: a3plus-workloads
annotations:
  devices.gke.io/container.tcpxo-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
    - path: /dev/dmabuf_import_helper
  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"},
      {"interfaceName":"eth5","network":"vpc5"},
      {"interfaceName":"eth6","network":"vpc6"},
      {"interfaceName":"eth7","network":"vpc7"},
      {"interfaceName":"eth8","network":"vpc8"}
    ]
...
containers:
  - name: tcpxo-daemon
    image: TCPXO_DAEMON_IMAGE
    imagePullPolicy: Always
    command: ["/bin/sh", "-c"]
    args:
      - |
        set -ex
        chmod 755 /fts/entrypoint_rxdm_container.sh
        /fts/entrypoint_rxdm_container.sh --num_hops=2 --num_nics=8 --uid= --alsologtostderr
    securityContext:
      capabilities:
        add:
          - NET_ADMIN
          - NET_BIND_SERVICE
    volumeMounts:
      - name: libraries
        mountPath: /usr/local/nvidia
      - name: sys
        mountPath: /hostsysfs
      - name: proc-sys
        mountPath: /hostprocsysfs
    
  - name: main-application-container
...
   
      - name: NCCL_FASTRAK_LLCM_DEVICE_DIRECTORY
        value: /dev/aperture_devices
    securityContext:
    volumeMounts:
      - name: aperture-devices
        mountPath: /dev/aperture_devices
    resources:
      limits:
        nvidia.com/gpu: 8
volumes:
  - name: libraries
    hostPath:
      path: /home/kubernetes/bin/nvidia
  - name: sys
    hostPath:
      path: /sys
  - name: proc-sys
    hostPath:
      path: /proc/sys
  - name: aperture-devices
    hostPath:
      path: /dev/aperture_devices

GPUDirect-TCPX

  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
      
    
  4. GPU をリクエストするコンテナに次のボリューム マウントを追加します。

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

完成した Pod 仕様は次のようになります。

apiVersion: v1
kind: Pod
metadata:
name: a3-gpu-workloads-example
labels:
  name: a3-gpu-workloads-example
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"}
    ]
spec:
containers:
  - name: tcpx-daemon
    image: us-docker.pkg.dev/gce-ai-infra/gpudirect-tcpx/tcpgpudmarxd-dev:v2.0.11
    imagePullPolicy: Always
    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
        readOnly: true
      - name: tcpx-socket
        mountPath: /run/tcpx
      - name: sys
        mountPath: /hostsysfs
      - name: proc-sys
        mountPath: /hostprocsysfs
    
  - name: a3-gpu-workloads-example
    ...
    volumeMounts:
      - name: tcpx-socket
        mountPath: /tmp
      - name: libraries
        mountPath: /usr/local/nvidia/lib64
        readOnly: true
    resources:
      limits:
        nvidia.com/gpu: 8
    
...
volumes:
  - name: libraries
    hostPath:
      path: /home/kubernetes/bin/nvidia/lib64
  - name: tcpx-socket
    emptyDir:
  - name: sys
    hostPath:
      path: /sys
  - name: proc-sys
    hostPath:
      path: /proc/sys

次のステップ