Skip to content

fix(inference): name the cause in Transfer rejection messages - #335

Merged
lfengad merged 1 commit into
NVIDIA:mainfrom
rwagwani:fix/transfer-error-messages
Oct 31, 2026
Merged

lfengad merged 1 commit into
NVIDIA:mainfrom
rwagwani:fix/transfer-error-messages

Conversation

@rwagwani

Copy link
Copy Markdown
Collaborator

Summary

Three Transfer rejections are correct but don't say what the request did wrong. This PR makes each message name the cause. Only message text changes: every request that runs today still runs, and every request that is rejected today is still rejected.

Found while validating every parameter of Cosmos3-Nano-Sim-Transfer (checkpoint 23b77384) on AV and Robotics inputs.

Changes

  1. Direct causal Transfer check. Today it lists all four rules, whichever one was broken:
    Direct causal Transfer requires exactly one control hint, num_first_chunk_conditional_frames=0, control_guidance=1.0, and share_vision_temporal_positions=true
    It now names only the rules this request breaks, with the values passed:
    Direct causal Transfer (transfer_resize_mode='direct_resize' on a causal checkpoint) cannot run this request:
      - control_guidance=1.5 (must be 1.0: the causal sampler has no control-guidance pass)
    
  2. Resolution on the 480-only SF-DMD checkpoint. 256, 704 and 768 were told "the teacher's trained 480 and 720 tiers only". A user then tried 720 and only then learned "supports only resolution='480'". The direct-resize check now raises the checkpoint's own limit. It identifies the checkpoint with the same predicate the resolution contract already uses (_is_sf_dmd_transfer_model, factored out of _apply_sf_dmd_transfer_inference_contract). Both messages now include the rejected value: This SF-DMD Transfer checkpoint supports only resolution='480', got resolution='768'. Other models keep the existing "480 and 720 tiers" message.
  3. aspect_ratio with direct_resize. Unsupported Transfer sample: 1280x720 -> 544x736 causes 140.52% aspect distortion, exceeding 3% does not mention that the user's own aspect_ratio caused it. The message now names it and says direct_resize does not crop. It also names the bucket automatic selection would pick, if one fits within 3%.
  4. Cookbook multi_control.json. It stated fps: 30, num_frames: 121 for a 16 fps, 93-frame video (robot_pouring.mp4). For a video input, Cosmos Framework takes both from the video, so the spec now states the real values and its output does not change: on GPU, the old and new spec give 16 fps / 93 frames and the same video, within same-seed run-to-run noise. The Diffusers notebook does not use this spec. The README field reference and table now say fps / num_frames should match the video.

Verification

  • Updated tests: transfer_direct_resize_test.py (the culprit messages), transfer_preprocessing_test.py (the aspect messages).
  • New tests in sim_transfer_args_test.py: the 480-only message for every rejected tier, and the teacher-tier message kept on a bidirectional model that records 480.
  • New transfer_cookbook_specs_test.py: each cookbook spec's fps / num_frames matches its video. It runs where the Git LFS videos are checked out and skips otherwise (CI's unit-test checkout does not fetch LFS).
  • All new tests are marked L0.
  • Touched test files plus transfer_test.py and inference_test.py: 315 passed, 1 skipped (the spec that downloads its input).
  • pre-commit (both configs) and ruff are clean.

A follow-up PR (stacked on this one) adds run-time warnings for transfer settings that cannot take effect.

🤖 Generated with Claude Code

Three Transfer rejections were correct but did not say what the request
did wrong:

- The direct causal Transfer check listed all four rules ("exactly one
  control hint, num_first_chunk_conditional_frames=0,
  control_guidance=1.0, and share_vision_temporal_positions=true"). It
  now names only the rules this request breaks, with the values passed.
- On the 480-only SF-DMD checkpoint, 256/704/768 were told "480 and 720
  tiers only", so a user tried 720 and only then learned "480 only".
  The direct-resize check now raises the checkpoint's own limit, using
  the same predicate as its resolution contract, and both messages
  include the rejected value.
- The direct_resize aspect error ("causes N% aspect distortion") did
  not mention a forced aspect_ratio. It now names it, says direct_resize
  does not crop, and names the bucket that would fit, if any.

The Transfer cookbook's multi_control.json stated fps 30 / num_frames
121 for a 16 fps, 93-frame video. Neither value is read for a video
input, so the spec now states the real values without changing its
output, and the README field reference says fps/num_frames should match
the video.

Signed-off-by: rwagwani <rwagwani@nvidia.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@rwagwani
rwagwani force-pushed the fix/transfer-error-messages branch from 7e7f1ad to bc48e94 Compare October 30, 2026 06:55
@yaoxu-crypto yaoxu-crypto added the Skill New skill or updating existing skill label Oct 30, 2026

@lfengad lfengad left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Static review of bc48e94: the accepted/rejected request conditions are preserved while the error messages identify the actual cause; the cookbook timing values are aligned with the input video. I found no blocking issue in this pass. Existing checks on this head have passed. The changed paths are outside the current I4 mapping. Approving the code review; merge still needs the remaining required approval and an up-to-date branch under the normal main protection rules. No tests were run locally for this review.

@lfengad
lfengad merged commit 55f0554 into NVIDIA:main Oct 31, 2026
20 checks passed
lfengad pushed a commit that referenced this pull request Nov 2, 2026
Stacked on #335 (rejection messages and the cookbook spec fix). This
PR's own change is the last commit.

## Summary

Several transfer settings are accepted without any message in setups
where the code never reads them, so users change them and get an
unchanged video. Found while validating every parameter of
Cosmos3-Nano-Sim-Transfer (checkpoint 23b77384) and Cosmos3-Nano on AV
and Robotics inputs. Most of these limits are already in the docs; this
PR makes the code say them at run time. It changes no generated video,
and every shipped cookbook spec and Sim-Transfer skill request builds
exactly as before, with no new warnings.

## Warnings (no output change)

- A single-control `weight`: weights are normalised by their sum, and
the causal Sim-Transfer path hard-codes 1.0.
- Single-view distilled causal Transfer: a table
(`_DISTILLED_TRANSFER_IGNORED_FIELDS`) of fields the fixed-step sampler
never reads (negative prompt, guidance, sigma_max, shift, normalize_cfg,
num_conditional_frames, both guidance windows). It warns only when the
sample or CLI sets a non-neutral value, not for values from a defaults
file. Also a chunk size unlike `num_frames`, and `model_mode` other than
`video2video`.
- `--sampler` other than unipc on any fixed-step checkpoint (checked
once at model load).
- A reversed `guidance_interval` / `control_guidance_interval` (`lo >=
hi`), only where that guidance pass would otherwise run.
- Single-view Transfer: a requested `fps` or `num_frames` that differs
from what the source video gives. This is checked in
`generate_transfer_sample` (and the streaming path), against the length
and frame rate generation actually resolves, so there is no second copy
of that logic. Also `prompt_upsampling=True`, and both `negative_prompt`
and `negative_prompt_file` set explicitly.

## Error

- Bidirectional single-view path: negative or all-zero control weights
raise `ValueError` when the sample is built, instead of a bare `assert`
inside `build_transfer_batch`. The causal path and joint camera+LiDAR
transfer do not read these weights, so they are left alone.

## Behaviour changes, stated plainly

- The only new error is the control-weight `ValueError` above. Those
requests already failed, later, with a bare `AssertionError` after model
load.
- A built `OmniSampleArgs` now records which fields the request set (a
pydantic private attribute, `requested_fields`, not serialized), so
generation can tell a request from a default. Pydantic includes private
attributes in `==`, so `test_sample_args` compares `model_dump()`. No
production code compares samples with `==`.

## Not changed here (follow-up)

On normal Nano/Super, the built-in video2video defaults always supply a
`negative_prompt`, so a request-level `negative_prompt_file` is never
read, and a missing path is accepted. The cookbook specs set
`../assets/negative_prompt.json`, whose caption differs slightly from
`defaults/neg_prompts.json`. Fixing this changes cookbook output
(precedence, and resolving the path relative to the spec), so it should
be its own PR.

## Verification

- New L0 tests (`transfer_shipped_specs_test.py`, plus additions to
existing files). They build all six cookbook specs and the six official
Sim-Transfer skill requests (written by `prepare_hf_sample.py`, run with
the skill's defaults file and CLI flags) through `from_files` +
`build_sample`, and assert no errors and no `[transfer]` warnings. They
do not need the Git LFS videos, so they run in CI. A separate
spec-vs-video check (fps/num_frames match the asset) runs only where the
LFS videos are checked out.
- Touched test files: 384 passed, 1 skipped.
- The CI unit-test job (`-m L0`, same command as `gpu-tests.yml`),
replicated on a single GB300: running; I will add the result here.
- GPU, Cosmos3-Nano-Sim-Transfer with the skill command (official
example2 depth and edge requests) and Cosmos3-Nano with the cookbook
depth spec: no new warnings, and the same videos as main within
same-seed run-to-run noise. A deliberately mis-set Sim-Transfer request
(`depth.weight=5`, `sigma_max=200`, `fps=10` on a 30 fps video) prints
exactly those three warnings and produces the same video as on main.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Signed-off-by: rwagwani <rwagwani@nvidia.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Skill New skill or updating existing skill

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants