dev.Log
ML Docker 이미지 크기 줄이는 법 본문
PyTorch/Transformers 이미지가 수 GB 되는 이유와 실전 다이어트 전략
ML 서비스(특히 PyTorch/Transformers/Whisper/LLM)를 Docker로 패키징하면 이미지가 쉽게 수 GB가 된다.
쿠버네티스 배포가 느려지고, 레지스트리 저장비가 늘고, CI 빌드 시간도 폭발한다.
이 글은 “이미지 크기가 커지는 원인”을 짚고, 실제로 효과가 큰 줄이는 방법을 우선순위대로 정리한다.
1. 왜 ML 이미지는 기본이 수 GB인가?
가장 흔한 원인은 다음 조합이다.
- base 이미지가 큼: nvidia/cuda:*, pytorch/pytorch:*
- 빌드 도구 포함: gcc, make, cmake, git
- Python 휠이 GPU/BLAS 포함: torch, xformers, onnxruntime-gpu
- 캐시가 남음: pip cache, apt lists, conda pkgs
- 모델 파일을 이미지에 포함: *.pt, *.safetensors, *.onnx
즉, “학습/빌드 환경”과 “실행 환경”을 한 이미지에 섞으면 거의 무조건 커진다.
2. 가장 효과 좋은 6가지 전략 (우선순위)
전략 A) 멀티스테이지 빌드로 “빌드 도구” 제거
컴파일이 필요한 패키지(예: 일부 audio/lib, custom ops)가 있을 때 특히 효과가 크다.
- 1단계(builder): gcc, cmake, git 포함해서 빌드
- 2단계(runtime): 결과물(venv/site-packages)만 복사
핵심은 “런타임 이미지에 build-essential을 남기지 않는다”다.
전략 B) base 이미지를 목적에 맞게 최소화
대부분 아래 원칙이 먹힌다.
- CPU 서비스: python:3.x-slim 또는 debian:bookworm-slim + python
- GPU 추론: nvidia/cuda:<ver>-runtime-ubuntuXX.XX (devel 말고 runtime)
- PyTorch GPU: 필요하면 pytorch/pytorch 대신 CUDA runtime 기반 + pip로 torch 설치
주의:
- *-devel 이미지는 개발 헤더/컴파일러까지 포함해서 크기가 확 커진다.
- “실행만” 하면 runtime이 정답이다.
전략 C) pip/apt 캐시를 “한 레이어에서” 없애기
Docker는 레이어 단위로 저장되므로, 설치와 삭제를 같은 RUN에서 해야 의미가 있다.
- apt:
- rm -rf /var/lib/apt/lists/*
- pip:
- pip install --no-cache-dir ...
- conda:
- conda clean -afy (하지만 운영에선 conda 자체를 피하는 게 더 큼)
전략 D) 모델 파일을 이미지에 넣지 말고 “런타임 다운로드/볼륨”으로 분리
이미지에 모델(수백 MB~수 GB)을 COPY하면 이미지가 끝없이 커지고, 배포/롤백이 느려진다.
권장:
- 모델은 S3/MinIO/NFS/Artifact repo에서 내려받기
- Kubernetes면 PVC로 마운트
- 또는 initContainer에서 모델 다운로드 후 공유 볼륨 사용
모델이 자주 바뀌는 경우 특히 효과적이다.
전략 E) 의존성을 최소화하고 “불필요한 GPU 패키지”를 빼기
예를 들어 CPU만 쓰는데도 onnxruntime-gpu, cupy, tensorflow 같은 게 들어가면 크기가 폭발한다.
체크리스트:
- torch가 CPU면 --index-url https://download.pytorch.org/whl/cpu 사용
- CUDA가 필요 없으면 GPU 관련 휠 제거
- transformers는 최소 extras만 사용(예: transformers[torch] 남발 금지)
전략 F) 최종 이미지에서 테스트/툴/소스 제거
실무에서 흔히 남는 것들:
- tests/, .git/, docs/, 예제 데이터
- 빌드 로그/캐시
- 필요 없는 locale, tzdata 등
.dockerignore로 원천 차단하는 게 가장 확실하다.
3. CPU용 “슬림” 예시 Dockerfile (실전 템플릿)
핵심: slim + venv + no-cache + apt list cleanup
이 형태로만 바꿔도 “불필요한 캐시” 때문에 커지던 이미지가 크게 줄어드는 경우가 많다.
4. GPU 추론용 “runtime-only” 예시 Dockerfile
핵심: nvidia/cuda:*runtime* + pip 캐시 제거 + 필요 라이브러리 최소화
주의:
- torch GPU 휠은 CUDA 버전 매칭이 중요하다.
- base CUDA 버전과 torch wheel의 CUDA 호환을 맞추지 않으면 런타임에서 import가 깨진다.
5. 이미지 크기를 실제로 줄였는지 확인하는 방법
(1) 전체 크기
(2) 레이어별로 뭐가 큰지
여기서 큰 레이어가:
- apt 설치
- pip 설치
- 모델 COPY
인지 바로 보인다.
(3) 컨테이너 내부에서 큰 디렉토리 찾기
6. 자주 하는 실수
- RUN apt-get update를 따로 하고 cleanup을 다음 레이어에서 함
→ 레이어에 apt list가 그대로 남는다. - pip 설치 시 캐시 남김
→ --no-cache-dir 필수 - 모델을 이미지에 COPY
→ 모델 업데이트마다 이미지 재배포/캐시 무효화 - devel 이미지를 런타임에 사용
→ 실행에 필요 없는 gcc/cmake까지 포함
결론: “빌드 환경”과 “실행 환경”을 분리하면 대부분 해결된다
ML Docker 이미지 다이어트의 핵심은 하나다.
- 빌드 도구는 builder에만
- 실행에는 runtime만
- 캐시는 설치 단계에서 없애기
- 모델은 이미지 밖으로
이 4가지만 지켜도 체감상 절반 이상 줄어드는 경우가 많다.
'인공지능' 카테고리의 다른 글
| systemd에서 conda 서비스가 안 뜨는 이유 (0) | 2026.01.02 |
|---|---|
| CUDA + PyTorch에서 pip vs conda 차이 (0) | 2026.01.02 |
| 운영 서버에서 conda 쓰면 실제로 터지는 사례들 (0) | 2026.01.02 |
| conda vs venv vs Docker (0) | 2026.01.02 |
| Whisper vs NeMo (EPD) (0) | 2025.12.30 |