LESSON 30分

デプロイメントパイプライン

田中VPoE「学習パイプラインとCI/CDの基本を押さえた。次はモデルを本番環境にデプロイするためのパイプラインを設計しよう。単にファイルを置き換えるだけでは不十分だ。」

あなた「Blue-Greenデプロイやカナリアリリースみたいな、段階的なデプロイ戦略が必要ということですか?」

田中VPoE「その通り。MLモデルのデプロイには、通常のアプリケーションにはない検証ステップが必要になる。順を追って学んでいこう。」

モデルデプロイの全体像

モデルデプロイメントパイプラインは、学習済みモデルを安全に本番環境へ配信するための一連のステップです。

デプロイメントパイプラインの構成要素

Model Registry → バリデーション → ステージング → 承認 → 本番デプロイ → 監視
フェーズ内容自動/手動
モデル取得Model Registryから指定バージョンを取得自動
バリデーション精度テスト・レイテンシテスト・入出力スキーマ検証自動
ステージングステージング環境でのE2Eテスト自動
承認本番昇格の承認(人間が判断)手動
本番デプロイデプロイ戦略に基づいた配信自動
監視デプロイ後の性能モニタリング自動

モデルサービングのパターン

本番環境でモデルを提供する方法は大きく3つあります。

1. REST API サービング

# FastAPI によるモデルサービング例
from fastapi import FastAPI
import mlflow
import pandas as pd

app = FastAPI()

# モデルのロード(起動時に1回だけ)
model = mlflow.pyfunc.load_model("models:/churn_model/Production")

@app.post("/predict")
async def predict(features: dict):
    input_df = pd.DataFrame([features])
    prediction = model.predict(input_df)
    return {
        "prediction": int(prediction[0]),
        "model_version": model.metadata.run_id
    }

2. バッチ推論

# バッチ推論パイプライン例
import mlflow
import pandas as pd

def batch_predict(input_path: str, output_path: str, model_name: str):
    """バッチ推論を実行する"""
    model = mlflow.pyfunc.load_model(f"models:/{model_name}/Production")
    input_df = pd.read_parquet(input_path)

    predictions = model.predict(input_df)
    input_df["prediction"] = predictions
    input_df["predicted_at"] = pd.Timestamp.now()

    input_df.to_parquet(output_path)
    print(f"Batch prediction completed: {len(input_df)} records")

3. エッジ/組み込みデプロイ

モデル最適化 → ONNX変換 → 量子化 → エッジデバイスへの配信
パターンユースケースレイテンシスケーラビリティ
REST APIリアルタイム推論低(ms単位)水平スケール可能
バッチ推論大量データ処理高(許容)データ量に応じて調整
エッジデバイス上推論最低デバイス数に依存

デプロイ戦略

Blue-Green デプロイ

                  ┌─── Blue(現行v1) ← 100% トラフィック
ロードバランサー ─┤
                  └─── Green(新v2) ← 0% トラフィック

切り替え後:
                  ┌─── Blue(現行v1) ← 0% トラフィック
ロードバランサー ─┤
                  └─── Green(新v2) ← 100% トラフィック
  • 利点:即座にロールバック可能
  • 欠点:リソースが2倍必要

カナリアリリース

                  ┌─── v1 ← 95% トラフィック
ロードバランサー ─┤
                  └─── v2 ← 5% トラフィック(カナリア)

段階的に比率を変更: 5% → 10% → 25% → 50% → 100%
  • 利点:問題を早期検知でき、影響範囲が限定的
  • 欠点:2つのバージョンの比較分析が必要

シャドウデプロイ

リクエスト → v1(本番応答) → ユーザーに返す
         └→ v2(シャドウ) → ログに記録(応答はしない)
  • 利点:ユーザーへの影響ゼロで新モデルを検証
  • 欠点:推論コストが2倍

Docker によるモデルパッケージング

# Dockerfile
FROM python:3.10-slim

WORKDIR /app

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

COPY app/ ./app/
COPY models/ ./models/

EXPOSE 8000

CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"]
# docker-compose.yml(ステージング環境)
version: "3.8"
services:
  model-api:
    build: .
    ports:
      - "8000:8000"
    environment:
      - MODEL_NAME=churn_model
      - MODEL_VERSION=Production
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8000/health"]
      interval: 30s
      timeout: 10s
      retries: 3

ロールバック戦略

本番デプロイ後に問題が発生した場合のロールバック手順を事前に定義しておくことが重要です。

ロールバック条件閾値例対応
レイテンシ増加p99 > 200ms前バージョンに即座に切り戻し
エラー率増加> 1%前バージョンに即座に切り戻し
精度低下AUC < 0.80前バージョンに切り戻し + 調査
データドリフト検知PSI > 0.25アラート発報 + 調査
# ロールバックスクリプト例
import mlflow

def rollback_model(model_name: str):
    """本番モデルを前バージョンにロールバックする"""
    client = mlflow.tracking.MlflowClient()

    # 現在のProductionバージョンを取得
    prod_versions = client.get_latest_versions(model_name, stages=["Production"])
    if not prod_versions:
        raise ValueError("No production model found")

    current = prod_versions[0]

    # Archivedから直前のバージョンを復元
    archived = client.get_latest_versions(model_name, stages=["Archived"])
    if not archived:
        raise ValueError("No archived version for rollback")

    previous = archived[0]

    # ステージ変更
    client.transition_model_version_stage(
        name=model_name,
        version=current.version,
        stage="Archived"
    )
    client.transition_model_version_stage(
        name=model_name,
        version=previous.version,
        stage="Production"
    )
    print(f"Rolled back from v{current.version} to v{previous.version}")

まとめ

項目ポイント
サービングパターンREST API・バッチ推論・エッジの3種類を使い分ける
デプロイ戦略Blue-Green・カナリア・シャドウから要件に応じて選択
パッケージングDockerでモデルと依存関係をまとめてコンテナ化
ロールバック閾値と手順を事前に定義し、即座に対応できる体制を作る

チェックリスト

  • 3種類のモデルサービングパターンの使い分けを説明できる
  • Blue-Green・カナリア・シャドウデプロイの違いを説明できる
  • Dockerによるモデルパッケージングの基本を理解している
  • ロールバック戦略の重要性と実装方法を説明できる

次のステップへ

デプロイメントパイプラインの設計を理解しました。次は、MLに特化したCI/CDパイプラインの実装方法を詳しく学びましょう。


推定読了時間:30分