docker容器中deepspeed多机多卡集群分布式训练大模型

1. 创建overlay共享网络

可以看这位大佬的文章讲的很详细docker容器中deepspeed多机多卡集群分布式训练大模型众所周知,大模型的训练需要大量的显存资源,单卡很容易就爆 - 掘金 (juejin.cn)

后面和代码大多借鉴的这位大佬的文章,但大佬跳过了一些基础内容,我进行了一些补充

2. 运行容器搭建

1. 训练框架准备

同样是建立这种目录结构

├── workspace/
    ├── code/
    ├── docker-compose.yml
    ├── Dockerfile

使用的是llamafactory框架进行,你也可以尝试其他框架

# 进入工作目录
$ cd workspace

# 克隆项目到code文件夹
$ git clone https://github.com/hiyouga/LLaMA-Factory code

# 进入特定commit
$ git checkout 2caf91f824320b226daa4666eda2da7cb853db9c

如果没有指定特定的commit,后面的运行代码会没有train_bash.py替换成train即可

requiement.txt版本

torch==2.0.1
transformers==4.33.1
datasets==2.14.6
deepspeed==0.12.3
accelerate==0.24.1
peft==0.6.0
trl==0.7.2
gradio==3.38.0
scipy==1.11.3
sentencepiece==0.1.99
protobuf==4.25.0
tiktoken==0.5.1
jieba==0.42.1
rouge-chinese==1.0.3
nltk==3.8.1
uvicorn==0.24.0
pydantic==1.10.11
fastapi==0.95.1
sse-starlette==1.6.5
matplotlib==3.8.1

更改后运行这个代码可以一键安装适合版本的,如果那个软件包安装报错可以试试跳过他,在requirement中删除对他相应的版本约束

pip install -r requirements.txt
2. 启动容器

我用的基础镜像是nvidia/cuda:11.7.1-devel-ubuntu22.04,需要安装一下python3.10,Dockerfile文件如下:

FROM nvidia/cuda:11.7.1-devel-ubuntu22.04

# 更新系统包
RUN apt-get update && apt-get install -y git build-essential zlib1g-dev libncurses5-dev libgdbm-dev libnss3-dev libssl-dev libsqlite3-dev libreadline-dev libffi-dev liblzma-dev libbz2-dev curl wget net-tools iputils-ping pdsh

# 安装Python
WORKDIR /home/user

RUN wget https://www.python.org/ftp/python/3.10.6/Python-3.10.6.tgz && \
  tar -zvxf Python-3.10.6.tgz && cd Python-3.10.6 && \
  ./configure --enable-optimizations && make -j 4 && make install

这里我们分别到 manager , worker 节点使用 docker compose up -d --build 命令启动容器,相应的配置文件如下:

version: "3"
services:
  llm:
    build:
      context: .
      dockerfile: Dockerfile
    container_name: llm
    tty: true
    restart: always
    ulimits:
      memlock: -1
      stack: 67108864
    shm_size: 40G
    deploy:
      resources:
        reservations:
          devices:
            - capabilities: [gpu]
    volumes:
      - ./code:/home/user/code:cached
    networks:
      - test-net

networks:
  test-net:
    external: true
3. 验证网络

然后去 manager 节点执行 docker exec -it llm bash 命令进入容器, ping 一下 worker 节点

在这里我遇到了双方无法ping通,我的问题和解决方法可以供参考

需要检测Swarm 节点之间的网络连接畅通,特别是端口 79464789

(ufw)Ubuntu 和 Debian 系统的默认防火墙工具

sudo ufw status
至                          动作          来自
-                          --          --
22                         ALLOW IN    Anywhere                  
22 (v6)                    ALLOW IN    Anywhere (v6)   

当时大概是显示了这些内容但是没有7946 和 4789

开放端口
sudo ufw allow 7946/tcp
sudo ufw allow 4789/udp

添加规则后,重新加载 ufw 配置:
sudo ufw reload
然后查看 ufw 状态以确认规则已经添加:
sudo ufw status verbose
应该会看到类似下面的输出,其中包括刚刚添加的端口规则:

至                          动作          来自
-                          --          --
22                         ALLOW IN    Anywhere                  
22 (v6)                    ALLOW IN    Anywhere (v6)    
7946/tcp                    ALLOW IN    Anywhere
4789/udp                    ALLOW IN    Anywhere

这时候测试连接应该就可以了
 

3. 开启容器间免密访问

1. 安装openssh-server服务

首先分别去manager,worker节点的容器中安装openssh-server服务并启动

# 安装ssh服务
apt-get install openssh-server -y
# 启动ssh服务
/etc/init.d/ssh start

2. 配置免密登录

注意:以下操作都是在manager,worker节点容器内部

分别去manager,worker节点的容器中执行 ssh-keygen -t rsa 命令,一直回车即可

root@2ef29f638705:/home/user/code# ssh-keygen -t rsa
Generating public/private rsa key pair. 
Enter file in which to save the key (/root/.ssh/id_rsa):
Created directory '/root/.ssh'. 
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /root/.ssh/id_rsa. 
Your public key has been saved in /root/.ssh/id_rsa.pub. 
The key fingerprint is: 
SHA256:tUB6SjLnvqM7p2l+bmHUZGNqUyyOPmXGyiMp3tC9xNA root@2ef29f638705 
The key's randomart image is: 
+---[RSA 2048]----+
|        ..       | 
|       .oB       | 
|     +++Oo..     | 
|    ..E@o.o .    | 
|  .++Bo.S .      | 
|..o.*=o          | 
|..o..+o.         | 
| . .oo=.         | 
|   o*Xo.         | 
+----[SHA256]-----+

  • manager节点中的~/.ssh/id_rsa.pub的内容复制写入到manager节点和worker节点中的~/.ssh/authorized_keys文件中。
  • worker节点中的~/.ssh/id_rsa.pub的内容复制写入到manager节点和worker节点中的~/.ssh/authorized_keys文件中。

可以使用vim命令复制,如果安装vim命令失败,可以使用cat命令

查看 worker 节点的公钥:
cat ~/.ssh/id_rsa.pub
将 worker 节点的公钥内容复制到 authorized_keys 文件中:

cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys
将公钥内容保存到临时文件中

在你要保存公钥的节点上,使用以下命令将复制的公钥内容保存到文件中:


cat <<EOF > worker_id_rsa.pub
(粘贴复制的公钥内容)
EOF


解释:

cat <<EOF > worker_id_rsa.pub 启动了一个多行输入模式,直到遇到 EOF。
(粘贴复制的公钥内容) 是你从上一步复制的公钥内容。
EOF 表示结束标记,> 符号表示将内容写入到 worker_id_rsa.pub 文件中。
直接重定向到文件

接着分别去managerworker节点的/etc/hosts文件中增加映射

10.0.3.2        6a732892
10.0.3.6        123232ds

解释123232ds是容器id

由于docker swarm网络会随机分配ip地址,每次服务器重启后,容器ip都会改变,所以都可需要修改映射,读者可以尝试如何固定容器静态IP

最后测试服务器容器之间是否可以免密登录

root@2ef29f638705:/home/user/code# ssh root@worker
Welcome to Ubuntu 22.04.3 LTS (GNU/Linux 3.10.0-1160.102.1.el7.x86_64 x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage

This system has been minimized by removing packages and content that are
not required on a system that users do not log into.

To restore this content, you can run the 'unminimize' command.
Last login: Tue Nov 21 12:01:18 2023 from 10.0.3.2

4. 分布式训练

1. 模型准备

先去下载chatglm2-6b模型,然后放到容器的 /home/user/code

尽量是下载好本地模型将其上传到服务器,实验过程中发现拉取文件不完全,后面发生报错,花费纠错时间较长

2. 安装依赖
root@2ef29f638705:~# cd /home/user/code/
root@2ef29f638705:/home/user/code# pip3 install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple
3. 准备配置文件

/home/user/code/目录下新建 hostfile 文件,写入:

 6a732892 slots=1
 123232ds slots=1

/home/user/code/目录下新建 ds_config.json 文件,写入:

{
  "train_batch_size": "auto",
  "train_micro_batch_size_per_gpu": "auto",
  "gradient_accumulation_steps": "auto",
  "gradient_clipping": "auto",
  "zero_allow_untested_optimizer": true,
  "fp16": {
    "enabled": "auto",
    "loss_scale": 0,
    "initial_scale_power": 16,
    "loss_scale_window": 1000,
    "hysteresis": 2,
    "min_loss_scale": 1
  },
  "zero_optimization": {
    "stage": 2,
    "allgather_partitions": true,
    "allgather_bucket_size": 5e8,
    "reduce_scatter": true,
    "reduce_bucket_size": 5e8,
    "overlap_comm": false,
    "contiguous_gradients": true
  }
}

managerworker节点需要执行同样的操作,保证训练代码和训练运行的环境一致

4. 执行训练命令

进入manager节点的 /home/user/code/ 文件夹,执行

deepspeed --hostfile hostfile src/train_bash.py \                 
    --deepspeed ds_config.json \
    --stage sft \
    --model_name_or_path /home/user/code/chatglm2-6b \
    --do_train \
    --dataset alpaca_gpt4_zh \
    --template chatglm2 \
    --finetuning_type lora \
    --lora_target query_key_value \
    --output_dir chatglm2_sft \
    --overwrite_cache \
    --overwrite_output_dir \
    --per_device_train_batch_size 4 \
    --gradient_accumulation_steps 4 \
    --lr_scheduler_type cosine \
    --logging_steps 10 \
    --save_steps 10000 \
    --learning_rate 5e-5 \
    --num_train_epochs 0.25 \
    --plot_loss \
    --fp16

这里的train_bash.py如果没有用commit就换成train.py

可以看到,训练已经跑起来了,并且输出了两台机器的日志 

多机多卡训练

分别去两台服务器中执行 nvidia-smi,可以看到显卡均有被使用,至此,分布式训练完毕。

  • 18
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值