Tendo33 / oneflow-test

oneflow test
0 stars 0 forks source link

腾讯云A800-Libai-Megatron对比 #15

Open Tendo33 opened 1 year ago

Tendo33 commented 1 year ago

A800-Libai-Megatron 关于 GPT2 对比测试

Docker 环境

  1. Docker镜像为:基于NGC容器 nvcr.io/nvidia/pytorch:21.07-py3,安装了免密,ib 驱动为5.3版本,配置好了宿主机的IP列表
  2. TCCL 插件为:nccl-rdma-sharp-plugins_1.1_amd64.deb

NCCL-Test

指定 export HOME=/data_turbo/home/share/workspace,后出现HOME均用此路径代替

  1. 启动 Docker 容器:docker run --gpus all -itd --shm-size=16g --ulimit memlock=-1 --ulimit core=0 --ulimit stack=67108864 --privileged --cap-add=IPC_LOCK --name "gpt_test" --ipc host --net host -v "$HOME":"$HOME" "ngc/pytorch-21.07:ssh-ib5.4-config-py38" bash -c "sed -i 's/Port 62620/Port 10098/g' /root/.ssh/config && /usr/sbin/sshd -p 10098 && bash" 创建一名为gpt_test 的容器,后出现gpt_test均指此容器
参数解释:

--gpus all:指定容器可以使用所有可用的GPU资源。

-itd:以交互模式并在后台运行容器。

--shm-size=16g:为容器设置共享内存大小为16GB。

--ulimit memlock=-1:设置容器可以锁定任意数量的内存。

--ulimit core=0:禁用容器内的核心转储文件生成。

--ulimit stack=67108864:设置容器的堆栈大小为64MB。

--privileged:赋予容器所有的特权。

--cap-add=IPC_LOCK:允许容器锁定共享内存。

--name "gpt_test":指定容器的名称为"gpt_test"。

--ipc host:共享宿主机的IPC命名空间。

--net host:使用宿主机的网络命名空间。

-v "$HOME":"$HOME":将宿主机的$HOME目录挂载到容器的$HOME目录中,以便容器可以访问宿主机上的文件。

"ngc/pytorch-21.07:ssh-ib5.4-config-py38":指定要使用的Docker镜像的名称和标签。

bash -c "sed -i 's/Port 62620/Port 10098/g' /root/.ssh/config && /usr/sbin/sshd -p 10098 && bash":在容器启动时执行的命令。此命令将更改容器内的SSH配置文件中的端口号,并启动SSH服务器。最后,它将启动一个新的bash shell供用户使用。
  1. 051,052,053,054,055,056,057,058 机器中运行容器
  2. 登录到任一台GPU节点的 docker 容器中:docker attach gpt_test进入容器
  3. 下载 nccl-test文件:cd $HOME && git clone [https://github.com/NVIDIA/nccl-tests.git](https://github.com/NVIDIA/nccl-tests.git)
  4. 编译 nccl-test:cd nccl-tests && make MPI=1 MPI_HOME=/usr/local/mpi/
  5. 测试 8 台机器,逐步递增,增长因子为 2:mpirun -np 64 -H 051:8,052:8,053:8,054:8,055:8,056:8,057:8,058:8 --allow-run-as-root -bind-to none -map-by slot -x NCCL_IB_DISABLE=0 -x NCCL_IB_GID_INDEX=3 -x NCCL_GDR_LEVEL=2 -x NCCL_DEBUG=INFO -x NCCL_IB_QPS_PER_CONNECTION=4 -x NCCL_IB_TC=160 -x LD_LIBRARY_PATH -x PATH -mca pml ob1 -mca btl_tcp_if_include bond0 -mca btl ^openib $HOME/nccl-tests/build/all_reduce_perf -b 2G -e 4G -f 2 -g 1 | tee $HOME/nccl-tests/nccl_log/nccl_increace_16n8g.log 测试 8 台机器,固定大小重复 100 次:mpirun -np 64 -H 051:8,052:8,053:8,054:8,055:8,056:8,057:8,058:8 --allow-run-as-root -bind-to none -map-by slot -x NCCL_IB_DISABLE=0 -x NCCL_IB_GID_INDEX=3 -x NCCL_GDR_LEVEL=2 -x NCCL_DEBUG=INFO -x NCCL_IB_QPS_PER_CONNECTION=4 -x NCCL_IB_TC=160 -x LD_LIBRARY_PATH -x PATH -mca pml ob1 -mca btl_tcp_if_include bond0 -mca btl ^openib $HOME/nccl-tests/build/all_reduce_perf -b 4G -e 4G -n 100 -g 1 | tee $HOME/nccl-tests/nccl_log/nccl_stable_16n8g.log
参数详解:

mpirun:这是使用 MPI 启动并行程序的命令。
-np 64:这指定启动的进程数,本例中为 64。

-H 051:8,052:8,053:8,054:8,055:8,056:8,057:8,058:8:该选项指定要在哪些节点上启动进程,以及每个节点要启动的进程数。在本例中,每个节点 051、052、053、054、055、056、057 和 058 上启动了 8 个进程。

--allow-run-as-root:此选项允许以 root 用户身份运行程序。

-bind-to none:此选项指定进程不应绑定到特定的处理单元。

-map-by slot:此选项按插槽分配进程到处理单元,每个插槽代表一个处理单元。

-x NCCL_IB_DISABLE=0:此选项将环境变量 `NCCL_IB_DISABLE设置为 0,启用 InfiniBand 通信。

-x NCCL_IB_GID_INDEX=3:此选项将环境变量 NCCL_IB_GID_INDEX 设置为 3,指定 InfiniBand 通信使用的 GID(全局唯一标识符)索引。

-x NCCL_GDR_LEVEL=2:此选项将环境变量 NCCL_GDR_LEVEL 设置为 2,启用 GPU Direct RDMA(远程直接内存访问)用于 GPU 之间的通信。

-x NCCL_DEBUG=INFO:此选项将环境变量 NCCL_DEBUG 设置为 INFO,启用 NCCL(NVIDIA Collective Communications Library)操作的调试信息。

-x NCCL_IB_QPS_PER_CONNECTION=4:此选项将环境变量 NCCL_IB_QPS_PER_CONNECTION 设置为 4,指定每个 IB(InfiniBand)连接使用的 QP(队列对)数。

-x NCCL_IB_TC=160:此选项将环境变量 NCCL_IB_TC 设置为 160,指定 InfiniBand 通信使用的流量类。

-x LD_LIBRARY_PATH:此选项导出当前的 LD_LIBRARY_PATH 值,该环境变量指定要搜索共享库的目录。

-x PATH:此选项导出当前的 PATH 值,该环境变量指定要搜索可执行文件的目录。

-mca pml ob1:此选项指定要使用的 PML(点对点消息传递层)模块,默认为 Open MPI 的 ob1 模块。

-mca btl_tcp_if_include bond0:此选项指定要用于 TCP 通信的 BTL(字节传输层)模块,并指定要使用的网络接口为 bond0。

-mca btl ^openib:此选项指定要禁用 InfiniBand 通信的 Open MPI BTL 模块。

$HOME/nccl-tests/build/all_reduce_perf:此项指定要在 MPI 环境中运行的可执行文件路径。

-b 2G:开始的 size 大小

-e 4G:结束的 size 大小

-f 2:size 之间的乘数因子

-n 100:重复迭代次数

-g 1:此选项指定每个 GPU 上的进程数,本例中为 1。

| tee $HOME/nccl-tests/nccl_log/nccl_increace_16n8g.log:此项将程序的标准输出传输到 tee 命令,该命令将输出写入指定的文件
  1. 结果:busbw 值在 167GB/s左右,完整log,在log中注意 Using devicesGDRDMAUsing network IBext等信息。
#                                                              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)       
2147483648     536870912     float     sum      -1    25040   85.76  168.84      0    24828   86.49  170.28      0
4294967296    1073741824     float     sum      -1    52185   82.30  162.03      0    50414   85.19  167.73      0
# Out of bounds values : 0 OK
# Avg bus bandwidth    : 167.221

进行 Libai 训练

  1. 查看容器是否已经全部启动:ansible 051,052,053,054,055,056,057,058 -m shell -a "docker ps | grep gpt_test"
  2. 环境配置以及数据集下载 :run_libai_gpt.sh
  3. 在任意一台GPU机器,cd $HOME/libai创建一个DDP运行多机的文件,run_train_libai.sh
set -ex
# 解析输入参数,使用逗号分割多个主机名
hosts=$(echo $1 | tr "," "\n")
master_addr=$2
# 获取主机数量
global_batch_size=$(($num_hosts * 16))
num_hosts=$(echo $hosts | wc -w)

# 使用ansible在每个主机上执行命令
for (( i=0; i<$num_hosts; i++ )); do
  host=$(echo $hosts | cut -d " " -f $((i+1)))

  ansible $host -m shell -a "docker exec gpt_test bash -c 'cd $/libai && bash tools/args_train.sh configs/gpt2_pretrain.py $num_hosts 8 $i $master_addr 1 1 true true true 2 $global_batch_size false 2 220 100 48 144 2304 9216'" & 

done
  1. bash run_train_libai.sh 051,052,053,054,055,056,057,058 10.0.0.114 ,即可开始8个节点的训练。第一个节点必须是master节点,第二个参数是master节点的域名
  2. Libai 训练脚本:args_train.sh
    
    参数解释如下:

进行 Megatron 训练

  1. 查看容器是否已经全部启动:ansible 051,052,053,054,055,056,057,058 -m shell -a "docker ps | grep gpt_test"
  2. 环境配置以及数据集下载 :run_megatron_ml_gpt.sh
  3. 在任意一台GPU机器,cd $HOME/Megatron-LM创建一个DDP运行多机的文件,run_train_megatron.sh
set -ex
# 解析输入参数,使用逗号分割多个主机名
hosts=$(echo $1 | tr "," "\n")
master_addr=$2
# 获取主机数量
global_batch_size=$(($num_hosts * 16))
num_hosts=$(echo $hosts | wc -w)

# 使用ansible在每个主机上执行命令
for (( i=0; i<$num_hosts; i++ )); do
  host=$(echo $hosts | cut -d " " -f $((i+1)))

  ansible $host -m shell -a "docker exec gpt_test bash -c 'cd $/Megatron-LM && bash examples/megatron_args_pretrain_gpt2.sh $num_hosts 8 $i $master_addr 1 1 true true true 2 $global_batch_size false 2 220 100 48 144 2304 9216'" & 

done
  1. bash run_train_megatron.sh 051,052,053,054,055,056,057,058 10.0.0.114 ,即可开始8个节点的训练。第一个节点必须是 master 节点,第二个参数是 master 节点的域名
  2. Megatron 的训练脚本:megatron_args_pretrain_gpt2.sh,参数已与 libai 的训练脚本完全对齐

训练结果

Libai 与 Megatron 并行度测试 NVIDIA Graphics Device A800 80G OneFlow_eb3df25 Megatron_e156d2f
gpt2_pretrain_graph_nl48_nah144_hs2304_FP16actrue
DP64_MP1_PP1_zerofalse_stage2_mbs2_gbs128_acc1_8n8g
building graph cost time: 22.23s. / building plan cost time: 166.74s. / 66997-67197 Mib / 138.98 samples/s 64754 - 64826 MiB / 132.6 samples/s
gpt2_pretrain_graph_nl64_nah144_hs2304_FP16actrue
DP32_MP2_PP1_zerofalse_stage2_mbs32_gbs1024_acc1_8n8g
building graph cost time: 46.29s. / building plan cost time: 247.49s. / 55737-55811 Mib / 126.40 samples/s OOM
gpt2_pretrain_graph_nl80_nah144_hs2304_FP16actrue
DP16_MP2_PP2_zerofalse_stage2_mbs64_gbs1024_acc1_8n8g
building graph cost time: 55.35s. / building plan cost time: 168.52s. / 66296-67969 Mib / 50.68 samples/s OOM
gpt2_pretrain_graph_nl64_nah144_hs2304_FP16actrue
DP32_MP2_PP1_zerofalse_stage2_mbs16_gbs512_acc1_8n8g
building graph cost time: 49.1s. / building plan cost time: 250.73s. / 45741-45813 Mib / 118.90 samples/s 55190 - 55212 MiB / 121.5 samples/s
gpt2_pretrain_graph_nl80_nah144_hs2304_FP16actrue
DP16_MP2_PP2_zerofalse_stage2_mbs16_gbs256_acc1_8n8g
building graph cost time: 54.59s. / building plan cost time: 162.58s. / 33052-34771 Mib / 46.69 samples/s 41326 - 41402 MiB / 51.3 samples/s