午前2時のデータボトルネック
時刻は午前2時。私たちのチームは、カスタム物体検出プロジェクトの厳しい締め切りに直面していました。課題は、既存の公開データセットには存在しない「タービンブレードの酸化したリベット」を特定することでした。手元には15,000枚の未加工画像があり、CVATを使用した手動アノテーションの見積もりは3週間。しかし、私たちに残された時間はわずか3日でした。
これはコンピュータビジョンにおける「隠れたボトルネック」です。最新のトランスフォーマーアーキテクチャと十分なGPU計算リソースがあっても、人間が時給15ドルでボックスの角をクリックし続けるのを待たなければなりません。週末を費やして微細な細胞や輸送コンテナの輪郭をなぞったことがある人なら、そのフラストレーションがわかるはずです。ボトルネックは学習サイクルではなく、最初のエポックが始まる前に必要な膨大な手作業にあるのです。
なぜ手動アノテーションは限界に達するのか
作業の遅れは人員不足によるものではありませんでした。人間が介在するワークフロー(human-in-the-loop)特有の非効率性が原因でした。プロセスを監査した結果、3つの主要な問題が浮き彫りになりました。
- 疲労による精度の低下: 400枚を超えたあたりから、人間の精度は急落します。バウンディングボックスが5〜10ピクセルずれ、似たようなクラスの取り違えが発生し始めます。
- 専門知識の必要性: 22nmの半導体欠陥のラベル付けを、一般的なアノテーション業者に外注することはできません。欠陥がどのようなものかを知っているエンジニアが必要です。しかし、彼らの貴重な時間はボックスを描くためにあるのではありません。
- コールドスタートのパラドックス: ラベル付けを支援するモデルが必要なのに、ラベル付きデータがないためにそのモデルを学習させることができないという, もどかしいループに陥ります。
代替案の検討
現在のパイプラインを構築する前に、このデッドロックを打破するためのいくつかの方法を検討しました。
1. 学習済みYOLOモデル
COCOデータセットで事前学習されたYOLOv8モデルを使用するのは標準的な第一歩です。非常に高速ですが、80種類の一般的なクラスに限定されています。対象が「人」や「車」でない場合、モデルは実質的に何も見えていないのと同じです。既存のラベルがないニッチな産業用部品に対して、汎用モデルを適用するのは困難です。
2. モデル・イン・ザ・ループ
このアプローチでは、モデルが生成した大まかな予測を人間が修正します。ゼロから始めるよりは早いですが、依然として人間が速度の制限要因となります。人間の集中力とマウス操作のすべての時間にコストがかかり続けます。
3. ゼロショット基盤モデル
これが私たちの突破口となりました。Grounding DINOとSegment Anything Model (SAM)を組み合わせ、Vision LLMによるUI実装の自動化のように事前の学習なしで文脈を理解するパイプラインを構築しました。DINOがテキストプロンプトを使って物体を見つけ、SAMがピクセル単位の精密なマスキングを行います。手動でのボックス作成は不要になりました。
ロジック:Grounding DINO + SAM
Grounding DINOは、自然言語を理解する「目」だと考えてください。「鋼鉄の梁にある錆びたボルト」といったプロンプトを与えると、バウンディングボックスを返します。しかし、これらのボックスは緩かったり、中心が少しずれていたりすることがよくあります。そこでSAMの出番です。SAMはそのボックスを空間的なプロンプトとして受け取り、対象物を精密で高忠実度なマスクで「ぴったりと包み込み」ます。
私はこのスタックをアグリテックから重工業まで、さまざまな本番環境に導入してきました。これにより、新しいデータセットのイテレーションにかかる時間は、数週間からスクリプトを実行する数時間へと一貫して短縮されています。
自動アノテーションパイプラインの構築
これを効果的に実行するには、少なくとも12GBのVRAMを搭載したGPUが必要です。これらの基盤モデルをCPUで実行し、AI推論を最適化せずに運用しようとすると、1枚あたりの推論時間が30秒以上かかり、大規模なバッチ処理には向きません。
ステップ1:環境構築
pip install torch torchvision
pip install git+https://github.com/IDEA-Research/GroundingDINO.git
pip install git+https://github.com/facebookresearch/segment-anything.git
pip install opencv-python supervision pycocotools
ステップ2:Grounding DINOによる物体検出
テキスト文字列に基づいて物体を検出するようにGrounding DINOを初期化します。従来の検出器とは異なり、クラスIDではなく英語の説明文を使用します。
from groundingdino.util.inference import load_model, load_image, predict
import cv2
CONFIG_PATH = "GroundingDINO_SwinT_OGC.py"
WEIGHTS_PATH = "groundingdino_swint_ogc.pth"
model = load_model(CONFIG_PATH, WEIGHTS_PATH)
IMAGE_PATH = "turbine_blade_01.jpg"
TEXT_PROMPT = "酸化したリベット"
BOX_THRESHOLD = 0.35
TEXT_THRESHOLD = 0.25
image_source, image = load_image(IMAGE_PATH)
boxes, logits, phrases = predict(
model=model,
image=image,
caption=TEXT_PROMPT,
box_threshold=BOX_THRESHOLD,
text_threshold=TEXT_THRESHOLD
)
ステップ3:SAMによるマスク生成
次に、DINOが生成したボックスをSAMに渡します。このステップは、ボックスレベルの精度では不十分なインスタンスセグメンテーションタスクにおいて不可欠です。
from segment_anything import SamPredictor, sam_model_registry
sam = sam_model_registry["vit_h"](checkpoint="sam_vit_h_4b8939.pth").to("cuda")
predictor = SamPredictor(sam)
predictor.set_image(image_source)
# DINOのボックスは[cx, cy, w, h]形式で正規化されています。
# SAM用にピクセルベース of [x1, y1, x2, y2]形式に変換します。
for box in boxes:
masks, scores, _ = predictor.predict(
box=box.numpy(),
multimask_output=False
)
# 結果は学習に使用できる高品質なブーリアンマスクとなります
本番環境への移行:蒸留戦略
Grounding DINOとSAMは非常に重いモデルです。 エッジおよびローカルハードウェア向けのデバイスでリアルタイム推論を行うためにViT-H SAMモデルを実行することは不可能です。代わりに、このパイプラインを使用して一晩で10,000個の「シルバー・スタンダード(暫定的な正解)」ラベルを生成します。そして、それらのラベルを使用して、YOLOv8やRT-DETRのような軽量モデルを学習させます。
この戦略により、両方のメリットを享受できます。ラベル付けフェーズでは基盤モデルの深い推論能力を活用し、本番環境のハードウェアではミリ秒単位の推論速度を実現できます。
品質のためのフィルタリング
自動化システムは時としてハルシネーション(誤検知)を起こします。私たちのテストでは、Grounding DINOが影を物体として誤認することがありました。信頼度フィルタや、プロンプト評価の実践ガイドに基づいた品質管理を推奨します。ロジットスコアが0.45未満の場合は、その画像にフラグを立てて、人間が5秒間で確認するようにします。これにより、データセットの整合性を高く保ちながら、手作業を約92%削減できます。
最後に
何週間もかけてボックスをクリックし続ける時代は終わりつつあります。もしあなたのチームがいまだにすべてのフレームを手動でアノテーションしているなら、モデルの最適化やエッジケースのエンジニアリングに費やすべき時間を失っています。Grounding DINOとSAMを連携させ、プロンプト最適化の自動化を取り入れることで、アノテーション作業を単調な手作業から、プロンプトエンジニアリングのタスクへと変貌させることができます。
まずは少量のパイロットバッチで閾値を調整してみてください。マスクの精度が十分に高まったら、あとはスクリプトに残りの全データを処理させるだけです。翌朝には、学習パイプラインに投入できる準備が整った、完全にラベル付けされたデータセットが手に入っているはずです。

