diff --git a/src/diffusers/hooks/context_parallel.py b/src/diffusers/hooks/context_parallel.py index 1310b20c5c11..e8bd4c5bb28f 100644 --- a/src/diffusers/hooks/context_parallel.py +++ b/src/diffusers/hooks/context_parallel.py @@ -57,6 +57,9 @@ def _get_parameter_from_args_kwargs(self, identifier: str, args=(), kwargs=None) index = self.cached_parameter_indices.get(identifier, None) if index is None: raise ValueError(f"Parameter '{identifier}' not found in cached indices.") + if index >= len(args): + # Not passed positionally or as a kwarg; the forward will use its default value. + return None, False, index return args[index], False, index if self._cls is None: @@ -72,7 +75,8 @@ def _get_parameter_from_args_kwargs(self, identifier: str, args=(), kwargs=None) index = self.cached_parameter_indices[identifier] if index >= len(args): - raise ValueError(f"Expected {index} arguments but got {len(args)}.") + # Not passed positionally or as a kwarg; the forward will use its default value. + return None, False, index return args[index], False, index diff --git a/src/diffusers/models/attention_dispatch.py b/src/diffusers/models/attention_dispatch.py index 9414c151fd67..a07ca93ebc06 100644 --- a/src/diffusers/models/attention_dispatch.py +++ b/src/diffusers/models/attention_dispatch.py @@ -2395,6 +2395,10 @@ def forward( mask_list = [torch.empty_like(attn_mask) for _ in range(world_size)] dist.all_gather(mask_list, attn_mask, group=group) attn_mask = torch.cat(mask_list, dim=-1) + if attn_mask is not None and attn_mask.ndim == 4 and attn_mask.shape[1] == H: + # QKV carry H // world_size heads after the all-to-all; shard the mask's head axis to match. + local_rank = _parallel_config.context_parallel_config._ulysses_local_rank + attn_mask = attn_mask.chunk(world_size, dim=1)[local_rank] out = forward_op( ctx, diff --git a/src/diffusers/models/transformers/transformer_ltx2.py b/src/diffusers/models/transformers/transformer_ltx2.py index 465408d94693..26c36c3a5295 100644 --- a/src/diffusers/models/transformers/transformer_ltx2.py +++ b/src/diffusers/models/transformers/transformer_ltx2.py @@ -1091,18 +1091,6 @@ class LTX2VideoTransformer3DModel( _supports_gradient_checkpointing = True _skip_layerwise_casting_patterns = ["norm"] _repeated_blocks = ["LTX2VideoTransformerBlock"] - _cp_plan = { - "": { - "hidden_states": ContextParallelInput(split_dim=1, expected_dims=3, split_output=False), - "encoder_hidden_states": ContextParallelInput(split_dim=1, expected_dims=3, split_output=False), - "encoder_attention_mask": ContextParallelInput(split_dim=1, expected_dims=2, split_output=False), - }, - "rope": { - 0: ContextParallelInput(split_dim=1, expected_dims=3, split_output=True), - 1: ContextParallelInput(split_dim=1, expected_dims=3, split_output=True), - }, - "proj_out": ContextParallelOutput(gather_dim=1, expected_dims=3), - } @register_to_config def __init__( @@ -1318,6 +1306,37 @@ def __init__( self.gradient_checkpointing = False + # RoPE modules return (cos, sin) shaped (B, T, D) for rope_type="interleaved" and (B, H, T, D // 2) + # for rope_type="split", so the sequence dim to shard depends on the config. + if rope_type == "split": + rope_plan = { + 0: ContextParallelInput(split_dim=2, expected_dims=4, split_output=True), + 1: ContextParallelInput(split_dim=2, expected_dims=4, split_output=True), + } + else: + rope_plan = { + 0: ContextParallelInput(split_dim=1, expected_dims=3, split_output=True), + 1: ContextParallelInput(split_dim=1, expected_dims=3, split_output=True), + } + self._cp_plan = { + "": { + "hidden_states": ContextParallelInput(split_dim=1, expected_dims=3, split_output=False), + "timestep": ContextParallelInput(split_dim=1, expected_dims=2, split_output=False), + "audio_hidden_states": ContextParallelInput(split_dim=1, expected_dims=3, split_output=False), + "audio_timestep": ContextParallelInput(split_dim=1, expected_dims=2, split_output=False), + "encoder_hidden_states": ContextParallelInput(split_dim=1, expected_dims=3, split_output=False), + "encoder_attention_mask": ContextParallelInput(split_dim=1, expected_dims=2, split_output=False), + "audio_encoder_hidden_states": ContextParallelInput(split_dim=1, expected_dims=3, split_output=False), + "audio_encoder_attention_mask": ContextParallelInput(split_dim=1, expected_dims=2, split_output=False), + }, + "rope": rope_plan, + "audio_rope": rope_plan, + "cross_attn_rope": rope_plan, + "cross_attn_audio_rope": rope_plan, + "proj_out": ContextParallelOutput(gather_dim=1, expected_dims=3), + "audio_proj_out": ContextParallelOutput(gather_dim=1, expected_dims=3), + } + @apply_lora_scale("attention_kwargs") def forward( self,