[bugfix] LTX2: honor video_position_offset_sec in the DiT - #1422
Conversation
There was a problem hiding this comment.
Code Review
This pull request introduces a video_position_offset_sec parameter to the forward method of the LTX2 model to allow offsetting video positions. Feedback highlights a potential unit mismatch issue: if fps is None, temporal positions are represented in frame units rather than seconds, meaning adding the offset directly would be incorrect. It is recommended to raise a ValueError if an offset is provided without fps.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
| if video_position_offset_sec: | ||
| positions[:, 0, ...] = positions[:, 0, ...] + float(video_position_offset_sec) |
There was a problem hiding this comment.
If fps is None, the temporal positions are in frame units rather than seconds (since _get_pixel_coords only divides by fps if it is not None). Adding video_position_offset_sec (which is in seconds) directly to frame units would cause a unit mismatch and incorrect positioning. We should raise an error if an offset is requested but fps is missing.
| if video_position_offset_sec: | |
| positions[:, 0, ...] = positions[:, 0, ...] + float(video_position_offset_sec) | |
| if video_position_offset_sec: | |
| if fps is None: | |
| raise ValueError("video_position_offset_sec cannot be applied when fps is None") | |
| positions[:, 0, ...] = positions[:, 0, ...] + float(video_position_offset_sec) |
Merge ProtectionsYour pull request matches the following merge protections and will not be merged until they are valid. 🔴 PR merge requirementsWaiting for
This rule is failing.
|
The DiT forward swallowed video_position_offset_sec via **kwargs, so multi-segment rollouts never advanced the temporal RoPE phase between segments, causing ~1s audio/ video desync at each seam. Add the offset to the temporal position coords (mirrors #1422).
…from the standard-workflow path The workflow served from this branch uses only standard ComfyUI(-LTXVideo) nodes, so drop the two third-party-plugin ports that ltx23-ancestral-reference added (3b0ca73, extended by 23c7d96): Removed end to end: - text attention amplifier (LTXTextAttentionAmplifier port): ltx2_text_amp_* FastVideoArgs fields + validation, build_text_amp_weight, the per-block text_amp gating / SP-shard / reference-prefix extension in the DiT forward, and the denoising-stage wiring. - latent anchor (LTXLatentAnchorAware port): fastvideo/models/dits/ ltx2_anchor.py (whole module), ltx2_anchor_* FastVideoArgs fields + validation, apply_latent_anchor call + anchor_block_set in the DiT, LatentAnchorContext buffers + per-step capture flags in the denoising stage, and the energy-map build in latent preparation. - parse_block_range (only consumer was the two features above). - examples/inference/basic/eager_ltx2_3_allinone_i2v.py (existed solely to wire the custom "all-in-one v2" workflow, nodes 942/969). - their unit tests in fastvideo/tests/stages/test_ltx2_ancestral_and_reference.py and the stale surface entries in docs/design/inference_schema_parity_inventory.yaml. Verified kept (standard-node semantics / infra): - euler_ancestral_rf_step / euler_ancestral_cfg_pp_step (+ sigma>=1 limit), get_ancestral_step, repin_conditioned_latents (KSamplerX0Inpaint equivalent), scheduler sigma computation, per-step CFG schedule (STGGuiderAdvanced, official ComfyUI-LTXVideo) incl. the forced negative encoding in the text-encoding stage. - reference token conditioning (used per-request by the ltx23_server production path), inplace i2v/flf2v conditioning, crop guides, per-stage CRF/preprocess, STG, gated attention, regional compile + recompile limits, FA4 fp8 branches, and all LTX-2.5 additions (keyframes_mask, prompt_adaln, per-stage LoRA, HQ decoder, presets, 2.5 ancestral path). - video_position_offset_sec (upstream origin/main, PRs hao-ai-lab#1250/hao-ai-lab#1333/hao-ai-lab#1422). Verification: python -m compileall clean; repo-wide grep for text_amp/latent_anchor/anchor_block/parse_block_range returns nothing; tests/local_tests/ltx2 (9 passed, 8 env skips), tests/local_tests/ltx2_5 (42 passed), stages suite 32 passed (2 pre-existing failures unrelated and identical before this change), param-mapping + compile-conditions 17 passed; pre-commit hooks pass. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
video_position_offset_secwas plumbed through the pipeline but swallowed byLTX2Transformer3DModel.forward's**kwargsand never applied, so the audio continuation pre-roll had no matching video shift. In multi-segment continuation this accumulated into multi-second audio/video desync.Fix: offset the video temporal RoPE positions (in seconds) by
video_position_offset_sec— audio positions are already in seconds, so video aligns with the matching later portion of audio.