mcpField
M
model-deployment

model-deployment

github.com/secondskyクラウド・DevOps240386 回インストール5 週間前に更新
リポジトリ

model-deployment について

学習済み機械学習モデルを本番環境へデプロイするためのスキルガイドです。サービング方式、コンテナ化、監視に加え、検証やロールバックの実践方法を扱います。

主な機能

  1. 01REST、バッチ、ストリーミング、エッジでのサービング
  2. 02FastAPI予測サーバーのパターン
  3. 03Dockerコンテナへのデプロイ
  4. 04ヘルスチェックと入力検証
  5. 05レイテンシとモデルドリフトの監視
  6. 06バージョン管理とロールバックの指針

活用シーン

  1. 01REST API経由で予測を提供
  2. 02大量の予測バッチを処理
  3. 03本番環境のレイテンシとドリフトを監視
  4. 04問題のあるモデルデプロイをロールバック

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/secondsky/claude-skills --skill model-deployment

インストール後、Claude Code で/model-deploymentを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

references/
cicd-ml-models.md
containerization-deployment.md
fastapi-production-server.md
model-monitoring-drift.md

詳細

ML モデルのデプロイ

適切なサービングとモニタリングにより、学習済みモデルを本番環境にデプロイします。

デプロイの選択肢

方法用途レイテンシ
REST APIWeb サービス中
バッチ大規模処理該当なし
ストリーミングリアルタイム低
エッジデバイス上非常に低

FastAPI モデルサーバー

from fastapi import FastAPI
from pydantic import BaseModel
import joblib
import numpy as np

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

class PredictionRequest(BaseModel):
    features: list[float]

class PredictionResponse(BaseModel):
    prediction: float
    probability: float

@app.get('/health')
def health():
    return {'status': 'healthy'}

@app.post('/predict', response_model=PredictionResponse)
def predict(request: PredictionRequest):
    features = np.array(request.features).reshape(1, -1)
    prediction = model.predict(features)[0]
    probability = model.predict_proba(features)[0].max()
    return PredictionResponse(prediction=prediction, probability=probability)

Docker のデプロイ

FROM python:3.12-slim

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

COPY model.pkl .
COPY app.py .

EXPOSE 8000
CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "8000"]

モデルのモニタリング

class ModelMonitor:
    def __init__(self):
        self.predictions = []
        self.latencies = []

    def log_prediction(self, input_data, prediction, latency):
        self.predictions.append({
            'input': input_data,
            'prediction': prediction,
            'latency': latency,
            'timestamp': datetime.now()
        })

    def detect_drift(self, reference_distribution):
        # Compare current predictions to reference
        pass

デプロイのチェックリスト

  • テストセットでモデルを検証済み
  • API エンドポイントを文書化済み
  • ヘルスチェックエンドポイントを用意済み
  • 認証を設定済み
  • ロギングとモニタリングを設定済み
  • モデルのバージョン管理を実施済み
  • ロールバック手順を文書化済み

クイックスタート:6 ステップでモデルをデプロイ

# 1. Save trained model
import joblib
joblib.dump(model, 'model.pkl')

# 2. Create FastAPI app (see references/fastapi-production-server.md)
# app.py with /predict and /health endpoints

# 3. Create Dockerfile
cat > Dockerfile << 'EOF'
FROM python:3.12-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY app.py model.pkl ./
CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "8000"]
EOF

# 4. Build and test locally
docker build -t model-api:v1.0.0 .
docker run -p 8000:8000 model-api:v1.0.0

# 5. Push to registry
docker tag model-api:v1.0.0 registry.example.com/model-api:v1.0.0
docker push registry.example.com/model-api:v1.0.0

# 6. Deploy to Kubernetes
kubectl apply -f deployment.yaml
kubectl rollout status deployment/model-api

既知の問題を未然に防ぐ

1. ヘルスチェックがないとダウンタイムが発生

問題:ロードバランサーが異常な Pod にトラフィックを送信し、503 エラーが発生します。

解決策:ライブネスプローブとレディネスプローブの両方を実装します。

# app.py
@app.get("/health")  # Liveness: Is service alive?
async def health():
    return {"status": "healthy"}

@app.get("/ready")  # Readiness: Can handle traffic?
async def ready():
    try:
        _ = model_store.model  # Verify model loaded
        return {"status": "ready"}
    except:
        raise HTTPException(503, "Not ready")
# deployment.yaml
livenessProbe:
  httpGet:
    path: /health
    port: 8000
  initialDelaySeconds: 30
readinessProbe:
  httpGet:
    path: /ready
    port: 8000
  initialDelaySeconds: 5
2. コンテナ内でモデルが見つからないエラー

問題:コンテナの起動時に FileNotFoundError: model.pkl が発生します。

解決策:Dockerfile でモデルファイルがコピーされていることと、パスが一致していることを確認します。

# ❌ Wrong: Model in wrong directory
COPY model.pkl /app/models/  # But code expects /app/model.pkl

# ✅ Correct: Consistent paths
COPY model.pkl /models/model.pkl
ENV MODEL_PATH=/models/model.pkl

# In Python:
model_path = os.getenv("MODEL_PATH", "/models/model.pkl")
3. 入力検証が未処理だと500エラーが発生

問題:無効な入力によって API が未処理の例外を発生させ、クラッシュします。

解決策:Pydantic を使用して自動検証します。

from pydantic import BaseModel, Field, validator

class PredictionRequest(BaseModel):
    features: List[float] = Field(..., min_items=1, max_items=100)

    @validator('features')
    def validate_finite(cls, v):
        if not all(np.isfinite(val) for val in v):
            raise ValueError("All features must be finite")
        return v

# FastAPI auto-validates and returns 422 for invalid requests
@app.post("/predict")
async def predict(request: PredictionRequest):
    # Request is guaranteed valid here
    pass
4. ドリフトのモニタリングがないと劣化に気付けない

問題:モデルの性能が時間とともに劣化しても、ユーザーから苦情が寄せられるまで誰も気付きません。

解決策:ドリフト検出を実装します(references/model-monitoring-drift.md を参照)。

monitor = ModelMonitor(reference_data=training_data, drift_threshold=0.1)

@app.post("/predict")
async def predict(request: PredictionRequest):
    prediction = model.predict(features)
    monitor.log_prediction(features, prediction, latency)

    # Alert if drift detected
    if monitor.should_retrain():
        alert_manager.send_alert("Model drift detected - retrain recommended")

    return prediction
5. リソース制限がないと OOM による強制終了が発生

問題:Kubernetes の OOMKiller によって Pod が強制終了し、サービスが停止します。

解決策:メモリと CPU の制限およびリクエストを設定します。

resources:
  requests:
    memory: "512Mi"  # Guaranteed
    cpu: "500m"
  limits:
    memory: "1Gi"    # Max allowed
    cpu: "1000m"

# Monitor actual usage:
kubectl top pods
6. ロールバック計画がないと問題のあるデプロイから戻れない

問題:新しいモデルバージョンにバグがあっても、すぐに元に戻す方法がありません。

解決策:イメージにバージョンタグを付け、前のデプロイを保持します。

# Deploy with version tag
kubectl set image deployment/model-api model-api=registry/model-api:v1.2.0

# If issues, rollback to previous
kubectl rollout undo deployment/model-api

# Or specify version
kubectl set image deployment/model-api model-api=registry/model-api:v1.1.0
7. 同期予測ではバッチ処理が遅い

問題:10,000 件の予測を1件ずつ処理すると、何時間もかかります。

解決策:バッチエンドポイントを実装します。

@app.post("/predict/batch")
async def predict_batch(request: BatchPredictionRequest):
    # Process all at once (vectorized)
    features = np.array(request.instances)
    predictions = model.predict(features)  # Much faster!
    return {"predictions": predictions.tolist()}
8. CI/CD での検証がないと不良モデルをデプロイしてしまう

問題:基本的なテストに失敗するモデルをデプロイし、本番環境に支障が生じます。

解決策:CI パイプラインで検証します(references/cicd-ml-models.md を参照)。

# .github/workflows/deploy.yml
- name: Validate model performance
  run: |
    python scripts/validate_model.py \
      --model model.pkl \
      --test-data test.csv \
      --min-accuracy 0.85  # Fail if below threshold

ベストプラクティス

  • すべてにバージョンを付ける:モデル(セマンティックバージョニング)、Docker イメージ、デプロイ
  • 継続的にモニタリングする:レイテンシ、エラー率、ドリフト、リソース使用量
  • デプロイ前にテストする:ユニットテスト、統合テスト、性能ベンチマーク
  • 段階的にデプロイする:カナリア(10%)の後、全体に展開
  • ロールバックに備える:前のバージョンを保持し、手順を文書化
  • 予測をログに記録する:デバッグとドリフト検出を可能にする
  • リソース制限を設定する:OOM による強制終了とリソース競合を防止
  • ヘルスチェックを使用する:適切なロードバランシングを可能にする

リファレンスを読み込むタイミング

詳細な実装を確認するには、リファレンスファイルを読み込んでください。

  • FastAPI 本番サーバー:エラーハンドリング、バリデーション(Pydantic モデル)、ロギング、ヘルスチェック/レディネスチェック、バッチ予測、モデルのバージョン管理、ミドルウェア、例外ハンドラー、パフォーマンス最適化(キャッシュ、非同期処理)を含む、本番環境ですぐに使用できる完全な FastAPI 実装については、references/fastapi-production-server.md を読み込んでください。

  • モデルのモニタリングとドリフト:KS 検定によるドリフト検出、Jensen-Shannon ダイバージェンス、Prometheus メトリクスとの統合、アラート設定(Slack、メール)、継続的なモニタリングサービス、ダッシュボードのエンドポイントを備えた ModelMonitor の実装については、references/model-monitoring-drift.md を読み込んでください。

  • コンテナ化とデプロイ:マルチステージ Dockerfile、コンテナ内でのモデルのバージョン管理、Docker Compose のセットアップ、Nginx を使用した A/B テスト、Kubernetes のデプロイ(ローリングアップデート、ブルーグリーン、カナリア)、GitHub Actions の CI/CD、デプロイのチェックリストについては、references/containerization-deployment.md を読み込んでください。

  • ML モデルの CI/CD:モデルの検証、データの検証、自動テスト、セキュリティスキャン、パフォーマンスベンチマーク、自動ロールバック、デプロイ戦略を含む完全な GitHub Actions パイプラインについては、references/cicd-ml-models.md を読み込んでください。

コメント