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

众所周知,大模型的训练需要大量的显存资源,单卡很容易就爆了,于是就有了单机多卡、多机多卡的训练方案。本文主要是介绍如何使用deepspeed框架做多机多卡的分布式训练。

由于PyTorch、NVIDIA、CUDA等运行环境搭建也是很繁琐,所以这次我们用docker来快速搭建,但是deepspeed多机训练是通过ssh来通讯的,不同服务器的docker容器通讯是个麻烦事。还好,docker可以创建overlay网络来解决这个问题。

1. 创建overlay共享网络

假设我们有两台主机,均已经在宿主机上安装完docker、NVIDIA的驱动。

  • server1: 10.0.18.1
  • server2: 10.0.18.2

宿主机的ip不太重要,我们需要的是能跨网的容器间ip,让它们能跨服务器间通讯。docker官方的overlay-network有详细的使用方法,下面是复现步骤,注意命令是分别在不同的节点上执行的:

1. 初始化集群

我们选择 server1 作为 manager 节点,在此服务器上执行初始化命令:docker swarm init

$ docker swarm init
Swarm initialized: current node (vz1mm9am11qcmo979tlrlox42) is now a manager.

To add a worker to this swarm, run the following command:

    docker swarm join --token SWMTKN-1-5g90q48weqrtqryq4kj6ow0e8xm9wmv9o6vgqc5j320ymybd5c-8ex8j0bc40s6hgvy5ui5gl4gy 10.0.18.1:2377

To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
2. 加入集群

将 server2 作为 worker 节点加入集群,进入 server2 执行下面join命令:

$ docker swarm join --token SWMTKN-1-5g90q48weqrtqryq4kj6ow0e8xm9wmv9o6vgqc5j320ymybd5c-8ex8j0bc40s6hgvy5ui5gl4gy 10.0.18.1:2377
3. 创建网络

在 manager 中创建 overlay 网络,执行命令:

$ docker network create --driver=overlay --attachable test-net
uqsof8phj3ak0rq9k86zta6ht

执行命令查看当前网络状态,可以看到最后一行,已经创建好了

[root@i-spxeloti ~]# docker network ls
NETWORK ID     NAME              DRIVER    SCOPE
873253604b76   bridge            bridge    local
983eae14396c   docker_gwbridge   bridge    local
720dada15466   host              host      local
z8hpu4pg07m7   ingress           overlay   swarm
2f209b7ceaf6   none              null      local
un6gq3jb0jy9   test-net          overlay   swarm
4. 同步网络

接着进入 worker 节点执行命令查看会发现,看不到上一步创建的网络

[root@i-sboq81f6 code]# docker network ls
NETWORK ID     NAME              DRIVER    SCOPE
cab8b04240be   bridge            bridge    local
289c7a4e3a88   docker_gwbridge   bridge    local
7912cd38ffbd   host              host      local
z8hpu4pg07m7   ingress           overlay   swarm
5668efe47596   none              null      local

这时候我们只需要开启一个容器,强制指定网络为test-net,docker就会自动同步对应网络了

$ docker run -dit --name alpine2 --network test-net alpine
fb635f5ece59563e7b8b99556f816d24e6949a5f6a5b1fbd92ca244db17a4342

这个时候再来查看,worker 节点中就有了刚刚创建的网络了。

 

2. 运行容器搭建

进入manager节点,先创建一个 workspace 文件夹,内部的文件列表如下:

├── workspace/
    ├── code/
    ├── docker-compose.yml
    ├── Dockerfile
1. 训练框架准备

我用的是 hiyouga/LLaMA-Factory: Easy-to-use LLM fine-tuning framework 这个大模型训练微调框架,它支持目前市面上主流的大模型(llama2、chatglm2、baichuan2、qwen等),以及多种训练模式(sft、pt、ppo、dpo等),使用起来挺方便的,作者更新和回复也挺勤。

# 进入工作目录
$ cd workspace

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

# 进入特定commit
$ git checkout 2caf91f824320b226daa4666eda2da7cb853db9c

我这边测试成功的环境:

  • 显卡驱动版本是 CUDA Version: 11.8
  • torch版本 2.0.1
  • 训练框架的commit是 2caf91f824320b226daa4666eda2da7cb853db9c

requirements.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
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. 验证网络

启动之后,可以使用docker inspect llm 命令查看对应容器的网络结构

manager 节点网络ip如下:

worker 节点网络ip如下:

 

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

root@2ef29f638705:/home/user/code# ping 10.0.3.6
PING 10.0.3.6 (10.0.3.6) 56(84) bytes of data.
64 bytes from 10.0.3.6: icmp_seq=1 ttl=64 time=0.414 ms
64 bytes from 10.0.3.6: icmp_seq=2 ttl=64 time=0.311 ms

同样的操作去 worker 节点也ping一下

root@cbf2783f58c4:/home/user/code# ping 10.0.3.2
PING 10.0.3.2 (10.0.3.2) 56(84) bytes of data.
64 bytes from 10.0.3.2: icmp_seq=1 ttl=64 time=0.527 ms
64 bytes from 10.0.3.2: icmp_seq=2 ttl=64 time=0.485 ms
64 bytes from 10.0.3.2: icmp_seq=3 ttl=64 time=0.506 ms

到此,两台服务器间的容器网络就通了。

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文件中。

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

10.0.3.2        manager
10.0.3.6        worker

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

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. 配置NCCL网络

NCCL相关配置需要修改一下,要不然训练的时候会卡住。先要看容器使用的是哪个网卡,就是看节点的ip对应的网卡

可以看到manager节点用的是eth0网卡

我一般是直接将这个环境变量写入到 /etc/profile 中

...
#需要注意NCCL的配置,这里需要根据机器的情况指定NCCL的通讯网卡 
export NCCL_SOCKET_IFNAME=eth0

然后不要忘了 source /etc/profile 让其生效,worker节点要执行同样的操作。

5. 分布式训练

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 文件,写入:

manager slots=1
worker 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

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

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

6. 常见报错

1. pdsh 问题

raise RuntimeError(f"launcher '{args.launcher}' not installed.")

这个错误一般是 pdsh 没安装,容器里面执行 apt-get install pdsh 命令安装即可

2. NCCL 问题

Proxy Call to rank 0 failed (Connect)

这个是NCCL问题,按照上面的教程,配置一下环境变量就行

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

<think>好的,用户现在有20张RTX 3060显,想知道是否可以使用OpenPAI来管理,并且本地部署大模型,以及能部署大的模型。我需要分步骤来回答这个问题。 首先,确认OpenPAI是否支持RTX 3060。OpenPAI是基于Kubernetes的,所以需要检查Kubernetes对RTX 3060的支持,尤其是NVIDIA的驱动和容器运行时。RTX 3060使用Ampere架构,需要CUDA 11.1及以上,所以用户需要安装合适的驱动和CUDA工具包。此外,NVIDIA的容器工具如nvidia-docker2也是必需的。这些应该是可行的,只要用户正确配置环境。 接下来是管理能力。20张显不算特别大的集群,OpenPAI设计上支持弹性扩展,所以管理这个规模的资源应该没问题。OpenPAI的任务调度和资源隔离功能可以帮助用户有效分配这些GPU,避免资源冲突。 然后是本地部署大模型的可能性。RTX 3060每张有12GB显存,20张的话总共有240GB显存。不过,大模型部署通常需要分布式训练或推理,显存和计算资源的协同是关键。OpenPAI支持分布式训练,用户可以通过它来调度任务,结合数据并行、模型并行或者流水线并行等技术。 关于模型大小的问题,需要考虑显存和模型参数的关系。一般来说,模型参数所需的显存大约是参数数量乘以4字节(float32)。例如,175B参数的模型需要大约700GB显存,显然超过总显存。但如果使用量化技术,比如int8,可以减半到350GB,但240GB显存仍然不够。不过,用户可能指的是训练还是推理?如果是训练,显存需求更大;如果是推理,可以通过模型并行和优化技术部署更大的模型。比如,使用DeepSpeed的ZeRO优化或者模型并行,可能可以部署几十B参数的模型,具体取决于并行策略和显存优化效果。 另外,用户可能需要考虑混合精度训练和梯度累积等技术来节省显存。同时,模型并行需要框架支持,比如PyTorch的FSDP或TensorFlow的Mesh TensorFlow,这些在OpenPAI中是否容易配置? 还需要提醒用户注意单显存限制,即使总显存足够,单个节点的显存可能限制模型分片的大小。此外,网络带宽和延迟在分布式训练中也会影响性能,特别是当模型分布在器上时,需要高速互联。 最后,建议用户实际测试,从较小的模型开始,逐步优化配置,并参考OpenPAI的文档和社区资源,调整分布式策略和参数。同时,考虑显存优化工具如DeepSpeed、Hugging Face的accelerate库等,以最大化利用现有硬件资源。</think>可以!**OpenPAI完全支持用20张RTX 3060显搭建本地集群**,并能通过分布式训练支持大模型部署。以下是具体分析: --- ### 一、硬件兼容性 1. **RTX 3060适配性** - OpenPAI基于Kubernetes调度GPU资源,需确保以下条件: - 安装**NVIDIA驱动>=470.57.02**(支持Ampere架构)。 - 部署**CUDA Toolkit>=11.1**和**nvidia-docker2**运行时。 - RTX 3060的12GB显存适合中等规模模型训练,但需注意**单显存限制**。 2. **集群管理能力** - 20张显可通过OpenPAI统一管理,支持: - 动态分配任务(如单任务占用2/4/8)。 - 隔离不同用户的训练任务,避免显存冲突。 --- ### 二、大模型部署能力 #### (1)模型规模估算(以训练为例) | 并行策略 | 单显存需求(参考) | 20可支持模型规模 | |------------------|----------------------|--------------------------| | **数据并行** | 全量参数加载 | 约10B参数(如GPT-2 Large)| | **模型并行+ZeRO**| 分片加载参数 | 20-50B参数(如LLaMA-13B)| | **混合并行** | 结合数据/流水线并行 | 50B+参数(如部分BLOOM变体)| **关键限制**: - **显存瓶颈**:单12GB显存可能限制单次批量大小(batch size)。 - **通信开销**:间梯度同步需高速网络(建议至少10Gbps互联)。 #### (2)优化手段 - **量化训练**:使用FP16/INT8降低显存占用(可扩展1.5-2倍模型规模)。 - **梯度检查点**:以计算时间换取显存空间(节省20%-30%显存)。 - **DeepSpeed集成**:通过ZeRO-2/3优化显存分配(支持百亿级模型)。 --- ### 三、OpenPAI部署建议 1. **配置示例** - **Kubernetes集群**:建议使用KubeSpray部署(需设置NVIDIA GPU插件)。 - **OpenPAI任务模板**:在Job配置中指定`gpuNum: N`(N为所需显数)。 2. **分布式训练代码适配** ```python # PyTorch + DeepSpeed示例 import deepspeed model, optimizer, _, _ = deepspeed.initialize( args=args, model=model, model_parameters=model.parameters(), config_params="ds_config.json" # 定义ZeRO策略 ) ``` 3. **监控与调优** - 通过OpenPAI Web UI实时查看各显存利用率。 - 使用**NVIDIA DCGM工具**分析GPU性能瓶颈。 --- ### 四、典型场景示例 - **70亿参数模型(如LLaMA-7B)**: 使用ZeRO-2 + FP16,约需8-10即可训练(批量大小=8)。 - **130亿参数模型(如LLaMA-13B)**: 需结合模型并行(2路) + ZeRO-3,约需16-20。 --- ### 五、注意事项 - **显存碎片问题**:长时间运行任务可能导致显存碎片,建议定期重启节点。 - **散热与功耗**:20集群需确保电源(建议≥5kW)和散热系统稳定。 - **模型格式**:推荐使用Hugging Face格式,便于框架加载。 如果需要具体配置参数或性能测试方法,可进一步说明需求! 🚀
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值