,

GPU 분산 학습 완전 정복 — 4가지 방식 요약 + 5단계 학습 로드맵

“GPU 여러 개 꽂으면 자동으로 빨라진다”는 착각에서 출발해, 실제로 무엇을 공부하면 분산 학습을 다룰 수 있는지까지 정리한 학습 로드맵입니다.


1. 핵심 전제: GPU는 도구, 분산은 설계

GPU를 늘린다고 자동으로 분산되지 않습니다. 실행되려면 아래 네 가지가 모두 갖춰져야 합니다.

GPU 여러 개
    ↓
분산 전략 선택  (Data / Model / Pipeline / Tensor Parallel)
    ↓
프레임워크 지원 (PyTorch DDP / DeepSpeed / FSDP / Accelerate)
    ↓
모델 구조 지원  (레이어 분할 가능 여부)
    ↓
실행

거대 AI 회사들의 경쟁력도 “GPU 수” 자체보다 “GPU 수천 장을 얼마나 효율적으로 묶는가”에 훨씬 가깝습니다.


2. 4가지 분산 방식 요약

① Data Parallel — 가장 흔함, 시작점

GPU1 → 배치 1~16
GPU2 → 배치 17~32
GPU3 → 배치 33~48
GPU4 → 배치 49~64

각 GPU: 동일한 모델 복사본 + 다른 데이터
→ gradient 합산 후 동기화
내용
장점구현 쉬움, 대부분 모델 지원, LoRA 파인튜닝에 흔함
단점GPU마다 모델 복사본 → 24GB + 24GB여도 실제 가용 모델 크기 ≈ 24GB
쓰는 곳이미지 분류, LoRA, 일반 파인튜닝

② Model Parallel — 큰 모델을 나눠 담기

GPU1: Layer 1 ~ 30
GPU2: Layer 31 ~ 60

→ 24GB + 24GB ≈ 더 큰 모델 가능
내용
장점VRAM 합산 효과 — 실제로 더 큰 모델을 올릴 수 있음
단점GPU 간 통신이 많고, 한 GPU가 쉬는 동안 다른 GPU가 대기 (bubble 문제)
쓰는 곳70B+ 모델, 단일 GPU에 안 올라가는 모델

③ Pipeline Parallel — 공장 생산라인

입력 → GPU1(인코더) → GPU2(중간) → GPU3(디코더) → GPU4(출력)

micro-batch를 연속으로 흘려서 GPU 유휴 시간을 줄임
내용
장점Model Parallel의 bubble 문제를 micro-batch로 완화
단점설정 복잡, 모델을 균등하게 나누기 어려움
쓰는 곳GPT-3/4급 사전학습, DeepSpeed PipelineEngine

④ Tensor Parallel — 행렬 자체를 쪼갬

거대한 Weight Matrix
    ↓
GPU1: 행렬 왼쪽 절반
GPU2: 행렬 오른쪽 절반

→ 각 GPU가 부분 계산 후 결과 합산
내용
장점대형 Attention/FFN 레이어를 여러 GPU에 분산 가능
단점GPU 간 All-Reduce 통신이 매 레이어마다 발생 → NVLink 없으면 병목
쓰는 곳GPT 계열, Llama, DeepSeek 사전학습

5가지 핵심 기법 한눈에 보기

기법분류핵심 아이디어대표 API
DDP (DistributedDataParallel)데이터 병렬동일 모델을 각 GPU에 복사, 미니배치를 나눠 처리한 뒤 gradient All-Reducetorch.nn.parallel.DistributedDataParallel
FSDP (Fully Sharded DP)데이터+메모리 병렬모델 가중치·gradient·optimizer state를 GPU 간 완전 분산. DDP 대비 메모리 대폭 절감torch.distributed.fsdp.FullyShardedDataParallel
DeepSpeed ZeRO메모리 최적화ZeRO-1(optimizer)/ZeRO-2(+gradient)/ZeRO-3(+parameter) 단계별 메모리 분산. CPU/NVMe Offload 지원deepspeed.initialize()
Tensor Parallel모델 병렬레이어 내 가중치 행렬을 열/행 단위로 GPU에 분할. 대형 Attention·FFN 레이어에 효과적Megatron-LM, torch.distributed.tensor
Pipeline Parallel모델 병렬레이어를 스테이지별로 GPU에 분할. 마이크로배치로 버블 최소화GPipe, PipeDream, Megatron PP

실제 프레임워크는 여러 개를 조합

DeepSpeed  = Data Parallel + Tensor Parallel + Pipeline Parallel + Memory Offload (ZeRO)
FSDP       = 모델 가중치·gradient·optimizer state 자체를 GPU 간 분산 (Full Sharding)
Accelerate = 위 전략들을 코드 최소 변경으로 사용하는 래퍼

3. 주요 제약 사항

항목영향
GPU VRAM 크기가 다름작은 GPU 기준으로 제한됨 (4090 24GB + 3060 12GB → 사실상 12GB 기준)
GPU 연결 속도PCIe 4.0 × 16: ~32GB/s, NVLink 4.0: ~900GB/s — 통신 비중 높을수록 차이 큼
NVLink 유무Tensor Parallel / Model Parallel 효율에 직결. PCIe만이면 Data Parallel이 낫다
모델 구조Attention 구조가 독특한 모델은 Tensor Parallel 적용 어려움
배치 크기너무 작으면 통신 오버헤드 > 연산 이득 → 효율 역전
모델분산 난이도비고
Stable Diffusion낮음xformers + Data Parallel이면 충분
FLUX중간큰 모델이라 Model Parallel 필요할 수 있음
Llama 7B~70B낮음~중간llama.cpp, vLLM, Accelerate 지원 풍부
GPT류중간Tensor Parallel 고려 필요
비디오 생성높음시퀀스 길이 + 3D 텐서로 VRAM 폭발
멀티모달높음인코더/디코더가 다른 모달리티라 분산 설계 어려움

4. 학습 로드맵 — 5단계

목표: 분산 학습의 기본 패턴 숙지 + 속도 체감. 홈랩(LoRA, 캐릭터 영상, 파인튜닝) 기준으로 현실적인 순서입니다.

1단계 — PyTorch DDP: 분산의 기초 문법

기간 목표: 2~3주

모든 분산 학습의 출발점입니다. GPU 1개짜리 학습 코드를 DDP로 바꿔서 2개 GPU에서 돌려보고 속도를 측정합니다.

import torch
import torch.distributed as dist
from torch.nn.parallel import DistributedDataParallel as DDP
from torch.utils.data.distributed import DistributedSampler

def setup(rank, world_size):
    dist.init_process_group("nccl", rank=rank, world_size=world_size)
    torch.cuda.set_device(rank)

def cleanup():
    dist.destroy_process_group()

def train(rank, world_size):
    setup(rank, world_size)

    model = MyModel().to(rank)
    model = DDP(model, device_ids=[rank])          # ← 이 한 줄이 핵심

    sampler = DistributedSampler(dataset, num_replicas=world_size, rank=rank)
    loader  = DataLoader(dataset, sampler=sampler, batch_size=32)

    for batch in loader:
        loss = model(batch)
        loss.backward()
        optimizer.step()

    cleanup()

# 실행: torchrun --nproc_per_node=2 train.py

체크포인트:

  • GPU 1개 vs 2개 학습 시간 비교 기록
  • gradient 동기화가 언제 일어나는지 이해
  • DistributedSampler가 왜 필요한지 설명 가능

2단계 — Hugging Face Accelerate: 코드 변경 최소화

기간 목표: 2~3주

DDP를 직접 짜는 대신, Accelerate가 내부에서 처리하게 합니다. LoRA 파인튜닝에서 가장 많이 쓰이는 패턴입니다.

from accelerate import Accelerator

accelerator = Accelerator()                         # ← 환경 자동 감지

model, optimizer, loader = accelerator.prepare(
    model, optimizer, train_loader
)

for batch in loader:
    with accelerator.accumulate(model):             # gradient accumulation
        loss = model(**batch).loss
        accelerator.backward(loss)
        optimizer.step()
        optimizer.zero_grad()

# 실행: accelerate launch --num_processes 2 train.py
# 또는: accelerate config → 설정 파일로 관리

체크포인트:

  • Llama 또는 SD 모델을 Accelerate로 LoRA 파인튜닝 실행
  • gradient accumulation steps를 바꿔가며 throughput 측정
  • single GPU / multi GPU 설정 전환 자유롭게 가능

3단계 — DeepSpeed ZeRO: VRAM 절약의 핵심

기간 목표: 3~4주

ZeRO(Zero Redundancy Optimizer)는 모델 가중치·gradient·optimizer state를 GPU 간에 분산해서 저장합니다. 24GB GPU에서 70B 모델을 파인튜닝하는 것이 가능해지는 마법입니다.

// deepspeed_config.json
{
  "zero_optimization": {
    "stage": 3,                           // 0: 없음, 1: optimizer, 2: +gradient, 3: +weights
    "offload_optimizer": { "device": "cpu" },   // CPU RAM으로 offload (VRAM 절약)
    "offload_param":     { "device": "cpu" }
  },
  "bf16": { "enabled": true },
  "train_micro_batch_size_per_gpu": 1,
  "gradient_accumulation_steps": 8
}
# Accelerate + DeepSpeed 조합 (가장 실용적)
accelerate launch   --config_file deepspeed_config.json   --num_processes 2   finetune.py

ZeRO Stage 비교:

Stage분산 대상VRAM 절약통신 비용
ZeRO-1Optimizer state낮음낮음
ZeRO-2+ Gradient중간중간
ZeRO-3+ 모델 가중치높음높음
ZeRO-3 + CPU offload+ CPU RAM 활용매우 높음속도 저하 있음

체크포인트:

  • ZeRO Stage 1/2/3 각각 실행 후 VRAM 사용량 비교
  • CPU offload 켰을 때 속도 차이 체감
  • 단일 GPU에서 올라가지 않는 모델을 multi GPU + ZeRO로 실행

4단계 — FSDP: PyTorch 공식 분산 표준

기간 목표: 3~4주

FSDP(Fully Sharded Data Parallel)는 PyTorch가 공식적으로 제공하는 ZeRO-3 구현입니다. Meta의 Llama 파인튜닝 공식 코드가 FSDP를 씁니다.

from torch.distributed.fsdp import FullyShardedDataParallel as FSDP
from torch.distributed.fsdp.wrap import transformer_auto_wrap_policy

# Transformer 레이어 단위로 자동 분산
wrap_policy = transformer_auto_wrap_policy(
    transformer_layer_cls={LlamaDecoderLayer}   # 모델의 레이어 클래스
)

model = FSDP(
    model,
    auto_wrap_policy=wrap_policy,
    device_id=torch.cuda.current_device(),
    sharding_strategy=ShardingStrategy.FULL_SHARD,  # ZeRO-3 상당
)

체크포인트:

  • Llama 7B를 FSDP로 파인튜닝 실행
  • checkpoint 저장/로드 (FSDP는 별도 처리 필요)
  • DeepSpeed ZeRO-3 vs FSDP 속도 비교

5단계 — Ray + Kubernetes: 머신 경계를 넘기

기간 목표: 4~6주 (장기)

단일 머신의 GPU를 넘어, 집 PC + 클라우드 GPU + 여러 머신을 하나의 학습 클러스터로 묶는 단계입니다.

import ray
from ray import train
from ray.train.torch import TorchTrainer
from ray.train import ScalingConfig

def train_func():
    # 기존 학습 코드 그대로
    model = MyModel()
    trainer = Trainer(model)
    trainer.train()

trainer = TorchTrainer(
    train_func,
    scaling_config=ScalingConfig(
        num_workers=4,       # 4개 프로세스
        use_gpu=True,
        resources_per_worker={"GPU": 1}
    )
)
trainer.fit()
# Kubernetes에서 Ray 클러스터 (홈랩 최종 형태)
# ray-cluster.yaml
apiVersion: ray.io/v1
kind: RayCluster
spec:
  headGroupSpec:
    replicas: 1
    rayStartParams: { num-gpus: "1" }
  workerGroupSpecs:
    - replicas: 3
      rayStartParams: { num-gpus: "1" }

체크포인트:

  • 로컬 Ray 클러스터에서 분산 학습 실행
  • 노드 추가/제거 시 학습 자동 재조정 확인
  • 집 PC + 클라우드 1대를 Ray로 연결해서 학습

5. 미니 목표 체크리스트

각 단계에서 “이걸 했으면 다음으로 가도 됩니다”의 기준입니다.

단계최소 확인 목표보너스 목표
1단계 DDPGPU 2개로 학습 실행 + 시간 측정GPU 1개 대비 속도 향상 그래프 그리기
2단계 AccelerateLoRA 파인튜닝을 Accelerate로 실행config만 바꿔서 single/multi GPU 전환
3단계 DeepSpeedZeRO-3로 단일 GPU에 안 올라가는 모델 실행Stage별 VRAM 비교표 작성
4단계 FSDPLlama 7B FSDP 파인튜닝 체크포인트 저장DeepSpeed vs FSDP 처리량 비교
5단계 Ray로컬 Ray 클러스터로 분산 실행Kubernetes RayCluster 매니페스트 작성

6. 홈랩 맥락에서의 현실적 조언

상황추천 전략
GPU 1개 (24GB)ZeRO-3 + CPU offload로 70B 모델 LoRA 가능
GPU 2개 동급 (24GB × 2)Data Parallel + ZeRO-2가 가장 효율적
GPU 2개 다른 크기작은 GPU 기준 제한 → Data Parallel이 그나마 낫지만 효율↓
NVLink 없는 멀티 GPUTensor/Model Parallel 피하기, Data Parallel 또는 ZeRO로
캐릭터 LoRA / SD 파인튜닝2단계(Accelerate)에서 이미 충분
장기 — 집 + 클라우드 혼합5단계(Ray) 이후

핵심 기억법: 모델이 GPU에 안 올라가면 ZeRO-3, 더 빠르게 하고 싶으면 Data Parallel, GPU가 여러 머신에 퍼져 있으면 Ray. 이 세 줄이 홈랩 기준 99%의 케이스를 커버합니다.

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다