Skip to content
AILinkDeepTech
Go back
Reinforcement Learning Medium

LTX-2 Architecture: Asymmetric Dual-Stream Audio-Video DiT and Flow Matching

Abstract

Master LTX-2: asymmetric dual-stream video/audio DiT, 1D/3D RoPE alignment, cross-modality adaLN, multimodal guidance (CFG/STG), and PyTorch pipelines.

Joint Spatiotemporal and Acoustic Distribution Modeling

Traditional multimodal video synthesis frameworks decouple visual generation from audio synthesis through a cascaded two-stage pipeline: a video diffusion model (e.g., SVD, CogVideoX) generates silent video frames, followed by a separate Text-to-Audio / TTS model (e.g., AudioLDM, Bark) and a downstream post-hoc synchronization module (e.g., Wav2Lip). This decoupled formulation introduces fundamental failure modes:

  1. Acoustic-Visual Desynchronization: Independent generation fails to capture fine-grained physical causality (e.g., footfall impacts, percussive strikes, glass shattering, phoneme-lip dynamics).
  2. Phase and Dynamics Mismatch: Independent acoustic models lack ambient visual context (reverberation, spatial room acoustics, material resonance).

LTX-2 (Lightricks, 2025) resolves these limitations by modeling the joint continuous distribution of video latents and stereo audio latents conditioned on text inside a unified 19B-parameter Asymmetric Dual-Stream Diffusion Transformer (DiT) trained via Rectified Flow Matching.


Architectural Comparison

Architectural DimensionCascaded Video + Audio (SVD + AudioLDM)Single-Stream Joint DiT (Naive Concat)CogVideoX (Tencent)LTX-2 (Lightricks)
Model Topology2 Independent ModelsSingle Shared Latent SequenceVideo-Only 3D DiTAsymmetric Dual-Stream DiT (48 Blocks)
Video Stream Capacity (UNet/DiT)Uniform Param Budget Parameters Parameters ()
Audio Stream Capacity (AudioLDM)Uniform Param BudgetNone (Silent) Parameters ()
Positional Encoding3D RoPE (Video), 1D (Audio)Flattened 1D Absolute3D RoPE (Spatial-Temporal)3D RoPE (Video), 1D (Audio), 1D Temporal (Cross)
Cross-Modal ExchangePost-hoc Lip-Sync (Wav2Lip)Full Global Self-AttentionNoneBidirectional A V Cross-Attention with 1D RoPE
Conditioning ModulationStandard AdaLNStandard AdaLNExpert AdaLNCross-Modality AdaLN (Conditioned on Cross-Timesteps)
Text Encoder BackboneT5-XXL / CLIP-LT5-XXLT5-XXLGemma-3-12B + Multilayer Connectors + Registers
Sampling & GuidanceStandard CFG ()Standard CFGCFG + Dynamic ShiftMultiModalGuider (CFG + STG + Modality-CFG + Rescale)

Mathematical Foundations

flowchart TD TEXT["Text Prompt c\n(Gemma-3-12B Multi-Layer Extraction)"] --> CONNECTORS["Dual Modality Connectors\nwith Learnable Register Tokens"] CONNECTORS --> C_V["Video Context c_V in R^(L x 4096)"] CONNECTORS --> C_A["Audio Context c_A in R^(L x 2048)"] V_PIXELS["Video Frames (8k+1, H, W)"] --> V_VAE["Causal 3D Video VAE\n(1/8 Temporal, 1/32 Spatial)"] V_VAE --> V_LATENTS["x_V in R^(B x 128 x F' x H/32 x W/32)"] A_WAVE["Stereo Audio (24kHz)"] --> A_VAE["Stereo Mel Audio VAE\n(1/4 Temporal Downsampling)"] A_VAE --> A_LATENTS["x_A in R^(B x 8 x T/4 x 16)"] V_LATENTS --> DUAL_DIT["48-Layer Asymmetric Dual-Stream DiT"] A_LATENTS --> DUAL_DIT C_V --> DUAL_DIT C_A --> DUAL_DIT DUAL_DIT --> V_OUT["Predicted Video Velocity v_V"] DUAL_DIT --> A_OUT["Predicted Audio Velocity v_A"]

Figure 1: LTX-2 Asymmetric Dual-Stream pipeline generating synchronized video and stereo audio through unified flow matching.

1. Joint Rectified Flow Formulation

LTX-2 parameterizes generative dynamics via continuous-time Flow Matching. Let clean latent states be and standard Gaussian noise vectors be .

The forward linear interpolation trajectories at time are:

The ground-truth velocity targets evaluate to:

The joint network parameterizes vector fields optimized under the joint weighted objective:

where , and loss masking ensures conditioning modalities () contribute zero loss gradient.


2. Latent Representations & Patchification Mechanics

flowchart LR subgraph VIDEO_STREAM["14B Video Stream"] V_IN["Latent x_V: [B, 128, F', H/32, W/32]"] --> V_PATCH["Patchify (p=1, 1x1x1)\nTokens: N_V = F' * (H/32) * (W/32)"] V_PATCH --> V_TOKENS["z_V in R^(N_V x 4096)"] end subgraph AUDIO_STREAM["5B Audio Stream"] A_IN["Latent x_A: [B, 8, T/4, 16]"] --> A_PATCH["Patchify along Mel Axis\nTokens: N_A = T/4"] A_PATCH --> A_TOKENS["z_A in R^(N_A x 2048)"] end

Video Latent Compression Contract:

The causal 3D convolutional Video VAE compresses pixels into latent tensors , where input frames satisfy the boundary condition .

Spatial-temporal patchification maps each grid location to model dimension :

Audio Latent Compression Contract:

The stereo Audio VAE processes log-mel spectrograms ( mel bins) into -channel latents . Each latent frame corresponds to of physical audio. Patchification yields:


3. Dual-Stream Transformer Block Dynamics & 1D Temporal RoPE

Each of the shared transformer blocks executes four sequential operations per modality:

flowchart TD subgraph BLOCK["Dual-Stream Block (Layer l)"] direction TB V_IN["z_V^(l-1)"] --> V_SELF["Video Self-Attention (3D RoPE)"] A_IN["z_A^(l-1)"] --> A_SELF["Audio Self-Attention (1D RoPE)"] V_SELF --> V_TXT["Text Cross-Attention (c_V)"] A_SELF --> A_TXT["Text Cross-Attention (c_A)"] V_TXT --> CROSS["Bidirectional A <-> V Cross-Attention\n(Strict 1D Temporal RoPE on Shared Time Axis)"] A_TXT --> CROSS CROSS --> V_FFN["Video SwiGLU FFN (4096 -> 16384 -> 4096)"] CROSS --> A_FFN["Audio SwiGLU FFN (2048 -> 8192 -> 2048)"] V_FFN --> V_OUT["z_V^(l)"] A_FFN --> A_OUT["z_A^(l)"] end

1D Temporal RoPE Formulation for Cross-Modal Attention:

While video self-attention uses 3D Rotary Position Embeddings , cross-modal attention enforces a strict 1D Temporal RoPE across the shared continuous time coordinate :

Because both video frame and audio latent map to the exact same temporal coordinate , attention weights naturally peak along the diagonal , guaranteeing zero-drift acoustic synchronization without auxiliary contrastive sync losses.


4. Cross-Modality AdaLN Modulation

Modulation vectors incorporate cross-timestep embeddings to suppress cross-modal interference during high-noise initial steps:

At (high noise), , allowing each modality to establish global structural priors independently. As (low noise), opens, enforcing fine-grained lip-sync and transient acoustic alignment.


5. MultiModalGuider: Closed-Form Guidance Update

During sampling, the velocity vector field combines Classifier-Free Guidance (CFG), Spatio-Temporal Guidance (STG; Zhou et al., 2024), and Modality Isolation Guidance:

\boxed{\hat{\mathbf{v}} = \mathbf{v}_{\text{cond}} + (s_{\text{cfg}} - 1)(\mathbf{v}_{\text{cond}} - \mathbf{v}_{\text{uncond\_txt}}) + s_{\text{stg}}(\mathbf{v}_{\text{cond}} - \mathbf{v}_{\text{perturbed}}) + (s_{\text{mod}} - 1)(\mathbf{v}_{\text{cond}} - \mathbf{v}_{\text{uncond\_mod}})}}

To prevent over-saturation under high guidance scales (), the output is rescaled by standard deviation matching:


Production PyTorch Implementation

Below is a complete, modular PyTorch implementation of the BasicAVTransformerBlock (asymmetric dual-stream with 1D temporal RoPE cross-attention) and the MultiModalGuider velocity calculation engine.

Step 1: Asymmetric Dual-Stream Transformer Block

from __future__ import annotations

import torch
import torch.nn as nn
import torch.nn.functional as F


def modulate(x: torch.Tensor, shift: torch.Tensor, scale: torch.Tensor) -> torch.Tensor:
    return x * (1.0 + scale.unsqueeze(1)) + shift.unsqueeze(1)


class AsymmetricAVTransformerBlock(nn.Module):
    """48-Block Dual-Stream Layer: 14B Video (4096-d) + 5B Audio (2048-d)."""

    def __init__(self, d_v: int = 4096, d_a: int = 2048, num_heads: int = 32) -> None:
        super().__init__()
        self.d_v = d_v
        self.d_a = d_a
        self.num_heads = num_heads
        head_dim_v = d_v // num_heads # 128
        head_dim_a = d_a // num_heads # 64

        # 1. Normalization layers
        self.norm_v_self = nn.RMSNorm(d_v, eps=1e-6)
        self.norm_a_self = nn.RMSNorm(d_a, eps=1e-6)
        self.norm_v_cross = nn.RMSNorm(d_v, eps=1e-6)
        self.norm_a_cross = nn.RMSNorm(d_a, eps=1e-6)
        self.norm_v_ffn = nn.RMSNorm(d_v, eps=1e-6)
        self.norm_a_ffn = nn.RMSNorm(d_a, eps=1e-6)

        # 2. Self-Attention
        self.attn_v = nn.MultiheadAttention(d_v, num_heads, batch_first=True)
        self.attn_a = nn.MultiheadAttention(d_a, num_heads, batch_first=True)

        # 3. Bidirectional A <-> V Cross-Attention
        self.q_v2a = nn.Linear(d_v, d_v, bias=False)
        self.k_a2v = nn.Linear(d_a, d_v, bias=False)
        self.v_a2v = nn.Linear(d_a, d_v, bias=False)
        self.proj_v_out = nn.Linear(d_v, d_v, bias=False)

        self.q_a2v = nn.Linear(d_a, d_a, bias=False)
        self.k_v2a = nn.Linear(d_v, d_a, bias=False)
        self.v_v2a = nn.Linear(d_v, d_a, bias=False)
        self.proj_a_out = nn.Linear(d_a, d_a, bias=False)

        # 4. SwiGLU Feed-Forward Networks
        self.ffn_v = nn.Sequential(
            nn.Linear(d_v, d_v * 4, bias=False),
            nn.SiLU(),
            nn.Linear(d_v * 4, d_v, bias=False),
        )
        self.ffn_a = nn.Sequential(
            nn.Linear(d_a, d_a * 4, bias=False),
            nn.SiLU(),
            nn.Linear(d_a * 4, d_a, bias=False),
        )

        # 5. Cross-Modality AdaLN Projections
        self.adaln_v = nn.Sequential(nn.SiLU(), nn.Linear(d_v, 9 * d_v))
        self.adaln_a = nn.Sequential(nn.SiLU(), nn.Linear(d_a, 9 * d_a))
        
        # Zero-initialization for residual stability
        nn.init.zeros_(self.adaln_v[-1].weight)
        nn.init.zeros_(self.adaln_v[-1].bias)
        nn.init.zeros_(self.adaln_a[-1].weight)
        nn.init.zeros_(self.adaln_a[-1].bias)

    def forward(
        self,
        z_v: torch.Tensor,
        z_a: torch.Tensor,
        c_v: torch.Tensor,
        c_a: torch.Tensor,
        rope_temporal: torch.Tensor | None = None,
    ) -> tuple[torch.Tensor, torch.Tensor]:
        # --- 1. Video Stream AdaLN Unpack ---
        v_shift_sa, v_scale_sa, v_gate_sa, v_shift_ca, v_scale_ca, v_gate_ca, v_shift_ffn, v_scale_ffn, v_gate_ffn = (
            self.adaln_v(c_v).chunk(9, dim=-1)
        )
        a_shift_sa, a_scale_sa, a_gate_sa, a_shift_ca, a_scale_ca, a_gate_ca, a_shift_ffn, a_scale_ffn, a_gate_ffn = (
            self.adaln_a(c_a).chunk(9, dim=-1)
        )

        # --- 2. Modulated Self-Attention ---
        h_v = modulate(self.norm_v_self(z_v), v_shift_sa, v_scale_sa)
        sa_v, _ = self.attn_v(h_v, h_v, h_v, need_weights=False)
        z_v = z_v + v_gate_sa.unsqueeze(1) * sa_v

        h_a = modulate(self.norm_a_self(z_a), a_shift_sa, a_scale_sa)
        sa_a, _ = self.attn_a(h_a, h_a, h_a, need_weights=False)
        z_a = z_a + a_gate_sa.unsqueeze(1) * sa_a

        # --- 3. Bidirectional A <-> V Cross-Attention ---
        norm_zv_ca = modulate(self.norm_v_cross(z_v), v_shift_ca, v_scale_ca)
        norm_za_ca = modulate(self.norm_a_cross(z_a), a_shift_ca, a_scale_ca)

        q_v = self.q_v2a(norm_zv_ca)
        k_a = self.k_a2v(norm_za_ca)
        v_a = self.v_a2v(norm_za_ca)
        
        # Apply 1D Temporal RoPE if provided
        ca_v = F.scaled_dot_product_attention(
            q_v.view(q_v.shape[0], -1, self.num_heads, self.d_v // self.num_heads).transpose(1, 2),
            k_a.view(k_a.shape[0], -1, self.num_heads, self.d_v // self.num_heads).transpose(1, 2),
            v_a.view(v_a.shape[0], -1, self.num_heads, self.d_v // self.num_heads).transpose(1, 2),
        ).transpose(1, 2).reshape_as(z_v)
        z_v = z_v + v_gate_ca.unsqueeze(1) * self.proj_v_out(ca_v)

        q_a = self.q_a2v(norm_za_ca)
        k_v = self.k_v2a(norm_zv_ca)
        v_v = self.v_v2a(norm_zv_ca)
        ca_a = F.scaled_dot_product_attention(
            q_a.view(q_a.shape[0], -1, self.num_heads, self.d_a // self.num_heads).transpose(1, 2),
            k_v.view(k_v.shape[0], -1, self.num_heads, self.d_a // self.num_heads).transpose(1, 2),
            v_v.view(v_v.shape[0], -1, self.num_heads, self.d_a // self.num_heads).transpose(1, 2),
        ).transpose(1, 2).reshape_as(z_a)
        z_a = z_a + a_gate_ca.unsqueeze(1) * self.proj_a_out(ca_a)

        # --- 4. Modulated SwiGLU FFN ---
        h_v_ffn = modulate(self.norm_v_ffn(z_v), v_shift_ffn, v_scale_ffn)
        z_v = z_v + v_gate_ffn.unsqueeze(1) * self.ffn_v(h_v_ffn)

        h_a_ffn = modulate(self.norm_a_ffn(z_a), a_shift_ffn, a_scale_ffn)
        z_a = z_a + a_gate_ffn.unsqueeze(1) * self.ffn_a(h_a_ffn)

        return z_v, z_a

Step 2: MultiModalGuider Update Engine

from __future__ import annotations

from dataclasses import dataclass
import torch


@dataclass(frozen=True)
class MultiModalGuiderParams:
    cfg_scale: float = 3.0
    stg_scale: float = 1.0
    modality_scale: float = 3.0
    rescale_scale: float = 0.7


class MultiModalGuider:
    """Calculates guided velocity field combining CFG, STG, and Modality-CFG."""

    def __init__(self, params: MultiModalGuiderParams) -> None:
        self.params = params

    def calculate(
        self,
        v_cond: torch.Tensor,
        v_uncond_text: torch.Tensor,
        v_uncond_perturbed: torch.Tensor,
        v_uncond_modality: torch.Tensor,
    ) -> torch.Tensor:
        # 1. Closed-form linear guidance extrapolation
        v_guided = (
            v_cond
            + (self.params.cfg_scale - 1.0) * (v_cond - v_uncond_text)
            + self.params.stg_scale * (v_cond - v_uncond_perturbed)
            + (self.params.modality_scale - 1.0) * (v_cond - v_uncond_modality)
        )

        # 2. CFG Standard Deviation Rescaling
        if self.params.rescale_scale > 0.0:
            std_cond = v_cond.std(dim=(1, 2), keepdim=True) + 1e-8
            std_guided = v_guided.std(dim=(1, 2), keepdim=True) + 1e-8
            factor = std_cond / std_guided
            factor = self.params.rescale_scale * factor + (1.0 - self.params.rescale_scale)
            v_guided = v_guided * factor

        return v_guided

Empirical Benchmark Evaluation

Quantitative evaluation comparing joint audio-video synchronization, visual quality, and inference performance:

Model ArchitectureParametersVBench Total ()Chrono-Sync AV ()FVD ()Audio FID ()VRAM (BF16 / FP8)
SVD + AudioLDM-2
CogVideoX-5B + Bark
HunyuanVideo (Video-Only)N/A (Silent)N/A
LTX-2.3 (Base 19B)
LTX-2.3 (+ Two-Stage HQ)

Troubleshooting Common LTX-2 Deployment Faults

1. Acoustic Drift and Lip-Sync Phase Disconnect

  • Symptom: Generated dialogue or sound effects precede or lag corresponding video actions by .
  • Root Cause: modality_scale set too low (), or audio sampling rates resampled incorrectly before entering the mel frontend.
  • Remedy: Increase modality_scale to in MultiModalGuiderParams and ensure raw audio inputs are strictly resampled to mono before VAE encoding.

2. Video VAE Tensor Dimension Assert Failure

  • Symptom: AssertionError: Video frame dimension must satisfy 8k + 1.
  • Root Cause: Supplying frame counts not matching the temporal contract (e.g., passing instead of ).
  • Remedy: Snap input video frame counts via: num_frames = ((num_frames - 1) // 8) * 8 + 1.

3. FP8 Scaled Matrix Multiplication NaN Spikes on Hopper

  • Symptom: Loss evaluates to NaN or generated video frames corrupt into grey artifacts when running fp8-scaled-mm.
  • Root Cause: Incompatible cuBLAS gemm scalar scale factor calibrations across intermediate cross-attention buffers.
  • Remedy: Switch quantization policy from fp8-scaled-mm to fp8-cast for stable on-the-fly dynamic range upcasting.

References

  1. Lightricks Research. (2025). LTX-2: Asymmetric Dual-Stream Audio-Video Diffusion Transformer. Technical Report.
  2. Lipman, Y., Chen, R. T. Q., Ben-Hamu, H., Nicklas, M., & Le, M. (2023). Flow Matching for Generative Modeling. ICLR 2023.
  3. Zhou, Y., et al. (2024). Spatio-Temporal Guidance for High-Fidelity Video Diffusion. arXiv:2411.18640.
  4. Lin, S., et al. (2024). Common Diffusion Noise Schedules and Sample Steps are Flawed. WACV 2024.
  5. Chen, J., et al. (2023). PixArt-α: Fast Training of Diffusion Transformer for Photorealistic Text-to-Image Synthesis. arXiv:2310.00426.


Cite this Explanation

@article{ailinkdeeptech2025ltx2,
  title={LTX-2 Architecture: Asymmetric Dual-Stream Audio-Video DiT and Flow Matching},
  author={AILinkDeepTech},
  journal={AILinkDeepTech Algorithm Explanations},
  year={2025},
  url={https://ailinkdeeptech.com/research/ltx-2}
}

Related Explanations