horovod多机多卡启动指南

要使用horovod的多机多卡,需要有以下的3个先决条件

  1. 不同机器可以访问相同的文件:nfs
  2. 不同机器使用相同的训练环境: Docker
  3. 不同机器可以ssh交互:ssh 免密登录

假设现在要在两台服务器A和B上多机多卡跑horovod,A为主worker,下面介绍怎么准备horovod的启动条件。

NFS

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# 在A上的操作
#1. 安装nfs服务器
sudo apt install nfs-kernel-server

#2. 编写配置文件
sudo vi /etc/exports
#/etc/exports文件的内容如下
/data1/share *(rw,sync,no_subtree_check,no_root_squash)

#3. 创建共享目录
sudo mkdir -p /data1/share

#4. 重启nfs服务
sudo service nfs-kernel-server restart

#5. 常用命令工具:
#在安装NFS服务器时,已包含常用的命令行工具,无需额外安装。

#显示已经mount到本机nfs目录的客户端机器。
sudo showmount -e localhost

#将配置文件中的目录全部重新export一次!无需重启服务。
sudo exportfs -rv

#查看NFS的运行状态
sudo nfsstat

#查看rpc执行信息,可以用于检测rpc运行情况
sudo rpcinfo

#查看网络端口,NFS默认是使用111端口。
sudo netstat -tu -4
1
2
3
4
5
6
7
8
9
10
11
12
# 在B上的操作
#1. 安装nfs客户端
sudo apt install nfs-common

#2. 查看NFS服务器上的共享目录
sudo showmount -e A的ip

#3. 创建本地挂载目录
sudo mkdir -p /data1/share

#4. 挂载共享目录
sudo mount -t nfs A的ip:/data1/share /data1/share

这样就完成了nfs的挂载,两台服务器A和B都可以访问和读写 /data1/share 这个共同目录,并且目录内的东西会保持一致。以后horovod需要的训练代码和数据也将会存在这些路径之下,以便两台服务器都可以访问。

Docker

分别在A和B服务器上通过docker建立容器,这里仅以在A上的操作为例,B的类似。

  1. 将用户加到docker的组

    1
    sudo gpasswd -a user docker

    加入后退出连接,重新ssh登录就可以不加sudo运行docker命令了。

  2. pull docker

    1
    docker pull horovod/horovod:0.18.2-tf2.0.0-torch1.3.0-mxnet1.5.0-py3.6-gpu
  3. 建立容器

    这里需要注意要把上一步的共享目录映射进来

    1
    nvidia-docker run -itd --net=host -v /data1:/data1 --name horovod --shm-size=126g horovod/horovod:0.18.2-tf2.0.0-torch1.3.0-mxnet1.5.0-py3.6-gpu bash
  4. 运行容器

    1
    docker exec -it horovod bash

ssh免密登录

此时A和B应分别在horovod容器内。

这里踩了个坑,如果按照horovod的Docker教程, 创建容器时如果添加映射 share/ssh:/root/.ssh,就一直实现不了免密的登录,不添加映射反而可以免密登录了。

  1. 先在B服务器上开启ssh
1
2
3
4
5
6
7
8
9
10
11
12
13
#1. 修改sshd配置 
vim /etc/ssh/sshd_config
#2. 改动如下
Port 12345
PermitRootLogin yes
PubkeyAuthentication yes
AuthorizedKeysFile .ssh/authorized_keys .ssh/authorized_keys2
#3. 保存配置,启动sshd
/usr/sbin/sshd
#4. 查看ssh是否启动
ps -ef | grep ssh
#5. 修改root的密码
passwd
  1. 在A服务器上创建秘钥并且免密登录到B
1
2
3
4
5
6
7
8
9
#1. 生成秘钥
ssh-keygen -t rsa
#2. 在B上创建.ssh文件夹
ssh -p 12345 B mkdir -p .ssh
#3. 将公钥添加到B的authorized_keys里
cat .ssh/id_rsa.pub | ssh -p 12345 B 'cat >> .ssh/authorized_keys'

#测试是否可以免密登录
ssh -p 12345 B

启动测试

至此horovod的启动环境就搭好了,剩下的配套地修改训练代码可以参考horovod的docs去改。

这里以horovod的github为例测试一下是否可以正常启动多机多卡训练。以下操作在服务器A上进行。

  1. 将horovod的代码下载到共享文件,注意下tag跟docker对应的版本

    1
    git clone -b v0.18.2 https://github.com/horovod/horovod.git
  2. 修改examples下的pytorch_imagenet_resnet50.py,将imagenet路径修改为自己的路径(应在/data1/share里)。

  3. 按照TensorboardX和tqdm (服务器B也要安装)

    1
    2
    pip install tensorboardX
    pip install tqdm
  4. 运行启动多机多卡命令,每个服务器各用4张卡

    1
    horovodrun -np 8 -H localhost:4,B:4 -p 12345 python pytorch_imagenet_resnet50.py

分别查看A和B的显卡占用,是否多机多卡启动正常。