Tao Generate Referring Expressions
NVIDIAOfficialCreated by NVIDIA Corporation
- Skill
- Workflow
- Data and AI
- Apache-2.0
- Medium risk
AutoGineer summary
Written by AutoGineer from the skill’s own files, not by the author
The tao-generate-referring-expressions skill provides an automated pipeline for transforming images and KITTI-format bounding box labels into rich, grounded referring expressions. By leveraging a Vision-Language Model (VLM) as a teacher, the pipeline performs four distinct steps: generating region-specific descriptions, creating holistic scene captions, producing grouped grounding phrases tied to bounding boxes, and optionally verifying the accuracy of these expressions. This tool is designed to assist in auto-labeling traffic or scene images for training datasets, offering a structured approach to data annotation that supports both Gemini and OpenAI-compatible VLM endpoints.
What it does
- Generates discriminative region descriptions for objects defined by KITTI bounding boxes.
- Produces holistic, location-agnostic scene captions for input images.
- Groups objects into semantic phrases with associated bounding box lists.
- Performs an optional verification pass to tighten or remove inaccurate bounding boxes.
- Supports multiple VLM backends including Gemini and self-hosted OpenAI-compatible services.
- Outputs unified annotations in JSONL format for downstream machine learning tasks.
When to use it
- When you need to auto-label traffic or scene images for referring expression datasets.
- When you have existing KITTI-format bounding box labels and want to add descriptive text annotations.
- When you need to verify and refine existing grounding expressions for higher accuracy.
- When you want to build a dataset of grounded referring expressions tied to specific image regions.
Advantages
- Automates complex annotation tasks using powerful VLM capabilities.
- Provides a modular workflow where steps can be enabled or disabled based on requirements.
- Includes a built-in verification step to improve the quality of generated labels.
- Flexible integration with various VLM endpoints including local self-hosted servers.
- Supports both modern JSONL output and legacy formats for compatibility with existing tools.
Usage examples
- “Run the referring expression pipeline on my traffic images.”
- The agent will guide you through setting up the image and label directories, selecting a VLM endpoint, and executing the four-step annotation process.
- “How can I verify my existing grounding expressions?”
- The agent will configure the pipeline to run the Step 3 double-check verification pass on your existing annotations to identify and correct mismatches.
Install
Download the skill as a ZIP:
https://autogineer.com/agent-skills/nvidia/tao-generate-referring-expressions/downloadUnzip it into the cross-client skills folder of your project:
mkdir -p .agents/skills && unzip tao-generate-referring-expressions.zip -d .agents/skills
Documentation by NVIDIA Corporation
Image Referring Expression Pipeline
Standalone install? If this session was not initialized by the TAO skill bank plugin, run the
tao-setupskill first (host preflight, credentials, cross-skill discovery).
Generate referring-expression and grounding annotations from images with KITTI-format bounding box labels. A single VLM (Gemini or any OpenAI-compatible endpoint) runs four steps: per-object region descriptions, holistic image captions, grouped grounding expressions tied to bboxes, and an optional double-check verification pass.
Purpose
Transform (image, KITTI labels) pairs into a unified annotations.jsonl containing rich, grounded referring expressions. The VLM acts as a "teacher" annotator: Steps 0-1 see the image; Step 2 groups Step 0 outputs into grouping phrases with bbox lists; Step 3 (optional) re-examines those bboxes against the image and corrects mismatches.
Pipeline Architecture
Step 0: Region expression ──┐
├──▶ Step 2: Grounding expression ──▶ [Step 3: Double check]
Step 1: Image caption ──────┘ (optional)Step 0 (region_expr) — VLM emits one short discriminative phrase per KITTI bbox (
bbox_2d,type,color,description).Step 1 (image_caption) — VLM emits a holistic, location-agnostic scene caption.
Step 2 (grounding_expr) — VLM groups Step 0 objects into grouping phrases and returns one bbox list per group, optionally using Step 1's caption as extra context.
Step 3 (double_check) — VLM re-checks each Step 2 bbox against the image; bad matches are removed, slightly-off boxes get tightened.
Steps 0 and 1 run in parallel within a single thread pool (they only depend on the seed records). Each step writes its own step_<N>_*/annotations.jsonl and skips already-processed images on re-run unless workflow.force_reprocess: true.
Instructions
Initial setup
When a user wants to run this pipeline, walk through these steps:
Images: Ask for
data.image_dir, the directory containing.jpg,.jpeg, or.pngimages.KITTI labels: Ask for
data.kitti_label_dir, the directory containing one.txtlabel file per image. Each label line must use KITTI format:<type> <truncated> <occluded> <alpha> <bbox_left> <bbox_top> <bbox_right> <bbox_bottom> .... Lines with fewer than 8 fields are silently skipped. Set this even for Step 1-only runs because Steps 0 and 2 require it.Resume from existing annotations: If the user already has a unified
annotations.jsonlfrom a previous run, setdata.input_annotations_jsonlto that file instead of seeding fromdata.image_diranddata.kitti_label_dir.API access: Ask the user which VLM endpoint they want to use. Present these five options and act on the choice:
Gemini — set
vlm.backend: "gemini"; requireGOOGLE_API_KEY(env var orvlm.gemini.api_key).NIM (e.g.
https://inference-api.nvidia.com/v1) — setvlm.backend: "openai"; collectbase_url,model_name, andapi_key.TAO inference microservice (self-hosted, OpenAI-compatible). Confirm whether the server is already running:
Running — collect
base_url,model_name, and (optionally)api_key; setvlm.backend: "openai".Not running — guide the user through the
skills/applications/tao-run-inference-serviceskill, which stands up a local TAO inference microservice with an OpenAI-compatible API. Before promising a specific model, checkskills/applications/tao-run-inference-service/references/service.yamlforvalid_network_arch_config_basenames. Once the server is up, collectbase_url,model_name, and (optionally)api_key; setvlm.backend: "openai".
vLLM (self-hosted, OpenAI-compatible). Confirm whether the server is already running:
Running — collect
base_url,model_name, and (optionally)api_key; setvlm.backend: "openai".Not running — follow references/vllm_server.md to install and launch a vLLM server, then collect
base_url,model_name, and (optionally)api_key; setvlm.backend: "openai".
Custom (any other OpenAI-compatible endpoint) — set
vlm.backend: "openai"; collectbase_url,model_name, and (optionally)api_key.
If the user has no endpoint and does not want to set one up, stop and help resolve API access first.
Workflow steps: Choose one of:
Full pipeline:
["0", "1", "2", "3"]No caption generation:
["0", "2", "3"], where Step 2 falls back to image-only contextNo verification:
["0", "1", "2"]Custom subset: any supported subset of steps
Output format: Choose one of:
jsonl: unified schema onlylegacy: byte-compatible.txt.stepNfiles onlyboth: writes both formats and is the default for downstream tooling
Running the pipeline
The pipeline runs inside the TAO Toolkit container via the auto_label CLI:
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_KEYGenerate a default spec: auto_label default_specs results_dir=/results module_name=auto_label, then set autolabel_type: "image_referring_expression". All fields support Hydra dot-notation overrides on the command line.
See references/configuration.md for the full YAML structure, all parameters, model/endpoint setup, and error patterns.
Recommended pilot workflow
Run on 5-10 images with all four steps.
Inspect
step_0_region_expr/annotations.jsonl— are object types, colors, and discriminating phrases accurate?Inspect
step_2_grounding_expr/annotations.jsonl— are objects grouped sensibly, and do bbox coordinates match the described groups?Inspect
step_3_double_check/annotations.jsonl— were mismatched bboxes removed or tightened? Are any new errors introduced (rare)?If quality is insufficient, switch the VLM to a stronger model (e.g.
gemini-2.5-proor a larger Qwen3-VL endpoint), raisemedia_resolution/max_output_tokens, then re-run withworkflow.force_reprocess=true.Scale to the full dataset once satisfied.
Configuration
Key configuration fields (full reference in references/configuration.md):
| Field | Default | Description |
|---|---|---|
workflow.steps | ["0","1","2","3"] | Which steps to execute (0=region_expr, 1=image_caption, 2=grounding_expr, 3=double_check) |
workflow.max_workers | 4 | Parallel threads per step (watch API rate limits) |
workflow.force_reprocess | false | Ignore cached per-step outputs and reprocess from scratch |
workflow.output_format | "jsonl" (set to "both" in the default spec) | "jsonl", "legacy", or "both" |
vlm.backend | "gemini" | "gemini" or "openai" (OpenAI-compatible endpoint) |
data.image_dir | required | Directory of input images (.jpg / .jpeg / .png) |
data.kitti_label_dir | required (unless resuming) | Directory of KITTI-format .txt label files |
data.input_annotations_jsonl | "" | Optional pre-seeded annotations.jsonl (skips KITTI seeding) |
Inputs
Two ways to seed the pipeline:
Image directory + KITTI labels (default). Set
data.image_diranddata.kitti_label_dir. The orchestrator walks the image directory, reads the matching<stem>.txtKITTI file, parses bboxes (fields 0 + 4-7), reads each image'swidth/heightvia PIL, and writes aseed_annotations.jsonltoresults_dir/.Pre-seeded annotations JSONL (resume / pre-computed regions). Set
data.input_annotations_jsonlto a file with one{"image_id", "image_path", "width", "height", "kitti_bboxes": [...]}object per line.
Outputs
All outputs go to results_dir/:
seed_annotations.jsonl— initial per-image records (unlessinput_annotations_jsonlwas supplied).step_0_region_expr/annotations.jsonl— addsregions[](each withbbox/bbox_2d,type,color,description).step_1_image_caption/annotations.jsonl— addscaption(string).step_2_grounding_expr/annotations.jsonl— addsexpressions[](each{text, instances: [{bbox: [x1,y1,x2,y2]}]}).step_3_double_check/annotations.jsonl— same shape as Step 2, with bboxes removed/updated.results_dir/annotations.jsonl— copy of the last completed step's output.When
workflow.output_formatis"legacy"or"both", each step also writes byte-compatiblestep_<N>_*/labels/<stem>.txt.stepNfiles for the original 2d-data-engine tooling.
Prerequisites
Container:
nvcr.io/nvidia/tao/tao-toolkit:7.3.0-pyt<!-- versions-key: images.tao_toolkit.pyt -->API access: At least one VLM endpoint (Gemini API key or OpenAI-compatible endpoint capable of image input)
PIL / Pillow: Required to read image dimensions during seeding (already present in the TAO container)
Files
- ATTRIBUTION.mdAdded by AutoGineer972 B
- BENCHMARK.md7.3 KiB
- LICENSELicence file added by AutoGineer11.2 KiB
- SKILL.md10.2 KiB
- config/skillspector-baseline.yaml834 B
- evals/evals.json849 B
- references/configuration.md12.7 KiB
- references/skill_info.yaml1.5 KiB
- references/vllm_server.md6.8 KiB
- skill-card.md4.8 KiB
- skill.oms.sig5.4 KiB
BENCHMARK.md
Skill Benchmark: tao-generate-referring-expressions
✅ Overall verdict: PASS — Recommended for publication
Publication Recommendation
Recommended for publication based on the completed evaluation evidence in this report.
Evaluation Metadata
Skill:
tao-generate-referring-expressionsEvaluation date: 2026-10-16
Evaluator version:
1.5.6Agents: Claude Code (
aws/anthropic/bedrock-claude-opus-4-8), Codex (openai/openai/gpt-5.5)Tasks: 1 evaluation tasks (1 positive)
Dataset digest:
sha256:5d32143561ff4b116cf31ee3c4b782a64cf164ba5aad47c65d8f71564c34eb09(skill-evaluator-dataset-snapshot/1)Attempts per task: 1
Environment:
k8s-sandboxTier 2 evidence: required for publication
Tier 3 evidence: required for publication
Each task attempt ran in its own isolated sandbox pod.
What This Report Answers
The three-tier evaluation checks whether the skill:
is safe to use;
produces correct answers;
is discovered and activated when needed;
helps the agent complete the user's goal and expected workflow; and
avoids wasted skill and tool usage.
Results at a Glance
| Measure | Claude Code (Baseline → Skill Uplift) | Codex (Baseline → Skill Uplift) |
|---|---|---|
| Overall | 99.6% — baseline ran, but no comparable score was available; uplift unavailable | 76.7% — baseline ran, but no comparable score was available; uplift unavailable |
| Security | 100.0% → 100.0% (±0.0 points) | 100.0% → 100.0% (±0.0 points) |
| Correctness | 0.0% → 100.0% (+100.0 points) | 20.0% → 100.0% (+80.0 points) |
| Discoverability | 100.0% — baseline ran, but no comparable score was available; uplift unavailable | 0.0% — baseline ran, but no comparable score was available; uplift unavailable |
| Effectiveness | 16.7% → 100.0% (+83.3 points) | 48.3% → 85.0% (+36.7 points) |
| Efficiency | 98.0% — baseline ran, but no comparable score was available; uplift unavailable | 99.7% → 98.5% (-1.2 points) |
How to read this table: baseline is the same task attempted without the target skill. Scores are rounded to one decimal; threshold-adjacent values use additional precision so their displayed band matches the verdict. Uplift is derived from those displayed scores and shown in percentage points.
Example: 47.0% → 92.0% (+45.0 points) means the skill-assisted run scored 92.0%, 45.0 percentage points above its 47.0% no-skill baseline.
A partial dimension was calculated from only the available configured signals; review the detailed report before relying on it.
Token Usage
Actual Tier 3 execution usage is reported for every observed agent/case pair and both conditions.
| Agent | Dataset case | With skill | Without skill | Delta | Change | Coverage |
|---|---|---|---|---|---|---|
| claude-code | All cases | 66,082 | 245,870 | -179,788 | -73.12% | skill 1/1; base 1/1 |
| claude-code | tao-generate-referring-expressions-basic | 66,082 | 245,870 | -179,788 | -73.12% | skill 1/1; base 1/1 |
| codex | All cases | 13,944 | 13,502 | +442 | +3.27% | skill 1/1; base 1/1 |
| codex | tao-generate-referring-expressions-basic | 13,944 | 13,502 | +442 | +3.27% | skill 1/1; base 1/1 |
| ALL AGENTS | Dataset aggregate | 80,026 | 259,372 | -179,346 | -69.15% | skill 2/2; base 2/2 |
Prompt tokens include cached reads, so total tokens are prompt + completion (cached is not added twice). The Efficiency score uses (prompt - cached) + completion. N/A means the relevant trajectory counters were not available; coverage is never estimated.
Tier Status
| Tier | Purpose | Status | Evidence |
|---|---|---|---|
| Tier 1 | Static validation | PASSED WITH OBSERVATIONS | 11 validator(s); 22 finding(s) |
| Tier 2 | Semantic deduplication | PASSED WITH OBSERVATIONS | 2 validator(s); 1 finding(s) |
| Tier 3 | Live agent evaluation | PASS | 2 agent(s); 1 task(s) |
Findings and Observations
<details> <summary>Show detailed findings and successful checks</summary>
HIGH DUPLICATE/duplicate: Duplicate content found across SKILL.md and references/configuration.md: "### Initial setup" in SKILL.md (lines 28-56) vs "## Configuration" in SKILL.md (lines 82-96) vs "## Key Configuration Decisions" in references/configuration.md (lines 60-73) vs "## All Parameters" in references/configuration.md (lines 123-147) (
SKILL.md:28)MEDIUM QUALITY/quality_correctness: SKILL_SPEC recommended field missing: 'metadata.tags' (
skills/data/tao-generate-referring-expressions/SKILL.md)MEDIUM SCHEMA/frontmatter_field_placement: Root field 'tags' is ignored; use 'metadata.tags' (
skills/data/tao-generate-referring-expressions/SKILL.md)MEDIUM SCHEMA/folder_hierarchy: Unexpected nesting depth for general skill (
skills/data/tao-generate-referring-expressions)MEDIUM SCHEMA/body_recommended_section: Missing recommended section: '## Examples' (
skills/data/tao-generate-referring-expressions/SKILL.md)18 additional finding(s) are available in the full evaluation artifacts.
</details>
Scoring Methodology
<details> <summary>Show dimension definitions, source signals, and thresholds</summary>
| Dimension | Question | Scored signals |
|---|---|---|
| Security | Is it safe to use? | security (100%) |
| Correctness | Is the answer correct? | accuracy (100%) |
| Discoverability | Was the right skill loaded when needed? | skill_execution (100%) |
| Effectiveness | Did the skill help complete the task? | goal_accuracy (50%) + behavior_check (50%) |
| Efficiency | Did it avoid wasted tool calls and token usage? | skill_efficiency (50%) + token_efficiency (50%) |
Dimension bands: PASS at 50% or above; NEUTRAL from 40% to below 50%; FAIL below 40%.
Overall Tier 3 lift: PASS at +5 points or more; FAIL at -10 points or less; values between those bands are NEUTRAL.
Overall verdict: PASS only when every configured dimension passes for at least one supported agent. Lift is reported as diagnostic evidence and does not override this gate.
The 50% attempt pass threshold is a separate per-task gate; it is not the dimension pass threshold.
Effectiveness is the equal-weight mean of goal completion (
goal_accuracy) and expected workflow adherence (behavior_check).Efficiency is 50% tool-call productivity (the backward-compatible
skill_efficiencywire id) and 50%token_efficiency. Positive-case skill routing is scored under Discoverability, not Efficiency; a negative case without a routing target is N/A. N/A sources are omitted, remaining weights are renormalized, and the dimension is marked partial.
Signals present in this run:
security(Security): unsafe operations, secret leakage, and unauthorized access.skill_execution(Skill Execution): whether the expected skill was selected, decoys were avoided, and the workflow executed.skill_efficiency(Tool Productivity): tool-call productivity (legacy wire id; routing is scored under Discoverability).accuracy(Accuracy): final-answer correctness against the reference answer.goal_accuracy(Goal Accuracy): whether the user's goal was achieved.behavior_check(Behavior Check): whether the expected workflow behavior was followed.token_efficiency(Token Efficiency): actual uncached prompt plus completion usage (50% of Efficiency).
</details>
Freshness
Regenerate this benchmark when the skill, evaluation dataset, target agent/model, evaluator version, environment, or scoring policy changes.
Requirements and compatibility
Works with: Claude Code, Claude apps, OpenAI Codex, GitHub Copilot, Cursor, Gemini CLI, Kiro, OpenCode, Goose, Amp, Roo Code, JetBrains Junie, Factory Droid, Devin (ex-Windsurf), Mistral Vibe, OpenHands, Letta
“Works with” means the tool reads the open Agent Skills format; a skill written for one tool may use features others lack.
Needs: Declares allowed tools, Needs an API key
The author says: Requires docker + nvidia-container-toolkit + at least one VLM endpoint (Gemini API key or OpenAI-compatible).
Security
What our scanner noticed· Medium risk
- Large base64-encoded blobs
- Instructions that use the network
A static scan is not a guarantee. Skills are third-party content: review a skill before you let an agent use it.
Attribution and licence
- Created by
- NVIDIA Corporation
- Publisher
- NVIDIA (Official)
- Source
- NVIDIA/skills · skills/tao-generate-referring-expressions · commit fce3cca
- Licence
- Apache License 2.0 (redistribution allowed)
- LICENSE (added by AutoGineer from LICENSE-APACHE)
- ATTRIBUTION.md (written by AutoGineer)
- Synced
AutoGineer is not affiliated with or endorsed by NVIDIA Corporation or NVIDIA.
Download ZIP
The ZIP holds the skill’s files, its licence files and an ATTRIBUTION.md. Download tao-generate-referring-expressions.zip