提交一个MPI分布式任务
对于MPI提交的分布式任务,我们会创建一个后缀为Launcher的Pod和多个后缀为Worker的Pod,分别表示MPI任务的启动节点和执行节点,当然Launcher即是启动节点也是执行节点。与Pytorch DDP的方式不同,mpirun没有提供master_addr
和master_port
,而是由MPI的通信机制建立容器之间的进程拓扑关系。因此MPI分布式任务的启动命令必须是如mpirun的启动命令或者包含mpirun启动命令的脚本。常见的MPI分布式训练任务有:
- Pytorch+Horovod
- Pytorch +MPI
- TensorFlow+MPI
- TensorFlow+Horovod
MPI任务在启动时会做如下事情:
- 收集当前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
在MPI Launcher Pod中增加
OMPI_MCA_plm_rsh_agent=/etc/mpi/kubexec.sh
环境变量使得mpirun建立进程通信时可以走该代理通道,从而无需建立ssh连接;同时Launcher Pod中要执行的命令也是通过该代理通道下发到各个Worker中的。在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_TC
、NCCL_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角色启动任务。