eRDMA GPU集群最佳实践

随着人工智能和高性能计算(HPC)应用的快速发展,GPU集群的需求日益增长。为了提升集群内部通信效率,远程直接内存访问(RDMA)技术被广泛应用。eRDMA(增强型RDMA)进一步优化了这一技术,尤其在大规模分布式训练和数据处理任务中表现出色。本文将探讨如何在GPU集群中充分利用eRDMA技术,以实现最佳性能和资源利用率。

准备工作

  1. 创建一个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环境和DeepNCCLECS实例。更多信息,请参见GPU实例上配置eRDMADeepNCCL使用限制

    • 计算节点间使用eRDMA网络互联。

    集群镜像

    • 管理节点:centos_7_6_x64_20G_alibase_20211130.vhd

    • 计算节点:ubuntu_22_04_uefi_x64_20G_alibase_20240807.vhd

    软件与服务组件

    • docker

    • erdma-installer

  2. 创建一个集群用户,具体操作,请参见用户管理

搭建环境

步骤一:搭建基础软件环境

  1. 远程连接已创建的ECS计算节点实例。具体操作,请参见使用Workbench工具以SSH协议登录Linux实例

    image

  2. 通过脚本安装GPU驱动。具体操作,请参见GPU计算型实例中手动安装Tesla驱动(Linux)

    说明

    在软件与服务组件勾选了erdma-installer,则无需安装eRDMA驱动。更多内容,请参见(可选)在实例内安装弹性RDMA网卡(ERI)软件栈。

  3. 校验eRDMA设备状态。

    1. 检查网卡是否正常,正常则返回PORT_ACTIVE

      ibv_devinfo

      image

    2. 检查网卡IP。

      ifconfig
    3. 查看网卡eRDMA流量。

      eadm stat -d erdma_0 -l
  4. 校验Nvidia驱动与卡状态,确认NVIDIA驱动已安装。

    如果这个命令能够成功运行,并显示出你的GPU信息(包括型号、驱动版本等),则说明NVIDIA驱动已经被正确安装并且可以正常使用。

    nvidia-smi

    校验nv_peer_mem服务组件是否正常安装。

    lsmod nvidia-peermem
    
    Usage: lsmod
  5. 远程登录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
  6. 编译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
  7. 编译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/

步骤二:批量扩容

  1. 使用计算节点创建自定义镜像,以便后续集群扩容节点。具体操作,请参见创建自定义镜像

  2. 单击目标集群名称,在左侧导航栏,选择节点与队列 > 节点

  3. 单击添加节点,进行集群扩容。

    1. 选择节点数eRDMA网络;选择实例规格,填入目标规格,自定义镜像,系统盘大小,节点数量等参数。

      image.png

    2. 单击确认添加,进行扩容。

步骤三:建立实例之间的SSH免密登录

重要

普通用户无需配置免密登录;如果使用root用户进行NCCL测试,请配置SSH免密登录。

  1. 执行以下命令,在compute000生成公钥后并拷贝到compute001上以建立实例之间的SSH互信。

    说明

    compute000为初始计算节点,compute001为扩容计算节点。

    #在compute000执行
    ssh-keygen
    ssh-copy-id -i ~/.ssh/id_rsa.pub ${compute001}
    
    ssh root@{compute001}   # 在compute000执行,测试一下是否可以无密码连接compute001。如果是,表示已建立实例之间的SSH互信。
  2. compute001上重复执行此操作。

NCCL实践

单节点执行NCCL

  1. 登录E-HPC Portal。具体操作,请参见登录E-HPC Portal

  2. 提交NCCL作业。

    在顶部导航栏,选择任务管理,在页面上方,单击submitter,在创建作业页面,填写作业计算节点数1

    image.png

    执行命令脚本如下:

    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
    
  3. 查询作业。

    进入任务管理页面,可以查询作业列表,包含作业状态,作业操作等。更多内容,请参见查询作业

    image.png

    image.png

多节点执行NCCL

  1. 登录E-HPC Portal。具体操作,请参见登录E-HPC Portal

  2. 提交NCCL作业。

    在顶部导航栏,选择任务管理,在页面上方,单击submitter,在创建作业页面,填写作业计算节点数2任务数8

    image

    执行命令脚本如下:

    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
  3. 查询作业。

    进入任务管理页面,可以查询作业列表,包含作业状态,作业操作等。更多内容,请参见查询作业

    image

安装DeepNCCL

DeepNCCL的架构、优化原理和性能说明,请参见什么是AI通信加速库DeepNCCL

通过命令行提交DeepNCCL作业

  1. 登录集群,远程连接已创建的ECS计算节点实例。具体操作,请参见使用Workbench工具以SSH协议登录Linux实例

    image

  2. 编写作业脚本。

    #!/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
  3. 提交作业。替换your_shell脚本名称。

    sbatch your_shell.sh
  4. 通过slurm查询作业。

    使用 squeue 命令可以查询当前正在运行和排队中的作业列表。

    squeue

    使用 sacct 命令可以查询作业的历史记录,包括已完成的作业。

    sacct
  5. 到目标节点校验nccl-test运行状态。

    1. 查询NCCL 带宽。

      执行命令,打开作业输出日志output.out,查询算法带宽与总线带宽。

       cat output.out

      df72fc21a91ea181fdc0cae1cd59b4da8cf99a03d146023ffbb4734067e5371b

    2. 查询eRDMA带宽。

      说明

      在任务通信时进行测试。

      执行eadm stat -d erdma_1 -lnvidia-smi校验all-reduce运行状态与eRDMA带宽情况。

      eadm stat -d erdma_1 -l
      
      nvidia-smi

      image.png

PyTorch实践

安装PyTorch

  1. 远程连接计算节点实例。具体操作,请参见使用Workbench工具以SSH协议登录Linux实例

  2. 执行命令,安装PyTorch。

    重要

    在两台计算节点上安装PyTorch。

    pip install torch torchvision torchaudio --extra-index-url https://download.pytorch.org/whl/cu121
  3. 使用root用户,在/opt下创建文件 benchmark.py。具体代码,请参见官方网站

通过Portal提交作业

  1. 登录E-HPC Portal。具体操作,请参见登录E-HPC Portal

  2. 提交NCCL作业。

    在顶部导航栏,选择任务管理,在页面上方,单击submitter,在创建作业页面,填写作业计算节点数2任务数1Gpu8

    image

    执行命令脚本如下:

    #!/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'
  3. 查询作业。

    进入任务管理页面,可以查询作业列表,包含作业状态,作业操作等。更多内容,请参见查询作业

    image.pngimage.png

通过slurm提交作业

  1. 登录集群,具体操作,请参见连接集群

  2. 在登录节点/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'
  3. 执行脚本run_pytorch.slurm

    sbatch run_pytorch.slurm
  4. 通过slurm查询作业。

    使用 squeue 命令可以查询当前正在运行和排队中的作业列表。

    squeue

    使用 sacct 命令可以查询作业的历史记录,包括已完成的作业。

    sacct

    image.png

    执行命令nvidia-smi查看显卡信息。

    nvidia-smi

    image.png

运维管理

E-HPC提供eRDMA GPU集群的RDMAGPU异常巡检功能,全面监测eRDMA网卡状态、GPU掉卡及驱动状态等异常情况,并将监测结果实时通过事件总线上报至钉钉或飞书平台。

  1. 自行创建飞书/钉钉的Webhook。

  2. 登录事件总线控制台,在事件总线产品页,单击确认开通,进行事件总线产品服务开通。

    image.png

  3. 选择地域,在左侧导航栏,单击事件总线,单击default进入云服务专用总线概览页。

    image.png

  4. 单击事件规则页签,单击创建规则按钮,在弹出的创建规则面板,配置以下信息:

    1. 配置基本信息向导,自定义规则名称,然后单击下一步

      image.png

    2. 配置事件模式向导,按如下进行配置,然后单击下一步

      1. 事件源类型:选择阿里云官方事件源

      2. 事件源:选择acs.ehpc

      3. 事件类型:选择事件,本文选择ehpc:Maintenance:NodeGpuFaultehpc:Maintenance:NodeErdmaFaultimage.png

    3. 配置事件目标向导,按如下进行配置,最后单击创建

      1. 服务类型:选择飞书 acs.lark钉钉 acs.dingtalk

      2. 地址:输入步骤一创建的飞书/钉钉的Webhook.

      3. 变量:

        {
            "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"
        }
      4. 模板

        {
            "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发起工单提问!"
            }
        }
  5. eRDMA GPU集群出现RDMAGPU异常时,事件总线会发送通知给您设置的Webhook。

    飞书推送测试示意图:

    image