Skip to content

Commit 3a13196

Browse files
committed
LTX2.3 improvements and bug fixes
1 parent 9616d1c commit 3a13196

7 files changed

Lines changed: 249 additions & 222 deletions

File tree

src/maxdiffusion/generate_ltx2.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,8 @@ def run(config, pipeline=None, filename_prefix="", commit_hash=None):
237237

238238
# Export videos
239239
for i in range(len(videos)):
240-
video_path = f"{filename_prefix}ltx2_output_{getattr(config, 'seed', 0)}_{i}.mp4"
240+
model_name_prefix = getattr(config, "model_name", "ltx2").replace(".", "_")
241+
video_path = f"{filename_prefix}{model_name_prefix}_output_{getattr(config, 'seed', 0)}_{i}.mp4"
241242
audio_i = audios[i] if audios is not None else None
242243

243244
audio_format = getattr(config, "audio_format", "s16")

src/maxdiffusion/models/attention_flax.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1383,7 +1383,7 @@ def __init__(
13831383
self,
13841384
mesh: Mesh,
13851385
attention_kernel: str,
1386-
scale: int,
1386+
scale: float,
13871387
heads: int,
13881388
dim_head: int,
13891389
use_memory_efficient_attention: bool = False,
@@ -1475,7 +1475,7 @@ def apply_attention(self, query: Array, key: Array, value: Array, attention_mask
14751475
class AttentionOp(nn.Module):
14761476
mesh: Mesh
14771477
attention_kernel: str
1478-
scale: int
1478+
scale: float
14791479
heads: int
14801480
dim_head: int
14811481
use_memory_efficient_attention: bool = False

src/maxdiffusion/models/ltx2/attention_ltx2.py

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -88,13 +88,8 @@ def apply_split_rotary_emb(x: Array, freqs: Tuple[Array, Array]) -> Array:
8888
first_x = split_x[..., 0, :]
8989
second_x = split_x[..., 1, :]
9090

91-
cos_u = jnp.expand_dims(cos, axis=-2)
92-
sin_u = jnp.expand_dims(sin, axis=-2)
93-
94-
out = split_x * cos_u
95-
96-
out_first = out[..., 0, :] - second_x * sin_u.squeeze(-2)
97-
out_second = out[..., 1, :] + first_x * sin_u.squeeze(-2)
91+
out_first = first_x * cos - second_x * sin
92+
out_second = second_x * cos + first_x * sin
9893

9994
out = jnp.stack([out_first, out_second], axis=-2)
10095
out = out.reshape(*out.shape[:-2], last_dim)
@@ -176,12 +171,6 @@ def prepare_video_coords(
176171
patch_ends = grid + patch_size_delta
177172

178173
# Combine start and end coordinates
179-
latent_coords = jnp.stack([grid, patch_ends], axis=-1) # [3, N_F, N_H, N_W, 2]
180-
latent_coords = latent_coords.transpose(1, 2, 3, 0, 4) # [N_F, N_H, N_W, 3, 2]
181-
latent_coords = latent_coords.reshape(-1, 3, 2) # [num_patches, 3, 2]
182-
latent_coords = jnp.expand_dims(latent_coords, 0) # [1, num_patches, 3, 2]
183-
latent_coords = jnp.tile(latent_coords, (batch_size, 1, 1, 1)) # [B, num_patches, 3, 2]
184-
185174
latent_coords = jnp.stack([grid, patch_ends], axis=-1) # [3, N_F, N_H, N_W, 2]
186175
latent_coords = latent_coords.reshape(3, -1, 2) # [3, num_patches, 2]
187176
latent_coords = jnp.expand_dims(latent_coords, 0) # [1, 3, num_patches, 2]
@@ -485,7 +474,7 @@ def __call__(
485474
# 3. Apply RoPE
486475
with jax.named_scope("Apply RoPE"):
487476
if rotary_emb is not None:
488-
if hasattr(self, "rope_type") and self.rope_type == "split":
477+
if self.rope_type == "split":
489478
# Split RoPE: passing full freqs [B, H, S, D//2]
490479
# apply_split_rotary_emb handles reshaping query/key
491480

src/maxdiffusion/models/ltx2/text_encoders/torchax_text_encoder.py

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,9 @@
2121
from torchax import interop, default_env
2222

2323
# --- Monkeypatch transformers masking_utils to avoid torchax integer tracing bug ---
24+
from unittest import mock
2425
import transformers.masking_utils
2526

26-
_orig_sliding_window_overlay = transformers.masking_utils.sliding_window_overlay
27-
2827

2928
def _patched_sliding_window_overlay(sliding_window: int):
3029
# pylint: disable=unused-argument
@@ -57,8 +56,7 @@ def __call__(
5756
self, input_ids: jax.Array, attention_mask: jax.Array, output_hidden_states: bool = True
5857
) -> Tuple[jax.Array, ...]:
5958
# Dynamically patch transformers.masking_utils only during the duration of this call
60-
transformers.masking_utils.sliding_window_overlay = _patched_sliding_window_overlay
61-
try:
59+
with mock.patch("transformers.masking_utils.sliding_window_overlay", _patched_sliding_window_overlay):
6260
with default_env():
6361
input_ids = interop.torch_view(input_ids)
6462
attention_mask = interop.torch_view(attention_mask)
@@ -72,9 +70,6 @@ def __call__(
7270
output_hidden_states=output_hidden_states,
7371
)
7472
return interop.jax_view(output)
75-
finally:
76-
# Restore original behavior to prevent side effects on other potential models in same env
77-
transformers.masking_utils.sliding_window_overlay = _orig_sliding_window_overlay
7873

7974
@staticmethod
8075
def _forward_inner(model, input_ids, attention_mask, output_hidden_states=True):

0 commit comments

Comments
 (0)