创建自定义 AI 优化型 A3 Edge GKE 集群

本页面介绍了如何创建经过 AI 优化的 Google Kubernetes Engine (GKE) 集群,该集群使用 A3 Edge 虚拟机 (VM) 来支持人工智能 (AI) 和机器学习 (ML) 工作负载。A3 Edge 机器旨在让您能够运行大规模 AI 和机器学习集群,并提供有针对性的工作负载放置、紧凑布置、高级集群维护控制和 TAS 等功能。如需了解详情,请参阅集群管理概览

GKE 提供了一个统一的平台,可供组织运行各种工作负载,从而减轻管理多个平台的运营负担。您可以运行高性能分布式预训练、模型微调、模型推理、应用服务和支持服务等工作负载。

本页面介绍了如何使用 GPUDirect-TCPX、gVNIC 和多网络功能创建 Google Kubernetes Engine (GKE) Standard 集群和 Autopilot 集群。

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

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

本页面假定您熟悉网络接口卡 (NIC) 和 TCP 等网络技术,以及 NVIDIA Collective Communications Library (NCCL) 等加速器技术。

Google Cloud GPU 超级计算机简介

Google Cloud 提供专为可伸缩的大型模型构建的加速器优化超级计算机。这些 GPU 机器类型可获得高达 3,600 Gbps 的网络带宽。

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

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

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

  • GPUDirect 网络栈:A3 Edge 支持 3 种网络栈,用于自定义远程直接内存访问 (RDMA)。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 虚拟机。如需获取此容量,请先从使用选项中进行选择。如需按照本页中的说明操作,您可以使用按需容量、按需预留或最长 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 节点必须使用 535 或更高版本的 NVIDIA 驱动程序。
  • 您必须使用 GKE Dataplane V2。
  • 在 GKE 1.34 及更高版本中,您必须使用 3.1.9 版或更高版本的 GPUDirect-TCPX 安装程序以及 2.0.12 版或更高版本的 GPUDirect-TCPX Sidecar。安装程序版本和边车版本具有一对一的映射关系,并且必须对应。例如,安装程序版本 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 节点必须使用 535 或更高版本的 NVIDIA 驱动程序。
  • 您必须使用 GKE Dataplane V2。
  • 在 GKE 1.34 及更高版本中,您必须使用 3.1.9 版或更高版本的 GPUDirect-TCPX 安装程序和 2.0.12 版或更高版本的 GPUDirect-TCPX Sidecar。安装程序版本和辅助信息文件版本具有一对一的映射关系,并且必须对应。例如,安装程序版本 3.1.12 对应于边车版本 2.0.15。如需详细了解安装程序和边车版本,请参阅 GPUDirect-TCPX 版本说明
  • 对于跨多个节点池运行的 GPUDirect-TCPX 工作负载,所有节点池都必须位于同一 Compute Engine 可用区中,并且必须使用相同的网络集,例如 VPC 和子网。

限制

存在以下限制:

  • 多实例 GPUGPU 分时NVIDIA MPS 不支持 GPUDirect-TCPX。
  • 您无法将 NCCL FastSocket 与 GPUDirect-TCPX 搭配使用。
  • 您的 GKE 工作负载必须使用单个节点上所有可用的 GPU 和所有可用的次要 NIC。多个 Pod 无法在单个节点上使用 GPUDirect-TCPX。

创建 VPC 和子网

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

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

    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 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
    

    这些资源会告诉 GKE 以直通模式为 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 标志的值可以是 specificany。不过,对于高性能分布式 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 节点都有八个 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. 将库和二进制文件存储在虚拟机上的 /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
    

Autopilot

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

  2. 创建专用命名空间:

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

部署 NRI 设备注入器插件

本部分介绍如何使用 DaemonSet 安装 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
    

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

部署测试工作负载

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

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

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

  1. 查看 GitHub 中的 nccl-config.yaml ConfigMap 清单。此清单部署初始化 NCCL all-gather 测试的脚本并设置特定于 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 消息都为 RunningREADY 的值为 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 配置设置提高性能

以下键值对是 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: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 规范示例,请参阅 GitHub 上的 nccl-test-latest.yaml 清单。

Autopilot

对于 Autopilot 模式,您还必须在 Pod 清单中选择合适的 GPU,以便 GKE 配置硬件。

将以下节点选择器添加到 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 问题

后续步骤