CPM-9G-8B/quick_start_clean/readmes/README_DISTRIBUTED.md

124 lines
3.9 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 分布式多机训练
- 首先保证机器之间能够通信
- 每台机器上的训练环境、代码、数据等一致
## 简单模式
这种方式只适用于机器很少的提交方法比如说两台机器debug调试的时候可以如下操作
以sft_cpm9g_8b.sh举例
```shell
# 这儿指定主节点的IP值
export MASTER_ADDR=g3002
#中间省略各种参数配置
#--nnodes 指定用几台机器提交任务后主节点会一直等待通信满足4台机器直到time out
#--nproc_per_node 每张机器多少张卡
CMD="torchrun --nnodes=2 --nproc_per_node=8 --rdzv_id=1 --rdzv_backend=c10d --rdzv_endpoint=${MASTER_ADDR}:${MASTER_PORT} ${CPM_PATH}/apps/cpm9g/sft_cpm9g.py ${OPTS}"
```
接下来在这两个机器中都执行bash sft_cpm9g_8b.sh这样就完成一次最简单的多机训练
不过机器多了之后不推荐这种方式
## slurm 集群多机任务提交
算力平台使用Slurm调度常用Slurm命令包括
``` shell
Slurm命令 功能
sinfo 查看集群分区状态
squeue 查看作业队列
srun, salloc 交互式运行作业
sbatch 提交作业
scancel 取消作业
scontrol 查看和修改作业参数
sacct 查看已完成作业
```
### 单机任务
参考脚本
前面"#SBATCH"是Slurm配置参数解释如下
``` shell
●--partition: 使用的队列名称
●--nodes: 节点数量,用多少台机器
●--ntasks-per-node每个节点的进程数和每节点的GPU数量保持一致
●--gres=gpu:8每个节点分配的GPU数量
●--cpus-per-task每个任务分配的CPU数量建议不要修改该节点的cpu总数为任务数乘以每个任务的cpu数这个示例脚本中的cpu总数为8x8=64
```
#### 具体示例:
train.sh:
```
#!/bin/bash
#SBATCH --partition=gpu1
#SBATCH --nodelist=g1001
#SBATCH --nodes=1
#SBATCH --ntasks-per-node=8
#SBATCH --gres=gpu:8
#SBATCH --cpus-per-task=8
python main.py
```
提交任务
```
sbatch train.sh
```
### 多机任务
已测试通过torchrun的方式多机训练需要设置"MASTER_ADDR"和"MASTER_PORT"两个环境变量,先提交一个主节点的任务,获取"MASTER_ADDR"在提交从节点任务。一个4台机器的多机任务的操作示例如下
注意:#SBATCH的nodes参数设置为1slurm的多节点通信与bmtrain的环境变量有冲突且srun不稳定推荐采用slurm提交多个单节点任务用torchrun的方式实现多节点通信。
##### 第一步:启动主节点
train_master.sh:
```
#!/bin/bash
#SBATCH --partition=gpu1
#SBATCH --nodes=1
#SBATCH --ntasks-per-node=8
#SBATCH --gres=gpu:8
#SBATCH --cpus-per-task=8
MASTER_ADDR=`hostname`
MASTER_PORT=12345
echo $MASTER_ADDR
torchrun --nnodes=4 --nproc_per_node=8 --rdzv_id=1 --rdzv_backend=c10d --rdzv_endpoint=${MASTER_ADDR}:${MASTER_PORT} train.py
```
提交主节点:
```
sbatch train_master.sh
```
在输出的logslurm-xxx.log中查看主节点的名称例如此时查到主节点是"g1001"
##### 第二步:启动从节点
train_slave.sh:
```
#!/bin/bash
#SBATCH --partition=gpu1
#SBATCH --nodes=1
#SBATCH --ntasks-per-node=8
#SBATCH --gres=gpu:8
#SBATCH --cpus-per-task=8
MASTER_ADDR=g1001
MASTER_PORT=12345
echo $MASTER_ADDR
torchrun --nnodes=4 --nproc_per_node=8 --rdzv_id=1 --rdzv_backend=c10d --rdzv_endpoint=${MASTER_ADDR}:${MASTER_PORT} train.py
```
提交从节点示例是一个4台机器的任务因此再提交3个从节点程序
```
for i in {1..3};do
sbatch train_slave.sh
done
```
## dockers上的多机提交任务
dockers 容器上的多机任务和在主机上是相同的,只需要再其基础上满足两个要求
- 在每个机器上拉取同样的docker和激活同样的训练环境在docker共享的路径、数据、代码都一致
- 在docker启动的时候保障 --network=host和主机共享网络通信只要机器之间能通信在dockers中也可以通信和训练
#### TODOs
1 完善K8s集群的分布式多机任务训练