Настройка NVIDIA NCCL для мульти-GPU обучения
NCCL (NVIDIA Collective Communications Library) — это библиотека примитивов коллективных операций (all-reduce, broadcast, all-gather, reduce-scatter), оптимизированных для NVIDIA GPU. Именно NCCL отвечает за синхронизацию градиентов между GPU при распределённом обучении. Неправильная конфигурация NCCL — частая причина низкой эффективности мульти-GPU обучения.
Архитектура NCCL
NCCL автоматически выбирает оптимальный transport для коммуникации:
- NVLink — внутри сервера между GPU (400+ GB/s для H100), приоритет 1
- PCIe — внутри сервера без NVLink (32-64 GB/s), приоритет 2
- InfiniBand (RDMA) — между серверами через Mellanox/ConnectX (200+ GB/s), приоритет 1 для multi-node
- Ethernet — между серверами (10-100 GB/s), медленнее IB
Установка и проверка
# Установка
sudo apt install libnccl2 libnccl-dev
# Или из conda
conda install nccl -c nvidia
# Проверка версии
python -c "import torch; print(torch.cuda.nccl.version())"
# NCCL tests для бенчмаркинга
git clone https://github.com/NVIDIA/nccl-tests.git
cd nccl-tests
make MPI=1 MPI_HOME=/usr/lib/x86_64-linux-gnu/openmpi CUDA_HOME=/usr/local/cuda
# Тест all_reduce (наиболее используемая операция в DDP)
./build/all_reduce_perf -b 1M -e 4G -f 2 -g 8
Переменные окружения NCCL
# Отладка — подробный вывод алгоритмов и топологии
export NCCL_DEBUG=INFO
export NCCL_DEBUG_SUBSYS=ALL
# Принудительный выбор транспорта (для диагностики)
export NCCL_P2P_DISABLE=0 # 1 - отключить P2P (NVLink/PCIe direct)
export NCCL_SHM_DISABLE=0 # 1 - отключить shared memory
export NCCL_SOCKET_IFNAME=eth0 # Сетевой интерфейс для multi-node
# Настройка для InfiniBand
export NCCL_IB_DISABLE=0
export NCCL_IB_HCA=mlx5_0 # Имя IB адаптера
export NCCL_IB_GID_INDEX=3 # GID индекс для RoCE
# Оптимизация буферов
export NCCL_BUFFSIZE=4194304 # 4MB buffer
export NCCL_NTHREADS=512
# Отключение NVLink для диагностики (проверить разницу в скорости)
export NCCL_P2P_LEVEL=0 # Отключить все P2P
Диагностика топологии
# Просмотр NVLink топологии
nvidia-smi topo -m
# Выводит матрицу соединений:
# NV4 = 4 NVLink линки, PIX = PCIe switch, PHB = PCIe host bridge
# Пример вывода для DGX A100:
# GPU0 GPU1 GPU2 GPU3 GPU4 GPU5 GPU6 GPU7
# GPU0 X NV12 NV12 NV12 NV12 NV12 NV12 NV12
# GPU1 NV12 X NV12 NV12 NV12 NV12 NV12 NV12
Benchmark: влияние топологии на all-reduce
# Benchmark без NVLink (PCIe only)
NCCL_P2P_DISABLE=1 ./build/all_reduce_perf -b 1G -e 4G -f 2 -g 8
# Результат: ~30-40 GB/s algbw
# Benchmark с NVLink (A100 DGX)
./build/all_reduce_perf -b 1G -e 4G -f 2 -g 8
# Результат: ~250-280 GB/s algbw
Разница в 6-7x объясняет, почему DGX-серверы с NVLink значительно эффективнее для distributed training по сравнению с обычными серверами с несколькими GPU через PCIe.
Multi-node NCCL через InfiniBand
# Требуется установка: OFED, nv_peer_mem или gdrcopy
# gdrcopy - RDMA direct GPU memory copy
apt install libgdrapi-dev gdrcopy
# Запуск 2-узлового обучения
NCCL_IB_DISABLE=0 NCCL_IB_HCA=mlx5_0 \
torchrun --nnodes=2 --nproc_per_node=8 \
--master_addr=10.0.0.1 --master_port=29500 \
train.py
# Ожидаемая пропускная способность all-reduce (2 узла, 8 GPU каждый):
# InfiniBand HDR (200Gbps): ~18-20 GB/s
# 100GbE: ~9-11 GB/s
Оптимизация NCCL для конкретных топологий
Если NVLink недоступен, но GPU соединены через один PCIe switch, NCCL автоматически использует shared memory через NVLink-like shared topology. Для cross-socket GPU (GPU на разных NUMA-узлах) рекомендуется NCCL_CROSS_NIC=1 при multi-NIC конфигурации.
Правильно настроенный NCCL — разница между 85% и 30% scaling efficiency на мульти-GPU обучении.







