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://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/configuration-schema.md

Configuration Schema

Configs live under configs/cookbook/<use-case>/. See the cookbook index for the folder layout.

All YAML configs are validated against a Pydantic PipelineConfig model (modules/aug_utils/schema/). Seven top-level sections:

data:             # List of input/output sample paths (required, min 1)
endpoints:        # LIST of API endpoints (one entry per model/role)
pipeline:         # Retry, logging, evaluation settings
captioning:       # VLM and/or LLM captioning configuration
augmentation:     # Model selection, parameters, modalities
data_processing:  # Optional processors: preprocessing.resize runs BEFORE generation, alignment + transcode AFTER
evaluators:       # Ordered list of quality checks

data — Input/Output Samples

data:
  - inputs:
      rgb: "/path/to/input.mp4"          # Required: source video or image
      controls:                           # Optional: control modality inputs (video_transfer)
        edge: "/path/to/edge.mp4"
        depth: "/path/to/depth.mp4"
        seg: "/path/to/seg.mp4"
        vis: "/path/to/vis.mp4"
        wsm: "/path/to/wsm.mp4"           # Cosmos3 world-scenario control
      prompt_attributes:                  # Required only for VLM+template captioning
        event_type: "person_falling"
        motion_level: "natural"
        aftermath: "affected_entity_remains_visible"
    output:
      video: "/path/to/output.mp4"        # Required: generated output (a .jpg for image edit)
      caption: "/path/to/prompt.txt"       # Required: generated prompt text
      metadata: "/path/to/metadata.json"   # Required: run metadata
      evaluation: "/path/to/eval.json"     # Optional: evaluation results

For Cosmos3 WSM transfer, data[].inputs.controls.wsm is a client-readable video path. The openai.video.sync and openai.video.async adapters upload its bytes as control_reference and send control_type=wsm; the generation server creates the request-scoped control_path. Do not also set control or control_path under augmentation.parameters.extra_params.wsm. Other WSM options, such as control_weight, may remain in that object. The async adapter accepts one WSM control only on a video_transfer endpoint and rejects other control combinations.

endpoints — API Endpoint Registry (a LIST)

endpoints: is a list of endpoint entries (the BYOM registry). Each entry declares a role and, optionally, the API-contract adapter. The pipeline resolves the model and each captioning/evaluator consumer to an endpoint by role (and id when present).

endpoints:
  - id: vlm_qwen                 # optional exact selector; required to disambiguate 2+ same-role endpoints
    role: vlm
    url: "http://localhost:8000/v1"
    model: "Qwen/Qwen3.6-27B-FP8"
    # adapter omitted -> role default (openai.chat.completions)
  - id: llm_qwen
    role: llm
    url: "http://localhost:8002/v1"
    model: "Qwen/Qwen2.5-14B-Instruct"
  - id: cosmos_transfer
    role: video_transfer
    url: "http://10.63.146.234:8000"        # CT2.5 NIM, POST /v1/infer
    model: ""                                # single-model NIM — leave empty
    adapter: nim                             # role default is also nim
    timeout: 600

Endpoint fields: role (required), url (required), model (wire model string, default ""), id (optional handle), adapter (optional → role default), api_key_env (name of the env var holding the key — keys are never stored literally in the config), timeout (seconds).

For hosted NVCF NIM endpoints, timeout is the total budget for the invocation and any status polling, so set it above the expected queue plus generation time. The NIM adapter sends NVCF-POLL-SECONDS and follows an HTTP 202 NVCF-REQID through the authenticated NVCF status endpoint. Set NVCF_POLL_SECONDS to choose each long-poll window (default 300 seconds; larger values are capped at the NVCF gateway maximum of 300). This does not replace endpoint timeout, which remains the total invocation budget.

Roles → default adapter: vlm→openai.chat.completions, llm→openai.chat.completions, image_edit→nim, video_transfer→nim, video_predict→nim, image2video→openai.video.sync. The evaluator role has no default: an external Cosmos Evaluator endpoint must explicitly set adapter: cosmos.evaluator.arbitrator.

Adapters (API contracts): generation/captioning uses openai.chat.completions, openai.images.edits, openai.video.sync, openai.video.async, nim, or passthrough. cosmos.evaluator.arbitrator is an evaluator-only contract and intentionally does not enter the generation adapter registry.

Model selection: augmentation.model.name resolves to an endpoint by id, then by role, then by the model-name→role map (image-edit→image_edit, cosmos-transfer2.5→video_transfer, cosmos-predict→video_predict, cosmos3-image2video→image2video). If two endpoints share the matched role, disambiguate by setting augmentation.model.name to a specific endpoint id.

Cross-section validation enforces: captioning with VLM requires a vlm-role endpoint; captioning with LLM requires an llm-role endpoint (unless using text/file captioner); VLM+template samples must select defined catalog IDs; the generation model name must resolve to exactly one endpoint, and that endpoint's effective adapter must be a known contract. An enabled external Cosmos evaluator must select an endpoint by endpoint_id whose role is evaluator and whose explicit adapter is cosmos.evaluator.arbitrator.

pipeline — Pipeline Settings

pipeline:
  retry: 1                           # Max retries on evaluation failure (default: 1, keep low to save time)
  regenerate_caption_on_retry: true  # On evaluator failure, bump seed and rerun captioning before retrying generation
  logging:
    enabled: true
    level: "INFO"                     # DEBUG, INFO, WARNING, ERROR
  evaluation:
    strict: true                      # Fail sample on any evaluator failure
    retain_failures: true             # Keep output files on failure

captioning — Captioning Strategies

Captioner type is inferred from which sub-sections and fields are present (no explicit type field):

Config PatternCaptionerDescription
llm.text setTextCaptionerFixed prompt with {variable} substitution
llm.file_path setFileCaptionerSample prompts from a text file
Both vlm + templateTemplateCaptionerVLM describes media, fixed template assembles prompt
Both vlm + llmVLMLLMCaptionerVLM describes media, LLM generates prompt
Only vlmVLMCaptionerVLM-only description
Only llm (with variables)LLMCaptionerLLM generates prompt from variables

Invalid combinations: vlm + llm.text, vlm + llm.file_path, template without vlm, or template + llm will raise an error.

The vlm and llm captioning consumers resolve to the vlm-role and llm-role endpoints in the endpoints: list. For full per-strategy YAML examples and prompt-tuning guidance, read captioning-strategy-guide.md. A condensed VLM+LLM example:

captioning:
  vlm:
    parser: "instruct"              # "instruct" (user_prompt only) or "reasoning" (system + user)
    system_prompt: |
      You are a vision-language model describing scene content. Plain text only.
    user_prompt: |
      Describe this footage. Focus on weather, lighting, layout, objects, people.
      Do not suggest edits; describe only what is visible.
    parameters:
      temperature: 0.3
      top_p: 0.95
      max_tokens: 4096
      stream: false
      # fps / max_pixels are DEPRECATED no-ops: still accepted so existing configs
      # validate, but never sent. Declare the server's real knobs under extra_body.
      #
      # extra_body: vendor-specific request body, forwarded VERBATIM on VIDEO input
      # only. Unset (default) -> nothing extra is sent, which is what portable /
      # hosted VLMs want. Set it when your server needs its own knobs; there is no
      # model-name auto-detection. Qwen2.5-VL / NIM want:
      # extra_body:
      #   media_io_kwargs: {video: {fps: 4.0}}
      #   mm_processor_kwargs: {videos_kwargs: {min_pixels: 1568, max_pixels: 307200}}
      # Do NOT set these for Gemma — its processor rejects the request with a 400
      # ("Failed to apply Gemma4Processor ... kwargs={'videos_kwargs': ...}").
  llm:
    system_prompt: |
      You write one concise generation prompt from a scene caption plus attribute-value
      pairs. Output only a JSON object with a single key "prompt".
    example_prompt: |
      Change the scene to a rainy night with wet roads, preserving viewpoint and motion.
    parameters:
      temperature: 0.3
      max_tokens: 512
      stream: true
    variables:
      weather_condition: ["raining"]
      lighting_condition: ["night"]
VLM + deterministic template

This mode grounds the final prompt in the VLM description but does not invoke an LLM. The client defines allowed text once and each sample selects one ID from each of the three supported axes:

data:
  - inputs:
      rgb: "/workspace/data/warehouse_test.png"
      prompt_attributes:
        event_type: "person_falling"
        motion_level: "natural"
        aftermath: "affected_entity_remains_visible"
    output:
      video: "/workspace/data/out/warehouse_fall.mp4"
      caption: "/workspace/data/out/warehouse_fall_prompt.txt"
      metadata: "/workspace/data/out/warehouse_fall_metadata.json"

captioning:
  vlm:
    parser: "instruct"
    user_prompt: "Describe only visible scene facts; do not invent the requested event."
  template:
    template: |
      {scene_caption}
      Requested event: {event_type_text}
      Motion: {motion_level_text}
      Aftermath: {aftermath_text}
    attributes:
      event_type:
        person_falling: "The existing foreground worker loses balance and falls."
      motion_level:
        natural: "Use physically plausible motion with realistic timing."
      aftermath:
        affected_entity_remains_visible: "Keep the affected entity visible."

Every template placeholder is required exactly once, and every selected ID must exist in its catalog. See captioning-strategy-guide.md and config_image2video_cosmos3_vlm_template.yaml for the full warehouse example.

Text Captioning (fixed prompt with variable substitution)
captioning:
  llm:
    text: "change the person top outer color to {top_outer_color}, bottom type to {bottom_type}"
    variables:
      top_outer_color: ["blue"]
      bottom_type: ["jeans"]

Placeholders are validated at init time — a missing variable raises an error; unused/extra variables are logged as a warning (not fatal). No endpoint required.

File Captioning (sample from file)
captioning:
  llm:
    file_path: "/path/to/prompts.txt"   # One prompt per line
    seed: 42                            # Optional: reproducible selection

augmentation — Model & Generation

augmentation:
  model:
    name: "cosmos-transfer2.5"    # free-form string; resolves to an endpoint id/role
    version: "ct2.5"              # Optional version tag
  parameters:                     # pass-through (extra="allow"): only what you set is sent
    sigma: 90                     # Cosmos Transfer noise level
    seed: null                    # null = random per run
    guidance: 3.0
    num_steps: 35
  modalities:                     # Control modality weights (cosmos-transfer only)
    edge: 1.0
    depth: 0.4
    seg: 0.3
    vis: 0.05
    seg_control_prompt: "road surface, vehicles, sidewalks"
    positive_prompt: "cinematic, photorealistic, ultra high quality..."
    negative_prompt: "cartoon, pixelated, low quality..."

ModelConfig is just name (free-form string — not a closed enum) + optional version. There is no executor_type and no local_parameters — all inference is remote, dispatched by the endpoint's adapter. augmentation.parameters is a permissive pass-through surface: only explicitly-set knobs are forwarded to the endpoint (so a strict server is not handed defaults meant for another model), and numeric values for string-typed fields are coerced (e.g. resolution: 720 → "720"). seed is located wherever you place it (top-level or inside an envelope such as extra_params/extra_body) and re-rolled on retry. Model-native knobs not listed in the schema are accepted and forwarded as-is.

Per-model parameter highlights (all optional, pass-through):

  • Cosmos Transfer 2.5: sigma, guidance, num_steps, inference_name; control weights under modalities.

  • Cosmos3 WSM transfer: source video under data[].inputs.rgb, WSM video under data[].inputs.controls.wsm, and WSM tuning such as extra_params.wsm.control_weight plus extra_params.control_guidance. Use a video_transfer endpoint with openai.video.sync or openai.video.async; for async, the endpoint URL is the create route ending in /v1/videos.

  • Cosmos Predict 2.5: inference_type (text2world/image2world/video2world), num_output_frames, enable_autoregressive, chunk_size, chunk_overlap, resolution, offload_tokenizer, offload_text_encoder.

  • image edit: the nim /v1/infer contract uses its own native knob names — steps (5–100) and cfg_scale (>1.0, default 4.0), plus negative_prompt/seed; the openai.chat.completions and openai.images.edits contracts instead use num_inference_steps, guidance_scale, negative_prompt (often nested under an extra_body: envelope the server expects).

  • image-to-video: model-native knobs pass through verbatim (Cosmos3: size/num_frames/fps/num_inference_steps/guidance_scale/flow_shift/extra_params; Veo: seconds/size).

data_processing — Post-Processors

Optional processors, keyed by sub-key (presence enables it — no enabled flag). Timing depends on the processor: preprocessing.resize runs before generation (it resizes the input), while alignment and transcode run after generation. Post-processors mutate the file at data.output.video and write their parameters into data.output.metadata under the same sub-key.

Sub-keyPurpose
preprocessing.resizeAspect-ratio-preserving resize of the input before generation (target_megapixels, grid, interp); used to match an image-edit server's internal normalization for aligned output.
alignment5-DOF affine MI-registration warping the generated image back into the input's frame; required for Defect Image Generation where the model upscales (e.g. 158×114 → 1216×864). GPU-only (cupy).
transcodeNormalizes the generated video to one codec (VP9) so the output format doesn't vary with the model that produced it (Cosmos Transfer NIM emits VP9, vLLM-omni emits H.264). Knobs: codec (only vp9), crf (0–63, default 31), speed (0–8 -cpu-used, default 4), pix_fmt (default yuv420p), force (re-encode even if already VP9). Skips image outputs and skips a source already in the target codec (no generation loss).

transcode and GPUs: re-encoding an H.264 source needs --gpus — the image ships only the hardware h264_cuvid decoder (software AVC decode is off for licensing). VP9 sources decode in software and need no GPU. If the re-encode can't run, the original output is kept, the run still succeeds, and the reason lands in metadata.transcode.error — check that field if a uniform codec is a hard requirement.

data_processing:
  preprocessing:
    resize:
      target_megapixels: 1.048576   # = 1024*1024 px
      grid: 32                       # snap dims to /32, aspect-ratio preserved
      interp: lanczos
  alignment:
    rot_range_deg: [-1.0, 1.0, 0.1] # rotation search [start, stop, step] in degrees
    shift_step:    1                # tx/ty grid step (px)
    bins:          64               # MI histogram bins
    interp:        bilinear         # nearest | bilinear warp kernel
    no_resize:     true             # skip pre-resize of align→ref
    min_mi:        null             # null = no MI floor; else abort threshold
  transcode:
    codec: vp9                      # only supported target
    crf: 31                         # 0-63, lower = better quality
    speed: 4                        # libvpx-vp9 -cpu-used (0-8)
    force: false                    # re-encode even when already VP9

Do NOT set sx_range, sy_range, shift_range, or pyr_levels when authoring an alignment config — they are auto-derived in run_alignment from the generated and reference image dimensions. The schema exposes them only as escape-hatch overrides for visibly failing alignment runs. Derivation rules and override criteria are in the Post-Processing: Data-Processing Alignment section of the config decision tree reference.

evaluators — Quality Checks

Evaluators run after generation. On a quality failure, the pipeline retries with an incremented seed according to pipeline.retry. Three executable entry shapes are accepted: hallucination_check, attribute_verification, and cosmos_evaluator. The first two are built in; external Cosmos evaluation delegates checker execution to Arbitrator. VLM verification is the visual half of attribute_verification and therefore runs only as its nested vlm_verification block.

evaluators:
  - hallucination_check:
      enabled: true
      threshold: 0.682           # Optical flow similarity threshold
      params:
        grad_thresh: 10.0
        blur_ksize: 7
        morph_k: 3
        dist_tol_px: 7.0
  - attribute_verification:
      enabled: true
      generate_natural_caption_on_pass: true
      exclude_variables: []       # variables to skip in the MCQ gate
      extra_questions:            # Additional fixed MCQ checks
        - variable: "multi_view_consistency"
          question: "Is the appearance consistent across all views?"
          options: {A: "Yes, consistent", B: "No, inconsistent"}
          correct_answer: "A"
          request_reasoning: true
      question_generation:
        endpoint_id: llm_qwen     # optional; defaults to the single llm-role endpoint
        generate_options: true    # let the LLM invent distractors (correct answer stays pinned)
        system_prompt: "..."
        parameters: {temperature: 0.2, max_tokens: 2048}
      vlm_verification:           # VLM prompt + params used to answer the MCQs
        endpoint_id: vlm_qwen     # optional; defaults to the single vlm-role endpoint
        frames: 6                 # frames sampled from a video (1 = first frame only)
        system_prompt: "..."
        parameters: {temperature: 0.0, max_tokens: 10}

question_generation.endpoint_id / vlm_verification.endpoint_id pick a specific endpoint by id (otherwise the single endpoint of the matching role is used). generate_options lets the LLM write distractors instead of drawing from verification_options. frames controls how many evenly-spaced video frames the VLM verifier sees — use >1 so a mid-video event is visible (the first frame of an image→video clip is the pre-event seed). A top-level vlm_verification: entry is rejected during validation because it supplies no questions or expected answers; put it inside attribute_verification.

External Cosmos Evaluator

External Cosmos evaluation is checker-agnostic. The endpoint is the Arbitrator, not an individual checker, and configured names are free-form strings validated at startup against both GET /checkers and GET /dependency-graph.

endpoints:
  - id: cosmos_evaluator
    role: evaluator
    url: "http://cosmos-evaluator-arbitrator:8000"
    adapter: cosmos.evaluator.arbitrator      # explicit; not a generation adapter
    timeout: 1800                             # total submit-and-poll budget

evaluators:
  - cosmos_evaluator:
      enabled: true
      endpoint_id: cosmos_evaluator
      poll_interval_seconds: 5
      stream_key: camera_front_wide_120fov   # optional; derived when omitted
      output_storage_prefix: "team/run-42/"  # required relative object-key prefix
      merge_captioning_selections: true
      checks:
        - name: metropolis.attribute_verification
          gate: true
          metadata_key: attribute_verification
        - name: future.checker
          gate: false                         # preserve result; do not reject output
      inputs:
        original_video_urls:                  # optional opaque Arbitrator input
          camera_front_wide_120fov: s3://bucket/original.mp4
      config:                                 # one shared dict sent to every check
        selected_variables: {weather: snowy}
        variable_options: {weather: [sunny, cloudy, rainy, snowy]}

Fields and behavior:

  • enabled: disabled entries make no network requests. At most one enabled Cosmos entry is allowed.

  • endpoint_id: required and must select the explicit evaluator endpoint.

  • checks: non-empty, with unique, non-blank names. gate: true requires a literal top-level boolean passed in that check's result. gate: false preserves an opaque result without using it for candidate acceptance.

  • metadata_key: optional root-level compatibility alias. It cannot collide with built-in evaluator metadata, the cosmos_evaluator provider block, or another alias.

  • inputs: deep-copied pass-through input fields such as original_video_urls, world_model_video_urls, and rds_hq_url. augmented_video_urls is reserved because runtime binds it to the generated candidate. Per-stream companion maps must contain the resolved stream key.

  • config: one shared opaque dictionary forwarded to every selected checker; per-checker configuration maps are not part of the Arbitrator contract.

  • merge_captioning_selections: when true, runtime selected_variables and variable_options are merged by key into the copied shared config. Runtime values win for sampled keys; configured extra keys remain. The loaded YAML is not mutated. When false, captioning selections are not merged.

  • poll_interval_seconds: positive delay between execution snapshots.

  • output_storage_prefix: required for enabled entries. It is a relative object-storage key prefix, not an s3:// URI. Surrounding whitespace is stripped; a trailing slash is preserved. It must have no scheme, authority, query, fragment, leading slash, backslash, ASCII control character, empty path segment, . segment, or .. segment. One final empty segment from an optional trailing slash is allowed. Supply a concrete prefix unique to every live run.

When stream_key is present, surrounding whitespace is stripped and the remaining non-empty value is used unchanged. Otherwise runtime derives it from data[].output.video exactly once:

  1. Parse the URI and remove its query and fragment.

  2. Take the final non-empty POSIX path component, percent-decode it, and remove only its final filename suffix.

  3. Normalize the stem with Unicode NFKC.

  4. Replace each maximal run outside [A-Za-z0-9._-] with _, then strip leading/trailing ., _, and -.

  5. If nothing remains, use stream-<digest>, where <digest> is the first 12 lowercase hexadecimal characters of SHA-256 over the UTF-8, query-free and fragment-free candidate URI.

Examples: s3://bucket/run/candidate.mp4 becomes candidate; and https://host/run/My%20Clip.final.mp4?token=secret#frame becomes My_Clip.final. The same resolved key is reused for request inputs, result lookup, and provider metadata.

The generated candidate and configured media inputs must be remotely readable by the checker deployment (s3://, msc://, gs://, az://, or HTTP). Augmentation does not upload local files solely for evaluation. Results may be nested by stream under checker_results[checker_name][stream_key] or stored directly at checker_results[checker_name]; other checker-specific fields stay opaque. Quality failures may spend pipeline.retry; at most pipeline.retry + 1 candidates are generated. HTTP, discovery, polling, execution, missing/skipped-result, or gating-contract failures are service failures and do not generate another candidate. An ambiguous POST is surfaced as a redacted service failure with error_code: ambiguous_post and a machine-readable request_id field (null when no usable ID was received). It is never automatically resubmitted; use the operator recovery procedure in the evaluator setup guide. Clear failures use error_code: service_failure. pipeline.evaluation.strict and retain_failures remain authoritative after evaluation.

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 or NVIDIA.

Download ZIP

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