4GPU Server
8GPU Server
HGX Server
2GPU Workstation
4GPU Workstation
나라장터 등록제품
Compact AI
10GPU Server
WEB Server
WAS Server
고성능 DB
타워형서버
나라장터 등록제품
1CPU Workstation
2CPU Workstation
나라장터 등록제품
Cloud
Open Source
NVIDIA
HCI
Backup
MLOps
HW/SW 유지보수
DDP | Torchrun | |
---|---|---|
작업 방식 | PyTorch에서 멀티 GPU/멀티 노드 학습을 지원하는 모듈 | DDP 실행을 편하게 해주는 런처 (launcher) |
역할 |
각 GPU에 모델 복제 → 각자 학습 → gradient를 통신으로 동기화 → 최종적으로 같은 모델이 학습됨 |
프로세스/ GPU 수만큼 자동으로 띄우고nproc_per_node ,
RANK ,
WORLD_SIZE ,
LOCAL_RANK
같은 분산 통신 환경변수를 세팅함
|
#실습 환경
OS : ubuntu 22.04
Nvidia driver : 535.171
Cuda : 12.1
cudnn : 8.8.0
설치 패키지 :
[ torch, torchvision, torchaudio, —index-url]
클라이언트 설정 파일 생성
패키지 | 용도 |
---|---|
torch | PyTorch 핵심 라이브러리, GPU/텐서/모델 학습 지원 |
torchvision | 컴퓨터 비전 유틸리티, 이미지 데이터셋/전처리/모델 제공 |
torchaudio | 오디오 처리 유틸리티, 오디오 데이터셋/변환 제공 |
--index-url | CUDA 버전에 맞는 공식 휠 저장소 지정, GPU 연산 가능 |
실습
1. sudo apt install python3.10-venv # Python 3.10용 가상환경 생성 패키지 설치
2. python3 -m venv ~/pt-venv # 홈 디렉토리에 Python 가상환경(pt-venv) 생성
3. source ~/pt-venv/bin/activate # 가상환경 활성화
4. pip install --upgrade pip setuptools wheel # pip, setuptools, wheel 최신 버전으로 업그레이드
5. pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu121 # PyTorch, TorchVision, Torchaudio 설치(CUDA 12.1)
설치 패키지 확인
#PyTorch 버전과 CUDA 사용 가능 여부 확인
python -c "import torch; print(\'Torch version:\', torch.**version**, \'CUDA available:\',
torch.cuda.is_available())"
#TorchVision 버전 확인
python -c "import torchvision; print(\'Torchvision version:\', torchvision.**version**)"
#Torchaudio 버전 확인
python -c "import torchaudio; print(\'Torchaudio version:\', torchaudio.**version**)"
간단한 gpu test 코드
gpu_test.py 파일 생성
import torch
#GPU 개수 확인
num_gpus = torch.cuda.device_count()
print("Available GPUs:", num_gpus)
#GPU 이름 확인
for i in range(num_gpus):
print(f"GPU {i}: {torch.cuda.get_device_name(i)}")
#간단한 연산 테스트
if num_gpus >= 2:
x = torch.randn(1000, 1000).cuda(0)
y = torch.randn(1000, 1000).cuda(1)
z = x.cuda(1) + y
print("Multi-GPU operation successful. Mean value:", z.mean().item())
else:
print("GPU가 2장 이상 필요합니다.")
#실행
- python gpu_test.py
DDP 멀티 GPU 테스트 코드
ddp_test.py 파일 생성 (2 GPU 기준)
import os
import torch
import torch.distributed as dist
import torch.multiprocessing as mp
from torch.nn import Linear
from torch.nn.parallel import DistributedDataParallel as DDP
from torch.utils.data import DataLoader, TensorDataset, DistributedSampler
#------------------
#NCCL 환경 변수 설정
#------------------
os.environ["NCCL_DEBUG"] = "WARN" # NCCL 경고 메시지 출력
os.environ["NCCL_IB_DISABLE"] = "1" # InfiniBand 비활성화
os.environ["NCCL_P2P_LEVEL"] = "NVL" # P2P 통신 레벨 설정
os.environ["CUDA_VISIBLE_DEVICES"] = "0,1" # 사용할 GPU 선택
#DDP 필수 환경 변수
os.environ[\'MASTER_ADDR\'] = \'127.0.0.1\'
os.environ[\'MASTER_PORT\'] = \'29500\'
#------------------
#DDP 초기화
#------------------
def setup(rank, world_size):
dist.init_process_group("nccl", rank=rank, world_size=world_size) # 프로세스 그룹 초기화
torch.cuda.set_device(rank) # 현재 프로세스를 특정 GPU에 매핑
#------------------
#DDP 종료
#------------------
def cleanup():
dist.destroy_process_group() # 프로세스 그룹 종료
#------------------
#학습 루프
#------------------
def train(rank, world_size):
setup(rank, world_size) # DDP 초기화
# 모델 정의 및 GPU 이동
model = Linear(10, 1).cuda(rank) # Linear 모델을 해당 GPU로 이동
ddp_model = DDP(model, device_ids=[rank]) # DDP로 래핑
# 데이터셋 및 DataLoader
dataset = TensorDataset(torch.randn(100, 10), torch.randn(100, 1)) # 랜덤 데이터 생성
sampler = DistributedSampler(dataset, num_replicas=world_size, rank=rank) # DDP용 샘플러
loader = DataLoader(dataset, batch_size=8, sampler=sampler) # DataLoader 생성
optimizer = torch.optim.SGD(ddp_model.parameters(), lr=0.01) # 옵티마이저 설정
# 학습 루프
for epoch in range(2):
running_loss = 0.0 # **추가: epoch별 누적 loss 초기화**
for batch_idx, (x, y) in enumerate(loader):
x, y = x.cuda(rank), y.cuda(rank) # 입력 데이터를 GPU로 이동
optimizer.zero_grad() # 기울기 초기화
loss = ((ddp_model(x) - y) ** 2).mean() # MSE Loss 계산
loss.backward() # 역전파
optimizer.step() # 가중치 업데이트
running_loss += loss.item() # **추가: 배치 loss 누적**
# 5배치마다 출력 (기존 출력문 수정)
print(f"[GPU {rank} | Epoch {epoch} | Batch {batch_idx}] Loss: {loss.item():.6f}")
# **기존: rank==0만 출력 → 이제 모든 GPU 출력**
# ------------------- 추가: epoch 끝난 뒤 평균 loss 출력 -------------------
avg_loss = running_loss / len(loader)
print(f"[GPU {rank} | Epoch {epoch}] Average Loss: {avg_loss:.6f}")
# **추가: 한 눈에 GPU별 학습 상태 확인 가능**
cleanup() # DDP 종료
#------------------
#메인 실행
#------------------
if __name__ == "__main__":
world_size = torch.cuda.device_count() # 사용 가능한 GPU 개수
mp.spawn(train, args=(world_size,), nprocs=world_size, join=True) # 멀티프로세스 학습 시작
#실행
torchrun --standalone --nproc_per_node=2 ddp_test.py
정상 출력 시 로그
(pt-venv) test@ubuntu:~$ python ddp_test.py
NCCL version 2.21.5+cuda12.4
[GPU 1 | Epoch 0 | Batch 0] Loss: 0.512695
[GPU 0 | Epoch 0 | Batch 0] Loss: 1.596358
[GPU 0 | Epoch 0 | Batch 1] Loss: 3.234331
[GPU 1 | Epoch 0 | Batch 1] Loss: 1.230204
[GPU 0 | Epoch 0 | Batch 2] Loss: 1.251617
[GPU 1 | Epoch 0 | Batch 2] Loss: 2.918502
[GPU 0 | Epoch 0 | Batch 3] Loss: 0.790517
[GPU 1 | Epoch 0 | Batch 3] Loss: 0.996800
[GPU 0 | Epoch 0 | Batch 4] Loss: 1.685620
[GPU 1 | Epoch 0 | Batch 4] Loss: 1.339857
[GPU 0 | Epoch 0 | Batch 5] Loss: 0.529339
[GPU 1 | Epoch 0 | Batch 5] Loss: 1.109558
[GPU 0 | Epoch 0 | Batch 6] Loss: 0.962902
[GPU 0 | Epoch 0] Average Loss: 1.435812
[GPU 1 | Epoch 0 | Batch 6] Loss: 0.309195
[GPU 1 | Epoch 0] Average Loss: 1.202401
[GPU 1 | Epoch 1 | Batch 0] Loss: 0.476248
[GPU 0 | Epoch 1 | Batch 0] Loss: 1.503265
[GPU 1 | Epoch 1 | Batch 1] Loss: 1.115403
[GPU 0 | Epoch 1 | Batch 1] Loss: 3.244143
[GPU 1 | Epoch 1 | Batch 2] Loss: 2.682358
[GPU 0 | Epoch 1 | Batch 2] Loss: 1.068382
[GPU 1 | Epoch 1 | Batch 3] Loss: 0.868395
[GPU 0 | Epoch 1 | Batch 3] Loss: 0.723319
[GPU 1 | Epoch 1 | Batch 4] Loss: 1.248225
[GPU 0 | Epoch 1 | Batch 4] Loss: 1.516317
[GPU 1 | Epoch 1 | Batch 5] Loss: 0.936232
[GPU 0 | Epoch 1 | Batch 5] Loss: 0.508594
[GPU 1 | Epoch 1 | Batch 6] Loss: 0.269102
[GPU 1 | Epoch 1] Average Loss: 1.085138
[GPU 0 | Epoch 1 | Batch 6] Loss: 0.833279
[GPU 0 | Epoch 1] Average Loss: 1.342471