提交一个MPI分布式任务 | 大装置帮助中心
跳到主要内容

提交一个MPI分布式任务

对于MPI提交的分布式任务,我们会创建一个后缀为Launcher的Pod和多个后缀为Worker的Pod,分别表示MPI任务的启动节点和执行节点,当然Launcher即是启动节点也是执行节点。与Pytorch DDP的方式不同,mpirun没有提供master_addrmaster_port,而是由MPI的通信机制建立容器之间的进程拓扑关系。因此MPI分布式任务的启动命令必须是如mpirun的启动命令或者包含mpirun启动命令的脚本。常见的MPI分布式训练任务有:

  • Pytorch+Horovod
  • Pytorch +MPI
  • TensorFlow+MPI
  • TensorFlow+Horovod

MPI任务在启动时会做如下事情:

  1. 收集当前MPI任务所有的Podname到MPI Launcher Pod的/etc/mpi/hostfile 文件中, 格式如下:
MPI-zjwghlra-launcher slots=8
MPI-zjwghlra-worker-0 slots=8
MPI-zjwghlra-worker-1 slots=8
MPI-zjwghlra-worker-2 slots=8
MPI-zjwghlra-worker-3 slots=8
MPI-zjwghlra-worker-4 slots=8
MPI-zjwghlra-worker-5 slots=8
MPI-zjwghlra-worker-6 slots=8
  1. 在MPI Launcher Pod中增加OMPI_MCA_plm_rsh_agent=/etc/mpi/kubexec.sh环境变量使得mpirun建立进程通信时可以走该代理通道,从而无需建立ssh连接;同时Launcher Pod中要执行的命令也是通过该代理通道下发到各个Worker中的。

  2. 在MPI Launcher Pod中增加OMPI_MCA_orte_default_hostfile=/etc/mpi/hostfile环境变量来设置默认hostfile,这样用户在执行mpirun命令的时候就无需手动指定hostfile。

此外针对MPI启动命令,必须增加一些必备项,才能保障正确执行,如下所示:

mpirun --allow-run-as-root -bind-to none -map-by slot -mca pml ob1 -mca btl ^openib -mca plm_rsh_num_concurrent 300 -mca routed_radix 600 -mca plm_rsh_no_tree_spawn 1

详细解释:

mpirun \
--allow-run-as-root \ ## 指的是允许root身份执行程序,默认是不允许
-bind-to none -map-by slot \ ## openMPI才会用到,指的是不自动绑定cpu核心,可以使用超线程,并且按照设置的slot进行映射,我们默认的每个节点的slot=用户设置的Pod GPU数量
-mca pml ob1 -mca btl ^openib \ ## openMPI建立进程socket的强制使用ob1 PML方式,建立连接不使用IB网
-mca plm_rsh_num_concurrent 300 \ ## openMPI 指定要同时调用的plm_rsh_agent实例数
-mca routed_radix 600 \ ## 解决限制Pod并发数量问题,在起的MPI 容器少于65个时不用加,大于等于65就需要加这个,否则会被openMPI约束
-mca plm_rsh_no_tree_spawn 1 \ ## openMPI指定是否使用基于树的拓扑启动应用程序,1为允许
-np 1 \ ## 表示训练任务使用的进程数,其值小于等于GPU总数,如4机8卡,就是4*8=32;当np小于GPU总数时会有 (GPU总数-np) 个GPU无法被使用

对于使用RoCE的算力池的训练任务,可以在训练脚本中增加如下环境变量获得最优性能, 这个环境变量需要写到用户得任务脚本中或者通过mpirun -x的参数项带到进程中:

注意:对于使用IB类型的算力池任务,可以不加NCCL_IB_TCNCCL_IB_GID_INDEX这两个环境变量,加了可能会比较慢

export NCCL_DEBUG=INFO     # 这个与性能无关,只是便于排查问题
export NCCL_IB_TC=106 # 指定NCCL使用的交换机通道
export NCCL_IB_GID_INDEX=3 # 选择指定的IB index
export NCCL_SOCKET_IFNAME=eth0 # 在构建NCCL socket时选择eth0网络
export NCCL_CROSS_NIC=0 # 固定每个网卡的连接通道

#当训练的规模达到千卡及以上时,可以增加如下环境变量:
export NCCL_ALGO=RING

UI界面提交MPI任务示例

注意:算力池当前的MPI任务只支持openmpi!!!原因是社区中采用预配置节点的方式为openmpi命令独有的参数,其他MPI实现可能会有所差别,暂时还不支持。https://www.open-MPI.org/

在a100_RoCE_1024算力池【RoCE类型的算力池】上启动一个128机8卡共计1024卡的NCCL-test 任务。 启动命令如下:

mpirun --allow-run-as-root \
-bind-to none -map-by slot \
-mca pml ob1 -mca btl ^openib \
-mca plm_rsh_num_concurrent 300 \
-mca routed_radix 600 \
-mca plm_rsh_no_tree_spawn 1 \
-x NCCL_DEBUG=INFO \
-x NCCL_IB_GID_INDEX=3 \
-x NCCL_IB_TC=106 \
-x NCCL_CROSS_NIC=0 \
-x NCCL_ALGO=RING \
-x NCCL_SOCKET_IFNAME=eth0 \
-np 1024 \
/root/nccl_test/build/all_reduce_perf -b 4M -e 1024M -f 2 -g 1

上面是RoCE类型算力池MPI任务的示例,如果是IB类型的算力池,提交的流程完全相同,只需要去掉启动命令中的

-x NCCL_IB_GID_INDEX=3
-x NCCL_IB_TC=106

这两个环境变量即可。

注意:我们在新版本的高性能AI算力池中简化了任务提交流程,您只需要指定一个角色数量和规格。若您指定和n个角色数量,我们会自动为您以1个Launcher角色和n-1个Worker角色启动任务。