最近需要 Horovod 相关的知识,在这里记录一下,进行备忘:
- 分布式训练,分为数据并行和模型并行两种;
- 模型并行:分布式系统中的不同GPU负责网络模型的不同部分。神经网络模型的不同网络层被分配到不同的GPU或者同一层内部的不同参数被分配到不同的GPU之上;
- 数据并行:不同的GPU有同一个模型的多个副本,每个GPU分配到不同的数据,然后将所有的GPU的结果按照某种方式合并;
- 不同的GPU,可以是同一台机器之上的多个GPU或者是不同机器上的GPU;
- 在数据并行过程中,各个GPU之间需要同步模型参数,参数分为 同步更新和异步更新两种情况;
- 图中的Machine可以认为是GPU或者是CPU;也有 数据并行和模型并行的混合模式;模型并行各个部分存在一定的依赖,规模伸缩性差;而数据并行中,各个部分独立,规模伸缩性好;实际训练过程中更多使用数据并行;
- 数据并行会涉及到各个 GPU 之间同步模型参数,一般分为同步更新和异步更新。同步更新要等到所有 GPU 的梯度计算完成,再统一计算新权值,然后所有 GPU 同步新值后,才进行下一轮计算。异步更新,每个 GPU 梯度计算完后,无需等待其他 GPU 的梯度计算(有时可以设置需要等待的梯度个数),可立即更新整体权值,然后同步此权值,即可进行下一轮计算。同步更新有等待,异步更新基本没有等待,但异步更新涉及到梯度过时等更复杂问题;在实际应用中,单机多卡的同步式数据并行是最常用的,在论文中最常见的训练方式是单机八卡。数据再多时,一般就需要多机多卡;
- 无论是单机多卡,还是多机多卡,都是分布式训练;
保持更新,更多内容请关注 cnblogs.com/xuyaowen;
Horovod 安装:
安装 cuda 9.0; https://www.cnblogs.com/xuyaowen/p/nvidia-driver-cuda-installation.html
编译安装nccl 根据cuda 9.0; https://www.cnblogs.com/xuyaowen/p/nccl-learning.html
安装 gcc 4.9: https://www.cnblogs.com/xuyaowen/p/gcc-49-install-on-ubuntu.html
python 版本 Python 3.6.9 (具体环境请自行适配)
安装 openmpi 4.0 : https://www.cnblogs.com/xuyaowen/p/openmpi-40-install.html
pip 安装 Horovod 框架:
HOROVOD_NCCL_HOME=nccl的home目录 HOROVOD_NCCL_LIB=nccl的lib目录 HOROVOD_NCCL_INCLUDE=nccl的include目录 HOROVOD_GPU_ALLREDUCE=NCCL pip install --no-cache-dir horovod
HOROVOD_NCCL_HOME=/home/name/nccl/build/ HOROVOD_NCCL_LIB=/home/name/nccl/build/lib/ HOROVOD_NCCL_INCLUDE=/home/name/nccl/build/include/ HOROVOD_GPU_ALLREDUCE=NCCL pip install --no-cache-dir horovod
安装后,使用:python -c "import horovod.tensorflow as hvd;" 命令进行测试,如果无错误输出,则表示安装成功;之后可参考官方手册使用Horovod;
➜ openmpi python -c "import horovod.tensorflow as hvd;" /home/name/anaconda3/envs/gnnalgos/lib/python3.6/site-packages/tensorflow/python/framework/dtypes.py:523: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'. _np_qint8 = np.dtype([("qint8", np.int8, 1)]) /home/name/anaconda3/envs/gnnalgos/lib/python3.6/site-packages/tensorflow/python/framework/dtypes.py:524: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'. _np_quint8 = np.dtype([("quint8", np.uint8, 1)]) /home/name/anaconda3/envs/gnnalgos/lib/python3.6/site-packages/tensorflow/python/framework/dtypes.py:525: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'. _np_qint16 = np.dtype([("qint16", np.int16, 1)]) /home/name/anaconda3/envs/gnnalgos/lib/python3.6/site-packages/tensorflow/python/framework/dtypes.py:526: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'. _np_quint16 = np.dtype([("quint16", np.uint16, 1)]) /home/name/anaconda3/envs/gnnalgos/lib/python3.6/site-packages/tensorflow/python/framework/dtypes.py:527: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'. _np_qint32 = np.dtype([("qint32", np.int32, 1)]) /home/name/anaconda3/envs/gnnalgos/lib/python3.6/site-packages/tensorflow/python/framework/dtypes.py:532: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'. np_resource = np.dtype([("resource", np.ubyte, 1)])
参考连接:
https://github.com/horovod/horovod (官方文档,可以参考安装和使用)
https://www.infoq.cn/article/J4ry_9bsfbcNkv6dfuqC
http://fyubang.com/2019/07/08/distributed-training/ (讲解了分布式多卡训练相关的基础知识)
分布式多卡-pytorch,tensorflow 系列教程 (较为详细的教程,讲解了现有较为优秀的框架的特点和使用方式)
https://zhuanlan.zhihu.com/p/78303865 (安装使用参考,本文中的安装步骤参考此教程)