帮助改进此页面
要帮助改进本用户指南,请选择位于每个页面右侧窗格中的在 GitHub 上编辑此页面链接。
本主题介绍如何将 Elastic Fabric Adapter(EFA)与部署在 Amazon EKS 集群中的容器组(pod)集成。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
在比较实例类型以便进行选择时,应注意实例类型可用的 EFA 网卡数量以及加速卡数量、CPU 大小和内存大小。您最多可以为每张网卡分配一个 EFA。一个 EFA 计为一个网络接口。要查看每种具有 EFA 的实例类型有多少 EFA 可用,请参阅《Amazon EC2 用户指南》中的网卡列表。
仅限 EFA 和 EFA 的接口
Elastic Fabric Adapter(EFA) 是一种网络接口,它结合了弹性网络适配器(ENA)和操作系统旁路接口的功能,由 AWS 可扩展的可靠数据报(SRD)协议提供支持。EFA 功能允许应用程序直接与硬件通信,实现低延迟传输。您可以选择使用仅限 EFA 的接口仅访问 EFA 功能,从而将通信限制在同一可用区内的接口。
要创建可以具有仅限 EFA 的接口的节点,您必须使用自定义 EC2 启动模板并将 InterfaceType
设置为 efa-only
。在您的自定义启动模板中,您不能将网卡 0
设置为仅限 EFA 的接口,因为该接口是 EC2 实例的主网卡和网络接口。您必须拥有 VPC CNI 1.18.5
或更高版本才能使用仅限 EFA 的接口。如果您使用 Amazon Linux 2,则必须是 v20240928
或更高 ami 版本才能使用仅限 EFA 的接口。
以下步骤指导您使用 eksctl
创建具有 nVidia GPU 和 EFA 接口的节点的 EKS 集群。您不能使用 eksctl
创建使用仅限 EFA 的接口的节点和节点组。
先决条件
-
现有 Amazon EKS 集群。如果您没有现有集群,请参考开始使用 Amazon EKS 创建一个集群。您的集群必须部署在至少具有一个私有子网的 VPC 中,该子网应当具有足够多的可用 IP 地址以便在其中部署节点。私有子网必须具有由外部设备(如 NAT 网关)提供的出站 Internet 访问。
如果您计划使用
eksctl
创建您的节点组,eksctl
还可以为您创建集群。 -
在您的设备或 AWS CloudShell 上安装和配置 AWS 命令行界面(AWS CLI)的版本
2.12.3
或更高版本,或版本1.27.160
或更高版本。要查看当前版本,请使用aws --version | cut -d / -f2 | cut -d ' ' -f1
。yum
、apt-get
或适用于 macOS 的 Homebrew 等软件包管理器通常比 AWS CLI 的最新版本落后几个版本。要安装最新版本,请参阅《AWS 命令行界面用户指南》中的安装和使用 aws configure 快速配置。AWS CloudShell 中安装的 AWS CLI 版本也可能比最新版本落后几个版本。要对其进行更新,请参阅《AWS CloudShell 用户指南》中的将 AWS CLI 安装到您的主目录。 -
您的设备或 AWS CloudShell 上安装了
kubectl
命令行工具。该版本可以与集群的 Kubernetes 版本相同,或者最多早于或晚于该版本一个次要版本。例如,如果您的集群版本为1.29
,则可以将kubectl
的1.28
、1.29
或1.30
版本与之配合使用。要安装或升级kubectl
,请参阅 设置 kubectl 和 eksctl。 -
必须先安装适用于 Kubernetes 的 Amazon VPC CNI 插件的
1.7.10
或更高版本,才能启动支持多个 Elastic Fabric Adapter 的 Worker 节点(例如p4d
或p5
)。有关更新适用于 Kubernetes 的 Amazon VPC CNI 插件版本的更多信息,请参阅使用 Amazon VPC CNI 将 IP 分配给容器组(pod)。
重要
在 Kubernetes 中采用 EFA 时需要考虑的一个重要因素,是将 Huge Pages 作为集群中的资源进行配置和管理。有关更多信息,请参阅 Kubernetes 文档中的管理 Huge Pages
创建节点组
下面的程序通过一个包含 EFA 接口和 GPUDirect RDMA 且受 p4d.24xlarge
支持的节点组,帮助您创建节点组,并使用 EFA 针对多节点 NCCL 性能运行一个 NVIDIA Collective Communications Library (NCCL) 示例测试。该示例可用作使用 EFA 在 Amazon EKS 上进行分布式深度学习培训的模板。
-
确定您想在其中部署节点的 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 区域中可用。
-
确定您想要部署的实例类型在哪些可用区中可用。本教程使用了
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 地址。
-
使用
eksctl
创建节点组。您需要在设备或 AWS CloudShell 上安装0.204.0
版或更高版本的eksctl
命令行工具。要安装或更新eksctl
,请参阅eksctl
文档中的 Installation。 -
将以下内容复制到名为
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
-
在现有集群中创建托管节点组。
eksctl create nodegroup -f efa-cluster.yaml
如果您没有现有集群,可以运行以下命令来创建集群和节点组。
eksctl create cluster -f efa-cluster.yaml
注意
由于此示例中使用的实例类型具有 GPU,
eksctl
会在每个实例上为您自动安装 NVIDIA Kubernetes 设备插件。
-
-
部署 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 Tests
-
部署 Kubeflow MPI Operator:
对于 NCCL 测试,您可以应用 Kubeflow MPI Operator。MPI Operator 可以轻松地在 Kubernetes 上运行 Allreduce 模式的分布式训练。有关更多信息,请参阅 GitHub 上的 MPI Operator
。 -
运行多节点 NCCL 性能测试以验证 GPUDirectRDMA/EFA:
要通过 EFA 使用 GPUDirectRDMA 验证 NCCL 性能,请运行标准 NCCL 性能测试。有关更多信息,请参阅 GitHub 上的官方 NCCL 测试
存储库。 完成以下步骤以运行双节点 NCCL 性能测试。在示例 NCCL 测试作业中,每个 Worker 节点会请求八个 GPU、5210Mi 的
hugepages-2Mi
、四个 EFA 和 8000Mi 的内存,这意味着每个 Worker 节点都会使用一个p5.48xlarge
实例的所有资源。-
创建 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
-
应用 NCCL-tests MPIJob:
通过应用清单提交
MPIJob
。这将创建两个p5.48xlarge
Amazon EC2 实例。kubectl apply -f nccl-tests.yaml
示例输出如下。
mpijob.kubeflow.org/nccl-tests created
-
验证作业是否启动了容器组(pod):
查看正在运行的容器组(pod)。
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 个工作线程容器组(pod)(每个节点上一个)。
-
使用日志来验证作业是否成功运行:
查看
nccl-tests-launcher
容器组(pod)的日志。将nbql9
替换为输出中的值。kubectl logs -f nccl-tests-launcher-nbql9
-
如果测试成功完成,则可以部署使用 Nvidia 集合通信库的应用程序。