---
title: lingbot_video
---

<div class="python-reference">
<a id="fastvideo.models.encoders.lingbot_video-classes"></a>
<a id="fastvideo.models.encoders.lingbot_video.LingBotVideoQwen3VLAttention-functions"></a>
<a id="fastvideo.models.encoders.lingbot_video.LingBotVideoQwen3VLDecoderLayer-functions"></a>
<a id="fastvideo.models.encoders.lingbot_video.LingBotVideoQwen3VLTextModel-functions"></a>
<a id="fastvideo.models.encoders.lingbot_video"></a>
<p>Native LingBot-Video Qwen3-VL language model for text-only conditioning.</p>
<h2 id="fastvideo.models.encoders.lingbot_video.BaseEncoderOutput"><code>fastvideo.models.encoders.lingbot_video.BaseEncoderOutput</code></h2>
<pre class="doc-signature"><code>BaseEncoderOutput(last_hidden_state: torch.FloatTensor | None = None, pooler_output: torch.FloatTensor | None = None, hidden_states: tuple&#91;torch.FloatTensor, ...&#93; | None = None, attentions: tuple&#91;torch.FloatTensor, ...&#93; | None = None, attention_mask: torch.Tensor | None = None)</code></pre>


<h2 id="fastvideo.models.encoders.lingbot_video.RMSNorm"><code>fastvideo.models.encoders.lingbot_video.RMSNorm</code></h2>
<pre class="doc-signature"><code>RMSNorm(hidden_size: int, eps: float = 1e-06, dtype: torch.dtype = torch.float32, var_hidden_size: int | None = None, has_weight: bool = True)</code></pre>
<p>Root mean square normalization.</p>
<p>Computes x -&gt; w * x / sqrt(E[x^2] + eps) where w is the learned weight.
Refer to https://arxiv.org/abs/1910.07467</p>

<h3 id="fastvideo.models.encoders.lingbot_video.RMSNorm.forward_native"><code>fastvideo.models.encoders.lingbot_video.RMSNorm.forward_native</code></h3>
<pre class="doc-signature"><code>forward_native(x: torch.Tensor, residual: torch.Tensor | None = None) -&gt; torch.Tensor | tuple&#91;torch.Tensor, torch.Tensor&#93;</code></pre>
<p>PyTorch-native implementation equivalent to forward().</p>
<h3 id="fastvideo.models.encoders.lingbot_video.RMSNorm.extra_repr"><code>fastvideo.models.encoders.lingbot_video.RMSNorm.extra_repr</code></h3>
<pre class="doc-signature"><code>extra_repr() -&gt; str</code></pre>

<h2 id="fastvideo.models.encoders.lingbot_video.VocabParallelEmbedding"><code>fastvideo.models.encoders.lingbot_video.VocabParallelEmbedding</code></h2>
<pre class="doc-signature"><code>VocabParallelEmbedding(num_embeddings: int, embedding_dim: int, params_dtype: torch.dtype | None = None, org_num_embeddings: int | None = None, padding_size: int = DEFAULT_VOCAB_PADDING_SIZE, quant_config: QuantizationConfig | None = None, prefix: str = &#x27;&#x27;)</code></pre>
<p>Embedding parallelized in the vocabulary dimension.</p>
<p>Adapted from torch.nn.Embedding, note that we pad the vocabulary size to
make sure it is divisible by the number of model parallel GPUs.</p>
<p>In order to support various loading methods, we ensure that LoRA-added
embeddings are always at the end of TP-sharded tensors. In other words,
we shard base embeddings and LoRA embeddings separately (both padded),
and place them in the same tensor.
In this example, we will have the original vocab size = 1010,
added vocab size = 16 and padding to 64. Therefore, the total
vocab size with padding will be 1088 (because we first pad 1010 to
1024, add 16, and then pad to 1088).
Therefore, the tensor format looks like the following:
TP1, rank 0 (no sharding):
                        |&lt; --------BASE-------- &gt;|&lt; -BASE PADDING-- &gt;|&lt; -----LORA------ &gt;|&lt; -LORA PADDING-- &gt;|
corresponding token_id: |  0  |  1  | ... | 1009 |  -1  | ... |  -1  | 1010 | ... | 1015 |  -1  | ... |  -1  |
                 index: |  0  |  1  | ... | 1009 | 1010 | ... | 1023 | 1024 | ... | 1039 | 1040 | ... | 1087 |</p>
<p>TP2, rank 0:
                        |&lt; --------------------BASE--------------------- &gt;|&lt; -----LORA------ &gt;|&lt; -LORA PADDING- &gt;|
corresponding token_id: |  0  |  1  |  2  | ... | 497  | 498 | ...  | 511 | 1000 | ... | 1015 |  -1  | ... |  -1 |
                 index: |  0  |  1  |  2  | ... | 497  | 498 | ...  | 511 | 512  | ... | 527  |  520 | ... | 543 |
TP2, rank 1:
                        |&lt; -----------BASE----------- &gt;|&lt; -BASE PADDING- &gt;|&lt; -----------LORA PADDING----------- &gt;|
corresponding token_id: | 512 | 513 | 514 | ... | 1009 | -1  | ...  | -1  |  -1  | ... |  -1  | -1  | ... |   -1 |
                 index: |  0  |  1  |  2  | ... | 497  | 498 | ...  | 511 | 512  | ... | 519  | 520 | ... |  543 |</p>
<h3>Parameters</h3>
<dl>
<dt><code>num_embeddings: int</code></dt><dd><p>vocabulary size.</p></dd>
<dt><code>embedding_dim: int</code></dt><dd><p>size of hidden state.</p></dd>
<dt><code>params_dtype: torch.dtype | None</code></dt><dd><p>type of the parameters.</p></dd>
<dt><code>org_num_embeddings: int | None</code></dt><dd><p>original vocabulary size (without LoRA).</p></dd>
<dt><code>padding_size: int</code></dt><dd><p>padding size for the vocabulary.</p></dd>
<dt><code>quant_config: QuantizationConfig | None</code></dt><dd><p>quant config for the layer</p></dd>
<dt><code>prefix: str</code></dt><dd><p>full name of the layer in the state dict</p></dd>
</dl>

<h3 id="fastvideo.models.encoders.lingbot_video.VocabParallelEmbedding.get_sharded_to_full_mapping"><code>fastvideo.models.encoders.lingbot_video.VocabParallelEmbedding.get_sharded_to_full_mapping</code></h3>
<pre class="doc-signature"><code>get_sharded_to_full_mapping() -&gt; list&#91;int&#93; | None</code></pre>
<p>Get a mapping that can be used to reindex the gathered
logits for sampling.</p>
<p>During sampling, we gather logits from all ranks. The relationship
of index-&gt;token_id will follow the same format as outlined in the class
docstring. However, after the gather, we want to reindex the final
logits tensor to map index-&gt;token_id one-to-one (the index is always
equal the token_id it corresponds to). The indices returned by this
method allow us to do that.</p>
<h3 id="fastvideo.models.encoders.lingbot_video.VocabParallelEmbedding.weight_loader"><code>fastvideo.models.encoders.lingbot_video.VocabParallelEmbedding.weight_loader</code></h3>
<pre class="doc-signature"><code>weight_loader(param: Parameter, loaded_weight: torch.Tensor)</code></pre>

<h3 id="fastvideo.models.encoders.lingbot_video.VocabParallelEmbedding.forward"><code>fastvideo.models.encoders.lingbot_video.VocabParallelEmbedding.forward</code></h3>
<pre class="doc-signature"><code>forward(input_)</code></pre>

<h3 id="fastvideo.models.encoders.lingbot_video.VocabParallelEmbedding.extra_repr"><code>fastvideo.models.encoders.lingbot_video.VocabParallelEmbedding.extra_repr</code></h3>
<pre class="doc-signature"><code>extra_repr() -&gt; str</code></pre>

<h2 id="fastvideo.models.encoders.lingbot_video.TextEncoder"><code>fastvideo.models.encoders.lingbot_video.TextEncoder</code></h2>
<pre class="doc-signature"><code>TextEncoder(config: TextEncoderConfig)</code></pre>
<p>Base for native encoders with a model-specific forward output contract.</p>

<h3 id="fastvideo.models.encoders.lingbot_video.TextEncoder.forward"><code>fastvideo.models.encoders.lingbot_video.TextEncoder.forward</code></h3>
<pre class="doc-signature"><code>forward(*args: Any, **kwargs: Any) -&gt; TextEncoderOutputT</code></pre>

<h2 id="fastvideo.models.encoders.lingbot_video.Qwen3Attention"><code>fastvideo.models.encoders.lingbot_video.Qwen3Attention</code></h2>
<pre class="doc-signature"><code>Qwen3Attention(config: Qwen3TextConfig, hidden_size: int, num_heads: int, num_kv_heads: int, rope_theta: float = 1000000.0, rope_scaling: dict&#91;str, Any&#93; | None = None, max_position_embeddings: int = 40960, quant_config: QuantizationConfig | None = None, bias: bool = False, prefix: str = &#x27;&#x27;)</code></pre>
<p>Qwen3 attention with QK-Norm and tensor parallelism.</p>
<p>Key difference from LLaMA: RMSNorm is applied to Q and K before attention.</p>

<h3 id="fastvideo.models.encoders.lingbot_video.Qwen3Attention.forward"><code>fastvideo.models.encoders.lingbot_video.Qwen3Attention.forward</code></h3>
<pre class="doc-signature"><code>forward(positions: torch.Tensor, hidden_states: torch.Tensor, attention_mask: torch.Tensor | None = None) -&gt; torch.Tensor</code></pre>

<h2 id="fastvideo.models.encoders.lingbot_video.Qwen3DecoderLayer"><code>fastvideo.models.encoders.lingbot_video.Qwen3DecoderLayer</code></h2>
<pre class="doc-signature"><code>Qwen3DecoderLayer(config: Qwen3TextConfig, quant_config: QuantizationConfig | None = None, prefix: str = &#x27;&#x27;)</code></pre>
<p>Qwen3 transformer decoder layer.</p>

<h3 id="fastvideo.models.encoders.lingbot_video.Qwen3DecoderLayer.forward"><code>fastvideo.models.encoders.lingbot_video.Qwen3DecoderLayer.forward</code></h3>
<pre class="doc-signature"><code>forward(positions: torch.Tensor, hidden_states: torch.Tensor, residual: torch.Tensor | None, attention_mask: torch.Tensor | None = None) -&gt; tuple&#91;torch.Tensor, torch.Tensor&#93;</code></pre>

<h2 id="fastvideo.models.encoders.lingbot_video.Qwen3ForCausalLM"><code>fastvideo.models.encoders.lingbot_video.Qwen3ForCausalLM</code></h2>
<pre class="doc-signature"><code>Qwen3ForCausalLM(config: Qwen3TextConfig)</code></pre>
<p>Qwen3 causal language model for text encoding in diffusion models (e.g. Flux2 Klein).</p>
<p>Features:
- Tensor parallelism support
- FlashAttention/SDPA support via LocalAttention
- QK-Norm for better training stability
- output_hidden_states for Klein (layers 9, 18, 27)</p>

<h3 id="fastvideo.models.encoders.lingbot_video.Qwen3ForCausalLM.from_pretrained_local"><code>fastvideo.models.encoders.lingbot_video.Qwen3ForCausalLM.from_pretrained_local</code></h3>
<pre class="doc-signature"><code>from_pretrained_local(model_path: str, model_config: Qwen3TextConfig, dtype: torch.dtype, device: torch.device) -&gt; nn.Module</code></pre>

<h3 id="fastvideo.models.encoders.lingbot_video.Qwen3ForCausalLM.get_input_embeddings"><code>fastvideo.models.encoders.lingbot_video.Qwen3ForCausalLM.get_input_embeddings</code></h3>
<pre class="doc-signature"><code>get_input_embeddings(input_ids: torch.Tensor) -&gt; torch.Tensor</code></pre>

<h3 id="fastvideo.models.encoders.lingbot_video.Qwen3ForCausalLM.forward"><code>fastvideo.models.encoders.lingbot_video.Qwen3ForCausalLM.forward</code></h3>
<pre class="doc-signature"><code>forward(input_ids: torch.Tensor | None = None, position_ids: torch.Tensor | None = None, attention_mask: torch.Tensor | None = None, inputs_embeds: torch.Tensor | None = None, output_hidden_states: bool | None = None, **kwargs: Any) -&gt; BaseEncoderOutput</code></pre>

<h3 id="fastvideo.models.encoders.lingbot_video.Qwen3ForCausalLM.load_weights"><code>fastvideo.models.encoders.lingbot_video.Qwen3ForCausalLM.load_weights</code></h3>
<pre class="doc-signature"><code>load_weights(weights: Iterable&#91;tuple&#91;str, torch.Tensor&#93;&#93;) -&gt; set&#91;str&#93;</code></pre>

<h2 id="fastvideo.models.encoders.lingbot_video.Qwen3MLP"><code>fastvideo.models.encoders.lingbot_video.Qwen3MLP</code></h2>
<pre class="doc-signature"><code>Qwen3MLP(hidden_size: int, intermediate_size: int, hidden_act: str, quant_config: QuantizationConfig | None = None, bias: bool = False, prefix: str = &#x27;&#x27;)</code></pre>
<p>Qwen3 MLP with SwiGLU activation and tensor parallelism.</p>

<h3 id="fastvideo.models.encoders.lingbot_video.Qwen3MLP.forward"><code>fastvideo.models.encoders.lingbot_video.Qwen3MLP.forward</code></h3>
<pre class="doc-signature"><code>forward(x: torch.Tensor) -&gt; torch.Tensor</code></pre>

<h2 id="fastvideo.models.encoders.lingbot_video.LingBotVideoQwen3VLAttention"><code>fastvideo.models.encoders.lingbot_video.LingBotVideoQwen3VLAttention</code></h2>
<pre class="doc-signature"><code>LingBotVideoQwen3VLAttention(config: Qwen3TextConfig, hidden_size: int, num_heads: int, num_kv_heads: int, rope_theta: float = 1000000.0, rope_scaling: dict&#91;str, Any&#93; | None = None, max_position_embeddings: int = 40960, quant_config: QuantizationConfig | None = None, bias: bool = False, prefix: str = &#x27;&#x27;)</code></pre>
<p>Qwen3-VL attention with the official masked repeat-K/V SDPA path.</p>
<details><summary>Source</summary><pre><code>class LingBotVideoQwen3VLAttention(Qwen3Attention):
    &quot;&quot;&quot;Qwen3-VL attention with the official masked repeat-K/V SDPA path.&quot;&quot;&quot;

    def _apply_qwen3_vl_rope(
        self,
        positions: torch.Tensor,
        query: torch.Tensor,
        key: torch.Tensor,
    ) -&gt; tuple&#91;torch.Tensor, torch.Tensor&#93;:
        &quot;&quot;&quot;Apply NeoX RoPE with Qwen3-VL&#x27;s input-dtype multiply-add ordering.&quot;&quot;&quot;
        flat_positions = positions.flatten()
        cos_sin = self.rotary_emb.cos_sin_cache.index_select(0, flat_positions)
        cos_half, sin_half = cos_sin.chunk(2, dim=-1)
        cos = torch.cat((cos_half, cos_half), dim=-1).to(query.dtype)
        sin = torch.cat((sin_half, sin_half), dim=-1).to(query.dtype)
        if flat_positions.numel() == query.shape&#91;1&#93;:
            cos = cos.view(1, query.shape&#91;1&#93;, 1, self.head_dim)
            sin = sin.view(1, query.shape&#91;1&#93;, 1, self.head_dim)
        else:
            cos = cos.view(*query.shape&#91;:2&#93;, 1, self.head_dim)
            sin = sin.view(*query.shape&#91;:2&#93;, 1, self.head_dim)

        def rotate(tensor: torch.Tensor) -&gt; torch.Tensor:
            first, second = tensor.chunk(2, dim=-1)
            rotated = torch.cat((-second, first), dim=-1)
            return tensor * cos + rotated * sin

        return rotate(query), rotate(key)

    def forward(
        self,
        positions: torch.Tensor,
        hidden_states: torch.Tensor,
        attention_mask: torch.Tensor | None = None,
    ) -&gt; torch.Tensor:
        &quot;&quot;&quot;Apply fused projections, QK norm, RoPE, and causal grouped attention.&quot;&quot;&quot;
        qkv, _ = self.qkv_proj(hidden_states)
        query, key, value = qkv.split(&#91;self.q_size, self.kv_size, self.kv_size&#93;, dim=-1)
        batch_size, sequence_length = query.shape&#91;:2&#93;
        query = query.reshape(batch_size, sequence_length, self.num_heads, self.head_dim)
        key = key.reshape(batch_size, sequence_length, self.num_kv_heads, self.head_dim)
        value = value.reshape(batch_size, sequence_length, self.num_kv_heads, self.head_dim)
        query = self.q_norm(query)
        key = self.k_norm(key)
        query, key = self._apply_qwen3_vl_rope(positions, query, key)
        no_padding = attention_mask is None
        if no_padding:
            attention_output = torch.nn.functional.scaled_dot_product_attention(
                query.transpose(1, 2),
                key.transpose(1, 2),
                value.transpose(1, 2),
                dropout_p=0.0,
                is_causal=sequence_length &gt; 1,
                scale=self.scaling,
                enable_gqa=self.num_heads != self.num_kv_heads,
            ).transpose(1, 2)
        else:
            groups = self.num_heads // self.num_kv_heads
            key = (key&#91;:, :, :, None, :&#93;.expand(-1, -1, -1, groups, -1).reshape(batch_size, sequence_length,
                                                                                self.num_heads, self.head_dim))
            value = (value&#91;:, :, :, None, :&#93;.expand(-1, -1, -1, groups, -1).reshape(batch_size, sequence_length,
                                                                                    self.num_heads, self.head_dim))
            causal_mask = torch.ones(sequence_length, sequence_length, device=query.device, dtype=torch.bool).tril()
            key_mask = attention_mask.to(device=query.device, dtype=torch.bool)
            sdpa_mask = causal_mask&#91;None, None, :, :&#93; &amp; key_mask&#91;:, None, None, :&#93;
            attention_output = torch.nn.functional.scaled_dot_product_attention(
                query.transpose(1, 2),
                key.transpose(1, 2),
                value.transpose(1, 2),
                attn_mask=sdpa_mask,
                dropout_p=0.0,
                is_causal=False,
                scale=self.scaling,
            ).transpose(1, 2)
        output, _ = self.o_proj(attention_output.reshape(batch_size, sequence_length, -1))
        return output</code></pre></details>
<h3 id="fastvideo.models.encoders.lingbot_video.LingBotVideoQwen3VLAttention.forward"><code>fastvideo.models.encoders.lingbot_video.LingBotVideoQwen3VLAttention.forward</code></h3>
<pre class="doc-signature"><code>forward(positions: torch.Tensor, hidden_states: torch.Tensor, attention_mask: torch.Tensor | None = None) -&gt; torch.Tensor</code></pre>
<p>Apply fused projections, QK norm, RoPE, and causal grouped attention.</p>
<details><summary>Source</summary><pre><code>def forward(
    self,
    positions: torch.Tensor,
    hidden_states: torch.Tensor,
    attention_mask: torch.Tensor | None = None,
) -&gt; torch.Tensor:
    &quot;&quot;&quot;Apply fused projections, QK norm, RoPE, and causal grouped attention.&quot;&quot;&quot;
    qkv, _ = self.qkv_proj(hidden_states)
    query, key, value = qkv.split(&#91;self.q_size, self.kv_size, self.kv_size&#93;, dim=-1)
    batch_size, sequence_length = query.shape&#91;:2&#93;
    query = query.reshape(batch_size, sequence_length, self.num_heads, self.head_dim)
    key = key.reshape(batch_size, sequence_length, self.num_kv_heads, self.head_dim)
    value = value.reshape(batch_size, sequence_length, self.num_kv_heads, self.head_dim)
    query = self.q_norm(query)
    key = self.k_norm(key)
    query, key = self._apply_qwen3_vl_rope(positions, query, key)
    no_padding = attention_mask is None
    if no_padding:
        attention_output = torch.nn.functional.scaled_dot_product_attention(
            query.transpose(1, 2),
            key.transpose(1, 2),
            value.transpose(1, 2),
            dropout_p=0.0,
            is_causal=sequence_length &gt; 1,
            scale=self.scaling,
            enable_gqa=self.num_heads != self.num_kv_heads,
        ).transpose(1, 2)
    else:
        groups = self.num_heads // self.num_kv_heads
        key = (key&#91;:, :, :, None, :&#93;.expand(-1, -1, -1, groups, -1).reshape(batch_size, sequence_length,
                                                                            self.num_heads, self.head_dim))
        value = (value&#91;:, :, :, None, :&#93;.expand(-1, -1, -1, groups, -1).reshape(batch_size, sequence_length,
                                                                                self.num_heads, self.head_dim))
        causal_mask = torch.ones(sequence_length, sequence_length, device=query.device, dtype=torch.bool).tril()
        key_mask = attention_mask.to(device=query.device, dtype=torch.bool)
        sdpa_mask = causal_mask&#91;None, None, :, :&#93; &amp; key_mask&#91;:, None, None, :&#93;
        attention_output = torch.nn.functional.scaled_dot_product_attention(
            query.transpose(1, 2),
            key.transpose(1, 2),
            value.transpose(1, 2),
            attn_mask=sdpa_mask,
            dropout_p=0.0,
            is_causal=False,
            scale=self.scaling,
        ).transpose(1, 2)
    output, _ = self.o_proj(attention_output.reshape(batch_size, sequence_length, -1))
    return output</code></pre></details>
<h2 id="fastvideo.models.encoders.lingbot_video.LingBotVideoQwen3VLDecoderLayer"><code>fastvideo.models.encoders.lingbot_video.LingBotVideoQwen3VLDecoderLayer</code></h2>
<pre class="doc-signature"><code>LingBotVideoQwen3VLDecoderLayer(config: Any, prefix: str)</code></pre>
<p>Qwen3-VL decoder layer with explicit official residual rounding order.</p>
<p>Build the final Qwen3-VL attention once to avoid orphan parameters.</p>
<details><summary>Source</summary><pre><code>class LingBotVideoQwen3VLDecoderLayer(Qwen3DecoderLayer):
    &quot;&quot;&quot;Qwen3-VL decoder layer with explicit official residual rounding order.&quot;&quot;&quot;

    def __init__(self, config: Any, prefix: str) -&gt; None:
        &quot;&quot;&quot;Build the final Qwen3-VL attention once to avoid orphan parameters.&quot;&quot;&quot;
        nn.Module.__init__(self)
        self.hidden_size = config.hidden_size
        quant_config = getattr(config, &quot;quant_config&quot;, None)
        self.self_attn = LingBotVideoQwen3VLAttention(
            config=config,
            hidden_size=self.hidden_size,
            num_heads=config.num_attention_heads,
            num_kv_heads=config.num_key_value_heads,
            rope_theta=config.rope_theta,
            rope_scaling=config.rope_scaling,
            max_position_embeddings=config.max_position_embeddings,
            quant_config=quant_config,
            bias=config.attention_bias,
            prefix=f&quot;&#123;prefix&#125;.self_attn&quot;,
        )
        self.mlp = Qwen3MLP(
            hidden_size=self.hidden_size,
            intermediate_size=config.intermediate_size,
            hidden_act=config.hidden_act,
            quant_config=quant_config,
            bias=getattr(config, &quot;mlp_bias&quot;, False),
            prefix=f&quot;&#123;prefix&#125;.mlp&quot;,
        )
        self.input_layernorm = RMSNorm(self.hidden_size, eps=config.rms_norm_eps)
        self.post_attention_layernorm = RMSNorm(self.hidden_size, eps=config.rms_norm_eps)

    def forward(
        self,
        positions: torch.Tensor,
        hidden_states: torch.Tensor,
        attention_mask: torch.Tensor | None = None,
    ) -&gt; torch.Tensor:
        &quot;&quot;&quot;Run attention and MLP with each residual sum rounded before normalization.&quot;&quot;&quot;
        residual = hidden_states
        hidden_states = self.input_layernorm(hidden_states)
        hidden_states = self.self_attn(positions, hidden_states, attention_mask)
        hidden_states = residual + hidden_states
        residual = hidden_states
        hidden_states = self.post_attention_layernorm(hidden_states)
        hidden_states = self.mlp(hidden_states)
        return residual + hidden_states</code></pre></details>
<h3 id="fastvideo.models.encoders.lingbot_video.LingBotVideoQwen3VLDecoderLayer.forward"><code>fastvideo.models.encoders.lingbot_video.LingBotVideoQwen3VLDecoderLayer.forward</code></h3>
<pre class="doc-signature"><code>forward(positions: torch.Tensor, hidden_states: torch.Tensor, attention_mask: torch.Tensor | None = None) -&gt; torch.Tensor</code></pre>
<p>Run attention and MLP with each residual sum rounded before normalization.</p>
<details><summary>Source</summary><pre><code>def forward(
    self,
    positions: torch.Tensor,
    hidden_states: torch.Tensor,
    attention_mask: torch.Tensor | None = None,
) -&gt; torch.Tensor:
    &quot;&quot;&quot;Run attention and MLP with each residual sum rounded before normalization.&quot;&quot;&quot;
    residual = hidden_states
    hidden_states = self.input_layernorm(hidden_states)
    hidden_states = self.self_attn(positions, hidden_states, attention_mask)
    hidden_states = residual + hidden_states
    residual = hidden_states
    hidden_states = self.post_attention_layernorm(hidden_states)
    hidden_states = self.mlp(hidden_states)
    return residual + hidden_states</code></pre></details>
<h2 id="fastvideo.models.encoders.lingbot_video.LingBotVideoQwen3VLTextModel"><code>fastvideo.models.encoders.lingbot_video.LingBotVideoQwen3VLTextModel</code></h2>
<pre class="doc-signature"><code>LingBotVideoQwen3VLTextModel(config)</code></pre>
<p>Load the Qwen3-VL language-model subset without its vision tower or LM head.</p>
<p>Construct the exact Qwen3-VL module graph without replacing base layers.</p>
<details><summary>Source</summary><pre><code>class LingBotVideoQwen3VLTextModel(Qwen3ForCausalLM):
    &quot;&quot;&quot;Load the Qwen3-VL language-model subset without its vision tower or LM head.&quot;&quot;&quot;

    supports_hf_from_pretrained = False

    def __init__(self, config) -&gt; None:
        &quot;&quot;&quot;Construct the exact Qwen3-VL module graph without replacing base layers.&quot;&quot;&quot;
        TextEncoder.__init__(self, config)
        self.quant_config = getattr(config, &quot;quant_config&quot;, None)
        if getattr(config, &quot;lora_config&quot;, None) is not None:
            max_loras = getattr(config.lora_config, &quot;max_loras&quot;, 1)
            lora_vocab_size = getattr(config.lora_config, &quot;lora_extra_vocab_size&quot;, 1)
            lora_vocab = lora_vocab_size * max_loras
        else:
            lora_vocab = 0
        self.vocab_size = config.vocab_size + lora_vocab
        self.org_vocab_size = config.vocab_size
        self.embed_tokens = VocabParallelEmbedding(
            self.vocab_size,
            config.hidden_size,
            org_num_embeddings=config.vocab_size,
            quant_config=self.quant_config,
        )
        self.layers = nn.ModuleList(
            LingBotVideoQwen3VLDecoderLayer(config, prefix=f&quot;&#123;config.prefix&#125;.layers.&#123;index&#125;&quot;)
            for index in range(config.num_hidden_layers))
        self.norm = RMSNorm(config.hidden_size, eps=config.rms_norm_eps)

    def forward(
        self,
        input_ids: torch.Tensor | None = None,
        position_ids: torch.Tensor | None = None,
        attention_mask: torch.Tensor | None = None,
        inputs_embeds: torch.Tensor | None = None,
        output_hidden_states: bool | None = None,
        **kwargs: Any,
    ) -&gt; BaseEncoderOutput:
        &quot;&quot;&quot;Run explicit Qwen3-VL layers and return the requested hidden-state tuple.&quot;&quot;&quot;
        del kwargs
        output_hidden_states = (output_hidden_states
                                if output_hidden_states is not None else self.config.output_hidden_states)
        if inputs_embeds is None:
            if input_ids is None:
                raise ValueError(&quot;input_ids or inputs_embeds is required&quot;)
            hidden_states = self.get_input_embeddings(input_ids)
        else:
            hidden_states = inputs_embeds
        if position_ids is None:
            position_ids = torch.arange(hidden_states.shape&#91;1&#93;, device=hidden_states.device).unsqueeze(0)
        if attention_mask is not None and bool(attention_mask.to(torch.bool).all()):
            attention_mask = None
        all_hidden_states: tuple&#91;torch.Tensor, ...&#93; | None = () if output_hidden_states else None
        for layer in self.layers:
            if all_hidden_states is not None:
                all_hidden_states += (hidden_states, )
            hidden_states = layer(position_ids, hidden_states, attention_mask)
        hidden_states = self.norm(hidden_states)
        if all_hidden_states is not None:
            all_hidden_states += (hidden_states, )
        return BaseEncoderOutput(
            last_hidden_state=hidden_states,
            hidden_states=all_hidden_states,
        )

    def load_weights(self, weights: Iterable&#91;tuple&#91;str, torch.Tensor&#93;&#93;) -&gt; set&#91;str&#93;:
        &quot;&quot;&quot;Accept either official compound keys or converted native keys.&quot;&quot;&quot;
        prefix = &quot;model.language_model.&quot;
        language_weights = ((name&#91;len(prefix):&#93; if name.startswith(prefix) else name, tensor)
                            for name, tensor in weights
                            if name.startswith(prefix) or not name.startswith((&quot;model.&quot;, &quot;lm_head.&quot;)))
        return super().load_weights(language_weights)</code></pre></details>
<h3 id="fastvideo.models.encoders.lingbot_video.LingBotVideoQwen3VLTextModel.forward"><code>fastvideo.models.encoders.lingbot_video.LingBotVideoQwen3VLTextModel.forward</code></h3>
<pre class="doc-signature"><code>forward(input_ids: torch.Tensor | None = None, position_ids: torch.Tensor | None = None, attention_mask: torch.Tensor | None = None, inputs_embeds: torch.Tensor | None = None, output_hidden_states: bool | None = None, **kwargs: Any) -&gt; BaseEncoderOutput</code></pre>
<p>Run explicit Qwen3-VL layers and return the requested hidden-state tuple.</p>
<details><summary>Source</summary><pre><code>def forward(
    self,
    input_ids: torch.Tensor | None = None,
    position_ids: torch.Tensor | None = None,
    attention_mask: torch.Tensor | None = None,
    inputs_embeds: torch.Tensor | None = None,
    output_hidden_states: bool | None = None,
    **kwargs: Any,
) -&gt; BaseEncoderOutput:
    &quot;&quot;&quot;Run explicit Qwen3-VL layers and return the requested hidden-state tuple.&quot;&quot;&quot;
    del kwargs
    output_hidden_states = (output_hidden_states
                            if output_hidden_states is not None else self.config.output_hidden_states)
    if inputs_embeds is None:
        if input_ids is None:
            raise ValueError(&quot;input_ids or inputs_embeds is required&quot;)
        hidden_states = self.get_input_embeddings(input_ids)
    else:
        hidden_states = inputs_embeds
    if position_ids is None:
        position_ids = torch.arange(hidden_states.shape&#91;1&#93;, device=hidden_states.device).unsqueeze(0)
    if attention_mask is not None and bool(attention_mask.to(torch.bool).all()):
        attention_mask = None
    all_hidden_states: tuple&#91;torch.Tensor, ...&#93; | None = () if output_hidden_states else None
    for layer in self.layers:
        if all_hidden_states is not None:
            all_hidden_states += (hidden_states, )
        hidden_states = layer(position_ids, hidden_states, attention_mask)
    hidden_states = self.norm(hidden_states)
    if all_hidden_states is not None:
        all_hidden_states += (hidden_states, )
    return BaseEncoderOutput(
        last_hidden_state=hidden_states,
        hidden_states=all_hidden_states,
    )</code></pre></details>
<h3 id="fastvideo.models.encoders.lingbot_video.LingBotVideoQwen3VLTextModel.load_weights"><code>fastvideo.models.encoders.lingbot_video.LingBotVideoQwen3VLTextModel.load_weights</code></h3>
<pre class="doc-signature"><code>load_weights(weights: Iterable&#91;tuple&#91;str, torch.Tensor&#93;&#93;) -&gt; set&#91;str&#93;</code></pre>
<p>Accept either official compound keys or converted native keys.</p>
<details><summary>Source</summary><pre><code>def load_weights(self, weights: Iterable&#91;tuple&#91;str, torch.Tensor&#93;&#93;) -&gt; set&#91;str&#93;:
    &quot;&quot;&quot;Accept either official compound keys or converted native keys.&quot;&quot;&quot;
    prefix = &quot;model.language_model.&quot;
    language_weights = ((name&#91;len(prefix):&#93; if name.startswith(prefix) else name, tensor)
                        for name, tensor in weights
                        if name.startswith(prefix) or not name.startswith((&quot;model.&quot;, &quot;lm_head.&quot;)))
    return super().load_weights(language_weights)</code></pre></details>
</div>
