모델이 완성되면 끝인가?

모델 학습이 완료되면 높은 정확도의 체크포인트 파일이 하나 남는다. 그런데 이 파일 자체로는 아무런 비즈니스 가치를 만들어내지 못한다. 사용자의 요청을 받아 예측 결과를 반환하는 서빙 시스템이 갖춰져야 비로소 모델이 의미를 가지게 되는 것이다.

모델 서빙은 단순히 Flask 서버에 모델을 올리는 것 이상의 문제이다. 레이턴시, 처리량, 동시 접속, 모델 버전 관리, 무중단 배포 등 프로덕션 수준의 요구사항을 충족해야 한다. 이 포스트에서는 추론 방식의 선택부터 서빙 프레임워크, 배포 전략까지 순서대로 살펴본다.

실시간 추론과 배치 추론

모델 서빙 방식은 크게 두 가지로 나뉜다. 실시간 추론(real-time inference)과 배치 추론(batch inference)이다.

실시간 추론은 사용자의 요청이 들어올 때마다 즉시 예측 결과를 반환하는 방식이다. 추천 시스템, 사기 탐지, 챗봇 등 응답 속도가 중요한 서비스에서 사용된다. REST API나 gRPC를 통해 요청을 받고, 수십에서 수백 밀리초 이내에 응답을 돌려주어야 한다.

배치 추론은 대량의 데이터를 모아서 한꺼번에 처리하는 방식이다. 매일 밤 전체 고객에 대한 이탈 확률을 계산하거나, 주간 단위로 상품 추천 목록을 갱신하는 경우가 이에 해당한다. 응답 속도보다 처리량이 중요하며, Spark나 Airflow 같은 배치 처리 프레임워크와 결합하여 운영하는 것이 일반적이다.

어떤 방식을 선택할지는 비즈니스 요구사항에 따라 결정된다. 과연 모든 서비스에 실시간 추론이 필요한가? 그렇지 않다. 결과가 몇 시간 뒤에 나와도 무방한 경우라면 배치 추론이 훨씬 비용 효율적이다. 반대로, 사용자가 화면을 보고 있는 상황에서 수 초의 지연도 허용되지 않는다면 실시간 추론이 불가피하다.

REST API 서빙 패턴

실시간 추론을 구현할 때 가장 흔한 방식은 REST API이다. 모델을 로드한 서버가 HTTP 엔드포인트를 노출하고, 클라이언트가 JSON 형태로 입력 데이터를 보내면 예측 결과를 JSON으로 반환하는 구조이다.

# FastAPI를 활용한 간단한 서빙 예시
from fastapi import FastAPI
import joblib

app = FastAPI()
model = joblib.load("model.pkl")

@app.post("/predict")
async def predict(data: dict):
    features = preprocess(data)
    prediction = model.predict(features)
    return {"prediction": prediction.tolist()}

이 방식은 프로토타이핑에는 충분하지만 프로덕션 환경에서는 한계가 있다. 모델 로딩 시간, 메모리 관리, 동시 요청 처리, GPU 활용 등의 문제를 직접 해결해야 하기 때문이다. 이러한 이유로 전문 서빙 프레임워크가 등장한 것이다.

모델 서빙 프레임워크

프로덕션 수준의 모델 서빙을 위해 여러 프레임워크가 존재한다. 각각의 특성을 이해하고 상황에 맞게 선택하는 것이 중요하다.

프레임워크특징적합한 상황
TensorFlow ServingTensorFlow 모델에 최적화, gRPC 지원TensorFlow 기반 프로젝트
NVIDIA Triton멀티 프레임워크 지원, 동적 배칭GPU 기반 고성능 추론
BentoMLPython 친화적, 패키징 용이빠른 프로토타입에서 프로덕션 전환
TorchServePyTorch 모델에 최적화PyTorch 기반 프로젝트

TensorFlow Serving은 TensorFlow 생태계에서 가장 성숙한 서빙 솔루션이다. SavedModel 형식을 직접 로드하며, 모델 버전 관리와 핫 스왑을 기본적으로 지원한다. 다만 TensorFlow 이외의 프레임워크로 학습된 모델을 서빙하기에는 적합하지 않다.

NVIDIA Triton Inference Server는 TensorFlow, PyTorch, ONNX 등 다양한 프레임워크의 모델을 단일 서버에서 서빙할 수 있다는 점에서 강력하다. 동적 배칭(dynamic batching)을 통해 개별 요청들을 모아 한 번에 GPU로 처리함으로써 처리량을 극대화할 수 있다. 모델 앙상블이나 파이프라인 구성도 지원하므로, 복잡한 추론 워크플로우를 구성해야 하는 경우에 적합하다.

# Triton 모델 저장소 구조
model_repository/
├── text_classifier/
│   ├── config.pbtxt
│   ├── 1/
│   │   └── model.onnx
│   └── 2/
│       └── model.onnx

BentoML은 모델 서빙의 진입 장벽을 낮추는 데 초점을 맞춘 프레임워크이다. 데코레이터 기반의 API 정의, 자동 컨테이너 빌드, 적응형 배칭 등을 제공하여 데이터 사이언티스트가 인프라에 대한 깊은 지식 없이도 서빙 시스템을 구축할 수 있게 한다.

레이턴시 최적화

서빙 시스템에서 레이턴시는 사용자 경험을 직접적으로 좌우하는 요소이다. 모델 추론 자체의 소요 시간뿐만 아니라 데이터 전처리, 네트워크 통신, 후처리까지 포함한 전체 응답 시간을 관리해야 한다.

레이턴시를 줄이기 위한 접근법은 여러 가지가 있다. 모델 최적화 측면에서는 양자화(quantization)를 통해 FP32 모델을 INT8로 변환하여 추론 속도를 높이거나, ONNX Runtime이나 TensorRT 같은 추론 최적화 엔진을 활용할 수 있다. 인프라 측면에서는 모델을 GPU 메모리에 상주시켜 로딩 오버헤드를 제거하고, 요청이 많은 시간대에는 오토스케일링을 적용하여 응답 시간을 일정하게 유지하는 전략이 필요하다.

과연 모든 최적화를 한꺼번에 적용해야 하는가? 그렇지 않다. 먼저 병목 지점을 프로파일링으로 파악한 후, 가장 효과가 큰 지점부터 최적화하는 것이 합리적이다.

컨테이너화

모델 서빙 시스템을 프로덕션에 배포하려면 컨테이너화가 사실상 필수이다. 모델 코드, 의존성, 모델 아티팩트를 하나의 Docker 이미지로 패키징함으로써 환경 간 일관성을 보장할 수 있다.

FROM python:3.11-slim

COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

COPY model/ /app/model/
COPY serve.py /app/

WORKDIR /app
CMD ["uvicorn", "serve:app", "--host", "0.0.0.0", "--port", "8080"]

컨테이너 이미지의 크기는 배포 속도와 직결된다. 불필요한 의존성을 제거하고, 멀티 스테이지 빌드를 활용하며, 모델 파일이 크다면 이미지 외부에서 로딩하는 방식을 고려해야 한다. GPU를 사용하는 경우에는 NVIDIA CUDA 베이스 이미지를 사용하되, 이미지 크기가 수 GB에 달할 수 있으므로 레이어 캐싱 전략이 더욱 중요해진다.

배포 전략

모델을 업데이트할 때 전체 트래픽을 한꺼번에 새 모델로 전환하는 것은 위험하다. 새 모델에 예상치 못한 문제가 있을 수 있기 때문이다. 안전한 배포를 위한 전략이 필요하다.

카나리 배포(canary deployment)는 새 모델을 전체 트래픽의 일부(예: 5~10%)에만 먼저 적용하고, 성능 지표를 관찰한 후 문제가 없으면 점진적으로 트래픽 비율을 높이는 방식이다. 새 모델의 정확도가 기존 모델보다 떨어지거나 레이턴시가 급격히 증가하는 경우 빠르게 롤백할 수 있다는 장점이 있다.

A/B 테스트는 두 개 이상의 모델을 동시에 운영하며 비즈니스 지표를 비교하는 방식이다. 카나리 배포가 기술적 안정성에 초점을 맞춘다면, A/B 테스트는 비즈니스 성과를 기준으로 모델을 평가한다는 점에서 차이가 있다. 추천 시스템에서 클릭률을 비교하거나, 검색 모델에서 전환율을 측정하는 것이 대표적인 사례이다.

                    ┌──── 모델 v1 (90%) ────┐
사용자 요청 ──→ 로드밸런서 ──┤                        ├──→ 응답
                    └──── 모델 v2 (10%) ────┘
                         (카나리)

블루-그린 배포(blue-green deployment)는 기존 환경(블루)과 새 환경(그린)을 동시에 준비한 후, 트래픽을 한 번에 전환하는 방식이다. 문제가 발생하면 즉시 블루 환경으로 되돌릴 수 있다. 카나리 배포보다 운영은 단순하지만, 두 배의 인프라 비용이 필요하다는 트레이드오프가 있다.

정리

모델 서빙은 학습된 모델을 실제 가치로 전환하는 과정이다. 실시간 추론과 배치 추론 중 적절한 방식을 선택하고, 프로덕션 수준의 서빙 프레임워크를 활용하며, 안전한 배포 전략을 적용하는 것이 핵심이다. 컨테이너화를 통해 환경 일관성을 확보하고, 레이턴시 최적화를 통해 사용자 경험을 보장해야 한다.

다음 포스트에서는 배포된 모델의 성능을 지속적으로 관찰하고 데이터 드리프트를 감지하는 모니터링 전략을 살펴본다.