- Published on
멀티 GPU·멀티노드 학습 플랫폼 총정리 — 프레임워크 지도부터 Slurm·Kubeflow 실전 가이드까지
- Authors

- Name
- Youngju Kim
- @fjvbn20031
- 들어가며 — GPU가 늘어나는 순간 문제는 소프트웨어가 된다
- 1부 — AI 라이브러리·프레임워크 생태계 지도
- 2부 — 병렬화 전략: 무엇이 안 들어가는가부터 묻기
- 3부 — torchrun: 모든 것의 공통 분모
- 4부 — Slurm 사용 가이드: HPC의 왕
- 5부 — Kubeflow 사용 가이드: 쿠버네티스 진영의 답
- 6부 — 선택 기준: Slurm vs Kubeflow vs Ray
- 마치며
- 참고 자료
들어가며 — GPU가 늘어나는 순간 문제는 소프트웨어가 된다
GPU 한 장의 학습은 프레임워크가 알아서 해 줍니다. GPU 여덟 장, 노드 네 대가 되는 순간부터는 프로세스를 어떻게 띄우고, 서로를 어떻게 찾게 하고, 실패하면 어떻게 다시 시작하는가라는 인프라 문제가 시작됩니다. 이 글은 그 지형 전체를 다룹니다 — 어떤 라이브러리들이 있는지(생태계 지도), 모델을 어떻게 쪼개는지(병렬화 전략), 그리고 잡을 어디에 던지는지(Slurm vs Kubeflow vs Ray). AI 모델 개발 생애주기의 "분산 학습 스택" 절을 실전 수준으로 확장한 글입니다.
1부 — AI 라이브러리·프레임워크 생태계 지도
먼저 등장인물부터. 층위로 나누면 지형이 명확해집니다.
층위 대표 주자 한 줄 요약
──────────────── ──────────────────────────── ─────────────────────────────
기반 프레임워크 PyTorch 2.x 사실상 표준. torch.compile로 컴파일 가속
JAX 함수형+XLA. TPU·구글 계열 연구의 중심
모델·데이터 허브 HuggingFace Transformers 모델 정의의 공용어
Datasets / Tokenizers 데이터 로딩·토크나이즈 표준
파인튜닝 계층 PEFT (LoRA), TRL (SFT/DPO) 적은 자원으로 튜닝·정렬
Accelerate 단일↔분산 코드를 같게 만드는 추상화
분산 학습 엔진 PyTorch DDP/FSDP 프레임워크 내장 병렬화
DeepSpeed (ZeRO) 메모리 최적화의 대명사
Megatron-LM TP/PP 포함 초대형 사전학습의 표준
오케스트레이션 Slurm HPC 클러스터의 왕
Kubeflow / Ray 쿠버네티스·파이썬 네이티브 진영
서빙(참고) vLLM / SGLang / TensorRT-LLM 학습이 끝나면 이쪽 — 서빙 편 참조
선택 감각: 연구·파인튜닝은 PyTorch + HF 스택이 기본값, TPU나 대규모 병렬 연구는 JAX, 초대형 사전학습은 Megatron 계열, 그리고 그 사이의 모든 곳에 DeepSpeed와 FSDP가 있습니다.
2부 — 병렬화 전략: 무엇이 안 들어가는가부터 묻기
병렬화 선택은 "무엇이 GPU에 안 들어가는가"로 결정됩니다.
- DDP(Data Parallel) — 모델은 들어가는데 더 빨리 학습하고 싶다. 모델을 GPU마다 복제하고 배치를 나눠, 역전파 후 그래디언트를 all-reduce로 동기화합니다. 가장 단순하고 확장 효율도 좋아, 가능하면 항상 DDP가 1순위입니다.
- ZeRO / FSDP(Fully Sharded Data Parallel) — 모델(정확히는 파라미터+그래디언트+옵티마이저 상태)이 안 들어간다. 그 세 가지를 GPU들에 샤딩해 두고, 필요한 순간에만 모아 씁니다. DeepSpeed ZeRO의 단계(1: 옵티마이저, 2: +그래디언트, 3: +파라미터)와 PyTorch FSDP가 같은 아이디어의 두 구현입니다. 7B~70B 파인튜닝의 주력입니다.
- TP(Tensor Parallel) — 한 층조차 안 들어간다, 또는 지연이 중요하다. 행렬 곱 자체를 GPU들에 쪼갭니다. 통신이 잦아 노드 내(NVLink) 사용이 원칙입니다.
- PP(Pipeline Parallel) — 층들을 GPU 그룹에 나눠 조립 라인처럼 흘립니다. 마이크로배치로 파이프라인 거품을 줄입니다. 노드 경계를 넘는 분할에 적합합니다.
- 실전 초대형 학습은 이들을 3D 병렬(DP × TP × PP)로 조합하고, MoE 모델이면 EP(Expert Parallel)가 추가됩니다.
암기 공식: 들어가면 DDP → 안 들어가면 FSDP/ZeRO → 그래도 안 되면 TP·PP 추가. 그리고 어떤 조합이든 혼합 정밀도(bf16)와 그래디언트 체크포인팅은 기본 장착입니다.
3부 — torchrun: 모든 것의 공통 분모
Slurm이든 Kubeflow든, 바닥에서는 대부분 torchrun(PyTorch의 분산 런처)이 돕니다. 개념은 세 가지뿐입니다 — 전체 프로세스 수(world size), 내 순번(rank), 만남의 장소(rendezvous).
# 단일 노드 8 GPU
torchrun --nproc_per_node=8 train.py
# 멀티 노드 (예: 2노드 × 8GPU = world size 16)
# 모든 노드에서 같은 명령 실행, node_rank만 다르게
torchrun \
--nnodes=2 --nproc_per_node=8 --node_rank=0 \
--rdzv_backend=c10d --rdzv_endpoint=10.0.0.1:29500 \
train.py
학습 코드는 torch.distributed.init_process_group() 후 LOCAL_RANK 환경변수로 자기 GPU를 잡으면 됩니다. HF Accelerate나 Lightning을 쓰면 이 배선을 라이브러리가 대신합니다. 멀티노드의 성능 전제 조건 하나 — 노드 간은 이더넷이 아니라 RDMA(InfiniBand/RoCE) 여야 all-reduce가 병목이 되지 않고, NCCL이 그 위에서 통신을 담당합니다.
4부 — Slurm 사용 가이드: HPC의 왕
Slurm은 수십 년 HPC 역사에서 다듬어진 배치 스케줄러로, GPU 클러스터 학습의 사실상 표준입니다. 버전은 연.월 체계(24.11, 25.05 …)로 SchedMD가 관리합니다. 개념은 네 개면 충분합니다: 노드(기계) — 파티션(노드 묶음, 큐) — 잡(자원 요청+스크립트) — GRES(GPU 같은 일반 자원).
# 클러스터 상태 훑기
sinfo # 파티션·노드 상태
squeue --me # 내 잡 큐
scontrol show node node01 # 노드 상세
# 잡 던지기 3형제
sbatch job.sh # 배치 제출 (표준)
srun --pty bash # 인터랙티브 셸 (디버깅용)
salloc --gres=gpu:2 # 자원 선점 후 수동 실행
멀티노드 학습의 핵심은 sbatch 스크립트입니다. 2노드 × 8GPU torchrun 예시:
#!/bin/bash
#SBATCH --job-name=llm-train
#SBATCH --partition=gpu
#SBATCH --nodes=2 # 노드 2대
#SBATCH --ntasks-per-node=1 # 노드당 torchrun 1개 (프로세스는 torchrun이 8개 생성)
#SBATCH --gres=gpu:8 # 노드당 GPU 8장
#SBATCH --cpus-per-task=64
#SBATCH --time=48:00:00
#SBATCH --output=logs/%x-%j.out # %x=잡이름 %j=잡ID
# 랑데부 주소 = 첫 번째 노드
export MASTER_ADDR=$(scontrol show hostnames "$SLURM_JOB_NODELIST" | head -n 1)
export MASTER_PORT=29500
# 각 노드에서 torchrun 실행 — SLURM 변수로 배선 자동화
srun torchrun \
--nnodes=$SLURM_JOB_NUM_NODES \
--nproc_per_node=8 \
--node_rank=$SLURM_NODEID \
--rdzv_backend=c10d \
--rdzv_endpoint=$MASTER_ADDR:$MASTER_PORT \
train.py --config config.yaml
읽는 법: srun이 잡에 배정된 각 노드에서 한 번씩 torchrun을 실행하고, SLURM_NODEID가 노드 순번을, scontrol show hostnames가 마스터 주소를 자동으로 채웁니다. 이 패턴 하나가 Slurm 멀티노드 학습의 80%입니다. 나머지 20%는 운영 팁입니다 — 체크포인트는 --time 제한보다 자주 쓰고(선점·타임아웃 대비), --signal=SIGUSR1@120으로 종료 2분 전 신호를 받아 마지막 체크포인트를 남기고, 어레이 잡(--array)으로 하이퍼파라미터 스윕을 돌립니다.
5부 — Kubeflow 사용 가이드: 쿠버네티스 진영의 답
GPU 클러스터가 이미 쿠버네티스라면(GPU Operator로 세팅된 그 클러스터), 학습 잡도 쿠버네티스 리소스로 던지는 것이 자연스럽습니다. Kubeflow는 그 진영의 종합 플랫폼입니다.
구성요소 지도 — 전부 쓸 필요는 없습니다:
컴포넌트 역할 꼭 필요한가
────────────────── ─────────────────────────── ─────────────────
Training Operator 분산 학습 잡 CRD (핵심!) ★ 이것만으로 시작 가능
Pipelines ML 워크플로 DAG 오케스트레이션 파이프라인화 단계에서
Katib 하이퍼파라미터 튜닝·AutoML 필요할 때
Notebooks 클러스터 내 주피터 환경 편의 기능
KServe 모델 서빙 (별도 프로젝트화) 서빙 단계에서
핵심은 Training Operator입니다. PyTorchJob CRD 하나로 멀티노드 학습이 선언됩니다:
apiVersion: kubeflow.org/v1
kind: PyTorchJob
metadata:
name: llm-train
spec:
nprocPerNode: "8" # 노드(파드)당 프로세스 수 = GPU 수
pytorchReplicaSpecs:
Master:
replicas: 1
template:
spec:
containers:
- name: pytorch
image: my-registry/train:latest
command: ["torchrun", "train.py"]
resources:
limits:
nvidia.com/gpu: 8
Worker:
replicas: 3 # 마스터 1 + 워커 3 = 4노드
template:
spec:
containers:
- name: pytorch
image: my-registry/train:latest
command: ["torchrun", "train.py"]
resources:
limits:
nvidia.com/gpu: 8
Training Operator가 파드들을 만들고 MASTER_ADDR·WORLD_SIZE·RANK 환경변수를 자동 주입하므로, Slurm에서 손으로 하던 배선이 사라집니다. 잡 상태는 kubectl get pytorchjobs로 봅니다. 참고로 차세대 Kubeflow Trainer(v2) 는 프레임워크별 CRD들을 TrainJob 하나로 통합하는 방향으로 진화 중입니다 — 신규 도입이라면 문서에서 v2 지원 상태를 확인하고 시작하세요. 갱 스케줄링(전 노드가 동시에 확보되어야 시작)은 Volcano/Kueue 같은 스케줄러를 붙여 해결합니다.
6부 — 선택 기준: Slurm vs Kubeflow vs Ray
상황 추천
───────────────────────────────────────── ─────────────────────────
HPC 전통이 있는 조직, 베어메탈 GPU 팜 Slurm
이미 쿠버네티스로 모든 걸 운영 Kubeflow (Training Operator)
파이썬 코드 안에서 유연한 분산·서빙 통합 Ray (Train/Serve)
연구실 소규모, 노드 2~4대 그냥 torchrun + pdsh/tmux도 충분
클라우드 매니지드 선호 SageMaker/Vertex 등 (개념은 동일)
본질을 하나만 남기면 — 어느 플랫폼이든 바닥은 같습니다: torchrun(또는 그 등가물)이 프로세스를 띄우고, NCCL이 GPU 간 통신을 하고, 체크포인트가 장애를 견딥니다. 플랫폼은 "누가 노드를 빌려주고 환경변수를 채워주는가"의 차이일 뿐입니다. 그래서 한 플랫폼에서 멀티노드를 제대로 이해하면 나머지는 번역 문제가 됩니다.
마치며
GPU가 한 장에서 여러 장, 여러 노드로 늘 때 마주치는 결정을 순서대로 정리하면: 병렬화 전략(들어가면 DDP, 안 들어가면 FSDP/ZeRO, 그래도 안 되면 TP·PP) → 런처(torchrun) → 오케스트레이터(Slurm 또는 Kubeflow) → 운영(체크포인트·RDMA·갱 스케줄링). 이 스택 위에서 학습이 돌기 시작하면, 다음 병목은 데이터입니다 — 그 이야기는 LLM 학습 데이터 전처리 편에서 이어집니다.