Azure Custom Vision でトレーニングを開始したのに、ポータルの表示がいつまでも「Training…」から進まず、学習のやり直しもできない――そんな現場の“詰み”を最短で解消するための実践ガイドです。原因の多くはバックエンド混雑やリソース制約に起因します。本記事は、即効性のある復旧手順(REST API でのイテレーション削除)から再発防止の設計指針まで、運用に耐える具体策を網羅します。
Azure Custom Vision の学習が「Training…」のまま終わらない現象とは
少量画像(例:24 枚)でクイックトレーニングを実行したにもかかわらず、通常は数分で完了する処理が、数時間~数日、場合によってはさらに長い時間、ポータル上は「Training…」のまま進捗しないことがあります。さらに困るのは、進行中イテレーションをキャンセルできず、新しいトレーニングが開始できない点です。スタンダード系のリソース階層や、Advanced(予約)トレーニングの予算 1hでも発生し得ます。
典型的な困りごと
- ポータルに途中停止ボタンが存在しないため、ぶら下がったイテレーションを止められない。
- 該当イテレーションを削除できず、新しい学習がブロックされる。
- 課金がどうなるか不安(予算の上限やキュー待ち中の扱いが不明)。
まず押さえるべき要点(要約)
| 対処 | 詳細 |
|---|---|
| ① 原因の大半はバックエンド混雑/リソース不足 | 高トラフィックやリージョンの一時的なリソース枯渇で、学習ジョブが長時間キュー滞留することがある。 |
| ② ポータルからのキャンセルは不可 | 現在、ポータル UI に途中停止機能はない。Advanced(予約)トレーニングの「予算(Reserved Budget)」は上限として機能する。 |
| ③ 応急処置:REST API で該当イテレーションを削除 | DELETE /customvision/v3.3/Training/projects/{projectId}/iterations/{iterationId} を実行して強制削除。新規トレーニングが再び実行可能になる事例が多い(モデルとメトリクスは失われるため、必要に応じて事前エクスポート)。 |
| ④ 再発防止のヒント | 混雑時間帯を避ける/上位 SKU(S 系列のより高い層)や別リージョン活用/画像を分割して小刻みに学習/事前にサービス正常性を確認/継続発生ならサポートに相談。 |
| ⑤ サービス状況の読み方 | 一時的なリージョン混雑やメンテナンス、既知のインシデントの影響を受ける場合がある。再試行やリージョン切替で改善することがある。 |
| ⑥ 課金面 | Advanced 予算を設定していれば上限超過課金は抑制される。キュー待機時間は原則計算時間に含まれない。とはいえ、コスト管理で使用量を都度確認するのが安心。 |
即効性のある復旧:REST API でイテレーションを削除する
最短で現状を打破する方法は、Custom Vision Training API で問題のイテレーションをDELETE することです。削除後は新規トレーニングの実行が可能になります。以下では、安全に特定 → 退避(必要に応じて)→ 削除までを段階的に示します。
前提:必要な情報
- Endpoint(例:
https://<region>.api.cognitive.microsoft.com) - Training Key(Training-Key ヘッダーで使用)
- Project ID(ポータルのプロジェクト設定または API で取得)
- Iteration ID(該当イテレーションを API で列挙して確認)
ステップ 1:イテレーション一覧を取得し、問題の ID を特定
# 例:環境変数をセット
export ENDPOINT="https://<region>.api.cognitive.microsoft.com"
export TRAINING_KEY="<YOUR_TRAINING_KEY>"
export PROJECT_ID="<YOUR_PROJECT_ID>"
# イテレーション一覧
curl -sS -H "Training-Key: ${TRAINING_KEY}"
"${ENDPOINT}/customvision/v3.3/Training/projects/${PROJECT_ID}/iterations" | jq '.[] | {id, name, status, created, lastModified}'
status が Training のまま動かないイテレーションを確認します。必要に応じて 最新の完成済みモデル(Completed) の情報を控えたり、エクスポート対応モデルであれば事前にエクスポートを検討してください(削除するとそのイテレーションのメトリクスやモデルは失われます)。
ステップ 2:イテレーションを削除(強制解除)
export ITERATION_ID="<HUNG_ITERATION_ID>"
# 強制削除
curl -X DELETE -sS -H "Training-Key: ${TRAINING_KEY}"
"${ENDPOINT}/customvision/v3.3/Training/projects/${PROJECT_ID}/iterations/${ITERATION_ID}"
削除が成功するとレスポンスは空(204 No Content 相当)または簡素な内容になります。ポータルをリロードし、該当イテレーションが消えていることを確認したら、新規トレーニングを再実行できます。
PowerShell 例
$endpoint = "https://<region>.api.cognitive.microsoft.com"
$trainingKey = "<YOUR_TRAINING_KEY>"
$projectId = "<YOUR_PROJECT_ID>"
# イテレーション一覧
$iterations = Invoke-RestMethod -Headers @{ "Training-Key" = $trainingKey } ` -Uri "$endpoint/customvision/v3.3/Training/projects/$projectId/iterations"`
-Method GET
$iterations | Select-Object id, name, status, created, lastModified | Format-Table
# 問題のイテレーションを削除
$iterationId = ""
Invoke-RestMethod -Headers @{ "Training-Key" = $trainingKey } ` -Uri "$endpoint/customvision/v3.3/Training/projects/$projectId/iterations/$iterationId"`
-Method DELETE
Python(requests)例
import os, requests
endpoint = os.getenv("ENDPOINT")
training_key = os.getenv("TRAINING_KEY")
project_id = os.getenv("PROJECT_ID")
iteration_id = os.getenv("ITERATION_ID") # 問題のID
headers = {"Training-Key": training_key}
# 確認
r = requests.get(f"{endpoint}/customvision/v3.3/Training/projects/{project_id}/iterations",
headers=headers)
r.raise_for_status()
for it in r.json():
print(it["id"], it["name"], it["status"])
# 削除
d = requests.delete(f"{endpoint}/customvision/v3.3/Training/projects/{project_id}/iterations/{iteration_id}",
headers=headers)
print(d.status_code) # 204など
C#(.NET SDK)例
SDK を使うと、CustomVisionTrainingClient で一覧取得や削除が簡潔に書けます。
using Microsoft.Azure.CognitiveServices.Vision.CustomVision.Training;
using Microsoft.Azure.CognitiveServices.Vision.CustomVision.Training.Models;
var endpoint = "https://.api.cognitive.microsoft.com";
var trainingKey = "";
var projectId = Guid.Parse("");
var iterationId = Guid.Parse("");
var client = new CustomVisionTrainingClient(
new ApiKeyServiceClientCredentials(trainingKey)) { Endpoint = endpoint };
// 一覧
var iterations = await client.GetIterationsAsync(projectId);
foreach (var it in iterations)
{
Console.WriteLine($"{it.Id} {it.Name} {it.Status}");
}
// 削除
await client.DeleteIterationAsync(projectId, iterationId);
注意:SDK のバージョンによりメソッド名・名前空間が異なる場合があります。ビルド時の IntelliSense を優先してください。
なぜ「Training…」が長引くのか:技術的背景
| 想定原因 | 解説 | 対処の方向性 |
|---|---|---|
| リージョン混雑・キュー滞留 | 同一リージョンにトレーニング要求が集中し、ジョブが長時間キューで待機。UI は「Training…」のまま。 | 時間帯変更(混雑回避)/別リージョンのリソース利用/上位 SKU 検討。 |
| リソース上限・同時実行制約 | リソースの同時学習枠やスロットが上限に達すると待機が発生。 | ジョブ分割、小刻み実行、並列度を落とす。古いイテレーションの整理。 |
| データセット構成の重さ | タグ数/画像数/解像度や前処理により、想定以上に計算量が増える。 | 解像度の適正化、画像の分割投入、タグの整理、ドメイン選択の見直し。 |
| 一時的なサービス側障害 | メンテナンスや障害時、ジョブが停滞・再試行ループに入る可能性。 | 時間を置いて再試行/別リージョン/サポートチケットでの状況確認。 |
課金の考え方(安心材料と注意点)
- Advanced(予約)トレーニング:
reservedBudgetInHoursで指定した予算が上限。その枠を超えて課金が膨らむことは抑制されます。 - Quick(通常)トレーニング:主に実際の計算時間が課金対象。キュー滞留時間は計算時間に含まれないのが一般的です。
- いずれの場合も、コスト管理でメーターを確認するのが安全運用。異常値があれば速やかにサポートへ。
再発防止のための運用設計チェックリスト
| 項目 | 推奨 | 効果 |
|---|---|---|
| 画像投入の粒度 | 一度に大量登録しない。スプリント単位で小刻みに学習。 | ジョブ時間・失敗時の影響を局所化、キュー滞留の抑制。 |
| リソース階層(SKU) | ワークロードに応じて S 系列のより高い層へ拡張を検討。 | スロット・性能に余裕を持たせ、待機を減らす。 |
| リージョン選択 | 近接性と混雑バランスを考慮。冗長構成として別リージョンを用意。 | 障害/混雑時にフェイルオーバー。 |
| 学習スケジュール | 混雑時間帯(各地域の午前帯など)を回避し夜間バッチ化。 | 待機時間の短縮、成功率の向上。 |
| データ設計 | 解像度・タグ数の適正化。ドメイン選択の見直し。 | 無駄な計算を削減し所要時間を短縮。 |
| イテレーション整備 | 不要なイテレーションを定期削除。命名規約を導入。 | 管理性向上、誤操作や再学習の混乱を防止。 |
| 監視とアラート | トレーニング時間・コストのしきい値監視。 | 異常の早期検知、迅速な切り戻し。 |
「削除前に」やっておくと安心なこと
- モデルの退避:対象イテレーションのエクスポート可否を確認し、可能ならエクスポート。
- メトリクスの保存:Precision/Recall/mAP 等のスクリーンショットや JSON 取得。
- 実験ノート:画像セット・タグ変更・ドメインの履歴を残し、再現性を担保。
削除後のリカバリー手順(おすすめのやり直し方)
- ポータルをリロードし、ぶら下がりイテレーションが消えたことを確認。
- まずは少量(例:10~30 枚)でクイックトレーニングし、動作確認。
- 問題が解消していれば、段階的に画像を追加して再学習。必要に応じて Advanced(予算 1~2h から)へ。
- 時間帯をずらす・別リージョンで再試を行い、安定性を比較。
Quick と Advanced の使い分けメモ
| 項目 | Quick(通常) | Advanced(予約) |
|---|---|---|
| 狙い | 短時間でモデルの当たりを確認 | 精度追求・ハイパラ探索を含む本格学習 |
| 時間/コスト制御 | 短時間・低コスト(ただし混雑の影響を受けやすい) | 予算(Reserved Budget)で上限管理 |
| 詰まり時の対応 | DELETE で解放→時間帯/リージョン変更 | DELETE で解放→予算・時間帯・リージョン最適化 |
トラブル時の深掘り診断ポイント
サブスクリプション/リソースの状態
- リソースのキーやエンドポイントの誤りがないか(Training と Prediction の取り違え等)。
- RBAC(アクセス権)やリソース移行直後の整合性問題がないか。
データセットの特性
- 画像解像度が極端に大きすぎないか(無駄な計算増)。
- タグが過剰に多くないか、クラス不均衡が極端でないか。
- ドメイン(General/Compact 等)の選択が用途に合っているか。
学習ジョブの並列度とスケジュール
- 複数プロジェクトで同時にトレーニングしていないか。
- 混雑時間帯(多地域の業務時間帯)への投下を避ける。
よくある質問(FAQ)
Q1. ポータルにキャンセルボタンはありますか?
A. 現時点ではポータル UI に途中停止やキャンセルはありません。REST API によるイテレーション削除が実質的な解放手段です。
Q2. 削除すると何が消えますか?
A. そのイテレーションのモデルとメトリクスが失われます。必要であれば事前にエクスポートやメトリクスの保存を行ってください。
Q3. 課金はどうなりますか?
A. Advanced では予算時間が上限として働きます。Quick でもキュー待機自体は計算時間ではないのが一般的です。いずれにせよ、コスト管理でのモニタリングが安心です。
Q4. 別リージョンに作り直すと改善しますか?
A. 一時的な混雑の影響を回避できる場合があります。ベンチマーク的に試す価値があります。
Q5. 画像が少ないのに遅いのはなぜ?
A. 遅さの主要因は計算だけではなくキュー滞留です。画像が少量でも混雑の影響は受けます。
現場で役立つ運用レシピ
レシピ 1:学習パイプラインを“こまめに”回す
- 新規画像はバッチサイズ小さめ(例:50~200 枚)で投入。
- Quick で当たりを確認 → Advanced で最終精度出し。
- 完了イテレーションを命名規約に沿って整理・退避・不要分削除。
レシピ 2:二段リージョン運用
- 主力リージョン:通常運用。
- 待機リージョン:混雑・障害時のみ切替。API の接続先をパラメータ化。
レシピ 3:自動解放スクリプト
「status == Training で一定時間を超えるイテレーション」を検出したら通知し、承認後に DELETE を流す仕組みを用意しておくと復旧が速くなります。
削除が失敗する/応答が返らない場合のヒント
- ヘッダーは
Training-Keyを使用(Prediction-Key と混同しない)。 projectIdとiterationIdは GUID。打ち間違いに注意。- ネットワーク経路(プロキシ/ファイアウォール)の制約を確認。
- 時間を置いて再試行(短時間での連打は避ける)。
- 最終手段として、新規プロジェクトを作成し学習を移行(データはエクスポート/再インポート)。
サポートに問い合わせるときの情報テンプレート
・発生日時(JST/UTC を明記)
・リージョン(例:japaneast / eastus 等)
・リソース階層(SKU)
・プロジェクト ID と問題のイテレーション ID
・学習種別(Quick / Advanced)と Advanced なら予算時間
・画像枚数/タグ数/ドメイン(General / Compact 等)
・直前の変更(データ追加、タグ変更、ドメイン変更など)
・試した回避策(時間帯変更、別リージョン、DELETE 実行可否)
・課金メーターの状況(異常の有無)
まとめ(運用の勘所)
- まずは REST API の DELETE で該当イテレーションを解放:これが最短の復旧ルート。
- 混雑回避・上位 SKU・リージョン分散・小刻み学習で再発を抑止。
- Advanced 予算で時間上限を明確化し、コストも同時にコントロール。
- 継続する場合はサービス正常性の確認とサポート相談をセットで。
Custom Vision の学習はクラウドの共同利用資源上で動くため、混雑や制約に左右されます。設計段階で“詰まったら即切り戻すライン”を決め、削除 → 再試行を自動化・標準化しておくと、現場のダウンタイムを最小化できます。
付録:よく使う API エンドポイント早見表(v3.3)
| 目的 | HTTP | パス(${ENDPOINT} からの相対) | 備考 |
|---|---|---|---|
| プロジェクト一覧 | GET | /customvision/v3.3/Training/projects | Project ID の確認用 |
| イテレーション一覧 | GET | /customvision/v3.3/Training/projects/{projectId}/iterations | status / id を確認 |
| イテレーション削除 | DELETE | /customvision/v3.3/Training/projects/{projectId}/iterations/{iterationId} | 復旧の切り札 |
| 学習実行(例) | POST | /customvision/v3.3/Training/projects/{projectId}/train | Advanced の場合は { trainingType:"advanced", reservedBudgetInHours: 1 } 等の JSON をボディに指定 |
付録:学習ジョブが詰まりにくいデータ設計のコツ
- 画像解像度は用途に応じて適正化(無暗に高解像度にしない)。
- クラス(タグ)を整理し、極端な不均衡を避ける。
- 物体検出はアノテーションの質が計算量にも影響。外れ値の除去を徹底。
- ドメイン選択(General / Compact / 物体検出など)は要件に合致させる。
付録:自動監視サンプル(擬似コード)
/**
* 擬似コード:長時間 "Training" のイテレーションを検出 → 通知
*/
const THRESHOLD_MIN = 60; // 60分
const iterations = listIterations(projectId); // API 呼び出し
const hung = iterations.filter(it => it.status === "Training" && minutesFrom(it.created) > THRESHOLD_MIN);
if (hung.length > 0) {
notifyOwner(hung);
// ここで人の承認後に DELETE を実行する運用を推奨
}
最後に
「Training…」で進まない問題は、DELETE による強制解放 → 条件を変えて再挑戦が王道です。運用の設計と自動化を進め、混雑や制約に揺らがない ML ライフサイクルを築いていきましょう。

コメント