ML 모델 가중치 관리 및 배포 패턴

코드와 모델을 분리하는 실무 아키텍처

딥러닝 모델 가중치 파일을 서버에 배포하고 관리하는 실무 패턴을 정리한다. Git LFS, 클라우드 스토리지, DVC 등 전송 방법부터 서비스 규모별 아키텍처까지 다룬다.

Engineering
Deep Learning
Machine Learning
저자

Kwangmin Kim

공개

2026년 03월 26일

1 문제: 모델 가중치는 왜 별도 관리가 필요한가

딥러닝 모델을 학습하면 가중치(weight) 파일이 생성된다. .pt, .pth, .h5, .onnx 등의 형식이며, 용량은 수백 MB에서 수 GB에 이른다. 이 파일은 일반 코드와 근본적으로 성격이 다르다.

속성 소스 코드 모델 가중치
용량 수 KB ~ 수 MB 수백 MB ~ 수 GB
변경 빈도 커밋 단위 학습 완료 시
버전 관리 Git (diff 가능) 바이너리 (diff 불가)
배포 대상 모든 개발 환경 서빙/추론 환경만

Git 저장소에 가중치를 직접 넣으면 clone 속도가 급격히 느려지고, .git 히스토리에 대용량 바이너리가 누적되어 저장소 크기가 비정상적으로 커진다. 따라서 코드와 모델 가중치는 반드시 분리하여 관리한다.


2 가중치 파일 전송 방법

모델 가중치를 서버에 올리는 방법은 크게 4가지이다. 각 방법의 특성과 적합한 상황이 다르다.

2.1 Git LFS (Git Large File Storage)

Git 저장소에 대용량 파일을 포함시키되, 실제 파일은 별도 스토리지에 저장하는 방식이다.

# 설치 후 대용량 파일 트래킹
git lfs install
git lfs track "*.pt" "*.pth" "*.h5" "*.onnx"
git add .gitattributes
git commit -m "track model weights with LFS"
  • Git 워크플로를 그대로 유지할 수 있다는 장점이 있다
  • GitHub 무료 용량 제한이 1GB이므로, 대형 모델에는 부적합하다
  • 팀 규모가 작고 모델 크기가 수백 MB 이하일 때 적합하다

2.2 클라우드 오브젝트 스토리지

실무에서 가장 많이 사용하는 방식이다. Azure Blob Storage, AWS S3, GCS 등 클라우드 오브젝트 스토리지에 모델을 업로드하고, 서버에서 필요할 때 다운로드한다.

# GCS 예시
gsutil cp model_weights.pt gs://your-bucket/models/
# VM에서 다운로드
gsutil cp gs://your-bucket/models/model_weights.pt ./models/

# AWS S3 예시
aws s3 cp model_weights.pt s3://your-bucket/models/
  • 용량 제한이 사실상 없다
  • 팀 공유가 쉽고, 버전 관리(versioning) 기능을 제공한다
  • CI/CD 파이프라인과의 통합이 자연스럽다

2.3 SCP / rsync (직접 전송)

온프레미스 환경에서 빠르게 파일을 전송할 때 사용한다.

# SCP: 단순 복사
scp model_weights.pt user@vm-ip:/path/to/models/

# rsync: 중단 시 이어받기 가능, 변경분만 전송
rsync -avz --progress model_weights.pt user@vm-ip:/path/to/models/
  • 별도 인프라 없이 바로 사용할 수 있다
  • 수동 작업이라 자동화에 한계가 있다
  • 프로토타이핑이나 일회성 전송에 적합하다

2.4 DVC (Data Version Control)

모델과 데이터의 버전 관리가 함께 필요할 때 사용한다. Git과 유사한 인터페이스로 대용량 파일을 관리한다.

pip install dvc
dvc init
dvc add models/weights.pt
dvc remote add -d storage s3://your-bucket/dvc
dvc push
  • Git 커밋과 모델 버전을 1:1로 매핑할 수 있다
  • 실험 재현성(reproducibility)이 중요한 연구 환경에 적합하다
  • 초기 설정이 다소 복잡하다

2.5 방법 선택 기준

상황 추천 방법
소규모 팀, 모델 < 500MB Git LFS
실무 서비스, 팀 공유 필요 클라우드 스토리지 (S3, Blob, GCS)
온프레미스, 일회성 전송 SCP / rsync
실험 재현성, 모델+데이터 버전 관리 DVC

일반적으로 클라우드 오브젝트 스토리지가 가장 범용적인 선택이다. .gitignore에 가중치 파일을 추가하고, 코드에서 스토리지로부터 자동 다운로드하는 패턴이 표준이다.


3 Azure Blob Storage 기반 모델 관리

주기적으로 업데이트되는 모델일수록 클라우드 오브젝트 스토리지가 적합하다. Azure 환경을 예시로 설명하지만, S3나 GCS에서도 동일한 패턴이 적용된다.

3.1 왜 Blob Storage인가

  • 버전 관리: Blob Storage의 versioning을 활성화하면 모델 업데이트 이력이 자동 보존된다
  • 자동화 용이: 학습 파이프라인 끝에 업로드 스크립트 한 줄이면 된다
  • pull 방식: VM이 시작 시 또는 스케줄에 맞춰 최신 모델을 가져온다

3.2 전체 흐름

[학습 서버/파이프라인]
    |  학습 완료 -> 가중치 업로드
    v
[Azure Blob Storage]  <- 버전 관리 ON
    |
    v
[서빙 VM]  <- 최신 모델 pull (스케줄 or 이벤트 트리거)

3.3 구현 예시

from azure.storage.blob import BlobServiceClient

blob_client = BlobServiceClient.from_connection_string(conn_str)
container = blob_client.get_container_client("models")

# 학습 후 업로드
with open("model_v2.pt", "rb") as f:
    container.upload_blob("latest/model.pt", f, overwrite=True)

# 서빙 VM에서 다운로드
blob = container.get_blob_client("latest/model.pt")
with open("model.pt", "wb") as f:
    f.write(blob.download_blob().readall())

3.4 고도화 옵션

모델 관리 요구사항이 복잡해지면 아래와 같이 확장한다.

요구사항 방법
업데이트 시 VM에 자동 알림 Event Grid + Azure Functions
A/B 테스트, 롤백 latest/, stable/, canary/ 폴더 분리
모델 메타데이터 관리 Azure ML Model Registry
CI/CD 통합 Azure DevOps Pipeline에서 업로드/배포 자동화

하지만 이런 고도화는 트래픽과 요구사항이 생긴 뒤에 고민할 문제이다. 처음부터 이렇게 설계할 필요는 없다.


4 코드와 모델의 역할 분리: Poetry + Blob Storage

“Poetry로 모델을 설치할 수 있지 않나?”라는 의문이 들 수 있다. Poetry는 Python 패키지(코드) 의존성 관리 도구이지, 대용량 바이너리 파일 배포용이 아니다.

역할 도구 대상
코드 배포 Poetry (pip, conda 등) Python 라이브러리, 소스 코드
모델 배포 Blob Storage (S3, GCS 등) 가중치 파일 (.pt, .h5 등)

PyPI 패키지 최대 용량은 약 60MB이므로, 수백 MB 이상인 모델 가중치는 올릴 수 없다.

앞서 코드와 모델의 역할이 다름을 확인했으므로, 이제 이 분리를 프로젝트 구조에 반영하는 방법을 살펴본다.

4.1 프로젝트 디렉토리 구조

your_project/
├── pyproject.toml          # Poetry 프로젝트 설정
├── scripts/
│   └── upload_model.py     # 로컬에서 학습 후 Blob에 업로드
├── your_package/
│   └── model_loader.py     # 서버에서 Blob에서 모델 다운로드
└── models/                 # .gitignore에 추가 (가중치 파일)

별도 프로젝트 두 개를 만드는 것이 아니라, 같은 프로젝트에 업로드/다운로드 스크립트를 함께 두는 구조이다.

4.2 실행 흐름

[로컬 개발 PC]                        [서버 VM]

1. 모델 학습                           1. poetry install
2. python scripts/upload_model.py     2. 앱 실행 -> model_loader.py가
   -> Blob Storage에 업로드                Blob에서 자동 다운로드

4.3 첫 실행 시 자동 다운로드 패턴

HuggingFace의 transformers 라이브러리도 이 방식이다. pip/poetry로 코드만 설치하고, 모델 가중치는 첫 실행 시 Hub에서 다운로드한다.

import os
from azure.storage.blob import BlobServiceClient

MODEL_PATH = "models/weights.pt"

def ensure_model():
    """모델이 로컬에 없으면 Blob Storage에서 다운로드한다."""
    if not os.path.exists(MODEL_PATH):
        print("Downloading model weights...")
        blob = container.get_blob_client("latest/weights.pt")
        with open(MODEL_PATH, "wb") as f:
            f.write(blob.download_blob().readall())
    return MODEL_PATH

poetry install 후 코드를 실행하면 모델이 없을 때 자동으로 받아오므로, 사용자 입장에서는 한 번에 세팅되는 느낌이다.


5 서비스 규모별 모델 서빙 아키텍처

앞서 모델을 저장하고 가져오는 방법을 다루었다. 이제 실제 서비스에서 이 패턴을 어떻게 확장하는지 규모별로 살펴본다.

5.1 소규모 / 초기 서비스

앞서 설명한 패턴을 그대로 사용한다.

VM 시작 -> Blob에서 모델 다운로드 -> FastAPI 등으로 서빙

대부분의 서비스가 이 구조에서 시작하며, 이 단계에서 충분히 동작한다.

5.2 규모가 커질 때

문제 해결
모델 업데이트 시 서버 재시작이 번거로움 모델 버전 관리 + 핫 리로드
트래픽 증가 여러 VM에 로드밸런싱
모델이 여러 개 Azure ML, MLflow 같은 모델 레지스트리
GPU 서빙 필요 Triton Inference Server, TorchServe

핵심은 처음부터 복잡한 아키텍처를 설계하지 않는 것이다. Blob Storage + 다운로드 스크립트 패턴으로 시작하고, 병목이 발생하는 지점부터 개선한다.


6 온프레미스 환경에서의 적용

클라우드 VM이 아닌 사내 GPU 서버에서도 동일한 패턴이 적용된다. 실제로 온프레미스 서버에 Azure Blob Storage를 마운트하여 로컬 디렉토리처럼 사용하는 경우도 있다.

# blobfuse2로 Blob Storage를 로컬 디렉토리에 마운트하는 예시
# 마운트된 상태에서는 일반 파일 시스템처럼 접근 가능
ls /BiO/home/user/az_storage/models/

이 경우 별도의 다운로드 스크립트 없이, 마운트된 경로에서 직접 모델을 로드할 수 있다. 다만 네트워크 I/O가 발생하므로, 추론 성능이 중요하면 로컬 디스크에 복사한 뒤 사용하는 것이 좋다.


7 요약

[코드]                          [모델 가중치]
  |                                 |
  v                                 v
Poetry / pip install           Blob Storage / S3 / GCS
  |                                 |
  v                                 v
소스 코드 + 라이브러리          .pt / .h5 / .onnx 파일
  |                                 |
  └─────────── 서버에서 합류 ────────┘
                  |
                  v
            모델 서빙 (FastAPI 등)
  • 코드와 모델 가중치는 역할이 다르므로 배포 경로를 분리한다
  • 가중치 전송은 클라우드 오브젝트 스토리지가 가장 범용적이다
  • 프로젝트 내에 업로드/다운로드 스크립트를 함께 두고, 첫 실행 시 자동 다운로드 패턴을 사용한다
  • 소규모로 시작하고 병목이 생기면 확장한다

Subscribe

Enjoy this blog? Get notified of new posts by email: