Skip to content
Published on

MLOps 파이프라인 설계: ML 시스템 프로덕션화 완전 가이드

Authors
  • Name
    Twitter

1. MLOps란 무엇인가

1.1 정의와 배경

MLOps(Machine Learning Operations)는 ML 모델의 개발, 배포, 운영을 체계적으로 관리하기 위한 일련의 실천 방법론(practice)이다. DevOps가 소프트웨어 개발(Development)과 운영(Operations)의 간극을 해소하기 위해 탄생한 것처럼, MLOps는 ML 모델 개발과 프로덕션 운영 사이의 간극을 해소하는 것을 목표로 한다.

Google Cloud의 공식 MLOps 가이드에서는 MLOps를 다음과 같이 정의한다:

MLOps는 ML 시스템 개발(Dev)과 ML 시스템 운영(Ops)을 통합하는 것을 목표로 하는 ML 엔지니어링 문화이자 실천 방법이다.

전통적인 소프트웨어 시스템에서는 코드만 관리하면 되지만, ML 시스템에서는 코드, 데이터, 모델 세 가지 축을 동시에 관리해야 한다. 이 근본적인 차이가 MLOps라는 별도의 방법론을 필요로 만든다.

1.2 DevOps와의 핵심 차이

DevOps와 MLOps는 자동화, CI/CD, 모니터링이라는 공통 원칙을 공유하지만, ML 시스템 고유의 특성 때문에 여러 가지 차이점이 존재한다.

구분DevOpsMLOps
관리 대상코드코드 + 데이터 + 모델
테스트단위/통합 테스트데이터 검증 + 모델 검증 + 코드 테스트
배포서비스/애플리케이션 배포모델 배포 + 예측 서비스 배포
모니터링시스템 성능, 에러율모델 성능 저하, Data Drift, Concept Drift
롤백 기준에러 발생 시모델 성능 지표 기반
버전 관리코드 버전 관리코드 + 데이터 + 모델 + 하이퍼파라미터 버전 관리
재현성빌드 재현실험 재현(데이터, 환경, 파라미터 포함)

1.3 ML 시스템의 기술 부채: Google 논문 분석

2015년 Google 연구팀이 발표한 논문 "Hidden Technical Debt in Machine Learning Systems" (Sculley et al., NeurIPS 2015)는 ML 시스템의 기술 부채 문제를 체계적으로 정리한 핵심 논문이다. 이 논문의 핵심 메시지는 다음과 같다:

실제 프로덕션 ML 시스템에서 ML 코드는 전체 시스템의 극히 일부분에 불과하다. 나머지 대부분은 데이터 수집, 검증, Feature 추출, 설정 관리, 모니터링, 서빙 인프라 등 주변 인프라로 구성된다.

논문이 지적하는 ML 시스템 고유의 기술 부채 유형은 다음과 같다:

  • Entanglement (얽힘): ML 모델에서 하나의 Feature를 변경하면 다른 모든 Feature의 영향력이 변할 수 있다. 이를 CACE(Changing Anything Changes Everything) 원칙이라 부른다.
  • Hidden Feedback Loops (숨겨진 피드백 루프): 모델의 출력이 향후 입력 데이터에 영향을 미치는 순환 구조가 감지되지 않은 채 존재할 수 있다.
  • Undeclared Consumers (선언되지 않은 소비자): 모델의 출력을 누가 사용하는지 추적하지 않으면, 모델 변경 시 예상치 못한 곳에서 문제가 발생한다.
  • Data Dependencies (데이터 의존성): 코드 의존성보다 추적하기 어렵고, 불안정한 외부 데이터 소스에 대한 의존성이 시스템 전체를 취약하게 만든다.
  • Configuration Debt (설정 부채): 수많은 하이퍼파라미터, Feature 플래그, 전처리 설정 등이 체계적으로 관리되지 않으면 재현이 불가능해진다.

이러한 기술 부채를 체계적으로 관리하기 위해 MLOps 파이프라인이 필요한 것이다.

2. Google MLOps Maturity Model

Google Cloud Architecture Center에서 제시하는 MLOps 성숙도 모델은 Level 0부터 Level 2까지 3단계로 구성된다. 각 레벨은 ML 파이프라인의 자동화 수준과 CI/CD 통합 정도에 따라 구분된다.

2.1 Level 0: Manual Process (수동 프로세스)

Level 0는 대부분의 ML 팀이 시작하는 단계로, 모든 과정이 수동으로 이루어진다.

특징:

  • Data Scientist가 Jupyter Notebook 등에서 수동으로 데이터 분석, 전처리, 모델 학습, 검증을 수행한다
  • 학습된 모델을 엔지니어링 팀에 수동으로 전달(handoff)한다
  • 모델 배포 빈도가 매우 낮다 (연 수회 수준)
  • CI/CD가 없다 --- 코드 테스트도, 자동 배포도 없다
  • 프로덕션 환경에서 모델 성능 모니터링이 없다
  • 학습 스크립트와 예측 서비스가 분리되어 있다

핵심 문제: Level 0에서는 모델이 프로덕션에 배포된 이후 시간이 지남에 따라 성능이 저하(model decay)되지만, 이를 감지할 수 있는 메커니즘이 없다. Google 가이드에서는 "models can decay in more ways than conventional software systems"라고 명시하며, 데이터 프로파일의 변화가 모델 성능 저하의 주요 원인임을 강조한다.

2.2 Level 1: ML Pipeline Automation (ML 파이프라인 자동화)

Level 1의 목표는 Continuous Training (CT) --- 즉 ML 파이프라인을 자동화하여 모델의 지속적 학습을 가능하게 하는 것이다.

핵심 구성 요소:

  • 자동화된 ML 파이프라인: 데이터 추출, 검증, 전처리, 학습, 평가, 배포의 전 과정이 오케스트레이션된 파이프라인으로 실행된다
  • Data Validation (데이터 검증): 자동화된 스키마 검증과 통계적 Drift 탐지를 수행한다
  • Model Validation (모델 검증): 새로 학습된 모델이 기존 모델보다 좋은 성능을 보이는지 자동으로 평가한다
  • Feature Store: 학습(Training)과 서빙(Serving) 간의 Feature 일관성을 보장하는 중앙 집중식 Feature 저장소를 활용한다
  • Metadata Management: 파이프라인 실행 이력, 데이터 Lineage, 모델 아티팩트를 체계적으로 추적한다
  • Pipeline Triggers: 스케줄, 새 데이터 도착, 성능 저하 감지, Concept Drift 등 다양한 조건으로 재학습을 트리거한다

Level 0과의 핵심 차이: Level 0에서는 학습된 "모델"을 배포하지만, Level 1에서는 "파이프라인"을 배포한다. 개발 환경과 프로덕션 환경에서 동일한 파이프라인이 대칭적으로 실행되며, 파이프라인의 각 단계는 모듈화되고 컨테이너화된다.

2.3 Level 2: CI/CD Pipeline Automation (CI/CD 파이프라인 자동화)

Level 2는 ML 파이프라인 자체의 업데이트까지 자동화하는 단계이다. Level 1이 모델의 지속적 학습(CT)을 자동화했다면, Level 2는 파이프라인 코드의 지속적 통합(CI)과 지속적 배포(CD)까지 포괄한다.

6단계 파이프라인 구성:

  1. 개발 및 실험: 오케스트레이션된 단계에서 새 알고리즘과 모델링 기법을 실험한다
  2. Continuous Integration (CI): 소스 코드 빌드, 테스트, 패키징을 수행한다. Feature Engineering 로직 단위 테스트, 모델 학습 수렴 검증, 컴포넌트 통합 테스트 등이 포함된다
  3. Continuous Delivery (CD): 파이프라인 아티팩트를 대상 환경에 배포한다
  4. 자동화된 트리거: 프로덕션 환경에서 파이프라인을 자동으로 실행한다
  5. Model CD: 학습된 모델을 예측 서비스로 배포한다
  6. 모니터링: 모델 성능과 파이프라인 효율성을 지속적으로 추적한다

배포 전략:

  • 테스트 환경에 자동 배포
  • Pre-production 환경에 리뷰 후 반자동 배포
  • 프로덕션 환경에 Pre-production 검증 후 수동 승인 배포

CI에 포함되는 테스트 항목:

  • Feature Engineering 로직에 대한 단위 테스트
  • 모델 학습의 수렴성(convergence) 테스트
  • 모델 학습에서 NaN이나 무한대 값이 발생하지 않는지 검증
  • 파이프라인 컴포넌트 간 통합 테스트
  • 모델 인터페이스 호환성 테스트

3. Data Management

3.1 Feature Store: Feast

Feature Store는 ML 파이프라인에서 Feature를 중앙 집중식으로 관리하고 제공하는 시스템이다. Feast(Feature Store)는 대표적인 오픈소스 Feature Store로, 학습과 서빙 간의 Feature 일관성 문제(Training-Serving Skew)를 해결하는 것을 핵심 목표로 한다.

Feast의 핵심 아키텍처:

                    +-------------------+
                    |   Feature Store   |
                    |     (Feast)       |
                    +-------------------+
                   /                     \
    +------------------+        +------------------+
    |  Offline Store   |        |  Online Store    |
    |  (Historical)    |        |  (Low-latency)   |
    +------------------+        +------------------+
    | - BigQuery       |        | - Redis          |
    | - Redshift       |        | - DynamoDB       |
    | - Snowflake      |        | - Datastore      |
    | - File (Parquet) |        | - SQLite         |
    +------------------+        +------------------+
           |                            |
    Model Training               Model Serving
    (Batch Feature Retrieval)    (Online Feature Retrieval)
  • Offline Store: 대량의 과거 Feature 데이터를 저장하며, 모델 학습 시 배치(batch) 단위로 Feature를 조회하는 데 사용된다
  • Online Store: 최신 Feature 값을 낮은 지연시간(low-latency)으로 제공하며, 실시간 추론 서빙에 사용된다

Feast를 사용하는 이유:

  1. Training-Serving Skew 방지: 학습 시 사용한 Feature 변환 로직과 서빙 시 사용하는 로직이 동일함을 보장한다
  2. Feature 재사용성: 한 번 정의한 Feature를 여러 모델에서 재사용할 수 있다
  3. Point-in-time Correctness: 과거 시점의 Feature 값을 정확하게 조회할 수 있어 Data Leakage를 방지한다
  4. Feature Discovery: 중앙 저장소에서 사용 가능한 Feature를 검색하고 탐색할 수 있다

Feast Feature 정의 예제:

from feast import Entity, FeatureView, Field, FileSource
from feast.types import Float32, Int64
from datetime import timedelta

# 데이터 소스 정의
driver_stats_source = FileSource(
    path="data/driver_stats.parquet",
    timestamp_field="event_timestamp",
)

# Entity 정의
driver = Entity(
    name="driver_id",
    description="Driver identifier",
)

# Feature View 정의
driver_stats_fv = FeatureView(
    name="driver_hourly_stats",
    entities=[driver],
    ttl=timedelta(hours=2),
    schema=[
        Field(name="conv_rate", dtype=Float32),
        Field(name="acc_rate", dtype=Float32),
        Field(name="avg_daily_trips", dtype=Int64),
    ],
    source=driver_stats_source,
)

3.2 Data Versioning: DVC

DVC(Data Version Control)는 Git을 기반으로 데이터와 ML 파이프라인을 버전 관리하는 오픈소스 도구이다. Git이 코드를 관리하듯이, DVC는 대용량 데이터셋, 모델 파일, 중간 산출물을 효율적으로 버전 관리한다.

DVC의 핵심 원리:

Git 저장소에는 데이터 파일의 메타 정보(.dvc 파일과 dvc.yaml)만 커밋하고, 실제 데이터는 Remote Storage(S3, GCS, Azure Blob 등)에 저장한다.

# DVC 초기화
dvc init

# 데이터 파일 추적 시작
dvc add data/training_dataset.csv

# Git에는 메타 파일만 커밋
git add data/training_dataset.csv.dvc data/.gitignore
git commit -m "Add training dataset v1"

# Remote Storage 설정
dvc remote add -d myremote s3://my-bucket/dvc-storage
dvc push

DVC Pipeline 정의 (dvc.yaml):

stages:
  preprocess:
    cmd: python src/preprocess.py
    deps:
      - src/preprocess.py
      - data/raw/
    outs:
      - data/processed/

  train:
    cmd: python src/train.py
    deps:
      - src/train.py
      - data/processed/
    outs:
      - models/model.pkl
    metrics:
      - metrics/scores.json:
          cache: false

  evaluate:
    cmd: python src/evaluate.py
    deps:
      - src/evaluate.py
      - models/model.pkl
      - data/test/
    metrics:
      - metrics/eval_results.json:
          cache: false

DVC의 파이프라인은 ML 프로젝트의 "Makefile" 역할을 한다. 각 단계의 입력, 출력, 의존성이 명시적으로 정의되어 있어, dvc repro 명령어 하나로 전체 파이프라인을 재현할 수 있다.

4. Experiment Tracking

4.1 MLflow Tracking

MLflow는 ML 실험의 전체 라이프사이클을 관리하는 오픈소스 플랫폼으로, Databricks가 개발하였다. MLflow Tracking은 실험 관리의 핵심 컴포넌트로, 파라미터, 메트릭, 아티팩트, 코드 버전을 체계적으로 기록하고 비교한다.

MLflow Tracking의 핵심 개념:

  • Experiment: 관련된 Run들의 논리적 그룹이다
  • Run: 한 번의 모델 학습 실행으로, 파라미터, 메트릭, 아티팩트, 태그를 기록한다
  • Parameter: 모델 학습 시 사용한 하이퍼파라미터(learning rate, batch size 등)
  • Metric: 모델의 성능 지표(accuracy, loss, F1-score 등)
  • Artifact: 모델 파일, 시각화, 데이터 파일 등 실행 결과물

MLflow Tracking 사용 예제:

import mlflow
import mlflow.sklearn
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score, f1_score
from sklearn.model_selection import train_test_split

# Tracking Server URI 설정
mlflow.set_tracking_uri("http://mlflow-server:5000")
mlflow.set_experiment("fraud-detection-experiment")

# 실험 실행
with mlflow.start_run(run_name="rf_baseline_v1"):
    # 하이퍼파라미터 로깅
    params = {
        "n_estimators": 100,
        "max_depth": 10,
        "min_samples_split": 5,
        "random_state": 42
    }
    mlflow.log_params(params)

    # 모델 학습
    model = RandomForestClassifier(**params)
    model.fit(X_train, y_train)

    # 예측 및 메트릭 계산
    y_pred = model.predict(X_test)
    accuracy = accuracy_score(y_test, y_pred)
    f1 = f1_score(y_test, y_pred, average='weighted')

    # 메트릭 로깅
    mlflow.log_metrics({
        "accuracy": accuracy,
        "f1_score": f1
    })

    # 모델 아티팩트 로깅
    mlflow.sklearn.log_model(model, "random_forest_model")

    # 추가 아티팩트 (confusion matrix 이미지 등) 로깅
    mlflow.log_artifact("plots/confusion_matrix.png")

4.2 Weights & Biases (W&B)

Weights & Biases는 실험 추적, 하이퍼파라미터 최적화, 모델 관리를 위한 통합 MLOps 플랫폼이다. MLflow와 유사한 기능을 제공하지만, 특히 실시간 대시보드와 팀 협업 기능에 강점이 있다.

W&B의 핵심 기능:

  • Experiment Tracking: 학습 과정의 파라미터, 메트릭, 시스템 자원 사용량을 실시간으로 추적하고 인터랙티브 차트로 시각화한다
  • Artifacts: 데이터셋과 모델 체크포인트를 버전 관리하여, 특정 모델이 어떤 데이터로 학습되었는지 정확히 추적(Lineage)할 수 있다
  • Sweeps: 하이퍼파라미터 최적화를 자동화한다. Bayesian Optimization, Grid Search, Random Search 등 다양한 전략을 지원한다
  • Tables: 예측 결과를 테이블 형태로 시각화하여 모델 행동을 세밀하게 분석할 수 있다
import wandb

# W&B 초기화
wandb.init(
    project="fraud-detection",
    config={
        "learning_rate": 0.001,
        "epochs": 50,
        "batch_size": 32,
        "architecture": "ResNet50"
    }
)

# 학습 루프에서 메트릭 로깅
for epoch in range(wandb.config.epochs):
    train_loss = train_one_epoch(model, train_loader)
    val_loss, val_acc = evaluate(model, val_loader)

    wandb.log({
        "epoch": epoch,
        "train_loss": train_loss,
        "val_loss": val_loss,
        "val_accuracy": val_acc
    })

wandb.finish()

MLflow vs W&B 비교:

항목MLflowW&B
라이선스오픈소스 (Apache 2.0)프리미엄 (개인 무료)
호스팅자체 호스팅 / Managed클라우드 (SaaS)
실시간 대시보드기본적고급 인터랙티브
팀 협업제한적강력한 협업 기능
Model Registry내장Artifacts로 관리
Hyperparameter Tuning미지원 (별도 도구 필요)Sweeps 내장

5. Model Registry와 버전 관리

5.1 MLflow Model Registry

MLflow Model Registry는 ML 모델의 전체 라이프사이클을 중앙에서 관리하는 컴포넌트이다. 모델의 버전 관리, 스테이지 전환, 승인 워크플로우를 체계적으로 지원한다.

Model Registry의 핵심 개념:

  • Registered Model: 논리적 모델 단위 (예: "fraud-detection-model")
  • Model Version: 등록된 모델의 각 버전. 자동으로 버전 번호가 부여된다
  • Model Aliases: 특정 버전에 의미 있는 이름을 부여한다 (예: @champion, @challenger)
  • Tags: 모델에 메타데이터를 태그로 부착하여 검색과 필터링을 용이하게 한다

Model Registry 워크플로우:

개발 (Experiment) --> 모델 등록 --> Staging --> Production
                         |              |           |
                     Version 1      테스트/검증    서빙
                     Version 2        A/B 테스트
                     Version 3

MLflow Model Registry 사용 예제:

import mlflow
from mlflow import MlflowClient

client = MlflowClient()

# 모델 학습 및 로깅 (Tracking에서 수행)
with mlflow.start_run() as run:
    mlflow.sklearn.log_model(model, "model")
    model_uri = f"runs:/{run.info.run_id}/model"

# Model Registry에 등록
model_version = mlflow.register_model(
    model_uri=model_uri,
    name="fraud-detection-model"
)

# Alias 설정 (champion으로 지정)
client.set_registered_model_alias(
    name="fraud-detection-model",
    alias="champion",
    version=model_version.version
)

# 프로덕션에서 champion 모델 로드
champion_model = mlflow.pyfunc.load_model(
    model_uri="models:/fraud-detection-model@champion"
)
predictions = champion_model.predict(input_data)

Model Registry를 사용하는 이유:

  1. 감사 추적(Audit Trail): 어떤 모델이 언제, 누구에 의해, 어떤 실험에서 프로덕션에 배포되었는지 전체 이력을 추적할 수 있다
  2. 롤백 용이성: 모델 성능 문제 발생 시 이전 버전의 모델로 즉시 롤백할 수 있다
  3. 승인 워크플로우: 모델이 프로덕션에 배포되기 전에 리뷰와 승인 과정을 거치도록 강제할 수 있다
  4. 재현성: 각 모델 버전이 어떤 Run과 연결되어 있는지 추적하여, 학습 데이터, 파라미터, 코드를 정확히 재현할 수 있다

6. CI/CD for ML

6.1 전통적 CI/CD와 ML CI/CD의 차이

ML 프로젝트에서의 CI/CD는 코드뿐만 아니라 데이터와 모델까지 파이프라인에 포함해야 한다. 이를 CI/CD/CT (Continuous Integration / Continuous Delivery / Continuous Training)라고 부른다.

  • CI (Continuous Integration): 코드 변경 시 자동으로 테스트를 실행한다. ML에서는 데이터 스키마 검증, Feature Engineering 로직 테스트, 모델 학습 스크립트 테스트가 추가된다.
  • CD (Continuous Delivery): 검증된 파이프라인과 모델을 대상 환경에 자동으로 배포한다.
  • CT (Continuous Training): 새 데이터가 도착하거나 모델 성능이 저하되었을 때 자동으로 모델을 재학습한다.

6.2 CML (Continuous Machine Learning)

CML은 Iterative.ai(DVC 개발사)에서 만든 오픈소스 도구로, GitHub Actions 및 GitLab CI와 통합하여 ML 프로젝트의 CI/CD를 구현한다.

CML의 핵심 기능:

  • ML 실험 결과를 Pull Request에 자동으로 리포트(메트릭, 시각화)로 게시한다
  • GPU 등 계산 자원이 필요한 경우 AWS, GCP, Azure에서 클라우드 인스턴스를 자동으로 할당한다
  • DVC와 연동하여 데이터 버전에 따른 실험을 자동으로 실행한다

GitHub Actions + CML 워크플로우 예제:

# .github/workflows/ml-pipeline.yml
name: ML Pipeline CI/CD

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

jobs:
  train-and-evaluate:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - uses: actions/setup-python@v5
        with:
          python-version: '3.11'

      - uses: iterative/setup-cml@v2

      - name: Install dependencies
        run: |
          pip install -r requirements.txt

      - name: Pull data with DVC
        run: |
          dvc pull
        env:
          AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
          AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}

      - name: Train model
        run: |
          dvc repro

      - name: Create CML report
        env:
          REPO_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: |
          # 메트릭 비교
          echo "## Model Performance Report" >> report.md
          echo "" >> report.md
          dvc metrics diff --md >> report.md
          echo "" >> report.md

          # 시각화 추가
          echo "## Training Curves" >> report.md
          cml asset publish plots/training_curve.png --md >> report.md
          echo "" >> report.md
          echo "## Confusion Matrix" >> report.md
          cml asset publish plots/confusion_matrix.png --md >> report.md

          # PR에 코멘트로 게시
          cml comment create report.md

이 워크플로우는 Pull Request가 생성될 때 자동으로 모델을 학습하고, 성능 메트릭과 시각화를 PR 코멘트로 게시한다. 코드 리뷰어는 코드 변경뿐만 아니라 모델 성능 변화까지 리뷰할 수 있다.

6.3 ML 파이프라인에서의 테스트 전략

ML 프로젝트에서는 전통적인 소프트웨어 테스트 외에 다음과 같은 ML 고유의 테스트가 필요하다.

+----------------------------------------------------+
|              ML Testing Pyramid                     |
|                                                     |
|                  /\                                  |
|                 /  \     End-to-End Pipeline Test    |
|                /----\                                |
|               / Model \   Model Quality Tests       |
|              /  Quality \  (Performance Threshold)   |
|             /------------\                           |
|            /   Training    \  Training Tests         |
|           /   Convergence   \ (NaN, Inf, Overfit)    |
|          /-------------------\                       |
|         /   Data Validation    \ Schema, Statistics  |
|        /     & Feature Tests    \                    |
|       /-------------------------\                    |
|      /     Unit Tests (Code)      \  Standard Unit   |
|     /______________________________\  Tests          |
+----------------------------------------------------+
  • Unit Tests: 전처리 함수, Feature Engineering 로직의 정확성 검증
  • Data Validation Tests: 입력 데이터의 스키마 일치, 통계적 특성 검증, 결측치 비율 검증
  • Training Tests: 모델 학습의 수렴 여부, NaN/Inf 발생 여부, 과적합 검증
  • Model Quality Tests: 정의된 성능 임계값(threshold) 이상인지 검증
  • End-to-End Pipeline Tests: 전체 파이프라인이 올바르게 실행되는지 통합 검증

7. Model Serving 패턴

모델이 학습되고 검증된 후에는 실제 사용자에게 예측을 제공하기 위해 서빙(Serving)해야 한다. 서빙 방식과 배포 전략은 비즈니스 요구사항과 시스템 특성에 따라 결정된다.

7.1 Batch Serving vs Real-time Serving

Batch Serving (배치 서빙):

  • 주기적으로(시간/일/주 단위) 대량의 데이터에 대해 예측을 수행하고 결과를 저장한다
  • 추천 시스템에서 사전 계산된 추천 목록, 이탈 예측 스코어링, 주간 수요 예측 등에 활용된다
  • 실시간성이 요구되지 않으며, 처리량(throughput)이 중요하다
  • Apache Spark, Apache Airflow 등과 연동하여 구현한다
# Batch Serving 예시: Apache Spark + MLflow
from pyspark.sql import SparkSession
import mlflow

spark = SparkSession.builder.appName("batch-prediction").getOrCreate()

# 프로덕션 모델 로드
model = mlflow.pyfunc.load_model("models:/fraud-detection@champion")

# 대량 데이터에 대한 배치 예측
input_df = spark.read.parquet("s3://data-lake/daily/transactions/")
predictions = model.predict(input_df.toPandas())

# 결과 저장
result_df = input_df.toPandas()
result_df["prediction"] = predictions
spark.createDataFrame(result_df).write.parquet("s3://data-lake/predictions/")

Real-time Serving (실시간 서빙):

  • 개별 요청에 대해 즉시(수 ms~수백 ms 이내) 예측 결과를 반환한다
  • 사기 탐지, 실시간 추천, 검색 랭킹 등에 활용된다
  • 지연시간(latency)과 가용성(availability)이 핵심 지표이다
  • REST API 또는 gRPC 엔드포인트로 모델을 서빙한다
  • TensorFlow Serving, TorchServe, Triton Inference Server, BentoML 등을 활용한다

7.2 배포 전략 (Deployment Strategies)

A/B Testing:

두 가지 이상의 모델 버전을 동시에 프로덕션에 배포하고, 트래픽을 분할하여 비즈니스 메트릭에 미치는 영향을 통계적으로 비교한다.

사용자 요청 ──────> Load Balancer
                        |
              +---------+---------+
              |                   |
         Model A (70%)       Model B (30%)
         (현재 모델)         (새 모델)
              |                   |
         응답 반환            응답 반환
              |                   |
              +----> 메트릭 수집 <----+
                        |
                  통계적 유의성 분석
  • 직접적인 비즈니스 메트릭(클릭율, 전환율, 매출 등)을 기반으로 모델을 비교한다
  • 통계적 유의성(statistical significance)이 확보될 때까지 실험을 지속한다
  • 사용자에게 실제 영향을 미치므로 신중하게 설계해야 한다

Shadow Deployment (그림자 배포):

새 모델이 프로덕션 트래픽을 복제받아 예측을 수행하지만, 실제 응답에는 사용되지 않는다. 기존 모델만이 실제 응답을 제공한다.

사용자 요청 ──────> 기존 모델 (Production)
       |                    |
       |               실제 응답 반환
       |
       +---------->모델 (Shadow)
                         |
                    예측 결과 저장 (응답에 사용 안 함)
                         |
                    성능 비교 분석
  • 사용자에게 영향을 주지 않으면서 새 모델을 프로덕션 환경에서 검증할 수 있다
  • 실제 프로덕션 데이터에 대한 성능을 사전에 파악할 수 있다
  • 단점은 인프라 비용이 두 배로 든다는 것이다

Canary Deployment (카나리 배포):

새 모델을 소수의 사용자(예: 전체 트래픽의 5%)에게만 먼저 배포하고, 문제가 없으면 점진적으로 트래픽 비율을 높여간다.

Phase 1:  기존 모델 95% ──|── 새 모델 5%     (모니터링)
Phase 2:  기존 모델 75% ──|── 새 모델 25%    (검증)
Phase 3:  기존 모델 50% ──|── 새 모델 50%    (확인)
Phase 4:  기존 모델 0%  ──|── 새 모델 100%   (완료)
  • 새 모델의 기술적 안정성(에러율, 지연시간)을 점진적으로 검증한다
  • 문제 발생 시 즉시 롤백이 가능하다(영향 범위가 제한적이므로)
  • A/B Testing과 결합 가능하다: 먼저 Canary로 기술적 안정성을 확인한 후, A/B Testing으로 비즈니스 효과를 측정한다

8. Monitoring: Drift 탐지

모델이 프로덕션에 배포된 이후의 모니터링은 MLOps에서 가장 중요하면서도 종종 간과되는 영역이다. 시간이 지남에 따라 모델 성능은 반드시 저하되며, 이를 조기에 감지하고 대응하는 것이 핵심이다.

8.1 Drift의 유형

Data Drift (데이터 드리프트):

입력 데이터의 통계적 분포가 학습 시 사용한 데이터의 분포와 달라지는 현상이다. 모델 자체는 변하지 않았지만, 입력 데이터의 특성이 변하여 모델의 예측 정확도가 저하된다.

  • 예시: 코로나19 팬데믹으로 인한 소비 패턴의 급격한 변화, 계절적 변동
  • 수학적 정의: P_train(X) != P_production(X)

Concept Drift (개념 드리프트):

입력(X)과 출력(Y) 사이의 관계 자체가 변하는 현상이다. 동일한 입력에 대해 정답이 달라진 것이다.

  • 예시: 사기 패턴의 진화, 사용자 선호도의 변화, 규정 변경으로 인한 분류 기준 변화
  • 수학적 정의: P_train(Y|X) != P_production(Y|X)

Model Drift (모델 드리프트):

모델의 예측 성능 지표(accuracy, precision, recall 등)가 시간이 지남에 따라 저하되는 현상이다. Data Drift나 Concept Drift의 결과로 나타나는 경우가 많다.

8.2 Evidently AI를 활용한 Drift 모니터링

Evidently AI는 ML 모델과 데이터 품질을 모니터링하기 위한 오픈소스 Python 라이브러리이다. 20개 이상의 사전 구축된 Drift 탐지 방법과 100개 이상의 내장 메트릭을 제공한다.

Evidently의 핵심 기능:

  • Data Drift 탐지: KS Test, PSI (Population Stability Index), Jensen-Shannon Divergence, Wasserstein Distance 등 다양한 통계 검정을 사용하여 Feature별 Drift를 탐지한다
  • Data Quality 모니터링: 결측치 비율, 이상치, 데이터 타입 변경 등 데이터 품질 문제를 감지한다
  • Model Performance 추적: 정확도, 에러율 등 모델 성능 메트릭의 시계열 변화를 추적한다
  • 인터랙티브 리포트: 탐지 결과를 시각적 리포트로 자동 생성한다

Evidently Data Drift 탐지 예제:

import pandas as pd
from evidently.report import Report
from evidently.metric_preset import DataDriftPreset, DataQualityPreset
from evidently.metrics import DataDriftTable

# 학습 데이터 (reference)와 프로덕션 데이터 (current) 로드
reference_data = pd.read_csv("data/training_data.csv")
current_data = pd.read_csv("data/production_data_latest.csv")

# Data Drift 리포트 생성
drift_report = Report(metrics=[
    DataDriftPreset(),
    DataQualityPreset(),
])

drift_report.run(
    reference_data=reference_data,
    current_data=current_data
)

# HTML 리포트 저장
drift_report.save_html("reports/data_drift_report.html")

# 프로그래밍 방식으로 결과 접근
report_dict = drift_report.as_dict()
dataset_drift = report_dict["metrics"][0]["result"]["dataset_drift"]

if dataset_drift:
    print("Dataset Drift가 감지되었습니다! 모델 재학습을 트리거합니다.")
    # 재학습 파이프라인 트리거 로직

자동화된 모니터링 파이프라인 구성:

from evidently.test_suite import TestSuite
from evidently.tests import (
    TestShareOfDriftedColumns,
    TestColumnDrift,
    TestShareOfMissingValues
)

# 테스트 스위트 정의 (CI/CD 통합용)
data_stability_tests = TestSuite(tests=[
    TestShareOfDriftedColumns(lt=0.3),  # Drift된 컬럼이 30% 미만이어야 함
    TestColumnDrift(column_name="transaction_amount"),
    TestColumnDrift(column_name="user_age"),
    TestShareOfMissingValues(lt=0.05),  # 결측치 비율 5% 미만
])

data_stability_tests.run(
    reference_data=reference_data,
    current_data=current_data
)

# 테스트 결과 확인
test_results = data_stability_tests.as_dict()
all_passed = all(
    test["status"] == "SUCCESS"
    for test in test_results["tests"]
)

if not all_passed:
    # 알림 전송 및 재학습 트리거
    send_alert("Data stability test failed!")

8.3 모니터링 전략 수립

효과적인 ML 모니터링을 위해서는 다층적(multi-layered) 접근이 필요하다.

모니터링 계층대상도구주기
인프라CPU/GPU 사용률, 메모리, 네트워크Prometheus, Grafana실시간
서비스응답 지연시간, 에러율, 처리량Prometheus, Datadog실시간
데이터 품질스키마, 결측치, 이상치Evidently, Great Expectations배치/실시간
Data DriftFeature 분포 변화Evidently, NannyML일간/주간
모델 성능정확도, F1, AUC 등Evidently, W&B일간/주간
비즈니스 메트릭전환율, 매출, 클릭율자체 분석 도구일간/주간

9. 전체 아키텍처 다이어그램

아래는 MLOps Level 2에 해당하는 완전한 MLOps 파이프라인 아키텍처이다.

┌────────────────────────────────────────────────────────────────────┐
MLOps Pipeline Architecture├────────────────────────────────────────────────────────────────────┤
│                                                                    │
│  ┌─────────────┐    ┌──────────────┐    ┌──────────────────────┐  │
│  │ Data Sources │───>Data Pipeline │───>Feature Store (Feast)│  │
 (DB, API, (Ingestion,  │    │ ┌────────┐┌────────┐│  │
│  │  Streaming) │    │  Validation, │    │ │Offline ││Online  ││  │
│  └─────────────┘    │  Transform)  │    │ │Store   ││Store   ││  │
│        │            └──────────────┘    │ └────────┘└────────┘│  │
│        │                   │            └──────────────────────┘  │
│        │                   │                   │          │       │
│        ▼                   ▼                   ▼          │       │
│  ┌──────────┐    ┌────────────────┐    ┌────────────┐    │       │
│  │   DVC    │    │  Data Version  │    │  Training   │    │       │
 (Data    │    │  & Validation  │    │  Pipeline   │    │       │
│  │ Version)  (Evidently)   │    │             │    │       │
│  └──────────┘    └────────────────┘    └──────┬─────┘    │       │
│                                               │          │       │
│                                               ▼          │       │
│  ┌──────────────────────────────────────────────────┐    │       │
│  │           Experiment Tracking                     │    │       │
│  │    ┌─────────────┐    ┌──────────────────┐       │    │       │
│  │    │   MLflow     │    │   Weights &      │       │    │       │
│  │    │  Tracking    │    │   Biases          │       │    │       │
│  │    └──────┬──────┘    └──────────────────┘       │    │       │
│  └───────────┼──────────────────────────────────────┘    │       │
│              ▼                                           │       │
│  ┌──────────────────┐   ┌───────────────────────────┐    │       │
│  │  Model Registry  │   │    CI/CD Pipeline          │    │       │
  (MLflow)        │──>  (GitHub Actions + CML)    │    │       │
│  │  ┌────────────┐  │   │  ┌─────┐ ┌────┐ ┌─────┐  │    │       │
│  │  │ @champion  │  │   │  │ CI  │ │ CD │ │ CT  │  │    │       │
│  │  │ @challenger│  │   │  └─────┘ └────┘ └─────┘  │    │       │
│  │  └────────────┘  │   └────────────┬──────────────┘    │       │
│  └──────────────────┘                │                   │       │
│                                      ▼                   │       │
│  ┌───────────────────────────────────────────────────────┐│       │
│  │              Model Serving Layer                      ││       │
│  │  ┌──────────┐  ┌──────────┐  ┌──────────────────┐   │▼       │
│  │  │  Batch   │  │Real-time │  │ Deployment Strategy│   │       │
│  │  │ Serving  │  │ Serving  │  │ - A/B Testing     │   │       │
│  │   (Spark) (REST/   │  │ - Canary          │   │       │
│  │  │          │  │  gRPC)   │  │ - Shadow          │   │       │
│  │  └──────────┘  └──────────┘  └──────────────────┘   │       │
│  └───────────────────────────────────────────────────────┘       │
│                            │                                     │
│                            ▼                                     │
│  ┌───────────────────────────────────────────────────────┐       │
│  │              Monitoring Layer                          │       │
│  │  ┌────────────┐ ┌──────────────┐ ┌─────────────────┐ │       │
│  │  │ Data Drift │ │ Model Perf   │ │ Infrastructure  │ │       │
│  │  (Evidently) │ │ Monitoring (Prometheus/    │ │       │
│  │  │            │ │              │ │  Grafana)       │ │       │
│  │  └──────┬─────┘ └──────┬───────┘ └─────────────────┘ │       │
│  └─────────┼──────────────┼─────────────────────────────┘       │
│            │              │                                      │
│            ▼              ▼                                      │
│  ┌──────────────────────────────┐                                │
│  │   Alert & Retrain Trigger   │──── 재학습 파이프라인 트리거     │
│  └──────────────────────────────┘                                │
│                                                                    │
└────────────────────────────────────────────────────────────────────┘

아키텍처 구성 요소 간 데이터 흐름:

  1. 데이터 수집 및 전처리: 다양한 데이터 소스(DB, API, Streaming)에서 데이터를 수집하고, 데이터 파이프라인을 통해 전처리한다. DVC로 데이터를 버전 관리하고, Evidently로 데이터 품질을 검증한다.

  2. Feature Engineering: 전처리된 데이터를 Feature Store(Feast)에 저장한다. Offline Store는 학습용, Online Store는 서빙용 Feature를 제공한다.

  3. 모델 학습 및 실험 관리: Training Pipeline에서 모델을 학습하고, MLflow Tracking 또는 W&B로 실험을 추적한다. 파라미터, 메트릭, 아티팩트가 체계적으로 기록된다.

  4. 모델 등록 및 배포: 검증된 모델을 MLflow Model Registry에 등록하고, CI/CD 파이프라인(GitHub Actions + CML)을 통해 자동으로 테스트, 검증, 배포한다.

  5. Model Serving: Batch Serving(Spark) 또는 Real-time Serving(REST/gRPC)으로 예측을 제공하며, A/B Testing, Canary, Shadow 등의 배포 전략을 적용한다.

  6. 모니터링 및 재학습: Evidently로 Data Drift와 모델 성능을 모니터링하고, Prometheus/Grafana로 인프라를 모니터링한다. 이상이 감지되면 자동으로 재학습 파이프라인을 트리거한다.

이 아키텍처에서 핵심은 **피드백 루프(Feedback Loop)**이다. 모니터링에서 감지된 문제가 자동으로 재학습을 트리거하고, 재학습된 모델이 다시 검증, 등록, 배포되는 순환 구조가 MLOps의 본질이다.

10. 결론: MLOps 도입 가이드

MLOps를 처음 도입하는 팀에게는 점진적 접근(incremental approach)을 권장한다.

Phase 1 - 기반 구축 (Level 0에서 시작):

  • 버전 관리 시스템 도입: 코드(Git), 데이터(DVC)
  • 실험 추적 도구 도입: MLflow Tracking 또는 W&B
  • 기본적인 모델 서빙 환경 구축

Phase 2 - 파이프라인 자동화 (Level 1 달성):

  • 학습 파이프라인 자동화 (Airflow, Kubeflow 등)
  • Feature Store 도입 (Feast)
  • Model Registry 도입 (MLflow Model Registry)
  • 기본적인 모니터링 구축 (Evidently)

Phase 3 - CI/CD 통합 (Level 2 달성):

  • CI/CD 파이프라인 구축 (GitHub Actions + CML)
  • 자동화된 테스트(데이터, 모델, 파이프라인)
  • 고급 배포 전략 (A/B Testing, Canary)
  • 포괄적 모니터링 및 자동 재학습

각 단계에서 조직의 ML 성숙도와 팀 규모, 비즈니스 요구사항을 고려하여 적절한 도구와 프로세스를 선택하는 것이 중요하다. 완벽한 MLOps 시스템을 처음부터 구축하려는 것보다, 현재 가장 큰 병목(bottleneck)을 해결하는 데 집중하고 점진적으로 확장해 나가는 것이 현실적이고 효과적인 전략이다.

References

  1. Google Cloud, "MLOps: Continuous delivery and automation pipelines in machine learning" - https://docs.cloud.google.com/architecture/mlops-continuous-delivery-and-automation-pipelines-in-machine-learning
  2. Google Cloud, "Practitioners Guide to MLOps" - https://cloud.google.com/resources/mlops-whitepaper
  3. Sculley et al., "Hidden Technical Debt in Machine Learning Systems", NeurIPS 2015 - https://papers.neurips.cc/paper/5656-hidden-technical-debt-in-machine-learning-systems.pdf
  4. MLflow Official Documentation - https://mlflow.org/docs/latest/
  5. MLflow Tracking - https://mlflow.org/docs/latest/ml/tracking/
  6. MLflow Model Registry - https://mlflow.org/docs/latest/ml/model-registry/
  7. Feast Official Documentation - https://docs.feast.dev
  8. DVC Official Documentation - https://doc.dvc.org/
  9. DVC Data Pipelines - https://doc.dvc.org/start/data-pipelines/data-pipelines
  10. CML (Continuous Machine Learning) - https://cml.dev/
  11. Iterative CML GitHub - https://github.com/iterative/cml
  12. Evidently AI Official - https://www.evidentlyai.com
  13. Evidently AI GitHub - https://github.com/evidentlyai/evidently
  14. Evidently AI, "What is data drift in ML" - https://www.evidentlyai.com/ml-in-production/data-drift
  15. Evidently AI, "What is concept drift in ML" - https://www.evidentlyai.com/ml-in-production/concept-drift
  16. Weights & Biases Documentation - https://docs.wandb.ai
  17. Weights & Biases Experiment Tracking - https://wandb.ai/site/experiment-tracking/