
DeepSpeed多卡训练问题梳理
环境背景
- 内网centos8.3_x86_64环境
- gcc版本8.3.1
- python版本3.8
- nvidia驱动对应cuda版本为11.6(通过nvida-smi可以获取)
- cuda toolkit版本为11.3(通过nvcc -V可以获取)
依赖安装
由于内网环境没有网络,需要通过外网执行以下命名获取所有的依赖库以及依赖的依赖并导入内网。
pip download -r requirement.txt -d ./
在内网通过pip install 安装所有依赖。
DeepSpeed安装
安装好依赖和可以直接接通install.sh安装,也可以通过以下指令指定参数安装。
cd DeepSpeed
rm -rf build
TORCH_CUDA_ARCH_LIST="8.0" DS_BUILD_CPU_ADAM=1 DS_BUILD_UTILS=1 pip install . \
--global-option="build_ext" --global-option="-j8" --no-cache -v \
--disable-pip-version-check 2>&1 | tee build.log
TORCH_CUDA_ARCH_LIST 根据你运行的 GPU 架构做调整,获取 TORCH_CUDA_ARCH_LIST
CUDA_VISIBLE_DEVICES=0 python -c "import torch; print(torch.cuda.get_device_capability())"
如果返回的结果是(8, 0),那么 TORCH_CUDA_ARCH_LIST=“8.0”
为了适配多机多卡训练需要安装pdsh并配置免密登陆。
安装pdsh工具
wget https://github.com/chaos/pdsh/releases/download/pdsh-2.34/pdsh-2.34.tar.gz
tar -zxvf pdsh-2.34.tar.gz
./configure
make
make install
配置免密登陆
# 如果没有ssh key则先生成key
ssh-keygen -t rsa -C "xxx@email.com"
# 把生成的公钥内容拷贝到集群其他机器的对应用户的.ssh目录下的authorized_keys,如果没有就创建。
执行Example训练
下载DeepSpeedExample代码,执行训练任务
git clone https://github.com/microsoft/DeepSpeedExamples.git
cd DeepSpeedExamples/training/pipeline_parallelism
# 单卡训练任务
./run.sh
# 多卡训练任务
# 创建hostfile指定所有gpu资源,填写host的相应gpu数量(slots=4代表有4个gpu)
# host1 slots=4
# host2 slots=4
# 执行训练任务,通过include参数指定本次训练用到的gpu资源
deepspeed --hostfile=hostfile --include="host1:3@host2:2,3" train.py -p 2 --steps=200 --deepspeed_config=ds_config.json
碰到问题与解决
单卡训练
RuntimeError: num_states (2) must divide distributed world size (1)
run.sh中默认通过-p指定并发数为2,我们只有一个GPU资源,可以将-p参数改为1即可。
多机多卡训练
Host key verification failed.
详细报错信息:
linux0157: Host key verification failed.
pdsh@linux0156: linux0157: ssh exited with exit code 255
linux0156: [2023-07-03 16:02:19,595] [INFO] [real_accelerator.py:110:get_accelerator] Setting ds_accelerator to cuda (auto detect)
linux0156: [2023-07-03 16:02:19,941] [INFO] [launch.py:145:main] WORLD INFO DICT: {'linux0156':[0], 'linux0157': [0]}
linux0156: [2023-07-03 16:02:19,941] [INFO] [launch.py:151:main] nnodes=2, num_local_procs=1, node_rank=0
linux0156: [2023-07-03 16:02:19,941] [INFO] [launch.py:162:main] global_rank_mapping=defaultdic(<class 'list'>, {'linux0156': [0], 'linux0157': [1]})
linux0156: [2023-07-03 16:02:19,941] [INFO] [launch.py:163:main] dist_world_size=2
linux0156: [2023-07-03 16:02:19,941] [INFO] [launch.py:165:main] Setting CUDA_VISIBLE_DIVICES=0
linux0156: [2023-07-03 16:02:21,142] [INFO] [real_accelerator.py:110:get_accelerator] Setting ds_accelerator to cuda (auto detect)
linux0156: [2023-07-03 16:02:21,454] [WARNING] [comm.py:152:init_deepspeed_backend] NCCL backend in DeepSpeed not yet implemented
linux0156: [2023-07-03 16:02:21,455] [INFO] [comm.py:594:init_distributed] cdb=None
linux0156: [2023-07-03 16:02:21,455] [INFO] [comm.py:625:init_distributed] Initializing TorchBackend in DeepSpeed with backend nccl
执行被卡在init_distributed函数。只是由于无法连接到集群中的远程机器导致的。我们需要将需要连接的linux0157机器在/etc/hosts中配置好。比如在hosts中添加一行:
192.168.0.157 linux0157
然后通过ssh 连接该host:
ssh linux0157
第一次连接需要验证,选择yes建立连接。
连接成功后便不再出现该问题。注意执行时的用户与前面设置的免密登陆用户相同。
torch.distributed.DistBackendError: NCCL error in: …/torch/csrc/distributed/c10d/ProcessGroupNCCL.cpp:1275, internal error, NCCL version 2.14.3
具体报错信息
linux0156: linux0156:125450:125450 [0] NCCL INFO@x3ca866e0 rank nranks 2 cudaDev 0 busId 2000 -Abort COMPLETE
linux0156: Traceback (mostrecent call last):
linux0156: File "train.py",line 160,in <module>
linux0156: train_pipe(args)
linux0156: File "train.py",line 138, in train_pipe
linux0156: trainset = cifar_trainset(args ,local_rank)
linux0156: File "train.py",line 31, in cifar_trainset
linux0156: dist.barrier()
linux0156: File "/home/liding/tiger/lib/python3.8/site-packages/torch/distributed/distributed_c10d.py", line 3328, in barrier
linux0156: work = default_pg.barrier(opts=opt)
linux0156: torch.distributed.DistBackendError: NCCL error in: ../torch/csrc/distributed/c10d/ProcessGroupNCCL.cpp:1275, internal error, NCCL version 2.14.3
linux0156: ncclInternalError: Internal check failed.
linux0156: Last error:
linux0156: Proxy Call to rank failed (Connect)
可以通过配置export NCCL_DEBUG=INFO来输出NCCL的debug信息,通过输出信息可以看到:
linux0157: linux0157:252543:252690 [0] proxy.cc:1119 NCCL WARN [Proxy Service 1] Failed to execute operation Connect from rank 1, retcode 6
linux0157:
linux0157: linux0157:252543:252690 [0] misc/socket.cc:538 NCCL WARN Net : Call to recv from fe80::ecee:eeff:feee:eeee%6<47217> failed : Broken pipe
linux0157: linux0157:252543:252690 [0] NCCL INFO misc/socket.cc:535 -> 6
linux0157: linux0157:252543:252690 [0] NCCL INFO transport/net_socket.cc:368 -> 6
linux0157: linux0157:252543:252690 [0] NCCL INFO include/net.h:26 -> 6
linux0157: linux0157:252543:252690 [0] NCCL INFO transport/net.cc:517 -> 6
linux0157: linux0157:252543:252690 [0] NCCL INFO proxy.cc:991 -> 6
从上述信息可以看到是连接ipv6地址失败,这说明NCCL连接远程机器并没有按照我们预想的找到配置host对应的ipv4地址。通过ifconfig可以看到所有网卡设备信息。我们需要指定对应的网卡通信。
通过export NCCL_SOCKET_IFNAME=eth0可以指定通信网卡。eth0为一个网卡名称(可以配置你自己的网卡名称)。该配置会由pdsh发送给集群中的各个机器作为环境变量且集群的网卡信息不一致,所以我们需要先通过配置相同的网卡来保证可以找到正确的网卡通信。修改网卡名称如下:
# 进入网络配置文件目录
cd /etc/sysconfig/network-scripts
# 编辑配置文件,修改NAME与DEVICE两个字段配置固定名称,我们这里统一配置为eth0
vi ifcfg-ens33d
# 修改系统默认命名规则
sed -i 's/rhgb/net.ifnames=0 biosdevname=0 &/' /etc/default/grub
# 同步到系统内核
grub2-mkconfig -o /boot/grub2/grub.cfg
# 重启系统
reboot
# 重启后通过ifconfig可以看到更改后的网卡名称
集群节点对应网卡名称改为eth0后我们配置的export NCCL_SOCKET_IFNAME=eth0就可以正确找到网卡进行通信。
Ninja is required to load C++ extensions
通过pip list可以看到已经安装了ninja库。这里还需要安装ninja的执行文件即可:
wget https://github.com/ninja-build/ninja/releases/download/v1.10.2/ninja-linux.zip
unzip ninja-linux.zip -d /usr/local/bin/
update-alternatives --install /usr/bin/ninja ninja /usr/local/bin/ninja 1
更多推荐
所有评论(0)