再トレーニングループを自動化する
1つのデプロイを再現可能なループに変えます。手順書、スクリプト化された昇格ゲート、ロールバック可能な自動リリース、週次レビューを用意します。
最初のデプロイはプロジェクトですが、その後のデプロイはすべてプロセスです。ループをスクリプト化しているチームは、ホールドアウトアラートが発生するたびに午後のうちに再トレーニングできます。スクリプト化していないチームは、プレッシャーの中で記憶を頼りに手順を再構築して回帰をリリースしてしまいます。このレッスンでは、pillモデルを使ってファインチューニング、ゲート、リリースまでの一連のループを実行し、次回から定型作業にできる手順書を作成します。
実践的
すべてのステップに担当者を置くループ#
前のレッスンに取り組んでいれば、系列情報は自動的に記録されています。モデルの Run Information カードには親モデルと固定されたデータセットバージョンが表示され、データセットの Models タブには各バージョンでトレーニングされたすべてのモデルが一覧表示されます。また、デプロイページからは、そのデプロイで使用されているモデルを確認できます。精度が低下したら、デプロイから始めてさかのぼって確認します。

エージェントがデータ収集のステップを自動化します。Collect Uncertain Detections はデプロイを通じて推論を行い、信頼度が指定範囲内の検出結果を含む画像をレビュー用データセットにコピーします。Capture and Alert は条件に一致する画像を保存し、Slackに投稿します。ワークフローは Run をクリックしたときに実行されるため、週次レビューの一環として実行してください。

実例:Pill Modelでの一連のサイクル#
1. デプロイ済みモデルからファインチューニングします。 Platformで My Models からデプロイ済みモデルを選択し、Save Dataset Version を有効にして、オプティマイザーを明示的に設定します。ローカルでは、同じ手順を次のように実行します。
from ultralytics import YOLO
model = YOLO("pills-v1.pt") # デプロイ済みモデルのbest.pt
model.train(data="medical-pills.yaml", epochs=5, imgsz=320, optimizer="SGD", lr0=0.001, name="v2-finetune")これはトレーニング、実行結果の確認、ファインチューニングのレッスンで行ったファインチューニングです。mAP50-95は0.659から0.687に上昇しました。
2. デプロイ済みモデルと比較して合否を判定します。 レッスン6の gate.py をホールドアウトデータと2つのチェックポイントに対して再利用します。
DATA = "medical-pills.yaml" # ホールドアウトデータセットのYAMLまたはul:// URI
BASELINE, CANDIDATE = "pills-v1.pt", "pills-v2.pt" # デプロイ済みモデルと再トレーニング候補PASS mAP50-95 0.659 -> 0.687 beats noise
PASS every class keeps 90% of its AP (weak: none)
PASS inference 4.0 ms within 100 ms
verdict: ship the candidate判定処理が終了コード0を返すため、CIはリリースのステップに進めます。(このデモでは、medical-pillsのvalスプリットをホールドアウトの代わりに使用しています。本番環境では、モデルが一度も見ていないホールドアウトバージョンを使用してください。)
3. リリースします。 候補モデルを同じワークスペースにアップロードするかトレーニングし、CIからultralytics-platform SDKを呼び出して Replace model を実行し、どのモデルが使用されているかを確認します。
import time
from ultralytics_platform import Platform
OWNER, DEPLOYMENT = "your-username", "pill-detector-st-ghislain"
PROJECT, NEW_MODEL = "pill-inspection", "v2-finetune"
with Platform() as client: # reads ULTRALYTICS_API_KEY
body = {"action": "replace", "project": PROJECT, "model": NEW_MODEL}
reply = client.deployments.update(OWNER, DEPLOYMENT, body=body)
print(reply["status"], "-", reply["message"]) # "deploying" while the new model starts
while (deployment := client.deployments.retrieve(OWNER, DEPLOYMENT)["deployment"])["status"] == "deploying":
time.sleep(15)
print(f"status={deployment['status']} model={deployment.get('model')}")
if deployment.get("model") != NEW_MODEL: # a failed rollout leaves the previous model serving
raise SystemExit("Replacement failed; the previous model is still live")deploying を1回、その後 ready を返すスタブAPIに対して実行すると、次のように出力されます。
deploying - Replacement model is deploying
status=ready model=v2-finetunedeployments.update は action: "replace" を使って PATCH /api/deployments/{owner}/{deployment} を送信します。新しいモデルの準備が整うまでは、以前のモデルが使用されます。ループはステータスが deploying から変わるまで retrieve をポーリングし、その後、使用中のモデルを確認します。ロールアウトに失敗した場合も、以前のモデルのまま ready に到達するためです。ロールバックするには、同じスクリプトで NEW_MODEL に以前のバージョンを指定します。ultralytics に付属する ul cloud コマンドラインツールも同じAPIをラップしており、APIリファレンスですべての呼び出し方法を説明しています。
4. ベースラインをリセットします。 レッスン8の holdout_check.py を、新しいチェックポイントと新しい履歴ファイルを使って実行します。
ランブックを作成する#
# Retraining runbook: pill-detector
## Trigger
- Holdout mAP50-95 more than 1 point below baseline for 2 consecutive weeks, OR
- Batch Annotation edit rate above 25% on a new batch.
## Steps
1. Collect: Save to dataset from Monitoring, plus the "Collect Uncertain Detections" agent into pill-review.
2. Label: Batch Annotation with the deployed model at the swept threshold; review every image; record the edit rate.
3. Merge into the training dataset; rerun the duplicate check, class audit, and Clustering.
4. Create dataset version v(n+1) with a description of what changed.
5. Fine-tune from the deployed model with Save Dataset Version on; optimizer SGD, lr0 0.001.
6. Run gate.py against the deployed model on the holdout. Stop here on any FAIL.
7. ML lead approves; CI runs release.py.
8. Watch endpoint_check.py for 24 hours; start a new holdout baseline.
## Rollback
- Run release.py with NEW_MODEL set to the previous version. Never delete that model while it's the rollback target.
## Owner
- ML lead approves step 7. On-call runs steps 1-6 and 8.週次レビューとして15分の予定をカレンダーに設定し、次の2点を確認します。赤信号(エンドポイントのチェック、ホールドアウト、編集率)はあるか。デプロイに変更があったか、あった場合はその理由は何か。ほとんどの週はどちらも「いいえ」で、ミーティングは5分で終わります。一般的な四半期の例を示します。
Week 1 : Holdout alert. Collect, label, retrain, gate, release v(n+1).
Week 2-3 : Quiet. Checks green.
Week 4 : New defect class requested. Label, new version, retrain v(n+2).
Week 5-7 : Quiet.
Week 8 : Second plant in Poland. Check regions; add an endpoint in europe-central2.
Week 9-11: Quiet.
Week 12 : Quarterly holdout refresh and review.よくある落とし穴#
症状: リリースに問題が発生し、以前のモデルが見つかりません。対処法: プロジェクトには、本番環境で使用している直近 2 つ以上のモデルを保持してください。モデルを削除するとゴミ箱に移動し、完全に削除すると、そのモデルを引き続き使用しているデプロイも削除されます。
症状: 10%/50%/100% のカナリアリリースを計画していたのに、Replace model によってすべてのトラフィックが一度に切り替わります。対処法: エンドポイントが提供するモデルは 1 つです。カナリアリリースでは、候補モデルを 2 つ目のエンドポイントにデプロイして、自前のルーターでトラフィックを分割し、その後モデルを置き換えて 2 つ目のエンドポイントを削除してください。
症状: すべての候補がゲートを通過するのに、本番環境では依然として性能が低下します。対処法: ゲートが正しく機能するのは、どの実行でもトレーニングに使っていないホールドアウトバージョンを使用した場合だけです。ホールドアウトは専用の非公開データセットに保持し、トレーニングデータには決して統合しないでください。
解答を表示
Pillラインでのサイクル例。トリガー:夜勤のホールドアウトチェックが0.05低下。収集:夕方シフトのMonitoringの例180件を pill-review に保存し、Collect Uncertain Detectionsエージェントから120件を追加。デプロイ済みの v2-finetune を使用したBatch Annotationを信頼度0.35で実行し、編集率は18%。レビューしてマージし、監査で問題がないことを確認。バージョンは v6: +300 night-shift frames。v2-finetune から v3-night をSGD、lr0 0.001、20エポックでファインチューニング。夜勤画像100件を含む300枚のホールドアウトで判定:mAP50-95は0.66から0.71に上昇し、弱いクラスはなく、所要時間は4 ms。合格。NEW_MODEL = "v3-night" を使った release.py は status=ready model=v3-night を報告し、holdout_check.py が0.71の新しいベースラインを書き込みます。v2-finetune はロールバック対象としてプロジェクトに残し、ランブック、判定処理、リリーススクリプトをまとめてコミットします。