From 3704b6cf3cbc27ecf3a676005e6f526265a912c2 Mon Sep 17 00:00:00 2001 From: sergioperezcheco Date: Wed, 22 Jul 2026 09:42:14 +0800 Subject: [PATCH] fix(ltx2): use actual video sequence length for dynamic timestep shift calculate_shift() was being called with max_image_seq_len as its first argument (image_seq_len), which collapses mu to a constant max_shift regardless of resolution or frame count. With use_dynamic_shifting=True this had no effect. Pass the sample's packed sequence length (latent_num_frames * latent_height * latent_width) instead, matching the Flux/SD3 pipelines and the LTX reference (math.prod(latent.shape[2:])). Fixes #14243 Signed-off-by: Sergio Perez --- src/diffusers/pipelines/ltx2/pipeline_ltx2.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/diffusers/pipelines/ltx2/pipeline_ltx2.py b/src/diffusers/pipelines/ltx2/pipeline_ltx2.py index 493db96e48a7..8f6114267545 100644 --- a/src/diffusers/pipelines/ltx2/pipeline_ltx2.py +++ b/src/diffusers/pipelines/ltx2/pipeline_ltx2.py @@ -1108,7 +1108,6 @@ def __call__( raise ValueError( f"Provided `latents` tensor has shape {latents.shape}, but the expected shape is either [batch_size, seq_len, num_features] or [batch_size, latent_dim, latent_frames, latent_height, latent_width]." ) - # video_sequence_length = latent_num_frames * latent_height * latent_width num_channels_latents = self.transformer.config.in_channels latents = self.prepare_latents( @@ -1164,8 +1163,9 @@ def __call__( # 5. Prepare timesteps sigmas = np.linspace(1.0, 1 / num_inference_steps, num_inference_steps) if sigmas is None else sigmas + video_sequence_length = latent_num_frames * latent_height * latent_width mu = calculate_shift( - self.scheduler.config.get("max_image_seq_len", 4096), + video_sequence_length, self.scheduler.config.get("base_image_seq_len", 1024), self.scheduler.config.get("max_image_seq_len", 4096), self.scheduler.config.get("base_shift", 0.95),