Настройка Horovod для распределённого обучения
Horovod — фреймворк для распределённого обучения от Uber, поддерживающий TensorFlow, Keras, PyTorch и MXNet. Его ключевое преимущество — унифицированный API для разных фреймворков и оптимизированная реализация ring-allreduce для агрегации градиентов.
Установка
# Зависимости
apt install -y g++ openmpi-bin libopenmpi-dev
# Установка с поддержкой NCCL и gloo
HOROVOD_GPU_OPERATIONS=NCCL pip install horovod[tensorflow,keras,pytorch,mxnet]
# Проверка
horovodrun --check-build
Интеграция с PyTorch
import torch
import horovod.torch as hvd
# Инициализация
hvd.init()
# Привязка к GPU по rank
torch.cuda.set_device(hvd.local_rank())
# Масштабирование learning rate пропорционально числу GPU
lr = 1e-3 * hvd.size()
optimizer = torch.optim.SGD(model.parameters(), lr=lr)
# Оборачивание оптимизатора — добавляет all-reduce градиентов
optimizer = hvd.DistributedOptimizer(
optimizer,
named_parameters=model.named_parameters(),
compression=hvd.Compression.fp16 # Сжатие градиентов
)
# Broadcast начальных весов с rank 0 на все GPU
hvd.broadcast_parameters(model.state_dict(), root_rank=0)
hvd.broadcast_optimizer_state(optimizer, root_rank=0)
# Сохранение только на rank 0
if hvd.rank() == 0:
torch.save(model.state_dict(), "model.pt")
Запуск
# Один узел, 4 GPU
horovodrun -np 4 -H localhost:4 python train.py
# Несколько узлов
horovodrun -np 16 -H server1:8,server2:8 \
--network-interface eth0 \
python train.py
# С MPI
mpirun -np 16 \
-H server1:8,server2:8 \
-bind-to none -map-by slot \
-x NCCL_DEBUG=INFO \
-x LD_LIBRARY_PATH \
python train.py
Horovod Elastic Training
Elastic training позволяет динамически добавлять и удалять узлы во время обучения без остановки:
import horovod.torch as hvd
from horovod.torch.elastic import run
@hvd.elastic.run
def train(state):
# state.epoch и state.batch сохраняются между resizing
for state.epoch in range(state.epoch, num_epochs):
for state.batch, batch in enumerate(
get_loader(state.epoch, state.batch), state.batch
):
train_step(batch)
state.commit() # Checkpoint состояния
state = hvd.elastic.TorchState(
model=model,
optimizer=optimizer,
epoch=0,
batch=0
)
run(train, state)
Timeline профилировщик
Horovod включает встроенный profiler для анализа коммуникационных накладных расходов:
HOROVOD_TIMELINE=timeline.json horovodrun -np 4 python train.py
# Открыть chrome://tracing и загрузить timeline.json
Timeline показывает время each allreduce операции, что помогает найти bottleneck — слои с медленной синхронизацией.
Сравнение с альтернативами
Horovod исторически был популярен до появления PyTorch DDP и DeepSpeed. Сегодня для новых проектов на PyTorch предпочтительнее PyTorch DDP (нативная интеграция) или DeepSpeed (для больших моделей). Horovod остаётся актуальным для:
- Существующих кодовых баз TensorFlow с распределённым обучением
- Multi-framework окружений (PyTorch + TensorFlow одновременно)
- Сред с MPI-инфраструктурой (HPC-кластеры с SLURM)
При переходе с Horovod на PyTorch DDP: основное изменение — замена hvd.DistributedOptimizer на torch.nn.parallel.DistributedDataParallel и использование torchrun вместо horovodrun.







