오늘은 “데이터 병렬은 안 되는데… 그렇다고 GPU를 놀릴 순 없고…” 라는 현실적인 고민에서 출발했다.
하루 종일 CUDA 지형도를 탐사하며, GPU 간 통신부터 DDP 구조까지 파고든 실전 기록을 남긴다.

1. 문제의 시작: DataParallel이 먹통이었다
초기 목표는 단순했다.
“GPU 두 장 있으니 DataParallel로 성능 두 배!”
하지만 NVIDIA의 냉정한 진단 한 줄.
nvidia-smi topo -p2p a
결과는…
GPU0 ↔ GPU1 : NS (Not Supported)
즉, 두 GPU가 서로 직접 접근(P2P, peer-to-peer)을 지원하지 않는 구조였다.
메인보드의 PCIe 토폴로지 때문인데, 이건 소프트웨어로 바꿀 수 있는 문제가 아니다.
따라서 DataParallel은 비효율, 심지어 멈춤 현상까지 발생.
그래서 방향을 틀었다.
2. 결론: DistributedDataParallel(DDP)로 전환
P2P가 없어도 동작하는 GPU 분산 방식이 바로 DDP(DistributedDataParallel).
- DP는 메인 GPU로 모든 배치를 몰아주는 구조라 P2P가 필수
- DDP는 각 프로세스가 자신의 GPU에서 모델을 독립적으로 수행하고, NCCL로만 통신하여 P2P 필요 없음
즉,
P2P Not Supported 시스템 → DDP는 문제 없음
실제로 DP 보다 DDP에 대한 내용이 더 최신이었고 효과도 좋았다.
python main.py 에서도 2GPU DDP 실행
- spawn 기반으로 프로세스 n개 생성
- GPU 개수 따라 world_size 자동 설정
- torchrun 호출 없이도 same behavior
오늘은 이 기반 구조까지 완성했다.
4. main.py 개선: use_gpu 옵션 기반 자동 실행
오늘 작성한 핵심 구조:
def main(use_gpu):
if use_gpu == 1:
main_worker(world_size=1)
else:
mp.spawn(main_worker, nprocs=use_gpu, args=(world_size,))
이제 사용자는 GPU 몇 개 사용할지만 정하면 된다.
처음엔 gpu 1장과 2장의 성능 차이를 비교하는걸 생각했는데 그렇게 하지 않아도 되었다.
하지만 궁금증 때문에 비교햇고 2장이 조금 더 나았다.(35분 vs 32분)
5. GPU 사용 시간 추적 기능 추가
- 전체 main.py 실행 시간
- GPU 두 장이 동시에 사용된 시간
- 두 시간의 비율(%)
이걸 실시간 모니터링하는 GPUUsageTracker 클래스도 추가.
학습 끝에는 이런 리포트가 뜨도록 했다:
⏱️ 실행 시간 요약
• main.py 전체 실행 시간 : 0시간 32분 12초
• GPU 2대 동시 사용 시간 : 0시간 14분 55초
• 동시 사용 비율 : 46.32%
학습 병렬성 체크의 아주 훌륭한 지표.
6. GPU 메모리 출력 포맷 개선
기존 출력:
GPU 0: 100% 2340/97887MB
개선 후:
GPU 0: 2340/97887MB (2.23%)
GPU 1: 2340/97887MB (2.23%)
훨씬 직관적이다.
7. 결과 분석: DDP는 잘 돌아갔다
로그를 보면 DDP가 정상적으로 두 GPU를 활용하고 있음:
GPU 0: 2340/97887MB (2.23%)
GPU 1: 2340/97887MB (2.23%)
→ 두 GPU 모두 모델 shard를 가지고 forward/backward 수행한 흔적
→ NCCL은 정상 작동
→ 병렬학습 ✔︎
9. 오늘의 전체 성과
| GPU 토폴로지 분석 | P2P 불가 → DataParallel 비효율 원인 확인 |
| 분산 학습 | spawn 기반 DDP 2GPU 지원 완료 |
| 실행 UX | python main.py –use-gpu=2 구현 |
| GPU 모니터링 | 실시간 메모리 사용률 + 동시 사용 시간 |
| 출력 로그 정리 | 불필요한 중복 출력 제거 |
'<ML>' 카테고리의 다른 글
| Kubernetes + PyTorch DDP에서 NCCL ALLREDUCE 타임아웃 해결기 (0) | 2025.11.13 |
|---|---|
| CatboostEncoder (0) | 2023.01.30 |
| SOM 자기조직화지도 (0) | 2023.01.02 |