概述


Horovod 是一个面向 TensorFlow、Keras、PyTorch 和 Apache MXNet 的分布式深度学习训练框架。 Horovod 的目标是让分布式深度学习变得快速且易于使用。

LF AI & Data

Horovod 由 LF AI & 数据基金会 (LF AI & Data) 托管。如果您是一家致力于在人工智能、机器学习和深度学习领域使用开源技术的公司,并希望支持这些领域的开源项目社区,请考虑加入 LF AI & 数据基金会。有关参与方以及 Horovod 如何发挥作用的详细信息,请阅读 Linux 基金会的 公告



为什么选择 Horovod?

该项目的主要动机是让单GPU训练脚本能够轻松地成功扩展到并行训练多个GPU。这包含两个方面:

  1. 将一个程序修改为分布式需要做多少改动,运行起来有多容易?

  2. 在分布式模式下运行速度能提升多少?

在Uber内部,我们发现MPI模型比之前的解决方案(如使用参数服务器的分布式TensorFlow)更加直观,且需要更少的代码更改。一旦为Horovod编写了可扩展的训练脚本,它就可以在单GPU、多GPU甚至多台主机上运行,无需任何额外的代码更改。 更多详情请参见Usage部分。

除了易于使用之外,Horovod 还非常快速。下图展示了在128台服务器上进行的基准测试结果,每台服务器配备4个Pascal GPU,并通过支持RoCE的25 Gbit/s网络连接:

512-GPU Benchmark

Horovod 在 Inception V3 和 ResNet-101 上实现了 90% 的扩展效率,在 VGG-16 上实现了 68% 的扩展效率。 请参阅 基准测试 了解如何复现这些数据。

虽然安装MPI和NCCL本身可能看起来有些麻烦,但这只需要基础设施团队完成一次,而公司中构建模型的其他人则可以享受大规模训练的简便性。

安装

在 Linux 或 macOS 上安装 Horovod:

  1. 安装 CMake

  1. 如果你从PyPI安装了TensorFlow,请确保已安装g++-5或更高版本。 从TensorFlow 2.10开始,将需要支持C++17的编译器,如g++8或更高版本。

    如果你从PyPI安装了PyTorch,请确保已安装g++-5或更高版本。

    如果你从Conda安装了任一软件包,请确保已安装gxx_linux-64 Conda软件包。

  1. 安装 horovod pip 包。

    要在 CPU 上运行:

    $ pip install horovod
    

    要在 GPU 上使用 NCCL 运行:

    $ HOROVOD_GPU_OPERATIONS=NCCL pip install horovod
    

有关安装支持 GPU 的 Horovod 的更多详细信息,请阅读 Horovod on GPU

有关 Horovod 安装选项的完整列表,请阅读 安装指南

如果你想使用MPI,请阅读Horovod with MPI

如果你想使用 Conda,请阅读构建支持 GPU 的 Horovod Conda 环境

如果你想使用Docker,请阅读Horovod in Docker

要从源代码编译 Horovod,请遵循贡献者指南中的说明。

概念

Horovod 核心原则基于 MPI 概念,例如 sizeranklocal rankallreduceallgatherbroadcastalltoall。更多详细信息请参见 此页面

用法

要使用 Horovod,请向您的程序添加以下内容:

  1. 运行 hvd.init() 来初始化 Horovod。

  1. 将每个GPU固定到一个进程,以避免资源争用。

    在典型的每个进程一个GPU的设置中,将此设置为本地排名。服务器上的第一个进程将被分配第一个GPU,第二个进程将被分配第二个GPU,依此类推。

  1. 根据工作节点数量缩放学习率。

    在同步分布式训练中,有效批次大小会随工作节点数量成比例增加。 提高学习率可以补偿增大的批次大小。

  1. 将优化器包装在 hvd.DistributedOptimizer 中。

    分布式优化器将梯度计算委托给原始优化器,使用 allreduceallgather 对梯度进行平均,然后应用这些平均后的梯度。

  1. 将初始变量状态从等级0广播到所有其他进程。

    当使用随机权重开始训练或从检查点恢复时,这能确保所有工作节点的一致初始化。

  1. 修改你的代码,仅在worker 0上保存检查点,以防止其他worker损坏它们。

使用 TensorFlow v1 的示例(完整训练示例请参见 examples 目录):

import tensorflow as tf
import horovod.tensorflow as hvd


# Initialize Horovod
hvd.init()

# Pin GPU to be used to process local rank (one GPU per process)
config = tf.ConfigProto()
config.gpu_options.visible_device_list = str(hvd.local_rank())

# Build model...
loss = ...
opt = tf.train.AdagradOptimizer(0.01 * hvd.size())

# Add Horovod Distributed Optimizer
opt = hvd.DistributedOptimizer(opt)

# Add hook to broadcast variables from rank 0 to all other processes during
# initialization.
hooks = [hvd.BroadcastGlobalVariablesHook(0)]

# Make training operation
train_op = opt.minimize(loss)

# Save checkpoints only on worker 0 to prevent other workers from corrupting them.
checkpoint_dir = '/tmp/train_logs' if hvd.rank() == 0 else None

# The MonitoredTrainingSession takes care of session initialization,
# restoring from a checkpoint, saving to a checkpoint, and closing when done
# or an error occurs.
with tf.train.MonitoredTrainingSession(checkpoint_dir=checkpoint_dir,
                                       config=config,
                                       hooks=hooks) as mon_sess:
  while not mon_sess.should_stop():
    # Perform synchronous training.
    mon_sess.run(train_op)

运行 Horovod

以下示例命令展示了如何运行分布式训练。 更多详情请参阅运行 Horovod,包括RoCE/InfiniBand调优技巧以及处理卡顿问题的建议。

  1. 在一台拥有4个GPU的机器上运行:

    $ horovodrun -np 4 -H localhost:4 python train.py
    
  2. 在4台机器上运行,每台机器有4个GPU:

    $ horovodrun -np 16 -H server1:4,server2:4,server3:4,server4:4 python train.py
    
  3. 要在不使用horovodrun包装器的情况下通过Open MPI运行,请参阅Running Horovod with Open MPI

  4. 要在Docker中运行,请参阅Horovod in Docker

  5. 要在Kubernetes上运行,请参阅Helm ChartKubeflow MPI OperatorFfDLPolyaxon

  6. 要在Spark上运行,请参阅Horovod on Spark

  7. 要在Ray上运行,请参阅Horovod on Ray

  8. 要在Singularity中运行,请参阅Singularity

  9. 要在LSF HPC集群(例如Summit)中运行,请参见LSF

  10. 要在Hadoop Yarn上运行,请参阅 TonY

Gloo

Gloo 是由 Facebook 开发的开源集体通信库。

Gloo 已包含在 Horovod 中,允许用户无需安装 MPI 即可运行 Horovod。

对于同时支持 MPI 和 Gloo 的环境,您可以通过向 --gloo 传递参数给 horovodrun 来选择在运行时使用 Gloo:

$ horovodrun --gloo -np 2 python train.py

mpi4py

Horovod 支持将 Horovod 集合操作与其他 MPI 库(如 mpi4py)混合使用,前提是 MPI 构建时支持多线程。

你可以通过查询hvd.mpi_threads_supported()函数来检查MPI多线程支持。

import horovod.tensorflow as hvd

# Initialize Horovod
hvd.init()

# Verify that MPI multi-threading is supported.
assert hvd.mpi_threads_supported()

from mpi4py import MPI
assert hvd.size() == MPI.COMM_WORLD.Get_size()

你也可以使用mpi4py子通信器来初始化Horovod,在这种情况下,每个子通信器将运行一个独立的Horovod训练。

from mpi4py import MPI
import horovod.tensorflow as hvd

# Split COMM_WORLD into subcommunicators
subcomm = MPI.COMM_WORLD.Split(color=MPI.COMM_WORLD.rank % 2,
                               key=MPI.COMM_WORLD.rank)

# Initialize Horovod
hvd.init(comm=subcomm)

print('COMM_WORLD rank: %d, Horovod rank: %d' % (MPI.COMM_WORLD.rank, hvd.rank()))

推理

了解如何优化模型以进行推理并从图中移除Horovod操作 here

Tensor Fusion

Horovod 的独特之处在于它能够交错进行通信和计算,并结合对小规模 allreduce 操作的批处理能力,从而提升性能。我们将这种批处理功能称为 Tensor Fusion。

查看这里获取完整详情和调整说明。

Horovod Timeline

Horovod 具备记录其活动时间轴的能力,称为 Horovod Timeline。

Horovod Timeline

使用 Horovod 时间线来分析 Horovod 性能。 查看这里获取完整详情和使用说明。

自动性能调优

选择合适的值以高效利用Tensor Fusion及其他高级Horovod功能可能需要大量试错。我们提供了一个名为自动调优的系统来自动化此性能优化过程,您只需通过一个命令行参数即可在horovodrun中启用该功能。

查看这里获取完整详情和使用说明。

Horovod Process Sets

Horovod 允许您在一场分布式训练中,同时在不同的进程组内执行不同的集合操作。设置 hvd.process_set 对象以利用此功能。

查看进程集获取详细说明。

指南

  1. 使用Batch AI和Horovod在Microsoft Azure中运行分布式训练。

  2. 使用Horovod进行分布式模型训练

向我们发送您希望在本网站上发布的任何用户指南链接

故障排除

如果找不到答案,请参阅故障排除并提交工单

引用

如果 Horovod 对您的研究有所帮助,请在您的出版物中引用它:

@article{sergeev2018horovod,
  Author = {Alexander Sergeev and Mike Del Balso},
  Journal = {arXiv preprint arXiv:1802.05799},
  Title = {Horovod: fast and easy distributed deep learning in {TensorFlow}},
  Year = {2018}
}

Publications

1. Sergeev, A., Del Balso, M. (2017) 遇见 Horovod:Uber 的开源分布式深度学习框架 for TensorFlow. 检索自 https://eng.uber.com/horovod/

2. Sergeev, A. (2017) Horovod - 分布式TensorFlow变得简单. 检索自 https://www.slideshare.net/AlexanderSergeev4/horovod-distributed-tensorflow-made-easy

3. Sergeev, A., Del Balso, M. (2018) Horovod: fast and easy distributed deep learning in TensorFlow. 检索自 arXiv:1802.05799

参考文献

Horovod 源代码基于 Andrew Gibiansky 和 Joel Hestness 编写的百度 tensorflow-allreduce 代码库。他们的原始工作在文章 Bringing HPC Techniques to Deep Learning 中有详细描述。

参与其中