源文件: examples/aws_efa
在 HyperPod/EKS 上使用 AWS Elastic Fabric Adapter (EFA) 及 SkyPilot#
Elastic Fabric Adapter (EFA) 是 AWS 提供的一种替代 Nvidia InfiniBand 的方案,可实现节点间高水平通信。它对于需要跨节点高网络带宽的分布式 AI 训练和推理特别有用。
总而言之 (TL;DR):使用 SkyPilot 启用 EFA#
您可以在 AWS HyperPod/EKS 集群上通过在 SkyPilot YAML 中添加一个简单设置来启用 EFA
config:
kubernetes:
pod_config:
spec:
containers:
- resources:
limits:
vpc.amazonaws.com/efa: 4
requests:
vpc.amazonaws.com/efa: 4
通过 HyperPod/EKS 启用 EFA#
在 HyperPod(由 EKS 支持)上,EFA 默认启用,您无需进行任何操作。
在 EKS 上,您可能需要参考官方 AWS 文档来启用 EFA。
要检查 EFA 是否已启用,请运行
kubectl get nodes "-o=custom-columns=NAME:.metadata.name,INSTANCETYPE:.metadata.labels.node\.kubernetes\.io/instance-type,GPU:.status.allocatable.nvidia\.com/gpu,EFA:.status.allocatable.vpc\.amazonaws\.com/efa"
您会看到如下示例输出:
NAME INSTANCETYPE GPU EFA
hyperpod-i-0beea7c849d1dc614 ml.p4d.24xlarge 8 4
hyperpod-i-0da69b9076c7ff6a4 ml.p4d.24xlarge 8 4
...
访问 HyperPod 并使用 SkyPilot 运行分布式作业#
要访问 HyperPod 并使用 SkyPilot 运行分布式作业,请参阅 SkyPilot 的HyperPod 示例。
在 SkyPilot YAML 中添加 EFA 配置#
要在 SkyPilot YAML 中启用 EFA,您可以在 SkyPilot YAML 中指定以下部分
config:
kubernetes:
pod_config:
spec:
containers:
- resources:
limits:
vpc.amazonaws.com/efa: 4
requests:
vpc.amazonaws.com/efa: 4
本部分对于 EFA 集成非常重要
config.kubernetes.pod_config
: 提供 Kubernetes 特定的 Pod 配置spec.containers[0].resources
: 定义资源需求limits.vpc.amazonaws.com/efa: 4
: 限制 Pod 使用 4 个 EFA 设备requests.vpc.amazonaws.com/efa: 4
: 为 Pod 请求 4 个 EFA 设备
vpc.amazonaws.com/efa
资源类型由 Kubernetes 中的 AWS EFA 设备插件暴露。要查看每个支持 EFA 的实例类型有多少个 EFA 可用,请参阅 Amazon EC2 用户指南中的网络卡列表。
请查看下表,了解 AWS 实例类型的 GPU 和 EFA 数量对应关系
实例类型 |
GPU 类型 |
#EFA |
---|---|---|
p4d.24xlarge |
A100:8 |
4 |
p4de.24xlarge |
A100:8 |
4 |
p5.48xlarge |
H100:8 |
32 |
p5e.48xlarge |
H200:8 |
32 |
p5en.48xlarge |
H200:8 |
16 |
g5.8xlarge |
A10G:1 |
1 |
g5.12xlarge |
A10G:4 |
1 |
g5.16xlarge |
A10G:1 |
1 |
g5.24xlarge |
A10G:4 |
1 |
g5.48xlarge |
A10G:8 |
1 |
g4dn.8xlarge |
T4:1 |
1 |
g4dn.12xlarge |
T4:4 |
1 |
g4dn.16xlarge |
T4:1 |
1 |
g4dn.metal |
T4:8 |
1 |
g6.8xlarge |
L4:1 |
1 |
g6.12xlarge |
L4:4 |
1 |
g6.16xlarge |
L4:1 |
1 |
g6.24xlarge |
L4:4 |
1 |
g6.48xlarge |
L4:8 |
1 |
g6e.8xlarge |
L40S:1 |
1 |
g6e.12xlarge |
L40S:4 |
1 |
g6e.16xlarge |
L40S:1 |
1 |
g6e.24xlarge |
L40S:4 |
2 |
g6e.48xlarge |
L40S:8 |
4 |
根据您使用的 GPU 更新 nccl_efa.yaml
中的 EFA 数量。
使用 SkyPilot 运行带 EFA 的 NCCL 测试#
请查看 nccl_efa.yaml
获取完整的 SkyPilot 集群 YAML 配置。
image_id
提供了 NCCL (NVIDIA Collective Communications Library) 和 EFA (Elastic Fabric Adapter) 的环境设置。
要运行支持 EFA 的 NCCL 测试
sky launch -c efa nccl_efa.yaml
SkyPilot 将会
在启用 EFA 的节点的 Kubernetes 集群上调度作业
启动具有所需 EFA 设备的 Pod
使用 EFA 网络执行 NCCL 性能测试
输出显示 EFA 在分布式训练中优势的性能指标
注意:我们可以通过传递环境变量来禁用
nccl_efa.yaml
中的 EFAsky launch -c efa --env USE_EFA=false nccl_efa.yaml
基准测试结果#
我们在同一 HyperPod 集群(2x p4d.24xlarge,即 2xA100:8)上使用 NCCL 测试报告比较了启用和未启用 EFA 时的性能。
Speed-up
列通过 busbw EFA (GB/s) / busbw Non-EFA (GB/s)
计算得出。
消息大小 |
总线带宽 EFA (GB/s) |
总线带宽 Non-EFA (GB/s) |
加速比 |
---|---|---|---|
8 B |
0 |
0 |
- |
16 B |
0 |
0 |
- |
32 B |
0 |
0 |
- |
64 B |
0 |
0 |
- |
128 B |
0 |
0 |
- |
256 B |
0 |
0 |
- |
512 B |
0.01 |
0.01 |
1 倍 |
1 KB |
0.01 |
0.01 |
1 倍 |
2 KB |
0.02 |
0.02 |
1 倍 |
4 KB |
0.04 |
0.05 |
0.8 倍 |
8 KB |
0.08 |
0.06 |
1.3 倍 |
16 KB |
0.14 |
0.06 |
2.3 倍 |
32 KB |
0.25 |
0.17 |
1.4 倍 |
64 KB |
0.49 |
0.23 |
2.1 倍 |
128 KB |
0.97 |
0.45 |
2.1 倍 |
256 KB |
1.86 |
0.68 |
2.7 倍 |
512 KB |
3.03 |
1.01 |
3 倍 |
1 MB |
4.61 |
1.65 |
2.8 倍 |
2 MB |
6.5 |
1.75 |
3.7 倍 |
4 MB |
8.91 |
2.39 |
3.7 倍 |
8 MB |
10.5 |
2.91 |
3.6 倍 |
16 MB |
19.03 |
3.22 |
5.9 倍 |
32 MB |
31.85 |
3.58 |
8.9 倍 |
64 MB |
44.37 |
3.85 |
11.5 倍 |
128 MB |
54.94 |
3.87 |
14.2 倍 |
256 MB |
65.46 |
3.94 |
16.6 倍 |
512 MB |
71.83 |
4.04 |
17.7 倍 |
1 GB |
75.34 |
4.08 |
18.4 倍 |
2 GB |
77.35 |
4.13 |
18.7 倍 |
重点发现#
范围 |
观察 |
---|---|
≤ 256 KB |
几乎没有区别——带宽主要受软件/延迟开销限制,未达到网络上限。 |
512 KB – 16 MB |
EFA 逐渐显现优势,在几 MB 时达到约 3–6 倍。 |
≥ 32 MB |
互连网络真正发挥作用:在 32 MB 时 ≥ 8 倍,对于 1–2 GB 消息,攀升至约 18 倍。非 EFA 最高约为 4 GB/s,而 EFA 可达到 ≈ 77 GB/s。 |
EFA 提供了比传统 TCP 传输更高的吞吐量。启用 EFA 可以显著提升实例间通信性能,从而加速分布式 AI 训练和推理。
包含文件#
nccl_efa.yaml
name: nccl-test-efa
resources:
cloud: kubernetes
accelerators: A100:8
cpus: 90+
image_id: docker:public.ecr.aws/hpc-cloud/nccl-tests:latest
num_nodes: 2
envs:
USE_EFA: "true"
run: |
if [ "${SKYPILOT_NODE_RANK}" == "0" ]; then
echo "Head node"
# Total number of processes, NP should be the total number of GPUs in the cluster
NP=$(($SKYPILOT_NUM_GPUS_PER_NODE * $SKYPILOT_NUM_NODES))
# Append :${SKYPILOT_NUM_GPUS_PER_NODE} to each IP as slots
nodes=""
for ip in $SKYPILOT_NODE_IPS; do
nodes="${nodes}${ip}:${SKYPILOT_NUM_GPUS_PER_NODE},"
done
nodes=${nodes::-1}
echo "All nodes: ${nodes}"
# Set environment variables
export PATH=$PATH:/usr/local/cuda-12.2/bin:/opt/amazon/efa/bin:/usr/bin
export LD_LIBRARY_PATH=/usr/local/cuda-12.2/lib64:/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
export NCCL_HOME=/opt/nccl
export CUDA_HOME=/usr/local/cuda-12.2
export NCCL_DEBUG=INFO
export NCCL_BUFFSIZE=8388608
export NCCL_P2P_NET_CHUNKSIZE=524288
export NCCL_TUNER_PLUGIN=/opt/aws-ofi-nccl/install/lib/libnccl-ofi-tuner.so
if [ "${USE_EFA}" == "true" ]; then
export FI_PROVIDER="efa"
else
export FI_PROVIDER=""
fi
/opt/amazon/openmpi/bin/mpirun \
--allow-run-as-root \
--tag-output \
-H $nodes \
-np $NP \
-N $SKYPILOT_NUM_GPUS_PER_NODE \
--bind-to none \
-x FI_PROVIDER \
-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 2G \
-f 2 \
-g 1 \
-c 5 \
-w 5 \
-n 100
else
echo "Worker nodes"
fi
config:
kubernetes:
pod_config:
spec:
containers:
- resources:
limits:
vpc.amazonaws.com/efa: 4
requests:
vpc.amazonaws.com/efa: 4