분산 학습의 통신은 왜 전부 AllReduce로 귀결되는가
Broadcast부터 Ring AllReduce의 bandwidth-optimal 증명까지, 분산 학습 multi-GPU 통신의 6가지 collective operation과 NCCL 토폴로지 선택 원리를 추적한다.
- 01 분산 학습의 통신은 왜 전부 AllReduce로 귀결되는가
- 02 Data Parallelism의 수학 — AllReduce는 왜 정확한가
- 03 Tensor Parallelism은 왜 AllReduce가 정확히 2번인가
- 04 Pipeline Bubble은 어떻게 줄어드는가
- 05 ZeRO는 왜 단계적으로 분산하는가
- 06 Transformer 학습에서 Activation Memory는 왜 폭발하는가
- 07 분산 학습의 네 가지 축 — 3D Parallelism, MoE, Checkpoint, Elastic
분산 학습의 모든 multi-GPU 통신은 결국 6가지 collective operation의 조합으로 환원된다. Data Parallelism의 gradient sync든, ZeRO-3의 parameter fetch든, 겉으로 보이는 프레임워크 추상화 아래에는 동일한 수학 구조가 있다. 그렇다면 왜 그 수많은 operation 중 AllReduce가 지배적으로 쓰이고, 그 AllReduce를 구현하는 최선의 방법은 무엇인가?
6가지 Operation의 구조적 분류
collective operation 6가지는 두 가지 원시 패턴의 조합으로 이해할 수 있다 — “하나가 모두에게” 와 “모두가 하나로”.
| Operation | 입력 | 출력 | 분산 학습 사용처 |
|---|---|---|---|
| Broadcast | root의 tensor 1개 | 모든 rank에 복사 | 모델 초기화 |
| Scatter | root의 P개 chunk | 각 rank에 자신의 chunk | ZeRO-3 param 분배 |
| Gather | 각 rank의 chunk | root에 concatenate | inference output 수집 |
| AllGather | 각 rank의 chunk | 모든 rank에 full tensor | ZeRO-3 forward param fetch |
| ReduceScatter | 모든 rank의 tensor | reduce 후 각 rank에 자신의 chunk | ZeRO-2 gradient sharding |
| AllReduce | 모든 rank의 tensor | sum 후 모든 rank에 broadcast | DDP gradient sync |
이 중 AllReduce가 “가장 흔한 operation”이 된 이유는 단순하다. Data Parallelism에서 backward pass 후 모든 GPU는 동일한 gradient를 갖고 동일한 optimizer step을 밟아야 한다. 각 rank의 gradient를 합산해 전부에게 돌려주는 것 — 그것이 AllReduce의 정의다.
AllReduce를 한 번에 수행하는 것과, ReduceScatter로 합산된 chunk를 각 rank에 분배한 뒤 AllGather로 재조립하는 것은 수학적으로 동등하다. ZeRO-2/3는 이 등가성을 이용해 메모리를 절약한다.
AllReduce ≡ ReduceScatter + AllGather
이 등가성은 단순한 관찰이 아니라 분산 학습 메모리 최적화의 근간이다.
개 rank의 distributed group 에서, 각 rank 가 tensor 을 보유할 때:
즉 두 방식은 동일한 최종 상태를 생성하며, 총 통신량도 동일하다.
Step 1 — ReduceScatter 후 상태: 각 rank 는 sum된 chunk 를 보유한다.
Step 2 — AllGather 적용: 각 rank는 모든 을 수신하여 full reduced tensor를 얻는다.
Step 3 — AllReduce와의 동등성: AllReduce의 정의
와 정확히 동일한 결과다. 통신량 역시 ReduceScatter의 scatter phase와 AllGather의 gather phase를 합하면 AllReduce와 일치한다.
이 분해가 중요한 이유는 메모리 활용 방식이 달라지기 때문이다. AllReduce는 전 과정에서 각 rank가 full-size gradient를 보유해야 하지만, ReduceScatter + AllGather는 중간 단계에서 크기의 chunk만 유지할 수 있다. ZeRO-2가 이를 정확히 활용한다.
Ring AllReduce는 왜 Bandwidth-Optimal인가
AllReduce를 구현하는 방법은 여러 가지다. Naive reduce-then-broadcast, Recursive Halving/Doubling, Tree, 그리고 Ring. 이 중 대규모 분산 학습에서 Ring이 사실상 표준이 된 이유는 수학적으로 증명 가능하다.
Ring AllReduce는 두 phase로 구성된다.
초기: rank i는 tensor를 N개 chunk로 분할
rank i: [c0^(i) | c1^(i) | ... | c_{N-1}^(i)]
Scatter-Reduce (N-1 steps):
각 rank i가 시계방향으로 chunk를 전달하며 누적
step 0: rank 0 → 1, rank 1 → 2, ..., rank N-1 → 0
step N-2 완료 시: rank i가 chunk i의 완전한 합 보유
All-Gather (N-1 steps):
완성된 chunk를 동일한 ring으로 전파
최종: 모든 rank가 모든 chunk의 합 보유
communication model에서, Ring AllReduce의 per-rank 통신량은:
이며, 일 때 AllReduce의 bandwidth lower bound 에 수렴한다.
통신량 유도: 각 step에서 rank는 bytes 크기의 chunk 1개만 전송/수신한다. Scatter-Reduce phase는 steps, All-Gather phase도 steps이므로:
Lower bound와의 비교: AllReduce의 결과는 각 rank가 size- vector를 보유해야 하므로, 어떤 알고리즘도 per-rank 최소 통신량 bytes를 피할 수 없다. 이 bandwidth lower bound는:
Ring은 일 때:
따라서 Ring은 점근적으로 bandwidth-optimal이다.
이 증명이 Patarasuk & Yuan (2009)의 핵심 기여다. NCCL, DeepSpeed, Megatron이 모두 large message에서 Ring을 기본값으로 채택하는 수학적 근거가 바로 여기에 있다.
Bandwidth vs Latency: 언제 어느 알고리즘을 선택하는가
Ring이 bandwidth-optimal임에도 항상 Ring을 쓰지 않는 이유가 있다. Ring의 latency는 이지만, Tree AllReduce는 이다. 작은 message에서는 이 차이가 지배적이다.
모델에서 두 알고리즘의 교차점 는 다음과 같이 도출된다:
실제 값으로 보면: , , 일 때 . 현대 LLM의 gradient는 수 GB 단위이므로, 대규모 학습에서 Ring이 압도적으로 유리하다.
Tree AllReduce는 latency , bandwidth per-rank . Ring AllReduce는 latency , bandwidth per-rank . NCCL은 message size를 기준으로 자동 선택하지만, NCCL_DEBUG=INFO로 실제 선택된 알고리즘을 확인할 수 있다.
물리 토폴로지가 Ring을 바꾼다: NCCL의 역할
Ring AllReduce가 수학적으로 bandwidth-optimal이더라도, 물리적 네트워크 토폴로지를 무시하면 수배의 성능 손실이 발생한다.
| 연결 종류 | Bandwidth | 비고 |
|---|---|---|
| NVLink 4.0 | 600 GB/s | Intra-node (H100, 8 GPU) |
| InfiniBand NDR | 50 GB/s | Inter-node |
| PCIe Gen5 | 64 GB/s | CPU-GPU 또는 구형 |
NVLink와 InfiniBand 간에는 12배 이상의 bandwidth 차이가 있다. Ring의 bottleneck은 가장 느린 edge에서 결정되므로, ring 구성 순서가 성능을 좌우한다. node-aware ring(같은 노드의 GPU를 연속 배치)은 inter-node hop을 최소화하여 최적 성능을 낸다.
NCCL은 이 토폴로지를 자동으로 인식하고 최적 ring을 구성한다. 이것이 “그냥 dist.all_reduce() 호출하면 되는” 이유다.
정리
- 분산 학습의 모든 통신은 Broadcast, Scatter, Gather, AllGather, ReduceScatter, AllReduce 6가지로 분해된다.
- AllReduce ≡ ReduceScatter + AllGather는 수학적 등가이며, ZeRO-2/3의 메모리 최적화 근거다.
- Ring AllReduce는 에서 bandwidth lower bound 에 수렴하는 점근적 최적 알고리즘이다.
- message size가 보다 작으면 Tree가, 크면 Ring이 유리하다 — NCCL이 자동으로 선택한다.
- 물리 토폴로지(NVLink vs InfiniBand)가 ring 구성에 영향을 주며, node-aware ring이 필수다.
다음 글에서는 이 collective operation의 조합 위에 ZeRO-1/2/3가 어떻게 메모리 효율을 단계적으로 개선하는지 추적한다.