NVIDIA's NCCL implements the same all-reduce with several algorithms - ring, tree, and switch-assisted variants over NVLink and NVSwitch - and chooses between them at runtime. Why does one collective operation need several algorithms, and what does that force a cluster scheduler to know?
Show the full answer Hide the answer
The situation NCCL is in
Synchronous data-parallel training ends every step with an all-reduce over the gradients. That collective is a barrier: no rank starts the next step until all ranks finish, so the collective's cost is added to every step of a run that may last weeks. NCCL has to serve that operation across hardware whose links differ by an order of magnitude — GPUs inside a server connected by NVLink and NVSwitch, servers connected by a network — and across message sizes from kilobytes to many gigabytes.
What the algorithms trade
- Ring moves roughly
2(N−1)/Ntimes the payload per GPU, which approaches the bandwidth optimum, but it takes2(N−1)sequential hops, so its latency grows linearly with rank count. - Tree has depth on the order of
log N, so latency grows logarithmically. It wins on small messages and at large scale, and gives up some bandwidth efficiency. - Switch-assisted variants (NVLS, using NVLink SHARP) perform the reduction inside the switch rather than on the GPUs, which removes hops entirely for the intra-node part.
Published analyses of NCCL put the crossover where you would expect from that algebra: ring for large messages, tree for small messages and very large rank counts. One operation needs several algorithms because the cost function has two terms — latency per hop and bytes per link — and which term dominates flips with message size and scale.
Why this fits a hierarchical cluster
The common shape is a two-level collective: reduce inside the node over NVLink, all-reduce across nodes over the network, broadcast back inside the node. It exists because the intra-node fabric is far faster than the inter-node one, so you do as much of the reduction as possible on the fast side and send the smallest possible payload across the slow one.
What it forces a scheduler to know
- Placement is a performance decision, not a packing decision. A job whose ranks are scattered across leaf switches pays its slowest link on every step. Topology-aware gang scheduling — all ranks of a job inside one rail or leaf domain — is what keeps the step time predictable.
- One straggler sets everyone's step time, because of the barrier. A single GPU at reduced clocks, or one node on a degraded link, slows 1,024 GPUs.
- The signal to watch is not GPU utilisation. Utilisation stays high while ranks spin in the collective. Watch the gap between compute time and step time, and bus bandwidth from a collective benchmark, per job.
What it costs
Topology-aware gang scheduling fragments the cluster: holding a leaf domain free for a large job leaves accelerators idle, so allocation efficiency falls to protect step time. That is the real trade, and it is a business decision about whether a long training run or overall occupancy matters more.
When not to copy this, and where it would be a mistake
A team fine-tuning on eight GPUs in one server has no inter-node collective at all, and every sentence above is noise; their step time is dominated by data loading. For inference, the reasoning inverts: tensor-parallel all-reduce happens per generated token with tiny messages, so latency per hop dominates and bandwidth-optimal rings are the wrong choice. The transferable lesson is not "use ring" — it is that a collective's cost is a property of the topology you were placed on, which means placement belongs to the scheduler and must be measured per job.