Generated banner for Cdf Augmentation
Generated logo for Cdf Augmentation

Cdf Augmentation

NVIDIAOfficialCreated by NVIDIA

  • Skill
  • Workflow
  • Data and AI
  • Apache-2.0
  • Medium risk

From the author

Use when authoring or validating Cosmos Data Factory (CDF) augmentation YAML configs, or running remote Cosmos Transfer (including Cosmos3 WSM controls), Cosmos Predict, image-edit, or image-to-video inference.
— the description by NVIDIA

AutoGineer summary

Written by AutoGineer from the skill’s own files, not by the author

The cdf-augmentation skill provides a structured workflow for managing remote-API pipelines within the Cosmos Data Factory ecosystem. It enables users to author and validate YAML configurations for tasks including Cosmos Transfer, Cosmos Predict, image editing, and image-to-video inference. The skill handles the entire lifecycle of an augmentation task, from verifying container environments and endpoint connectivity to executing inference loops and applying quality gates via external evaluators.

What it does

  • Author and validate PipelineConfig YAML files for various augmentation tasks.
  • Manage remote inference pipelines for video transfer, prediction, and image editing.
  • Verify container runtime environments and Git commit integrity before execution.
  • Configure and execute captioning strategies using VLM and LLM endpoints.
  • Implement quality gates and evaluation loops with external Cosmos evaluators.
  • Handle precomputed WSM controls for advanced video generation workflows.

When to use it

  • When you need to perform scene attribute changes on video using Cosmos Transfer.
  • When generating or extending video content via Cosmos Predict.
  • When editing specific attributes of an image or animating a frame into video.
  • When you need to validate a pipeline configuration against schema requirements.
  • When integrating external Cosmos evaluation into a media generation workflow.

Advantages

  • Provides a standardized, repeatable workflow for complex media augmentation tasks.
  • Ensures configuration consistency through mandatory validation steps.
  • Supports flexible, remote-API based model execution without local weight dependencies.
  • Includes built-in quality control via configurable evaluation gates.
  • Enforces strict environment verification to ensure reproducible results.

Usage examples

“I need to change the weather in this video to rainy. How do I start?”
The agent will guide you through selecting the appropriate Cosmos Transfer config, verifying your input video, and setting up the required VLM/LLM endpoints for captioning.
“Validate my config_video_transfer_CT3_omni.yaml file.”
The agent will launch the container, run the validation command against the specified YAML, and report any schema or configuration errors.
“Run an image-to-video generation using my image at s3://my-bucket/frame.png.”
The agent will verify the environment, check the provided S3 URI, and execute the inference pipeline using the configured Cosmos3 image-to-video model.

Install

  1. Download the skill as a ZIP:

    https://mp-staging.autogineer.com/agent-skills/nvidia/cdf-augmentation/download
  2. Unzip it into the cross-client skills folder of your project:

    mkdir -p .agents/skills && unzip cdf-augmentation.zip -d .agents/skills

Documentation by NVIDIA

CDF Augmentation Pipeline Skill

Remote-API pipeline for captioning, generating, and evaluating augmented camera data. Models are configured as HTTP endpoints; no local model weights are included.

Purpose

Use it to select a supported generation mode, author and validate PipelineConfig YAML, configure captioning/evaluators, and run the cdf-augmentation:1.2.0 container. It covers Cosmos Transfer/Predict, Cosmos3 WSM controls, image editing, image-to-video, BYOM endpoints, and quality gates.

Do not use this skill for training or fine-tuning models, deploying clusters or NIM endpoints, or unrelated application/database development.

Prerequisites

RequirementDetail
Dockerdocker --version. The image is remote-API only — it bundles no Cosmos/torch weights, so plain remote inference needs no GPU and no HF_TOKEN.
NVIDIA GPU (conditional)Only when a configured local stage requires CUDA or decodes H.264 in the augmentation container. See Limitations.
Endpoint URLsOne reachable URL per role used by the selected config. The examples name local Qwen services (Qwen/Qwen3.6-27B-FP8 on vlm, Qwen/Qwen2.5-14B-Instruct on llm), but those are not guaranteed to be running. Resolve every required role independently: keep each reachable configured endpoint and ask only for the missing role URLs.
API keys (conditional)Only for endpoints requiring authentication. Pass the environment variable named by each endpoint's api_key_env; never hardcode values in YAML. Local unauthenticated endpoints need none.
Input mediaA video/image reachable by multistorageclient (s3://, msc://, gs://, az://, or HTTPS). Local paths are allowed only when no external Cosmos evaluator is enabled; external evaluation requires checker-readable remote URIs.
Approved release commit (execution only)A 40-character commit hash confirmed by the user as release-owner-approved or retrieved from the verified release manifest. Never invent it or rely on an unverified environment value.

Inputs

Resolve each value in this precedence order: state file → explicit prompt arguments → agent context → user prompt. Ask the user only for what remains unresolved.

InputRequiredDescription
config_pathYesPath to the pipeline YAML, e.g. configs/cookbook/video-data-augmentation/config_video_transfer_CT3_omni.yaml. If absent, pick a starting config from Supported Models and confirm with the user.
input_mediaConditionalSource video/image → data[].inputs.rgb. Required for every mode except Cosmos Predict inference_type: text2world, where inputs may be null or rgb omitted. Overridable at run time via data.0.inputs.rgb=....
control_mediaFor precomputed controlControl video → data[].inputs.controls.<type>. For Cosmos3 WSM transfer, set controls.wsm; the client uploads it rather than exposing its local path to the server.
output_pathsYesdata[].output.{video,caption,metadata}; evaluation optional.
model_nameYesaugmentation.model.name — an endpoint id, a role, or a known model name. Free-form string, not an enum.
endpoint_urlsYesOne endpoints[] entry per role in use.
api_key_envIf authEnv-var name per endpoint; the value comes from the environment.
target_attributesNocaptioning.llm.variables (e.g. weather_condition, lighting_condition).
generation_paramsNoaugmentation.parameters — pass-through; only set knobs are sent.
seedNoUnder augmentation.parameters. Before the first candidate, null resolves once to the generator/executor seed when available, otherwise the current Unix time. Retry n uses that resolved base seed plus n. pipeline.retry defaults to 1, so evaluation permits at most 2 candidates by default.

BYOM model: endpoints, adapters, roles

Each endpoints: list entry declares role, url, wire model, and optional id, adapter, api_key_env, and timeout. Roles are vlm, llm, image_edit, video_transfer, video_predict, image2video, and evaluator. augmentation.model.name resolves by endpoint id, then role, then the known model-name mapping. Adapter contracts and full fields are in configuration-schema.md.

Supported Models

When the user hasn't specified a model, choose from their input type and goal:

Input Type → Goalmodel.nameRole / default adapterInput → Output
Video — change scene attributes (weather, lighting, style)cosmos-transfer2.5video_transfer / nimVideo (+ controls) → Video
Video + precomputed WSM — follow world-state geometry/motionA video_transfer endpoint id, e.g. cosmos3-transfer-wsmvideo_transfer / openai.video.asyncRGB video + WSM control + prompt → Video
Video + text — extend or predict continuationcosmos-predictvideo_predict / nimVideo+Text → Video
Text only — generate video from scratchcosmos-predict (inference_type: text2world)video_predict / nimText → Video
Image — edit specific attributesimage-editimage_edit / nim (or openai.chat.completions, openai.images.edits)Image → Image
Image — animate a first framecosmos3-image2video (or your Veo endpoint id)image2video / openai.video.sync (Veo: openai.video.async)Image + prompt → Video

Key rule: use Cosmos Transfer for video scene changes, Cosmos Predict for new/continued video, image edit for still edits, and image-to-video to animate a frame. For Cosmos3 WSM, set data[].inputs.controls.wsm. Config selection details are in config-decision-tree.md.

All models run via remote HTTP through one BaseExecutor; there is no local torchrun and no executor_type field.

Canonical Workflow

Follow this ordered decision tree; open the linked references only for the selected mode's details.

Config Correction Budget

config_attempts counts YAML versions, not validation or preflight calls. Keep it across the whole workflow and never reset it.

  1. Set it to 1 after initial authoring.

  2. On a correctable error, if it is already 3, STOP and report the error. Otherwise increment it once and make one correction pass containing all currently reported YAML fixes.

  3. Validate and preflight that edited version without another increment. Repeat rule 2 only if a later check finds another correctable YAML error.

STEP 0 — Mandatory Entry Gate

Execute this gate before every other step:

  • Scope gate: if the request asks for training, fine-tuning, cluster/NIM deployment, or unrelated development, decline it and STOP.

  • Input gate: resolve values using Inputs. If required values remain unresolved, request only those values and STOP until they are supplied.

  • Proceed only when both gates pass and the input type and augmentation goal are known.

  1. Select the model from Supported Models using that input type and goal.

  2. Author the YAML in this order: data, endpoints, captioning, augmentation, evaluators, pipeline, then data_processing. Omit optional sections rather than creating placeholders. Set config_attempts = 1 (config attempt 1 of 3).

  3. Branch on the requested outcome:

    • Configuration only or “do not execute”: do not build, launch, run preflight, or infer. A trusted runtime is an already-running container whose recorded immutable image ID/digest, checkout commit, and config mounts satisfy step 4. If validation was explicitly requested and such a runtime exists, run only the validation command and apply step 5's failure rules. Return the config (mark it unvalidated if validation was not run) and STOP.

    • Inference/run requested: proceed to step 4.

  4. Prepare the runtime in these verifiable sub-steps: a. Obtain EXPECTED_RELEASE_REF from the user as a release-owner-approved full commit or retrieve it from the verified release manifest. b. Verify the Git working tree is clean. c. Verify HEAD matches EXPECTED_RELEASE_REF. If a release tag selected the revision, verify the tag first, then compare its resolved full commit. d. Build the image and capture its immutable sha256: image ID, or obtain a verified registry digest. e. Create the cdf Docker bridge if needed and attach local services. f. Launch the container using the recorded image ID, the cdf network, required volume mounts, --entrypoint /bin/bash, and only the endpoint key variables named by api_key_env plus the scoped storage credential variables required for the configured remote media. If any sub-step fails, STOP and report the exact failure and relevant remediation: clean a dirty tree, supply the approved revision, resolve a revision mismatch, check the Docker daemon/build, fix network setup, or fix the container launch. Do not continue with a partial runtime.

  5. Inside the container, run the validation-only command in Usage Step 2 and classify its result while preserving config_attempts (current config attempt N of 3):

    • Success: if no external Cosmos evaluator is enabled, proceed directly to step 7. If one is enabled, proceed to step 6.

    • Editable YAML/schema error: when required endpoint URL/model details are known, apply the Config Correction Budget rule, then rerun validation on that YAML version.

    • Infrastructure/unknown input: for missing endpoint details, credentials, DNS, connectivity, or unhealthy services, do not edit speculatively. STOP and report the error or ask for the missing endpoint details.

  6. With external Cosmos evaluation enabled, preserve config_attempts (current config attempt N of 3) and run its hard preflight gate before captioning/generation by querying /health, /checkers, and /dependency-graph:

    • Pass: require /health.status == "healthy"; require every configured checks[].name to exactly equal one string in the top-level checkers array returned by /checkers and one key in the top-level checkers object returned by /dependency-graph. Do not use substring, alias, or nested-field matching. Then proceed to step 7.

    • Config error: only a 4xx response from /checkers or /dependency-graph whose body explicitly identifies a configured checker name or invalid config field qualifies. Apply the Config Correction Budget rule, then return to step 5; revalidation does not increment the counter.

    • Infrastructure failure: any timeout, network/DNS error, 5xx response, /health failure, unhealthy service, or missing deployed checker stops the workflow before generation. Create no candidate and report the root cause.

  7. Enter inference only after step 5 succeeds and, when external evaluation is enabled, step 6 passes. Run a candidate loop bounded to pipeline.retry + 1 candidates (retry defaults to 1, so the default maximum is 2). Resolve the base seed once before the first candidate as defined in Inputs; retry n uses base_seed + n:

    • Generate a candidate and run its configured evaluators.

    • On pass, accept it and exit the loop.

    • On quality failure with attempts remaining, set the next seed to base_seed + next_retry_number. If regenerate_caption_on_retry: true, regenerate the caption next; then generate the replacement. If false, generate the replacement immediately.

    • On exhausted quality retries, fail evaluation and exit the loop.

    • On a service/contract failure, stop on the current candidate without generating another. For external Cosmos evaluation, this means a submission, polling, or discovery failure; a failed execution; a missing or skipped result; or an invalid gating contract without a literal top-level boolean passed. With pipeline.evaluation.strict: true (the default), apply retain_failures: its default true retains video, caption, metadata, and evaluation outputs for inspection; explicit false deletes them. With strict: false, retain the files and report the evaluator failure without failing the sample.

      • If provider metadata contains error_code: ambiguous_post, preserve the retained candidate, do not resubmit automatically, STOP, and defer to operator recovery. Follow the ambiguous-POST recovery flow.

Usage

Step 1: Verify, Build, and Launch the Docker Container

Set EXPECTED_RELEASE_REF to a release-owner-reviewed full 40-character commit, never a tag or branch. If a signed release tag selects the revision, verify the tag first and record its resolved full commit as EXPECTED_RELEASE_REF. Build only from a clean matching checkout, then record the resulting immutable image ID. For a prebuilt release, use its verified digest.

set -e

EXPECTED_RELEASE_REF="${EXPECTED_RELEASE_REF:?set a reviewed full commit ID}"
test "${#EXPECTED_RELEASE_REF}" -eq 40
case "$EXPECTED_RELEASE_REF" in *[!0-9a-fA-F]*) exit 1 ;; esac
test -z "$(git status --porcelain)"
test "$(git rev-parse HEAD)" = "$(git rev-parse "${EXPECTED_RELEASE_REF}^{commit}")"

DOCKER_BUILDKIT=0 docker build \
  -t cdf-augmentation:1.2.0 \
  -f docker/Dockerfile .
CDF_IMAGE_ID="$(docker image inspect --format '{{.Id}}' cdf-augmentation:1.2.0)"
case "$CDF_IMAGE_ID" in sha256:*) ;; *) exit 1 ;; esac
test "$(docker image inspect --format '{{.Id}}' cdf-augmentation:1.2.0)" = "$CDF_IMAGE_ID"

docker network inspect cdf >/dev/null 2>&1 || \
  docker network create cdf
# Attach each local model container once, for example:
# docker network connect cdf vlm

# Example only: replace these with exactly the api_key_env names declared by
# the selected config; use an empty array when every endpoint is unauthenticated.
CDF_ENDPOINT_KEY_ARGS=()
# Authenticated example:
# CDF_ENDPOINT_KEY_ARGS=(-e VLM_API_KEY -e LLM_API_KEY -e VEO_API_KEY)

# Forward only credential names required by the configured remote media. Give
# checker containers their own scoped credentials in their deployment.
CDF_STORAGE_CREDENTIAL_ARGS=()
# S3-compatible example (include only the names your storage config requires):
# CDF_STORAGE_CREDENTIAL_ARGS=(-e AWS_ACCESS_KEY_ID -e AWS_SECRET_ACCESS_KEY \
#   -e AWS_DEFAULT_REGION -e AWS_ENDPOINT_URL)

docker run -it --rm \
  --network cdf \
  "${CDF_ENDPOINT_KEY_ARGS[@]}" \
  "${CDF_STORAGE_CREDENTIAL_ARGS[@]}" \
  -v "$(pwd)/modules:/workspace/modules" \
  -v "$(pwd)/configs:/workspace/configs" \
  -v "$(pwd)/data:/workspace/data" \
  --entrypoint /bin/bash \
  "$CDF_IMAGE_ID"

Persist the captured sha256: ID and use it directly for every later launch; never re-resolve the mutable tag as the launch target. For registry releases, verify the signed manifest and use name:tag@sha256:<manifest-digest>.

  • Networking: augmentation is an outbound-only client and does not publish ports. Use the user-defined cdf bridge for the augmentation container and every local model, Arbitrator, and checker container. cosmos-evaluator may be a container/DNS hostname on that bridge; it is not a second bridge name. Change endpoint URLs from host localhost addresses to container DNS names, for example http://vlm:8000/v1. The default bridge is sufficient when every endpoint is remote.

  • API keys: prefer a platform secrets manager that injects the required environment variables. Otherwise, export only the required keys and forward their names with -e VAR_NAME; never mount or load a broad credential file.

  • No GPU needed for remote inference — add --gpus for data_processing.alignment and any H.264 decode; pick a GPU not shared with a busy model server. Container runs as uid 10000; ensure data/ is writable (or --user "$(id -u):$(id -g)").

Warning: Never enable Docker host-network mode on shared, multi-tenant, or production hosts. It is permitted only when all three conditions hold: (1) a required host-local service cannot be moved onto the cdf bridge, (2) the host is single-tenant and isolated with no other workloads, and (3) the user sends an explicit message in the current conversation choosing host networking after receiving a warning that it removes network namespace isolation. Silence, prior documentation, or an earlier unrelated approval is not acceptance. Do not select it automatically. Review pipeline-operations.md.

Step 2: Validate, Then Run (Inside the Container)
# Schema and cross-section preflight only: no endpoint calls or inference.
uv run --no-sync modules/cli.py --config configs/<config_file>.yaml --validate-only

# Run only after validation succeeds.
uv run --no-sync modules/cli.py --config configs/<config_file>.yaml

# With OmegaConf CLI overrides (dot-list syntax)
uv run --no-sync modules/cli.py --config configs/<config_file>.yaml \
  data.0.inputs.rgb=/workspace/data/input.mp4 \
  augmentation.parameters.seed=42

Environment variables: generation/captioning keys resolve as the api_key_env var → the role's default env var. External Cosmos evaluation reads only the variable explicitly named by its endpoint and fails initialization when that variable is unset. Leave api_key_env off for unauthenticated endpoints. LOG_LEVEL sets logging.

Configuration Schema

Configs are validated against PipelineConfig (modules/aug_utils/schema/) and have seven top-level sections. Author them in the canonical order above; YAML key order does not change runtime semantics. Full per-section YAML is in configuration-schema.md; runtime flow and common editing tasks are in pipeline-operations.md.

Troubleshooting

Run all inference and schema validation inside the Docker container for a consistent environment. For config-validation errors, runtime/endpoint errors, and typical per-stage timings, see troubleshooting.md.

Limitations

  • Remote inference only. All models run behind remote HTTP endpoints; no local weights, no torchrun, no executor_type, no Gradio executor.

  • GPU for configured local stages. Remote inference needs no augmentation-container GPU. A CUDA GPU is required by data_processing.alignment (cupy) and by any local stage decoding H.264 because the image ships only the hardware h264_cuvid decoder (software AVC decode is off for licensing). VP9 decodes in software. Video output is VP9-only.

  • External-evaluator media must be remote. When an external evaluator is enabled, schema validation rejects local data[].inputs.rgb, control media, generated data[].output.video, and configured companion media. Use checker-readable s3://, msc://, gs://, az://, or HTTP(S) URIs; the pipeline does not upload local files solely for evaluation.

  • Inference only. This pipeline augments and generates media — it does not train or fine-tune models.

  • Auth varies by endpoint. Hosted endpoints (e.g. Veo) need a key via api_key_env; local endpoints (e.g. vLLM) need none.

Reference files

Files

references/evaluator-setup-guide.md

Evaluator Setup Guide

Overview

Evaluators run after generation to assess output quality. They are defined as a list under evaluators: in the config. Three executable top-level evaluator types are available:

  1. Hallucination Check — optical-flow-based motion artifact detection

  2. Attribute Verification — LLM generates MCQ questions, VLM answers them (the VLM-side config lives in a nested vlm_verification block)

  3. External Cosmos Evaluator — checker-agnostic quality gates orchestrated by a separately deployed Cosmos Evaluator Arbitrator

vlm_verification is not a standalone evaluator: it has no independent question/expected-answer contract. A top-level entry is rejected during config validation. Nest it under attribute_verification, where the LLM-generated or fixed MCQs provide that contract.

On failure, the pipeline retries with an incremented seed up to pipeline.retry times.

Hallucination Check

Detects motion artifacts by comparing optical flow between the original and augmented video. A high score means the output preserves the original motion well.

Note: This evaluator only works for video outputs. It is not applicable to image outputs (e.g., image edit), since optical flow requires multiple frames.

evaluators:
  - hallucination_check:
      enabled: true
      threshold: 0.682              # Score >= threshold = pass
      params:
        grad_thresh: 10.0           # Gradient threshold for motion detection
        blur_ksize: 7               # Gaussian blur kernel size
        morph_k: 3                  # Morphological operation kernel
        dist_tol_px: 7.0            # Distance tolerance in pixels
        max_frames: null            # null = all frames; set integer to limit
Tuning Hallucination Check
SymptomParameter to AdjustDirection
Too many false failures (good videos rejected)thresholdLower (e.g., 0.5)
Artifacts not caughtthresholdRaise (e.g., 0.8)
Slow on long videosmax_framesSet to 30–60
Noisy input causing false motion detectionblur_ksizeIncrease (must be odd)
Small artifacts missedgrad_threshLower (e.g., 5.0)

Typical scores: Good augmentations score 0.85–0.99. Hallucinated motion artifacts usually score below 0.5.

No additional endpoints required — runs locally using OpenCV optical flow.

Attribute Verification

A two-stage evaluator that verifies whether the generated output matches target attributes:

  1. LLM Question Generator — creates MCQ questions from variables (e.g., "What color is the person's shirt? A) Red B) Blue C) Green")

  2. VLM Verifier — answers the MCQ questions by looking at the generated output

Note: For video outputs, vlm_verification.frames controls how many evenly-spaced frames the VLM verifier samples (default 1 = first frame only). Use frames: >1 (e.g. 6) when the attribute is a mid-video event — the first frame of an image→video clip is the pre-event seed, so frames: 1 cannot see a collapse/fall/etc. For steady-state attributes (e.g. clothing color, weather) the first frame is usually enough.

evaluators:
  - attribute_verification:
      enabled: true
      generate_natural_caption_on_pass: true    # Generate natural description on success
      natural_caption:                          # Config for natural caption generation
        system_prompt: |
          Write a single natural sentence describing the person's appearance.
        user_prompt_template: |
          This image shows a person with: {attributes_text}.
          Write one sentence describing the person's appearance.
      extra_questions:                          # Custom MCQ questions (in addition to auto-generated)
        - variable: "multi_view_consistency"
          question: "Is the person's appearance consistent across all views?"
          options:
            A: "Yes, consistent across all views"
            B: "No, inconsistent across views"
          correct_answer: "A"
          request_reasoning: true
      question_generation:
        endpoint_id: llm_qwen       # optional; defaults to the single llm-role endpoint
        generate_options: false     # true = let the LLM invent distractors (correct answer stays pinned)
        system_prompt: |
          You are an expert at creating multiple choice verification questions.
          Generate a simple, direct question that verifies a specific attribute.
          The question must have 2-4 answer options.
          Output as a single JSON object.
        parameters:
          retry: 1
          temperature: 0.2          # Low temperature for consistent question format
          top_p: 0.95
          frequency_penalty: 0.0
          presence_penalty: 0.0
          max_tokens: 2048
          stream: true
      vlm_verification:             # VLM prompt + params used to answer the MCQ questions
        endpoint_id: vlm_qwen       # optional; defaults to the single vlm-role endpoint
        frames: 6                   # evenly-spaced video frames to sample (1 = first frame only)
        system_prompt: |
          You are an expert vision model. Analyze the frame(s) and select the best
          answer from the options. Respond with ONLY a single letter (A, B, C, or D).
        parameters:
          retry: 5                  # Higher retry for flaky VLM responses
          temperature: 0.0          # Deterministic for consistent answers
          top_p: 1.0
          frequency_penalty: 0.0
          max_tokens: 10            # Only need a single letter
          stream: false
Endpoint Requirements

Attribute verification requires both an llm-role endpoint (question generation) and a vlm-role endpoint (answering questions against the generated output) in the endpoints: list. By default each consumer uses the single endpoint of its role; set question_generation.endpoint_id / vlm_verification.endpoint_id to target a specific endpoint by id when more than one shares the role. Keys resolve per endpoint via api_key_env → role default (LLM_API_KEY, VLM_API_KEY); unauthenticated endpoints (e.g. local vLLM) need none.

How Variables Drive Verification

The verification questions are auto-generated from captioning.llm.variables (or verification_values if set):

captioning:
  llm:
    variables:
      top_outer_color: ["blue"]
      shoe_type: ["boots"]
    verification_options:
      top_outer_color: ["red", "blue", "green", "black", "white"]
      shoe_type: ["sneakers", "boots", "sandals", "heels"]

For each variable, the LLM generates a question like:

What color is the person's outer top garment?
A) red
B) blue       ← correct answer (from variables/verification_values)
C) green
D) black

The VLM then answers by looking at the generated image/video. If it selects "B", the check passes.

Extra Questions

Custom questions appended to the auto-generated ones. Useful for domain-specific checks:

      extra_questions:
        - variable: "multi_view_consistency"      # Variable name for metadata
          question: "Is the appearance consistent across all views?"
          options:
            A: "Yes, consistent"
            B: "No, inconsistent"
          correct_answer: "A"
          request_reasoning: true                  # Ask VLM for reasoning

Fields:

  • variable — optional, associates the question with a named attribute in metadata

  • question — the question text

  • options — dict of letter → answer text (2–4 options)

  • correct_answer — the expected correct letter

  • request_reasoning — if true, asks VLM to explain before answering

Natural Caption Generation

When generate_natural_caption_on_pass: true, after all attribute checks pass, the VLM generates a natural-language description of the output:

      generate_natural_caption_on_pass: true
      natural_caption:
        system_prompt: |
          You are an expert at describing images of people. Be concise and factual.
        user_prompt_template: |
          This image shows a person with: {attributes_text}.
          Write one natural sentence describing the person's appearance.

The {attributes_text} placeholder is replaced with the verified attribute values (e.g., "top outer color: blue; shoe type: boots"). The resulting caption is saved to metadata.natural_caption.

External Cosmos Evaluator

This evaluator submits an externally readable generated candidate to a Cosmos Evaluator Arbitrator. Augmentation selects free-form checker names through configuration and interprets only their common top-level passed: bool gating contract; checker-specific scores and fields remain opaque.

The endpoint must use the evaluator-only contract:

endpoints:
  - id: cosmos_evaluator
    role: evaluator
    url: "http://cosmos-evaluator-arbitrator:8000"
    adapter: cosmos.evaluator.arbitrator
    timeout: 1800

The hostname above assumes the augmentation container joins the same Docker bridge as Arbitrator. For a separate deployment, use its trusted URL. If that deployment requires authentication, add api_key_env with the name of the environment variable holding the key. The key is sent as Authorization: Bearer <key>; never put its value in YAML.

evaluators:
  - cosmos_evaluator:
      enabled: true
      endpoint_id: cosmos_evaluator
      poll_interval_seconds: 5
      stream_key: camera_front_wide_120fov
      output_storage_prefix: "team/evaluations/run-42/"
      merge_captioning_selections: true
      checks:
        - name: metropolis.attribute_verification
          gate: true
          metadata_key: attribute_verification
      inputs: {}
      config:
        selected_variables:
          weather: snowy
          time_of_day: night
        variable_options:
          weather: [sunny, cloudy, rainy, snowy]
          time_of_day: [morning, night]
Discovery and request flow

Before captioning or generation, augmentation calls Arbitrator's /health, /checkers, and /dependency-graph endpoints. Every selected checker must be both healthy and present in the graph. For each candidate, augmentation then:

  1. Deep-copies inputs and injects the generated URI at augmented_video_urls[stream_key].

  2. Deep-copies the one shared config; when merge_captioning_selections: true, sampled captioning values/options are merged by key and win over matching configured keys.

  3. Submits once to POST /process/async, then polls GET /executions/{request_id} until terminal within the endpoint timeout.

  4. Reads each configured result either from checker_results[checker_name][stream_key] or directly from checker_results[checker_name]. The pinned service stores response_json as a JSON string; the client also accepts an already-decoded object.

output_storage_prefix is required for enabled evaluation and is a relative key prefix in storage configured for the checker services—not a storage URI. Use a concrete prefix unique to each run. See configuration-schema.md for its exact validation rules and the deterministic fallback stream-key algorithm.

inputs can carry current or future Arbitrator fields without checker-specific augmentation code. Common media fields are original_video_urls (for Hallucination), world_model_video_urls, and rds_hq_url (for Objects). Per-stream companion maps must contain the resolved stream key.

Gating and failures
  • gate: true: the selected result must contain a literal top-level boolean passed. false is a quality failure and can use the existing generation retry/seed re-roll.

  • gate: false: the result is retained as observation metadata but does not reject the candidate; it need not expose passed.

  • A terminal parent execution status of success means checker jobs completed; it is not itself a quality pass. Augmentation still inspects every gate.

  • Submission/polling/discovery failures, a failed execution, missing or skipped results, and an invalid gating contract are service failures. Safe GETs are retried, but an ambiguous POST is never resubmitted because Arbitrator has no idempotency key. Service failures stop evaluation without generating a new candidate. The provider block records a redacted service_failure; with the defaults (strict: true, retain_failures: true) the generated candidate is retained for inspection, the sample is not counted as successful, and the run exits non-zero.

The persisted cosmos_evaluator provider block is machine-readable. It always contains request_id (an integer after a valid acceptance response, otherwise null). error_code: ambiguous_post means the POST may have reached Arbitrator but no usable request ID reached the client; agents must enter the recovery flow below. Other clear operational failures use error_code: service_failure and must not be treated as ambiguous submissions.

For an ambiguous POST (the request may have reached Arbitrator but no request_id reached the client), recovery is deliberately operator-driven:

  1. Do not blindly resubmit. Check Arbitrator logs and the checker storage area identified by that run's unique output_storage_prefix to determine whether the original execution exists or completed.

  2. If the original execution can be identified, inspect or finish handling that execution without posting the candidate again.

  3. If its state cannot be established, preserve the retained candidate, choose a new unique output_storage_prefix, and rerun it as a new evaluation. This may leave an orphaned first execution, but avoids silently treating an uncertain submission as a quality rejection.

Automatic POST retry is unsafe until Arbitrator offers an idempotency key or a client-supplied request identifier that can be queried after a lost response.

The generated video and every configured media input must be readable by the external checker containers, normally through shared object storage or HTTP. The pipeline does not upload local files solely for evaluation. Remote evaluation adds no GPU requirement to the augmentation container.

CT3 Omni external evaluator example

configs/cookbook/video-data-augmentation/config_video_transfer_CT3_omni.yaml is the shipped external-evaluator VDA example. It has no built-in evaluator fallback: one Cosmos entry selects gated metropolis.hallucination and metropolis.attribute_verification and exposes their results through the compatibility aliases hallucination_check and attribute_verification.

Hallucination requires both sides of the comparison. Augmentation injects the generated remote URI as augmented_video_urls[stream_key]; the config derives inputs.original_video_urls[stream_key] from data[0].inputs.rgb, so one input override updates both consumers. The stream key is camera_front_wide_120fov. The generated video is also remote, while output_storage_prefix remains a unique relative key.

The shared flat config overrides the Hallucination threshold while relying on the checker's defaults for its motion-mask settings. It defines snow/night Attribute Verification selections and supplies checker-side LLM/VLM URL/model values. Those service names must resolve from the checker containers, not only from augmentation.

The deployed external Attribute Verification checker examines the first video frame and does not generate natural_caption. Replace S3 and output_storage_prefix placeholders before running. Both checks are gates and pipeline.evaluation.strict is true, so either failure marks the sample unsuccessful. pipeline.retry: 0 means it does not generate a replacement. Outputs are still retained (retain_failures: true).

Evaluator Combinations

No Evaluators (Generation Only)
# Simply omit the evaluators section
# evaluators: null
Hallucination Check Only
evaluators:
  - hallucination_check:
      enabled: true
      threshold: 0.682
Attribute Verification Only (Image Editing)

Common for image edit where there's no motion to hallucination-check:

evaluators:
  - attribute_verification:
      enabled: true
      question_generation:
        system_prompt: "..."
      vlm_verification:
        system_prompt: "..."
Full Evaluation (Video Augmentation)

Hallucination check runs first; if it passes, attribute verification runs:

evaluators:
  - hallucination_check:
      enabled: true
      threshold: 0.682
      params:
        grad_thresh: 10.0
  - attribute_verification:
      enabled: true
      question_generation:
        system_prompt: "..."
      vlm_verification:
        system_prompt: "..."
External Cosmos Gate (CT3 Omni)

Use the config_video_transfer_CT3_omni.yaml example. It contains one external gate rather than duplicating the built-in attribute verifier:

evaluators:
  - cosmos_evaluator:
      enabled: true
      endpoint_id: cosmos_evaluator
      output_storage_prefix: "<OUTPUT_PREFIX>/ct3-omni/<RUN_ID>/"
      checks:
        - name: metropolis.attribute_verification
          gate: true
          metadata_key: attribute_verification

Retry Behavior

The retry mechanism is a bounded candidate loop:

  1. Generation runs with initial seed

  2. Evaluators run in order for that candidate:

    • If hallucination check fails → skip attribute verification, retry immediately

    • If attribute verification fails → retry

    • If an external Cosmos gate returns passed: false → retry

  3. A quality failure creates a replacement only when attempts remain. On that retry, the seed is incremented by 1.

  4. If pipeline.regenerate_caption_on_retry: true and a captioner is configured, captioning reruns and overwrites the prompt (saved to output.caption)

  5. Generation reruns with the new seed (and possibly a new prompt)

  6. The loop ends after a pass or after exactly pipeline.retry + 1 candidate attempts. Exhaustion is an evaluation failure; there is no further cycle.

External service/contract failures are not quality failures and do not spend a generation retry: they stop the loop on the current candidate and follow strict/retain_failures. Observe-only Cosmos checks never trigger a retry.

Seed progression: If original seed is 12345, retries use 12346, 12347, etc.

Pipeline settings control retry behavior:

pipeline:
  retry: 1
  regenerate_caption_on_retry: true # Rerun captioning before a retry if evaluators fail
  evaluation:
    strict: true                    # Fail sample on any evaluator failure
    retain_failures: true           # Keep output files even on failure

Metadata Output

After evaluation completes, results are written to output.metadata:

{
  "prompt": "change the person top outer color to blue...",
  "selections": {"top_outer_color": "blue", "shoe_type": "boots"},
  "output_media_path": "/workspace/data/output.png",
  "input_media_path": "/workspace/modules/input.png",
  "control_media": {},
  "hallucination_check": {
    "passed": true,
    "score": 0.9685,
    "threshold": 0.682,
    "attempt": 1,
    "seed_used": 42
  },
  "attribute_verification": {
    "passed": true,
    "details": { ... },
    "attempt": 2,
    "seed_used": 43
  },
  "natural_caption": "A person wearing a blue shirt and black jeans with brown boots."
}

An external run instead adds its sanitized provider block and any configured compatibility alias. It does not imply a built-in evaluator also ran:

{
  "cosmos_evaluator": {
    "request_id": 814,
    "status": "success",
    "version": "1.1.0",
    "commit_sha": "...",
    "stream_key": "camera_front_wide_120fov",
    "checks": {
      "metropolis.attribute_verification": {
        "camera_front_wide_120fov": {
          "passed": true,
          "result": {"passed": true}
        }
      }
    }
  },
  "attribute_verification": {
    "passed": true,
    "result": {"passed": true}
  }
}

If a Cosmos check declares metadata_key, the same sanitized compatibility view is written at that root key when schema validation proves it cannot collide. If output.evaluation is specified in the data section, a separate evaluation-only JSON is also written.

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: Needs an API key, Needs a command-line tool, Needs Python

Security

What our scanner noticed· Medium risk

  • Large base64-encoded blobs

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
Publisher
NVIDIA (Official)
Source
NVIDIA/skills · skills/cdf-augmentation · 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.

Download ZIP

The ZIP holds the skill’s files, its licence files and an ATTRIBUTION.md. Download cdf-augmentation.zip