[TRTLLM-14234][perf] LTX-2: replicate audio stream across Ulysses ranks by default#16228
[TRTLLM-14234][perf] LTX-2: replicate audio stream across Ulysses ranks by default#16228luyiyun1021 wants to merge 1 commit into
Conversation
|
/bot run --disable-fail-fast |
|
PR_Github #58640 [ run ] triggered by Bot. Commit: |
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Enterprise Run ID: 📒 Files selected for processing (1)
📝 WalkthroughWalkthroughLTX2 now models audio Ulysses distribution with ChangesAudio Ulysses shard modes
Estimated code review effort: 4 (Complex) | ~60 minutes Sequence Diagram(s)sequenceDiagram
participant LTXModel
participant Ulysses
participant BasicAVTransformerBlock
participant VideoToAudioAttention
LTXModel->>Ulysses: configure and pad audio sequence
LTXModel->>BasicAVTransformerBlock: pass derived audio shard mode
BasicAVTransformerBlock->>Ulysses: slice replicated audio Q in CONDITIONAL mode
Ulysses->>VideoToAudioAttention: execute local v2a attention
VideoToAudioAttention-->>Ulysses: return local output
Ulysses->>BasicAVTransformerBlock: all-gather audio output
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
ac85793 to
880b1dc
Compare
…ks by default Under Ulysses sequence-parallelism the LTX-2 DiT sharded both video (15360 tokens) and audio (126). Audio is ~122x smaller and latency/occupancy-bound, so seq-sharding it removed ~0 compute while adding per-block collectives (audio-self A2A + a2v all-gather). Replicate the audio stream on every Ulysses rank by default: audio self/cross-attention and FFN run local, and only v2a keeps head-sharding via a local per-rank slice of the replicated Q plus an output all-gather around the unchanged async-Ulysses driver. The mode is a single internal knob _audio_full_shard (default False = replicate); the resolved state is a 3-value AudioShardMode (NONE / CONDITIONAL / FULL). Setting _audio_full_shard = True restores the exact original sharded path bit-for-bit, so this is a default flip over two already-existing, validated code paths, with no user-facing config change. Perf (8-GPU cfg2 x uly4, single denoise step, nsys): audio+v2a NCCL -81%, a2v all-gather -47%, real comm -14%, GPU wall -5.3%, Ulysses scaling efficiency 65% -> 69%. Correctness (8x B200, seed 42, 768x1280, 121 frames): LPIPS replicate vs sharded 0.112, at/below the sharded-vs-sharded noise floor 0.129. Signed-off-by: Yiyun Lu <55233584+luyiyun1021@users.noreply.github.com>
880b1dc to
df631ff
Compare
There was a problem hiding this comment.
Are we trying to maintain any compatibility? It seems to me this is a "always have benefit optimization", any cases we want to switch to the "legacy mode"?
There was a problem hiding this comment.
I‘ve done a quick test on 15s video shape's audio computation, in this case the audio part starts to scale a little bit(still worse compared to video), but I haven't done a thorough test and detailed analysis on this config since we currently focuses on 5s video. But I think the kind of comparsion between computation saved and comm overhead is a bit tricky while the shape changes. So I leave the full shard path here in case we need to re-enable it.
Summary by CodeRabbit
Description
Under Ulysses sequence-parallelism the LTX-2 DiT sharded both streams — video (15360 tokens) and audio (126). Audio is ~122x smaller and its self/cross-attention, GEMMs and FFN are latency/occupancy-bound (the audio NVFP4 GEMM is a single 128x128 kernel at ~7% SM / ~9% DRAM SOL, flat across uly1->8), so seq-sharding audio removes ~0 compute while adding per-block collectives (audio-self A2A + a2v all-gather). This PR makes the audio stream replicated on every Ulysses rank by default: audio self/cross-attention and FFN run local (no A2A / all-gather), and only v2a (audio-Q x video-KV — the one audio op that scales, via head-split) keeps Ulysses sharding, implemented as a local per-rank slice of the replicated Q plus an output all-gather around the unchanged async-Ulysses driver, so no attention-backend or C++ change is needed.
The mode is a single internal knob
_audio_full_shard(defaultFalse= replicate); the resolved runtime state is a 3-valueAudioShardMode—NONE(Ulysses off / single rank),CONDITIONAL(replicate, default),FULL(legacy seq-shard). There is no new user-facing config. Setting_audio_full_shard = Truerestores the exact original sharded path bit-for-bit (same fp4 modulation scales, a2v all-gather, input-shard/output-gather, and v2a async/sync driver), so the change is a default flip over two already-existing, validated code paths.Changes (all in
transformer_ltx2.py):configure_audio_ulyssesseeds the mode and pads audio to a multiple of the Ulysses degree; the block forward routes v2a through slice-in -> unchanged driver ->_sp_all_gatherinCONDITIONALand reuses the existing SHARD path inFULL; audio self-attn Ulysses is gated off in replicate; the audio-cross fused-modulation emits bf16 (not fp4) only for the tensor v2a slices (an NVFP4 output carries swizzled per-block scale-factors that cannot be sequence-sliced per rank), and the audio-cross GEMMs re-quantize the tiny audio internally.Test Coverage
Correctness — 8x B200, seed 42, 768x1280, 121 frames, LPIPS (AlexNet) over decoded mp4 frames:
Performance — single denoise step, per-layer µs, nsys (
--cuda-graph-trace=node), sharded -> replicate:4-GPU (cfg2 x uly2) is consistent: REAL COMM 22.37 -> 19.19 (−14%), GPU wall 185.8 -> 177.9 (−4.3%). End-to-end 8x B200 generate (denoise -> VAE -> saved video) completes for both modes: wall 5.56 -> 5.44 s, denoise-only 4.39 -> 4.27 s (single run, indicative — audio is a small fraction of the full pipeline). The gain is modest in relative terms (audio is ~5% of the step) but free and grows with Ulysses degree.
Output Quality (LPIPS)
Replicate vs sharded baseline, 8x B200, seed 42, 768x1280, 121 frames. Header shows mean/min/max LPIPS; each row shows that frame's per-frame LPIPS. Mean 0.112 is at/below the 0.129 sharded-vs-sharded noise floor — same scene and quality, only fine-detail drift.
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.