随着人工智能和高性能计算(HPC)应用的快速发展,GPU集群的需求日益增长。为了提升集群内部通信效率,远程直接内存访问(RDMA)技术被广泛应用。eRDMA(增强型RDMA)进一步优化了这一技术,尤其在大规模分布式训练和数据处理任务中表现出色。本文将探讨如何在GPU集群中充分利用eRDMA技术,以实现最佳性能和资源利用率。
准备工作
-
创建一个E-HPC集群。具体操作,请参见创建标准版集群。
本文使用的集群配置示例如下:
配置项
配置
系列
标准版
部署模式
公共云集群
集群类型
SLURM
节点配置
-
包含
1个管理节点、1个登录节点和1个计算节点,规格如下:-
管理节点:采用ecs.r7.xlarge实例规格,该规格配置为4 vCPU,32 GiB内存。
说明管理节点推荐4 vCPU及以上的实例规格
-
登录节点:采用ecs.r7.xlarge实例规格,该规格配置为4 vCPU,32 GiB内存。
-
计算节点:采用ecs.ebmgn8v.48xlarge实例规格,该规格配置为192 vCPU、1024 GiB内存。
说明需使用支持eRDMA环境和DeepNCCL的ECS实例。更多信息,请参见GPU实例上配置eRDMA和DeepNCCL使用限制。
-
-
计算节点间使用eRDMA网络互联。
集群镜像
-
管理节点:centos_7_6_x64_20G_alibase_20211130.vhd
-
计算节点:ubuntu_22_04_uefi_x64_20G_alibase_20240807.vhd
软件与服务组件
-
docker
-
erdma-installer
-
-
创建一个集群用户,具体操作,请参见用户管理。
搭建环境
步骤一:搭建基础软件环境
-
远程连接已创建的ECS计算节点实例。具体操作,请参见使用Workbench登录Linux实例。
-
通过脚本安装GPU驱动。具体操作,请参见在GPU计算型实例中手动安装Tesla驱动(Linux)。
说明在软件与服务组件勾选了erdma-installer,则无需安装eRDMA驱动。更多内容,请参见(可选)在实例内安装弹性RDMA网卡(ERI)软件栈。
-
校验eRDMA设备状态。
-
检查网卡是否正常,正常则返回
PORT_ACTIVE。ibv_devinfo[root@xxx ]# ibv_devinfo hca_id: mlx5_bond_0 transport: InfiniBand (0) fw_ver: 32.39.3920 node_guid: c470:bd03:005d:d222 sys_image_guid: c470:bd03:005d:d222 vendor_id: 0x02c9 vendor_part_id: 41692 hw_ver: 0x1 board_id: MT_0000001093 phys_port_cnt: 1 port: 1 state: PORT_ACTIVE (4) max_mtu: 4096 (5) active_mtu: 4096 (5) sm_lid: 0 port_lid: 0 port_lmc: 0x00 link_layer: Ethernet hca_id: mlx5_bond_1 transport: InfiniBand (0) fw_ver: 32.39.3920 node_guid: c470:bd03:0071:fba0 sys_image_guid: c470:bd03:0071:fba0 vendor_id: 0x02c9 vendor_part_id: 41692 hw_ver: 0x1 board_id: MT_0000001093 phys_port_cnt: 1 port: 1 state: PORT_ACTIVE (4) max_mtu: 4096 (5) active_mtu: 4096 (5) sm_lid: 0 port_lid: 0 port_lmc: 0x00 link_layer: Ethernet -
检查网卡IP。
ifconfig -
查看网卡eRDMA流量。
eadm stat -d erdma_0 -l
-
-
校验Nvidia驱动与卡状态,确认NVIDIA驱动已安装。
如果这个命令能够成功运行,并显示出你的GPU信息(包括型号、驱动版本等),则说明NVIDIA驱动已经被正确安装并且可以正常使用。
nvidia-smi校验nv_peer_mem服务组件是否正常安装。
lsmod nvidia-peermem Usage: lsmod -
远程登录login节点,执行命令下载安装NCCL。
cd /root git clone https://github.com/NVIDIA/nccl.git cd nccl/ make -j src.lib PREFIX=/usr/local/nccl make install PREFIX=/usr/local/nccl -
编译OpenMPI。
wget https://download.open-mpi.org/release/open-mpi/v4.1/openmpi-4.1.3.tar.gz tar -xzf openmpi-4.1.3.tar.gz cd openmpi-4.1.3 ./configure --prefix=/opt/openmpi make -j && make install -
编译NCCL-Test。
cd /opt sudo git clone https://github.com/NVIDIA/nccl-tests.git cd nccl-tests make MPI=1 CUDA_HOME=/usr/local/cuda-12.4/ MPI_HOME=/opt/openmpi NCCL_HOME=/usr/local/nccl/
步骤二:批量扩容
-
使用计算节点创建自定义镜像,以便后续集群扩容节点。具体操作,请参见创建自定义镜像。
-
单击目标集群名称,在左侧导航栏,选择。
-
单击添加节点,进行集群扩容。
-
选择节点数,eRDMA网络;选择实例规格,填入目标规格,自定义镜像,系统盘大小,节点数量等参数。
-
单击确认添加,进行扩容。
-
步骤三:建立实例之间的SSH免密登录
普通用户无需配置免密登录;如果使用root用户进行NCCL测试,请配置SSH免密登录。
-
执行以下命令,在
compute000生成公钥后并拷贝到compute001上以建立实例之间的SSH互信。说明compute000为初始计算节点,compute001为扩容计算节点。#在compute000执行 ssh-keygen ssh-copy-id -i ~/.ssh/id_rsa.pub ${compute001} ssh root@{compute001} # 在compute000执行,测试一下是否可以无密码连接compute001。如果是,表示已建立实例之间的SSH互信。 -
在
compute001上重复执行此操作。
NCCL实践
单节点执行NCCL
-
登录E-HPC Portal。具体操作,请参见登录E-HPC Portal。
-
提交NCCL作业。
在顶部导航栏,选择任务管理,在页面上方,单击submitter,在创建作业页面,填写作业计算节点数为
1。执行命令脚本如下:
CUDA_HOME=/usr/local/cuda NCCL_HOME=/usr/local/nccl MPI_HOME=/opt/openmpi export LD_LIBRARY_PATH=${NCCL_HOME}/lib:${CUDA_HOME}/lib64:${MPI_HOME}/lib:$LD_LIBRARY_PATH export PATH=${CUDA_HOME}/bin:${MPI_HOME}/bin:$PATH mpirun --allow-run-as-root \ --bind-to none \ -mca btl_tcp_if_include eth0 \ -x NCCL_SOCKET_IFNAME=eth0 \ -x NCCL_DEBUG=INFO \ -x LD_LIBRARY_PATH \ -x PATH \ /opt/nccl-tests/build/all_reduce_perf -b 1 -e 1G -f 2 -g 8 -n 500 -
查询作业。
进入任务管理页面,可以查询作业列表,包含作业状态,作业操作等。更多内容,请参见查询作业。
页面左侧提供作业用户和作业队列筛选功能,作业列表以表格形式展示各作业的名称、用户、状态、应用、队列、提交时间及操作按钮。
单击目标作业可查看详情页,包含基本信息(作业名称、状态、提交时间等)、工作文件(输出日志列表)和资源使用仪表盘(CPU与内存占用率),输出日志中包含 NCCL 测试的通信和性能数据。
多节点执行NCCL
-
登录E-HPC Portal。具体操作,请参见登录E-HPC Portal。
-
提交NCCL作业。
在顶部导航栏,选择任务管理,在页面上方,单击submitter,在创建作业页面,填写作业计算节点数为
2,任务数为8。执行命令脚本如下:
CUDA_HOME=/usr/local/cuda MPI_HOME=/opt/openmpi NCCL_HOME=/usr/local/nccl export LD_LIBRARY_PATH=${NCCL_HOME}/lib:${CUDA_HOME}/lib64:${MPI_HOME}/lib:$LD_LIBRARY_PATH export PATH=${CUDA_HOME}/bin:${MPI_HOME}/bin:$PATH scontrol show hostnames $SLURM_NODELIST > hostfile mpirun --allow-run-as-root \ -np $SLURM_NTASKS -hostfile hostfile -npernode $SLURM_NTASKS_PER_NODE \ --bind-to none -mca btl_tcp_if_include eth0 \ -x NCCL_SOCKET_IFNAME=eth0 \ -x NCCL_IB_DISABLE=0 \ -x NCCL_IB_GID_INDEX=1 \ -x NCCL_NET_GDR_LEVEL=5 \ -x NCCL_IB_QPS_PER_CONNECTION=4 \ -x NCCL_MIN_NCHANNELS=16 \ -x NCCL_DEBUG=INFO \ -x NCCL_ALGO=Ring -x NCCL_P2P_LEVEL=5 \ -x LD_LIBRARY_PATH -x PATH \ /opt/nccl-tests/build/all_reduce_perf -b 1 -e 512M -f 2 -g 1 -n 1000 -w 1000 -c 0 -z 0 -o sum -
查询作业。
进入任务管理页面,可以查询作业列表,包含作业状态,作业操作等。更多内容,请参见查询作业。
安装DeepNCCL
DeepNCCL的架构、优化原理和性能说明,请参见什么是AI通信加速库DeepNCCL。
-
安装DeepNCCL。具体操作,请参见安装并使用DeepNCCL。
通过命令行提交DeepNCCL作业
-
登录集群,远程连接已创建的ECS计算节点实例。具体操作,请参见使用Workbench登录Linux实例。
-
编写作业脚本。
#!/bin/bash #SBATCH --job-name=your_job_name #SBATCH --output=output.out #SBATCH --nodes=2 #SBATCH --gres=gpu:8 #SBATCH --partition=comp #SBATCH --cpus-per-task=1 #SBATCH --ntasks-per-node=8 CUDA_HOME=/usr/local/cuda MPI_HOME=/opt/openmpi export LD_LIBRARY_PATH=${CUDA_HOME}/lib64:${MPI_HOME}/lib:$LD_LIBRARY_PATH export PATH=${CUDA_HOME}/bin:${MPI_HOME}/bin:$PATH scontrol show hostnames $SLURM_NODELIST > hostfile mpirun --allow-run-as-root -np $SLURM_NTASKS -hostfile hostfile -npernode $SLURM_NTASKS_PER_NODE \ --bind-to none -mca btl_tcp_if_include eth0 \ -x NCCL_SOCKET_IFNAME=eth0 \ -x NCCL_IB_DISABLE=0 \ -x NCCL_IB_GID_INDEX=1 \ -x NCCL_NET_GDR_LEVEL=5 \ -x NCCL_IB_QPS_PER_CONNECTION=4 \ -x NCCL_MIN_NCHANNELS=16 \ -x NCCL_DEBUG=INFO \ -x NCCL_ALGO=Ring -x NCCL_P2P_LEVEL=5 \ -x LD_LIBRARY_PATH -x PATH \ /opt/nccl-tests/build/all_reduce_perf -b 100M -i 100000000 -e 10G -f 2 -g 1 -n 10 -
提交作业。替换
your_shell脚本名称。sbatch your_shell.sh -
通过slurm查询作业。
使用
squeue命令可以查询当前正在运行和排队中的作业列表。squeue使用
sacct命令可以查询作业的历史记录,包括已完成的作业。sacct -
到目标节点校验
nccl-test运行状态。-
查询NCCL 带宽。
执行命令,打开作业输出日志
output.out,查询算法带宽与总线带宽。cat output.out# nThread 1 nGpus 1 minBytes 1 maxBytes 1073741824(1G) step: 2(factor) warmup iters: 1000 iters: 1000 agg iters: 1 validation: 0 graph: 0 # # Using devices # Rank 0 Pid 27549 on compute000 device 0 [0x00] NVIDIA A800-SXM4-80GB # Rank 1 Pid 27549 on compute000 device 1 [0x00] NVIDIA A800-SXM4-80GB # Rank 2 Pid 27549 on compute000 device 2 [0x00] NVIDIA A800-SXM4-80GB # Rank 3 Pid 27549 on compute000 device 3 [0x00] NVIDIA A800-SXM4-80GB # Rank 4 Pid 27549 on compute000 device 4 [0x00] NVIDIA A800-SXM4-80GB # Rank 5 Pid 27549 on compute000 device 5 [0x00] NVIDIA A800-SXM4-80GB # Rank 6 Pid 27549 on compute000 device 6 [0x00] NVIDIA A800-SXM4-80GB # Rank 7 Pid 27549 on compute000 device 7 [0x00] NVIDIA A800-SXM4-80GB compute000:27549:27549 [0] NCCL INFO Channel 00/16 : 0 1 2 3 4 5 6 7 ... compute000:27549:27549 [0] NCCL INFO comm 0x5607... rank 0 nranks 8 cudaDev 0 nvmlDev 0 busId 0 - Init COMPLETEcompute000:27549:27549 [0] NCCL INFO comm 0x5607... rank 0 nranks 8 - Init COMPLETE ... # 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) 8 2 float sum -1 8.16 0.00 0.00 0 8.06 0.00 0.00 0 16 4 float sum -1 8.14 0.00 0.00 0 8.07 0.00 0.00 0 32 8 float sum -1 8.14 0.00 0.00 0 8.08 0.00 0.00 0 1024 256 float sum -1 9.94 0.10 0.09 0 9.93 0.10 0.09 0 16384 4096 float sum -1 14.49 1.13 0.99 0 14.45 1.13 0.99 0 262144 65536 float sum -1 25.47 10.29 9.01 0 25.61 10.24 8.96 0 1048576 262144 float sum -1 44.14 23.76 20.79 0 44.24 23.70 20.74 0 16777216 4194304 float sum -1 193.2 86.83 76.00 0 193.1 86.88 76.02 0 268435456 67108864 float sum -1 2671.3 100.48 87.92 0 2672.4 100.44 87.89 0 1073741824 268435456 float sum -1 10574 101.54 88.85 0 10572 101.56 88.86 0 # Avg bus bandwidth : 87.42 # Out of bounds values : 0 OK compute000:27549:27549 [0] NCCL INFO comm ... rank 0 nranks 8 - Destroy COMPLETE -
查询eRDMA带宽。
说明在任务通信时进行测试。
执行
eadm stat -d erdma_1 -l与nvidia-smi校验all-reduce运行状态与eRDMA带宽情况。eadm stat -d erdma_1 -l nvidia-smiProcesses: GPU GI CI PID Type Process name GPU Memory Usage 0 N/A N/A 68258 C /opt/nccl-tests/build/all_reduce_perf 31550MiB 1 N/A N/A 68259 C /opt/nccl-tests/build/all_reduce_perf 31550MiB 2 N/A N/A 68260 C /opt/nccl-tests/build/all_reduce_perf 31550MiB 3 N/A N/A 68261 C /opt/nccl-tests/build/all_reduce_perf 31550MiB 4 N/A N/A 68262 C /opt/nccl-tests/build/all_reduce_perf 31550MiB 5 N/A N/A 68263 C /opt/nccl-tests/build/all_reduce_perf 31550MiB 6 N/A N/A 68264 C /opt/nccl-tests/build/all_reduce_perf 31550MiB 7 N/A N/A 68265 C /opt/nccl-tests/build/all_reduce_perf 31550MiB root@compute016:/home/usertest# eadm stat -d erdma_1 -l Monitoring erdma_1... (press CTRL-C to stop) 14:57:26 rx: 0 B/s 0 p/s tx: 0 B/s 0 p/s 14:57:58 rx: 9.13 GiB/s 7118852 p/s tx: 9.14 GiB/s 7123069 p/s
-
PyTorch实践
安装PyTorch
-
远程连接计算节点实例。具体操作,请参见使用Workbench登录Linux实例。
-
执行命令,安装PyTorch。
重要在两台计算节点上安装PyTorch。
pip install torch torchvision torchaudio --extra-index-url https://download.pytorch.org/whl/cu121 -
使用root用户,在
/opt下创建文件benchmark.py。具体代码,请参见官方网站。
通过Portal提交作业
-
登录E-HPC Portal。具体操作,请参见登录E-HPC Portal。
-
提交NCCL作业。
在顶部导航栏,选择任务管理,在页面上方,单击submitter,在创建作业页面,填写作业计算节点数为
2,任务数为1,Gpu数为8。执行命令脚本如下:
#!/bin/sh export NCCL_DEBUG=INFO export NCCL_SOCKET_IFNAME=eth0 export NCCL_IB_DISABLE=0 export NCCL_IB_GID_INDEX=1 export NCCL_NET_GDR_LEVEL=5 export NCCL_IB_QPS_PER_CONNECTION=4 export NCCL_MIN_NCHANNELS=16 export NCCL_P2P_LEVEL=5 export NCCL_ALGO=Ring export MASTER_ADDR=$(scontrol show hostnames $SLURM_JOB_NODELIST | head -n 1) export MASTER_PORT=9901 srun bash -c 'echo "Node ID: $SLURM_NODEID, Current Node: $(hostname)" && torchrun --nproc_per_node=$SLURM_GPUS_ON_NODE \ --nnodes=$SLURM_NNODES \ --node_rank=$SLURM_NODEID \ --master_addr=$MASTER_ADDR \ --master_port=$MASTER_PORT \ /opt/benchmark.py \ --world-size=$(($SLURM_NNODES * $SLURM_GPUS_ON_NODE)) \ --batch-size=320 \ --master-addr=$MASTER_ADDR \ --master-port=$MASTER_PORT \ --warmup-iterations=50 \ --measured-iterations=200 \ --bucket-size=25 \ --model=resnet50' -
查询作业。
进入任务管理页面,可以查询作业列表,包含作业状态,作业操作等。更多内容,请参见查询作业。
提交作业后,在作业列表中可查看该作业,状态显示为RUNNING表示作业正在运行。单击目标作业查看详情,工作文件区域列出输出文件及其大小和最后修改时间,右侧展示资源使用仪表盘。
通过slurm提交作业
-
登录集群,具体操作,请参见连接集群。
-
在登录节点
/opt下创建脚本run_pytorch.slurm,内容如下:#!/bin/bash #SBATCH --job-name=pytorch_demo #SBATCH --output=pytorch_demo.ouput #SBATCH --nodes=2 #SBATCH --gres=gpu:8 #SBATCH --partition=comp #SBATCH --cpus-per-task=1 #SBATCH --ntasks-per-node=1 export NCCL_DEBUG=INFO export NCCL_SOCKET_IFNAME=eth0 export NCCL_IB_DISABLE=0 export NCCL_IB_GID_INDEX=1 export NCCL_NET_GDR_LEVEL=5 export NCCL_IB_QPS_PER_CONNECTION=4 export NCCL_MIN_NCHANNELS=16 export NCCL_DEBUG=INFO export NCCL_P2P_LEVEL=5 export NCCL_ALGO=Ring export MASTER_ADDR=$(scontrol show hostnames $SLURM_JOB_NODELIST | head -n 1) export MASTER_PORT=9901 srun bash -c 'torchrun --nproc_per_node=$SLURM_GPUS_ON_NODE \ --nnodes=$SLURM_NNODES \ --node_rank=$SLURM_NODEID \ --master_addr=$MASTER_ADDR \ --master_port=$MASTER_PORT \ benchmark.py \ --world-size=$(($SLURM_NNODES * $SLURM_GPUS_ON_NODE)) \ --batch-size=320 \ --master-addr=$MASTER_ADDR \ --master-port=$MASTER_PORT \ --warmup-iterations=50 \ --measured-iterations=200 \ --bucket-size=25 \ --model=resnet50' -
执行脚本
run_pytorch.slurm。sbatch run_pytorch.slurm -
通过slurm查询作业。
使用
squeue命令可以查询当前正在运行和排队中的作业列表。squeue使用
sacct命令可以查询作业的历史记录,包括已完成的作业。sacct[root@login0 usertest]# sacct JobID JobName Partition Account AllocCPUS State ExitCode ------------ ---------- ---------- ---------- ---------- ---------- -------- 52 submitter+ comp 2 CANCELLED+ 0:0 52.batch batch 1 CANCELLED 0:15 53 submitter+ comp 1 CANCELLED+ 0:0 53.batch batch 1 CANCELLED 0:15 54 pytorch_d+ comp root 1 COMPLETED 0:0 54.batch batch 1 COMPLETED 0:0 55 pytorch_d+ comp root 2 RUNNING 0:0 55.batch batch 1 RUNNING 0:0执行命令
nvidia-smi查看显卡信息。nvidia-smi$ nvidia-smi +-----------------------------------------------------------------------------------------+ | NVIDIA-SMI 550.54.15 Driver Version: 550.54.15 CUDA Version: 12.4 | |-----------------------------------------+------------------------+----------------------+ | GPU Name Persistence-M | Bus-Id Disp.A | Volatile Uncorr. ECC | | Fan Temp Perf Pwr:Usage/Cap | Memory-Usage | GPU-Util Compute M. | |=========================================+========================+======================| | 0 NVIDIA A800-SXM4-80GB On | 00000000:1d:00.0 Off | 0 | | N/A 54C P0 377W / 400W | 31550MiB / 81920MiB | 100% Default | |-----------------------------------------+------------------------+----------------------+ | 1 NVIDIA A800-SXM4-80GB On | 00000000:3d:00.0 Off | 0 | | N/A 56C P0 340W / 400W | 31550MiB / 81920MiB | 100% Default | |-----------------------------------------+------------------------+----------------------+ | 2 NVIDIA A800-SXM4-80GB On | 00000000:60:00.0 Off | 0 | | N/A 53C P0 338W / 400W | 31550MiB / 81920MiB | 100% Default | |-----------------------------------------+------------------------+----------------------+ | 3 NVIDIA A800-SXM4-80GB On | 00000000:88:00.0 Off | 0 | | N/A 54C P0 352W / 400W | 31550MiB / 81920MiB | 100% Default | |-----------------------------------------+------------------------+----------------------+
运维管理
E-HPC提供eRDMA GPU集群的RDMA与GPU异常巡检功能,全面监测eRDMA网卡状态、GPU掉卡及驱动状态等异常情况,并将监测结果实时通过事件总线上报至钉钉或飞书平台。
-
自行创建飞书/钉钉的Webhook。
-
登录事件总线控制台,在事件总线产品页,单击确认开通,进行事件总线产品服务开通。
-
选择地域,在左侧导航栏,单击事件总线,单击default进入云服务专用总线概览页。
-
单击事件规则页签,单击创建规则按钮,在弹出的创建规则面板,配置以下信息:
-
在配置基本信息向导,自定义规则名称,然后单击下一步。
例如,在名称中输入gpu-fault-event。
-
在配置事件模式向导,按如下进行配置,然后单击下一步。
-
事件源类型:选择阿里云官方事件源。
-
事件源:选择acs.ehpc。
-
事件类型:选择事件,本文选择ehpc:Maintenance:NodeGpuFault、ehpc:Maintenance:NodeErdmaFault。
-
-
在配置事件目标向导,按如下进行配置,最后单击创建。
-
服务类型:选择飞书 acs.lark或钉钉 acs.dingtalk。
-
地址:输入步骤一创建的飞书/钉钉的Webhook.
-
变量:
{ "Uid": "$.data.Uid", "SeverityLevel": "$.data.SeverityLevel", "ExecuteCmd": "$.data.ExecuteCmd", "ClusterId": "$.data.ClusterId", "InstanceId": "$.data.InstanceId", "FaultDetail": "$.data.FaultDetail", "FaultType": "$.data.FaultType", "FaultTarget": "$.data.FaultTarget", "InstanceType": "$.data.InstanceType", "MessageId": "$.data.MessageId", "DetectedAt": "$.data.DetectedAt", "aliyunregionid": "$.aliyunregionid", "eventID": "$.id" } -
模板:
{ "msg_type": "text", "content": { "text": "亲爱的阿里云客户 ${Uid} ,您好!\n温馨提醒您的账户下在 ${aliyunregionid} 地域的弹性高性能计算集群 ${ClusterId} 于 ${DetectedAt} 出现节点故障,详细信息如下:\n\t实例ID: ${InstanceId}\n\t实例类型: ${InstanceType}\n\t错误类型: ${FaultType}\n\t错误对象: ${FaultTarget}\n\t消息ID: ${MessageId}\n\t错误等级: ${SeverityLevel}\n\t错误详情: ${FaultDetail}\n\nPS: 本次的事件ID为 ${eventID} ,如果您在使用E-HPC过程有任何疑问请凭此事件ID发起工单提问!" } }
-
-
-
当eRDMA GPU集群出现RDMA或GPU异常时,事件总线会发送通知给您设置的Webhook。
飞书推送测试示意图:
