使用 Elastic Fabric Adapter 在 Amazon EKS 上运行机器学习训练 - Amazon EKS

帮助改进此页面

想为本用户指南做出贡献? 滚动到页面底部,然后选择在 GitHub 上编辑此页面。您的贡献有助于我们的用户指南为每个人提供更充分的参考。

使用 Elastic Fabric Adapter 在 Amazon EKS 上运行机器学习训练

本主题介绍如何将 Elastic Fabric Adapter(EFA)与部署在 Amazon EKS 集群中的 Pods 集成。Elastic Fabric Adapter (EFA) 是 Amazon EC2 实例的网络接口,使您能够在AWS上运行要求大规模高级别节点间通信的应用程序。其量身定制的操作系统旁路硬件接口增强了实例间通信的性能,这对扩缩这些应用程序至关重要。借助 EFA,采用消息传递接口 (MPI) 的高性能计算 (HPC) 应用程序和采用 NVIDIA Collective Communications Library (NCCL) 的 Machine Learning (ML) 应用程序可以扩展到数千个 CPU 或 GPU。因此,您同时获得了本地 HPC 集群的应用程序性能,以及AWS云的按需弹性和灵活度。将 EFA 与 Amazon EKS 集群上运行的应用程序集成,可以缩短完成大规模分布式培训工作负载的时间,而无需向集群添加更多实例。有关 EFA 的更多信息,请参阅 Elastic Fabric Adapter

具有 EFA 的实例类型

AWS EFA Kubernetes 设备插件支持所有具有 EFA 的 Amazon EC2 实例类型。要查看具有 EFA 的所有实例类型的列表,请参阅《Amazon EC2 用户指南》中的支持的实例类型。但是,要快速运行机器学习应用程序,我们建议除了 EFA 之外,实例还应具备 nVidia GPU、AWS Inferentia 芯片或 AWS Trainium 芯片等硬件加速芯片。要查看具有硬件加速芯片和 EFA 的实例类型列表,请参阅《Amazon EC2 用户指南》中的加速型计算

在比较实例类型以便进行选择时,应注意实例类型可用的 EFA 网卡数量以及加速卡数量、CPU 大小和内存大小。您最多可以为每张网卡分配一个 EFA。一个 EFA 计为一个网络接口。要查看每种具有 EFA 的实例类型有多少 EFA 可用,请参阅《Amazon EC2 用户指南》中的网卡列表

先决条件

  • 现有 Amazon EKS 集群。如果您没有现有集群,请参考我们的某个 开始使用 Amazon EKS 指南创建一个集群。您的集群必须部署在至少具有一个私有子网的 VPC 中,该子网应当具有足够多的可用 IP 地址以便在其中部署节点。私有子网必须具有由外部设备(如 NAT 网关)提供的出站 Internet 访问。

    如果您计划使用 eksctl 创建您的节点组,eksctl 还可以为您创建集群。

  • 在您的设备或 AWS CloudShell 上安装和配置了 AWS Command Line Interface(AWS CLI)的版本 2.12.3 或更高版本,或版本 1.27.160 或更高版本。要查看当前版本,请使用 aws --version | cut -d / -f2 | cut -d ' ' -f1。软件包管理器(如 yumapt-get 或适用于 macOS 的 Homebrew)通常比 AWS CLI 的最新版本落后几个版本。要安装最新版本,请参阅《AWS Command Line Interface 用户指南》中的安装、更新和卸载 AWS CLI,以及使用 aws configure 快速配置。AWS CloudShell 中安装的 AWS CLI 版本也可能比最新版本落后几个版本。如需更新,请参阅《AWS CloudShell 用户指南》中的将 AWS CLI 安装到主目录

  • 您的设备或 AWS CloudShell 上安装了 kubectl 命令行工具。该版本可以与集群的 Kubernetes 版本相同,或者最多早于或晚于该版本一个次要版本。例如,如果您的集群版本为 1.30,则可以将 kubectl1.291.301.31 版本与之配合使用。要安装或升级 kubectl,请参阅 设置 kubectl 和 eksctl

  • 您必须首先安装 Amazon VPC CNI plugin for Kubernetes 版本 1.7.10 或更高版本,然后才能启动支持多个 Elastic Fabric Adapter 的 Worker 节点(例如 p4dp5)。有关更新您的 Amazon VPC CNI plugin for Kubernetes 版本的更多信息,请参阅 使用 Amazon VPC CNI 将 IP 分配给 Pods

重要

采用具有 Kubernetes 的 EFA 时需要考虑的一个重要因素,是将 Huge Pages 作为集群中的资源进行配置和管理。有关更多信息,请参阅 Kubernetes 文档中的管理 Huge Pages。安装了 EFA 驱动程序的 Amazon EC2 实例会预先分配 5128 个 2MiB 的 Huge Pages,您可以请求将其作为资源在作业规范中使用。

创建节点组

下面的程序通过一个包含 EFA 接口和 GPUDirect RDMA 且受 p4d.24xlarge 支持的节点组,帮助您创建节点组,并使用 EFA 针对多节点 NCCL 性能运行一个 NVIDIA Collective Communications Library (NCCL) 示例测试。该示例可用作使用 EFA 在 Amazon EKS 上进行分布式深度学习培训的模板。

  1. 确定您想在其中部署节点的 AWS 区域 中有哪些支持 EFA 的 Amazon EC2 实例类型可用。region-code 替换为您想要在其中部署节点组的 AWS 区域。

    aws ec2 describe-instance-types --region region-code \ --filters Name=network-info.efa-supported,Values=true \ --query "InstanceTypes[*].[InstanceType]" --output text

    部署节点时,您想要部署的实例类型必须在集群所在的 AWS 区域 中可用。

  2. 确定您想要部署的实例类型在哪些可用区中可用。本教程使用了 p5.48xlarge 实例类型,必须在上一步所指定的 AWS 区域 的输出中返回该实例类型。在生产集群中部署节点时,请将 p5.48xlarge 替换为上一步中返回的任何实例类型。

    aws ec2 describe-instance-type-offerings --region region-code \ --location-type availability-zone --filters Name=instance-type,Values=p4d.24xlarge,p5.48xlarge \ --query 'InstanceTypeOfferings[*].Location' --output text

    示例输出如下。

    us-west-2a us-west-2c us-west-2b

    记下返回的可用区,以供后续步骤使用。将节点部署到集群时,VPC 的子网必须在输出返回的其中一个可用区中具有可用的 IP 地址。

  3. 使用 eksctl 创建节点组。

    先决条件

    您的设备或 AWS CloudShell 上安装了 0.191.0 版或更高版本的 eksctl 命令行工具。要安装或更新 eksctl,请参阅 eksctl 文档中的 Installation

    1. 将以下内容复制到名为 efa-cluster.yaml 的文件中。将 example values 替换为您自己的值。您可以将 p5.48xlarge 替换为不同的实例,但是如果您进行替换,请确保 availabilityZones 的值为第 1 步中针对实例类型返回的可用区。

      apiVersion: eksctl.io/v1alpha5 kind: ClusterConfig metadata: name: my-efa-cluster region: region-code version: "1.XX" iam: withOIDC: true availabilityZones: ["us-west-2a", "us-west-2c"] managedNodeGroups: - name: my-efa-ng instanceType: p5.48xlarge minSize: 1 desiredCapacity: 2 maxSize: 3 availabilityZones: ["us-west-2a"] volumeSize: 300 privateNetworking: true efaEnabled: true
    2. 在现有集群中创建托管节点组。

      eksctl create nodegroup -f efa-cluster.yaml

      如果您没有现有集群,可以运行以下命令来创建集群和节点组。

      eksctl create cluster -f efa-cluster.yaml
      注意

      由于此示例中使用的实例类型具有 GPU,eksctl 会在每个实例上为您自动安装 NVIDIA Kubernetes 设备插件。

  4. 部署 EFA Kubernetes 设备插件。

    EFA Kubernetes 设备插件检测 EFA 接口并将其通告为可分配给 Kubernetes 的资源。应用程序可以使用 Pod 请求规范中的扩展资源类型 vpc.amazonaws.com/efa,就像 CPU 和内存一样。有关更多信息,请参阅 Kubernetes 文档中的使用扩展资源。请求后,该插件会自动为 Pod 分配并挂载 EFA 接口。使用该设备插件可以简化 EFA 设置,而且不需要在特权模式下运行 Pod。

    helm repo add eks https://aws.github.io/eks-charts helm install aws-efa-k8s-device-plugin --namespace kube-system eks/aws-efa-k8s-device-plugin

(可选)测试 EFA 的性能

建议您测试 EFA 安装。您可以使用 GitHub 上 aws-samples/awsome-distributed-training 存储库中的 NCCL TestsNCCL Tests 使用 Nvidia 集合通信库来评估网络性能。以下步骤会在 Amazon EKS 上提交 NCCL 测试。

  1. 部署 Kubeflow MPI Operator

    对于 NCCL 测试,您可以应用 Kubeflow MPI Operator。MPI Operator 可以轻松地在 Kubernetes 上运行 Allreduce 模式的分布式训练。有关更多信息,请参阅 GitHub 上的 MPI Operator

  2. 运行多节点 NCCL 性能测试来验证 GPUDirectRDMA/EFA

    要通过 EFA 使用 GPUDirectRDMA 验证 NCCL 性能,请运行标准 NCCL 性能测试。有关更多信息,请参阅 GitHub 上的官方 NCCL 测试存储库。

    完成以下步骤以运行双节点 NCCL Performance Test。在示例 NCCL 测试作业中,每个 Worker 节点会请求八个 GPU、5210Mi 的 hugepages-2Mi、四个 EFA 和 8000Mi 的内存,这意味着每个 Worker 节点都会使用一个 p5.48xlarge 实例的所有资源。

    1. 创建 MPIJob 清单

      将以下内容复制到名为 nccl-tests.yaml 的文件中:

      apiVersion: kubeflow.org/v2beta1 kind: MPIJob metadata: name: nccl-tests spec: runPolicy: cleanPodPolicy: Running backoffLimit: 20 slotsPerWorker: 8 mpiReplicaSpecs: Launcher: replicas: 1 template: spec: restartPolicy: OnFailure containers: - image: public.ecr.aws/hpc-cloud/nccl-tests:latest imagePullPolicy: IfNotPresent name: test-nccl-launcher env: - name: PATH value: $PATH:/opt/amazon/efa/bin:/usr/bin - name: LD_LIBRARY_PATH value: /opt/amazon/openmpi/lib:/opt/nccl/build/lib:/opt/amazon/efa/lib:/opt/aws-ofi-nccl/install/lib:/usr/local/nvidia/lib:$LD_LIBRARY_PATH - name: NCCL_DEBUG value: INFO - name: NCCL_BUFFSIZE value: '8388608' - name: NCCL_P2P_NET_CHUNKSIZE value: '524288' - name: NCCL_TUNER_PLUGIN value: /opt/aws-ofi-nccl/install/lib/libnccl-ofi-tuner.so command: - /opt/amazon/openmpi/bin/mpirun - --allow-run-as-root - --tag-output - -np - "16" - -N - "8" - --bind-to - none - -x - PATH - -x - LD_LIBRARY_PATH - -x - NCCL_DEBUG=INFO - -x - NCCL_BUFFSIZE - -x - NCCL_P2P_NET_CHUNKSIZE - -x - NCCL_TUNER_PLUGIN - --mca - pml - ^cm,ucx - --mca - btl - tcp,self - --mca - btl_tcp_if_exclude - lo,docker0,veth_def_agent - /opt/nccl-tests/build/all_reduce_perf - -b - "8" - -e - "16G" - -f - "2" - -g - "1" - -c - "1" - -n - "100" Worker: replicas: 2 template: spec: nodeSelector: node.kubernetes.io/instance-type: "p5.48xlarge" containers: - image: public.ecr.aws/hpc-cloud/nccl-tests:latest imagePullPolicy: IfNotPresent name: nccl-tests-worker volumeMounts: - name: shmem mountPath: /dev/shm resources: limits: nvidia.com/gpu: 8 hugepages-2Mi: 5120Mi vpc.amazonaws.com/efa: 32 memory: 32000Mi requests: nvidia.com/gpu: 8 hugepages-2Mi: 5120Mi vpc.amazonaws.com/efa: 32 memory: 32000Mi volumes: - name: shmem hostPath: path: /dev/shm
    2. 应用 NCCL-tests MPIJob

      通过应用清单提交 MPIJob。这将创建两个 p5.48xlarge Amazon EC2 实例。

      kubectl apply -f nccl-tests.yaml

      示例输出如下。

      mpijob.kubeflow.org/nccl-tests created
    3. 验证作业是否启动了容器组(pod)

      查看您运行的 Pods。

      kubectl get pods

      示例输出如下。

      NAME READY STATUS RESTARTS AGE nccl-tests-launcher-nbql9 0/1 Init:0/1 0 2m49s nccl-tests-worker-0 1/1 Running 0 2m49s nccl-tests-worker-1 1/1 Running 0 2m49s

      MPI Operator 创建一个启动器 Pod 和 2 个工作线程 Pods(每个节点上一个)。

    4. 使用日志来验证作业是否成功运行

      查看 nccl-tests-launcher Pod 的日志。将 nbql9 替换为输出中的值。

      kubectl logs -f nccl-tests-launcher-nbql9

如果测试成功完成,则可以部署使用 Nvidia Collective Communication Library 的应用程序。