AI데이터센터 시스템 아키텍처 그림 출처
모듈 D · 소프트웨어·운영·12장·이론 2h / 실습 1h

분산 학습 시스템 아키텍처

병렬화는 다섯 가지가 있고, 각각이 타는 네트워크 계층이 정해져 있다. 그 대응만 정확히 알면 「이 모델을 이 하드웨어로 어떻게 학습할 것인가」는 취향이 아니라 계산의 문제가 된다.

이 장을 마치면

  1. DP/FSDP·TP·PP·EP·CP를 구분하고 각각이 사용하는 네트워크 계층을 말할 수 있다.
  2. 파이프라인 버블이 왜 생기고 어떻게 줄이는지 설명할 수 있다.
  3. Goodput 관점에서 학습 잡의 실효 처리량을 평가할 수 있다.
  4. 통신 시간을 프로파일링해 병목을 지목할 수 있다.

다섯 가지 병렬화와 그 자리

8장에서 scale-up과 scale-out의 차이가 「메모리를 읽느냐 메시지를 보내느냐」라고 했다. 그 결론이 여기서 지도로 정리된다.

병렬화를 어느 계층에 놓을 것인가 통신이 잦을수록 가까운 계층에 두어야 한다. 병렬화 무엇을 쪼개나 / 언제 통신하나 놓을 수 있는 계층 핵심 랙 클러스터 사이트 간 TP 텐서 병렬 한 행렬 곱을 여러 GPU가 나눠 계산 레이어마다 · 매우 잦음 가능 불가 불가 지연에 가장 민감하다. scale-up 도메인을 벗어나면 통신이 계산보다 오래 걸린다 EP 전문가 병렬 MoE의 전문가를 GPU에 흩뿌림 토큰마다 라우팅 · 잦음 가능 불가 불가 토큰이 어느 전문가로 갈지 미리 모른다 → 불규칙한 all-to-all 통신이 발생 CP 컨텍스트 병렬 긴 시퀀스를 토막 내 나눠 맡음 어텐션마다 · 잦음 가능 가능 불가 긴 컨텍스트 학습에 필수. 클러스터로 나가려면 시퀀스 토막을 크게 잡아야 PP 파이프라인 병렬 레이어 묶음을 단계별로 나눔 단계 경계에서 · 보통 가능 가능 불가 마이크로배치로 버블을 메운다. 지연을 계산 뒤에 숨길 여지가 있다 DP 데이터 병렬 · FSDP 배치를 나눠 같은 모델을 각자 스텝 끝에 한 번 · 드묾 가능 가능 가능 all-reduce 한 번으로 끝난다 → 지연이 커도 감출 수 있어 가장 멀리 나갈 수 있다

각 병렬화가 놓일 수 있는 계층. 통신이 잦을수록 가까운 계층에 두어야 한다.

직접 제작 도해 · 자유 사용
이 표를 외우는 대신 원리를 기억하자

통신 빈도가 배치를 결정한다. 레이어마다 동기화하는 TP는 ns 단위 지연을 요구하니 랙 안에만 있을 수 있고, 스텝 끝에 한 번 합치는 DP는 ms 지연도 감출 수 있으니 사이트를 넘어갈 수 있다.

그래서 「NVL72의 72」라는 숫자가 의미를 갖는다 — 한 랙 안에서 쓸 수 있는 TP·EP 크기의 상한이다.

순차 실행과 데이터 병렬의 차이. 가장 단순하고 가장 멀리 나갈 수 있는 병렬화다.

순차 실행과 데이터 병렬의 차이. 가장 단순하고 가장 멀리 나갈 수 있는 병렬화다.

출처: SavniCC BY-SA 4.0
텐서 병렬 — MLP와 셀프어텐션 안의 행렬 곱을 쪼갠다. 레이어마다 결과를 합쳐야 하므로 통신이 극도로 잦다.

텐서 병렬 — MLP와 셀프어텐션 안의 행렬 곱을 쪼갠다. 레이어마다 결과를 합쳐야 하므로 통신이 극도로 잦다.

출처: developer.nvidia.com© developer.nvidia.com (교육 목적 인용)

파이프라인 병렬과 버블

파이프라인 병렬(PP)은 레이어 묶음을 단계별로 나눠 여러 GPU에 얹는다. 문제는 앞 단계가 일하는 동안 뒤 단계가 놀고, 뒤 단계가 일하는 동안 앞 단계가 논다는 것이다. 이 유휴를 버블(bubble) 이라 한다.

텐서 병렬과 파이프라인 병렬을 함께 적용한 모습

텐서 병렬과 파이프라인 병렬을 함께 적용한 모습

점선 상자가 두 겹으로 그려져 있다 — 세로 점선이 텐서 병렬(Tensor MP) 분할, 굵은 테두리가 파이프라인 병렬(Pipeline MP) 분할이다. 실제 대규모 학습은 이렇게 여러 병렬화를 겹쳐서 쓴다. 위 병렬화 지도에서 「TP는 랙 안, PP는 랙 사이」라고 한 것이 이 그림의 두 점선이 각각 어느 계층에 놓이는가를 뜻한다.

출처: developer.nvidia.com© developer.nvidia.com (교육 목적 인용)
단순한 스케줄. 앞뒤 단계가 서로를 기다리는 구간(버블)이 크게 남는다.

단순한 스케줄. 앞뒤 단계가 서로를 기다리는 구간(버블)이 크게 남는다.

출처: developer.nvidia.com© developer.nvidia.com (교육 목적 인용)

버블을 줄이는 방법은 배치를 잘게 쪼개 파이프라인을 채우는 것이다. 마이크로배치를 흘려보내면 각 단계가 항상 뭔가를 하고 있게 된다.

1F1B(one-forward-one-backward) 스케줄. 순전파와 역전파를 번갈아 흘려 메모리 사용량을 억제하면서 버블을 줄인다.

1F1B(one-forward-one-backward) 스케줄. 순전파와 역전파를 번갈아 흘려 메모리 사용량을 억제하면서 버블을 줄인다.

출처: developer.nvidia.com© developer.nvidia.com (교육 목적 인용)
인터리브 방식. 한 GPU가 여러 단계를 나눠 맡아 버블을 더 잘게 만든다. 대신 통신 횟수가 늘어난다.

인터리브 방식. 한 GPU가 여러 단계를 나눠 맡아 버블을 더 잘게 만든다. 대신 통신 횟수가 늘어난다.

출처: developer.nvidia.com© developer.nvidia.com (교육 목적 인용)

10장의 「겹치기」와 같은 발상이다. 기다림을 없앨 수 없다면 다른 일 뒤에 숨기는 것이 분산 시스템 최적화의 기본 문법이다.

Goodput — 실제로 쓸모 있게 쓰인 시간

클러스터를 운영할 때 「GPU를 몇 장 샀는가」보다 중요한 것은 그중 몇 장이 실제로 유용한 계산을 하고 있는가이다.

지표정의무엇을 놓치는가
GPU 사용률SM이 명령을 실행 중인 시간 비율연산 유닛이 꽉 찼는지는 알 수 없다 (1장 실습 참고)
MFU달성 FLOPs ÷ 이론 피크 FLOPs장애로 날린 시간, 재시작 비용은 안 잡힌다
Goodput유효하게 전진한 학습 시간 ÷ 전체 점유 시간가장 정직한 지표. 아래 요소를 전부 포함한다
Goodput을 갉아먹는 것들
  • 통신 대기 — 병렬화 배치가 잘못되면 여기서 대부분을 잃는다 (이 장)
  • 데이터 굶주림 — 스토리지가 못 따라옴 (10장)
  • 체크포인트 쓰기 — 비동기가 아니면 그 시간만큼 멈춤 (10장)
  • 장애와 재시작 — 수만 GPU가 몇 주 돌면 반드시 고장 난다. 마지막 체크포인트로 되돌아간 만큼이 통째로 손실
  • 낙오 노드(straggler) — 한 노드가 느리면 동기 학습에서는 전체가 그 속도가 된다

이 중 어느 것이 지배적인지는 프로파일링 없이는 알 수 없다. 그래서 아래 실습을 한다.

파이프라인 병렬 차수를 올릴 때의 GPU당 성능 (배치 8 vs 128)

파이프라인 병렬 차수를 올릴 때의 GPU당 성능 (배치 8 vs 128)

가로축이 파이프라인 병렬 크기(1·2·4·8)이고 세로축이 GPU 한 장이 내는 teraFLOPs다. 파란 선(배치 8)은 크게 떨어지지만 빨간 선(배치 128)은 거의 평평하다. 파이프라인을 깊게 나눌수록 버블이 늘어나는데, 마이크로배치를 많이 흘리면 그 버블이 메워지기 때문이다. 위에서 본 1F1B·인터리브 스케줄이 노리는 것이 정확히 이 차이다.

출처: developer.nvidia.com© developer.nvidia.com (교육 목적 인용)
GPU 수와 모델 크기를 함께 키웠을 때 달성한 연산 성능

GPU 수와 모델 크기를 함께 키웠을 때 달성한 연산 성능

점마다 1.7B · 3.6B · 7.5B · 18B · 39B · 76B · 145B · 310B · 530B · 1T 라벨이 붙어 있다. 즉 GPU를 늘리면서 그만큼 큰 모델을 학습했을 때의 결과이며, 로그-로그 축에서 거의 직선이라는 것이 「이 규모까지는 잘 확장된다」는 주장이다. 다만 이론 피크 대비 비율(MFU)은 이 그래프에 나오지 않는다 — 대규모 학습에서 40~50%면 좋은 편이고, 나머지는 통신·대기·재계산·버블로 사라진다. 15장에서 tokens/$를 계산할 때 이 비율을 반영하지 않으면 비용이 절반으로 과소평가된다.

출처: developer.nvidia.com© developer.nvidia.com (교육 목적 인용)

MoE 학습이 특히 까다로운 이유

MoE(Mixture of Experts)는 지금 대형 모델의 주류다. 그런데 학습 시스템 관점에서 보면 dense 모델과는 다른 종류의 문제를 만든다.

측면Dense 모델MoE 모델
연산량파라미터 전부 사용활성 파라미터만 → 같은 크기에서 훨씬 적다
메모리파라미터 크기만큼전부 올려야 한다 — 절약 없음 (14장)
통신 패턴예측 가능 (all-reduce)예측 불가 (all-to-all) — 토큰마다 목적지가 다름
부하 균형자동으로 균등전문가마다 부하가 다르다
병렬화TP·PP·DP여기에 EP가 추가되고 서로 얽힌다

부하 불균형 — 가장 성가신 문제

라우터가 토큰을 전문가에게 배분하는데, 학습 초반에는 특정 전문가로 쏠리는 경향이 있다. 쏠린 전문가를 가진 GPU만 바빠지고 나머지는 논다. 동기 학습이므로 전체 속도는 가장 느린 GPU에 맞춰진다.

  • Capacity factor — 전문가당 처리할 토큰 수에 상한을 둔다. 넘치는 토큰은 버리거나 다음 레이어로 그냥 통과시킨다. 균형은 잡히지만 품질에 영향.
  • Auxiliary loss — 부하가 균등해지도록 손실 함수에 항을 추가한다. 학습 목표를 하나 더 얹는 셈이라 튜닝이 필요하다.
  • 전문가 배치 최적화 — 자주 함께 활성화되는 전문가를 같은 노드에 두어 통신을 줄인다.
그래서 MoE는 하드웨어를 고른다

all-to-all 통신은 scale-up 도메인 안에서 해야 실용적이다(8장 병렬화 지도). 랙 밖으로 나가면 지연이 µs 단위가 되어 매 레이어마다 그만큼 기다리게 된다.

즉 MoE 모델을 학습하려면 큰 scale-up 도메인이 필요하다. NVL72의 72, Helios의 72라는 숫자가 「전문가를 몇 개까지 흩뿌릴 수 있는가」의 상한이며, 17장 설계에서 「우리가 MoE를 학습할 것인가」는 랙 선택을 직접 좌우하는 질문이 된다.

복원력 — 수만 GPU에서 고장은 상수다

4,096 GPU가 한 달을 돈다면, 그 동안 반드시 여러 번 고장 난다. 학습 시스템 설계에서 「고장이 안 나게」가 아니라 「고장이 나도 계속 전진하게」가 목표인 이유다.

전략어떻게비용적용 규모
체크포인트 + 재시작주기적으로 저장, 장애 시 되감기쓰기 오버헤드 + 되감기 손실모든 규모의 기본
핫 스페어여분 노드를 대기시켜 두고 즉시 투입노는 장비 비용대규모 · 재시작 비용이 클 때
탄력적 학습노드 수가 줄어도 계속 진행 (배치 재조정)구현 복잡도 · 재현성 저하일부 프레임워크가 지원
계층적 체크포인트자주는 로컬, 가끔은 원격 (10장)저장소 이중 관리대규모에서 효과 큼
결정론적 재현같은 시드·같은 순서로 정확히 재현성능 손해디버깅 필요 시
재시작 비용을 실제로 계산해 보자

체크포인트 간격 30분, 평균 무고장 시간 6시간, 재시작 오버헤드 10분이라면 —

  • 하루에 장애 약 4회 → 되감기 손실 평균 15분 × 4 = 60분
  • 재시작 오버헤드 10분 × 4 = 40분
  • 체크포인트 쓰기 (비동기라면 거의 0, 동기면 2분 × 48회 = 96분)
  • 하루 1,440분 중 100~200분을 잃는다 → Goodput 86~93%

클러스터가 4배 커지면 장애 빈도도 대략 4배가 되므로, 같은 전략으로는 Goodput이 급격히 나빠진다. 그래서 대규모에서는 체크포인트를 더 빠르게(샤딩·비동기) 만들고 재시작을 자동화하는 데 큰 노력을 들인다.

프레임워크와 스케줄러

무엇인가어디에 강한가
Megatron-Core / NeMoNVIDIA의 대규모 학습 스택TP·PP·EP를 조합한 초대형 모델 학습
TorchTitanPyTorch 네이티브 분산 학습실험과 확장이 쉬움
DeepSpeedZeRO 계열 메모리 최적화제한된 메모리로 큰 모델
JAX / PathwaysTPU 생태계6장의 TPU 포드
Neuron SDKAWS Trainium6장의 Trainium
ROCmAMD5장의 Helios

잡 스케줄링 — Slurm과 Kubernetes

여러 팀이 한 클러스터를 나눠 쓰면 누가 언제 얼마나 쓸지를 정하는 계층이 필요하다.

  • Slurm — HPC의 표준. 대규모 배치 잡, 갱(gang) 스케줄링에 강하다.
  • Kubernetes — 서비스 운영에 강하고 추론 서빙과 궁합이 좋다. 학습 잡을 위해 Volcano·Kueue 같은 확장이 붙는다.
  • 토폴로지 인식 스케줄링 — 8장를 배웠으니 이제 이 말이 무슨 뜻인지 안다. 같은 잡의 GPU를 같은 랙 안에 몰아 배치해야 TP를 쓸 수 있다. 스케줄러가 토폴로지를 모르면 잡이 랙에 흩어져 성능이 무너진다.

실습 — 2대에서 FSDP를 돌리고 통신을 들여다보기

실습

목표: DGX Spark 2대에서 소형 모델을 FSDP로 학습하고, 전체 스텝 시간 중 통신이 차지하는 비율을 프로파일링으로 확인한다. 8장에서 측정한 대역폭이 여기서 결과로 나타난다.

1단계 — 단일 장비 기준선

# 1대에서 먼저 돌려 기준을 잡는다
torchrun --nproc_per_node=1 train.py --model small --batch 8 --steps 50
# 기록: 스텝당 시간, GPU 메모리, 처리량(samples/s)

2단계 — 2대로 확장

# 1번 장비
torchrun --nnodes=2 --node_rank=0 --master_addr=10.0.0.1 --master_port=29500 \
         --nproc_per_node=1 train.py --model small --batch 8 --fsdp

# 2번 장비
torchrun --nnodes=2 --node_rank=1 --master_addr=10.0.0.1 --master_port=29500 \
         --nproc_per_node=1 train.py --model small --batch 8 --fsdp

3단계 — 프로파일링

# Nsight Systems 로 타임라인 수집
nsys profile -t cuda,nvtx,osrt -o step_profile \
     torchrun --nnodes=2 ... train.py --steps 20

# 확인할 것
#   - NCCL 커널이 차지하는 시간
#   - 그것이 계산 커널과 겹쳐 있는가, 따로 서 있는가
#   - 스텝 사이에 비어 있는 구간(데이터 로딩 대기)이 있는가

4단계 — 기록표

1대2대이상적 값달성률
스텝 시간 (ms)——
처리량 (samples/s)2배
통신 시간 비율 (%)00—
계산과 겹친 통신 비율 (%)—100

5단계 — 해석

  1. 2대로 늘렸을 때 처리량이 2배가 되었는가? 아니라면 잃어버린 몫은 어디로 갔는가?
  2. 통신 시간 중 계산과 겹친 부분은 얼마인가? 겹치지 못한 이유는 무엇인가?
  3. 8장에서 측정한 노드 간 대역폭으로, 이 모델의 그래디언트를 주고받는 데 이론상 몇 ms가 걸려야 하는가? 실측과 비교하라.
  4. 배치 크기를 2배로 늘리면 통신 비율은 어떻게 되는가? 왜 그런가?
  5. 이 장비 2대로 TP를 쓰면 어떤 일이 벌어질지 예측하고, 가능하면 확인하라. 위 병렬화 지도의 예측과 맞는가?

제출물

측정표 + nsys 타임라인 캡처 + 5단계 해석 (A4 3장 이내).

토론
  • 낙오 노드 하나가 전체를 느리게 만드는 문제를 어떻게 완화할 수 있는가?
  • 체크포인트 간격을 정하는 최적화 문제를 수식으로 세워 보라. 무엇과 무엇의 균형인가?
  • 9장에서 오버서브스크립션이 학습에 위험하다고 했다. 이 실습의 결과로 그 이유를 설명해 보라.

참고 자료

  • Narayanan et al., Efficient Large-Scale Language Model Training on GPU Clusters Using Megatron-LM (SC 2021)
  • NVIDIA Technical Blog — Megatron 병렬화 : 이 페이지 도해 출처
  • PyTorch FSDP 문서 · TorchTitan 저장소
  • MLPerf Training 결과 — 실제 대규모 학습의 구성 사례