Skip to content
FastVideo
Esc
↑↓navigate↵open⌘Jpreview
On this page

causal_fast

LingBot World 2 causal-fast DiT implemented inside FastVideo.

fastvideo.models.dits.lingbotworld2.causal_fast.backend_name_to_enum

backend_name_to_enum(backend_name: str) -> AttentionBackendEnum | None

Convert a string backend name to a _Backend enum value.

Returns: * _Backend: enum value if backend_name is a valid in-tree type * None: otherwise it's an invalid in-tree type or an out-of-tree platform is loaded.

fastvideo.models.dits.lingbotworld2.causal_fast.get_attn_backend

get_attn_backend(head_size: int, dtype: torch.dtype, supported_attention_backends: tuple[AttentionBackendEnum, ...] | None = None, default_backend: AttentionBackendEnum | None = None, *, requested: AttentionBackendEnum | None | _NoRequest = NO_REQUEST) -> type[AttentionBackend]

Resolve the attention backend class for one call site.

requested is the decision made for the component this call site belongs to — read from ModelConfig._resolved_attention_backend. Passing it means the caller knows the answer, so nothing ambient is consulted:

  • requested=SOME_BACKEND — use it (subject to the layer's declared support), ignoring the construction scope and the environment;
  • requested=None — that component resolved to automatic selection. That is an answer, not an absence, so the environment is not consulted behind it;
  • requested omitted (NO_REQUEST) — the caller has no opinion; fall back to the construction scope, then the environment. This is the path every layer built inside a loader still takes.

fastvideo.models.dits.lingbotworld2.causal_fast.LingBotWorld2CausalFastVideoConfig

LingBotWorld2CausalFastVideoConfig(arch_config: DiTArchConfig = LingBotWorld2CausalFastArchConfig(), prefix: str = 'Wan', quant_config: QuantizationConfig | None = None, *, _resolved_attention_backend: AttentionBackendEnum | None = None)

fastvideo.models.dits.lingbotworld2.causal_fast.sequence_model_parallel_all_gather

sequence_model_parallel_all_gather(input_: torch.Tensor, dim: int = -1) -> torch.Tensor

All-gather the input tensor across model parallel group.

fastvideo.models.dits.lingbotworld2.causal_fast.sequence_model_parallel_all_to_all_4D

sequence_model_parallel_all_to_all_4D(input_: torch.Tensor, scatter_dim: int = 2, gather_dim: int = 1) -> torch.Tensor

All-to-all communication of 4D tensors (e.g. QKV matrices) across sequence parallel group.

fastvideo.models.dits.lingbotworld2.causal_fast.get_sp_parallel_rank

get_sp_parallel_rank() -> int

Return my rank for the sequence model parallel group.

fastvideo.models.dits.lingbotworld2.causal_fast.get_sp_world_size

get_sp_world_size() -> int

Return world size for the sequence model parallel group.

fastvideo.models.dits.lingbotworld2.causal_fast.BaseDiT

BaseDiT(config: DiTConfig, hf_config: dict[str, Any], **kwargs)

fastvideo.models.dits.lingbotworld2.causal_fast.BaseDiT.forward

forward(hidden_states: torch.Tensor, encoder_hidden_states: torch.Tensor | list[torch.Tensor], timestep: torch.LongTensor, encoder_hidden_states_image: torch.Tensor | list[torch.Tensor] | None = None, guidance = None, **kwargs) -> torch.Tensor

fastvideo.models.dits.lingbotworld2.causal_fast.BaseDiT.preprocess_loaded_weight

preprocess_loaded_weight(name: str, tensor: torch.Tensor) -> torch.Tensor

Adapt a checkpoint tensor before sharding; default models are unchanged.

fastvideo.models.dits.lingbotworld2.causal_fast.BaseDiT.inference_config_overrides

inference_config_overrides() -> dict[str, Any]

Extra config.json keys a deployable checkpoint of this model needs.

fastvideo.models.dits.lingbotworld2.causal_fast.BaseDiT.inference_export_expected_shape

inference_export_expected_shape(output_key: str, base_shape: tuple[int, ...]) -> tuple[int, ...]

The exported shape of output_key given the base checkpoint's shape.

fastvideo.models.dits.lingbotworld2.causal_fast.AttentionBackendEnum

AttentionBackendEnum()

fastvideo.models.dits.lingbotworld2.causal_fast.get_compute_dtype

get_compute_dtype() -> torch.dtype

Get the current compute dtype from mixed precision policy.

Returns

torch.dtype

torch.dtype: The compute dtype to use, defaults to get_default_dtype() if no policy set

fastvideo.models.dits.lingbotworld2.causal_fast.is_blocks

is_blocks(n: str, m) -> bool
Source
def is_blocks(n: str, m) -> bool:
    return "blocks" in n and str.isdigit(n.split(".")[-1])

fastvideo.models.dits.lingbotworld2.causal_fast.sinusoidal_embedding_1d

sinusoidal_embedding_1d(dim: int, position: torch.Tensor) -> torch.Tensor

Build Wan/LingBot World 2 sinusoidal timestep embeddings.

Source
def sinusoidal_embedding_1d(dim: int, position: torch.Tensor) -> torch.Tensor:
    """Build Wan/LingBot World 2 sinusoidal timestep embeddings."""
    assert dim % 2 == 0
    half = dim // 2
    position = position.type(torch.float64)
    sinusoid = torch.outer(
        position,
        torch.pow(10000, -torch.arange(half, device=position.device).to(position).div(half)),
    )
    return torch.cat([torch.cos(sinusoid), torch.sin(sinusoid)], dim=1)

fastvideo.models.dits.lingbotworld2.causal_fast.rope_params

rope_params(max_seq_len: int, dim: int, theta: int = 10000) -> torch.Tensor

Return complex RoPE frequencies used by the released LingBot World 2 model.

Source
@torch.amp.autocast("cuda", enabled=False)
def rope_params(max_seq_len: int, dim: int, theta: int = 10000) -> torch.Tensor:
    """Return complex RoPE frequencies used by the released LingBot World 2 model."""
    assert dim % 2 == 0
    freqs = torch.outer(
        torch.arange(max_seq_len),
        1.0 / torch.pow(theta,
                        torch.arange(0, dim, 2).to(torch.float64).div(dim)),
    )
    return torch.polar(torch.ones_like(freqs), freqs)

fastvideo.models.dits.lingbotworld2.causal_fast.flash_attention

flash_attention(q: torch.Tensor, k: torch.Tensor, v: torch.Tensor, q_lens: torch.Tensor | None = None, k_lens: torch.Tensor | None = None, dropout_p: float = 0.0, softmax_scale: float | None = None, q_scale: float | None = None, causal: bool = False, window_size: tuple[int, int] = (-1, -1), deterministic: bool = False, dtype: torch.dtype = torch.bfloat16, version: int | None = None) -> torch.Tensor

Run LingBot World 2-compatible FlashAttention on packed varlen inputs.

Source
def flash_attention(
    q: torch.Tensor,
    k: torch.Tensor,
    v: torch.Tensor,
    q_lens: torch.Tensor | None = None,
    k_lens: torch.Tensor | None = None,
    dropout_p: float = 0.0,
    softmax_scale: float | None = None,
    q_scale: float | None = None,
    causal: bool = False,
    window_size: tuple[int, int] = (-1, -1),
    deterministic: bool = False,
    dtype: torch.dtype = torch.bfloat16,
    version: int | None = None,
) -> torch.Tensor:
    """Run LingBot World 2-compatible FlashAttention on packed varlen inputs."""
    half_dtypes = (torch.float16, torch.bfloat16)
    assert dtype in half_dtypes
    assert q.device.type == "cuda" and q.size(-1) <= 256
b, lq, lk, out_dtype = q.size(0), q.size(1), k.size(1), q.dtype

def half(x: torch.Tensor) -&gt; torch.Tensor:
    return x if x.dtype in half_dtypes else x.to(dtype)

if q_lens is None:
    q = half(q.flatten(0, 1))
    q_lens = torch.tensor(&#91;lq&#93; * b, dtype=torch.int32, device=q.device)
else:
    q = half(torch.cat(&#91;u&#91;:v&#93; for u, v in zip(q, q_lens, strict=True)&#93;))

if k_lens is None:
    k = half(k.flatten(0, 1))
    v = half(v.flatten(0, 1))
    k_lens = torch.tensor(&#91;lk&#93; * b, dtype=torch.int32, device=k.device)
else:
    k = half(torch.cat(&#91;u&#91;:v&#93; for u, v in zip(k, k_lens, strict=True)&#93;))
    v = half(torch.cat(&#91;u&#91;:v&#93; for u, v in zip(v, k_lens, strict=True)&#93;))

q = q.to(v.dtype)
k = k.to(v.dtype)
if q_scale is not None:
    q = q * q_scale

if version == 3 and not FLASH_ATTN_3_AVAILABLE:
    warnings.warn(&quot;FlashAttention 3 is not available; using FlashAttention 2.&quot;)

cu_q = torch.cat(&#91;q_lens.new_zeros(&#91;1&#93;), q_lens&#93;).cumsum(0, dtype=torch.int32).to(q.device, non_blocking=True)
cu_k = torch.cat(&#91;k_lens.new_zeros(&#91;1&#93;), k_lens&#93;).cumsum(0, dtype=torch.int32).to(k.device, non_blocking=True)

if (version is None or version == 3) and FLASH_ATTN_3_AVAILABLE:
    x = flash_attn_interface.flash_attn_varlen_func(
        q=q,
        k=k,
        v=v,
        cu_seqlens_q=cu_q,
        cu_seqlens_k=cu_k,
        seqused_q=None,
        seqused_k=None,
        max_seqlen_q=lq,
        max_seqlen_k=lk,
        softmax_scale=softmax_scale,
        causal=causal,
        deterministic=deterministic,
    ).unflatten(0, (b, lq))
else:
    assert FLASH_ATTN_2_AVAILABLE
    x = flash_attn.flash_attn_varlen_func(
        q=q,
        k=k,
        v=v,
        cu_seqlens_q=cu_q,
        cu_seqlens_k=cu_k,
        max_seqlen_q=lq,
        max_seqlen_k=lk,
        dropout_p=dropout_p,
        softmax_scale=softmax_scale,
        causal=causal,
        window_size=window_size,
        deterministic=deterministic,
    ).unflatten(0, (b, lq))
return x.type(out_dtype)</code></pre></details>

fastvideo.models.dits.lingbotworld2.causal_fast.attention

attention(q: torch.Tensor, k: torch.Tensor, v: torch.Tensor, backend: AttentionBackendEnum, q_lens: torch.Tensor | None = None, k_lens: torch.Tensor | None = None, dropout_p: float = 0.0, softmax_scale: float | None = None, q_scale: float | None = None, causal: bool = False, window_size: tuple[int, int] = (-1, -1), deterministic: bool = False, dtype: torch.dtype = torch.bfloat16, fa_version: int | None = None) -> torch.Tensor

Dispatch LingBot World 2 attention through the selected backend.

Source
def attention(
    q: torch.Tensor,
    k: torch.Tensor,
    v: torch.Tensor,
    backend: AttentionBackendEnum,
    q_lens: torch.Tensor | None = None,
    k_lens: torch.Tensor | None = None,
    dropout_p: float = 0.0,
    softmax_scale: float | None = None,
    q_scale: float | None = None,
    causal: bool = False,
    window_size: tuple[int, int] = (-1, -1),
    deterministic: bool = False,
    dtype: torch.dtype = torch.bfloat16,
    fa_version: int | None = None,
) -> torch.Tensor:
    """Dispatch LingBot World 2 attention through the selected backend."""
    if backend == AttentionBackendEnum.FLASH_ATTN:
        return flash_attention(
            q=q,
            k=k,
            v=v,
            q_lens=q_lens,
            k_lens=k_lens,
            dropout_p=dropout_p,
            softmax_scale=softmax_scale,
            q_scale=q_scale,
            causal=causal,
            window_size=window_size,
            deterministic=deterministic,
            dtype=dtype,
            version=fa_version,
        )
assert backend == AttentionBackendEnum.TORCH_SDPA
if q_lens is not None or k_lens is not None:
    warnings.warn(&quot;Padding masks are disabled without FlashAttention.&quot;)
q = q.transpose(1, 2).to(dtype)
k = k.transpose(1, 2).to(dtype)
v = v.transpose(1, 2).to(dtype)
out = F.scaled_dot_product_attention(q, k, v, attn_mask=None, is_causal=causal, dropout_p=dropout_p)
return out.transpose(1, 2).contiguous()</code></pre></details>

fastvideo.models.dits.lingbotworld2.causal_fast.causal_rope_apply

causal_rope_apply(x: torch.Tensor, grid_sizes: torch.Tensor, freqs: torch.Tensor, start_frame: int = 0) -> torch.Tensor

Apply LingBot World 2 causal RoPE with the current chunk frame offset.

Source
@torch.amp.autocast("cuda", enabled=False)
def causal_rope_apply(
    x: torch.Tensor,
    grid_sizes: torch.Tensor,
    freqs: torch.Tensor,
    start_frame: int = 0,
) -> torch.Tensor:
    """Apply LingBot World 2 causal RoPE with the current chunk frame offset."""
    n, c = x.size(2), x.size(3) // 2
    freqs = freqs.split([c - 2 * (c // 3), c // 3, c // 3], dim=1)
    output = []
    for i, (f, h, w) in enumerate(grid_sizes.tolist()):
        seq_len = f * h * w
        x_i = torch.view_as_complex(x[i, :seq_len].to(torch.float64).reshape(seq_len, n, -1, 2))
        freqs_i = torch.cat(
            [
                freqs[0][start_frame:start_frame + f].view(f, 1, 1, -1).expand(f, h, w, -1),
                freqs[1][:h].view(1, h, 1, -1).expand(f, h, w, -1),
                freqs[2][:w].view(1, 1, w, -1).expand(f, h, w, -1),
            ],
            dim=-1,
        ).reshape(seq_len, 1, -1)
        x_i = torch.view_as_real(x_i * freqs_i).flatten(2)
        x_i = torch.cat([x_i, x[i, seq_len:]])
        output.append(x_i)
    return torch.stack(output).type_as(x)

fastvideo.models.dits.lingbotworld2.causal_fast.WanRMSNorm

WanRMSNorm(dim: int, eps: float = 1e-05)

RMSNorm used by Wan/LingBot World 2 attention projections.

Source
class WanRMSNorm(nn.Module):
    """RMSNorm used by Wan/LingBot World 2 attention projections."""
def __init__(self, dim: int, eps: float = 1e-5):
    super().__init__()
    self.dim = dim
    self.eps = eps
    self.weight = nn.Parameter(torch.ones(dim))

def forward(self, x: torch.Tensor) -&gt; torch.Tensor:
    &quot;&quot;&quot;Normalize the last dimension in fp32 and restore input dtype.&quot;&quot;&quot;
    return self._norm(x.float()).type_as(x) * self.weight

def _norm(self, x: torch.Tensor) -&gt; torch.Tensor:
    return x * torch.rsqrt(x.pow(2).mean(dim=-1, keepdim=True) + self.eps)</code></pre></details>

fastvideo.models.dits.lingbotworld2.causal_fast.WanRMSNorm.forward

forward(x: torch.Tensor) -> torch.Tensor

Normalize the last dimension in fp32 and restore input dtype.

Source
def forward(self, x: torch.Tensor) -> torch.Tensor:
    """Normalize the last dimension in fp32 and restore input dtype."""
    return self._norm(x.float()).type_as(x) * self.weight

fastvideo.models.dits.lingbotworld2.causal_fast.WanLayerNorm

WanLayerNorm(dim: int, eps: float = 1e-06, elementwise_affine: bool = False)

LayerNorm variant that computes in fp32 and returns the input dtype.

Source
class WanLayerNorm(nn.LayerNorm):
    """LayerNorm variant that computes in fp32 and returns the input dtype."""
def __init__(self, dim: int, eps: float = 1e-6, elementwise_affine: bool = False):
    super().__init__(dim, elementwise_affine=elementwise_affine, eps=eps)

def forward(self, x: torch.Tensor) -&gt; torch.Tensor:
    &quot;&quot;&quot;Apply layer norm in fp32 for LingBot World 2 numerical parity.&quot;&quot;&quot;
    return super().forward(x.float()).type_as(x)</code></pre></details>

fastvideo.models.dits.lingbotworld2.causal_fast.WanLayerNorm.forward

forward(x: torch.Tensor) -> torch.Tensor

Apply layer norm in fp32 for LingBot World 2 numerical parity.

Source
def forward(self, x: torch.Tensor) -> torch.Tensor:
    """Apply layer norm in fp32 for LingBot World 2 numerical parity."""
    return super().forward(x.float()).type_as(x)

fastvideo.models.dits.lingbotworld2.causal_fast.CausalWanSelfAttention

CausalWanSelfAttention(dim: int, num_heads: int, local_attn_size: int = -1, sink_size: int = 0, qk_norm: bool = True, eps: float = 1e-06)

LingBot World 2 causal self-attention with rolling KV cache.

Source
class CausalWanSelfAttention(nn.Module):
    """LingBot World 2 causal self-attention with rolling KV cache."""
def __init__(
    self,
    dim: int,
    num_heads: int,
    local_attn_size: int = -1,
    sink_size: int = 0,
    qk_norm: bool = True,
    eps: float = 1e-6,
):
    super().__init__()
    assert dim % num_heads == 0
    self.dim = dim
    self.num_heads = num_heads
    self.head_dim = dim // num_heads
    attn_backend = get_attn_backend(
        self.head_dim,
        get_compute_dtype(),
        supported_attention_backends=(AttentionBackendEnum.FLASH_ATTN, AttentionBackendEnum.TORCH_SDPA),
    )
    backend_name = attn_backend.get_name()
    self.backend = backend_name_to_enum(backend_name)
    assert self.backend is not None, f&quot;Unsupported attention backend: &#123;backend_name&#125;&quot;
    self.local_attn_size = local_attn_size
    self.sink_size = sink_size
    self.qk_norm = qk_norm
    self.eps = eps
    self.q = nn.Linear(dim, dim)
    self.k = nn.Linear(dim, dim)
    self.v = nn.Linear(dim, dim)
    self.o = nn.Linear(dim, dim)
    self.norm_q = WanRMSNorm(dim, eps=eps) if qk_norm else nn.Identity()
    self.norm_k = WanRMSNorm(dim, eps=eps) if qk_norm else nn.Identity()

def forward(
    self,
    x: torch.Tensor,
    seq_lens: torch.Tensor,
    grid_sizes: torch.Tensor,
    freqs: torch.Tensor,
    kv_cache: dict,
    current_start: int = 0,
    max_attention_size: int = 1_000_000,
    frame_seqlen: int | None = None,
    seq_lens_int: int | None = None,
) -&gt; torch.Tensor:
    &quot;&quot;&quot;Project QKV, update the rolling cache, and attend to its active window.&quot;&quot;&quot;
    b, s, n, d = *x.shape&#91;:2&#93;, self.num_heads, self.head_dim
    q = self.norm_q(self.q(x)).view(b, s, n, d)
    k = self.norm_k(self.k(x)).view(b, s, n, d)
    v = self.v(x).view(b, s, n, d)

    if frame_seqlen is None:
        frame_seqlen = math.prod(grid_sizes&#91;0&#93;&#91;1:&#93;).item()
    current_start_frame = current_start // frame_seqlen
    if seq_lens_int is None:
        seq_lens_int = int(seq_lens&#91;0&#93;.item() if seq_lens.dim() &gt; 0 else seq_lens.item())

    sp_size = get_sp_world_size()
    if sp_size &gt; 1:
        q = sequence_model_parallel_all_to_all_4D(q, scatter_dim=2, gather_dim=1)
        k = sequence_model_parallel_all_to_all_4D(k, scatter_dim=2, gather_dim=1)
        v = sequence_model_parallel_all_to_all_4D(v, scatter_dim=2, gather_dim=1)
        padded_seq_len = s * sp_size
        roped_query = causal_rope_apply(q, grid_sizes, freqs, start_frame=current_start_frame).type_as(v)
        roped_key = causal_rope_apply(k, grid_sizes, freqs, start_frame=current_start_frame).type_as(v)
        roped_query = roped_query&#91;:, :seq_lens_int&#93;
        roped_key = roped_key&#91;:, :seq_lens_int&#93;
        v = v&#91;:, :seq_lens_int&#93;
        num_new_tokens = seq_lens_int
    else:
        padded_seq_len = s
        roped_query = causal_rope_apply(q, grid_sizes, freqs, start_frame=current_start_frame).type_as(v)
        roped_key = causal_rope_apply(k, grid_sizes, freqs, start_frame=current_start_frame).type_as(v)
        num_new_tokens = roped_query.shape&#91;1&#93;

    current_end = current_start + num_new_tokens
    sink_tokens = self.sink_size * frame_seqlen
    kv_cache_size = kv_cache&#91;&quot;k&quot;&#93;.shape&#91;1&#93;

    if self.local_attn_size == -1:
        local_end_index = current_start + num_new_tokens
        local_start_index = current_start
        kv_cache&#91;&quot;k&quot;&#93;&#91;:, local_start_index:local_end_index&#93; = roped_key
        kv_cache&#91;&quot;v&quot;&#93;&#91;:, local_start_index:local_end_index&#93; = v
    elif (current_end
          &gt; kv_cache&#91;&quot;global_end_index&quot;&#93;.item()) and (num_new_tokens + kv_cache&#91;&quot;local_end_index&quot;&#93;.item()
                                                      &gt; kv_cache_size):
        num_evicted_tokens = num_new_tokens + kv_cache&#91;&quot;local_end_index&quot;&#93;.item() - kv_cache_size
        num_rolled_tokens = kv_cache&#91;&quot;local_end_index&quot;&#93;.item() - num_evicted_tokens - sink_tokens
        kv_cache&#91;&quot;k&quot;&#93;&#91;:, sink_tokens:sink_tokens +
                      num_rolled_tokens&#93; = kv_cache&#91;&quot;k&quot;&#93;&#91;:, sink_tokens + num_evicted_tokens:sink_tokens +
                                                         num_evicted_tokens + num_rolled_tokens&#93;.clone()
        kv_cache&#91;&quot;v&quot;&#93;&#91;:, sink_tokens:sink_tokens +
                      num_rolled_tokens&#93; = kv_cache&#91;&quot;v&quot;&#93;&#91;:, sink_tokens + num_evicted_tokens:sink_tokens +
                                                         num_evicted_tokens + num_rolled_tokens&#93;.clone()
        local_end_index = kv_cache&#91;&quot;local_end_index&quot;&#93;.item() + current_end - kv_cache&#91;&quot;global_end_index&quot;&#93;.item(
        ) - num_evicted_tokens
        local_start_index = local_end_index - num_new_tokens
        kv_cache&#91;&quot;k&quot;&#93;&#91;:, local_start_index:local_end_index&#93; = roped_key
        kv_cache&#91;&quot;v&quot;&#93;&#91;:, local_start_index:local_end_index&#93; = v
    else:
        local_end_index = kv_cache&#91;&quot;local_end_index&quot;&#93;.item() + current_end - kv_cache&#91;&quot;global_end_index&quot;&#93;.item()
        local_start_index = local_end_index - num_new_tokens
        kv_cache&#91;&quot;k&quot;&#93;&#91;:, local_start_index:local_end_index&#93; = roped_key
        kv_cache&#91;&quot;v&quot;&#93;&#91;:, local_start_index:local_end_index&#93; = v

    k_cache = kv_cache&#91;&quot;k&quot;&#93;&#91;:, max(0, local_end_index - max_attention_size):local_end_index&#93;
    v_cache = kv_cache&#91;&quot;v&quot;&#93;&#91;:, max(0, local_end_index - max_attention_size):local_end_index&#93;
    x = attention(roped_query, k_cache, v_cache, self.backend)
    kv_cache&#91;&quot;global_end_index&quot;&#93;.fill_(current_end)
    kv_cache&#91;&quot;local_end_index&quot;&#93;.fill_(local_end_index)

    if sp_size &gt; 1:
        sp_pad = padded_seq_len - seq_lens_int
        if sp_pad &gt; 0:
            x = torch.cat(&#91;x, x.new_zeros(b, sp_pad, x.size(2), d)&#93;, dim=1)
        x = sequence_model_parallel_all_to_all_4D(x, scatter_dim=1, gather_dim=2)
    return self.o(x.flatten(2))</code></pre></details>

fastvideo.models.dits.lingbotworld2.causal_fast.CausalWanSelfAttention.forward

forward(x: torch.Tensor, seq_lens: torch.Tensor, grid_sizes: torch.Tensor, freqs: torch.Tensor, kv_cache: dict, current_start: int = 0, max_attention_size: int = 1000000, frame_seqlen: int | None = None, seq_lens_int: int | None = None) -> torch.Tensor

Project QKV, update the rolling cache, and attend to its active window.

Source
def forward(
    self,
    x: torch.Tensor,
    seq_lens: torch.Tensor,
    grid_sizes: torch.Tensor,
    freqs: torch.Tensor,
    kv_cache: dict,
    current_start: int = 0,
    max_attention_size: int = 1_000_000,
    frame_seqlen: int | None = None,
    seq_lens_int: int | None = None,
) -> torch.Tensor:
    """Project QKV, update the rolling cache, and attend to its active window."""
    b, s, n, d = *x.shape[:2], self.num_heads, self.head_dim
    q = self.norm_q(self.q(x)).view(b, s, n, d)
    k = self.norm_k(self.k(x)).view(b, s, n, d)
    v = self.v(x).view(b, s, n, d)
if frame_seqlen is None:
    frame_seqlen = math.prod(grid_sizes&#91;0&#93;&#91;1:&#93;).item()
current_start_frame = current_start // frame_seqlen
if seq_lens_int is None:
    seq_lens_int = int(seq_lens&#91;0&#93;.item() if seq_lens.dim() &gt; 0 else seq_lens.item())

sp_size = get_sp_world_size()
if sp_size &gt; 1:
    q = sequence_model_parallel_all_to_all_4D(q, scatter_dim=2, gather_dim=1)
    k = sequence_model_parallel_all_to_all_4D(k, scatter_dim=2, gather_dim=1)
    v = sequence_model_parallel_all_to_all_4D(v, scatter_dim=2, gather_dim=1)
    padded_seq_len = s * sp_size
    roped_query = causal_rope_apply(q, grid_sizes, freqs, start_frame=current_start_frame).type_as(v)
    roped_key = causal_rope_apply(k, grid_sizes, freqs, start_frame=current_start_frame).type_as(v)
    roped_query = roped_query&#91;:, :seq_lens_int&#93;
    roped_key = roped_key&#91;:, :seq_lens_int&#93;
    v = v&#91;:, :seq_lens_int&#93;
    num_new_tokens = seq_lens_int
else:
    padded_seq_len = s
    roped_query = causal_rope_apply(q, grid_sizes, freqs, start_frame=current_start_frame).type_as(v)
    roped_key = causal_rope_apply(k, grid_sizes, freqs, start_frame=current_start_frame).type_as(v)
    num_new_tokens = roped_query.shape&#91;1&#93;

current_end = current_start + num_new_tokens
sink_tokens = self.sink_size * frame_seqlen
kv_cache_size = kv_cache&#91;&quot;k&quot;&#93;.shape&#91;1&#93;

if self.local_attn_size == -1:
    local_end_index = current_start + num_new_tokens
    local_start_index = current_start
    kv_cache&#91;&quot;k&quot;&#93;&#91;:, local_start_index:local_end_index&#93; = roped_key
    kv_cache&#91;&quot;v&quot;&#93;&#91;:, local_start_index:local_end_index&#93; = v
elif (current_end
      &gt; kv_cache&#91;&quot;global_end_index&quot;&#93;.item()) and (num_new_tokens + kv_cache&#91;&quot;local_end_index&quot;&#93;.item()
                                                  &gt; kv_cache_size):
    num_evicted_tokens = num_new_tokens + kv_cache&#91;&quot;local_end_index&quot;&#93;.item() - kv_cache_size
    num_rolled_tokens = kv_cache&#91;&quot;local_end_index&quot;&#93;.item() - num_evicted_tokens - sink_tokens
    kv_cache&#91;&quot;k&quot;&#93;&#91;:, sink_tokens:sink_tokens +
                  num_rolled_tokens&#93; = kv_cache&#91;&quot;k&quot;&#93;&#91;:, sink_tokens + num_evicted_tokens:sink_tokens +
                                                     num_evicted_tokens + num_rolled_tokens&#93;.clone()
    kv_cache&#91;&quot;v&quot;&#93;&#91;:, sink_tokens:sink_tokens +
                  num_rolled_tokens&#93; = kv_cache&#91;&quot;v&quot;&#93;&#91;:, sink_tokens + num_evicted_tokens:sink_tokens +
                                                     num_evicted_tokens + num_rolled_tokens&#93;.clone()
    local_end_index = kv_cache&#91;&quot;local_end_index&quot;&#93;.item() + current_end - kv_cache&#91;&quot;global_end_index&quot;&#93;.item(
    ) - num_evicted_tokens
    local_start_index = local_end_index - num_new_tokens
    kv_cache&#91;&quot;k&quot;&#93;&#91;:, local_start_index:local_end_index&#93; = roped_key
    kv_cache&#91;&quot;v&quot;&#93;&#91;:, local_start_index:local_end_index&#93; = v
else:
    local_end_index = kv_cache&#91;&quot;local_end_index&quot;&#93;.item() + current_end - kv_cache&#91;&quot;global_end_index&quot;&#93;.item()
    local_start_index = local_end_index - num_new_tokens
    kv_cache&#91;&quot;k&quot;&#93;&#91;:, local_start_index:local_end_index&#93; = roped_key
    kv_cache&#91;&quot;v&quot;&#93;&#91;:, local_start_index:local_end_index&#93; = v

k_cache = kv_cache&#91;&quot;k&quot;&#93;&#91;:, max(0, local_end_index - max_attention_size):local_end_index&#93;
v_cache = kv_cache&#91;&quot;v&quot;&#93;&#91;:, max(0, local_end_index - max_attention_size):local_end_index&#93;
x = attention(roped_query, k_cache, v_cache, self.backend)
kv_cache&#91;&quot;global_end_index&quot;&#93;.fill_(current_end)
kv_cache&#91;&quot;local_end_index&quot;&#93;.fill_(local_end_index)

if sp_size &gt; 1:
    sp_pad = padded_seq_len - seq_lens_int
    if sp_pad &gt; 0:
        x = torch.cat(&#91;x, x.new_zeros(b, sp_pad, x.size(2), d)&#93;, dim=1)
    x = sequence_model_parallel_all_to_all_4D(x, scatter_dim=1, gather_dim=2)
return self.o(x.flatten(2))</code></pre></details>

fastvideo.models.dits.lingbotworld2.causal_fast.WanCrossAttention

WanCrossAttention(dim: int, num_heads: int, local_attn_size: int = -1, sink_size: int = 0, qk_norm: bool = True, eps: float = 1e-06)

LingBot World 2 cross-attention with reusable text K/V cache.

Source
class WanCrossAttention(CausalWanSelfAttention):
    """LingBot World 2 cross-attention with reusable text K/V cache."""
def forward(
    self,
    x: torch.Tensor,
    context: torch.Tensor,
    context_lens: torch.Tensor | None,
    crossattn_cache: dict | None = None,
    cross_attn_first_call: bool | None = None,
) -&gt; torch.Tensor:
    &quot;&quot;&quot;Attend hidden states to text context, populating cache on first use.&quot;&quot;&quot;
    b, n, d = x.size(0), self.num_heads, self.head_dim
    q = self.norm_q(self.q(x)).view(b, -1, n, d)
    if crossattn_cache is not None:
        is_first = crossattn_cache&#91;&quot;is_init&quot;&#93;.item(
        ) == 0 if cross_attn_first_call is None else cross_attn_first_call
        if is_first:
            crossattn_cache&#91;&quot;is_init&quot;&#93;.fill_(1)
            k = self.norm_k(self.k(context)).view(b, -1, n, d)
            v = self.v(context).view(b, -1, n, d)
            crossattn_cache&#91;&quot;k&quot;&#93;.copy_(k)
            crossattn_cache&#91;&quot;v&quot;&#93;.copy_(v)
        else:
            k = crossattn_cache&#91;&quot;k&quot;&#93;
            v = crossattn_cache&#91;&quot;v&quot;&#93;
    else:
        k = self.norm_k(self.k(context)).view(b, -1, n, d)
        v = self.v(context).view(b, -1, n, d)
    # Dispatch through `attention` so the TORCH_SDPA backend this model
    # advertises actually works; self-attention already does the same. The
    # SDPA path ignores `k_lens`, which is safe here because the caller
    # always passes `context_lens=None`.
    x = attention(q, k, v, self.backend, k_lens=context_lens)
    return self.o(x.flatten(2))</code></pre></details>

fastvideo.models.dits.lingbotworld2.causal_fast.WanCrossAttention.forward

forward(x: torch.Tensor, context: torch.Tensor, context_lens: torch.Tensor | None, crossattn_cache: dict | None = None, cross_attn_first_call: bool | None = None) -> torch.Tensor

Attend hidden states to text context, populating cache on first use.

Source
def forward(
    self,
    x: torch.Tensor,
    context: torch.Tensor,
    context_lens: torch.Tensor | None,
    crossattn_cache: dict | None = None,
    cross_attn_first_call: bool | None = None,
) -> torch.Tensor:
    """Attend hidden states to text context, populating cache on first use."""
    b, n, d = x.size(0), self.num_heads, self.head_dim
    q = self.norm_q(self.q(x)).view(b, -1, n, d)
    if crossattn_cache is not None:
        is_first = crossattn_cache["is_init"].item(
        ) == 0 if cross_attn_first_call is None else cross_attn_first_call
        if is_first:
            crossattn_cache["is_init"].fill_(1)
            k = self.norm_k(self.k(context)).view(b, -1, n, d)
            v = self.v(context).view(b, -1, n, d)
            crossattn_cache["k"].copy_(k)
            crossattn_cache["v"].copy_(v)
        else:
            k = crossattn_cache["k"]
            v = crossattn_cache["v"]
    else:
        k = self.norm_k(self.k(context)).view(b, -1, n, d)
        v = self.v(context).view(b, -1, n, d)
    # Dispatch through `attention` so the TORCH_SDPA backend this model
    # advertises actually works; self-attention already does the same. The
    # SDPA path ignores `k_lens`, which is safe here because the caller
    # always passes `context_lens=None`.
    x = attention(q, k, v, self.backend, k_lens=context_lens)
    return self.o(x.flatten(2))

fastvideo.models.dits.lingbotworld2.causal_fast.CausalWanAttentionBlock

CausalWanAttentionBlock(dim: int, ffn_dim: int, num_heads: int, local_attn_size: int = -1, sink_size: int = 0, qk_norm: bool = True, cross_attn_norm: bool = False, eps: float = 1e-06)

One LingBot World 2 causal transformer block including camera injection.

Source
class CausalWanAttentionBlock(nn.Module):
    """One LingBot World 2 causal transformer block including camera injection."""
def __init__(
    self,
    dim: int,
    ffn_dim: int,
    num_heads: int,
    local_attn_size: int = -1,
    sink_size: int = 0,
    qk_norm: bool = True,
    cross_attn_norm: bool = False,
    eps: float = 1e-6,
):
    super().__init__()
    self.dim = dim
    self.ffn_dim = ffn_dim
    self.num_heads = num_heads
    self.local_attn_size = local_attn_size
    self.qk_norm = qk_norm
    self.cross_attn_norm = cross_attn_norm
    self.eps = eps
    self.norm1 = WanLayerNorm(dim, eps)
    self.self_attn = CausalWanSelfAttention(dim, num_heads, local_attn_size, sink_size, qk_norm, eps)
    self.norm3 = WanLayerNorm(dim, eps, elementwise_affine=True) if cross_attn_norm else nn.Identity()
    self.cross_attn = WanCrossAttention(dim, num_heads, qk_norm=qk_norm, eps=eps)
    self.norm2 = WanLayerNorm(dim, eps)
    self.ffn = nn.Sequential(nn.Linear(dim, ffn_dim), nn.GELU(approximate=&quot;tanh&quot;), nn.Linear(ffn_dim, dim))
    self.modulation = nn.Parameter(torch.randn(1, 6, dim) / dim**0.5)
    self.cam_injector_layer1 = nn.Linear(dim, dim)
    self.cam_injector_layer2 = nn.Linear(dim, dim)
    self.cam_scale_layer = nn.Linear(dim, dim)
    self.cam_shift_layer = nn.Linear(dim, dim)

def forward(
    self,
    x: torch.Tensor,
    e: torch.Tensor,
    seq_lens: torch.Tensor,
    grid_sizes: torch.Tensor,
    freqs: torch.Tensor,
    context: torch.Tensor,
    context_lens: torch.Tensor | None,
    dit_cond_dict: dict&#91;str, Any&#93; | None = None,
    kv_cache: dict | None = None,
    crossattn_cache: dict | None = None,
    current_start: int = 0,
    max_attention_size: int = 1_000_000,
    frame_seqlen: int | None = None,
    cross_attn_first_call: bool | None = None,
    seq_lens_int: int | None = None,
) -&gt; torch.Tensor:
    &quot;&quot;&quot;Apply self-attention, camera modulation, cross-attention, and FFN.&quot;&quot;&quot;
    assert kv_cache is not None
    assert e.dtype == torch.float32
    with torch.amp.autocast(&quot;cuda&quot;, dtype=torch.float32):
        e = (self.modulation.unsqueeze(0) + e).chunk(6, dim=2)

    y = self.self_attn(
        self.norm1(x).float() * (1 + e&#91;1&#93;.squeeze(2)) + e&#91;0&#93;.squeeze(2),
        seq_lens,
        grid_sizes,
        freqs,
        kv_cache,
        current_start,
        max_attention_size,
        frame_seqlen=frame_seqlen,
        seq_lens_int=seq_lens_int,
    )
    with torch.amp.autocast(&quot;cuda&quot;, dtype=torch.float32):
        x = x + y * e&#91;2&#93;.squeeze(2)

    if dit_cond_dict is not None and &quot;c2ws_plucker_emb&quot; in dit_cond_dict:
        c2ws_plucker_emb = dit_cond_dict&#91;&quot;c2ws_plucker_emb&quot;&#93;
        c2ws_hidden_states = self.cam_injector_layer2(F.silu(self.cam_injector_layer1(c2ws_plucker_emb)))
        c2ws_hidden_states = c2ws_hidden_states + c2ws_plucker_emb
        x = (1.0 + self.cam_scale_layer(c2ws_hidden_states)) * x + self.cam_shift_layer(c2ws_hidden_states)

    x = x + self.cross_attn(
        self.norm3(x),
        context,
        context_lens,
        crossattn_cache=crossattn_cache,
        cross_attn_first_call=cross_attn_first_call,
    )
    y = self.ffn(self.norm2(x).float() * (1 + e&#91;4&#93;.squeeze(2)) + e&#91;3&#93;.squeeze(2))
    with torch.amp.autocast(&quot;cuda&quot;, dtype=torch.float32):
        x = x + y * e&#91;5&#93;.squeeze(2)
    return x</code></pre></details>

fastvideo.models.dits.lingbotworld2.causal_fast.CausalWanAttentionBlock.forward

forward(x: torch.Tensor, e: torch.Tensor, seq_lens: torch.Tensor, grid_sizes: torch.Tensor, freqs: torch.Tensor, context: torch.Tensor, context_lens: torch.Tensor | None, dit_cond_dict: dict[str, Any] | None = None, kv_cache: dict | None = None, crossattn_cache: dict | None = None, current_start: int = 0, max_attention_size: int = 1000000, frame_seqlen: int | None = None, cross_attn_first_call: bool | None = None, seq_lens_int: int | None = None) -> torch.Tensor

Apply self-attention, camera modulation, cross-attention, and FFN.

Source
def forward(
    self,
    x: torch.Tensor,
    e: torch.Tensor,
    seq_lens: torch.Tensor,
    grid_sizes: torch.Tensor,
    freqs: torch.Tensor,
    context: torch.Tensor,
    context_lens: torch.Tensor | None,
    dit_cond_dict: dict[str, Any] | None = None,
    kv_cache: dict | None = None,
    crossattn_cache: dict | None = None,
    current_start: int = 0,
    max_attention_size: int = 1_000_000,
    frame_seqlen: int | None = None,
    cross_attn_first_call: bool | None = None,
    seq_lens_int: int | None = None,
) -> torch.Tensor:
    """Apply self-attention, camera modulation, cross-attention, and FFN."""
    assert kv_cache is not None
    assert e.dtype == torch.float32
    with torch.amp.autocast("cuda", dtype=torch.float32):
        e = (self.modulation.unsqueeze(0) + e).chunk(6, dim=2)
y = self.self_attn(
    self.norm1(x).float() * (1 + e&#91;1&#93;.squeeze(2)) + e&#91;0&#93;.squeeze(2),
    seq_lens,
    grid_sizes,
    freqs,
    kv_cache,
    current_start,
    max_attention_size,
    frame_seqlen=frame_seqlen,
    seq_lens_int=seq_lens_int,
)
with torch.amp.autocast(&quot;cuda&quot;, dtype=torch.float32):
    x = x + y * e&#91;2&#93;.squeeze(2)

if dit_cond_dict is not None and &quot;c2ws_plucker_emb&quot; in dit_cond_dict:
    c2ws_plucker_emb = dit_cond_dict&#91;&quot;c2ws_plucker_emb&quot;&#93;
    c2ws_hidden_states = self.cam_injector_layer2(F.silu(self.cam_injector_layer1(c2ws_plucker_emb)))
    c2ws_hidden_states = c2ws_hidden_states + c2ws_plucker_emb
    x = (1.0 + self.cam_scale_layer(c2ws_hidden_states)) * x + self.cam_shift_layer(c2ws_hidden_states)

x = x + self.cross_attn(
    self.norm3(x),
    context,
    context_lens,
    crossattn_cache=crossattn_cache,
    cross_attn_first_call=cross_attn_first_call,
)
y = self.ffn(self.norm2(x).float() * (1 + e&#91;4&#93;.squeeze(2)) + e&#91;3&#93;.squeeze(2))
with torch.amp.autocast(&quot;cuda&quot;, dtype=torch.float32):
    x = x + y * e&#91;5&#93;.squeeze(2)
return x</code></pre></details>

fastvideo.models.dits.lingbotworld2.causal_fast.CausalHead

CausalHead(dim: int, out_dim: int, patch_size: tuple[int, int, int], eps: float = 1e-06)

Output projection head for LingBot World 2 causal-fast DiT.

Source
class CausalHead(nn.Module):
    """Output projection head for LingBot World 2 causal-fast DiT."""
def __init__(self, dim: int, out_dim: int, patch_size: tuple&#91;int, int, int&#93;, eps: float = 1e-6):
    super().__init__()
    self.dim = dim
    self.out_dim = out_dim
    self.patch_size = patch_size
    self.eps = eps
    self.norm = WanLayerNorm(dim, eps)
    self.head = nn.Linear(dim, math.prod(patch_size) * out_dim)
    self.modulation = nn.Parameter(torch.randn(1, 2, dim) / dim**0.5)

def forward(self, x: torch.Tensor, e: torch.Tensor) -&gt; torch.Tensor:
    &quot;&quot;&quot;Normalize, modulate, and project hidden states to latent patches.&quot;&quot;&quot;
    assert e.dtype == torch.float32
    with torch.amp.autocast(&quot;cuda&quot;, dtype=torch.float32):
        e = (self.modulation.unsqueeze(0) + e.unsqueeze(2)).chunk(2, dim=2)
        x = self.head(self.norm(x) * (1 + e&#91;1&#93;.squeeze(2)) + e&#91;0&#93;.squeeze(2))
    return x</code></pre></details>

fastvideo.models.dits.lingbotworld2.causal_fast.CausalHead.forward

forward(x: torch.Tensor, e: torch.Tensor) -> torch.Tensor

Normalize, modulate, and project hidden states to latent patches.

Source
def forward(self, x: torch.Tensor, e: torch.Tensor) -> torch.Tensor:
    """Normalize, modulate, and project hidden states to latent patches."""
    assert e.dtype == torch.float32
    with torch.amp.autocast("cuda", dtype=torch.float32):
        e = (self.modulation.unsqueeze(0) + e.unsqueeze(2)).chunk(2, dim=2)
        x = self.head(self.norm(x) * (1 + e[1].squeeze(2)) + e[0].squeeze(2))
    return x

fastvideo.models.dits.lingbotworld2.causal_fast.LingBotWorld2CausalFastTransformer3DModel

LingBotWorld2CausalFastTransformer3DModel(config: LingBotWorld2CausalFastVideoConfig, hf_config: dict[str, Any])

Released LingBot World 2 14B causal-fast model with native FastVideo loading.

Source
class LingBotWorld2CausalFastTransformer3DModel(BaseDiT):
    """Released LingBot World 2 14B causal-fast model with native FastVideo loading."""
_fsdp_shard_conditions = &#91;is_blocks&#93;
_compile_conditions: list = &#91;&#93;
_supported_attention_backends = (
    AttentionBackendEnum.FLASH_ATTN,
    AttentionBackendEnum.TORCH_SDPA,
)
param_names_mapping: dict = &#123;&#125;
reverse_param_names_mapping: dict = &#123;&#125;
lora_param_names_mapping: dict = &#123;&#125;

def __init__(self, config: LingBotWorld2CausalFastVideoConfig, hf_config: dict&#91;str, Any&#93;) -&gt; None:
    super().__init__(config=config, hf_config=hf_config)
    self.model_type = config.model_type
    self.patch_size = tuple(config.patch_size)
    self.text_len = config.text_len
    self.in_dim = config.in_dim
    self.dim = config.dim
    self.hidden_size = config.dim
    self.ffn_dim = config.ffn_dim
    self.freq_dim = config.freq_dim
    self.text_dim = config.text_dim
    self.out_dim = config.out_dim
    self.out_channels = config.out_dim
    self.num_heads = config.num_heads
    self.num_attention_heads = config.num_heads
    self.attention_head_dim = config.dim // config.num_heads
    self.num_layers = config.num_layers
    self.local_attn_size = config.local_attn_size
    self.sink_size = config.sink_size
    self.qk_norm = config.qk_norm
    self.cross_attn_norm = config.cross_attn_norm
    self.eps = config.eps
    self.num_channels_latents = config.out_dim

    control_dim = 6
    self.patch_embedding = nn.Conv3d(self.in_dim, self.dim, kernel_size=self.patch_size, stride=self.patch_size)
    self.patch_embedding_wancamctrl = nn.Linear(
        control_dim * 64 * self.patch_size&#91;0&#93; * self.patch_size&#91;1&#93; * self.patch_size&#91;2&#93;,
        self.dim,
    )
    self.c2ws_hidden_states_layer1 = nn.Linear(self.dim, self.dim)
    self.c2ws_hidden_states_layer2 = nn.Linear(self.dim, self.dim)
    self.text_embedding = nn.Sequential(
        nn.Linear(self.text_dim, self.dim),
        nn.GELU(approximate=&quot;tanh&quot;),
        nn.Linear(self.dim, self.dim),
    )
    self.time_embedding = nn.Sequential(
        nn.Linear(self.freq_dim, self.dim),
        nn.SiLU(),
        nn.Linear(self.dim, self.dim),
    )
    self.time_projection = nn.Sequential(nn.SiLU(), nn.Linear(self.dim, self.dim * 6))
    self.blocks = nn.ModuleList(&#91;
        CausalWanAttentionBlock(
            self.dim,
            self.ffn_dim,
            self.num_heads,
            self.local_attn_size,
            self.sink_size,
            self.qk_norm,
            self.cross_attn_norm,
            self.eps,
        ) for _ in range(self.num_layers)
    &#93;)
    self.head = CausalHead(self.dim, self.out_dim, self.patch_size, self.eps)
    self.freqs: torch.Tensor | None = None
    self.init_weights()
    self.__post_init__()

def _get_freqs(self, device: torch.device) -&gt; torch.Tensor:
    &quot;&quot;&quot;Materialize the non-persistent RoPE frequency table outside meta init.&quot;&quot;&quot;
    if self.freqs is None or self.freqs.is_meta or self.freqs.device != device:
        d = self.dim // self.num_heads
        self.freqs = torch.cat(
            &#91;
                rope_params(1024, d - 4 * (d // 6)),
                rope_params(1024, 2 * (d // 6)),
                rope_params(1024, 2 * (d // 6)),
            &#93;,
            dim=1,
        ).to(device)
    return self.freqs

def forward(
    self,
    hidden_states: torch.Tensor | list&#91;torch.Tensor&#93; | None = None,
    encoder_hidden_states: torch.Tensor | list&#91;torch.Tensor&#93; | None = None,
    timestep: torch.Tensor | None = None,
    encoder_hidden_states_image: torch.Tensor | list&#91;torch.Tensor&#93; | None = None,
    guidance=None,
    *,
    x: list&#91;torch.Tensor&#93; | None = None,
    t: torch.Tensor | None = None,
    context: list&#91;torch.Tensor&#93; | torch.Tensor | None = None,
    seq_len: int | None = None,
    y: list&#91;torch.Tensor&#93; | None = None,
    dit_cond_dict: dict&#91;str, Any&#93; | None = None,
    kv_cache: list&#91;dict&#93; | None = None,
    crossattn_cache: list&#91;dict&#93; | None = None,
    current_start: int = 0,
    max_attention_size: int = 1_000_000,
    frame_seqlen: int | None = None,
    cross_attn_first_call: bool | None = None,
    **kwargs,
) -&gt; list&#91;torch.Tensor&#93;:
    &quot;&quot;&quot;Run one cached causal-fast DiT forward using the released LingBot World 2 ABI.&quot;&quot;&quot;
    del encoder_hidden_states_image, guidance, kwargs
    if x is None:
        assert isinstance(hidden_states, torch.Tensor)
        x = &#91;hidden_states&#91;0&#93;&#93;
    if t is None:
        assert timestep is not None
        t = timestep
    if context is None:
        context = encoder_hidden_states
    if isinstance(context, torch.Tensor):
        context = &#91;u for u in context&#93;
    assert context is not None
    assert seq_len is not None
    assert kv_cache is not None
    assert crossattn_cache is not None
    if self.model_type == &quot;i2v&quot;:
        assert y is not None

    device = self.patch_embedding.weight.device
    freqs = self._get_freqs(device)
    if y is not None:
        x = &#91;torch.cat(&#91;u, v&#93;, dim=0) for u, v in zip(x, y, strict=True)&#93;

    x = &#91;self.patch_embedding(u.unsqueeze(0)) for u in x&#93;
    grid_sizes = torch.stack(&#91;torch.tensor(u.shape&#91;2:&#93;, dtype=torch.long, device=u.device) for u in x&#93;)
    x = &#91;u.flatten(2).transpose(1, 2) for u in x&#93;
    seq_lens = torch.tensor(&#91;u.size(1) for u in x&#93;, dtype=torch.long, device=device)
    assert seq_lens.max() &lt;= seq_len
    x = torch.cat(x)
    seq_lens_int = int(seq_lens&#91;0&#93;.item())
    sp_size = get_sp_world_size()
    sp_rank = get_sp_parallel_rank()
    padded_seq_len = ((seq_lens_int + sp_size - 1) // sp_size) * sp_size
    sp_pad_len = padded_seq_len - seq_lens_int
    if sp_pad_len &gt; 0:
        x = torch.cat(&#91;x, x.new_zeros(x.size(0), sp_pad_len, x.size(2))&#93;, dim=1)

    if t.dim() == 1:
        t = t.expand(t.size(0), padded_seq_len)
    with torch.amp.autocast(&quot;cuda&quot;, dtype=torch.float32):
        bt = t.size(0)
        t = t.flatten()
        e = self.time_embedding(
            sinusoidal_embedding_1d(self.freq_dim, t).unflatten(0, (bt, padded_seq_len)).float())
        e0 = self.time_projection(e).unflatten(2, (6, self.dim))

    context_lens = None
    context = self.text_embedding(
        torch.stack(&#91;torch.cat(&#91;u, u.new_zeros(self.text_len - u.size(0), u.size(1))&#93;) for u in context&#93;))

    if dit_cond_dict is not None and &quot;c2ws_plucker_emb&quot; in dit_cond_dict:
        c2ws_plucker_emb = dit_cond_dict&#91;&quot;c2ws_plucker_emb&quot;&#93;
        c2ws_plucker_emb = &#91;
            rearrange(
                i,
                &quot;1 c (f c1) (h c2) (w c3) -&gt; 1 (f h w) (c c1 c2 c3)&quot;,
                c1=self.patch_size&#91;0&#93;,
                c2=self.patch_size&#91;1&#93;,
                c3=self.patch_size&#91;2&#93;,
            ) for i in c2ws_plucker_emb
        &#93;
        c2ws_plucker_emb = torch.cat(c2ws_plucker_emb, dim=1)
        c2ws_plucker_emb = self.patch_embedding_wancamctrl(c2ws_plucker_emb)
        c2ws_hidden_states = self.c2ws_hidden_states_layer2(F.silu(
            self.c2ws_hidden_states_layer1(c2ws_plucker_emb)))
        c2ws_plucker_emb = c2ws_plucker_emb + c2ws_hidden_states
        cam_len = c2ws_plucker_emb.size(1)
        if cam_len &lt; padded_seq_len:
            c2ws_plucker_emb = torch.cat(
                &#91;
                    c2ws_plucker_emb,
                    c2ws_plucker_emb.new_zeros(
                        c2ws_plucker_emb.size(0),
                        padded_seq_len - cam_len,
                        c2ws_plucker_emb.size(2),
                    ),
                &#93;,
                dim=1,
            )
        elif cam_len &gt; padded_seq_len:
            c2ws_plucker_emb = c2ws_plucker_emb&#91;:, :padded_seq_len, :&#93;
        if sp_size &gt; 1:
            c2ws_plucker_emb = torch.chunk(c2ws_plucker_emb, sp_size, dim=1)&#91;sp_rank&#93;
        dit_cond_dict = dict(dit_cond_dict)
        dit_cond_dict&#91;&quot;c2ws_plucker_emb&quot;&#93; = c2ws_plucker_emb

    if sp_size &gt; 1:
        x = torch.chunk(x, sp_size, dim=1)&#91;sp_rank&#93;
        e = torch.chunk(e, sp_size, dim=1)&#91;sp_rank&#93;
        e0 = torch.chunk(e0, sp_size, dim=1)&#91;sp_rank&#93;

    for block_index, block in enumerate(self.blocks):
        x = block(
            x,
            e=e0,
            seq_lens=seq_lens,
            grid_sizes=grid_sizes,
            freqs=freqs,
            context=context,
            context_lens=context_lens,
            dit_cond_dict=dit_cond_dict,
            kv_cache=kv_cache&#91;block_index&#93;,
            crossattn_cache=crossattn_cache&#91;block_index&#93;,
            current_start=current_start,
            max_attention_size=max_attention_size,
            frame_seqlen=frame_seqlen,
            cross_attn_first_call=cross_attn_first_call,
            seq_lens_int=seq_lens_int,
        )

    x = self.head(x, e)
    if sp_size &gt; 1:
        x = sequence_model_parallel_all_gather(x, dim=1)
    return &#91;u.float() for u in self.unpatchify(x, grid_sizes)&#93;

def unpatchify(self, x: torch.Tensor, grid_sizes: torch.Tensor) -&gt; list&#91;torch.Tensor&#93;:
    &quot;&quot;&quot;Reconstruct latent videos from flattened patch tokens.&quot;&quot;&quot;
    c = self.out_dim
    out = &#91;&#93;
    for u, v in zip(x, grid_sizes.tolist(), strict=True):
        u = u&#91;:math.prod(v)&#93;.view(*v, *self.patch_size, c)
        u = torch.einsum(&quot;fhwpqrc-&gt;cfphqwr&quot;, u)
        u = u.reshape(c, *&#91;i * j for i, j in zip(v, self.patch_size, strict=True)&#93;)
        out.append(u)
    return out

def init_weights(self) -&gt; None:
    &quot;&quot;&quot;Initialize modules for non-meta construction; checkpoint load overwrites them.&quot;&quot;&quot;
    if self.patch_embedding.weight.is_meta:
        return
    for m in self.modules():
        if isinstance(m, nn.Linear):
            nn.init.xavier_uniform_(m.weight)
            if m.bias is not None:
                nn.init.zeros_(m.bias)
    nn.init.xavier_uniform_(self.patch_embedding.weight.flatten(1))
    for m in self.text_embedding.modules():
        if isinstance(m, nn.Linear):
            nn.init.normal_(m.weight, std=0.02)
    for m in self.time_embedding.modules():
        if isinstance(m, nn.Linear):
            nn.init.normal_(m.weight, std=0.02)
    nn.init.zeros_(self.head.head.weight)</code></pre></details>

fastvideo.models.dits.lingbotworld2.causal_fast.LingBotWorld2CausalFastTransformer3DModel.forward

forward(hidden_states: torch.Tensor | list[torch.Tensor] | None = None, encoder_hidden_states: torch.Tensor | list[torch.Tensor] | None = None, timestep: torch.Tensor | None = None, encoder_hidden_states_image: torch.Tensor | list[torch.Tensor] | None = None, guidance = None, *, x: list[torch.Tensor] | None = None, t: torch.Tensor | None = None, context: list[torch.Tensor] | torch.Tensor | None = None, seq_len: int | None = None, y: list[torch.Tensor] | None = None, dit_cond_dict: dict[str, Any] | None = None, kv_cache: list[dict] | None = None, crossattn_cache: list[dict] | None = None, current_start: int = 0, max_attention_size: int = 1000000, frame_seqlen: int | None = None, cross_attn_first_call: bool | None = None, **kwargs) -> list[torch.Tensor]

Run one cached causal-fast DiT forward using the released LingBot World 2 ABI.

Source
def forward(
    self,
    hidden_states: torch.Tensor | list[torch.Tensor] | None = None,
    encoder_hidden_states: torch.Tensor | list[torch.Tensor] | None = None,
    timestep: torch.Tensor | None = None,
    encoder_hidden_states_image: torch.Tensor | list[torch.Tensor] | None = None,
    guidance=None,
    *,
    x: list[torch.Tensor] | None = None,
    t: torch.Tensor | None = None,
    context: list[torch.Tensor] | torch.Tensor | None = None,
    seq_len: int | None = None,
    y: list[torch.Tensor] | None = None,
    dit_cond_dict: dict[str, Any] | None = None,
    kv_cache: list[dict] | None = None,
    crossattn_cache: list[dict] | None = None,
    current_start: int = 0,
    max_attention_size: int = 1_000_000,
    frame_seqlen: int | None = None,
    cross_attn_first_call: bool | None = None,
    **kwargs,
) -> list[torch.Tensor]:
    """Run one cached causal-fast DiT forward using the released LingBot World 2 ABI."""
    del encoder_hidden_states_image, guidance, kwargs
    if x is None:
        assert isinstance(hidden_states, torch.Tensor)
        x = [hidden_states[0]]
    if t is None:
        assert timestep is not None
        t = timestep
    if context is None:
        context = encoder_hidden_states
    if isinstance(context, torch.Tensor):
        context = [u for u in context]
    assert context is not None
    assert seq_len is not None
    assert kv_cache is not None
    assert crossattn_cache is not None
    if self.model_type == "i2v":
        assert y is not None
device = self.patch_embedding.weight.device
freqs = self._get_freqs(device)
if y is not None:
    x = &#91;torch.cat(&#91;u, v&#93;, dim=0) for u, v in zip(x, y, strict=True)&#93;

x = &#91;self.patch_embedding(u.unsqueeze(0)) for u in x&#93;
grid_sizes = torch.stack(&#91;torch.tensor(u.shape&#91;2:&#93;, dtype=torch.long, device=u.device) for u in x&#93;)
x = &#91;u.flatten(2).transpose(1, 2) for u in x&#93;
seq_lens = torch.tensor(&#91;u.size(1) for u in x&#93;, dtype=torch.long, device=device)
assert seq_lens.max() &lt;= seq_len
x = torch.cat(x)
seq_lens_int = int(seq_lens&#91;0&#93;.item())
sp_size = get_sp_world_size()
sp_rank = get_sp_parallel_rank()
padded_seq_len = ((seq_lens_int + sp_size - 1) // sp_size) * sp_size
sp_pad_len = padded_seq_len - seq_lens_int
if sp_pad_len &gt; 0:
    x = torch.cat(&#91;x, x.new_zeros(x.size(0), sp_pad_len, x.size(2))&#93;, dim=1)

if t.dim() == 1:
    t = t.expand(t.size(0), padded_seq_len)
with torch.amp.autocast(&quot;cuda&quot;, dtype=torch.float32):
    bt = t.size(0)
    t = t.flatten()
    e = self.time_embedding(
        sinusoidal_embedding_1d(self.freq_dim, t).unflatten(0, (bt, padded_seq_len)).float())
    e0 = self.time_projection(e).unflatten(2, (6, self.dim))

context_lens = None
context = self.text_embedding(
    torch.stack(&#91;torch.cat(&#91;u, u.new_zeros(self.text_len - u.size(0), u.size(1))&#93;) for u in context&#93;))

if dit_cond_dict is not None and &quot;c2ws_plucker_emb&quot; in dit_cond_dict:
    c2ws_plucker_emb = dit_cond_dict&#91;&quot;c2ws_plucker_emb&quot;&#93;
    c2ws_plucker_emb = &#91;
        rearrange(
            i,
            &quot;1 c (f c1) (h c2) (w c3) -&gt; 1 (f h w) (c c1 c2 c3)&quot;,
            c1=self.patch_size&#91;0&#93;,
            c2=self.patch_size&#91;1&#93;,
            c3=self.patch_size&#91;2&#93;,
        ) for i in c2ws_plucker_emb
    &#93;
    c2ws_plucker_emb = torch.cat(c2ws_plucker_emb, dim=1)
    c2ws_plucker_emb = self.patch_embedding_wancamctrl(c2ws_plucker_emb)
    c2ws_hidden_states = self.c2ws_hidden_states_layer2(F.silu(
        self.c2ws_hidden_states_layer1(c2ws_plucker_emb)))
    c2ws_plucker_emb = c2ws_plucker_emb + c2ws_hidden_states
    cam_len = c2ws_plucker_emb.size(1)
    if cam_len &lt; padded_seq_len:
        c2ws_plucker_emb = torch.cat(
            &#91;
                c2ws_plucker_emb,
                c2ws_plucker_emb.new_zeros(
                    c2ws_plucker_emb.size(0),
                    padded_seq_len - cam_len,
                    c2ws_plucker_emb.size(2),
                ),
            &#93;,
            dim=1,
        )
    elif cam_len &gt; padded_seq_len:
        c2ws_plucker_emb = c2ws_plucker_emb&#91;:, :padded_seq_len, :&#93;
    if sp_size &gt; 1:
        c2ws_plucker_emb = torch.chunk(c2ws_plucker_emb, sp_size, dim=1)&#91;sp_rank&#93;
    dit_cond_dict = dict(dit_cond_dict)
    dit_cond_dict&#91;&quot;c2ws_plucker_emb&quot;&#93; = c2ws_plucker_emb

if sp_size &gt; 1:
    x = torch.chunk(x, sp_size, dim=1)&#91;sp_rank&#93;
    e = torch.chunk(e, sp_size, dim=1)&#91;sp_rank&#93;
    e0 = torch.chunk(e0, sp_size, dim=1)&#91;sp_rank&#93;

for block_index, block in enumerate(self.blocks):
    x = block(
        x,
        e=e0,
        seq_lens=seq_lens,
        grid_sizes=grid_sizes,
        freqs=freqs,
        context=context,
        context_lens=context_lens,
        dit_cond_dict=dit_cond_dict,
        kv_cache=kv_cache&#91;block_index&#93;,
        crossattn_cache=crossattn_cache&#91;block_index&#93;,
        current_start=current_start,
        max_attention_size=max_attention_size,
        frame_seqlen=frame_seqlen,
        cross_attn_first_call=cross_attn_first_call,
        seq_lens_int=seq_lens_int,
    )

x = self.head(x, e)
if sp_size &gt; 1:
    x = sequence_model_parallel_all_gather(x, dim=1)
return &#91;u.float() for u in self.unpatchify(x, grid_sizes)&#93;</code></pre></details>

fastvideo.models.dits.lingbotworld2.causal_fast.LingBotWorld2CausalFastTransformer3DModel.unpatchify

unpatchify(x: torch.Tensor, grid_sizes: torch.Tensor) -> list[torch.Tensor]

Reconstruct latent videos from flattened patch tokens.

Source
def unpatchify(self, x: torch.Tensor, grid_sizes: torch.Tensor) -> list[torch.Tensor]:
    """Reconstruct latent videos from flattened patch tokens."""
    c = self.out_dim
    out = []
    for u, v in zip(x, grid_sizes.tolist(), strict=True):
        u = u[:math.prod(v)].view(*v, *self.patch_size, c)
        u = torch.einsum("fhwpqrc->cfphqwr", u)
        u = u.reshape(c, *[i * j for i, j in zip(v, self.patch_size, strict=True)])
        out.append(u)
    return out

fastvideo.models.dits.lingbotworld2.causal_fast.LingBotWorld2CausalFastTransformer3DModel.init_weights

init_weights() -> None

Initialize modules for non-meta construction; checkpoint load overwrites them.

Source
def init_weights(self) -> None:
    """Initialize modules for non-meta construction; checkpoint load overwrites them."""
    if self.patch_embedding.weight.is_meta:
        return
    for m in self.modules():
        if isinstance(m, nn.Linear):
            nn.init.xavier_uniform_(m.weight)
            if m.bias is not None:
                nn.init.zeros_(m.bias)
    nn.init.xavier_uniform_(self.patch_embedding.weight.flatten(1))
    for m in self.text_embedding.modules():
        if isinstance(m, nn.Linear):
            nn.init.normal_(m.weight, std=0.02)
    for m in self.time_embedding.modules():
        if isinstance(m, nn.Linear):
            nn.init.normal_(m.weight, std=0.02)
    nn.init.zeros_(self.head.head.weight)

Was this page helpful?