Skip to content

[TRTLLM-11707][feat] Add CUDA graph support (torch compile compatible) for LTX-2#12653

Merged
luyiyun1021 merged 1 commit into
NVIDIA:mainfrom
luyiyun1021:feature/ltx2-cuda-graph
Apr 10, 2026
Merged

[TRTLLM-11707][feat] Add CUDA graph support (torch compile compatible) for LTX-2#12653
luyiyun1021 merged 1 commit into
NVIDIA:mainfrom
luyiyun1021:feature/ltx2-cuda-graph

Conversation

@luyiyun1021

@luyiyun1021 luyiyun1021 commented Apr 1, 2026

Copy link
Copy Markdown
Collaborator

@coderabbitai summary

Description

Add CUDA graph support for the LTX-2 diffusion transformer to reduce CPU dispatch overhead and eliminate inter-rank synchronization drift in multi-GPU Ulysses sequence parallelism.

Related PR: #12603 (alternative LTX-2 CUDA graph implementation)

Problem

In 8-GPU FP4 inference with Ulysses parallelism, each GPU processes 1/8 of the sequence. The resulting small kernels (~24us) are shorter than CPU dispatch interval (~35us), making kern/gap < 1. This exposes CPU jitter (~2us/launch) which accumulates into ~10-20ms rank drift per denoising step, degrading NCCL AllGather latency from 133us to 310us (2.3x).

Solution

Monolithic CUDA graph capture of the full LTXModel.forward(), including NCCL all-to-all collectives. This eliminates all per-kernel CPU dispatch gaps, reducing rank drift from ~10-20ms to ~0.02ms per step.

Key Changes

pipeline_ltx2.py_LTX2CUDAGraphRunner subclass of CUDAGraphRunner:

  • Handles Modality dataclass arguments (key derivation from nested tensor shapes, static buffer clone/copy)
  • BatchedPerturbationConfig fingerprinting ensures different STG configurations get separate graph captures
  • None-tolerant output refs for modality-isolated passes (video_vel, None) or (None, audio_vel)
  • Overrides _setup_cuda_graphs() to remove the torch.compile mutual exclusion — both work together

rope.py + transformer_args.py — GPU-side frequency grid cache:

  • _generate_freq_grid_np/pytorch() returns CPU tensors via lru_cache
  • Previously copied CPU→GPU every forward call (H2D transfer blocks graph capture)
  • Added freq_grid_cache parameter to precompute_freqs_cis(): first call does H2D and caches the GPU tensor; subsequent calls (including inside torch.cuda.graph()) reuse the cached tensor
  • Cache dict is owned by TransformerArgsPreprocessor instance (lifecycle tied to pipeline, not global)

visual_gen_ltx2.py — CLI support:

  • Added --enable_cudagraph argument for the example script

test_ltx2_transformer.py — CUDA graph correctness test:

  • TestLTX2CUDAGraphCapture: verifies graph capture + replay produces bitwise-identical output to eager forward in AudioVideo mode (the most complex path with video/audio self-attention, bidirectional AV cross-attention, text cross-attention, and RoPE)

How to Enable

# In YAML config:
cuda_graph:
  enable_cuda_graph: true

# Works with or without torch.compile:
torch_compile:
  enable_torch_compile: true   # optional, compatible

Or via CLI: python examples/visual_gen/visual_gen_ltx2.py --enable_cudagraph ...

torch.compile Compatibility

The previous implementation had torch.compile and CUDA graphs as mutually exclusive. This PR removes that restriction:

  • torch.compile operates at the block level (each of 48 transformer blocks compiled individually)
  • CUDA graph operates at the transformer.forward level (captures the entire forward including compiled blocks)
  • Graph capture happens during warmup, after torch.compile's lazy compilation is triggered by the CUDAGraphRunner's internal warmup iterations (WARMUP_STEPS=2), so the captured graph contains optimized compiled kernels

Performance Results

8-GPU B200 FP4, 768x1280x121 frames, Ulysses=8:

Per-step synced GPU time (with torch.cuda.synchronize(), steady-state step 20-40 of 40-step run):

Config Per-step Improvement
compile, no graph 204.2 ms baseline
compile + graph 200.2 ms -4.1ms (-2.0%)

Rank drift (from nsys analysis):

Config Rank spread per step
No graph ~10-20ms
CUDA graph ~0.02ms

The 4.1ms/step improvement comes from eliminating straggler CPU bubble and NCCL wait time. All 21 measured steady-state steps consistently showed improvement (-1.0 to -6.0ms).

Tests

  • TestLTX2CUDAGraphCapture::test_cuda_graph_audio_video_correctness — bitwise correctness for both capture and replay paths (AudioVideo mode)
  • All existing 12 tests in test_ltx2_transformer.py pass (no regression)

PR Checklist

  • PR description clearly explains what and why.

  • PR Follows TRT-LLM CODING GUIDELINES.

  • Test cases are provided for new code paths.

  • Any new dependencies have been scanned for license and vulnerabilities.

  • CODEOWNERS updated if ownership changes.

  • Documentation updated as needed.

  • Update tava architecture diagram if significant design change.

  • Please check this after reviewing the above items as appropriate for this PR.

GitHub Bot Help

To see a list of available CI bot commands, please comment /bot help.

@luyiyun1021
luyiyun1021 requested a review from a team as a code owner April 1, 2026 07:55
@coderabbitai

coderabbitai Bot commented Apr 1, 2026

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Walkthrough

Updates to the LTX2 model pipeline add caching for rope frequency computations, modify tensor handling in velocity calculations to preserve tensors during broadcasting, and introduce a CUDA graph runner subclass that manages cached graph capture and replay for the transformer with Modality tensor support.

Changes

Cohort / File(s) Summary
Frequency and Rope Optimization
tensorrt_llm/_torch/visual_gen/models/ltx2/ltx2_core/rope.py
Added device transfer defensiveness and GPU caching layer (_freq_grid_gpu_cache) to precompute_freqs_cis, reducing redundant device copies by caching precomputed indices keyed by generator parameters and target device.
Tensor Velocity Computation
tensorrt_llm/_torch/visual_gen/models/ltx2/ltx2_core/utils_ltx2.py
Modified to_velocity to preserve sigma as a tensor and apply broadcasting via unsqueezing trailing dimensions instead of converting to scalar, enabling proper element-wise division across matching shapes.
CUDA Graph Integration
tensorrt_llm/_torch/visual_gen/models/ltx2/pipeline_ltx2.py
Introduced _LTX2CUDAGraphRunner subclass that captures and replays CUDA graphs with Modality tensor support, deriving cache keys from tensor shapes and Modality constituent tensors; integrated into pipeline's transformer via _setup_cuda_graphs() method with capture warmup (gc.collect() and cache clearing).

Sequence Diagram(s)

sequenceDiagram
    participant Pipeline as LTX2Pipeline
    participant Runner as _LTX2CUDAGraphRunner
    participant Transformer as Transformer
    participant CUDA as CUDA Runtime
    participant Cache as Static Buffers

    Pipeline->>Runner: _setup_cuda_graphs()<br/>(wrap transformer.forward)
    Note over Pipeline,Runner: Setup Phase

    Pipeline->>Runner: forward(tensor_input,<br/>modality_input, ...)
    Note over Runner: Check cache key<br/>(shapes + modality)

    alt Cache Miss
        Runner->>Runner: Clone inputs → static buffers
        Runner->>CUDA: gc.collect()
        Runner->>CUDA: torch.cuda.empty_cache()
        Runner->>Transformer: Warmup capture
        Runner->>CUDA: Synchronize
        Runner->>Cache: Store graph + buffers<br/>in _graph_cache
    else Cache Hit
        Runner->>Cache: Retrieve cached graph
    end

    Note over Runner,Cache: Replay Phase
    Runner->>Cache: Copy input → static buffers<br/>(in-place for Modality)
    Runner->>CUDA: Launch replayed graph
    Runner->>Runner: Extract output from cache
    Runner->>Pipeline: Return result
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 53.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description check ✅ Passed PR description is comprehensive, well-structured, and follows the template with all required sections clearly filled out.
Title check ✅ Passed The PR title accurately describes the main feature: adding CUDA graph support for LTX-2 with torch compile compatibility. It matches the core objective and primary code changes across all modified files.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
tensorrt_llm/_torch/visual_gen/models/ltx2/ltx2_core/rope.py (1)

186-189: Consider cache management for long-running processes.

The module-level _freq_grid_gpu_cache grows unboundedly as different (generator, theta, n_dims, dim, device) combinations are used. For typical use this is fine (small number of configs), but for long-running services with varied configurations, this could accumulate GPU tensors.

Consider adding a clear_freq_cache() utility or using an LRU-bounded cache if memory pressure becomes a concern.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tensorrt_llm/_torch/visual_gen/models/ltx2/ltx2_core/rope.py` around lines
186 - 189, The module-level _freq_grid_gpu_cache stores GPU tensors keyed by
(generator_id, theta, n_dims, dim, device) and can grow unbounded in
long-running services; add a cache-management API such as a clear_freq_cache()
function (and optionally a remove_freq_cache(key) helper) that frees GPU tensors
and clears entries from _freq_grid_gpu_cache, and/or replace the dict with an
LRU-bounded cache implementation to evict old entries; update any callers that
rely on the cached values to use these helpers and ensure
torch.cuda.synchronize() / .to('cpu') or .detach() is used appropriately when
releasing GPU tensors so memory is actually freed.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@tensorrt_llm/_torch/visual_gen/models/ltx2/ltx2_core/utils_ltx2.py`:
- Around line 18-26: The current implementation only checks sigma == 0 in the
non-tensor branch, so when sigma is a torch.Tensor with all-zero values the
division ((sample.to(calc_dtype) - denoised.to(calc_dtype)) / sigma) will
produce inf/nan; update the tensor branch in utils_ltx2.py to validate tensor
sigma before broadcasting (e.g., check torch.any(sigma == 0) or torch.all
depending on desired semantics) and raise a ValueError("Sigma can't be 0.0") if
a zero is detected, preserving the existing dtype conversions and the
broadcasting loop for sample.dim(); ensure the error check is done after moving
sigma to calc_dtype but before performing the division with sample and denoised.

---

Nitpick comments:
In `@tensorrt_llm/_torch/visual_gen/models/ltx2/ltx2_core/rope.py`:
- Around line 186-189: The module-level _freq_grid_gpu_cache stores GPU tensors
keyed by (generator_id, theta, n_dims, dim, device) and can grow unbounded in
long-running services; add a cache-management API such as a clear_freq_cache()
function (and optionally a remove_freq_cache(key) helper) that frees GPU tensors
and clears entries from _freq_grid_gpu_cache, and/or replace the dict with an
LRU-bounded cache implementation to evict old entries; update any callers that
rely on the cached values to use these helpers and ensure
torch.cuda.synchronize() / .to('cpu') or .detach() is used appropriately when
releasing GPU tensors so memory is actually freed.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 453e20c5-f035-4112-a44d-2f6e7cd935b9

📥 Commits

Reviewing files that changed from the base of the PR and between 1e51f1c and 7a7eb65.

📒 Files selected for processing (3)
  • tensorrt_llm/_torch/visual_gen/models/ltx2/ltx2_core/rope.py
  • tensorrt_llm/_torch/visual_gen/models/ltx2/ltx2_core/utils_ltx2.py
  • tensorrt_llm/_torch/visual_gen/models/ltx2/pipeline_ltx2.py

Comment thread tensorrt_llm/_torch/visual_gen/models/ltx2/ltx2_core/utils_ltx2.py
@luyiyun1021
luyiyun1021 force-pushed the feature/ltx2-cuda-graph branch 2 times, most recently from f9458db to 4762386 Compare April 1, 2026 08:09
@luyiyun1021
luyiyun1021 requested a review from a team as a code owner April 1, 2026 08:09
@luyiyun1021

Copy link
Copy Markdown
Collaborator Author

/bot run --disable-fail-fast

@luyiyun1021
luyiyun1021 requested a review from zhenhuaw-me April 1, 2026 08:20
@luyiyun1021 luyiyun1021 changed the title [TRTLLM-11457][feat] Add CUDA graph support for LTX-2 transformer [TRTLLM-11457][feat] Add CUDA graph support (torch compile compatible) for LTX-2 transformer Apr 1, 2026
@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #41161 [ run ] triggered by Bot. Commit: 4762386 Link to invocation

@luyiyun1021 luyiyun1021 changed the title [TRTLLM-11457][feat] Add CUDA graph support (torch compile compatible) for LTX-2 transformer [TRTLLM-11104][feat] Add CUDA graph support (torch compile compatible) for LTX-2 transformer Apr 1, 2026
@luyiyun1021 luyiyun1021 changed the title [TRTLLM-11104][feat] Add CUDA graph support (torch compile compatible) for LTX-2 transformer [TRTLLM-11104][feat] Add CUDA graph support (torch compile compatible) for LTX-2 Apr 1, 2026
Comment thread tensorrt_llm/_torch/visual_gen/models/ltx2/ltx2_core/rope.py Outdated
Comment thread tensorrt_llm/_torch/visual_gen/models/ltx2/ltx2_core/rope.py Outdated
@luyiyun1021
luyiyun1021 force-pushed the feature/ltx2-cuda-graph branch 3 times, most recently from d41c719 to 51b9826 Compare April 1, 2026 12:27
@luyiyun1021

Copy link
Copy Markdown
Collaborator Author

/bot run --disable-fail-fast

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #41198 [ run ] triggered by Bot. Commit: 51b9826 Link to invocation

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #41198 [ run ] completed with state SUCCESS. Commit: 51b9826
/LLM/main/L0_MergeRequest_PR pipeline #32159 completed with status: 'FAILURE'

CI Report

⚠️ Action Required:

  • Please check the failed tests and fix your PR
  • If you cannot view the failures, ask the CI triggerer to share details
  • Once fixed, request an NVIDIA team member to trigger CI again

Link to invocation

@luyiyun1021
luyiyun1021 force-pushed the feature/ltx2-cuda-graph branch from 51b9826 to f4b199c Compare April 2, 2026 03:00
@luyiyun1021

Copy link
Copy Markdown
Collaborator Author

/bot run --disable-fail-fast

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #41330 [ run ] triggered by Bot. Commit: f4b199c Link to invocation

@zhenhuaw-me zhenhuaw-me left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

LGTM thanks!

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #41330 [ run ] completed with state SUCCESS. Commit: f4b199c
/LLM/main/L0_MergeRequest_PR pipeline #32278 completed with status: 'FAILURE'

CI Report

⚠️ Action Required:

  • Please check the failed tests and fix your PR
  • If you cannot view the failures, ask the CI triggerer to share details
  • Once fixed, request an NVIDIA team member to trigger CI again

Link to invocation

@luyiyun1021
luyiyun1021 force-pushed the feature/ltx2-cuda-graph branch from f4b199c to 7bedea5 Compare April 2, 2026 13:02
@luyiyun1021

Copy link
Copy Markdown
Collaborator Author

/bot run --disable-fail-fast

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #41434 [ run ] triggered by Bot. Commit: 7bedea5 Link to invocation

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #41434 [ run ] completed with state SUCCESS. Commit: 7bedea5
/LLM/main/L0_MergeRequest_PR pipeline #32365 completed with status: 'FAILURE'

CI Report

⚠️ Action Required:

  • Please check the failed tests and fix your PR
  • If you cannot view the failures, ask the CI triggerer to share details
  • Once fixed, request an NVIDIA team member to trigger CI again

Link to invocation

@luyiyun1021
luyiyun1021 force-pushed the feature/ltx2-cuda-graph branch from 7bedea5 to ec4c853 Compare April 3, 2026 06:51
@luyiyun1021

Copy link
Copy Markdown
Collaborator Author

/bot run --disable-fail-fast

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #41619 [ run ] triggered by Bot. Commit: ec4c853 Link to invocation

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #41619 [ run ] completed with state SUCCESS. Commit: ec4c853
/LLM/main/L0_MergeRequest_PR pipeline #32527 completed with status: 'FAILURE'

CI Report

⚠️ Action Required:

  • Please check the failed tests and fix your PR
  • If you cannot view the failures, ask the CI triggerer to share details
  • Once fixed, request an NVIDIA team member to trigger CI again

Link to invocation

@yibinl-nvidia yibinl-nvidia 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.

LGTM

Comment thread examples/visual_gen/visual_gen_ltx2.py
@luyiyun1021

Copy link
Copy Markdown
Collaborator Author

/bot run --disable-fail-fast

Add Modality-aware CUDA graph capture/replay for the LTX-2 transformer,
enabling monolithic graph capture of the full transformer forward including
NCCL all-to-all collectives (Ulysses sequence parallelism).

Key changes:
- pipeline_ltx2.py: _LTX2CUDAGraphRunner subclass that handles Modality
  dataclass args (key derivation, static buffer clone/copy, None-tolerant
  output refs) and BatchedPerturbationConfig fingerprinting for STG.
  Override _setup_cuda_graphs to remove torch.compile mutual exclusion.
- rope.py: GPU-side frequency grid cache to avoid CPU->GPU H2D transfer
  that blocks CUDA graph capture.
- utils_ltx2.py: Keep sigma as tensor in to_velocity() to avoid .item()
  GPU->CPU synchronization.

Compatible with torch.compile: graph capture happens during warmup after
torch.compile's lazy compilation, so captured graphs contain optimized
compiled kernels.

Ref: NVIDIA#12603
Signed-off-by: Yiyun Lu <55233584+luyiyun1021@users.noreply.github.com>
@luyiyun1021
luyiyun1021 force-pushed the feature/ltx2-cuda-graph branch from ec4c853 to c21974f Compare April 7, 2026 03:20
@luyiyun1021

Copy link
Copy Markdown
Collaborator Author

/bot run --disable-fail-fast

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #42045 [ run ] triggered by Bot. Commit: c21974f Link to invocation

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #42047 [ run ] triggered by Bot. Commit: c21974f Link to invocation

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #42045 [ run ] completed with state ABORTED. Commit: c21974f

Link to invocation

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #42047 [ run ] completed with state SUCCESS. Commit: c21974f
/LLM/main/L0_MergeRequest_PR pipeline #32892 completed with status: 'FAILURE'

CI Report

⚠️ Action Required:

  • Please check the failed tests and fix your PR
  • If you cannot view the failures, ask the CI triggerer to share details
  • Once fixed, request an NVIDIA team member to trigger CI again

Link to invocation

@luyiyun1021 luyiyun1021 changed the title [TRTLLM-11104][feat] Add CUDA graph support (torch compile compatible) for LTX-2 [TRTLLM-11707][feat] Add CUDA graph support (torch compile compatible) for LTX-2 Apr 8, 2026
@luyiyun1021

Copy link
Copy Markdown
Collaborator Author

/bot run --disable-fail-fast

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #42299 [ run ] triggered by Bot. Commit: c21974f Link to invocation

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #42299 [ run ] completed with state SUCCESS. Commit: c21974f
/LLM/main/L0_MergeRequest_PR pipeline #33094 completed with status: 'SUCCESS'

CI Report

Link to invocation

@luyiyun1021
luyiyun1021 removed the request for review from Shixiaowei02 April 10, 2026 02:47
@luyiyun1021
luyiyun1021 merged commit 1d4bd5d into NVIDIA:main Apr 10, 2026
7 checks passed
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.

5 participants