使用DeepSpeed在Slurm集群上多机跑大模型

最近使用了DeepSpeed跑Bloom模型,在多机训练时遇到了一点问题,查了一些资料没有发现DeepSpeed在Slurm集群上多机跑的方法笔记,特此记录一下。

我用的是DeepSpeed-Chat的Step 1 (SFT) 的训练code,官方给出的训练示例可以在这里找到。

在Slurm集群中,单机多卡的训练脚本如下:

#!/bin/bash
#SBATCH -J FT-BLOOM  ##提交的任务名称
#SBATCH -o ../log/ft.bloom.snode.log
#SBATCH -p GPU_NAME # 任务提交的分区名称
#SBATCH -N 1   # 任务申请1个节点
#SBATCH --cpus-per-task=16  ## 每个任务使用的cpu核数
#SBATCH --gres=gpu:8   ## 每个节点的gpu数
#SBATCH --mem 256G    ## 每个节点的memory 
###SBATCH -w GPU_NAME09 # 指定运行作业的节点,若不填写系统自动分配节点

OUTPUT=/path/to/output
ZERO_STAGE=3
export TOKENIZERS_PARALLELISM=true 
code_path=/path/to/DeepSpeed/DeepSpeedExamples/applications/DeepSpeed-Chat/training/step1_supervised_finetuning
deepspeed $code_path/main.py \
   --data_path knowledge_data \
   --data_split 10,0,0 \
   --sft_only_data_path knowledge_data \
   --data_output_path /path/to/output \
   --model_name_or_path /path/to/bloom-3b \
   --per_device_train_batch_size 1 \
   --per_device_eval_batch_size 1 \
   --max_seq_len 1024 \
   --learning_rate 1e-5 \
   --weight_decay 0.1 \
   --num_train_epochs 5 \
   --gradient_accumulation_steps 1 \
   --lr_scheduler_type cosine \
   --num_warmup_steps 0 \
   --seed 1234 \
   --zero_stage $ZERO_STAGE \
   --deepspeed \
   --output_dir $OUTPUT \
   &> $OUTPUT/training.snode.log

如果不使用slurm集群,DeepSpeed多机跑模型只需要在直接在 deepspeed 后面加一个参数 --hostfile=/path/to/hostfile,其中 hostfile 文件中存放的是节点名称及每个节点使用的gpu数:

...
deepspeed --hostfile=/path/to/hostfile \
$code_path/main.py \
...

/path/to/hostfile中的内容为:

g0003 slots=8
g0004 slots=8

其中每一行代表一个节点,第一个是节点名称,第二个是该节点使用的gpu数。

上述方法只适用于每个节点均允许无密钥ssh的情况,在slurm集群中并不能直接使用,slurm集群中使用多节点的脚本如下:

#!/bin/bash
#SBATCH -J FT-BLOOM
#SBATCH -o ../log/ft.bloom.mnodes.log
#SBATCH -p GPU_NAME
#SBATCH -N 2   # 作业申请 2 个节点
#SBATCH --gres=gpu:8  ## 每个节点使用8个GPU
#SBATCH --cpus-per-task=8 ## 每个任务使用8个cpu核
#SBATCH --ntasks-per-node=8  ## 每个节点上8个任务
#SBATCH --gpus-per-task=1  ## 每个GPU上1个任务
#SBATCH --mem 256G  ## 每个节点使用的内存
#SBATCH -w GPU_NAME[02-03] # 指定运行作业的节点,若不填写系统自动分配节点

OUTPUT=/path/to/output
export GPUS_PER_NODE=8

TASK_NAME="task_name"
export CKPT="$OUTPUT/$TASK_NAME"
mkdir -p $OUTPUT $CKPT 

echo "SLURM_NTASKS=$SLURM_NTASKS"
export HOSTFILE="./hostfile"
echo "[slurm node name] slots=$SLURM_NTASKS" > $HOSTFILE

### 定义节点到ip的映射
declare -A IB0
for i in $(seq 0 node_count); do
    key=$(printf "NODE_NAME%02d" "$i")
    value=$(printf "xx.xx.xx.%02d" $((i)))
    IB0["$key"]="$value"
done
### 这一步定义你的slurm集群中所有的节点与ip的对应关系,用一个dict存储

### 系统自动匹配当前进程的主节点
regex="[0-9]+"
if [[ $SLURM_JOB_NODELIST =~ $regex ]]; then
    extracted_number="${BASH_REMATCH[0]}"
    echo "Extracted number: $extracted_number"
else
    echo "No match found"
fi

MASTER_KEY="NODE_NAME$extracted_number"

### 定义master的地址和端口
export MASTER_ADDR=${IB0[$MASTER_KEY]}
export MASTER_PORT=31217

code_path=/path/to/DeepSpeed/DeepSpeedExamples/applications/DeepSpeed-Chat/training/step1_supervised_finetuning
deepspeed --num_nodes $SLURM_NNODES \
   --num_gpus $GPUS_PER_NODE \
   --master_addr $MASTER_ADDR \
   --master_port $MASTER_PORT \
   --hostfile $HOSTFILE \
   --no_ssh_check \
   --launcher SLURM \
   --force_multi \
   $code_path/main.py \
   --data_path knowledge_data \
   --data_split 10,0,0 \
   --sft_only_data_path knowledge_data \
   --data_output_path /path/to/output \
   --model_name_or_path /path/to/bloom-1b7 \
   --per_device_train_batch_size 1 \
   --per_device_eval_batch_size 1 \
   --max_seq_len 2048 \
   --learning_rate 1e-5 \
   --weight_decay 0.1 \
   --num_train_epochs 10 \
   --gradient_accumulation_steps 16 \
   --lr_scheduler_type cosine \
   --num_warmup_steps 0 \
   --seed 1234 \
   --zero_stage $ZERO_STAGE \
   --deepspeed \
   --output_dir $CKPT \
   --gradient_checkpointing \
   &> $OUTPUT/training.log

上面的脚本就是DeepSpeed在Slurm集群中多机运行的脚本,但是直接运行脚本会报错,local_rank无法通过args自动传参,导致没有分布式初始化,需要对/path/to/DeepSpeed/DeepSpeedExamples/applications/DeepSpeed-Chat/training/step1_supervised_finetuningmain.py 做一下修改,把环境变量传参进去,在 main.py 中添加:

### 添加环境变量
world_size = os.environ['SLURM_NTASKS']  
node_id = os.environ['SLURM_NODEID']   
rank = os.environ['SLURM_PROCID']   
local_rank = int(os.environ['SLURM_LOCALID'])

os.environ['RANK'] = os.environ['SLURM_PROCID']
os.environ['WORLD_SIZE'] = os.environ['SLURM_NTASKS']
os.environ['MASTER_PORT'] = os.environ['MASTER_PORT']
os.environ['LOCAL_RANK'] = os.environ['SLURM_LOCALID']

### main函数中添加:
args.local_rank = local_rank

其中Slurm环境变量含义如下:

SLURM_NTASKS  ## 总任务数量,可用作world_size
SLURM_NODEID  ## 节点下标,即node_id
SLURM_PROCID  ## 全局进程id,可用作global rank
SLURM_LOCALID ## 局部进程id,可用作local_rank

以上就是在Slurm集群中使用DeepSpeed Chat多机训练模型的方法,不对的地方欢迎指正!

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Slurm是一个用于作业调度和管理的开源软件。它被广泛应用于各种场景,包括本地服务器集群、混合云计算和云端计算等。在本地服务器集群中,Slurm可以组织多台服务器进行计算任务的调度和编排。在混合云计算环境中,Slurm同样可以使用,可以直接让供应商提供技术支持。云端的计算和超算中心也使用Slurm进行作业编排,而且云端环境不需要自己部署,直接使用即可,并且由专业的公司维护,稳定性更高。此外,还有一些开源工具可用于部署和管理Slurm集群,例如Omnia。Omnia是Dell HPC推出的开源集群部署工具,基于ansible进行部署k8s/slurm集群。你可以在GitHub上找到有关Omnia的更多信息。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [基于Centos7的slurm集群部署方案(测试环境)](https://blog.csdn.net/mogui60/article/details/125069490)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [Slurm集群部署](https://blog.csdn.net/weixin_31105189/article/details/113999400)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [Slurm集群安装部署](https://blog.csdn.net/qq_31910613/article/details/123983153)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值