モデルを壊さずに本番環境へ移行する方法
あなたのノートPCでノートブックはAUC 0.91を記録しました。モデルは今稼働中で、3%のリクエストに対して-infinityを返し、オンコールエンジニアは午前2時にページされ、乱数シードを固定していなかったため元の学習実行を再現できません。「モデルが動く」と「モデルが出荷できる」の間のギャップへようこそ。
私は6つの会社で、5つの異なるMLスタックで、このシーンが繰り返されるのを見てきました。パターンは変わりません。損失はアルゴリズムのものではなく、運用上のものです。学習と推論の乖離が、本番のAUCを4〜7ポイント静かに下げます。昨日は正常に動いていた特徴量パイプラインが、今日は誰かが上流のスキーマを変えて通知しなかったためにNaNを出力します。エンジニアがモデルをブラックボックスとして扱うのは、あなたが彼らのサービスをブラックボックスとして扱ったからです。
これは私が最初の本番インシデントの前に誰かに渡してほしかったPlaybookです。モデルが静かな収益ラインになるか、繰り返す事後分析のトピックになるかを決める7つのことをカバーしています。
なぜ今重要なのか
ほとんどのData Scienceチームは、オフラインのAUCとオンラインのビジネスへの影響の間で、モデルの価値の30〜50%を失います。私が作った数字ではありません。直近3つの出荷モデルで計算してみてください。オフラインの改善、オンラインの改善、「マージ済み」から「完全に展開完了」までの時間。ギャップはほぼ常に人員の問題であり、アルゴリズムの問題ではありません。
ロールバックの規律、モデル監視、エンジニアとのインターフェースを所有するData Scientistは、わずかに優れたモデルアーキテクチャを持つData Scientistの5倍の価値を出荷します。本番対応の準備は規律であり、ツールの選択ではありません。AWS BatchとPostgresテーブルでもできます。市場で最も高価なフィーチャーストアでも見事に失敗することもできます。
特徴量パイプライン: Feast対Tecton対DIY
私が個人的に引き起こした本番MLの失敗はすべて特徴量に起因します。具体的には: モデルが学習した特徴量が、スコアリング時にモデルが見た特徴量と一致しなかったことです。これを学習と推論の乖離と呼び、サイレントキラーです。
3つの選択肢:
DIY(PostGresテーブルまたはウェアハウスビュー)。 モデルが1つ、バッチスコアリング、同じSQLが学習データとサービングデータを生成する場合は問題ありません。ほとんどの会社はここから始めて、思っているより長く留まるべきです。罠: リアルタイム特徴量を追加し始めたとき、学習用に書いたSQL(ウェアハウスからの7日間ローリング合計)は、サービングサービスが実行するSQL(Redisからのストリーミング集計)と同じではありません。静かにドリフトします。
Feast(オープンソース)。 無料で、自分でホストします。3つ以上のモデルが特徴量を共有し、学習とオンラインサービングの両方で同じ定義を使い、RedisまたはDynamoDBとSparkまたはFlinkパイプラインを運用する意志がある場合に力を発揮します。正直なコスト: 特徴量が流れ始める前に四半期分のオンボーディングが必要です。1モデルフェーズを過ぎたなら価値があります。
Tecton(管理型)。 特徴量エンジニアリングが本当のボトルネックで、年間8〜20万ドルの予算があり、ストリーミングインフラを自分で運用したくない場合に購入を検討してください。Tectonは1つの定義でバックフィルとオンライン値の両方を生成することで学習と推論の乖離を解決します。リネージ追跡により「この特徴量が先週火曜日に変わった」という状況をあなたが気づく前に捕捉します。
意思決定は「どのツールが最良か」ではありません。問うべきは: モデルが1つか複数か、バッチかリアルタイムか、特徴量ドリフトが今現在自分には見えていないか。全部「はい」なら、フィーチャーストアが必要です。全部「いいえ」なら、ウェアハウスビューと学習・サービング両方でインポートする feature_definitions.py ファイルで十分です。
学習パイプラインの再現性
生データから、同じ分割と同じ指標で、本番稼働中のモデルを生み出した学習ジョブを今すぐ30分以内に再実行できますか?
答えが「いいえ」なら、再現可能なパイプラインはありません。お土産があるだけです。
再現性が実際に必要とするもの:
すべてのシードを固定する。 学習・テスト分割の
random_state=42だけでなく。numpy、PyTorch/TensorFlow、サンプラー、データシャッフラー、あらゆる水増し処理のシードを設定します。「同じノートブック」から2人のエンジニアがAUC 0.86と0.91を取得したモデルをデバッグしたことがあります。torchのCUDA RNGにシードが設定されていなかったためです。3日間を失いました。分割をハッシュ化する。 pandasのバージョン間で
train_test_splitが決定論的だと信用しないでください。行識別子(user_id、transaction_id)から安定したハッシュを計算し、分割比率でモジュロ演算します。同じ行は常に同じ分割に入ります。ボーナス: 新しいデータで再学習するとき、古いテストセットの行はテストに残ります。モデルアーティファクトにデータセットのSHAを記録する。 モデルカードには次の内容を含めるべきです: 学習データセットのSHA-256(特徴量エンジニアリング後)、学習期間(
2025-10-01 から 2026-03-31)、特徴量スキーマのバージョン、コードのコミット、ライブラリのロックファイルハッシュ、ホールドアウトでの評価指標、固定された参照セットでの評価指標。これはモデルの重みと同じGit LFSまたはMLflowアーティファクトに入ります。ランタイムをロックする。 モデルと一緒にコミットされた
requirements.lock、poetry.lock、またはuv.lock。ライブラリのバージョンドリフトは再現性を静かに壊します。scikit-learn 1.3対1.4だけで予測がずれることがあります。
「6週間前から学習を再実行する」テストは交渉の余地がありません。これをパスできなければ、回帰をデバッグできません。推測しているだけです。
バッチ対リアルタイムサービング、それぞれをいつ使うか
「リアルタイム」モデルのほとんどはバッチであるべきです。無視されるたびに繰り返すので2回言います。「リアルタイム」モデルのほとんどはバッチであるべきです。
意思決定ツリー:
- レイテンシー要件 > 1時間、予測の変化が遅い → 夜間バッチ。 午前2時に全員をスコアリングし、テーブルに書き込み、プロダクトはテーブルから読む。リードスコアリング、解約リスク、コールドスタートでないユーザーへのコンテンツ推薦。p99レイテンシー: SELECT文。
- レイテンシー要件 5〜60分、予測に時間単位の鮮度が必要 → 時間単位バッチ。 同じ形状で頻度が高い。在庫予測、需要シグナル。
- レイテンシー要件 30秒〜5分、セッションアクティビティに依存する → マイクロバッチ。 ストリーミングコンシューマーが30秒ごとに100〜1000件のレコードをスコアリング。不正シグナル、1分待てる異常検知。
- レイテンシー要件 < 200ms、リクエストが予測不可能 → リアルタイム。 広告ランキング、検索の関連性、チェックアウト時の不正ブロック、リアルタイムパーソナライゼーション。これが高価なものです。p99レイテンシー要件は、デプロイ後ではなく学習前にインターフェース契約で設定すべきです。
コストの差は膨大です。夜間バッチジョブは1時間、単一の大きなインスタンスで実行されます。リアルタイムサービスにはオートスケーリング、ウォームプール、p99モニタリング、ローテーション中のSREが必要です。本当の理由がない限りバッチを選んでください。
実話: リクエストごとに3つの特徴量ルックアップのためにPostgresを同期的に呼び出す「リアルタイム」推薦モデルを出荷しました。発見する前にp99が4秒になっていました。修正はPostgresを速くすることではありませんでした。モデルがリアルタイムである必要がないことを認め、バッチに移行し、事前計算済みテーブルから配信することでした。レイテンシーは8msに下がりました。推薦は実際にはセッション依存でなかったため、プロダクトチームは変更に気づきませんでした。
モデル監視: データドリフト、コンセプトドリフト、ビジネス指標
監視すべき4つのことがあります。3つは診断的です。1つだけが結果を出します。
入力ドリフト。 今日モデルが見ている特徴量は、学習したものと同じように分布していますか?特徴量ごとにPopulation Stability Index(PSI)を毎日追跡します。PSI > 0.1 = 調査。PSI > 0.25 = 学習時の分布と本番の分布がもはや同じではありません。アラートを出してください。連続した特徴量には、参照ウィンドウに対してKolmogorov-Smirnovテストも実行します。安くて速く、予測が悪化する前にスキーマの破損を捕まえます。
予測ドリフト。 モデルの出力は先週と同じように分布していますか?時に入力ドリフトは見えにくいですが(特徴量の相互作用が動く)、予測ドリフトは大きく出ます。モデル出力のp10/p50/p90を毎日追跡します。
コンセプトドリフト(ラベル遅延を考慮)。 特徴量とラベルの関係は変わりましたか?これは、多くのモデルで数日後または数週間後に到着するラベルがあるときにのみ確認できます。遅延評価パイプラインを構築します: ラベルが届いたら、それらの行のAUC/MAEを再計算して時間とともにグラフ化します。罠は、デプロイ翌日にラベルがまだない時点でAUCのアラートを設定すること。0を見続けることになります。
ビジネス指標。 収益。コンバージョン率。CAC。LTV。モデルが存在する目的となる数字。モデルが稼働し続けるかどうかを決める唯一の指標です。入力・予測ドリフトのアラート閾値は診断的です。ビジネス指標のアラート閾値は死活問題です。
美しく調整されたドリフトダッシュボードを持ちながら、収益が動いたかどうかについて全く可視性がないチームがモデルを出荷するのを見たことがあります。そのチームにならないでください。最初のダッシュボードはビジネスのものです。ドリフトダッシュボードは、ビジネス指標が動いた理由を説明するために存在します。代わりになるものではありません。
シャドーモード展開
スコアリングはするが、アクションはしない。1〜2週間。同じトラフィックで。新しいモデルの予測を既存モデルの予測と比較し、ラベルが届いたときの実際の結果と比較します。
これは本番MLで私が知る最もレバレッジの高いプラクティスであり、ほとんどのチームがスキップします。
シャドーモード展開の流れ:
- 既存モデルと並んで新しいモデルをデプロイします。両方がすべてのリクエストをスコアリングします。プロダクトの動作に影響するのは既存モデルの予測だけです。
- 両方の予測と使用したすべての特徴量をログに記録します。
- 7〜14日後に比較します:
- 分布の重なり: 同じインプットに対して2つのモデルが似た予測をしていますか?30%が異なるなら、切り替える前に理由を調べてください。
- オフラインの期待値との一致: 新しいモデルのオンラインの動作は、ホールドアウト評価が予測したものと一致しますか?オフラインで+5%の改善と言っていたのにシャドーでは同じなら、学習データがリークしていました。
- レイテンシー、エラー率、エッジケース(NaN入力、欠損特徴量): 新しいモデルはロングテールを処理できますか?
- シャドーデータがオフラインのストーリーを確認してからのみ切り替えます。
チャンピオン・チャレンジャーは同じアイデアを形式化したものです。既存モデルがチャンピオン。新しいモデルがチャレンジャー。テストセットだけでなく、実際のトラフィックで勝つまでチャレンジャーを昇格させません。
展開自体は段階的にすべきです: 1% → 5% → 25% → 50% → 100%、各ステップの間に少なくとも24〜48時間空け、各段階でビジネス指標を監視します。何かが間違った方向に動いたら、一時停止します。合理化しないでください。
エンジニアとの協働: インターフェース契約
「pickleファイルを壁越しに投げる」モデルは毎回失敗します。代わりに機能するのはこれです。
学習を始める前に、プラットフォームエンジニアと座って1ページのインターフェース契約を書いてください。以下をカバーします:
- APIスキーマ。 入力フィールド、型、許可されるnull、バリデーションルール。出力フィールド、型、範囲。モデルがスコアリングできない場合(特徴量の欠損、モデルサーバーがダウン)、レスポンスはどのようになるか。
- レイテンシーSLO。 ミリ秒でのp50、p95、p99。これが、リアルタイム特徴量ルックアップができるか、オフテーブルのモデルアーキテクチャは何か、GPU推論が必要かを決めます。
- スループットSLO。 ピーク時の1秒あたりのリクエスト数。オートスケーリング設定を決めます。
- エラーバジェット。 サービスは何%のリクエストまで失敗を許容されますか?0.1%?1%?これが入力バリデーションの厳しさの基準を設定します。
- 所有権の境界。 モデルが間違った予測を返す場合はDSが担当。サービスが500を返す場合はエンジニアリングが担当。どちらも担当するのが3番目(モデルは動いているが予測が悪い場合)。
- ロールバックの権限。 誰がエスカレーションなしに緊急停止スイッチを引けますか?午前3時の答えは「オンコールエンジニア」であるべきで、「Camelliaにページする」ではありません。
書き留めてください。署名してください。ピンしてください。避けられない本番インシデントが起きたとき、契約があることで会話は責任の交渉ではなく問題の解決に集中できます。
ドラフトの契約を持ってその会議に現れるData Scientistは、入室した瞬間に信頼を勝ち取ります。ノートブックを持って「これをどうやってデプロイしますか?」と聞くData Scientistはゼロからのスタートです。
ロールバックの規律
すべてのデプロイには、テスト済みのロールバック手順が付いてきます。文書化されたロールバック手順ではありません。テスト済みのものです。
3つのコンポーネント:
- バージョンタグ。 すべてのモデルにバージョンを付けます(
pricing-model-v23)。ログに記録されたすべての予測にはスコアリングしたバージョンが含まれます。回帰を調査するとき、バージョンでフィルタリングできます。 - 緊急停止スイッチ。 60秒以内に新しいモデルから前のモデルにトラフィックを切り替える設定フラグ。再デプロイではありません。フラグの切り替えです。サービングサービスはリクエスト時にフラグを読み取ります。
- ロールバックの演習。 四半期ごとに、低トラフィックの時間帯に本番環境で5分間ロールバックを実施します。90日間引き金を引いていなければ、ロールバックは理論上のものです。つまり機能しません。
ロールバックが初めて必要なときは、前のモデルのアーティファクトがS3から削除されている、特徴量パイプラインがリファクタリングされている、または緊急停止スイッチが一度も機能していなかったことを発見するタイミングではありません。私は個人的にこの3つすべてを経験しました。
よくある落とし穴
- サービング時にモデルが見られないデータで学習する。 リーク。最も一般的な形式: 予測しているイベントの後にしか計算できない特徴量。ウェアハウスから計算した「最後のログインからの日数」特徴量は、予測タイムスタンプ以降のログインを含みます。明示的にカットオフしない限り。
random_state=42を固定するが、上流のサンプラーにシードを設定しない。 分割は決定論的だが、学習はそうではありません。- チャンピオン・チャレンジャーなしでデプロイする。 新しいモデルが良いかどうか推測しているだけです。
- 収益ではなくAUCでアラートを設定する。 AUCが0.84から0.82に下がった。悪い?分かりません。収益が上がったかもしれません。
- 90日間ロールバックをテストしていない。 ロールバックはありません。希望があるだけです。
- エンジニアをサービスデスクではなくパートナーとして扱わない。 彼らはあなたのモデルを同じように扱います。
テンプレートとツール
出荷されたすべてのモデルが持つべき4つのドキュメント:
- モデルカード。 データセットのSHA、学習期間、シード、特徴量スキーマのバージョン、ホールドアウトと固定参照での評価指標、サービングSLO、オーナー、デプロイ日、ロールバック手順。
- シャドーモード比較チェックリスト。 分布の重なり、オフラインとオンラインの一致、レイテンシー、エラー率、エッジケースの処理、ステークホルダーごとのサインオフ要件。
- ロールバックランブック。 ステップバイステップの緊急停止スイッチの操作、前のモデルがトラフィックを処理していることの確認方法、通知先、事後分析テンプレート。
- エンジニアとDSのインターフェース契約。 1ページ。APIスキーマ、SLO、エラーバジェット、所有権の境界、ロールバックの権限。DS、エンジニアリングリード、オンコールのローテーションに署名済み。
成功の測定
次のような状態なら正しくやっています:
- 生データから30分以内に本番稼働中の任意のモデルの正確な学習実行を再現できる。
- すべてのデプロイに、過去90日以内に演習済みのロールバックが付いている。
- モニタリングが、ビジネス指標が動いた後ではなく前にドリフトを捉える。
- プラットフォームエンジニアが「あなたと働くのは楽です」と促されずに言う。
- 直近3回のデプロイが退屈だった。
退屈なデプロイが目標です。ドラマは失敗です。退屈なデプロイを出荷するData Scientistが頻繁に出荷するData Scientistであり、わずかに優れたモデルアーキテクチャを持つ誰よりも速く価値を複利で積み上げます。
関連リソース

Principal Product Marketing Strategist