def __init__(self, config: TextEncoderConfig) -> None:
super().__init__(config)
arch = config.arch_config
# LTX-2.3 routes the caption projection before the connector and uses
# separate per-modality feature extractor linears. Default (False)
# keeps the single LTX-2.0 GemmaFeaturesExtractorProjLinear.
self.use_v2_feature_extractor = bool(
getattr(arch, "caption_proj_before_connector", False))
if self.use_v2_feature_extractor:
video_out_features = (
getattr(arch, "video_feature_extractor_out_features", None)
or arch.feature_extractor_out_features)
audio_out_features = (
getattr(arch, "audio_feature_extractor_out_features", None)
or video_out_features)
self.video_feature_extractor_linear = nn.Linear(
arch.feature_extractor_in_features,
video_out_features,
bias=True,
)
self.audio_feature_extractor_linear = nn.Linear(
arch.feature_extractor_in_features,
audio_out_features,
bias=True,
)
else:
self.feature_extractor_linear = GemmaFeaturesExtractorProjLinear(
in_features=arch.feature_extractor_in_features,
out_features=arch.feature_extractor_out_features,
)
connector_apply_gated_attention = bool(
getattr(arch, "connector_apply_gated_attention", False))
video_connector_config = GemmaConnectorConfig(
num_attention_heads=arch.connector_num_attention_heads,
attention_head_dim=arch.connector_attention_head_dim,
num_layers=arch.connector_num_layers,
positional_embedding_theta=arch.connector_positional_embedding_theta,
positional_embedding_max_pos=arch.connector_positional_embedding_max_pos,
rope_type=LTXRopeType(arch.connector_rope_type),
double_precision_rope=arch.connector_double_precision_rope,
num_learnable_registers=arch.connector_num_learnable_registers,
apply_gated_attention=connector_apply_gated_attention,
)
audio_connector_config = GemmaConnectorConfig(
num_attention_heads=getattr(
arch, "audio_connector_num_attention_heads", None)
or arch.connector_num_attention_heads,
attention_head_dim=getattr(
arch, "audio_connector_attention_head_dim", None)
or arch.connector_attention_head_dim,
num_layers=getattr(arch, "audio_connector_num_layers", None)
or arch.connector_num_layers,
positional_embedding_theta=arch.connector_positional_embedding_theta,
positional_embedding_max_pos=arch.connector_positional_embedding_max_pos,
rope_type=LTXRopeType(arch.connector_rope_type),
double_precision_rope=arch.connector_double_precision_rope,
num_learnable_registers=arch.connector_num_learnable_registers,
apply_gated_attention=connector_apply_gated_attention,
)
self.embeddings_connector = Embeddings1DConnector(video_connector_config)
self.audio_embeddings_connector = Embeddings1DConnector(audio_connector_config)
self.gemma_model_path = arch.gemma_model_path
self.gemma_dtype = arch.gemma_dtype
self.padding_side = arch.padding_side
self._gemma_model: Gemma3ForConditionalGeneration | None = None