tao-generate-referring-expressions

Par nvidia · skills

"Pipeline en quatre étapes pour les expressions de référence sur images : transforme des images et des labels de boîtes englobantes KITTI en région

npx skills add https://github.com/nvidia/skills --skill tao-generate-referring-expressions

Pipeline d'expression référentielle d'image

Générez des annotations d'expressions référentielles et de grounding à partir d'images avec des labels de boîte englobante au format KITTI. Un seul VLM (Gemini ou tout endpoint compatible OpenAI) exécute quatre étapes : descriptions de région par objet, captions d'image holistiques, expressions de grounding groupées liées à des bbox, et une passe de vérification optionnelle en double vérification.

Objectif

Transformer les paires (image, labels KITTI) en un annotations.jsonl unifié contenant des expressions référentielles riches et ancrées. Le VLM agit comme annotateur « enseignant » : les étapes 0-1 voient l'image ; l'étape 2 groupe les sorties de l'étape 0 en phrases de groupement avec listes de bbox ; l'étape 3 (optionnelle) réexamine ces bbox par rapport à l'image et corrige les décalages.

Architecture du pipeline

Étape 0 : Expression de région  ──┐
                                    ├──▶  Étape 2 : Expression de grounding  ──▶  [Étape 3 : Double vérification]
Étape 1 : Caption d'image  ──────┘                                                     (optionnelle)
  • Étape 0 (region_expr) — Le VLM émet une courte phrase discriminative par bbox KITTI (bbox_2d, type, color, description).
  • Étape 1 (image_caption) — Le VLM émet une caption de scène holistique, indépendante de la localisation.
  • Étape 2 (grounding_expr) — Le VLM groupe les objets de l'étape 0 en phrases de groupement et retourne une liste de bbox par groupe, en utilisant optionnellement la caption de l'étape 1 comme contexte supplémentaire.
  • Étape 3 (double_check) — Le VLM re-vérifie chaque bbox de l'étape 2 par rapport à l'image ; les mauvaises correspondances sont supprimées, les boîtes légèrement décalées sont resserrées.

Les étapes 0 et 1 s'exécutent en parallèle au sein d'un seul thread pool (elles dépendent uniquement des enregistrements initiaux). Chaque étape écrit son propre step_<N>_*/annotations.jsonl et ignore les images déjà traitées lors d'une réexécution sauf si workflow.force_reprocess: true.

Instructions

Configuration initiale

Quand un utilisateur veut exécuter ce pipeline, suivez ces étapes :

  1. Images : Demandez data.image_dir, le répertoire contenant les images .jpg, .jpeg ou .png.

  2. Labels KITTI : Demandez data.kitti_label_dir, le répertoire contenant un fichier label .txt par image. Chaque ligne de label doit utiliser le format KITTI : <type> <truncated> <occluded> <alpha> <bbox_left> <bbox_top> <bbox_right> <bbox_bottom> .... Les lignes avec moins de 8 champs sont silencieusement ignorées. Définissez-le même pour les exécutions en étape 1 uniquement car les étapes 0 et 2 l'exigent.

  3. Reprendre à partir d'annotations existantes : Si l'utilisateur a déjà un annotations.jsonl unifié d'une exécution précédente, définissez data.input_annotations_jsonl sur ce fichier au lieu de l'amorcer à partir de data.image_dir et data.kitti_label_dir.

  4. Accès à l'API : Demandez à l'utilisateur quel endpoint VLM il souhaite utiliser. Présentez ces cinq options et agissez selon le choix :

    1. Gemini — définissez vlm.backend: "gemini" ; exigez GOOGLE_API_KEY (variable d'environnement ou vlm.gemini.api_key).
    2. NIM (p. ex. https://inference-api.nvidia.com/v1) — définissez vlm.backend: "openai" ; collectez base_url, model_name et api_key.
    3. TAO inference microservice (auto-hébergé, compatible OpenAI). Confirmez si le serveur est déjà en cours d'exécution :
      • En cours d'exécution — collectez base_url, model_name et (optionnellement) api_key ; définissez vlm.backend: "openai".
      • Non en cours d'exécution — guidez l'utilisateur à travers la skill skills/applications/tao-run-inference-service, qui met en place un microservice TAO inference local avec une API compatible OpenAI. Avant de promettre un modèle spécifique, vérifiez skills/applications/tao-run-inference-service/references/service.yaml pour valid_network_arch_config_basenames. Une fois le serveur actif, collectez base_url, model_name et (optionnellement) api_key ; définissez vlm.backend: "openai".
    4. vLLM (auto-hébergé, compatible OpenAI). Confirmez si le serveur est déjà en cours d'exécution :
      • En cours d'exécution — collectez base_url, model_name et (optionnellement) api_key ; définissez vlm.backend: "openai".
      • Non en cours d'exécution — suivez references/vllm_server.md pour installer et lancer un serveur vLLM, puis collectez base_url, model_name et (optionnellement) api_key ; définissez vlm.backend: "openai".
    5. Custom (tout autre endpoint compatible OpenAI) — définissez vlm.backend: "openai" ; collectez base_url, model_name et (optionnellement) api_key.

    Si l'utilisateur n'a pas d'endpoint et ne souhaite pas en configurer un, arrêtez-vous et aidez à résoudre d'abord l'accès à l'API.

  5. Étapes du workflow : Choisissez l'une de :

    • Pipeline complet : ["0", "1", "2", "3"]
    • Pas de génération de caption : ["0", "2", "3"], où l'étape 2 revient à un contexte d'image uniquement
    • Pas de vérification : ["0", "1", "2"]
    • Sous-ensemble personnalisé : tout sous-ensemble supporté d'étapes
  6. Format de sortie : Choisissez l'une de :

    • jsonl : schéma unifié uniquement
    • legacy : fichiers .txt.stepN compatibles uniquement
    • both : écrit les deux formats et est la valeur par défaut pour les outils aval

Exécution du pipeline

Le pipeline s'exécute à l'intérieur du conteneur TAO Toolkit via le CLI auto_label :

auto_label generate -e /path/to/spec.yaml \
    results_dir=/results \
    image_referring_expression.data.image_dir=/data/images \
    image_referring_expression.data.kitti_label_dir=/data/labels \
    image_referring_expression.vlm.gemini.api_key=$GOOGLE_API_KEY

Générez une spec par défaut : auto_label default_specs results_dir=/results module_name=auto_label, puis définissez autolabel_type: "image_referring_expression". Tous les champs supportent les surcharges de notation pointillée Hydra sur la ligne de commande.

Voir references/configuration.md pour la structure YAML complète, tous les paramètres, la configuration de modèle/endpoint et les modèles d'erreur.

Workflow pilote recommandé

  1. Exécutez sur 5-10 images avec les quatre étapes.
  2. Inspectez step_0_region_expr/annotations.jsonl — les types d'objets, les couleurs et les phrases discriminantes sont-ils exacts ?
  3. Inspectez step_2_grounding_expr/annotations.jsonl — les objets sont-ils groupés judicieusement, et les coordonnées bbox correspondent-elles aux groupes décrits ?
  4. Inspectez step_3_double_check/annotations.jsonl — les bbox mal appariées ont-elles été supprimées ou resserrées ? Des erreurs nouvelles sont-elles introduites (rare) ?
  5. Si la qualité est insuffisante, basculez vers un modèle VLM plus puissant (p. ex. gemini-2.5-pro ou un endpoint Qwen3-VL plus grand), augmentez media_resolution / max_output_tokens, puis réexécutez avec workflow.force_reprocess=true.
  6. Mettez à l'échelle le dataset complet une fois satisfait.

Configuration

Champs de configuration clés (référence complète dans references/configuration.md) :

Champ Défaut Description
workflow.steps ["0","1","2","3"] Quelles étapes exécuter (0=region_expr, 1=image_caption, 2=grounding_expr, 3=double_check)
workflow.max_workers 4 Threads parallèles par étape (surveiller les limites de débit API)
workflow.force_reprocess false Ignorer les sorties en cache par étape et retraiter de zéro
workflow.output_format "jsonl" (défini à "both" dans la spec par défaut) "jsonl", "legacy" ou "both"
vlm.backend "gemini" "gemini" ou "openai" (endpoint compatible OpenAI)
data.image_dir requis Répertoire des images d'entrée (.jpg / .jpeg / .png)
data.kitti_label_dir requis (sauf reprise) Répertoire des fichiers label .txt au format KITTI
data.input_annotations_jsonl "" annotations.jsonl pré-amorcé optionnel (ignore l'amorçage KITTI)

Entrées

Deux façons d'amorcer le pipeline :

  1. Répertoire d'images + labels KITTI (par défaut). Définissez data.image_dir et data.kitti_label_dir. L'orchestrateur parcourt le répertoire d'images, lit le fichier KITTI <stem>.txt correspondant, analyse les bbox (champs 0 + 4-7), lit les dimensions width/height de chaque image via PIL, et écrit un seed_annotations.jsonl dans results_dir/.
  2. Annotations JSONL pré-amorcées (reprise / régions pré-calculées). Définissez data.input_annotations_jsonl sur un fichier avec un objet {"image_id", "image_path", "width", "height", "kitti_bboxes": [...]} par ligne.

Sorties

Toutes les sorties vont dans results_dir/ :

  • seed_annotations.jsonl — enregistrements initiaux par image (sauf si input_annotations_jsonl a été fourni).
  • step_0_region_expr/annotations.jsonl — ajoute regions[] (chacun avec bbox/bbox_2d, type, color, description).
  • step_1_image_caption/annotations.jsonl — ajoute caption (chaîne).
  • step_2_grounding_expr/annotations.jsonl — ajoute expressions[] (chacun {text, instances: [{bbox: [x1,y1,x2,y2]}]}).
  • step_3_double_check/annotations.jsonl — même forme que l'étape 2, avec les bbox supprimées/mises à jour.
  • results_dir/annotations.jsonl — copie de la sortie de la dernière étape complétée.
  • Quand workflow.output_format est "legacy" ou "both", chaque étape écrit également des fichiers step_<N>_*/labels/<stem>.txt.stepN compatibles en octets pour l'outil original 2d-data-engine.

Prérequis

  • Conteneur : nvcr.io/nvidia/tao/tao-toolkit:6.26.3-pyt
  • Accès API : Au moins un endpoint VLM (clé API Gemini ou endpoint compatible OpenAI capable d'entrée d'image)
  • PIL / Pillow : Requis pour lire les dimensions d'image lors de l'amorçage (déjà présent dans le conteneur TAO)

Skills similaires