ml-ops-engineer について
MLOps エンジニア向けに、モデルデプロイ、トレーニングパイプライン、モデルレジストリ、ドリフト監視、フィーチャーストア、ML CI/CD を扱うスキルです。モデルバージョンの管理、データドリフト検出、パイプライン定義の検証用スクリプトも含みます。
主な機能
- 01トレーニングパイプラインを計画・拡張
- 02リアルタイムまたはバッチのデプロイを設定
- 03レジストリのバージョンとライフサイクル段階を管理
- 04データドリフトを検出し監視アラートを設定
- 05フィーチャーストアと実験追跡のパターンを定義
- 06パイプライン構成とデプロイ条件を検証
活用シーン
- 01モデル学習からデプロイまでの流れを設計
- 02モデルバージョンを比較して昇格
- 03参照データと本番データのドリフトを確認
- 04デプロイ前に ML パイプライン定義を検証
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ borghei/ claude-skills --skill ml-ops-engineerインストール後、Claude Code で/ml-ops-engineerを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
REFERENCE.mdscripts/drift_detector.pymodel_registry.pypipeline_validator.py詳細
MLOps エンジニア
エージェントはシニア MLOps エンジニアとして、モデルの本番環境へのデプロイ、トレーニングパイプラインのオーケストレーション、モデルの健全性の監視、フィーチャーストアの管理、ML CI/CD の自動化を行います。
まず確認すること
デプロイする前に、以下の入力を確定してください。入力が不足している、または曖昧で、結果に影響する場合は質問してください。影響しない場合は、妥当なデフォルト値を使い、使用した値を伝えてください。
- サービング方式 + レイテンシ SLA: リアルタイム(FastAPI/K8s)またはバッチ、および P99 の目標値(デプロイアーキテクチャ全体を左右します)。
- 現在の MLOps 成熟度: 手動、パイプライン、CI/CD、または完全な運用(最初に解決すべき最も影響の大きいギャップを特定します)。
- モデルアーティファクト + レジストリ/インフラ: フレームワーク、保存場所、対象プラットフォーム(MLflow、K8s)(サービングとレジストリの設定を左右します)。
- 監視のしきい値: ドリフトと精度低下の上限、およびチェックの間隔(アラートルールとドリフト検出の設定を左右します)。
リクエストに最も重要な入力を2つか3つ尋ね、リスト全体について質問しないでください。ユーザーがすぐに結果を求める場合は、結果を提示し、冒頭に前提条件を記載してください。
ワークフロー
- ML の成熟度を評価する -- 現在のレベル(手動ノートブック、自動化されたパイプライン、完全な CI/CD)を判断します。最初に解決すべき、最も影響の大きいギャップを特定します。
- トレーニングパイプラインを構築または拡張する -- データ取得、検証、前処理、トレーニング、評価の各ステージを定義します。Kubeflow、Airflow、または同等のツールを使用します。精度のしきい値(例:> 0.85)をデプロイのゲートにします。
- サービング用にモデルをデプロイする -- レイテンシ要件に基づき、リアルタイム(FastAPI + K8s)またはバッチ(Spark/Parquet)を選択します。ヘルスチェック、自動スケーリング、リソース上限を設定します。
- モデルレジストリに登録する -- パラメーター、メトリクス、アーティファクトを MLflow に記録します。最も優れたバージョンを Production ステージに移行し、前のバージョンをアーカイブします。
- 監視を計測する -- レイテンシ(P50/P95/P99)、エラー率、予測分布、特徴量ドリフトのダッシュボードを設定します。アラートのしきい値を設定します。
- エンドツーエンドで検証する -- サービングエンドポイントに対してスモークテストを実行します。監視ダッシュボードにデータが表示されることを確認します。ロールバック手順が機能することを検証します。
MLOps 成熟度モデル
| レベル | 機能 | 主な兆候 |
|---|---|---|
| 0 - 手動 | Jupyter ノートブック、手動デプロイ | モデルのバージョン管理なし |
| 1 - パイプライン | トレーニングの自動化、モデルのバージョン管理 | MLflow トラッキングを使用中 |
| 2 - CI/CD | 継続的なトレーニング、自動テスト | フィーチャーストアが稼働中 |
| 3 - 完全な MLOps | ドリフト時の自動再トレーニング、A/B テスト | SLA に裏付けられた監視 |
リアルタイムサービングの例
# model_server.py -- FastAPI model serving
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
import mlflow.pyfunc, time
app = FastAPI()
model = mlflow.pyfunc.load_model("models:/fraud_detector/Production")
class PredictionRequest(BaseModel):
features: list[float]
class PredictionResponse(BaseModel):
prediction: float
model_version: str
latency_ms: float
@app.post("/predict", response_model=PredictionResponse)
async def predict(req: PredictionRequest):
start = time.time()
try:
pred = model.predict([req.features])[0]
return PredictionResponse(
prediction=pred,
model_version=model.metadata.run_id,
latency_ms=(time.time() - start) * 1000,
)
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
@app.get("/health")
async def health():
return {"status": "healthy", "model_loaded": model is not None}
Kubernetes のデプロイ
# k8s/model-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: model-server
spec:
replicas: 3
selector:
matchLabels: {app: model-server}
template:
metadata:
labels: {app: model-server}
spec:
containers:
- name: model-server
image: gcr.io/project/model-server:v1.2.3
ports: [{containerPort: 8080}]
resources:
requests: {memory: "2Gi", cpu: "1000m"}
limits: {memory: "4Gi", cpu: "2000m", nvidia.com/gpu: 1}
env:
- {name: MODEL_URI, value: "s3://models/production/v1.2.3"}
readinessProbe:
httpGet: {path: /health, port: 8080}
initialDelaySeconds: 30
periodSeconds: 10
---
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: model-server-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: model-server
minReplicas: 2
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target: {type: Utilization, averageUtilization: 70}
ドリフト検出
# monitoring/drift_detector.py
import numpy as np
from scipy import stats
from dataclasses import dataclass
@dataclass
class DriftResult:
feature: str
drift_score: float
is_drifted: bool
p_value: float
def detect_drift(reference: np.ndarray, current: np.ndarray, threshold: float = 0.05) -> DriftResult:
"""Detect distribution drift using Kolmogorov-Smirnov test."""
statistic, p_value = stats.ks_2samp(reference, current)
return DriftResult(feature="", drift_score=statistic, is_drifted=p_value < threshold, p_value=p_value)
def monitor_all_features(reference: dict, current: dict, threshold: float = 0.05) -> list[DriftResult]:
"""Run drift detection across all features; return list of results."""
results = []
for feat in reference:
r = detect_drift(reference[feat], current[feat], threshold)
r.feature = feat
results.append(r)
return results
アラートルール
ALERT_RULES = {
"latency_p99": {"threshold": 200, "severity": "warning", "msg": "P99 latency exceeded 200 ms"},
"error_rate": {"threshold": 0.01, "severity": "critical", "msg": "Error rate exceeded 1%"},
"accuracy_drop": {"threshold": 0.05, "severity": "critical", "msg": "Accuracy dropped > 5%"},
"drift_score": {"threshold": 0.15, "severity": "warning", "msg": "Feature drift detected"},
}
フィーチャーストア(Feast)
# features/customer_features.py
from feast import Entity, Feature, FeatureView, FileSource, ValueType
from datetime import timedelta
customer = Entity(name="customer_id", value_type=ValueType.INT64)
customer_stats = FeatureView(
name="customer_stats",
entities=["customer_id"],
ttl=timedelta(days=1),
features=[
Feature(name="total_purchases", dtype=ValueType.FLOAT),
Feature(name="avg_order_value", dtype=ValueType.FLOAT),
Feature(name="days_since_last_order", dtype=ValueType.INT32),
Feature(name="lifetime_value", dtype=ValueType.FLOAT),
],
online=True,
source=FileSource(
path="gs://features/customer_stats.parquet",
timestamp_field="event_timestamp",
),
)
サービング時のオンライン取得:
from feast import FeatureStore
store = FeatureStore(repo_path=".")
features = store.get_online_features(
features=["customer_stats:total_purchases", "customer_stats:avg_order_value"],
entity_rows=[{"customer_id": 1234}],
).to_dict()
実験トラッキング(MLflow)
import mlflow
mlflow.set_tracking_uri("http://mlflow.company.com")
mlflow.set_experiment("fraud_detection")
with mlflow.start_run(run_name="xgboost_v2"):
mlflow.log_params({"n_estimators": 100, "max_depth": 6, "learning_rate": 0.1})
model = train_model(X_train, y_train)
mlflow.log_metrics({
"accuracy": accuracy_score(y_test, preds),
"f1": f1_score(y_test, preds),
})
mlflow.sklearn.log_model(model, "model", registered_model_name="fraud_detector")
パイプラインの詳細な例(Kubeflow、Airflow DAG、完全な CI/CD ワークフロー)については、REFERENCE.md を参照してください。
参考資料
REFERENCE.md-- 詳細なパターン:Kubeflow パイプライン、Airflow DAG、CI/CD ワークフロー、モデルレジストリの操作
スクリプト
python scripts/model_registry.py register --name fraud_detector --version v2.3 --metrics '{"f1":0.91,"auc":0.95}' --params '{"n_estimators":200}'
python scripts/model_registry.py promote --name fraud_detector --version v2.3 --stage production
python scripts/model_registry.py list --stage production --json
python scripts/model_registry.py compare --name fraud_detector --versions v2.2 v2.3
python scripts/drift_detector.py --reference train_data.csv --current prod_data.csv
python scripts/drift_detector.py --reference baseline.csv --current latest.csv --threshold 0.1 --json
python scripts/pipeline_validator.py --pipeline pipeline.json --strict
python scripts/pipeline_validator.py --pipeline pipeline.json --json
ツールのリファレンス
| ツール | 目的 | 主なフラグ |
|---|---|---|
model_registry.py | メトリクス、パラメーター、ライフサイクルステージを使って、モデルバージョンを登録、昇格、一覧表示、比較します | register --name --version --metrics --params、promote --stage、list、compare --versions、--json |
drift_detector.py | KS 統計量、PSI、カイ二乗検定を使って、参照データセットと現在のデータセット間のデータ/モデルドリフトを検出します | --reference <csv>、--current <csv>、--columns、--threshold、--json |
pipeline_validator.py | ML パイプラインの定義について、完全性、ステージの順序、評価ゲート、ロールバック設定を検証します | --pipeline <json>、--strict、--json |
トラブルシューティング
| 問題 | 考えられる原因 | 解決方法 |
|---|---|---|
| モデルのレイテンシがP99のSLA(> 200 ms)を超える | モデルが大きすぎる、入力の前処理が遅い、またはPodのリソースが不足している | サービングエンドポイントをプロファイリングします。モデルの蒸留、入力のキャッシュ、またはCPU/メモリの上限引き上げを検討してください |
drift_detector.py がすべての特徴量をドリフトありと判定する | しきい値が低すぎる、または参照データの期間が想定と異なる | しきい値を引き上げる(0.15~0.2を試してください)か、より代表的な期間のデータから参照データセットを再生成してください |
| パイプラインが評価ゲートで失敗する | モデルの精度が設定済みのしきい値を下回った | 上流工程のデータ品質に問題がないか確認します。drift_detector.py で特徴量の分布を比較し、新しいデータで再トレーニングしてください |
| モデルレジストリに「already registered」エラーが表示される | 同じ名前とバージョンの組み合わせがすでに登録されている | 新しいバージョン文字列(例:v2.3.1)を使用するか、テスト用の登録であれば古いエントリを削除してください |
| KubernetesのPodでモデルサーバーがクラッシュループする | モデルのサイズがメモリ上限を超えてOOMキルされている、またはヘルスチェックのタイムアウトが短すぎる | resources.limits.memory を引き上げます。大きなモデルの場合は、readiness probeの initialDelaySeconds を延長してください |
| Feature Storeから古い特徴量が返される | マテリアライゼーションジョブが失敗した、またはTTLの期間外に実行された | マテリアライゼーションのログを確認し、materialize_features を再実行します。TTLの短縮または鮮度アラートの追加も検討してください |
pipeline_validator.py がSTAGE_ORDERエラーを報告する | パイプラインのステージが想定された順序(data -> transform -> train -> evaluate -> deploy)で定義されていない | 正規の順序に従うようステージを並べ替えます。バリデーターは、データのステージがトレーニングのステージより前にあることを想定しています |
成功基準
- すべての本番モデルが、トラフィックを処理する前に、バージョン、メトリクス、パラメーターとともにモデルレジストリに登録されていること。
- ドリフト検出が定期的(少なくとも週1回)に実行され、PSI > 0.2またはKS > 0.15の場合にアラートが発生すること。
- デプロイ前に、MLパイプラインが
pipeline_validator.py --strictをエラーなしで通過すること。 - モデルのサービングレイテンシがSLAの範囲内に収まること:P50 < 50 ms、P95 < 100 ms、P99 < 200 ms。
- 本番環境へのモデル昇格のたびに、直前の本番バージョンが自動的にアーカイブされること。
- 直前のモデルバージョンへのロールバックが、ダウンタイムなしで5分以内に完了すること。
- パイプラインのステージに、精度が定義済みのしきい値を下回った場合にデプロイを阻止する評価ゲートが含まれていること。
対象範囲と制限事項
対象範囲: モデルのデプロイ(リアルタイムおよびバッチ)、MLパイプラインのオーケストレーション、モデルレジストリの管理、ドリフト検出(データドリフト、概念ドリフト、予測ドリフト)、Feature Storeのパターン、モニタリングとアラート、Kubernetesのデプロイ設定、MLのCI/CD。
対象範囲外: モデルアーキテクチャの設計とアルゴリズムの選定(data-scientistを参照)、生データの取り込みパイプライン、BIダッシュボードの開発、ビジネス戦略。
制限事項: PythonツールはPython標準ライブラリのみを使用します。drift_detector.py は、ほとんどの分布に適した近似値を使ってKS統計量とPSIを計算しますが、多変量ドリフト検出やEvidently/Alibi Detectとの連携には対応していません。model_registry.py は状態をローカルのJSONファイルに保存します。実運用では、MLflow Model Registryまたは同様のプラットフォームと連携してください。pipeline_validator.py は構造と規約を検証しますが、パイプラインのステージは実行しません。
統合ポイント
- データサイエンティスト(
data-analytics/data-scientist):実験メタデータ付きのトレーニング済みモデルを受け取り、デプロイに向けて有望な実験をレジストリに登録します。 - アナリティクスエンジニア(
data-analytics/analytics-engineer):特徴量エンジニアリングのパイプラインは dbt マートモデルに依存する場合があり、スキーマの変更があるとパイプラインの再検証が必要になります。 - エンジニアリング(
engineering/senior-ml-engineer):サービングの制約(レイテンシ、メモリ、GPU)に合わせたモデルアーキテクチャの最適化について連携します。 - インフラストラクチャ(
engineering/):Kubernetes の設定、自動スケーリングポリシー、CI/CD ワークフローは、プラットフォームエンジニアリングと共同で管理します。 - ビジネスインテリジェンス(
data-analytics/business-intelligence):モデルの予測結果は BI ダッシュボードに反映される場合があり、監視メトリクスは運用ダッシュボードに表示されます。