Skip to content

fix(inference): reject a missing negative_prompt_file and flag more Transfer settings that cannot take effect - #354

Open
rwagwani wants to merge 3 commits into
NVIDIA:mainfrom
rwagwani:fix/transfer-negative-file-and-metadata
Open

rwagwani wants to merge 3 commits into
NVIDIA:mainfrom
rwagwani:fix/transfer-negative-file-and-metadata

Conversation

@rwagwani

@rwagwani rwagwani commented Nov 3, 2026 •

Copy link
Copy Markdown
Collaborator

Follow-up to #338, covering the two items it listed as not covered, plus four more Transfer settings found while validating the blur and edge controls of Cosmos3-Nano-Sim-Transfer.

Summary

  • A missing negative_prompt_file is now rejected when the sample is parsed, before the model loads. Before, the file was read only when no negative_prompt was set; in almost every setup a default negative_prompt wins first, so a typo in the path was accepted with no message. Lookup order:

    1. the folder the run was launched from (where the file was read from before, so existing setups keep working);
    2. the spec file's folder (specs are validated inside a chdir to it; this is the cookbook's ../assets/negative_prompt.json layout);
    3. for a bare filename only, defaults/ (for example neg_prompts.json).

    A negative_prompt_file inside a --defaults-file is also tried next to that defaults file. A path that is not found fails with:

    negative_prompt_file not found: missing_negative.json (tried <launch>/missing_negative.json, <spec dir>/missing_negative.json, <package>/inference/defaults/missing_negative.json)
    
  • negative_metadata_mode and negative_prompt_keep_metadata warn on distilled causal Transfer. They are added to _DISTILLED_TRANSFER_IGNORED_FIELDS, with neutral values none and false, so a request that sets them gets the same [transfer] '<field>' is ignored by distilled causal Transfer: ... warning as the other fix(inference): warn when a transfer setting cannot take effect #338 fields. The distilled schedule has no negative-caption branch, so neither setting is read.

  • A preset next to a control_path now warns. load_transfer_control_frames uses a control_path as-is and computes the edge/blur control from vision_path only when there is no control_path, so blur.preset_blur_strength / edge.preset_edge_threshold are never read in that case. A non-default preset set by the request now logs [transfer] 'blur.preset_blur_strength'='very_high' is ignored: 'blur.control_path' is set, .... medium (the default, and the value in the shipped cookbook specs) stays silent.

  • show_input without vision_path now warns. There is no input video to put next to the output, so single-view Transfer writes the output alone with no message. A show_input=true set by the request, with every control coming from a control_path and no vision_path, now logs [transfer] 'show_input' has no effect without 'vision_path': ... (streaming Transfer already rejects this request).

  • num_conditional_frames >= the chunk size no longer stops the causal path. generate_transfer_sample called _get_num_chunks before branching, so num_conditional_frames=2 with num_video_frames_per_chunk=1 failed after model load with "num_conditional_frames must be smaller than num_video_frames_per_chunk", even though the causal path never reads either value and fix(inference): warn when a transfer setting cannot take effect #338 already reports both as ignored on distilled checkpoints. The chunk partition is now validated only on the chunked (bidirectional) path, which is unchanged.

  • resolution given as a number is accepted. "resolution": 480 in a JSON spec failed the Literal check (input_type=int); a before-validator on VisionDataOverrides.resolution turns an integer into its tier string. Values outside the tiers (1080, "4k") and booleans are still rejected as before.

Not changed

  • Which negative caption wins when both the defaults and the spec supply one. That changes cookbook output, so it stays a separate decision, as noted in fix(inference): warn when a transfer setting cannot take effect #338.
  • Generated output: no caption, sampler or generation path changes.
  • Resolution values outside the tiers still get the generic schema message, not the checkpoint's "supports only resolution='480'" message; that needs the check moved after the model config is known, which is a larger change.

Behaviour change, stated plainly

  • The only new error is a missing negative_prompt_file, and it lists every path it tried. Every shipped cookbook spec and Sim-Transfer skill request still builds; transfer_shipped_specs_test.py covers this.
  • The check runs whether or not the file would be read, including a path in a --defaults-file. A setup that carried an unused, broken path now fails, by design.
  • In a batch or jsonl run, a bad path now fails when the samples are loaded, like a bad vision_path, so --skip-invalid-samples does not skip it.
  • Requests with num_conditional_frames >= the chunk size on the causal path, and with resolution as an integer, used to fail and now run.
  • URLs were never read for this field, and they are now rejected with the same message instead of being accepted unused.
  • The stored sample args record the resolved absolute path.
  • negative_metadata_mode is checked against the value the request set, so none does not warn when negative_prompt_keep_metadata from the defaults promotes it to same.

Verification

  • New L0 CPU tests in sim_transfer_args_test.py:
    • a missing file is rejected on both the causal and the bidirectional path
    • a relative path still resolves from the launch folder first, then from the spec's folder (the cookbook layout)
    • a bare defaults/ filename is still accepted, but a path such as typo_dir/neg_prompts.json is not
    • the keep_metadata promotion does not produce a spurious negative_metadata_mode warning
    • negative_metadata_mode none / same / inverse and negative_prompt_keep_metadata false / true warn only for non-neutral values
  • Added for the four new items:
    • sim_transfer_args_test.py: the preset warns for a non-default value with control_path (blur and edge) and stays silent for medium, for no preset, and without control_path; show_input warns only when the request set it and there is no vision_path; integer 480/720 are accepted, 1080, "4k" and True are still rejected.
    • transfer_test.py: the causal path runs with num_conditional_frames 17 and 30 against a 17-frame chunk, for distilled and non-distilled checkpoints; _get_num_chunks still rejects it for the chunked path.
    • Each of these new tests fails without its change (7 failures) and passes with it.
  • test_unused_negative_prompt_file_is_not_opened now uses a file that exists, because a missing path is rejected earlier. It still checks that the file is not read when a default caption wins. A stale comment in transfer_shipped_specs_test.py is updated.
  • pytest cosmos_framework/inference/sim_transfer_args_test.py cosmos_framework/inference/transfer_shipped_specs_test.py cosmos_framework/inference/args_test.py: 159 passed.
  • pytest cosmos_framework/inference/ -m "not GPU": the same 7 failures as main (auto_rig_frontend_test x1, model_test x6), no new ones.
  • A spec launched from a folder holding neg.json, with the spec elsewhere, still resolves to the launch folder's file.
  • ruff check and ruff format --check: clean.
  • After adding the four items and rebasing onto main (d04e506): pytest -m CPU cosmos_framework/data cosmos_framework/inference: 1038 passed, 0 failed; sim_transfer_args_test.py, transfer_test.py, args_test.py, transfer_shipped_specs_test.py, transfer_direct_resize_test.py: 306 passed; pre-commit (base and full config): clean.
  • End to end on Cosmos3-Nano-Sim-Transfer (single GPU), with the same spec and the same command:
    • A spec with negative_prompt_file: "missing_negative.json" was accepted silently before. Now it stops before model load with the message above.
    • A spec with a valid negative_prompt_file still runs, with an unchanged result, and logs [transfer] 'negative_prompt_file' is ignored by distilled causal Transfer: the distilled schedule has no negative-caption branch.
    • A spec with negative_metadata_mode: "same" runs, with an unchanged result, and now logs [transfer] 'negative_metadata_mode' is ignored by distilled causal Transfer: the distilled schedule has no negative-caption branch to add metadata to.
    • The four new items, with the blur specs from the parameter sweep (AV clip):
      • the documented blur recipe runs with no new warning;
      • blur.control_path + preset_blur_strength: "very_high" runs and logs the new preset warning;
      • show_input: true with only a control_path runs and logs the new show_input warning;
      • num_conditional_frames: 2 with num_video_frames_per_chunk: 1 failed after model load before; it now runs and logs the two existing "is ignored by distilled causal Transfer" warnings;
      • "resolution": 480 (a number) failed the schema check before; it now runs at 480.

🤖 Generated with Claude Code

rwagwani and others added 3 commits November 4, 2026 13:59
…d negative-metadata settings

Follow-up to NVIDIA#338.

- negative_prompt_file is validated when the sample is parsed. A relative path
  resolves against the spec file's folder (as vision_path and prompt_path do), and a
  bare filename under defaults/ is still accepted. A path that does not exist now
  fails before model load, instead of passing silently whenever a default
  negative_prompt wins.
- negative_metadata_mode and negative_prompt_keep_metadata join the distilled
  causal Transfer ignored-fields table (neutral values: none / false).

No change to which negative caption is used, so cookbook and Sim-Transfer skill
outputs are unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ddress review

- Resolve a relative negative_prompt_file from the launch folder first (where it was
  read from before), then the spec's folder; a defaults-file entry is also tried next
  to that defaults file.
- Apply the defaults/ fallback to a bare filename only.
- Check negative_metadata_mode against the requested value, so a keep_metadata
  promotion of 'none' to 'same' does not warn.
- Update a stale comment in transfer_shipped_specs_test.py.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Found while validating the blur and edge controls of Cosmos3-Nano-Sim-Transfer:
- warn when an edge/blur preset other than the default is set next to a
  control_path, which is used as-is so the preset is never read;
- warn when show_input is set without vision_path (no input video to show);
- validate the chunk partition only on the chunked path, so the causal path no
  longer rejects num_conditional_frames >= num_video_frames_per_chunk, which it
  never reads;
- accept resolution given as an integer (480 -> "480").

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: root <root@pmgb300ws-0350.ipp9c1.colossus.nvidia.com>
@rwagwani
rwagwani force-pushed the fix/transfer-negative-file-and-metadata branch from 466ecdd to 9cfff2c Compare November 4, 2026 14:02
@rwagwani rwagwani changed the title fix(inference): reject a missing negative_prompt_file and flag ignored negative-metadata settings fix(inference): reject a missing negative_prompt_file and flag more Transfer settings that cannot take effect Nov 4, 2026

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant