开源免费集群Horovod快速入门指南

Horovod是一款面向TensorFlow、Keras、PyTorch及Apache MXNe的分布式深度学习训练框架,其设计目标在于让分布式深度学习变得高效且易于使用。
本篇主要是为那些寻找多GPU深度学习训练开源解决方案的同学提供一个快速了解Horovod的途径。
Horovod由LF AI & Data基金会(隶属Linux基金会)托管。若贵公司致力于在人工智能、机器学习及深度学习领域深度应用开源技术,并希望支持这些领域的开源项目社区,诚邀您加入LF AI & Data基金会。关于参与成员详情及Horovod在其中发挥的作用,请参阅Linux基金会发布的官方声明。
- Horovod的定位
- 安装
- 概念
- 支持框架
- 使用说明
- 运行Horovod
- Gloo
- mpi4py
- 推理
- Tensor Fusion
- Horovod Timeline
- 写在最后
对开源免费集群软件感兴趣的同学,也可以关注一下开源免费集群软件Slurm:
开源免费集群Slurm快速入门用户指南
Horovod的定位
Horovod项目的首要初衷,是让使用者能够轻松地将单GPU训练脚本扩展为多GPU并行训练。这主要涉及两个方面:
- 一是需要对程序进行多少修改才能实现分布式运行,以及操作流程是否简便;
- 二是在分布式模式下运行速度能提升多少。
在Uber内部实践中,我们发现相较于参数服务器模式的分布式TensorFlow等原有方案,基于MPI架构的Horovod不仅逻辑更清晰,所需代码修改量也大幅减少。使用Horovod编写的规模化训练脚本具备无缝扩展能力——无需调整代码即可在单GPU、多GPU乃至多主机环境中直接运行。具体操作指南请参阅「使用」章节。
除了易于使用之外,Horovod在性能方面同样出色。下图展示了基于128台服务器完成的基准测试结果,每台服务器配备4张Pascal架构GPU,并通过支持RoCE技术的25Gbit/s网络进行互联。
Horovod在Inception V3和ResNet-101模型上实现了90%的扩展效率,在VGG-16模型上也达到了68%的扩展效率。
虽然安装MPI和NCCL看似增加了额外步骤,但这些基础环境配置仅需由基础设施团队一次性完成。公司内其他进行模型开发的成员,都能享受到大规模分布式训练的便捷性。
安装
在Linux或macOS系统上安装Horovod的方法如下:
步骤一:安装CMake
步骤二:
- 若您通过PyPI安装了TensorFlow,请确保系统已安装g++-5或更高版本。从TensorFlow 2.10版本开始,将需要支持C++17标准的编译器(例如g++8或更高版本)。
- 若您通过PyPI安装了PyTorch,请确保系统中已安装g++-5或更高版本的编译器。
- 若您通过Conda安装了任一软件包,请确保已安装gxx_linux-64 Conda依赖包。
步骤三:安装horovod pip包:
- 若在CPU上运行:
$ pip install horovod- 若通过NCCL在GPU上运行:
$ HOROVOD_GPU_OPERATIONS=NCCL pip install horovod概念
Horovod的核心原理基于MPI概念:size(规模/进程数量)、rank(进程编号/全局进程编号)、local rank(本地进程编号)、allreduce(全局规约)、allgather(全局收集)、broadcast(广播)和alltoall(全交换)。这些概念通过示例解释最为有效。假设在4台服务器(每台含4个GPU)上启动训练脚本:
size:表示进程总数,本例中为16(4台服务器,每台含4个GPU,共4*4=16);
rank:表示从0到15的唯一进程ID(size - 1);
local rank:表示从0到3的唯一进程ID(server内局部编号);
allreduce:是一种在多个进程间聚合数据并将结果分发回各进程的操作,常用于平均密集张量。以下是MPI教程中的示例图示。

allgather:是一种在所有进程中收集数据的操作,用于聚合稀疏张量的值。以下是MPI教程中的示例图示。

broadcast:是一种从根进程(由根秩标识)向所有其他进程分发数据的操作。下图来自MPI教程的示意图展示了这一过程。

reducescatter:是一种在多个进程间聚合数据并分发的操作,用于对密集张量求平均后按进程拆分。该操作首先通过规约(如求和/求平均)聚合所有进程的数据,然后将结果按块分散到各进程。与allreduce不同,reducescatter不返回完整聚合结果,而是将结果分块分发。在Horovod等框架中,这种操作常用于高效处理大规模张量数据。以下是NVIDIA开发者指南中的示例图示。

alltoall:是一种在所有进程间交换数据的操作。在需要跨多个设备实现先进神经网络架构时,alltoall可能非常有用。
支持框架
- TensorFlow
- XLA in TensorFlow
- Keras
- Pytorch
- NXNet
使用说明
要使用Horovod,需在程序中添加以下内容:
1)运行hvd.init(),初始化Horovod;
2)将每个GPU绑定到单一进程以避免资源争用。在典型单GPU进程设置中,将local rank设置为进程ID。服务器第一个进程分配第一个GPU,第二个进程分配第二个GPU,依此类推;
3)根据工作进程(worker)数量调整学习率。在分布式训练中,通常需要将学习率乘以worker数量以保持总梯度更新的规模稳定。在同步分布式训练中,有效batch size会随工作进程数量增加而扩大,此时需相应提高学习率以补偿增大的batch size;
4)将优化器包装在 hvd.DistributedOptimizer 中。分布式优化器将梯度计算委托给原始优化器,通过allreduce或allgather操作对梯度进行平均,然后应用这些平均后的梯度。
5)将初始变量状态从rank 0的进程广播至所有其他进程。这是确保所有工作进程在训练开始时使用随机权重或从检查点checkpoint恢复时能保持初始化一致的必要操作。
6)修改代码,使其仅在worker 0(rank 0)上保存检查点checkpoint,以防止其他工作节点损坏检查点文件。
7)以下是Horovod在TensorFlow v1中的核心实现步骤:
import tensorflow as tfimport horovod.tensorflow as hvd# Initialize Horovodhvd.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 Optimizeropt = hvd.DistributedOptimizer(opt)# Add hook to broadcast variables from rank 0 to all other processes during# initialization.hooks =[hvd.BroadcastGlobalVariablesHook(0)]# Make training operationtrain_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()==0elseNone# 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:whilenot mon_sess.should_stop():# Perform synchronous training. mon_sess.run(train_op)运行Horovod
以下示例命令展示了如何运行分布式训练。详情请参阅Horovod官方文档,包括RoCE/InfiniBand的调整优化和解决卡顿问题的实用技巧:
1)在配备4张GPU卡的机器上运行:
$ horovodrun -np4-H localhost:4 python train.py2)在配置4张GPU卡的4台机器上运行:
$ horovodrun -np16-H server1:4,server2:4,server3:4,server4:4 python train.pyGloo
Gloo是Facebook开发的开源协同通信库。
Gloo已内置在Horovod中,用户无需安装MPI即可运行Horovod。
在同时支持MPI和Gloo的环境中,可以通过向horovodrun传递--gloo参数来在运行时选择使用Gloo。
$ horovodrun --gloo-np2 python train.pympi4py
Horovod支持将Horovod协同操作与其他MPI库(例如mpi4py)混合使用,前提是MPI库在构建时已启用多线程支持。
您可以通过查询hvd.mpi_threads_supported()函数来检查MPI多线程支持功能。
import horovod.tensorflow as hvd# Initialize Horovodhvd.init()# Verify that MPI multi-threading is supported.assert hvd.mpi_threads_supported()from mpi4py import MPIassert hvd.size()== MPI.COMM_WORLD.Get_size()您也可以使用mpi4py子通信器来初始化Horovod,在这种情况下,每个子通信器将运行一个独立的Horovod训练任务。
from mpi4py import MPIimport horovod.tensorflow as hvd# Split COMM_WORLD into subcommunicatorssubcomm = MPI.COMM_WORLD.Split(color=MPI.COMM_WORLD.rank %2, key=MPI.COMM_WORLD.rank)# Initialize Horovodhvd.init(comm=subcomm)print('COMM_WORLD rank: %d, Horovod rank: %d'%(MPI.COMM_WORLD.rank, hvd.rank()))推理
推理可以在用于训练模型的Python脚本之外进行。如果这样做,就不会引用到Horovod库。
对于通过启用Horovod的训练脚本生成的检查点进行推理时,您应该优化计算图并仅保留模型前向传播所需的操作。TensorFlow代码库中的"推理优化脚本"可为您完成此操作。
若需将检查点转换为冻结图Frozen Graph,应在完成上述优化操作后进行,否则冻结图Frozen Graph脚本将无法加载Horovod操作:
ValueError: No op named HorovodAllreduce in defined operations.Tensor Fusion
Horovod的独特之处在于它能够交错进行通信和计算,并能将小型全归约操作批量处理,从而提升性能。我们将这种批处理功能称为Tensor Fusion。
Tensor Fusion通过将当前时刻所有准备进行归约运算的张量合并为单一归约操作来实现功能。其算法如下:
1)确定哪些张量已准备进行归约运算。选取前几个符合HOROVOD_FUSION_THRESHOLD字节大小且数据类型相同的张量。
2)若之前未分配融合缓冲区,则分配一个大小为HOROVOD_FUSION_THRESHOLD的融合缓冲区。默认融合缓冲区大小为128MB。
3)将选定张量的数据复制到融合缓冲区中。
4)在融合缓冲区上执行全归约操作。
5)将融合缓冲区的数据复制到输出张量中。
6)重复以上步骤,直至当前周期内没有需要归约的张量。
融合缓冲区的大小可以通过在horovodrun命令中使用--fusion-threshold-mb参数进行调整:
$ horovodrun -np4 --fusion-threshold-mb 32 python train.py将--fusion-threshold-mb参数设置为零即可禁用Tensor Fusion`功能:
$ horovodrun -np4 --fusion-threshold-mb 0 python train.py您可以通过--cycle-time-ms命令行参数调整周期间隔时间(单位为毫秒):
$ horovodrun -np4 --cycle-time-ms 3.5 python train.pyHorovod Timeline

Horovod Timeline 是 Horovod 分布式训练框架中的一个性能分析工具。它可以记录训练过程中各个操作的精确时间线,帮助开发者:
- 可视化通信(如 AllReduce)和计算(如梯度计算)的时间开销
- 识别性能瓶颈(如通信等待时间过长)
- 优化训练效率,实现更好的硬件利用率
这个工具会生成一个 JSON 格式的时间线文件,可通过 Chrome 浏览器的 chrome://tracing 功能或Perfetto等工具可视化查看。
写在最后
Horovod可以通过多台GPU服务器提供分布式深度学习训练,其设计目标在于让分布式深度学习变得高效且易于使用。如果有同学嫌弃单机训练不够快,那么Horovod,不失为一个选择,当然,前提是各位的技术相对“硬”一些。毕竟,开源免费的附加物是时间投入。而售前工程师,在客户提到Horovod时,也无需再一脸茫然了。
本文内容仅供参考,不构成任何专业建议。使用本文提供的信息时,请自行判断并承担相应风险。



