tao-mine-aoi-images について
対象画像と候補ソース画像を埋め込み表現に変換し、近傍検索で類似画像を選んで重複のないParquetを出力する、VCN AOI向けスキルです。反復ワークフローでは履歴台帳を使い、前の反復で選ばれたサンプルも除外できます。
主な機能
- 01対象画像とソース画像を埋め込み化
- 02近傍検索で類似画像を特定
- 03ラベルによる絞り込みと重複排除
- 04反復時に選択済みサンプルを除外
- 05Parquetとマイニング概要を出力
活用シーン
- 01対象画像に似たソースプール画像を検索
- 02ラベルで画像の対応付けを限定
- 03学習ラウンド間の重複サンプリングを防止
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ nvidia/ skills --skill tao-mine-aoi-imagesインストール後、Claude Code で/tao-mine-aoi-imagesを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
BENCHMARK.mdskill-card.mdskill.oms.sigconfig/skillspector-baseline.yamlevals/evals.jsonhooks/_parse-stdin.shmining-artifacts-check.shmining-package.shmining-script-check.shmining-section-check.shreferences/outputs-and-reporting.mdreference-invocation.mdsetup.mdtroubleshooting.mdscripts/filter_mined_history.pytests/test_filter_mined_history.py詳細
DEFT マイニングと埋め込みスキル
単独でインストールしますか? このセッションが TAO スキルバンクプラグインによって初期化されていない場合は、まず
tao-setupスキルを実行してください(ホストの事前確認、認証情報、スキル間の検出)。
あなたは、VCN AOI 向けの DEFT 埋め込み後マイニングワークフローのオペレーターです。弱いターゲット画像の parquet(ギャップ分析またはルーティングの出力)とソースプールを入力し、ターゲットに類似したマイニング済みソース画像を重複排除した parquet として生成します。これは次のトレーニングラウンドですぐに使用できます。反復型の DEFT 呼び出しでは、以前の反復で選択されたサンプルが再び選択されないよう、同梱の履歴対応後処理ステップも実行します。
このワークフローは固定されており、決定論的です。ターゲットを埋め込み、ソースプールを埋め込み、最近傍をマイニングし、反復型ワークフローの場合は以前にマイニングされたサンプルを除外します。 各 GPU ステップの出力 parquet が次のステップの入力になります。履歴対応の選択はホスト側の後処理ステップであり、別の k-NN 検索ではありません。クラスタリング処理も、人間が介在する選択もありません。適切なエンコーダーを選び、履歴フィルタリング後に新しい候補が残るだけの幅を持つ topn を指定することで、十分な深さを確保します。
このスキル全体は、固定された TAO data-services イメージに対する docker run の直接呼び出し 3 回と、反復履歴向けのオプションのホスト側 Python 後処理で構成される薄いラッパーです(実行時の Setup で解決される versions.yaml を参照してください)。コンテナのエントリーポイントは <category> <action> -e <spec.yaml> [hydra overrides...] を受け取ります。埋め込みには embedding image_embeddings -e <embedding_spec.yaml> …、マイニングには tmm nearest_neighbors -e <mining_spec.yaml> … を渡します。-e フラグは、サブタスクのスキーマに対するデフォルト値を指定する YAML を指します。その後に続く値は、実行ごとに spec のフィールドを選択的に上書きする、単独の Hydra オーバーライド(key=value)です(コンテナ内に dataset キーワードはありません。これは TAO ランチャーのピラー接頭辞であり、ここでは省略されています)。イメージがキャッシュされていない場合は、一度プルしてください。docker pull "$DS_IMAGE"($DS_IMAGE は Setup に従って解決した後に実行します)。
data-services のリリース間でスキーマキーの名前が変わることがあります(RCA スキルでは inference_csv が inference_results_dir に、output_dir が results_dir に変わりました)。不明な場合は、イメージごとに一度、実際のスキーマを調べてください。docker run --rm "$DS_IMAGE" embedding image_embeddings --cfg=job および ... tmm nearest_neighbors --cfg=job。
入力
- 対象の parquet — ギャップ分析の出力です。通常は
tao-route-visual-changenet-samplesのmining_gaps.parquet(ルーティングをスキップした場合はtao-analyze-gaps-visual-changenetのkpi_gaps.parquet)です。必須列はfilepathです。labelも含まれている場合は、マイニング中にラベルを考慮したフィルタリングを利用できます。含まれていない場合、マイニングタスクはフィルターを何もせずに処理を続行します。 - ソースプール — マイニング対象となる候補画像の parquet で、
filepath列が必要です。CSV しかない場合は、ステップ 2 の前に同じ列を維持したまま parquet に変換してください。ラベルを考慮したフィルタリングを行うには、プールにもlabel列が必要です。 - 埋め込み仕様ファイル —
model、model_path、batch_size、および(model_pathが TAO の.pth/.ckptの場合のみ)model_config_pathを含む YAML です。ステップ 1 と 2 で再利用します。input_parquet/output_parquetは Hydra のオーバーライドとして実行ごとに指定します。両方の埋め込みステップで必ず同じ仕様を使用してください。異なるエンコーダーの埋め込みは比較できません。また、「マイニングした画像に関連性がない」という報告の最も一般的な原因は、エンコーダーの不一致です。 - マイニング仕様ファイル —
topn、knn_metric、filter_by_label、および(変更することはまれな)source_embed_column_name/target_embed_column_nameを含む YAML です。source_parquet/target_parquet/output_parquetは実行時に Hydra のオーバーライドとして指定します。SigLIP と CLIP の埋め込みにはknn_metric: cosineを使用してください。filter_by_label: trueでも、いずれかの埋め込み parquet にlabel列がない場合、コンテナは警告をログに出し、フィルタリングせずに処理を続行します。 - マイニング履歴(反復ワークフローのみ) — 実行単位の結果ディレクトリに保存する JSON 台帳と、反復ごとの履歴サマリーです。両方のファイルは
scripts/filter_mined_history.pyが管理します。正規化されたfilepathを使ってサンプルを識別し、過去の出力ハッシュをすべて検証して、反復の欠落や選択の重複を拒否します。再開時にこの台帳を手動で編集したり、再構築したりしないでください。
セットアップ
以下の固定バージョンの TAO data-services URI を使用し、ほかの作業を始める前に Docker、NVIDIA container toolkit、GPU が揃っていることを確認してください。エンコーダーのフォワードパスと cuML/cuDF の k-NN 検索の両方に GPU が必要です。CUDA がない場合、どちらのステップも失敗します。
# Resolve the pinned TAO data-services container URI from the release manifest.
DS_IMAGE="$(scripts/resolve_versions_key.py images.tao_toolkit.data_services)"
echo "DS_IMAGE=$DS_IMAGE"
docker info > /dev/null && echo "OK: docker"
nvidia-smi > /dev/null && echo "OK: GPU"
docker image inspect "$DS_IMAGE" > /dev/null \
|| docker pull "$DS_IMAGE"
コンテナが読み書きするすべてのホストパスをバインドマウントする必要があります。最も予測しやすい方法は、ワークスペースのルートをコンテナの内外で同一のパスにマウントし、3 回の呼び出しで同じ $DOCKER エイリアスを再利用することです。
WORKSPACE=<absolute path that contains all parquets, outputs, and the source-pool images>
DOCKER="docker run --gpus all --rm --shm-size=8g -v $WORKSPACE:$WORKSPACE -w $WORKSPACE $DS_IMAGE"
--user $(id -u):$(id -g) は渡さないでください。作業開始前の transformers のインポート時に getpwuid() の KeyError が発生します。コンテナは root として実行されるため、処理後に出力の所有者をホストの UID に戻してください。
反復ごとに 2 つの仕様ファイルを一度作成し、-e 引数がマウントの内外で解決されるよう $WORKSPACE の下に配置してください。実行ごとの値は仕様ファイルに含めず、Hydra のオーバーライドとして渡します。ソースプールが CSV の場合は、事前に filepath と(存在する場合は)label を維持したまま parquet に変換してください。デフォルトの embedding_spec.yaml は model: SigLIP、model_path: google/siglip-base-patch16-224、batch_size: 64 を使用します。デフォルトの mining_spec.yaml は topn: 5、knn_metric: cosine、filter_by_label: "false" を使用します(スキーマで文字列として読み取られるため、引用符が必要です)。反復型 DEFT ワークフローでも、デフォルトの topn: 5 を維持し、ユーザーが明示的に指定した値があればその値を保持してください。履歴サマリーから、狭い近傍が過去に選択した画像に偏っていることが分かった場合にのみ、値を増やしてください。
環境に関する詳細、TAO_SKILL_BANK_PATH の扱い、パスをマウントする理由、getpwuid の問題に対処するための chown 回避策、CSV から parquet への変換例、仕様ファイルの作成に使うそのままのコードブロックについては、references/setup.md を参照してください。
方法
コマンドを順番に3つ実行します。各コマンドの出力 parquet が次のコマンドの入力になります。Setup の $DOCKER エイリアスがコンテナ、GPU、マウントを処理するため、通常の Bash として実行してください。すべての呼び出しは同じ形式です。組み込みのデフォルト値には -e <spec> を指定し、実行ごとに異なるパスを Hydra オーバーライドでいくつか指定します。
ステップ 1 — 対象画像を埋め込む
$DOCKER embedding image_embeddings \
-e <embedding_spec.yaml> \
input_parquet=<target_parquet> \
output_parquet=<target_embeddings_parquet>
ギャップ分析/ルーティングの出力を読み込み、filepath、embedding、および入力からそのまま引き継いだ追加のメタデータ列(例:label、siamese_score、weakness)を含む parquet を書き出します。出力スキーマ(pd.read_parquet(...).columns)を stdout に出力し、スクリプトチェックのフックで embedding 列の存在を確認できるようにしてください。
spec を編集せずに、1 回の実行で model/model_path/batch_size をオーバーライドする必要がある場合は、Hydra オーバーライドとして追加します(例:model_path=...)。
ステップ 2 — ソースプールを埋め込む
$DOCKER embedding image_embeddings \
-e <embedding_spec.yaml> \
input_parquet=<source_pool_parquet> \
output_parquet=<source_embeddings_parquet>
ステップ 1 と同じ形式のコマンドを、ソースプールに対して実行します。ステップ 1 と同一の embedding_spec.yaml を使用し、ここでは model/model_path/batch_size を異なる値でオーバーライドしないでください。2 つのステップでエンコーダー設定が異なると、比較可能な埋め込みが生成されません。
ステップ 3 — 最近傍を抽出する
$DOCKER tmm nearest_neighbors \
-e <mining_spec.yaml> \
source_parquet=<source_embeddings_parquet> \
target_parquet=<target_embeddings_parquet> \
output_parquet=<mined_parquet>
各対象埋め込みについて、選択した距離指標で最も近い topn 個のソース埋め込みを検索し、対象間で重複を除去して、一意な抽出済みソースパスを含む単一列(filepath)の parquet を書き出します。単発の実行では、これを最終的な mined.parquet にしてもかまいません。DEFT の反復処理では、候補セットをステップ 4 用に不変のまま保持できるよう、mined_candidates.parquet として書き出してください。コンテナは出力 parquet の隣に mining_summary.txt も作成します。内容は、クエリ数、近傍数、削除した重複数、および(ラベルフィルタリングが有効な場合は)保持ペア数と除外ペア数です。スイープ時に topn、knn_metric、filter_by_label を変更するには、インラインの Hydra オーバーライドを使います。spec を書き換える必要はありません。
filter_by_label=true なのに、埋め込み parquet のどちらかに label 列がない場合、コンテナは警告をログに記録し、フィルタリングを行わずに処理を続けます。抽出された出力が予想より大きい場合や、異なるラベルのペアが含まれている場合は、タスクが正しく実行されたと決めつける前に、docker ログでその警告を確認してください。
references/reference-invocation.md を参照してください。単一のストリーム形式の Bash ブロックとして実行できる、貼り付けて必要箇所を編集するだけの最小限のエンドツーエンド手順が記載されています($DS_IMAGE の解決、両方の spec の書き出し、3 つのステップの実行、出力の chown、行数の表示を行います)。
ステップ 4 — 履歴を考慮した選択(反復型 DEFT のみ)
ラベル/類似度の保持フィルタを適用した後に実行し、入力が学習対象として 実際に適格な候補を表すようにしてください。
python3 skills/data/tao-mine-aoi-images/scripts/filter_mined_history.py \
--candidate-parquet <mined_candidates.parquet> \
--output-parquet <mined.parquet> \
--history-file <run_results_dir>/mining_history.json \
--summary <iteration_dir>/mining_history_summary.json \
--iteration <N> \
--topn <topn>
出力は候補の順序とスキーマを維持しますが、以前に確定した反復処理で
選択されていないファイルパスのみを含みます。台帳には、選択したパス、
候補/出力のハッシュ、件数、topn が記録されます。--resume は、これらの
成果物を検証した後に限り、すでに確定済みの反復処理を再利用します。出力行数が
0 件でも、現在の k-NN 候補セットに新規サンプルがなかったことを示す有効な
証拠です。反復処理を別の生成元(たとえば AnomalyGen)で続行できるか、
それとも完全に停止するかは、呼び出し側が判断します。サマリーに
historical_candidate_rate が高い値として報告された場合は、topn を増やすか、
ソースプールを拡張してください。すべての反復処理で同じ品質の低い近傍が取得される
場合、履歴フィルタリングでばらつきを生み出すことはできません。
出力とレポート
すべてのファイルを、実験/イテレーションディレクトリ内のタイムスタンプ付きフォルダーに書き込みます。Bash で date +%Y-%m-%d_%H%M%S を実行して実際のタイムスタンプを取得してください。ハードコードしたり、推測したりしないでください。ユーザーがカスタム出力パスを指定した場合は、そのパスをそのまま使用しますが、内部のレイアウトは同じにしてください。Mining_Report.md の書き込み時に、パッケージングフックが mining_config/ と claude_session.jsonl を自動で追加します。
履歴でフィルタリングした最終的なマイニング済み Parquet は、反復処理を行う後続のトレーニング段階で使用する成果物です。履歴フィルタリング前の候補 Parquet、イテレーションごとの履歴サマリー、実行単位の mining_history.json は、2 つの埋め込み Parquet とともに保持してください。これらにより、「k-NN で何も見つからなかった」場合と「k-NN が返したのは過去のイテレーションですでに使用されたサンプルだけだった」場合を区別できます。
出力ディレクトリの完全なレイアウトと、Mining_Report.md の逐語的なテンプレート(Verdict、Inputs、Encoder Consistency、Mining Run、Per-Label Breakdown、Output Sanity、Recommended Actions。600~1200 語)については、references/outputs-and-reporting.md を参照してください。
よくある落とし穴
最も頻繁に発生する失敗は、2 つの埋め込みステップでエンコーダーが一致していないことです。これはマイニング結果が無意味になる最も一般的な原因です。両方のステップで同じ embedding_spec.yaml を使用する必要があります。そのほかによくある落とし穴として、--user を渡す(getpwuid の KeyError)、埋め込みステップをスキップする、label 列がないため filter_by_label=true が何もせずに終了する、$WORKSPACE の外にあるスペックファイル、未解決の ??? センチネル、model_config_path のない TAO チェックポイント、CSV のソースプールをそのまま入力する、ホストとコンテナ間のパス不一致、GPU がない、イメージタグが未取得または :latest、topn × N_targets ≫ source size(想定どおりです。実際にマイニングされた件数をレポートしてください)、履歴フィルタリング後に新規サンプルが得られないほど topn が狭すぎる、といったものがあります。
正確なエラー、原因、修正方法を含む落とし穴の一覧については、references/troubleshooting.md を参照してください。
実行順序
DS_IMAGEに固定された data-services URI を設定し(Setup を参照)、docker info、nvidia-smi、docker image inspect "$DS_IMAGE"を一度実行して、環境を確認します。イメージがない場合は取得してください。いずれかが失敗した場合は、明確なメッセージを表示して中止します。date +%Y-%m-%d_%H%M%Sを実行してタイムスタンプを取得し、<output_dir>/mining_results/<timestamp>/を作成します。embedding_spec.yamlとmining_spec.yamlをタイムスタンプ付きディレクトリに書き込み、エンコーダーの選択とマイニング設定を入力します。-eのパスがコンテナ内で解決できるよう、これらは$WORKSPACEの下に置いてください。- ソースプールが CSV の場合は、先に Parquet に変換します(
filepathとlabelは保持してください)。 - Step 1(ターゲットの埋め込み)を
docker run … embedding image_embeddings -e embedding_spec.yaml input_parquet=… output_parquet=…で実行します。出力 Parquet の行数と列を stdout に出力します。 - Step 2(ソースプールの埋め込み)を、Step 1 と同一の
embedding_spec.yamlを使って実行します。出力の行数と列を出力します。 - Step 3(最近傍のマイニング)を
docker run … tmm nearest_neighbors -e mining_spec.yaml source_parquet=… target_parquet=… output_parquet=…で実行します。raw/candidate Parquet と同じ場所にmining_summary.txtが書き込まれたことを確認します。 - 反復処理を行う DEFT 呼び出し元の場合は、設定済みの保持フィルターをすべて適用してから、現在のイテレーション番号、記録済みの
topn、実行単位の台帳パス、他と区別できる最終的なmined.parquetを指定して Step 4 を実行します。raw candidate Parquet を累積トレーニングに直接渡してはいけません。 - ターゲット埋め込み Parquet と最終的なマイニング済み出力の両方に
labelがある場合は、filepath をキーに結合して、ラベルごとの内訳(Section 5)を算出します。 - 最後に
Mining_Report.mdを書き込みます。書き込みを契機にパッケージングフックが実行され、セッションログとスキル設定が隣接してコピーされます。