在 Standard 模式集群中最大限度地提高 GPU 网络带宽


本页面介绍了如何使用 GPUDirect-TCPXO、GPUDirect-TCPX、gVNIC 和多网络功能在 Google Kubernetes Engine (GKE) Standard 集群中最大限度地提高高性能 GPU 工作负载的网络带宽和吞吐量。如果您使用 Autopilot 集群,请参阅在 Autopilot 模式集群中最大限度地提高 GPU 网络带宽

本页面适用于为机器学习 (ML) 工作负载提供支持的机器学习工程师和平台管理员。 如需详细了解我们在 Google Cloud 内容中提及的常见角色和示例任务,请参阅常见的 GKE Enterprise 用户角色和任务

人工智能 (AI)、机器学习和高性能计算 (HPC) 应用需要通过缩短作业完成时间来获得极大的加速,从而优化性能。例如,用于对话式 AI 和图像生成的机器学习模型需要强大的可伸缩性和计算能力。

在阅读本页面内容之前,请确保您熟悉网络接口卡 (NIC) 和 TCP 等网络技术,以及 NVIDIA Collective Communications Library (NCCL) 等加速器技术。

Google Cloud GPU 超级计算机简介

Google Cloud 提供专为可伸缩的大型模型构建的加速器优化超级计算机。这种机器具有以下优势:

  • 每个机器搭载八个 NVIDIA H100 GPU。
  • 主 NIC 可支持最高 200 Gbps 的带宽。
  • 次要 NIC(A3 Mega 机器类型上最多 8 个,A3 High 机器类型最多 4 个),每个 NIC 支持最高 200 Gbps 的 GPU 数据传输带宽。

您的 GKE 工作负载必须使用单个节点上所有可用的 GPU 和所有可用的次要 NIC,并使用大部分的可用带宽。本文档中所述的解决方案非常适合需要高性能、高吞吐量和低延迟的工作负载。

最大限度地提高带宽所必需的特性和功能

如需最大限度地提高 GPU 超级计算机节点中的网络带宽,请使用以下所有功能:

  • GPUDirect 网络栈:A3 机器系列支持两种网络栈,用于自定义远程直接内存访问 (RDMA):
    • 在 A3 High 机器类型和 NVIDIA H100 GPU 上,利用 GPUDirect-TCPX 减少与 GPU 来回传输数据包载荷所需的开销,这与不使用 GPUDirect 的 GPU 相比,可大规模显著提高吞吐量。
    • 在 A3 Mega 机器类型和 NVIDIA H100 Mega GPU 上,利用 GPUDirect-TCPXO,进一步改进 GPU 到虚拟机的通信。
  • 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。

  • GPUDirect-TCPX 在 GKE 1.27 版或更高版本上受支持,并且需要:
    • * a3-highgpu-8g 机器类型。
    • 对于 GKE 1.27 版,请使用 GKE 补丁 1.27.7-gke.1121000 版或更高版本。
    • 对于 GKE 1.28 版,请使用 GKE 补丁 1.28.8-gke.1095000 版或更高版本。
    • 对于 GKE 1.29 版,请使用 GKE 补丁 1.29.3-gke.1093000 版或更高版本。
  • GPUDirect-TCPXO 在 GKE 1.28 版或更高版本上受支持,并且需要:
    • a3-megagpu-8g 机器类型。
    • 对于 GKE 1.28 版,请使用 GKE 补丁 1.28.9-gke.1250000 版或更高版本。
    • 对于 GKE 1.29 版,请使用 GKE 补丁 1.29.4-gke.1542000 版或更高版本。
  • GKE 节点必须使用 Container-Optimized OS (COS) 节点映像。不支持 Ubuntu 和 Windows 节点映像。
  • 您的 GPU 节点必须使用 535 或更高版本的 NVIDIA 驱动程序。
  • 您必须使用 GKE Dataplane V2。

限制

存在以下限制:

  • 多实例 GPUGPU 分时NVIDIA MPS 不支持 GPUDirect-TCPX 和 GPUDirect-TCPXO。
  • 您不能使用 NCCL FastSocket
  • 您的 GKE 工作负载必须使用单个节点上所有可用的 GPU 和所有可用的次要 NIC。多个 Pod 无法在单个节点上使用 GPUDirect-TCPX 或 GPUDirect-TCPXO。
  • 您只能使用 a3-highgpu-8ga3-megagpu-8g 机器类型。不支持其他 A3 机器类型。

创建 VPC 和子网

在项目中为将要添加到节点的每个虚拟 NIC 创建单独的 VPC 网络。每个 VPC 网络都必须具有一个子网和一条允许内部网络流量的防火墙规则。

  1. 在项目中为 GPUDirect 创建 VPC 网络,每个 VPC 网络都具有一个子网和一条防火墙规则。为 A3 High 机器类型选择 GPUDirect-TCPX 标签页,或是为 A3 Mega 机器类型选择 GPUDirect-TCPXO 标签页,然后按照以下说明操作:

    为了最大限度地提高带宽,我们建议您创建八个新网络。

    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 表示法。此示例命令将针对八个子网进行迭代,因此您应该使用变量来更改每个子网的 IP 地址。例如,指定 192.168.$N.0/24,从而使第一个子网使用 192.168.1.0/24,第二个子网使用 192.168.2.0/24,以此类推。
    • SOURCE_RANGE:允许入站流量的防火墙规则的来源 IP 地址范围(采用 CIDR 表示法)。例如 192.168.0.0/16

    为了最大限度地提高带宽,我们建议您创建四个新网络。

    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 表示法。此示例命令将针对四个子网进行迭代,因此您应该使用变量来更改每个子网的 IP 地址。例如,指定 192.168.$N.0/24,从而使第一个子网使用 192.168.1.0/24,第二个子网使用 192.168.2.0/24,以此类推。
    • SOURCE_RANGE:允许入站流量的防火墙规则的来源 IP 地址范围(采用 CIDR 表示法)。例如 192.168.0.0/16
  2. 验证网络已创建:

    gcloud compute networks list
    

创建 GKE 环境

创建一个使用多网络(预览版)的新 GKE 集群,并创建一个具有以下特性的 GPU 节点池:

  • 启用了 gVNIC
  • 为每个次要 NIC 指定了多网络子网
  • 具有为节点提供支持的 H100 GPU 的 A3 机器系列
  • 安装了最新 NVIDIA 驱动程序

您无法通过更新现有集群来使用多网络。

  1. 选择支持 GPUDirect-TCPXO 的可用 GKE 版本。如需列出版本,请运行以下命令:

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

    替换以下内容:

    • REGION:集群控制层面的计算区域
    • PROJECT_ID:您的 Google Cloud 项目 ID。
  2. 创建集群:

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

    请替换以下内容:

    • CLUSTER_NAME:新集群的名称。
    • VERSION:支持 GPUDirect-TCPXO 的 GKE 版本,如要求中所述。
    • ZONE:集群的计算可用区
  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
    

    这些资源会告诉 GKE 以直通模式为 GPU 流量配置 NIC。GKE 不会为此流量应用使用 eBPF 的内置网络编程。

  1. 创建集群:

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

    替换以下内容:* CLUSTER_NAME:新集群的名称。VERSION:支持 GPUDirect-TCPX 的 GKE 版本,如要求中所述。* ZONE:集群的计算可用区

  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
    

    这些资源会告诉 GKE 以直通模式为 GPU 流量配置 NIC。GKE 不会为此流量应用使用 eBPF 的内置网络编程。

创建 GPU 节点池

为 H100 GPU 创建节点池:

gcloud beta container node-pools create NODE_POOL_NAME \
    --zone=ZONE \
    --cluster=CLUSTER_NAME \
    --project=PROJECT_ID \
    --accelerator=type=nvidia-h100-mega-80gb,count=8,gpu-driver-version=LATEST \
    --machine-type=a3-megagpu-8g \
    --num-nodes=2 \
    --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 \
    --additional-node-network network=PREFIX-net-5,subnetwork=PREFIX-sub-5 \
    --additional-node-network network=PREFIX-net-6,subnetwork=PREFIX-sub-6 \
    --additional-node-network network=PREFIX-net-7,subnetwork=PREFIX-sub-7 \
    --additional-node-network network=PREFIX-net-8,subnetwork=PREFIX-sub-8 \
    --enable-gvnic \
    --no-enable-autoupgrade \
    --scopes "https://www.googleapis.com/auth/cloud-platform" \
    [--placement-policy=POLICY_NAME \
    --reservation-affinity=specific \
    --reservation=RESERVATION_NAME \
    --host-maintenance-interval=PERIODIC]

NODE_POOL_NAME 替换为您的节点池名称。

在该示例中,为方便测试,--scopes“https://www.googleapis.com/auth/cloud-platform”参数将节点实例的范围设置为 cloud-platform。对于生产环境,您可能需要限制范围,以配置更精细的凭据。

如果您使用预留,请使用 --placement-policy--reservation-affinity--reservation 标志。指定这些标志以在节点池中配置政策名称和预留。

如果此命令失败,则您的项目中可能没有足够的 H100 GPU 配额。确保您拥有足够的配额,然后重试命令。

为 H100 GPU 创建节点池:

gcloud container node-pools create NODE_POOL_NAME \
    --cluster=CLUSTER_NAME \
    --location=LOCATION \
    --machine-type=a3-highgpu-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

NODE_POOL_NAME 替换为节点池的名称。

如果此命令失败,则您的项目中可能没有足够的 H100 GPU 配额。确保您拥有配额,然后重试命令。

创建节点池后,请验证每个节点是否挂接了 GPU:

  1. 获取集群中的节点列表:

    kubectl get nodes
    
  2. 验证每个 GPU 节点都有八个 GPU:

    kubectl describe node NODE_NAME
    

    NODE_NAME 替换为要描述的节点的名称。

    输出内容类似如下:

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

安装 GPUDirect 二进制文件并配置 NCCL

本部分介绍如何使用 DaemonSet,根据您的 A3 机器类型(GPUDirect-TCPX 适用于 A3 High,GPUDirect-TCPXO 适用于 A3 Mega)安装 GPUDirect 二进制文件以及安装特定 NCCL 库版本。

此 DaemonSet 会执行以下操作:

  1. 进行预安装以设置 GPUDirect-TCPXO 相关配置。
  2. 在节点上安装 NCCL 库和 GPUDirect-TCPXO 二进制文件。
  3. 将库和二进制文件存储在虚拟机上的 /home/kubernetes/bin/nvidia/lib64 目录中。默认情况下,GKE 会将此目录装载到需要使用 NCCL 和 GPUDirect-TCPXO 的 GPU 容器中的 /usr/local/nvidia/lib64 路径中。

如需安装二进制程序并配置 NCCL,请执行以下步骤:

  1. 查看 GitHub 中的 nccl-tcpxo-installer.yaml Daemonset 清单

  2. 部署 DaemonSet:

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

    NCCL 插件大约需要两分钟才能开始运行。

  3. 验证 DaemonSet Pod 的状态:

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

    输出类似于以下内容:

    # Output
    nccl-tcpxo-installer-6c2pv                    1/1     Running   0          2m11s
    nccl-tcpxo-installer-qgg82                    1/1     Running   0          2m11s
    

此 DaemonSet 会执行以下操作:

  1. 在节点上安装 NCCL 库和 GPUDirect-TCPX 二进制文件。
  2. 将库和二进制文件存储在虚拟机上的 /home/kubernetes/bin/nvidia/lib64 目录中。默认情况下,GKE 会将此目录装载到需要使用 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 插件大约需要两分钟才能开始运行。

  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
    

部署 NRI 设备注入器插件

本部分介绍如何使用 DaemonSet 安装 NRI 设备注入器。两种 H100 GPU 机器类型都会安装相同的 NRI 设备注入器插件。此插件会执行以下操作:

  1. 在具有 H100 GPU 的节点上启用节点资源接口 (NRI)。 在 GKE 1.29 版及更高版本中,NRI 默认处于启用状态。
  2. 部署 NRI 设备注入器插件容器,以将 GPU 设备注入到由 Pod 注解指定的容器中。

如需安装此插件,请执行以下操作:

  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 插件大约需要两分钟才能开始运行。

  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
    

部署测试工作负载

在本部分中,您将部署一个示例工作负载来验证 NCCL 和 GPUDirect-TCPX 或 GPUDirect-TCPXO 是否按预期运行。 此示例工作负载会执行以下操作:

  1. 部署两个 Pod,每个 Pod 都在具有 H100 GPU 的节点中运行。
  2. 在每个 Pod 中部署一个边车容器,以使这些 Pod 能够使用 GPUDirect-TCPXO 或 GPUDirect-TCPX。

如需部署此示例工作负载,请执行以下操作:

此工作负载包含一个名为 tcpxo-daemon 的边车容器,它运行一个服务以使 Pod 能够使用 GPUDirect-TCPXO。您必须将此边车容器添加到您自己环境中需要使用 GPUDirect-TCPXO 的所有 Pod。如需查看要添加到清单的必填字段的代码段,请参阅将 GPUDirect 添加到清单

  1. 查看 GitHub 中的 nccl-test-latest.yaml 清单

  2. 部署包含测试工作负载的两个 Pod:

    kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/container-engine-accelerators/master/gpudirect-tcpxo/nccl-test-latest.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
    #
    

此工作负载包含一个名为 tcpx-daemon 的边车容器,它运行一个服务以使 Pod 能够使用 GPUDirect-TCPX。tcpx-daemon您必须将此边车容器添加到您自己环境中需要使用 GPUDirect-TCPX 的所有 Pod。如需查看要添加到清单的必填字段的代码段,请参阅将 GPUDirect 添加到清单

  1. 查看 GitHub 中的 nccl-config.yaml ConfigMap 清单。此清单部署初始化 NCCL all-gather 测试的脚本并设置特定于 NCCL 的配置设置。

  2. 查看 GitHub 中的 nccl-test-latest.yaml 部署清单

  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
    
  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 配置设置提高性能

以下键值对是 GPUDirect-TCPX 和 GPUDirect-TCPXO 所需的 NCCL 配置设置。部署使用 NCCL 的工作负载时,请将其设置为环境变量以优化性能。

## required

"LD_LIBRARY_PATH=\"${LD_LIBRARY_PATH}:/usr/local/nvidia/lib64\"",
"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. 在工作负载容器清单中,将以下键值对添加为环境变量:

    NCCL_LIB_DIR="/usr/local/nvidia/lib64"
    
  2. 确保在工作负载容器启动时执行 nccl-env-profile.sh 脚本。例如,您可以在 Pod 规范中执行此操作,方法是替换容器的命令,使其包含以下内容:

    source ${NCCL_LIB_DIR}/nccl-env-profile.sh
    
"LD_LIBRARY_PATH=\"${LD_LIBRARY_PATH}:/usr/local/tcpx/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 清单的必填字段。

根据 GPUDirect 的类型,执行以下操作:

  1. 将以下注解添加到 Pod 元数据中。 如果没有这些注解,Pod 需要 hostNetwork:truetcpxo-daemon 容器需要 privileged:true

    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.13_1

    - 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
      env:
        - name: LD_LIBRARY_PATH
          value: /usr/local/nvidia/lib64
    
  4. 将以下环境变量添加到每个 GPU 容器:

    env:
    - name: LD_LIBRARY_PATH
      value: /usr/local/nvidia/lib64
    - name: NCCL_FASTRAK_LLCM_DEVICE_DIRECTORY
      value: /dev/aperture_devices
    
  5. 将以下 volumeMount 添加到每个 GPU 容器中。如果没有 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
    env:
      - name: LD_LIBRARY_PATH
        value: /usr/local/nvidia/lib64
  - name: main-application-container
...
   env:
      - name: LD_LIBRARY_PATH
        value: /usr/local/nvidia/lib64
      - 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
  1. 将以下注解添加到 Pod 元数据中。 如果没有这些注解,Pod 需要 hostNetwork:truetcpx-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 规范如下所示:

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
    env:
      - name: LD_LIBRARY_PATH
        value: /usr/local/nvidia/lib64
  - 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
    env:
      - name: LD_LIBRARY_PATH
        value: /usr/local/nvidia/lib64
...
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

后续步骤