Repository navigation
[https://nvbugs/6418815][fix] Revert the per-batch cross-attention slicing (drop real_text_lens plumbing in… #15986
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
7e91edf
e375611
621a39a
ea9380f
5ac5bba
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -3,6 +3,8 @@ | |
| "model": "Cosmos3-Nano", | ||
| "source": "TensorRT-LLM VisualGen", | ||
| "prompt": "A serene mountain landscape with snow-capped peaks and a flowing river", | ||
| "negative_prompt": "pinned pre-audio descriptive default (COSMOS3_LPIPS_NEGATIVE_PROMPT)", | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Every other golden stores the literal negative prompt ( |
||
| "max_sequence_length": 1024, | ||
| "height": 720, | ||
| "width": 1280, | ||
| "num_frames": 1, | ||
|
|
@@ -15,7 +17,18 @@ | |
| "lpips_net": "alex", | ||
| "lpips_threshold": 0.05, | ||
| "diffusers_version": "0.38.0", | ||
| "tensorrt_llm_version": "1.3.0rc20", | ||
| "tensorrt_llm_commit": "85665f5fd331d0154a78172954846d843085e83f", | ||
| "container_image": "urm.nvidia.com/sw-tensorrt-docker/tensorrt-llm-staging/release@sha256:3308a2dc0192a8329ea02eca7b5c44f290f5e894cd8c5921099308d84c3e5691" | ||
| "tensorrt_llm_version": "1.3.0rc24", | ||
| "tensorrt_llm_commit": "1745a6e689082e32e113fe06460ee5c3dfecbba9", | ||
| "container_image": "urm.nvidia.com/sw-tensorrt-docker/tensorrt-llm:pytorch-26.05-py3-x86_64-ubuntu24.04-skip-tritondevel-202607271403-16694-handongl", | ||
| "rebake_reason": [ | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
| "Refreshed for https://nvbugs/6418815. The prior golden (commit", | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [MINOR] PR title/description contradict the actual change The title says 'Revert the per-batch cross-attention slicing (drop real_text_lens plumbing in transformer_cosmos3.py)', but transformer_cosmos3.py is untouched and this rebake_reason correctly argues real_text_lens is the correct behavior and must NOT be reverted. The real fix is golden rebake + input pinning. Update the PR description to match, since a future reader (and git archaeology on this golden) will rely on it to understand why the golden moved. |
||
| "85665f5fd331d0154a78172954846d843085e83f) predates the Cosmos3 audio-output", | ||
| "feature (f50ca53dae) and so encodes the pre-feature cross-attention numerics:", | ||
| "before that feature, cross-attention padded every CFG sample to the batch-wide", | ||
| "max text length and attended over the padding. f50ca53dae added per-sample", | ||
| "text slicing (real_text_lens), which is the correct behavior and which the", | ||
| "V2V golden (baked after it) depends on, so it must not be reverted. This", | ||
| "golden was regenerated with real_text_lens in force; the run is bit-exact", | ||
| "reproducible (verified across two independent runs on the same host)." | ||
| ] | ||
|
coderabbitai[bot] marked this conversation as resolved.
|
||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -49,6 +49,22 @@ | |
| # Cosmos3 requires VANILLA attention and guardrails disabled in CI. | ||
| COSMOS3_NANO_MODEL_SUBPATH = "Cosmos3-Nano" | ||
| COSMOS3_LPIPS_PROMPT = "A serene mountain landscape with snow-capped peaks and a flowing river" | ||
| # The T2I/T2V goldens were baked before the Cosmos3 audio-output feature | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This rationale is stale relative to the golden added in the same PR. It says the T2I golden "was baked before the Cosmos3 audio-output feature", but Also worth noting in the comment: with per-sample slicing active, |
||
| # (f50ca53dae) changed two conditioning defaults: the descriptive negative | ||
| # prompt became "" and max_sequence_length went 1024 -> 4096. Pin the original | ||
| # values for those two tests so they stay decoupled from future public-default | ||
| # changes (matching the WAN21/22, LTX2, QwenImage pattern). The V2V golden was | ||
| # baked after that feature landed, so it deliberately keeps the live defaults. | ||
| COSMOS3_LPIPS_NEGATIVE_PROMPT = ( | ||
| "The video captures a series of frames showing ugly scenes, static with no motion, " | ||
| "motion blur, over-saturation, shaky footage, low resolution, grainy texture, " | ||
| "pixelated images, poorly lit areas, underexposed and overexposed scenes, poor " | ||
| "color balance, washed out colors, choppy sequences, jerky movements, low frame " | ||
| "rate, artifacting, color banding, unnatural transitions, outdated special effects, " | ||
| "fake elements, unconvincing visuals, poorly edited content, jump cuts, visual " | ||
| "noise, and flickering. Overall, the video is of poor quality." | ||
| ) | ||
| COSMOS3_LPIPS_MAX_SEQUENCE_LENGTH = 1024 | ||
| COSMOS3_LPIPS_HEIGHT = 720 | ||
| COSMOS3_LPIPS_WIDTH = 1280 | ||
| COSMOS3_LPIPS_T2V_NUM_FRAMES = 189 | ||
|
|
@@ -128,13 +144,22 @@ def _build_cosmos3_accuracy_cases(): | |
| COSMOS3_ACCURACY_CASES = _build_cosmos3_accuracy_cases() | ||
|
|
||
|
|
||
| def _run_cosmos3_lpips_pipeline(num_frames, video=None): | ||
| def _run_cosmos3_lpips_pipeline( | ||
| num_frames, video=None, negative_prompt="", max_sequence_length=None | ||
| ): | ||
| """Run the Cosmos3-Nano pipeline (default setting, VANILLA attn, compile-off). | ||
|
|
||
| Returns the generated video tensor ``(B, T, H, W, C)`` (T == ``num_frames``), | ||
| or ``None`` if generation produced no video. ``num_frames=1`` yields the | ||
| single-frame text-to-image path; passing ``video`` (encoded MP4 bytes, | ||
| decoded on the worker's NVDEC) yields the video-to-video path. | ||
|
|
||
| ``negative_prompt`` defaults to ``""`` because the goldens were generated | ||
| against an empty uncond branch; leaving it unset would inherit the | ||
| video-mode default instead. ``max_sequence_length`` defaults to ``None``, | ||
| which leaves the pipeline's own default in force. Callers whose golden | ||
| predates the audio-output feature pass the pinned pre-audio values | ||
| explicitly. | ||
| """ | ||
| # Cosmos3 re-reads the guardrail flag in __init__; set it before the pipeline loads. | ||
| guardrails_env_key = "TRTLLM_DISABLE_COSMOS3_GUARDRAILS" | ||
|
|
@@ -163,15 +188,14 @@ def _run_cosmos3_lpips_pipeline(num_frames, video=None): | |
| with torch.no_grad(): | ||
| result = pipeline.forward( | ||
| prompt=COSMOS3_LPIPS_PROMPT, | ||
| # The goldens were generated against an empty uncond branch, | ||
| # so pin it rather than inheriting the video-mode default. | ||
| negative_prompt="", | ||
| negative_prompt=negative_prompt, | ||
| seed=COSMOS3_LPIPS_SEED, | ||
| height=COSMOS3_LPIPS_HEIGHT, | ||
| width=COSMOS3_LPIPS_WIDTH, | ||
| num_frames=num_frames, | ||
| num_inference_steps=COSMOS3_LPIPS_NUM_INFERENCE_STEPS, | ||
| guidance_scale=COSMOS3_LPIPS_GUIDANCE_SCALE, | ||
| max_sequence_length=max_sequence_length, | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [MAJOR] max_sequence_length=None is now always forwarded to pipeline.forward Previously extra = {} if max_sequence_length is None else {"max_sequence_length": max_sequence_length}
result = pipeline.forward(..., **extra) |
||
| frame_rate=COSMOS3_LPIPS_FRAME_RATE, | ||
| use_guardrails=False, | ||
| video=video, | ||
|
|
@@ -191,7 +215,11 @@ def _run_cosmos3_lpips_pipeline(num_frames, video=None): | |
|
|
||
| def _generate_cosmos3_lpips_video(output_path): | ||
| """Generate the Cosmos3-Nano text-to-video LPIPS sample.""" | ||
| video = _run_cosmos3_lpips_pipeline(COSMOS3_LPIPS_T2V_NUM_FRAMES) | ||
| video = _run_cosmos3_lpips_pipeline( | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This changes the T2V generation inputs, but T2V is waived under a separate bug, so this isn't gating, but it leaves a test in a state where nobody can tell from the golden what inputs it expects. Either rebake T2V here (and record the pins in its JSON), or leave T2V on pipeline defaults and scope this PR to T2I. |
||
| COSMOS3_LPIPS_T2V_NUM_FRAMES, | ||
| negative_prompt=COSMOS3_LPIPS_NEGATIVE_PROMPT, | ||
| max_sequence_length=COSMOS3_LPIPS_MAX_SEQUENCE_LENGTH, | ||
| ) | ||
| assert video is not None, "Cosmos3-Nano T2V LPIPS run produced no video" | ||
| _save_lpips_video_mp4(video, output_path, frame_rate=COSMOS3_LPIPS_FRAME_RATE) | ||
|
|
||
|
|
@@ -228,7 +256,11 @@ def _generate_cosmos3_lpips_image(output_path): | |
| """Generate the Cosmos3-Nano text-to-image LPIPS sample (single frame).""" | ||
| from tensorrt_llm.media.encoding import save_image | ||
|
|
||
| video = _run_cosmos3_lpips_pipeline(COSMOS3_LPIPS_T2I_NUM_FRAMES) | ||
| video = _run_cosmos3_lpips_pipeline( | ||
| COSMOS3_LPIPS_T2I_NUM_FRAMES, | ||
| negative_prompt=COSMOS3_LPIPS_NEGATIVE_PROMPT, | ||
| max_sequence_length=COSMOS3_LPIPS_MAX_SEQUENCE_LENGTH, | ||
| ) | ||
| assert video is not None, "Cosmos3-Nano T2I LPIPS run produced no frame" | ||
| # video is (B, T, H, W, C); take the single frame -> (H, W, C) for save_image. | ||
| save_image(video[0, 0], output_path) | ||
|
|
@@ -368,7 +400,10 @@ def test_cosmos3_nano_v2v_lpips_against_golden(_visual_gen_deps, tmp_path): | |
|
|
||
|
|
||
| @pytest.mark.skipif(not torch.cuda.is_available(), reason="CUDA not available") | ||
| def test_cosmos3_nano_t2i_lpips_against_golden(_visual_gen_deps, tmp_path): | ||
| def test_cosmos3_nano_t2i_lpips_against_golden(request, tmp_path): | ||
| # No _visual_gen_deps: this case is single-frame throughout (PIL save_image | ||
| # plus the eval script's image branch), so it needs none of that fixture's | ||
| # video codecs -- matching test_cosmos3_feature_accuracy_against_golden. | ||
| generated_path = tmp_path / "cosmos3_nano_t2i_generated.png" | ||
| golden_path = _golden_media_path( | ||
| tmp_path, "cosmos3_nano_t2i_lpips_golden.png", "Cosmos3-Nano T2I LPIPS golden image" | ||
|
|
@@ -382,6 +417,13 @@ def test_cosmos3_nano_t2i_lpips_against_golden(_visual_gen_deps, tmp_path): | |
| golden_path, | ||
| generated_path, | ||
| ) | ||
| _preserve_lpips_candidate_on_failure( | ||
| request, | ||
| score, | ||
| COSMOS3_LPIPS_THRESHOLD, | ||
| generated_path, | ||
| "cosmos3_nano_t2i_lpips_golden.png", | ||
| ) | ||
| _assert_lpips_below_threshold(score, COSMOS3_LPIPS_THRESHOLD) | ||
|
|
||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[MINOR] Unrelated lazy-import change; verify GroupedGemmInputsHelper is not also guarded
This MoE import refactor is unrelated to the visual-gen bug this PR claims to fix and carries no test. The four Sm100 runners are moved into
runner_tactic_comb_checker(lines 331-335) because they live insidecute_dsl_custom_ops'if IS_CUTLASS_DSL_AVAILABLE:block, butGroupedGemmInputsHelperis kept at module scope here. IfGroupedGemmInputsHelperis ALSO defined inside that same guard, then on a machine without the cutlass DSL this module-scope import still raises at import time — and since create_moe imports this file eagerly, it breaks all model startup, defeating the entire fix. ConfirmGroupedGemmInputsHelperis defined outside the guard (or has an else-branch fallback); if not, move it into the same lazy import.