@@ -22,7 +22,15 @@ class LTX2VideoArchConfig(DiTArchConfig):
2222 _fsdp_shard_conditions : list = field (default_factory = lambda : [is_ltx2_blocks ])
2323 _compile_conditions : list = field (default_factory = lambda : [is_ltx2_blocks ])
2424
25- # Parameter name mapping for weight conversion (hf/comfy -> FastVideo)
25+ # Parameter name mapping for weight conversion (hf/comfy -> FastVideo).
26+ # The ``to_gate_compress`` -> ``to_gate_logits`` rules for the LTX-2.3
27+ # gated-attention path are inserted at the front of this dict in
28+ # ``__post_init__`` only when ``apply_gated_attention=True``. Without
29+ # that flag the target model has no ``to_gate_logits`` slot, *and* the
30+ # same-named ``to_gate_compress`` already lives on the LTX-2.0 VSA-QAT
31+ # gate path (plus it is in the default ``lora_target_modules`` list).
32+ # Applying the rename unconditionally silently breaks LTX-2.0 VSA
33+ # checkpoints and default-target LoRAs.
2634 param_names_mapping : dict = field (
2735 default_factory = lambda : {
2836 r"^model\.diffusion_model\.(.*)$" : r"model.\1" ,
@@ -44,6 +52,9 @@ class LTX2VideoArchConfig(DiTArchConfig):
4452 attention_type : str = "default"
4553 rope_type : str = "split"
4654 double_precision_rope : bool = True
55+ # LTX-2.3 gated extensions. All default OFF == LTX-2.0 behavior.
56+ cross_attention_adaln : bool = False
57+ caption_proj_before_connector : bool = False
4758
4859 positional_embedding_theta : float = 10000.0
4960 positional_embedding_max_pos : list [int ] = field (default_factory = lambda : [20 , 2048 , 2048 ])
@@ -64,6 +75,27 @@ class LTX2VideoArchConfig(DiTArchConfig):
6475 audio_cross_attention_dim : int = 2048
6576 audio_positional_embedding_max_pos : list [int ] = field (default_factory = lambda : [20 ])
6677 av_ca_timestep_scale_multiplier : int = 1
78+ # LTX-2.3 gated self-attention (distinct from the VSA-QAT to_gate_compress
79+ # gate). Default OFF == LTX-2.0 behavior.
80+ apply_gated_attention : bool = False
81+
82+ # Text connector/feature extractor compatibility fields carried in some
83+ # transformer configs (used by the LTX-2.3 text stack). Defaults match
84+ # the LTX-2.0 connector layout.
85+ caption_projection_first_linear : bool = True
86+ caption_proj_input_norm : bool = True
87+ caption_projection_second_linear : bool = True
88+ connector_num_attention_heads : int = 30
89+ connector_attention_head_dim : int = 128
90+ connector_num_layers : int = 2
91+ audio_connector_num_attention_heads : int = 30
92+ audio_connector_attention_head_dim : int = 128
93+ audio_connector_num_layers : int = 2
94+
95+ # STG perturbation block index differs across model versions.
96+ # LTX-2.0 defaults to block 29; LTX-2.3 (caption_proj_before_connector)
97+ # uses block 28. ``None`` resolves in __post_init__.
98+ stg_block_idx : int | None = None
6799
68100 def __post_init__ (self ):
69101 super ().__post_init__ ()
@@ -72,6 +104,29 @@ def __post_init__(self):
72104 self .in_channels = self .num_channels_latents * patch_volume
73105 if self .out_channels is None :
74106 self .out_channels = self .in_channels
107+ if self .stg_block_idx is None :
108+ self .stg_block_idx = 28 if self .caption_proj_before_connector else 29
109+
110+ # LTX-2.3 stores the gated-attention weight under ``to_gate_compress``
111+ # upstream; FastVideo's internal name is ``to_gate_logits``. Only
112+ # enable the rename when the gated path is actually configured: the
113+ # LTX-2.0 attention module's own ``to_gate_compress`` parameter
114+ # (created when the backend is ``VIDEO_SPARSE_ATTN``) and the default
115+ # ``to_gate_compress`` LoRA target both share the upstream name, so
116+ # an unconditional rename would silently retarget them. Inserted at
117+ # the front so first-match-wins matching fires the rename before the
118+ # generic prefix-strip rules.
119+ if self .apply_gated_attention :
120+ gate_rules = {
121+ r"^model\.diffusion_model\.(.*)\.to_gate_compress\.(.*)$" : r"model.\1.to_gate_logits.\2" ,
122+ r"^diffusion_model\.(.*)\.to_gate_compress\.(.*)$" : r"model.\1.to_gate_logits.\2" ,
123+ r"^model\.(.*)\.to_gate_compress\.(.*)$" : r"model.\1.to_gate_logits.\2" ,
124+ r"^(.*)\.to_gate_compress\.(.*)$" : r"model.\1.to_gate_logits.\2" ,
125+ }
126+ self .param_names_mapping = {
127+ ** gate_rules ,
128+ ** self .param_names_mapping ,
129+ }
75130
76131
77132@dataclass
0 commit comments