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

qwen2_5_vl_custom

fastvideo.models.encoders.qwen2_5_vl_custom.Qwen2_5_VLMLP

Qwen2_5_VLMLP(config, bias: bool = False)
Source
class Qwen2_5_VLMLP(nn.Module):
def __init__(self, config, bias: bool = False):
    super().__init__()
    self.hidden_size = config.hidden_size
    self.intermediate_size = config.intermediate_size
    self.gate_proj = nn.Linear(self.hidden_size, self.intermediate_size, bias=bias)
    self.up_proj = nn.Linear(self.hidden_size, self.intermediate_size, bias=bias)
    self.down_proj = nn.Linear(self.intermediate_size, self.hidden_size, bias=bias)
    self.act_fn = ACT2FN[config.hidden_act]

def forward(self, hidden_state):
    return self.down_proj(self.act_fn(self.gate_proj(hidden_state)) * self.up_proj(hidden_state))</code></pre></details>

fastvideo.models.encoders.qwen2_5_vl_custom.Qwen2_5_VLMLP.forward

forward(hidden_state)
Source
def forward(self, hidden_state):
    return self.down_proj(self.act_fn(self.gate_proj(hidden_state)) * self.up_proj(hidden_state))

fastvideo.models.encoders.qwen2_5_vl_custom.Qwen2_5_VisionPatchEmbed

Qwen2_5_VisionPatchEmbed(patch_size: int = 14, temporal_patch_size: int = 2, in_channels: int = 3, embed_dim: int = 1152)
Source
class Qwen2_5_VisionPatchEmbed(nn.Module):
def __init__(
    self,
    patch_size: int = 14,
    temporal_patch_size: int = 2,
    in_channels: int = 3,
    embed_dim: int = 1152,
) -&gt; None:
    super().__init__()
    self.patch_size = patch_size
    self.temporal_patch_size = temporal_patch_size
    self.in_channels = in_channels
    self.embed_dim = embed_dim

    kernel_size = &#91;temporal_patch_size, patch_size, patch_size&#93;
    self.proj = nn.Conv3d(
        in_channels,
        embed_dim,
        kernel_size=kernel_size,
        stride=kernel_size,
        bias=False,
    )

def forward(self, hidden_states: torch.Tensor) -&gt; torch.Tensor:
    target_dtype = self.proj.weight.dtype
    hidden_states = hidden_states.view(
        -1,
        self.in_channels,
        self.temporal_patch_size,
        self.patch_size,
        self.patch_size,
    )
    hidden_states = self.proj(hidden_states.to(dtype=target_dtype)).view(-1, self.embed_dim)
    return hidden_states</code></pre></details>

fastvideo.models.encoders.qwen2_5_vl_custom.Qwen2_5_VisionPatchEmbed.forward

forward(hidden_states: torch.Tensor) -> torch.Tensor
Source
def forward(self, hidden_states: torch.Tensor) -> torch.Tensor:
    target_dtype = self.proj.weight.dtype
    hidden_states = hidden_states.view(
        -1,
        self.in_channels,
        self.temporal_patch_size,
        self.patch_size,
        self.patch_size,
    )
    hidden_states = self.proj(hidden_states.to(dtype=target_dtype)).view(-1, self.embed_dim)
    return hidden_states

fastvideo.models.encoders.qwen2_5_vl_custom.Qwen2_5_VisionRotaryEmbedding

Qwen2_5_VisionRotaryEmbedding(dim: int, theta: float = 10000.0)
Source
class Qwen2_5_VisionRotaryEmbedding(nn.Module):
def __init__(self, dim: int, theta: float = 10000.0) -&gt; None:
    super().__init__()
    inv_freq = 1.0 / (theta**(torch.arange(0, dim, 2, dtype=torch.float) / dim))
    self.register_buffer(&quot;inv_freq&quot;, inv_freq, persistent=False)
    self.dim = dim

def init_weights(self, buffer_device: Optional&#91;torch.device&#93; = None):
    device = self.inv_freq.device if buffer_device is None else buffer_device
    self.inv_freq = 1.0 / (10000.0**(torch.arange(0, self.dim, 2, dtype=torch.float) / self.dim)).to(device)

def forward(self, seqlen: int) -&gt; torch.Tensor:
    seq = torch.arange(seqlen, device=self.inv_freq.device, dtype=self.inv_freq.dtype)
    freqs = torch.outer(seq, self.inv_freq)
    return freqs</code></pre></details>

fastvideo.models.encoders.qwen2_5_vl_custom.Qwen2_5_VisionRotaryEmbedding.init_weights

init_weights(buffer_device: Optional[torch.device] = None)
Source
def init_weights(self, buffer_device: Optional[torch.device] = None):
    device = self.inv_freq.device if buffer_device is None else buffer_device
    self.inv_freq = 1.0 / (10000.0**(torch.arange(0, self.dim, 2, dtype=torch.float) / self.dim)).to(device)

fastvideo.models.encoders.qwen2_5_vl_custom.Qwen2_5_VisionRotaryEmbedding.forward

forward(seqlen: int) -> torch.Tensor
Source
def forward(self, seqlen: int) -> torch.Tensor:
    seq = torch.arange(seqlen, device=self.inv_freq.device, dtype=self.inv_freq.dtype)
    freqs = torch.outer(seq, self.inv_freq)
    return freqs

fastvideo.models.encoders.qwen2_5_vl_custom.Qwen2RMSNorm

Qwen2RMSNorm(hidden_size, eps = 1e-06)

Qwen2RMSNorm is equivalent to T5LayerNorm

Source
class Qwen2RMSNorm(nn.Module):
def __init__(self, hidden_size, eps=1e-6):
    &quot;&quot;&quot;
    Qwen2RMSNorm is equivalent to T5LayerNorm
    &quot;&quot;&quot;
    super().__init__()
    self.weight = nn.Parameter(torch.ones(hidden_size))
    self.variance_epsilon = eps

def forward(self, hidden_states):
    input_dtype = hidden_states.dtype
    hidden_states = hidden_states.to(torch.float32)
    variance = hidden_states.pow(2).mean(-1, keepdim=True)
    hidden_states = hidden_states * torch.rsqrt(variance + self.variance_epsilon)
    return self.weight * hidden_states.to(input_dtype)

def extra_repr(self):
    return f&quot;&#123;tuple(self.weight.shape)&#125;, eps=&#123;self.variance_epsilon&#125;&quot;</code></pre></details>

fastvideo.models.encoders.qwen2_5_vl_custom.Qwen2RMSNorm.forward

forward(hidden_states)
Source
def forward(self, hidden_states):
    input_dtype = hidden_states.dtype
    hidden_states = hidden_states.to(torch.float32)
    variance = hidden_states.pow(2).mean(-1, keepdim=True)
    hidden_states = hidden_states * torch.rsqrt(variance + self.variance_epsilon)
    return self.weight * hidden_states.to(input_dtype)

fastvideo.models.encoders.qwen2_5_vl_custom.Qwen2RMSNorm.extra_repr

extra_repr()
Source
def extra_repr(self):
    return f"{tuple(self.weight.shape)}, eps={self.variance_epsilon}"

fastvideo.models.encoders.qwen2_5_vl_custom.Qwen2_5_VLPatchMerger

Qwen2_5_VLPatchMerger(dim: int, context_dim: int, spatial_merge_size: int = 2)
Source
class Qwen2_5_VLPatchMerger(nn.Module):
def __init__(self, dim: int, context_dim: int, spatial_merge_size: int = 2) -&gt; None:
    super().__init__()
    self.hidden_size = context_dim * (spatial_merge_size**2)
    self.ln_q = Qwen2RMSNorm(context_dim, eps=1e-6)
    self.mlp = nn.Sequential(
        nn.Linear(self.hidden_size, self.hidden_size),
        nn.GELU(),
        nn.Linear(self.hidden_size, dim),
    )

def forward(self, x: torch.Tensor) -&gt; torch.Tensor:
    x = self.mlp(self.ln_q(x).view(-1, self.hidden_size))
    return x

def init_weights(self, buffer_device: Optional&#91;torch.device&#93; = None):
    pass</code></pre></details>

fastvideo.models.encoders.qwen2_5_vl_custom.Qwen2_5_VLPatchMerger.forward

forward(x: torch.Tensor) -> torch.Tensor
Source
def forward(self, x: torch.Tensor) -> torch.Tensor:
    x = self.mlp(self.ln_q(x).view(-1, self.hidden_size))
    return x

fastvideo.models.encoders.qwen2_5_vl_custom.Qwen2_5_VLPatchMerger.init_weights

init_weights(buffer_device: Optional[torch.device] = None)
Source
def init_weights(self, buffer_device: Optional[torch.device] = None):
    pass

fastvideo.models.encoders.qwen2_5_vl_custom.apply_rotary_pos_emb_flashatt

apply_rotary_pos_emb_flashatt(tensor: torch.Tensor, freqs: torch.Tensor) -> torch.Tensor
Source
def apply_rotary_pos_emb_flashatt(tensor: torch.Tensor, freqs: torch.Tensor) -> torch.Tensor:
    tensor_ = tensor.float()
    cos = freqs.cos().float()
    sin = freqs.sin().float()
    output = apply_rotary_emb(tensor_, cos, sin).type_as(tensor)
    return output

fastvideo.models.encoders.qwen2_5_vl_custom.Qwen2_5_VLVisionFlashAttention2

Qwen2_5_VLVisionFlashAttention2(dim: int, num_heads: int = 16)
Source
class Qwen2_5_VLVisionFlashAttention2(nn.Module):
def __init__(self, dim: int, num_heads: int = 16) -&gt; None:
    super().__init__()
    self.num_heads = num_heads
    self.qkv = nn.Linear(dim, dim * 3, bias=True)
    self.proj = nn.Linear(dim, dim)

def forward(
    self,
    hidden_states: torch.Tensor,
    cu_seqlens: torch.Tensor,
    rotary_pos_emb: torch.Tensor = None,
) -&gt; torch.Tensor:
    seq_length = hidden_states.shape&#91;0&#93;
    q, k, v = self.qkv(hidden_states).reshape(seq_length, 3, self.num_heads, -1).permute(1, 0, 2, 3).unbind(0)
    q = apply_rotary_pos_emb_flashatt(q.unsqueeze(0), rotary_pos_emb).squeeze(0)
    k = apply_rotary_pos_emb_flashatt(k.unsqueeze(0), rotary_pos_emb).squeeze(0)

    max_seqlen = (cu_seqlens&#91;1:&#93; - cu_seqlens&#91;:-1&#93;).max().item()
    attn_output = flash_attn_varlen_func(q, k, v, cu_seqlens, cu_seqlens, max_seqlen,
                                         max_seqlen).reshape(seq_length, -1)
    attn_output = self.proj(attn_output)
    return attn_output</code></pre></details>

fastvideo.models.encoders.qwen2_5_vl_custom.Qwen2_5_VLVisionFlashAttention2.forward

forward(hidden_states: torch.Tensor, cu_seqlens: torch.Tensor, rotary_pos_emb: torch.Tensor = None) -> torch.Tensor
Source
def forward(
    self,
    hidden_states: torch.Tensor,
    cu_seqlens: torch.Tensor,
    rotary_pos_emb: torch.Tensor = None,
) -> torch.Tensor:
    seq_length = hidden_states.shape[0]
    q, k, v = self.qkv(hidden_states).reshape(seq_length, 3, self.num_heads, -1).permute(1, 0, 2, 3).unbind(0)
    q = apply_rotary_pos_emb_flashatt(q.unsqueeze(0), rotary_pos_emb).squeeze(0)
    k = apply_rotary_pos_emb_flashatt(k.unsqueeze(0), rotary_pos_emb).squeeze(0)
max_seqlen = (cu_seqlens&#91;1:&#93; - cu_seqlens&#91;:-1&#93;).max().item()
attn_output = flash_attn_varlen_func(q, k, v, cu_seqlens, cu_seqlens, max_seqlen,
                                     max_seqlen).reshape(seq_length, -1)
attn_output = self.proj(attn_output)
return attn_output</code></pre></details>

fastvideo.models.encoders.qwen2_5_vl_custom.rotate_half

rotate_half(x)

Rotates half the hidden dims of the input.

Source
def rotate_half(x):
    """Rotates half the hidden dims of the input."""
    x1 = x[..., :x.shape[-1] // 2]
    x2 = x[..., x.shape[-1] // 2:]
    return torch.cat((-x2, x1), dim=-1)

fastvideo.models.encoders.qwen2_5_vl_custom.apply_rotary_pos_emb_vision

apply_rotary_pos_emb_vision(tensor: torch.Tensor, freqs: torch.Tensor) -> torch.Tensor
Source
def apply_rotary_pos_emb_vision(tensor: torch.Tensor, freqs: torch.Tensor) -> torch.Tensor:
    orig_dtype = tensor.dtype
    tensor = tensor.float()
    cos = freqs.cos()
    sin = freqs.sin()
    cos = cos.unsqueeze(1).repeat(1, 1, 2).unsqueeze(0).float()
    sin = sin.unsqueeze(1).repeat(1, 1, 2).unsqueeze(0).float()
    output = (tensor * cos) + (rotate_half(tensor) * sin)
    output = output.to(orig_dtype)
    return output

fastvideo.models.encoders.qwen2_5_vl_custom.Qwen2_5_VLVisionSdpaAttention

Qwen2_5_VLVisionSdpaAttention(dim: int, num_heads: int = 16)
Source
class Qwen2_5_VLVisionSdpaAttention(nn.Module):
def __init__(self, dim: int, num_heads: int = 16) -&gt; None:
    super().__init__()
    self.num_heads = num_heads
    self.qkv = nn.Linear(dim, dim * 3, bias=True)
    self.proj = nn.Linear(dim, dim)

def forward(
    self,
    hidden_states: torch.Tensor,
    cu_seqlens: torch.Tensor,
    rotary_pos_emb: torch.Tensor = None,
) -&gt; torch.Tensor:
    seq_length = hidden_states.shape&#91;0&#93;
    q, k, v = self.qkv(hidden_states).reshape(seq_length, 3, self.num_heads, -1).permute(1, 0, 2, 3).unbind(0)
    q = apply_rotary_pos_emb_vision(q.unsqueeze(0), rotary_pos_emb).squeeze(0)
    k = apply_rotary_pos_emb_vision(k.unsqueeze(0), rotary_pos_emb).squeeze(0)

    attention_mask = torch.zeros(&#91;1, seq_length, seq_length&#93;, device=q.device, dtype=torch.bool)
    for i in range(1, len(cu_seqlens)):
        attention_mask&#91;
            ...,
            cu_seqlens&#91;i - 1&#93;:cu_seqlens&#91;i&#93;,
            cu_seqlens&#91;i - 1&#93;:cu_seqlens&#91;i&#93;,
        &#93; = True
    q = q.transpose(0, 1)
    k = k.transpose(0, 1)
    v = v.transpose(0, 1)
    attn_output = F.scaled_dot_product_attention(q, k, v, attention_mask, dropout_p=0.0)
    attn_output = attn_output.transpose(0, 1)
    attn_output = attn_output.reshape(seq_length, -1)
    attn_output = self.proj(attn_output)
    return attn_output</code></pre></details>

fastvideo.models.encoders.qwen2_5_vl_custom.Qwen2_5_VLVisionSdpaAttention.forward

forward(hidden_states: torch.Tensor, cu_seqlens: torch.Tensor, rotary_pos_emb: torch.Tensor = None) -> torch.Tensor
Source
def forward(
    self,
    hidden_states: torch.Tensor,
    cu_seqlens: torch.Tensor,
    rotary_pos_emb: torch.Tensor = None,
) -> torch.Tensor:
    seq_length = hidden_states.shape[0]
    q, k, v = self.qkv(hidden_states).reshape(seq_length, 3, self.num_heads, -1).permute(1, 0, 2, 3).unbind(0)
    q = apply_rotary_pos_emb_vision(q.unsqueeze(0), rotary_pos_emb).squeeze(0)
    k = apply_rotary_pos_emb_vision(k.unsqueeze(0), rotary_pos_emb).squeeze(0)
attention_mask = torch.zeros(&#91;1, seq_length, seq_length&#93;, device=q.device, dtype=torch.bool)
for i in range(1, len(cu_seqlens)):
    attention_mask&#91;
        ...,
        cu_seqlens&#91;i - 1&#93;:cu_seqlens&#91;i&#93;,
        cu_seqlens&#91;i - 1&#93;:cu_seqlens&#91;i&#93;,
    &#93; = True
q = q.transpose(0, 1)
k = k.transpose(0, 1)
v = v.transpose(0, 1)
attn_output = F.scaled_dot_product_attention(q, k, v, attention_mask, dropout_p=0.0)
attn_output = attn_output.transpose(0, 1)
attn_output = attn_output.reshape(seq_length, -1)
attn_output = self.proj(attn_output)
return attn_output</code></pre></details>

fastvideo.models.encoders.qwen2_5_vl_custom.Qwen2_5_VLVisionBlock

Qwen2_5_VLVisionBlock(config, attn_implementation: str = 'sdpa')
Source
class Qwen2_5_VLVisionBlock(nn.Module):
def __init__(self, config, attn_implementation: str = &quot;sdpa&quot;) -&gt; None:
    super().__init__()
    self.norm1 = Qwen2RMSNorm(config.hidden_size, eps=1e-6)
    self.norm2 = Qwen2RMSNorm(config.hidden_size, eps=1e-6)
    self.attn = QWEN2_5_VL_VISION_ATTENTION_CLASSES&#91;attn_implementation&#93;(config.hidden_size,
                                                                         num_heads=config.num_heads)
    self.mlp = Qwen2_5_VLMLP(config, bias=True)

def forward(self, hidden_states, cu_seqlens, rotary_pos_emb) -&gt; torch.Tensor:
    hidden_states = hidden_states + self.attn(
        self.norm1(hidden_states),
        cu_seqlens=cu_seqlens,
        rotary_pos_emb=rotary_pos_emb,
    )
    hidden_states = hidden_states + self.mlp(self.norm2(hidden_states))
    return hidden_states</code></pre></details>

fastvideo.models.encoders.qwen2_5_vl_custom.Qwen2_5_VLVisionBlock.forward

forward(hidden_states, cu_seqlens, rotary_pos_emb) -> torch.Tensor
Source
def forward(self, hidden_states, cu_seqlens, rotary_pos_emb) -> torch.Tensor:
    hidden_states = hidden_states + self.attn(
        self.norm1(hidden_states),
        cu_seqlens=cu_seqlens,
        rotary_pos_emb=rotary_pos_emb,
    )
    hidden_states = hidden_states + self.mlp(self.norm2(hidden_states))
    return hidden_states

fastvideo.models.encoders.qwen2_5_vl_custom.Qwen2_5_VisionTransformerPretrainedModel

Qwen2_5_VisionTransformerPretrainedModel(config, parent_torch_dtype = None)
Source
class Qwen2_5_VisionTransformerPretrainedModel(nn.Module):
    config_class = Qwen2_5_VLVisionConfig
    _no_split_modules = ["Qwen2_5_VLVisionBlock"]
def __init__(self, config, parent_torch_dtype=None) -&gt; None:
    super().__init__()
    config = _normalize_attention_implementation(config)

    config_torch_dtype = getattr(config, &quot;torch_dtype&quot;, None)
    self.dtype = _resolve_torch_dtype(config_torch_dtype if config_torch_dtype is not None else parent_torch_dtype)

    self.spatial_merge_size = config.spatial_merge_size
    self.patch_size = config.patch_size
    self.fullatt_block_indexes = config.fullatt_block_indexes
    self.window_size = config.window_size
    self.spatial_merge_unit = self.spatial_merge_size * self.spatial_merge_size

    self.patch_embed = Qwen2_5_VisionPatchEmbed(
        patch_size=config.patch_size,
        temporal_patch_size=config.temporal_patch_size,
        in_channels=config.in_channels,
        embed_dim=config.hidden_size,
    )

    head_dim = config.hidden_size // config.num_heads
    self.rotary_pos_emb = Qwen2_5_VisionRotaryEmbedding(head_dim // 2)

    self.blocks = nn.ModuleList(
        &#91;Qwen2_5_VLVisionBlock(config, config._attn_implementation) for _ in range(config.depth)&#93;)
    self.merger = Qwen2_5_VLPatchMerger(
        dim=config.out_hidden_size,
        context_dim=config.hidden_size,
        spatial_merge_size=config.spatial_merge_size,
    )
    self.gradient_checkpointing = False

def init_weights(self, buffer_device: Optional&#91;torch.device&#93; = None):
    self.rotary_pos_emb.init_weights(buffer_device)

def rot_pos_emb(self, grid_thw):
    pos_ids = &#91;&#93;
    for t, h, w in grid_thw:
        hpos_ids = torch.arange(h).unsqueeze(1).expand(-1, w)
        hpos_ids = hpos_ids.reshape(
            h // self.spatial_merge_size,
            self.spatial_merge_size,
            w // self.spatial_merge_size,
            self.spatial_merge_size,
        )
        hpos_ids = hpos_ids.permute(0, 2, 1, 3)
        hpos_ids = hpos_ids.flatten()

        wpos_ids = torch.arange(w).unsqueeze(0).expand(h, -1)
        wpos_ids = wpos_ids.reshape(
            h // self.spatial_merge_size,
            self.spatial_merge_size,
            w // self.spatial_merge_size,
            self.spatial_merge_size,
        )
        wpos_ids = wpos_ids.permute(0, 2, 1, 3)
        wpos_ids = wpos_ids.flatten()
        pos_ids.append(torch.stack(&#91;hpos_ids, wpos_ids&#93;, dim=-1).repeat(t, 1))
    pos_ids = torch.cat(pos_ids, dim=0)
    max_grid_size = grid_thw&#91;:, 1:&#93;.max()
    rotary_pos_emb_full = self.rotary_pos_emb(max_grid_size)
    rotary_pos_emb = rotary_pos_emb_full&#91;pos_ids&#93;.flatten(1)
    return rotary_pos_emb

def get_window_index(self, grid_thw):
    window_index: list = &#91;&#93;
    cu_window_seqlens: list = &#91;0&#93;
    window_index_id = 0
    vit_merger_window_size = self.window_size // self.spatial_merge_size // self.patch_size

    for grid_t, grid_h, grid_w in grid_thw:
        llm_grid_h, llm_grid_w = (
            grid_h // self.spatial_merge_size,
            grid_w // self.spatial_merge_size,
        )
        index = torch.arange(grid_t * llm_grid_h * llm_grid_w).reshape(grid_t, llm_grid_h, llm_grid_w)
        pad_h = vit_merger_window_size - llm_grid_h % vit_merger_window_size
        pad_w = vit_merger_window_size - llm_grid_w % vit_merger_window_size
        num_windows_h = (llm_grid_h + pad_h) // vit_merger_window_size
        num_windows_w = (llm_grid_w + pad_w) // vit_merger_window_size
        index_padded = F.pad(index, (0, pad_w, 0, pad_h), &quot;constant&quot;, -100)
        index_padded = index_padded.reshape(
            grid_t,
            num_windows_h,
            vit_merger_window_size,
            num_windows_w,
            vit_merger_window_size,
        )
        index_padded = index_padded.permute(0, 1, 3, 2, 4).reshape(
            grid_t,
            num_windows_h * num_windows_w,
            vit_merger_window_size,
            vit_merger_window_size,
        )
        seqlens = (index_padded != -100).sum(&#91;2, 3&#93;).reshape(-1)
        index_padded = index_padded.reshape(-1)
        index_new = index_padded&#91;index_padded != -100&#93;
        window_index.append(index_new + window_index_id)
        cu_seqlens_tmp = seqlens.cumsum(0) * self.spatial_merge_unit + cu_window_seqlens&#91;-1&#93;
        cu_window_seqlens.extend(cu_seqlens_tmp.tolist())
        window_index_id += (grid_t * llm_grid_h * llm_grid_w).item()
    window_index = torch.cat(window_index, dim=0)

    return window_index, cu_window_seqlens

def forward(self, hidden_states: torch.Tensor, grid_thw: torch.Tensor) -&gt; torch.Tensor:
    &quot;&quot;&quot;
    Args:
        hidden_states (`torch.Tensor` of shape `(batch_size, seq_len, hidden_size)`):
            The final hidden states of the model.
        grid_thw (`torch.Tensor` of shape `(num_images_or_videos, 3)`):
            The temporal, height and width of feature shape of each image in LLM.

    Returns:
        `torch.Tensor`: hidden_states.
    &quot;&quot;&quot;
    hidden_states = self.patch_embed(hidden_states)
    rotary_pos_emb = self.rot_pos_emb(grid_thw)
    window_index, cu_window_seqlens = self.get_window_index(grid_thw)
    cu_window_seqlens = torch.tensor(
        cu_window_seqlens,
        device=hidden_states.device,
        dtype=grid_thw.dtype if torch.jit.is_tracing() else torch.int32,
    )
    cu_window_seqlens = torch.unique_consecutive(cu_window_seqlens)

    seq_len, _ = hidden_states.size()
    hidden_states = hidden_states.reshape(seq_len // self.spatial_merge_unit, self.spatial_merge_unit, -1)
    hidden_states = hidden_states&#91;window_index, :, :&#93;
    hidden_states = hidden_states.reshape(seq_len, -1)
    rotary_pos_emb = rotary_pos_emb.reshape(seq_len // self.spatial_merge_unit, self.spatial_merge_unit, -1)
    rotary_pos_emb = rotary_pos_emb&#91;window_index, :, :&#93;
    rotary_pos_emb = rotary_pos_emb.reshape(seq_len, -1)

    cu_seqlens = torch.repeat_interleave(grid_thw&#91;:, 1&#93; * grid_thw&#91;:, 2&#93;, grid_thw&#91;:, 0&#93;).cumsum(
        dim=0,
        # Select dtype based on the following factors:
        #  - FA2 requires that cu_seqlens_q must have dtype int32
        #  - torch.onnx.export requires that cu_seqlens_q must have same dtype as grid_thw
        # See https://github.com/huggingface/transformers/pull/34852 for more information
        dtype=grid_thw.dtype if torch.jit.is_tracing() else torch.int32,
    )
    cu_seqlens = F.pad(cu_seqlens, (1, 0), value=0)

    for layer_num, blk in enumerate(self.blocks):
        cu_seqlens_now = cu_seqlens if layer_num in self.fullatt_block_indexes else cu_window_seqlens
        if self.gradient_checkpointing and self.training:
            hidden_states = self._gradient_checkpointing_func(blk.__call__, hidden_states, cu_seqlens_now,
                                                              rotary_pos_emb)
        else:
            hidden_states = blk(
                hidden_states,
                cu_seqlens=cu_seqlens_now,
                rotary_pos_emb=rotary_pos_emb,
            )

    hidden_states = self.merger(hidden_states)
    reverse_indices = torch.argsort(window_index)
    hidden_states = hidden_states&#91;reverse_indices, :&#93;

    return hidden_states</code></pre></details>

fastvideo.models.encoders.qwen2_5_vl_custom.Qwen2_5_VisionTransformerPretrainedModel.init_weights

init_weights(buffer_device: Optional[torch.device] = None)
Source
def init_weights(self, buffer_device: Optional[torch.device] = None):
    self.rotary_pos_emb.init_weights(buffer_device)

fastvideo.models.encoders.qwen2_5_vl_custom.Qwen2_5_VisionTransformerPretrainedModel.rot_pos_emb

rot_pos_emb(grid_thw)
Source
def rot_pos_emb(self, grid_thw):
    pos_ids = []
    for t, h, w in grid_thw:
        hpos_ids = torch.arange(h).unsqueeze(1).expand(-1, w)
        hpos_ids = hpos_ids.reshape(
            h // self.spatial_merge_size,
            self.spatial_merge_size,
            w // self.spatial_merge_size,
            self.spatial_merge_size,
        )
        hpos_ids = hpos_ids.permute(0, 2, 1, 3)
        hpos_ids = hpos_ids.flatten()
    wpos_ids = torch.arange(w).unsqueeze(0).expand(h, -1)
    wpos_ids = wpos_ids.reshape(
        h // self.spatial_merge_size,
        self.spatial_merge_size,
        w // self.spatial_merge_size,
        self.spatial_merge_size,
    )
    wpos_ids = wpos_ids.permute(0, 2, 1, 3)
    wpos_ids = wpos_ids.flatten()
    pos_ids.append(torch.stack(&#91;hpos_ids, wpos_ids&#93;, dim=-1).repeat(t, 1))
pos_ids = torch.cat(pos_ids, dim=0)
max_grid_size = grid_thw&#91;:, 1:&#93;.max()
rotary_pos_emb_full = self.rotary_pos_emb(max_grid_size)
rotary_pos_emb = rotary_pos_emb_full&#91;pos_ids&#93;.flatten(1)
return rotary_pos_emb</code></pre></details>

fastvideo.models.encoders.qwen2_5_vl_custom.Qwen2_5_VisionTransformerPretrainedModel.get_window_index

get_window_index(grid_thw)
Source
def get_window_index(self, grid_thw):
    window_index: list = []
    cu_window_seqlens: list = [0]
    window_index_id = 0
    vit_merger_window_size = self.window_size // self.spatial_merge_size // self.patch_size
for grid_t, grid_h, grid_w in grid_thw:
    llm_grid_h, llm_grid_w = (
        grid_h // self.spatial_merge_size,
        grid_w // self.spatial_merge_size,
    )
    index = torch.arange(grid_t * llm_grid_h * llm_grid_w).reshape(grid_t, llm_grid_h, llm_grid_w)
    pad_h = vit_merger_window_size - llm_grid_h % vit_merger_window_size
    pad_w = vit_merger_window_size - llm_grid_w % vit_merger_window_size
    num_windows_h = (llm_grid_h + pad_h) // vit_merger_window_size
    num_windows_w = (llm_grid_w + pad_w) // vit_merger_window_size
    index_padded = F.pad(index, (0, pad_w, 0, pad_h), &quot;constant&quot;, -100)
    index_padded = index_padded.reshape(
        grid_t,
        num_windows_h,
        vit_merger_window_size,
        num_windows_w,
        vit_merger_window_size,
    )
    index_padded = index_padded.permute(0, 1, 3, 2, 4).reshape(
        grid_t,
        num_windows_h * num_windows_w,
        vit_merger_window_size,
        vit_merger_window_size,
    )
    seqlens = (index_padded != -100).sum(&#91;2, 3&#93;).reshape(-1)
    index_padded = index_padded.reshape(-1)
    index_new = index_padded&#91;index_padded != -100&#93;
    window_index.append(index_new + window_index_id)
    cu_seqlens_tmp = seqlens.cumsum(0) * self.spatial_merge_unit + cu_window_seqlens&#91;-1&#93;
    cu_window_seqlens.extend(cu_seqlens_tmp.tolist())
    window_index_id += (grid_t * llm_grid_h * llm_grid_w).item()
window_index = torch.cat(window_index, dim=0)

return window_index, cu_window_seqlens</code></pre></details>

fastvideo.models.encoders.qwen2_5_vl_custom.Qwen2_5_VisionTransformerPretrainedModel.forward

forward(hidden_states: torch.Tensor, grid_thw: torch.Tensor) -> torch.Tensor

Parameters

hidden_states: `torch.Tensor` of shape `(batch_size, seq_len, hidden_size)`

The final hidden states of the model.

grid_thw: `torch.Tensor` of shape `(num_images_or_videos, 3)`

The temporal, height and width of feature shape of each image in LLM.

Returns

torch.Tensor

torch.Tensor: hidden_states.

Source
def forward(self, hidden_states: torch.Tensor, grid_thw: torch.Tensor) -> torch.Tensor:
    """
    Args:
        hidden_states (`torch.Tensor` of shape `(batch_size, seq_len, hidden_size)`):
            The final hidden states of the model.
        grid_thw (`torch.Tensor` of shape `(num_images_or_videos, 3)`):
            The temporal, height and width of feature shape of each image in LLM.
Returns:
    `torch.Tensor`: hidden_states.
&quot;&quot;&quot;
hidden_states = self.patch_embed(hidden_states)
rotary_pos_emb = self.rot_pos_emb(grid_thw)
window_index, cu_window_seqlens = self.get_window_index(grid_thw)
cu_window_seqlens = torch.tensor(
    cu_window_seqlens,
    device=hidden_states.device,
    dtype=grid_thw.dtype if torch.jit.is_tracing() else torch.int32,
)
cu_window_seqlens = torch.unique_consecutive(cu_window_seqlens)

seq_len, _ = hidden_states.size()
hidden_states = hidden_states.reshape(seq_len // self.spatial_merge_unit, self.spatial_merge_unit, -1)
hidden_states = hidden_states&#91;window_index, :, :&#93;
hidden_states = hidden_states.reshape(seq_len, -1)
rotary_pos_emb = rotary_pos_emb.reshape(seq_len // self.spatial_merge_unit, self.spatial_merge_unit, -1)
rotary_pos_emb = rotary_pos_emb&#91;window_index, :, :&#93;
rotary_pos_emb = rotary_pos_emb.reshape(seq_len, -1)

cu_seqlens = torch.repeat_interleave(grid_thw&#91;:, 1&#93; * grid_thw&#91;:, 2&#93;, grid_thw&#91;:, 0&#93;).cumsum(
    dim=0,
    # Select dtype based on the following factors:
    #  - FA2 requires that cu_seqlens_q must have dtype int32
    #  - torch.onnx.export requires that cu_seqlens_q must have same dtype as grid_thw
    # See https://github.com/huggingface/transformers/pull/34852 for more information
    dtype=grid_thw.dtype if torch.jit.is_tracing() else torch.int32,
)
cu_seqlens = F.pad(cu_seqlens, (1, 0), value=0)

for layer_num, blk in enumerate(self.blocks):
    cu_seqlens_now = cu_seqlens if layer_num in self.fullatt_block_indexes else cu_window_seqlens
    if self.gradient_checkpointing and self.training:
        hidden_states = self._gradient_checkpointing_func(blk.__call__, hidden_states, cu_seqlens_now,
                                                          rotary_pos_emb)
    else:
        hidden_states = blk(
            hidden_states,
            cu_seqlens=cu_seqlens_now,
            rotary_pos_emb=rotary_pos_emb,
        )

hidden_states = self.merger(hidden_states)
reverse_indices = torch.argsort(window_index)
hidden_states = hidden_states&#91;reverse_indices, :&#93;

return hidden_states</code></pre></details>

fastvideo.models.encoders.qwen2_5_vl_custom.Qwen2_5_VLRotaryEmbedding

Qwen2_5_VLRotaryEmbedding(config: Qwen2_5_VLConfig, device = None)
Source
class Qwen2_5_VLRotaryEmbedding(nn.Module):
def __init__(self, config: Qwen2_5_VLConfig, device=None):
    super().__init__()
    # BC: &quot;rope_type&quot; was originally &quot;type&quot;
    if hasattr(config, &quot;rope_scaling&quot;) and config.rope_scaling is not None:
        self.rope_type = config.rope_scaling.get(&quot;rope_type&quot;, config.rope_scaling.get(&quot;type&quot;))
    else:
        self.rope_type = &quot;default&quot;
    self.max_seq_len_cached = config.max_position_embeddings
    self.original_max_seq_len = config.max_position_embeddings

    self.config = config
    if self.rope_type in ROPE_INIT_FUNCTIONS:
        self.rope_init_fn = ROPE_INIT_FUNCTIONS&#91;self.rope_type&#93;
    elif self.rope_type == &quot;default&quot;:
        # transformers&gt;=5 drops the &quot;default&quot; entry from ROPE_INIT_FUNCTIONS.
        self.rope_init_fn = _compute_default_rope_parameters
    else:
        raise KeyError(f&quot;Unsupported rope_type &#x27;&#123;self.rope_type&#125;&#x27;; available: &quot;
                       f&quot;&#123;&#91;&#x27;default&#x27;, *ROPE_INIT_FUNCTIONS&#93;&#125;&quot;)

    inv_freq, self.attention_scaling = self.rope_init_fn(self.config, device)
    self.register_buffer(&quot;inv_freq&quot;, inv_freq, persistent=False)
    self.original_inv_freq = self.inv_freq

def init_weights(self, buffer_device: Optional&#91;torch.device&#93; = None):
    device = self.inv_freq.device if buffer_device is None else buffer_device
    inv_freq, self.attention_scaling = self.rope_init_fn(self.config, device)
    self.inv_freq = inv_freq

def _dynamic_frequency_update(self, position_ids, device):
    raise NotImplementedError(&quot;Dynamic frequency update is not implemented for Qwen2_5_VL&quot;)
    # &quot;&quot;&quot;
    # dynamic RoPE layers should recompute `inv_freq` in the following situations:
    # 1 - growing beyond the cached sequence length (allow scaling)
    # 2 - the current sequence length is in the original scale (avoid losing precision with small sequences)
    # &quot;&quot;&quot;
    # seq_len = torch.max(position_ids) + 1
    # if seq_len &gt; self.max_seq_len_cached:  # growth
    #     inv_freq, self.attention_scaling = self.rope_init_fn(
    #         self.config, device, seq_len=seq_len, **self.rope_kwargs
    #     )
    #     self.register_buffer(&quot;inv_freq&quot;, inv_freq, persistent=False)
    #     self.max_seq_len_cached = seq_len

    # if seq_len &lt; self.original_max_seq_len and self.max_seq_len_cached &gt; self.original_max_seq_len:  # reset
    #     self.register_buffer(&quot;inv_freq&quot;, self.original_inv_freq, persistent=False)
    #     self.max_seq_len_cached = self.original_max_seq_len

@torch.no_grad()
def forward(self, x, position_ids):
    if &quot;dynamic&quot; in self.rope_type:
        self._dynamic_frequency_update(position_ids, device=x.device)

    # Core RoPE block. In contrast to other models, Qwen2_5_VL has different position ids for thw grids
    # So we expand the inv_freq to shape (3, ...)
    inv_freq_expanded = self.inv_freq&#91;None, None, :, None&#93;.float().expand(3, position_ids.shape&#91;1&#93;, -1, 1)
    position_ids_expanded = position_ids&#91;:, :, None, :&#93;.float()  # shape (3, bs, 1, positions)
    # Force float32 (see https://github.com/huggingface/transformers/pull/29285)
    device_type = x.device.type
    device_type = device_type if isinstance(device_type, str) and device_type != &quot;mps&quot; else &quot;cpu&quot;
    with torch.autocast(device_type=device_type, enabled=False):
        freqs = (inv_freq_expanded.float() @ position_ids_expanded.float()).transpose(2, 3)
        emb = torch.cat((freqs, freqs), dim=-1)
        cos = emb.cos()
        sin = emb.sin()

    # Advanced RoPE types (e.g. yarn) apply a post-processing scaling factor, equivalent to scaling attention
    cos = cos * self.attention_scaling
    sin = sin * self.attention_scaling

    return cos.to(dtype=x.dtype), sin.to(dtype=x.dtype)</code></pre></details>

fastvideo.models.encoders.qwen2_5_vl_custom.Qwen2_5_VLRotaryEmbedding.init_weights

init_weights(buffer_device: Optional[torch.device] = None)
Source
def init_weights(self, buffer_device: Optional[torch.device] = None):
    device = self.inv_freq.device if buffer_device is None else buffer_device
    inv_freq, self.attention_scaling = self.rope_init_fn(self.config, device)
    self.inv_freq = inv_freq

fastvideo.models.encoders.qwen2_5_vl_custom.Qwen2_5_VLRotaryEmbedding.forward

forward(x, position_ids)
Source
@torch.no_grad()
def forward(self, x, position_ids):
    if "dynamic" in self.rope_type:
        self._dynamic_frequency_update(position_ids, device=x.device)
# Core RoPE block. In contrast to other models, Qwen2_5_VL has different position ids for thw grids
# So we expand the inv_freq to shape (3, ...)
inv_freq_expanded = self.inv_freq&#91;None, None, :, None&#93;.float().expand(3, position_ids.shape&#91;1&#93;, -1, 1)
position_ids_expanded = position_ids&#91;:, :, None, :&#93;.float()  # shape (3, bs, 1, positions)
# Force float32 (see https://github.com/huggingface/transformers/pull/29285)
device_type = x.device.type
device_type = device_type if isinstance(device_type, str) and device_type != &quot;mps&quot; else &quot;cpu&quot;
with torch.autocast(device_type=device_type, enabled=False):
    freqs = (inv_freq_expanded.float() @ position_ids_expanded.float()).transpose(2, 3)
    emb = torch.cat((freqs, freqs), dim=-1)
    cos = emb.cos()
    sin = emb.sin()

# Advanced RoPE types (e.g. yarn) apply a post-processing scaling factor, equivalent to scaling attention
cos = cos * self.attention_scaling
sin = sin * self.attention_scaling

return cos.to(dtype=x.dtype), sin.to(dtype=x.dtype)</code></pre></details>

fastvideo.models.encoders.qwen2_5_vl_custom.Qwen2MLP

Qwen2MLP(config)
Source
class Qwen2MLP(nn.Module):
def __init__(self, config):
    super().__init__()
    self.config = config
    self.hidden_size = config.hidden_size
    self.intermediate_size = config.intermediate_size
    self.gate_proj = nn.Linear(self.hidden_size, self.intermediate_size, bias=False)
    self.up_proj = nn.Linear(self.hidden_size, self.intermediate_size, bias=False)
    self.down_proj = nn.Linear(self.intermediate_size, self.hidden_size, bias=False)
    self.act_fn = ACT2FN&#91;config.hidden_act&#93;

def forward(self, x):
    # in llama self.w2(F.silu(self.w1(x)) * self.w3(x))
    # i.e. w2 is self.down_proj, w1 is self.gate_proj, w3 is self.up_proj
    down_proj = self.down_proj(self.act_fn(self.gate_proj(x)) * self.up_proj(x))
    return down_proj</code></pre></details>

fastvideo.models.encoders.qwen2_5_vl_custom.Qwen2MLP.forward

forward(x)
Source
def forward(self, x):
    # in llama self.w2(F.silu(self.w1(x)) * self.w3(x))
    # i.e. w2 is self.down_proj, w1 is self.gate_proj, w3 is self.up_proj
    down_proj = self.down_proj(self.act_fn(self.gate_proj(x)) * self.up_proj(x))
    return down_proj

fastvideo.models.encoders.qwen2_5_vl_custom.apply_multimodal_rotary_pos_emb

apply_multimodal_rotary_pos_emb(q, k, cos, sin, mrope_section, unsqueeze_dim = 1)

Applies Rotary Position Embedding with Multimodal Sections to the query and key tensors (https://qwenlm.github.io/blog/qwen2-vl/).

Explanation

Multimodal 3D rotary position embedding is an extension to 1D rotary position embedding. The input embedding sequence contains vision (images / videos) embedding and text embedding or just contains text embedding. For vision embedding part, we apply rotary position embedding on temporal, height and width dimension seperately. Here we split the channel dimension to 3 chunks for the temporal, height and width rotary position embedding. For text embedding part, we just apply 1D rotary position embedding. The three rotary position index (temporal, height and width) of text embedding is always the same, so the text embedding rotary position embedding has no difference with modern LLMs.

Parameters

q: `torch.Tensor`

The query tensor.

k: `torch.Tensor`

The key tensor.

cos: `torch.Tensor`

The cosine part of the rotary embedding.

sin: `torch.Tensor`

The sine part of the rotary embedding.

position_ids: `torch.Tensor`

The position indices of the tokens corresponding to the query and key tensors. For example, this can be used to pass offsetted position ids when working with a KV-cache.

mrope_section: `List(int)`

Multimodal rope section is for channel dimension of temporal, height and width in rope calculation.

unsqueeze_dim: `int`, *optional*, defaults to 1

The 'unsqueeze_dim' argument specifies the dimension along which to unsqueeze cos[position_ids] and sin[position_ids] so that they can be properly broadcasted to the dimensions of q and k. For example, note that cos[position_ids] and sin[position_ids] have the shape [batch_size, seq_len, head_dim]. Then, if q and k have the shape [batch_size, heads, seq_len, head_dim], then setting unsqueeze_dim=1 makes cos[position_ids] and sin[position_ids] broadcastable to the shapes of q and k. Similarly, if q and k have the shape [batch_size, seq_len, heads, head_dim], then set unsqueeze_dim=2.

Returns: tuple(torch.Tensor) comprising of the query and key tensors rotated using the Rotary Position Embedding.

Source
def apply_multimodal_rotary_pos_emb(q, k, cos, sin, mrope_section, unsqueeze_dim=1):
    """Applies Rotary Position Embedding with Multimodal Sections to the query and key tensors (https://qwenlm.github.io/blog/qwen2-vl/).
Explanation:
    Multimodal 3D rotary position embedding is an extension to 1D rotary position embedding. The input embedding
    sequence contains vision (images / videos) embedding and text embedding or just contains text embedding. For
    vision embedding part, we apply rotary position embedding on temporal, height and width dimension seperately.
    Here we split the channel dimension to 3 chunks for the temporal, height and width rotary position embedding.
    For text embedding part, we just apply 1D rotary position embedding. The three rotary position index (temporal,
    height and width) of text embedding is always the same, so the text embedding rotary position embedding has no
    difference with modern LLMs.

Args:
    q (`torch.Tensor`): The query tensor.
    k (`torch.Tensor`): The key tensor.
    cos (`torch.Tensor`): The cosine part of the rotary embedding.
    sin (`torch.Tensor`): The sine part of the rotary embedding.
    position_ids (`torch.Tensor`):
        The position indices of the tokens corresponding to the query and key tensors. For example, this can be
        used to pass offsetted position ids when working with a KV-cache.
    mrope_section(`List(int)`):
        Multimodal rope section is for channel dimension of temporal, height and width in rope calculation.
    unsqueeze_dim (`int`, *optional*, defaults to 1):
        The &#x27;unsqueeze_dim&#x27; argument specifies the dimension along which to unsqueeze cos&#91;position_ids&#93; and
        sin&#91;position_ids&#93; so that they can be properly broadcasted to the dimensions of q and k. For example, note
        that cos&#91;position_ids&#93; and sin&#91;position_ids&#93; have the shape &#91;batch_size, seq_len, head_dim&#93;. Then, if q and
        k have the shape &#91;batch_size, heads, seq_len, head_dim&#93;, then setting unsqueeze_dim=1 makes
        cos&#91;position_ids&#93; and sin&#91;position_ids&#93; broadcastable to the shapes of q and k. Similarly, if q and k have
        the shape &#91;batch_size, seq_len, heads, head_dim&#93;, then set unsqueeze_dim=2.
Returns:
    `tuple(torch.Tensor)` comprising of the query and key tensors rotated using the Rotary Position Embedding.
&quot;&quot;&quot;
if isinstance(mrope_section, omegaconf.listconfig.ListConfig):
    mrope_section = list(mrope_section)
mrope_section = mrope_section * 2
cos = torch.cat(&#91;m&#91;i % 3&#93; for i, m in enumerate(cos.split(mrope_section, dim=-1))&#93;, dim=-1).unsqueeze(unsqueeze_dim)
sin = torch.cat(&#91;m&#91;i % 3&#93; for i, m in enumerate(sin.split(mrope_section, dim=-1))&#93;, dim=-1).unsqueeze(unsqueeze_dim)

q_embed = (q * cos) + (rotate_half(q) * sin)
k_embed = (k * cos) + (rotate_half(k) * sin)
return q_embed, k_embed</code></pre></details>

fastvideo.models.encoders.qwen2_5_vl_custom.repeat_kv

repeat_kv(hidden_states: torch.Tensor, n_rep: int) -> torch.Tensor

This is the equivalent of torch.repeat_interleave(x, dim=1, repeats=n_rep). The hidden states go from (batch, num_key_value_heads, seqlen, head_dim) to (batch, num_attention_heads, seqlen, head_dim)

Source
def repeat_kv(hidden_states: torch.Tensor, n_rep: int) -> torch.Tensor:
    """
    This is the equivalent of torch.repeat_interleave(x, dim=1, repeats=n_rep). The hidden states go from (batch,
    num_key_value_heads, seqlen, head_dim) to (batch, num_attention_heads, seqlen, head_dim)
    """
    batch, num_key_value_heads, slen, head_dim = hidden_states.shape
    if n_rep == 1:
        return hidden_states
    hidden_states = hidden_states[:, :, None, :, :].expand(batch, num_key_value_heads, n_rep, slen, head_dim)
    return hidden_states.reshape(batch, num_key_value_heads * n_rep, slen, head_dim)

fastvideo.models.encoders.qwen2_5_vl_custom.Qwen2_5_VLAttention

Qwen2_5_VLAttention(config: Qwen2_5_VLConfig, layer_idx: Optional[int] = None)

Multi-headed attention from 'Attention Is All You Need' paper. Modified to use sliding window attention: Longformer and "Generating Long Sequences with Sparse Transformers".

Source
class Qwen2_5_VLAttention(nn.Module):
    """
    Multi-headed attention from 'Attention Is All You Need' paper. Modified to use sliding window attention: Longformer
    and "Generating Long Sequences with Sparse Transformers".
    """
def __init__(self, config: Qwen2_5_VLConfig, layer_idx: Optional&#91;int&#93; = None):
    super().__init__()
    self.config = config
    self.layer_idx = layer_idx
    if layer_idx is None:
        logger.warning_once(
            f&quot;Instantiating &#123;self.__class__.__name__&#125; without passing `layer_idx` is not recommended and will &quot;
            &quot;to errors during the forward call, if caching is used. Please make sure to provide a `layer_idx` &quot;
            &quot;when creating this class.&quot;)

    self.hidden_size = config.hidden_size
    self.num_heads = config.num_attention_heads
    self.head_dim = self.hidden_size // self.num_heads
    self.num_key_value_heads = config.num_key_value_heads
    self.num_key_value_groups = self.num_heads // self.num_key_value_heads
    self.is_causal = True
    self.attention_dropout = config.attention_dropout
    self.rope_scaling = config.rope_scaling

    if (self.head_dim * self.num_heads) != self.hidden_size:
        raise ValueError(f&quot;hidden_size must be divisible by num_heads (got `hidden_size`: &#123;self.hidden_size&#125;&quot;
                         f&quot; and `num_heads`: &#123;self.num_heads&#125;).&quot;)
    self.q_proj = nn.Linear(self.hidden_size, self.num_heads * self.head_dim, bias=True)
    self.k_proj = nn.Linear(self.hidden_size, self.num_key_value_heads * self.head_dim, bias=True)
    self.v_proj = nn.Linear(self.hidden_size, self.num_key_value_heads * self.head_dim, bias=True)
    self.o_proj = nn.Linear(self.num_heads * self.head_dim, self.hidden_size, bias=False)

    self.rotary_emb = Qwen2_5_VLRotaryEmbedding(config=config)

def init_weights(self):
    self.rotary_emb.init_weights()

def forward(
    self,
    hidden_states: torch.Tensor,
    attention_mask: Optional&#91;torch.Tensor&#93; = None,
    position_ids: Optional&#91;torch.LongTensor&#93; = None,
    past_key_value: Optional&#91;Cache&#93; = None,
    output_attentions: bool = False,
    use_cache: bool = False,
    cache_position: Optional&#91;torch.LongTensor&#93; = None,
    position_embeddings: Optional&#91;Tuple&#91;torch.Tensor, torch.Tensor&#93;&#93; = None,  # necessary, but kept here for BC
) -&gt; Tuple&#91;torch.Tensor, Optional&#91;torch.Tensor&#93;, Optional&#91;Tuple&#91;torch.Tensor&#93;&#93;&#93;:
    bsz, q_len, _ = hidden_states.size()

    query_states = self.q_proj(hidden_states)
    key_states = self.k_proj(hidden_states)
    value_states = self.v_proj(hidden_states)

    query_states = query_states.view(bsz, q_len, -1, self.head_dim).transpose(1, 2)
    key_states = key_states.view(bsz, q_len, -1, self.head_dim).transpose(1, 2)
    value_states = value_states.view(bsz, q_len, -1, self.head_dim).transpose(1, 2)

    cos, sin = position_embeddings
    query_states, key_states = apply_multimodal_rotary_pos_emb(query_states, key_states, cos, sin,
                                                               self.rope_scaling&#91;&quot;mrope_section&quot;&#93;)

    if past_key_value is not None:
        cache_kwargs = &#123;
            &quot;sin&quot;: sin,
            &quot;cos&quot;: cos,
            &quot;cache_position&quot;: cache_position,
        &#125;  # Specific to RoPE models
        key_states, value_states = past_key_value.update(key_states, value_states, self.layer_idx, cache_kwargs)

    # repeat k/v heads if n_kv_heads &lt; n_heads
    key_states = repeat_kv(key_states, self.num_key_value_groups)
    value_states = repeat_kv(value_states, self.num_key_value_groups)

    attn_weights = torch.matmul(query_states, key_states.transpose(2, 3)) / math.sqrt(self.head_dim)

    if attention_mask is not None:  # no matter the length, we just slice it
        causal_mask = attention_mask&#91;:, :, :, :key_states.shape&#91;-2&#93;&#93;
        attn_weights = attn_weights + causal_mask

    # Fix precision issues in Qwen2-VL float16 inference
    # Replace inf values with zeros in attention weights to prevent NaN propagation
    if query_states.dtype == torch.float16:
        attn_weights = torch.where(torch.isinf(attn_weights), torch.zeros_like(attn_weights), attn_weights)

    # upcast attention to fp32
    attn_weights = nn.functional.softmax(attn_weights, dim=-1, dtype=torch.float32).to(query_states.dtype)
    attn_weights = nn.functional.dropout(attn_weights, p=self.attention_dropout, training=self.training)
    attn_output = torch.matmul(attn_weights, value_states)

    if attn_output.size() != (bsz, self.num_heads, q_len, self.head_dim):
        raise ValueError(f&quot;`attn_output` should be of size &#123;(bsz, self.num_heads, q_len, self.head_dim)&#125;, but is&quot;
                         f&quot; &#123;attn_output.size()&#125;&quot;)

    attn_output = attn_output.transpose(1, 2).contiguous()
    attn_output = attn_output.reshape(bsz, q_len, -1)

    attn_output = self.o_proj(attn_output)

    if not output_attentions:
        attn_weights = None

    return attn_output, attn_weights, past_key_value</code></pre></details>

fastvideo.models.encoders.qwen2_5_vl_custom.Qwen2_5_VLAttention.init_weights

init_weights()
Source
def init_weights(self):
    self.rotary_emb.init_weights()

fastvideo.models.encoders.qwen2_5_vl_custom.Qwen2_5_VLAttention.forward

forward(hidden_states: torch.Tensor, attention_mask: Optional[torch.Tensor] = None, position_ids: Optional[torch.LongTensor] = None, past_key_value: Optional[Cache] = None, output_attentions: bool = False, use_cache: bool = False, cache_position: Optional[torch.LongTensor] = None, position_embeddings: Optional[Tuple[torch.Tensor, torch.Tensor]] = None) -> Tuple[torch.Tensor, Optional[torch.Tensor], Optional[Tuple[torch.Tensor]]]
Source
def forward(
    self,
    hidden_states: torch.Tensor,
    attention_mask: Optional[torch.Tensor] = None,
    position_ids: Optional[torch.LongTensor] = None,
    past_key_value: Optional[Cache] = None,
    output_attentions: bool = False,
    use_cache: bool = False,
    cache_position: Optional[torch.LongTensor] = None,
    position_embeddings: Optional[Tuple[torch.Tensor, torch.Tensor]] = None,  # necessary, but kept here for BC
) -> Tuple[torch.Tensor, Optional[torch.Tensor], Optional[Tuple[torch.Tensor]]]:
    bsz, q_len, _ = hidden_states.size()
query_states = self.q_proj(hidden_states)
key_states = self.k_proj(hidden_states)
value_states = self.v_proj(hidden_states)

query_states = query_states.view(bsz, q_len, -1, self.head_dim).transpose(1, 2)
key_states = key_states.view(bsz, q_len, -1, self.head_dim).transpose(1, 2)
value_states = value_states.view(bsz, q_len, -1, self.head_dim).transpose(1, 2)

cos, sin = position_embeddings
query_states, key_states = apply_multimodal_rotary_pos_emb(query_states, key_states, cos, sin,
                                                           self.rope_scaling&#91;&quot;mrope_section&quot;&#93;)

if past_key_value is not None:
    cache_kwargs = &#123;
        &quot;sin&quot;: sin,
        &quot;cos&quot;: cos,
        &quot;cache_position&quot;: cache_position,
    &#125;  # Specific to RoPE models
    key_states, value_states = past_key_value.update(key_states, value_states, self.layer_idx, cache_kwargs)

# repeat k/v heads if n_kv_heads &lt; n_heads
key_states = repeat_kv(key_states, self.num_key_value_groups)
value_states = repeat_kv(value_states, self.num_key_value_groups)

attn_weights = torch.matmul(query_states, key_states.transpose(2, 3)) / math.sqrt(self.head_dim)

if attention_mask is not None:  # no matter the length, we just slice it
    causal_mask = attention_mask&#91;:, :, :, :key_states.shape&#91;-2&#93;&#93;
    attn_weights = attn_weights + causal_mask

# Fix precision issues in Qwen2-VL float16 inference
# Replace inf values with zeros in attention weights to prevent NaN propagation
if query_states.dtype == torch.float16:
    attn_weights = torch.where(torch.isinf(attn_weights), torch.zeros_like(attn_weights), attn_weights)

# upcast attention to fp32
attn_weights = nn.functional.softmax(attn_weights, dim=-1, dtype=torch.float32).to(query_states.dtype)
attn_weights = nn.functional.dropout(attn_weights, p=self.attention_dropout, training=self.training)
attn_output = torch.matmul(attn_weights, value_states)

if attn_output.size() != (bsz, self.num_heads, q_len, self.head_dim):
    raise ValueError(f&quot;`attn_output` should be of size &#123;(bsz, self.num_heads, q_len, self.head_dim)&#125;, but is&quot;
                     f&quot; &#123;attn_output.size()&#125;&quot;)

attn_output = attn_output.transpose(1, 2).contiguous()
attn_output = attn_output.reshape(bsz, q_len, -1)

attn_output = self.o_proj(attn_output)

if not output_attentions:
    attn_weights = None

return attn_output, attn_weights, past_key_value</code></pre></details>

fastvideo.models.encoders.qwen2_5_vl_custom.Qwen2_5_VLFlashAttention2

Qwen2_5_VLFlashAttention2(*args, **kwargs)

Qwen2_5_VL flash attention module, following Qwen2_5_VL attention module. This module inherits from Qwen2_5_VLAttention as the weights of the module stays untouched. The only required change would be on the forward pass where it needs to correctly call the public API of flash attention and deal with padding tokens in case the input contains any of them. Additionally, for sliding window attention, we apply SWA only to the bottom config.max_window_layers layers.

Source
class Qwen2_5_VLFlashAttention2(Qwen2_5_VLAttention):
    """
    Qwen2_5_VL flash attention module, following Qwen2_5_VL attention module. This module inherits from `Qwen2_5_VLAttention`
    as the weights of the module stays untouched. The only required change would be on the forward pass
    where it needs to correctly call the public API of flash attention and deal with padding tokens
    in case the input contains any of them. Additionally, for sliding window attention, we apply SWA only to the bottom
    config.max_window_layers layers.
    """
def __init__(self, *args, **kwargs):
    super().__init__(*args, **kwargs)

    # flash_attn&lt;2.1 generates top-left aligned causal mask, while what is needed here is bottom-right alignement, that was made default for flash_attn&gt;=2.1. This attribute is used to handle this difference. Reference: https://github.com/Dao-AILab/flash-attention/releases/tag/v2.1.0.
    # Beware that with flash_attn&lt;2.1, using q_seqlen != k_seqlen (except for the case q_seqlen == 1) produces a wrong mask (top-left).
    self._flash_attn_uses_top_left_mask = not is_flash_attn_greater_or_equal_2_10()

def forward(
    self,
    hidden_states: torch.Tensor,
    attention_mask: Optional&#91;torch.Tensor&#93; = None,
    position_ids: Optional&#91;torch.LongTensor&#93; = None,
    past_key_value: Optional&#91;Cache&#93; = None,
    output_attentions: bool = False,
    use_cache: bool = False,
    cache_position: Optional&#91;torch.LongTensor&#93; = None,
    position_embeddings: Optional&#91;Tuple&#91;torch.Tensor, torch.Tensor&#93;&#93; = None,  # necessary, but kept here for BC
    cp_mesh: DeviceMesh | None = None,
):
    &quot;&quot;&quot;
    Args:
        cp_mesh (DeviceMesh, optional): Device mesh over which context parallelism is done.
    &quot;&quot;&quot;
    bsz, q_len, _ = hidden_states.size()

    query_states = self.q_proj(hidden_states)
    key_states = self.k_proj(hidden_states)
    value_states = self.v_proj(hidden_states)
    query_states = query_states.view(bsz, q_len, -1, self.head_dim).transpose(1, 2)
    key_states = key_states.view(bsz, q_len, -1, self.head_dim).transpose(1, 2)
    value_states = value_states.view(bsz, q_len, -1, self.head_dim).transpose(1, 2)

    # Because the input can be padded, the absolute sequence length depends on the max position id.
    cos, sin = position_embeddings
    query_states, key_states = apply_multimodal_rotary_pos_emb(query_states, key_states, cos, sin,
                                                               self.rope_scaling&#91;&quot;mrope_section&quot;&#93;)

    if past_key_value is not None:
        cache_kwargs = &#123;
            &quot;sin&quot;: sin,
            &quot;cos&quot;: cos,
            &quot;cache_position&quot;: cache_position,
        &#125;  # Specific to RoPE models
        key_states, value_states = past_key_value.update(key_states, value_states, self.layer_idx, cache_kwargs)

    # repeat k/v heads if n_kv_heads &lt; n_heads
    key_states = repeat_kv(key_states, self.num_key_value_groups)
    value_states = repeat_kv(value_states, self.num_key_value_groups)
    dropout_rate = 0.0 if not self.training else self.attention_dropout

    # In PEFT, usually we cast the layer norms in float32 for training stability reasons
    # therefore the input hidden states gets silently casted in float32. Hence, we need
    # cast them back in float16 just to be sure everything works as expected.
    input_dtype = query_states.dtype
    if input_dtype == torch.float32:
        if torch.is_autocast_enabled():
            target_dtype = torch.get_autocast_gpu_dtype()
        # Handle the case where the model is quantized
        elif hasattr(self.config, &quot;_pre_quantization_dtype&quot;):
            target_dtype = self.config._pre_quantization_dtype
        else:
            target_dtype = self.q_proj.weight.dtype

        logger.warning_once(
            f&quot;The input hidden states seems to be silently casted in float32, this might be related to&quot;
            f&quot; the fact you have upcasted embedding or layer norm layers in float32. We will cast back the input in&quot;
            f&quot; &#123;target_dtype&#125;.&quot;)

        query_states = query_states.to(target_dtype)
        key_states = key_states.to(target_dtype)
        value_states = value_states.to(target_dtype)

    # Reashape to the expected shape for Flash Attention
    query_states = query_states.transpose(1, 2)
    key_states = key_states.transpose(1, 2)
    value_states = value_states.transpose(1, 2)

    if (self.config.use_sliding_window and getattr(self.config, &quot;sliding_window&quot;, None) is not None
            and self.layer_idx &gt;= self.config.max_window_layers):
        sliding_window = self.config.sliding_window
    else:
        sliding_window = None
    if cp_mesh is not None:
        raise NotImplementedError(
            &quot;CP is not supported for flash attention2, _flash_attention_forward will produce wrong output if query_states is sharded&quot;
        )

    attn_output = _flash_attention_forward(
        query_states,
        key_states,
        value_states,
        attention_mask,
        q_len,
        dropout=dropout_rate,
        sliding_window=sliding_window,
        is_causal=self.is_causal,
        use_top_left_mask=self._flash_attn_uses_top_left_mask,
    )

    attn_output = attn_output.reshape(bsz, q_len, -1).contiguous()
    attn_output = self.o_proj(attn_output)

    if not output_attentions:
        attn_weights = None

    return attn_output, attn_weights, past_key_value</code></pre></details>

fastvideo.models.encoders.qwen2_5_vl_custom.Qwen2_5_VLFlashAttention2.forward

forward(hidden_states: torch.Tensor, attention_mask: Optional[torch.Tensor] = None, position_ids: Optional[torch.LongTensor] = None, past_key_value: Optional[Cache] = None, output_attentions: bool = False, use_cache: bool = False, cache_position: Optional[torch.LongTensor] = None, position_embeddings: Optional[Tuple[torch.Tensor, torch.Tensor]] = None, cp_mesh: DeviceMesh | None = None)

Parameters

cp_mesh: DeviceMesh

Device mesh over which context parallelism is done.

Source
def forward(
    self,
    hidden_states: torch.Tensor,
    attention_mask: Optional[torch.Tensor] = None,
    position_ids: Optional[torch.LongTensor] = None,
    past_key_value: Optional[Cache] = None,
    output_attentions: bool = False,
    use_cache: bool = False,
    cache_position: Optional[torch.LongTensor] = None,
    position_embeddings: Optional[Tuple[torch.Tensor, torch.Tensor]] = None,  # necessary, but kept here for BC
    cp_mesh: DeviceMesh | None = None,
):
    """
    Args:
        cp_mesh (DeviceMesh, optional): Device mesh over which context parallelism is done.
    """
    bsz, q_len, _ = hidden_states.size()
query_states = self.q_proj(hidden_states)
key_states = self.k_proj(hidden_states)
value_states = self.v_proj(hidden_states)
query_states = query_states.view(bsz, q_len, -1, self.head_dim).transpose(1, 2)
key_states = key_states.view(bsz, q_len, -1, self.head_dim).transpose(1, 2)
value_states = value_states.view(bsz, q_len, -1, self.head_dim).transpose(1, 2)

# Because the input can be padded, the absolute sequence length depends on the max position id.
cos, sin = position_embeddings
query_states, key_states = apply_multimodal_rotary_pos_emb(query_states, key_states, cos, sin,
                                                           self.rope_scaling&#91;&quot;mrope_section&quot;&#93;)

if past_key_value is not None:
    cache_kwargs = &#123;
        &quot;sin&quot;: sin,
        &quot;cos&quot;: cos,
        &quot;cache_position&quot;: cache_position,
    &#125;  # Specific to RoPE models
    key_states, value_states = past_key_value.update(key_states, value_states, self.layer_idx, cache_kwargs)

# repeat k/v heads if n_kv_heads &lt; n_heads
key_states = repeat_kv(key_states, self.num_key_value_groups)
value_states = repeat_kv(value_states, self.num_key_value_groups)
dropout_rate = 0.0 if not self.training else self.attention_dropout

# In PEFT, usually we cast the layer norms in float32 for training stability reasons
# therefore the input hidden states gets silently casted in float32. Hence, we need
# cast them back in float16 just to be sure everything works as expected.
input_dtype = query_states.dtype
if input_dtype == torch.float32:
    if torch.is_autocast_enabled():
        target_dtype = torch.get_autocast_gpu_dtype()
    # Handle the case where the model is quantized
    elif hasattr(self.config, &quot;_pre_quantization_dtype&quot;):
        target_dtype = self.config._pre_quantization_dtype
    else:
        target_dtype = self.q_proj.weight.dtype

    logger.warning_once(
        f&quot;The input hidden states seems to be silently casted in float32, this might be related to&quot;
        f&quot; the fact you have upcasted embedding or layer norm layers in float32. We will cast back the input in&quot;
        f&quot; &#123;target_dtype&#125;.&quot;)

    query_states = query_states.to(target_dtype)
    key_states = key_states.to(target_dtype)
    value_states = value_states.to(target_dtype)

# Reashape to the expected shape for Flash Attention
query_states = query_states.transpose(1, 2)
key_states = key_states.transpose(1, 2)
value_states = value_states.transpose(1, 2)

if (self.config.use_sliding_window and getattr(self.config, &quot;sliding_window&quot;, None) is not None
        and self.layer_idx &gt;= self.config.max_window_layers):
    sliding_window = self.config.sliding_window
else:
    sliding_window = None
if cp_mesh is not None:
    raise NotImplementedError(
        &quot;CP is not supported for flash attention2, _flash_attention_forward will produce wrong output if query_states is sharded&quot;
    )

attn_output = _flash_attention_forward(
    query_states,
    key_states,
    value_states,
    attention_mask,
    q_len,
    dropout=dropout_rate,
    sliding_window=sliding_window,
    is_causal=self.is_causal,
    use_top_left_mask=self._flash_attn_uses_top_left_mask,
)

attn_output = attn_output.reshape(bsz, q_len, -1).contiguous()
attn_output = self.o_proj(attn_output)

if not output_attentions:
    attn_weights = None

return attn_output, attn_weights, past_key_value</code></pre></details>

fastvideo.models.encoders.qwen2_5_vl_custom.Qwen2_5_VLSdpaAttention

Qwen2_5_VLSdpaAttention(config: Qwen2_5_VLConfig, layer_idx: Optional[int] = None)

Qwen2 attention module using torch.nn.functional.scaled_dot_product_attention. This module inherits from Qwen2Attention as the weights of the module stays untouched. The only changes are on the forward pass to adapt to SDPA API.

Source
class Qwen2_5_VLSdpaAttention(Qwen2_5_VLAttention):
    """
    Qwen2 attention module using torch.nn.functional.scaled_dot_product_attention. This module inherits from
    `Qwen2Attention` as the weights of the module stays untouched. The only changes are on the forward pass to adapt to
    SDPA API.
    """
# Adapted from Qwen2Attention.forward
def forward(
    self,
    hidden_states: torch.Tensor,
    attention_mask: Optional&#91;torch.Tensor&#93; = None,
    position_ids: Optional&#91;torch.LongTensor&#93; = None,
    past_key_value: Optional&#91;Cache&#93; = None,
    output_attentions: bool = False,
    use_cache: bool = False,
    cache_position: Optional&#91;torch.LongTensor&#93; = None,
    position_embeddings: Optional&#91;Tuple&#91;torch.Tensor, torch.Tensor&#93;&#93; = None,  # necessary, but kept here for BC
    cp_mesh: DeviceMesh | None = None,
) -&gt; Tuple&#91;torch.Tensor, Optional&#91;torch.Tensor&#93;, Optional&#91;Tuple&#91;torch.Tensor&#93;&#93;&#93;:
    if output_attentions:
        logger.warning_once(
            &quot;Qwen2_5_VLModel is using Qwen2_5_VLSdpaAttention, but `torch.nn.functional.scaled_dot_product_attention` does not support `output_attentions=True`. Falling back to the manual attention implementation, &quot;
            &#x27;but specifying the manual implementation will be required from Transformers version v5.0.0 onwards. This warning can be removed using the argument `attn_implementation=&quot;eager&quot;` when loading the model.&#x27;
        )
        return super().forward(
            hidden_states=hidden_states,
            attention_mask=attention_mask,
            position_ids=position_ids,
            past_key_value=past_key_value,
            output_attentions=output_attentions,
            use_cache=use_cache,
            cache_position=cache_position,
            position_embeddings=position_embeddings,
        )

    bsz, q_len, _ = hidden_states.size()

    query_states = self.q_proj(hidden_states)
    key_states = self.k_proj(hidden_states)
    value_states = self.v_proj(hidden_states)

    query_states = query_states.view(bsz, q_len, -1, self.head_dim).transpose(1, 2)
    key_states = key_states.view(bsz, q_len, -1, self.head_dim).transpose(1, 2)
    value_states = value_states.view(bsz, q_len, -1, self.head_dim).transpose(1, 2)

    cos, sin = position_embeddings
    query_states, key_states = apply_multimodal_rotary_pos_emb(query_states, key_states, cos, sin,
                                                               self.rope_scaling&#91;&quot;mrope_section&quot;&#93;)

    if past_key_value is not None:
        cache_kwargs = &#123;
            &quot;sin&quot;: sin,
            &quot;cos&quot;: cos,
            &quot;cache_position&quot;: cache_position,
        &#125;  # Specific to RoPE models
        key_states, value_states = past_key_value.update(key_states, value_states, self.layer_idx, cache_kwargs)

    key_states = repeat_kv(key_states, self.num_key_value_groups)
    value_states = repeat_kv(value_states, self.num_key_value_groups)

    causal_mask = attention_mask
    if attention_mask is not None and attention_mask.ndim == 4:  # no matter the length, we just slice it
        causal_mask = attention_mask&#91;:, :, :, :key_states.shape&#91;-2&#93;&#93;

    # SDPA with memory-efficient backend is currently (torch==2.1.2) bugged with non-contiguous inputs with custom attn_mask,
    # Reference: https://github.com/pytorch/pytorch/issues/112577.
    if query_states.device.type == &quot;cuda&quot; and attention_mask is not None:
        query_states = query_states.contiguous()
        key_states = key_states.contiguous()
        value_states = value_states.contiguous()

    # We dispatch to SDPA&#x27;s Flash Attention or Efficient kernels via this `is_causal` if statement instead of an inline conditional assignment
    # in SDPA to support both torch.compile&#x27;s dynamic shapes and full graph options. An inline conditional prevents dynamic shapes from compiling.
    # The q_len &gt; 1 is necessary to match with AttentionMaskConverter.to_causal_4d that does not create a causal mask in case q_len == 1.
    is_causal = True if causal_mask is None and q_len &gt; 1 else False
    if cp_mesh is not None:
        key_states = DTensor.from_local(key_states, cp_mesh, &#91;Shard(2)&#93;).full_tensor()
        value_states = DTensor.from_local(value_states, cp_mesh, &#91;Shard(2)&#93;).full_tensor()

    attn_output = torch.nn.functional.scaled_dot_product_attention(
        query_states,
        key_states,
        value_states,
        attn_mask=causal_mask,
        dropout_p=self.attention_dropout if self.training else 0.0,
        is_causal=is_causal,
    )

    attn_output = attn_output.transpose(1, 2).contiguous()
    attn_output = attn_output.view(bsz, q_len, self.hidden_size)

    attn_output = self.o_proj(attn_output)

    return attn_output, None, past_key_value</code></pre></details>

fastvideo.models.encoders.qwen2_5_vl_custom.Qwen2_5_VLSdpaAttention.forward

forward(hidden_states: torch.Tensor, attention_mask: Optional[torch.Tensor] = None, position_ids: Optional[torch.LongTensor] = None, past_key_value: Optional[Cache] = None, output_attentions: bool = False, use_cache: bool = False, cache_position: Optional[torch.LongTensor] = None, position_embeddings: Optional[Tuple[torch.Tensor, torch.Tensor]] = None, cp_mesh: DeviceMesh | None = None) -> Tuple[torch.Tensor, Optional[torch.Tensor], Optional[Tuple[torch.Tensor]]]
Source
def forward(
    self,
    hidden_states: torch.Tensor,
    attention_mask: Optional[torch.Tensor] = None,
    position_ids: Optional[torch.LongTensor] = None,
    past_key_value: Optional[Cache] = None,
    output_attentions: bool = False,
    use_cache: bool = False,
    cache_position: Optional[torch.LongTensor] = None,
    position_embeddings: Optional[Tuple[torch.Tensor, torch.Tensor]] = None,  # necessary, but kept here for BC
    cp_mesh: DeviceMesh | None = None,
) -> Tuple[torch.Tensor, Optional[torch.Tensor], Optional[Tuple[torch.Tensor]]]:
    if output_attentions:
        logger.warning_once(
            "Qwen2_5_VLModel is using Qwen2_5_VLSdpaAttention, but `torch.nn.functional.scaled_dot_product_attention` does not support `output_attentions=True`. Falling back to the manual attention implementation, "
            'but specifying the manual implementation will be required from Transformers version v5.0.0 onwards. This warning can be removed using the argument `attn_implementation="eager"` when loading the model.'
        )
        return super().forward(
            hidden_states=hidden_states,
            attention_mask=attention_mask,
            position_ids=position_ids,
            past_key_value=past_key_value,
            output_attentions=output_attentions,
            use_cache=use_cache,
            cache_position=cache_position,
            position_embeddings=position_embeddings,
        )
bsz, q_len, _ = hidden_states.size()

query_states = self.q_proj(hidden_states)
key_states = self.k_proj(hidden_states)
value_states = self.v_proj(hidden_states)

query_states = query_states.view(bsz, q_len, -1, self.head_dim).transpose(1, 2)
key_states = key_states.view(bsz, q_len, -1, self.head_dim).transpose(1, 2)
value_states = value_states.view(bsz, q_len, -1, self.head_dim).transpose(1, 2)

cos, sin = position_embeddings
query_states, key_states = apply_multimodal_rotary_pos_emb(query_states, key_states, cos, sin,
                                                           self.rope_scaling&#91;&quot;mrope_section&quot;&#93;)

if past_key_value is not None:
    cache_kwargs = &#123;
        &quot;sin&quot;: sin,
        &quot;cos&quot;: cos,
        &quot;cache_position&quot;: cache_position,
    &#125;  # Specific to RoPE models
    key_states, value_states = past_key_value.update(key_states, value_states, self.layer_idx, cache_kwargs)

key_states = repeat_kv(key_states, self.num_key_value_groups)
value_states = repeat_kv(value_states, self.num_key_value_groups)

causal_mask = attention_mask
if attention_mask is not None and attention_mask.ndim == 4:  # no matter the length, we just slice it
    causal_mask = attention_mask&#91;:, :, :, :key_states.shape&#91;-2&#93;&#93;

# SDPA with memory-efficient backend is currently (torch==2.1.2) bugged with non-contiguous inputs with custom attn_mask,
# Reference: https://github.com/pytorch/pytorch/issues/112577.
if query_states.device.type == &quot;cuda&quot; and attention_mask is not None:
    query_states = query_states.contiguous()
    key_states = key_states.contiguous()
    value_states = value_states.contiguous()

# We dispatch to SDPA&#x27;s Flash Attention or Efficient kernels via this `is_causal` if statement instead of an inline conditional assignment
# in SDPA to support both torch.compile&#x27;s dynamic shapes and full graph options. An inline conditional prevents dynamic shapes from compiling.
# The q_len &gt; 1 is necessary to match with AttentionMaskConverter.to_causal_4d that does not create a causal mask in case q_len == 1.
is_causal = True if causal_mask is None and q_len &gt; 1 else False
if cp_mesh is not None:
    key_states = DTensor.from_local(key_states, cp_mesh, &#91;Shard(2)&#93;).full_tensor()
    value_states = DTensor.from_local(value_states, cp_mesh, &#91;Shard(2)&#93;).full_tensor()

attn_output = torch.nn.functional.scaled_dot_product_attention(
    query_states,
    key_states,
    value_states,
    attn_mask=causal_mask,
    dropout_p=self.attention_dropout if self.training else 0.0,
    is_causal=is_causal,
)

attn_output = attn_output.transpose(1, 2).contiguous()
attn_output = attn_output.view(bsz, q_len, self.hidden_size)

attn_output = self.o_proj(attn_output)

return attn_output, None, past_key_value</code></pre></details>

fastvideo.models.encoders.qwen2_5_vl_custom.Qwen2_5_VLDecoderLayer

Qwen2_5_VLDecoderLayer(config: Qwen2_5_VLConfig, layer_idx: int)
Source
class Qwen2_5_VLDecoderLayer(nn.Module):
def __init__(self, config: Qwen2_5_VLConfig, layer_idx: int):
    super().__init__()
    self.hidden_size = config.hidden_size

    if config.use_sliding_window and config._attn_implementation != &quot;flash_attention_2&quot;:
        logger.warning_once(
            f&quot;Sliding Window Attention is enabled but not implemented for `&#123;config._attn_implementation&#125;`; &quot;
            &quot;unexpected results may be encountered.&quot;)
    self.self_attn = QWEN2_5_VL_ATTENTION_CLASSES&#91;config._attn_implementation&#93;(config, layer_idx)
    self.mlp = Qwen2MLP(config)
    self.input_layernorm = Qwen2RMSNorm(config.hidden_size, eps=config.rms_norm_eps)
    self.post_attention_layernorm = Qwen2RMSNorm(config.hidden_size, eps=config.rms_norm_eps)

def forward(
    self,
    hidden_states: torch.Tensor,
    attention_mask: Optional&#91;torch.Tensor&#93; = None,
    position_ids: Optional&#91;torch.LongTensor&#93; = None,
    past_key_value: Optional&#91;Tuple&#91;torch.Tensor&#93;&#93; = None,
    output_attentions: Optional&#91;bool&#93; = False,
    use_cache: Optional&#91;bool&#93; = False,
    cache_position: Optional&#91;torch.LongTensor&#93; = None,
    position_embeddings: Optional&#91;Tuple&#91;torch.Tensor, torch.Tensor&#93;&#93; = None,  # necessary, but kept here for BC
    cp_mesh: DeviceMesh | None = None,
    **kwargs,
) -&gt; Tuple&#91;torch.FloatTensor, Optional&#91;Tuple&#91;torch.FloatTensor, torch.FloatTensor&#93;&#93;&#93;:
    &quot;&quot;&quot;
    Args:
        hidden_states (`torch.FloatTensor`): input to the layer of shape `(batch, seq_len, embed_dim)`
        attention_mask (`torch.FloatTensor`, *optional*): attention mask of size
            `(batch, sequence_length)` where padding elements are indicated by 0.
        output_attentions (`bool`, *optional*):
            Whether or not to return the attentions tensors of all attention layers. See `attentions` under
            returned tensors for more detail.
        use_cache (`bool`, *optional*):
            If set to `True`, `past_key_values` key value states are returned and can be used to speed up decoding
            (see `past_key_values`).
        past_key_value (`Tuple(torch.FloatTensor)`, *optional*): cached past key and value projection states
        cache_position (`torch.LongTensor` of shape `(sequence_length)`, *optional*):
            Indices depicting the position of the input sequence tokens in the sequence.
        position_embeddings (`Tuple&#91;torch.FloatTensor, torch.FloatTensor&#93;`, *optional*):
            Tuple containing the cosine and sine positional embeddings of shape `(batch_size, seq_len, head_dim)`,
            with `head_dim` being the embedding dimension of each attention head.
        cp_mesh (DeviceMesh, optional): Device mesh over which context parallelism is done.
        kwargs (`dict`, *optional*):
            Arbitrary kwargs to be ignored, used for FSDP and other methods that injects code
            into the model
    &quot;&quot;&quot;

    residual = hidden_states

    hidden_states = self.input_layernorm(hidden_states)
    hidden_states, self_attn_weights, present_key_value = self.self_attn(
        hidden_states,
        attention_mask,
        position_ids,
        past_key_value,
        output_attentions,
        use_cache,
        cache_position,
        position_embeddings,
        cp_mesh=cp_mesh,
    )
    hidden_states = residual + hidden_states

    residual = hidden_states
    hidden_states = self.post_attention_layernorm(hidden_states)
    hidden_states = self.mlp(hidden_states)
    hidden_states = residual + hidden_states

    outputs = (hidden_states, )

    if output_attentions:
        outputs += (self_attn_weights, )

    if use_cache:
        outputs += (present_key_value, )
    return outputs</code></pre></details>

fastvideo.models.encoders.qwen2_5_vl_custom.Qwen2_5_VLDecoderLayer.forward

forward(hidden_states: torch.Tensor, attention_mask: Optional[torch.Tensor] = None, position_ids: Optional[torch.LongTensor] = None, past_key_value: Optional[Tuple[torch.Tensor]] = None, output_attentions: Optional[bool] = False, use_cache: Optional[bool] = False, cache_position: Optional[torch.LongTensor] = None, position_embeddings: Optional[Tuple[torch.Tensor, torch.Tensor]] = None, cp_mesh: DeviceMesh | None = None, **kwargs) -> Tuple[torch.FloatTensor, Optional[Tuple[torch.FloatTensor, torch.FloatTensor]]]

Parameters

hidden_states: `torch.FloatTensor`

input to the layer of shape (batch, seq_len, embed_dim)

attention_mask: `torch.FloatTensor`, *optional*

attention mask of size (batch, sequence_length) where padding elements are indicated by 0.

output_attentions: `bool`, *optional*

Whether or not to return the attentions tensors of all attention layers. See attentions under returned tensors for more detail.

use_cache: `bool`, *optional*

If set to True, past_key_values key value states are returned and can be used to speed up decoding (see past_key_values).

past_key_value: `Tuple(torch.FloatTensor)`, *optional*

cached past key and value projection states

cache_position: `torch.LongTensor` of shape `(sequence_length)`, *optional*

Indices depicting the position of the input sequence tokens in the sequence.

position_embeddings: `Tuple[torch.FloatTensor, torch.FloatTensor]`, *optional*

Tuple containing the cosine and sine positional embeddings of shape (batch_size, seq_len, head_dim), with head_dim being the embedding dimension of each attention head.

cp_mesh: DeviceMesh

Device mesh over which context parallelism is done.

kwargs: `dict`, *optional*

Arbitrary kwargs to be ignored, used for FSDP and other methods that injects code into the model

Source
def forward(
    self,
    hidden_states: torch.Tensor,
    attention_mask: Optional[torch.Tensor] = None,
    position_ids: Optional[torch.LongTensor] = None,
    past_key_value: Optional[Tuple[torch.Tensor]] = None,
    output_attentions: Optional[bool] = False,
    use_cache: Optional[bool] = False,
    cache_position: Optional[torch.LongTensor] = None,
    position_embeddings: Optional[Tuple[torch.Tensor, torch.Tensor]] = None,  # necessary, but kept here for BC
    cp_mesh: DeviceMesh | None = None,
    **kwargs,
) -> Tuple[torch.FloatTensor, Optional[Tuple[torch.FloatTensor, torch.FloatTensor]]]:
    """
    Args:
        hidden_states (`torch.FloatTensor`): input to the layer of shape `(batch, seq_len, embed_dim)`
        attention_mask (`torch.FloatTensor`, *optional*): attention mask of size
            `(batch, sequence_length)` where padding elements are indicated by 0.
        output_attentions (`bool`, *optional*):
            Whether or not to return the attentions tensors of all attention layers. See `attentions` under
            returned tensors for more detail.
        use_cache (`bool`, *optional*):
            If set to `True`, `past_key_values` key value states are returned and can be used to speed up decoding
            (see `past_key_values`).
        past_key_value (`Tuple(torch.FloatTensor)`, *optional*): cached past key and value projection states
        cache_position (`torch.LongTensor` of shape `(sequence_length)`, *optional*):
            Indices depicting the position of the input sequence tokens in the sequence.
        position_embeddings (`Tuple[torch.FloatTensor, torch.FloatTensor]`, *optional*):
            Tuple containing the cosine and sine positional embeddings of shape `(batch_size, seq_len, head_dim)`,
            with `head_dim` being the embedding dimension of each attention head.
        cp_mesh (DeviceMesh, optional): Device mesh over which context parallelism is done.
        kwargs (`dict`, *optional*):
            Arbitrary kwargs to be ignored, used for FSDP and other methods that injects code
            into the model
    """
residual = hidden_states

hidden_states = self.input_layernorm(hidden_states)
hidden_states, self_attn_weights, present_key_value = self.self_attn(
    hidden_states,
    attention_mask,
    position_ids,
    past_key_value,
    output_attentions,
    use_cache,
    cache_position,
    position_embeddings,
    cp_mesh=cp_mesh,
)
hidden_states = residual + hidden_states

residual = hidden_states
hidden_states = self.post_attention_layernorm(hidden_states)
hidden_states = self.mlp(hidden_states)
hidden_states = residual + hidden_states

outputs = (hidden_states, )

if output_attentions:
    outputs += (self_attn_weights, )

if use_cache:
    outputs += (present_key_value, )
return outputs</code></pre></details>

fastvideo.models.encoders.qwen2_5_vl_custom.Qwen2_5_VLModel

Qwen2_5_VLModel(config: Qwen2_5_VLConfig)
Source
class Qwen2_5_VLModel(nn.Module):
def __init__(self, config: Qwen2_5_VLConfig):
    super().__init__()
    self.config = config
    self.padding_idx = getattr(config, &quot;pad_token_id&quot;, None)
    self.vocab_size = config.vocab_size

    self.embed_tokens = nn.Embedding(config.vocab_size, config.hidden_size, self.padding_idx)
    self.layers = nn.ModuleList(
        &#91;Qwen2_5_VLDecoderLayer(config, layer_idx) for layer_idx in range(config.num_hidden_layers)&#93;)
    self._attn_implementation = config._attn_implementation
    self.norm = Qwen2RMSNorm(config.hidden_size, eps=config.rms_norm_eps)
    self.rotary_emb = Qwen2_5_VLRotaryEmbedding(config=config)

    self.gradient_checkpointing = False
    self.dtype = config.torch_dtype
    self.cp_mesh = None

def init_weights(self, buffer_device: Optional&#91;torch.device&#93; = None):
    self.rotary_emb.init_weights(buffer_device)

def get_input_embeddings(self):
    return self.embed_tokens

def set_input_embeddings(self, value):
    self.embed_tokens = value

def set_cp_mesh(self, cp_mesh):
    self.cp_mesh = cp_mesh

def forward(
    self,
    input_ids: torch.LongTensor = None,
    attention_mask: Optional&#91;torch.Tensor&#93; = None,
    position_ids: Optional&#91;torch.LongTensor&#93; = None,
    past_key_values: Optional&#91;List&#91;torch.FloatTensor&#93;&#93; = None,
    inputs_embeds: Optional&#91;torch.FloatTensor&#93; = None,
    use_cache: Optional&#91;bool&#93; = None,
    output_attentions: Optional&#91;bool&#93; = None,
    output_hidden_states: Optional&#91;bool&#93; = None,
    return_dict: Optional&#91;bool&#93; = None,
    cache_position: Optional&#91;torch.LongTensor&#93; = None,
) -&gt; Union&#91;Tuple, BaseModelOutputWithPast&#93;:
    assert not self.gradient_checkpointing
    output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions
    output_hidden_states = (output_hidden_states
                            if output_hidden_states is not None else self.config.output_hidden_states)
    use_cache = use_cache if use_cache is not None else self.config.use_cache

    return_dict = return_dict if return_dict is not None else self.config.use_return_dict

    if (input_ids is None) ^ (inputs_embeds is not None):
        raise ValueError(&quot;You must specify exactly one of input_ids or inputs_embeds&quot;)

    if self.gradient_checkpointing and self.training:
        if use_cache:
            logger.warning_once(
                &quot;`use_cache=True` is incompatible with gradient checkpointing. Setting `use_cache=False`...&quot;)
            use_cache = False

    # torch.jit.trace() doesn&#x27;t support cache objects in the output
    if use_cache and past_key_values is None and not torch.jit.is_tracing():
        past_key_values = DynamicCache()
    if inputs_embeds is None:
        inputs_embeds = self.embed_tokens(input_ids)

    if cache_position is None:
        past_seen_tokens = past_key_values.get_seq_length() if past_key_values is not None else 0
        cache_position = torch.arange(
            past_seen_tokens,
            past_seen_tokens + inputs_embeds.shape&#91;1&#93;,
            device=inputs_embeds.device,
        )

    # the hard coded `3` is for temporal, height and width.
    if position_ids is None:
        position_ids = cache_position.view(1, 1, -1).expand(3, inputs_embeds.shape&#91;0&#93;, -1)
    elif position_ids.dim() == 2:
        position_ids = position_ids&#91;None, ...&#93;.expand(3, position_ids.shape&#91;0&#93;, -1)

    if self.cp_mesh is None:
        causal_mask = self._update_causal_mask(
            attention_mask,
            inputs_embeds,
            cache_position,
            past_key_values,
            output_attentions,
        )

    hidden_states = inputs_embeds

    # create position embeddings to be shared across the decoder layers
    position_embeddings = self.rotary_emb(hidden_states, position_ids)

    # decoder layers
    all_hidden_states = () if output_hidden_states else None
    all_self_attns = () if output_attentions else None
    next_decoder_cache = None
    layer_id = 0
    seqlen = hidden_states.shape&#91;1&#93;
    if self.config._attn_implementation == &quot;sdpa&quot;:
        causal_mask = torch.full((seqlen, seqlen), float(&quot;-inf&quot;), device=hidden_states.device).triu_(1)
        causal_mask = causal_mask.to(hidden_states.dtype)
    if self.cp_mesh is not None:
        seq_range = self._seq_range(seqlen)
        position_embeddings = (
            position_embeddings&#91;0&#93;&#91;:, :, seq_range&#91;0&#93;:seq_range&#91;1&#93;, :&#93;,
            position_embeddings&#91;1&#93;&#91;:, :, seq_range&#91;0&#93;:seq_range&#91;1&#93;, :&#93;,
        )
        hidden_states = hidden_states&#91;:, seq_range&#91;0&#93;:seq_range&#91;1&#93;, :&#93;
        position_ids = position_ids&#91;:, :, seq_range&#91;0&#93;:seq_range&#91;1&#93;&#93;
        cache_position = cache_position&#91;seq_range&#91;0&#93;:seq_range&#91;1&#93;&#93;
        causal_mask = causal_mask&#91;seq_range&#91;0&#93;:seq_range&#91;1&#93;&#93;
        assert past_key_values is None, &quot;not support cp with past_key_values&quot;

    for decoder_layer in self.layers:
        if output_hidden_states:
            all_hidden_states += (hidden_states, )
        layer_id += 1
        if self.gradient_checkpointing and self.training:
            raise NotImplementedError(&quot;Gradient checkpointing is not implemented here&quot;)
            # layer_outputs = self._gradient_checkpointing_func(
            #     decoder_layer.__call__,
            #     hidden_states,
            #     causal_mask,
            #     position_ids,
            #     past_key_values,
            #     output_attentions,
            #     use_cache,
            #     cache_position,
            #     position_embeddings,
            # )
        else:
            layer_outputs = decoder_layer(
                hidden_states,
                attention_mask=causal_mask,  # None
                position_ids=position_ids,
                past_key_value=past_key_values,  # None
                output_attentions=output_attentions,  # bool
                use_cache=use_cache,  # bool
                cache_position=cache_position,  # None
                position_embeddings=position_embeddings,
                cp_mesh=self.cp_mesh,  # device mesh
            )

        hidden_states = layer_outputs&#91;0&#93;

        if use_cache:
            next_decoder_cache = layer_outputs&#91;2 if output_attentions else 1&#93;

        if output_attentions:
            all_self_attns += (layer_outputs&#91;1&#93;, )

    hidden_states = self.norm(hidden_states)

    # add hidden states from the last decoder layer
    if output_hidden_states:
        all_hidden_states += (hidden_states, )

    next_cache = next_decoder_cache if use_cache else None

    if not return_dict:
        return tuple(v for v in &#91;hidden_states, next_cache, all_hidden_states, all_self_attns&#93; if v is not None)
    return BaseModelOutputWithPast(
        last_hidden_state=hidden_states,
        past_key_values=next_cache,
        hidden_states=all_hidden_states,
        attentions=all_self_attns,
    )

def _seq_range(self, seqlen) -&gt; tuple&#91;int, int&#93;:
    if self.cp_mesh is not None:
        assert seqlen % self.cp_mesh.size() == 0, f&quot;seqlen: &#123;seqlen&#125;, mesh size: &#123;self.cp_mesh.size()&#125;&quot;
        local_seqlen = seqlen // self.cp_mesh.size()
        cp_rank = self.cp_mesh.get_local_rank()
        return (cp_rank * local_seqlen, (cp_rank + 1) * local_seqlen)
    else:
        return (0, seqlen)

def _update_causal_mask(
    self,
    attention_mask: torch.Tensor,
    input_tensor: torch.Tensor,
    cache_position: torch.Tensor,
    past_key_values: Cache,
    output_attentions: bool,
):
    if self.config._attn_implementation == &quot;flash_attention_2&quot;:
        if attention_mask is not None and past_key_values is not None:
            is_padding_right = attention_mask&#91;:, -1&#93;.sum().item() != input_tensor.size()&#91;0&#93;
            if is_padding_right:
                raise ValueError(
                    &quot;You are attempting to perform batched generation with padding_side=&#x27;right&#x27;&quot;
                    &quot; this may lead to unexpected behaviour for Flash Attention version of Qwen2_5_VL. Make sure to &quot;
                    &quot; call `tokenizer.padding_side  = &#x27;left&#x27;` before tokenizing the input. &quot;)
        if attention_mask is not None and 0.0 in attention_mask:
            return attention_mask
        return None

    # For SDPA, when possible, we will rely on its `is_causal` argument instead of its `attn_mask` argument, in
    # order to dispatch on Flash Attention 2. This feature is not compatible with static cache, as SDPA will fail
    # to infer the attention mask.
    past_seen_tokens = past_key_values.get_seq_length() if past_key_values is not None else 0
    using_static_cache = isinstance(past_key_values, StaticCache)
    using_sliding_window_cache = isinstance(past_key_values, SlidingWindowCache)

    # When output attentions is True, sdpa implementation&#x27;s forward method calls the eager implementation&#x27;s forward
    if (self.config._attn_implementation == &quot;sdpa&quot; and not (using_static_cache or using_sliding_window_cache)
            and not output_attentions):
        if AttentionMaskConverter._ignore_causal_mask_sdpa(
                attention_mask,
                inputs_embeds=input_tensor,
                past_key_values_length=past_seen_tokens,
                sliding_window=self.config.sliding_window,
                is_training=self.training,
        ):
            return None

    dtype, device = input_tensor.dtype, input_tensor.device
    min_dtype = torch.finfo(dtype).min
    sequence_length = input_tensor.shape&#91;1&#93;
    # SlidingWindowCache or StaticCache
    if using_sliding_window_cache or using_static_cache:
        target_length = past_key_values.get_max_cache_shape()
    # DynamicCache or no cache
    else:
        target_length = (attention_mask.shape&#91;-1&#93;
                         if isinstance(attention_mask, torch.Tensor) else past_seen_tokens + sequence_length + 1)

    # In case the provided `attention` mask is 2D, we generate a causal mask here (4D).
    causal_mask = self._prepare_4d_causal_attention_mask_with_cache_position(
        attention_mask,
        sequence_length=sequence_length,
        target_length=target_length,
        dtype=dtype,
        device=device,
        cache_position=cache_position,
        batch_size=input_tensor.shape&#91;0&#93;,
        config=self.config,
        past_key_values=past_key_values,
    )

    if (self.config._attn_implementation == &quot;sdpa&quot; and attention_mask is not None
            and attention_mask.device.type in &#91;&quot;cuda&quot;, &quot;xpu&quot;&#93; and not output_attentions):
        # Attend to all tokens in fully masked rows in the causal_mask, for example the relevant first rows when
        # using left padding. This is required by F.scaled_dot_product_attention memory-efficient attention path.
        # Details: https://github.com/pytorch/pytorch/issues/110213
        causal_mask = AttentionMaskConverter._unmask_unattended(causal_mask, min_dtype)

    return causal_mask

@staticmethod
def _prepare_4d_causal_attention_mask_with_cache_position(
    attention_mask: torch.Tensor,
    sequence_length: int,
    target_length: int,
    dtype: torch.dtype,
    device: torch.device,
    cache_position: torch.Tensor,
    batch_size: int,
    config: Qwen2_5_VLConfig,
    past_key_values: Cache,
):
    &quot;&quot;&quot;
    Creates a causal 4D mask of shape `(batch_size, 1, query_length, key_value_length)` from a 2D mask of shape
    `(batch_size, key_value_length)`, or if the input `attention_mask` is already 4D, do nothing.

    Args:
        attention_mask (`torch.Tensor`):
            A 2D attention mask of shape `(batch_size, key_value_length)` or a 4D attention mask of shape `(batch_size, 1, query_length, key_value_length)`.
        sequence_length (`int`):
            The sequence length being processed.
        target_length (`int`):
            The target length: when generating with static cache, the mask should be as long as the static cache, to account for the 0 padding, the part of the cache that is not filled yet.
        dtype (`torch.dtype`):
            The dtype to use for the 4D attention mask.
        device (`torch.device`):
            The device to plcae the 4D attention mask on.
        cache_position (`torch.Tensor`):
            Indices depicting the position of the input sequence tokens in the sequence.
        batch_size (`torch.Tensor`):
            Batch size.
        config (`Qwen2_5_VLConfig`):
            The model&#x27;s configuration class
        past_key_values (`Cache`):
            The cache class that is being used currently to generate
    &quot;&quot;&quot;
    if attention_mask is not None and attention_mask.dim() == 4:
        # In this case we assume that the mask comes already in inverted form and requires no inversion or slicing.
        causal_mask = attention_mask
    else:
        min_dtype = torch.finfo(dtype).min
        causal_mask = torch.full(
            (sequence_length, target_length),
            fill_value=min_dtype,
            dtype=dtype,
            device=device,
        )
        diagonal_attend_mask = torch.arange(target_length, device=device) &gt; cache_position.reshape(-1, 1)
        if config.sliding_window is not None:
            # if we have sliding window, we should not attend to tokens beyond sliding window length, so we mask them out also
            # the check is needed to verify is current checkpoint was trained with sliding window or not
            if not isinstance(past_key_values, SlidingWindowCache) or sequence_length &gt; target_length:
                sliding_attend_mask = torch.arange(target_length, device=device) &lt;= (cache_position.reshape(-1, 1) -
                                                                                     config.sliding_window)
                diagonal_attend_mask.bitwise_or_(sliding_attend_mask)
        causal_mask *= diagonal_attend_mask
        causal_mask = causal_mask&#91;None, None, :, :&#93;.expand(batch_size, 1, -1, -1)
        if attention_mask is not None:
            causal_mask = causal_mask.clone()  # copy to contiguous memory for in-place edit
            if attention_mask.shape&#91;-1&#93; &gt; target_length:
                attention_mask = attention_mask&#91;:, :target_length&#93;
            mask_length = attention_mask.shape&#91;-1&#93;
            padding_mask = causal_mask&#91;:, :, :, :mask_length&#93; + attention_mask&#91;:, None, None, :&#93;.to(
                causal_mask.device)
            padding_mask = padding_mask == 0
            causal_mask&#91;:, :, :, :mask_length&#93; = causal_mask&#91;:, :, :, :mask_length&#93;.masked_fill(
                padding_mask, min_dtype)
    return causal_mask</code></pre></details>

fastvideo.models.encoders.qwen2_5_vl_custom.Qwen2_5_VLModel.init_weights

init_weights(buffer_device: Optional[torch.device] = None)
Source
def init_weights(self, buffer_device: Optional[torch.device] = None):
    self.rotary_emb.init_weights(buffer_device)

fastvideo.models.encoders.qwen2_5_vl_custom.Qwen2_5_VLModel.get_input_embeddings

get_input_embeddings()
Source
def get_input_embeddings(self):
    return self.embed_tokens

fastvideo.models.encoders.qwen2_5_vl_custom.Qwen2_5_VLModel.set_input_embeddings

set_input_embeddings(value)
Source
def set_input_embeddings(self, value):
    self.embed_tokens = value

fastvideo.models.encoders.qwen2_5_vl_custom.Qwen2_5_VLModel.set_cp_mesh

set_cp_mesh(cp_mesh)
Source
def set_cp_mesh(self, cp_mesh):
    self.cp_mesh = cp_mesh

fastvideo.models.encoders.qwen2_5_vl_custom.Qwen2_5_VLModel.forward

forward(input_ids: torch.LongTensor = None, attention_mask: Optional[torch.Tensor] = None, position_ids: Optional[torch.LongTensor] = None, past_key_values: Optional[List[torch.FloatTensor]] = None, inputs_embeds: Optional[torch.FloatTensor] = None, use_cache: Optional[bool] = None, output_attentions: Optional[bool] = None, output_hidden_states: Optional[bool] = None, return_dict: Optional[bool] = None, cache_position: Optional[torch.LongTensor] = None) -> Union[Tuple, BaseModelOutputWithPast]
Source
def forward(
    self,
    input_ids: torch.LongTensor = None,
    attention_mask: Optional[torch.Tensor] = None,
    position_ids: Optional[torch.LongTensor] = None,
    past_key_values: Optional[List[torch.FloatTensor]] = None,
    inputs_embeds: Optional[torch.FloatTensor] = None,
    use_cache: Optional[bool] = None,
    output_attentions: Optional[bool] = None,
    output_hidden_states: Optional[bool] = None,
    return_dict: Optional[bool] = None,
    cache_position: Optional[torch.LongTensor] = None,
) -> Union[Tuple, BaseModelOutputWithPast]:
    assert not self.gradient_checkpointing
    output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions
    output_hidden_states = (output_hidden_states
                            if output_hidden_states is not None else self.config.output_hidden_states)
    use_cache = use_cache if use_cache is not None else self.config.use_cache
return_dict = return_dict if return_dict is not None else self.config.use_return_dict

if (input_ids is None) ^ (inputs_embeds is not None):
    raise ValueError(&quot;You must specify exactly one of input_ids or inputs_embeds&quot;)

if self.gradient_checkpointing and self.training:
    if use_cache:
        logger.warning_once(
            &quot;`use_cache=True` is incompatible with gradient checkpointing. Setting `use_cache=False`...&quot;)
        use_cache = False

# torch.jit.trace() doesn&#x27;t support cache objects in the output
if use_cache and past_key_values is None and not torch.jit.is_tracing():
    past_key_values = DynamicCache()
if inputs_embeds is None:
    inputs_embeds = self.embed_tokens(input_ids)

if cache_position is None:
    past_seen_tokens = past_key_values.get_seq_length() if past_key_values is not None else 0
    cache_position = torch.arange(
        past_seen_tokens,
        past_seen_tokens + inputs_embeds.shape&#91;1&#93;,
        device=inputs_embeds.device,
    )

# the hard coded `3` is for temporal, height and width.
if position_ids is None:
    position_ids = cache_position.view(1, 1, -1).expand(3, inputs_embeds.shape&#91;0&#93;, -1)
elif position_ids.dim() == 2:
    position_ids = position_ids&#91;None, ...&#93;.expand(3, position_ids.shape&#91;0&#93;, -1)

if self.cp_mesh is None:
    causal_mask = self._update_causal_mask(
        attention_mask,
        inputs_embeds,
        cache_position,
        past_key_values,
        output_attentions,
    )

hidden_states = inputs_embeds

# create position embeddings to be shared across the decoder layers
position_embeddings = self.rotary_emb(hidden_states, position_ids)

# decoder layers
all_hidden_states = () if output_hidden_states else None
all_self_attns = () if output_attentions else None
next_decoder_cache = None
layer_id = 0
seqlen = hidden_states.shape&#91;1&#93;
if self.config._attn_implementation == &quot;sdpa&quot;:
    causal_mask = torch.full((seqlen, seqlen), float(&quot;-inf&quot;), device=hidden_states.device).triu_(1)
    causal_mask = causal_mask.to(hidden_states.dtype)
if self.cp_mesh is not None:
    seq_range = self._seq_range(seqlen)
    position_embeddings = (
        position_embeddings&#91;0&#93;&#91;:, :, seq_range&#91;0&#93;:seq_range&#91;1&#93;, :&#93;,
        position_embeddings&#91;1&#93;&#91;:, :, seq_range&#91;0&#93;:seq_range&#91;1&#93;, :&#93;,
    )
    hidden_states = hidden_states&#91;:, seq_range&#91;0&#93;:seq_range&#91;1&#93;, :&#93;
    position_ids = position_ids&#91;:, :, seq_range&#91;0&#93;:seq_range&#91;1&#93;&#93;
    cache_position = cache_position&#91;seq_range&#91;0&#93;:seq_range&#91;1&#93;&#93;
    causal_mask = causal_mask&#91;seq_range&#91;0&#93;:seq_range&#91;1&#93;&#93;
    assert past_key_values is None, &quot;not support cp with past_key_values&quot;

for decoder_layer in self.layers:
    if output_hidden_states:
        all_hidden_states += (hidden_states, )
    layer_id += 1
    if self.gradient_checkpointing and self.training:
        raise NotImplementedError(&quot;Gradient checkpointing is not implemented here&quot;)
        # layer_outputs = self._gradient_checkpointing_func(
        #     decoder_layer.__call__,
        #     hidden_states,
        #     causal_mask,
        #     position_ids,
        #     past_key_values,
        #     output_attentions,
        #     use_cache,
        #     cache_position,
        #     position_embeddings,
        # )
    else:
        layer_outputs = decoder_layer(
            hidden_states,
            attention_mask=causal_mask,  # None
            position_ids=position_ids,
            past_key_value=past_key_values,  # None
            output_attentions=output_attentions,  # bool
            use_cache=use_cache,  # bool
            cache_position=cache_position,  # None
            position_embeddings=position_embeddings,
            cp_mesh=self.cp_mesh,  # device mesh
        )

    hidden_states = layer_outputs&#91;0&#93;

    if use_cache:
        next_decoder_cache = layer_outputs&#91;2 if output_attentions else 1&#93;

    if output_attentions:
        all_self_attns += (layer_outputs&#91;1&#93;, )

hidden_states = self.norm(hidden_states)

# add hidden states from the last decoder layer
if output_hidden_states:
    all_hidden_states += (hidden_states, )

next_cache = next_decoder_cache if use_cache else None

if not return_dict:
    return tuple(v for v in &#91;hidden_states, next_cache, all_hidden_states, all_self_attns&#93; if v is not None)
return BaseModelOutputWithPast(
    last_hidden_state=hidden_states,
    past_key_values=next_cache,
    hidden_states=all_hidden_states,
    attentions=all_self_attns,
)</code></pre></details>

fastvideo.models.encoders.qwen2_5_vl_custom.Qwen2_5_VLCausalLMOutputWithPast

Qwen2_5_VLCausalLMOutputWithPast(loss: Optional[torch.FloatTensor] = None, logits: torch.FloatTensor = None, past_key_values: Optional[List[torch.FloatTensor]] = None, hidden_states: Optional[Tuple[torch.FloatTensor]] = None, attentions: Optional[Tuple[torch.FloatTensor]] = None, rope_deltas: Optional[torch.LongTensor] = None)

Base class for Qwen2_5_VL causal language model (or autoregressive) outputs.

Parameters

loss: `torch.FloatTensor` of shape `(1,)`, *optional*, returned when `labels` is provided

Language modeling loss (for next-token prediction).

logits: `torch.FloatTensor` of shape `(batch_size, sequence_length, config.vocab_size)`

Prediction scores of the language modeling head (scores for each vocabulary token before SoftMax).

past_key_values: `tuple(tuple(torch.FloatTensor))`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`

Tuple of tuple(torch.FloatTensor) of length config.n_layers, with each tuple having 2 tensors of shape (batch_size, num_heads, sequence_length, embed_size_per_head))

Contains pre-computed hidden-states (key and values in the self-attention blocks) that can be used (see past_key_values input) to speed up sequential decoding.

hidden_states: `tuple(torch.FloatTensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`

Tuple of torch.FloatTensor (one for the output of the embeddings, if the model has an embedding layer, + one for the output of each layer) of shape (batch_size, sequence_length, hidden_size).

Hidden-states of the model at the output of each layer plus the optional initial embedding outputs.

attentions: `tuple(torch.FloatTensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`

Tuple of torch.FloatTensor (one for each layer) of shape (batch_size, num_heads, sequence_length, sequence_length).

Attentions weights after the attention softmax, used to compute the weighted average in the self-attention heads.

rope_deltas: `torch.LongTensor` of shape `(batch_size, )`, *optional*

The rope index difference between sequence length and multimodal rope.

Source
@dataclass
class Qwen2_5_VLCausalLMOutputWithPast(ModelOutput):
    """
    Base class for Qwen2_5_VL causal language model (or autoregressive) outputs.
Args:
    loss (`torch.FloatTensor` of shape `(1,)`, *optional*, returned when `labels` is provided):
        Language modeling loss (for next-token prediction).
    logits (`torch.FloatTensor` of shape `(batch_size, sequence_length, config.vocab_size)`):
        Prediction scores of the language modeling head (scores for each vocabulary token before SoftMax).
    past_key_values (`tuple(tuple(torch.FloatTensor))`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`):
        Tuple of `tuple(torch.FloatTensor)` of length `config.n_layers`, with each tuple having 2 tensors of shape
        `(batch_size, num_heads, sequence_length, embed_size_per_head)`)

        Contains pre-computed hidden-states (key and values in the self-attention blocks) that can be used (see
        `past_key_values` input) to speed up sequential decoding.
    hidden_states (`tuple(torch.FloatTensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`):
        Tuple of `torch.FloatTensor` (one for the output of the embeddings, if the model has an embedding layer, +
        one for the output of each layer) of shape `(batch_size, sequence_length, hidden_size)`.

        Hidden-states of the model at the output of each layer plus the optional initial embedding outputs.
    attentions (`tuple(torch.FloatTensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`):
        Tuple of `torch.FloatTensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length,
        sequence_length)`.

        Attentions weights after the attention softmax, used to compute the weighted average in the self-attention
        heads.
    rope_deltas (`torch.LongTensor` of shape `(batch_size, )`, *optional*):
        The rope index difference between sequence length and multimodal rope.
&quot;&quot;&quot;

loss: Optional&#91;torch.FloatTensor&#93; = None
logits: torch.FloatTensor = None
past_key_values: Optional&#91;List&#91;torch.FloatTensor&#93;&#93; = None
hidden_states: Optional&#91;Tuple&#91;torch.FloatTensor&#93;&#93; = None
attentions: Optional&#91;Tuple&#91;torch.FloatTensor&#93;&#93; = None
rope_deltas: Optional&#91;torch.LongTensor&#93; = None</code></pre></details>

fastvideo.models.encoders.qwen2_5_vl_custom.Qwen2_5_VLForConditionalGenerationSimple

Qwen2_5_VLForConditionalGenerationSimple(config)
Source
class Qwen2_5_VLForConditionalGenerationSimple(nn.Module):
    _tied_weights_keys = ["lm_head.weight"]
    config_class = Qwen2_5_VLConfig
    _no_split_modules = ["Qwen2VLDecoderLayer", "Qwen2_5_VLVisionBlock"]
def __init__(self, config):
    super().__init__()
    config = _flatten_text_config(config)
    config = _normalize_attention_implementation(config)
    config.vision_config = _normalize_attention_implementation(config.vision_config)
    self.config = config
    self.visual = Qwen2_5_VisionTransformerPretrainedModel(
        config.vision_config,
        parent_torch_dtype=getattr(config, &quot;torch_dtype&quot;, None),
    )

    self.model = Qwen2_5_VLModel(config)
    self.vocab_size = config.vocab_size
    self.lm_head = nn.Linear(config.hidden_size, config.vocab_size, bias=False)
    self.rope_deltas = None

def init_weights(self, buffer_device: Optional&#91;torch.device&#93; = None):
    self.model.init_weights(buffer_device)
    self.visual.init_weights(buffer_device)

def can_generate(self):
    return True

def get_input_embeddings(self):
    return self.model.embed_tokens

def set_input_embeddings(self, value):
    self.model.embed_tokens = value

def get_output_embeddings(self):
    return self.lm_head

def set_output_embeddings(self, new_embeddings):
    self.lm_head = new_embeddings

def set_decoder(self, decoder):
    self.model = decoder

def get_decoder(self):
    return self.model

def get_rope_index(
    self,
    input_ids: Optional&#91;torch.LongTensor&#93; = None,
    image_grid_thw: Optional&#91;torch.LongTensor&#93; = None,
    video_grid_thw: Optional&#91;torch.LongTensor&#93; = None,
    second_per_grid_ts: Optional&#91;torch.Tensor&#93; = None,
    attention_mask: Optional&#91;torch.Tensor&#93; = None,
) -&gt; Tuple&#91;torch.Tensor, torch.Tensor&#93;:
    &quot;&quot;&quot;
    Calculate the 3D rope index based on image and video&#x27;s temporal, height and width in LLM.

    Explanation:
        Each embedding sequence contains vision embedding and text embedding or just contains text embedding.

        For pure text embedding sequence, the rotary position embedding has no difference with modern LLMs.
        Examples:
            input_ids: &#91;T T T T T&#93;, here T is for text.
            temporal position_ids: &#91;0, 1, 2, 3, 4&#93;
            height position_ids: &#91;0, 1, 2, 3, 4&#93;
            width position_ids: &#91;0, 1, 2, 3, 4&#93;

        For vision and text embedding sequence, we calculate 3D rotary position embedding for vision part
        and 1D rotary position embeddin for text part.
        Examples:
            Temporal (Time): 3 patches, representing different segments of the video in time.
            Height: 2 patches, dividing each frame vertically.
            Width: 2 patches, dividing each frame horizontally.
            We also have some important parameters:
            fps (Frames Per Second): The video&#x27;s frame rate, set to 1. This means one frame is processed each second.
            tokens_per_second: This is a crucial parameter. It dictates how many &quot;time-steps&quot; or &quot;temporal tokens&quot; are conceptually packed into a one-second interval of the video. In this case, we have 25 tokens per second. So each second of the video will be represented with 25 separate time points. It essentially defines the temporal granularity.
            temporal_patch_size: The number of frames that compose one temporal patch. Here, it&#x27;s 2 frames.
            interval: The step size for the temporal position IDs, calculated as tokens_per_second * temporal_patch_size / fps. In this case, 25 * 2 / 1 = 50. This means that each temporal patch will be have a difference of 50 in the temporal position IDs.
            input_ids: &#91;V V V V V V V V V V V V T T T T T&#93;, here V is for vision.
            vision temporal position_ids: &#91;0, 0, 0, 0, 50, 50, 50, 50, 100, 100, 100, 100&#93;
            vision height position_ids: &#91;0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1&#93;
            vision width position_ids: &#91;0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1&#93;
            text temporal position_ids: &#91;101, 102, 103, 104, 105&#93;
            text height position_ids: &#91;101, 102, 103, 104, 105&#93;
            text width position_ids: &#91;101, 102, 103, 104, 105&#93;
            Here we calculate the text start position_ids as the max vision position_ids plus 1.

    Args:
        input_ids (`torch.LongTensor` of shape `(batch_size, sequence_length)`):
            Indices of input sequence tokens in the vocabulary. Padding will be ignored by default should you provide
            it.
        image_grid_thw (`torch.LongTensor` of shape `(num_images, 3)`, *optional*):
            The temporal, height and width of feature shape of each image in LLM.
        video_grid_thw (`torch.LongTensor` of shape `(num_videos, 3)`, *optional*):
            The temporal, height and width of feature shape of each video in LLM.
        second_per_grid_ts (`torch.Tensor` of shape `(num_videos)`, *optional*):
            The time interval (in seconds) for each grid along the temporal dimension in the 3D position IDs.
        attention_mask (`torch.Tensor` of shape `(batch_size, sequence_length)`, *optional*):
            Mask to avoid performing attention on padding token indices. Mask values selected in `&#91;0, 1&#93;`:

            - 1 for tokens that are **not masked**,
            - 0 for tokens that are **masked**.

    Returns:
        position_ids (`torch.LongTensor` of shape `(3, batch_size, sequence_length)`)
        mrope_position_deltas (`torch.Tensor` of shape `(batch_size)`)
    &quot;&quot;&quot;
    spatial_merge_size = self.config.vision_config.spatial_merge_size
    image_token_id = self.config.image_token_id
    video_token_id = self.config.video_token_id
    vision_start_token_id = self.config.vision_start_token_id
    mrope_position_deltas = &#91;&#93;
    if input_ids is not None and (image_grid_thw is not None or video_grid_thw is not None):
        total_input_ids = input_ids
        if attention_mask is None:
            attention_mask = torch.ones_like(total_input_ids)
        position_ids = torch.ones(
            3,
            input_ids.shape&#91;0&#93;,
            input_ids.shape&#91;1&#93;,
            dtype=input_ids.dtype,
            device=input_ids.device,
        )
        image_index, video_index = 0, 0
        attention_mask = attention_mask.to(total_input_ids.device)
        for i, input_ids in enumerate(total_input_ids):
            input_ids = input_ids&#91;attention_mask&#91;i&#93; == 1&#93;
            image_nums, video_nums = 0, 0
            vision_start_indices = torch.argwhere(input_ids == vision_start_token_id).squeeze(1)
            vision_tokens = input_ids&#91;vision_start_indices + 1&#93;
            image_nums = (vision_tokens == image_token_id).sum()
            video_nums = (vision_tokens == video_token_id).sum()
            input_tokens = input_ids.tolist()
            llm_pos_ids_list: list = &#91;&#93;
            st = 0
            remain_images, remain_videos = image_nums, video_nums
            for _ in range(image_nums + video_nums):
                if image_token_id in input_tokens and remain_images &gt; 0:
                    ed_image = input_tokens.index(image_token_id, st)
                else:
                    ed_image = len(input_tokens) + 1
                if video_token_id in input_tokens and remain_videos &gt; 0:
                    ed_video = input_tokens.index(video_token_id, st)
                else:
                    ed_video = len(input_tokens) + 1
                if ed_image &lt; ed_video:
                    t, h, w = (
                        image_grid_thw&#91;image_index&#93;&#91;0&#93;,
                        image_grid_thw&#91;image_index&#93;&#91;1&#93;,
                        image_grid_thw&#91;image_index&#93;&#91;2&#93;,
                    )
                    second_per_grid_t = 0
                    image_index += 1
                    remain_images -= 1
                    ed = ed_image

                else:
                    t, h, w = (
                        video_grid_thw&#91;video_index&#93;&#91;0&#93;,
                        video_grid_thw&#91;video_index&#93;&#91;1&#93;,
                        video_grid_thw&#91;video_index&#93;&#91;2&#93;,
                    )
                    second_per_grid_t = second_per_grid_ts&#91;video_index&#93; if second_per_grid_ts is not None else 1.0
                    video_index += 1
                    remain_videos -= 1
                    ed = ed_video
                llm_grid_t, llm_grid_h, llm_grid_w = (
                    t.item(),
                    h.item() // spatial_merge_size,
                    w.item() // spatial_merge_size,
                )
                text_len = ed - st

                st_idx = llm_pos_ids_list&#91;-1&#93;.max() + 1 if len(llm_pos_ids_list) &gt; 0 else 0
                llm_pos_ids_list.append(
                    torch.arange(text_len, device=input_ids.device).view(1, -1).expand(3, -1) + st_idx)

                range_tensor = torch.arange(llm_grid_t).view(-1, 1)
                expanded_range = range_tensor.expand(-1, llm_grid_h * llm_grid_w)

                time_tensor = expanded_range * second_per_grid_t * self.config.vision_config.tokens_per_second

                time_tensor_long = time_tensor.long()
                t_index = time_tensor_long.flatten()

                h_index = torch.arange(llm_grid_h).view(1, -1, 1).expand(llm_grid_t, -1, llm_grid_w).flatten()
                w_index = torch.arange(llm_grid_w).view(1, 1, -1).expand(llm_grid_t, llm_grid_h, -1).flatten()
                llm_pos_ids_list.append(torch.stack(&#91;t_index, h_index, w_index&#93;) + text_len + st_idx)
                st = ed + llm_grid_t * llm_grid_h * llm_grid_w

            if st &lt; len(input_tokens):
                st_idx = llm_pos_ids_list&#91;-1&#93;.max() + 1 if len(llm_pos_ids_list) &gt; 0 else 0
                text_len = len(input_tokens) - st
                llm_pos_ids_list.append(torch.arange(text_len).view(1, -1).expand(3, -1) + st_idx)

            llm_positions = torch.cat(llm_pos_ids_list, dim=1).reshape(3, -1)
            position_ids&#91;..., i, attention_mask&#91;i&#93; == 1&#93; = llm_positions.to(position_ids.device)
            mrope_position_deltas.append(llm_positions.max() + 1 - len(total_input_ids&#91;i&#93;))
        mrope_position_deltas = torch.tensor(mrope_position_deltas, device=input_ids.device).unsqueeze(1)
        return position_ids, mrope_position_deltas
    else:
        if attention_mask is not None:
            position_ids = attention_mask.long().cumsum(-1) - 1
            position_ids.masked_fill_(attention_mask == 0, 1)
            position_ids = position_ids.unsqueeze(0).expand(3, -1, -1).to(attention_mask.device)
            max_position_ids = position_ids.max(0, keepdim=False)&#91;0&#93;.max(-1, keepdim=True)&#91;0&#93;
            mrope_position_deltas = max_position_ids + 1 - attention_mask.shape&#91;-1&#93;
        else:
            position_ids = (torch.arange(input_ids.shape&#91;1&#93;,
                                         device=input_ids.device).view(1, 1, -1).expand(3, input_ids.shape&#91;0&#93;, -1))
            mrope_position_deltas = torch.zeros(
                &#91;input_ids.shape&#91;0&#93;, 1&#93;,
                device=input_ids.device,
                dtype=input_ids.dtype,
            )

        return position_ids, mrope_position_deltas

def forward(
    self,
    input_ids: torch.LongTensor = None,
    attention_mask: Optional&#91;torch.Tensor&#93; = None,
    position_ids: Optional&#91;torch.LongTensor&#93; = None,
    past_key_values: Optional&#91;List&#91;torch.FloatTensor&#93;&#93; = None,
    inputs_embeds: Optional&#91;torch.FloatTensor&#93; = None,
    labels: Optional&#91;torch.LongTensor&#93; = None,
    use_cache: Optional&#91;bool&#93; = None,
    output_attentions: Optional&#91;bool&#93; = None,
    output_hidden_states: Optional&#91;bool&#93; = None,
    return_dict: Optional&#91;bool&#93; = None,
    pixel_values: Optional&#91;torch.Tensor&#93; = None,
    pixel_values_videos: Optional&#91;torch.FloatTensor&#93; = None,
    image_grid_thw: Optional&#91;torch.LongTensor&#93; = None,
    video_grid_thw: Optional&#91;torch.LongTensor&#93; = None,
    rope_deltas: Optional&#91;torch.LongTensor&#93; = None,
    cache_position: Optional&#91;torch.LongTensor&#93; = None,
    second_per_grid_ts: Optional&#91;torch.Tensor&#93; = None,
) -&gt; Union&#91;Tuple, Qwen2_5_VLCausalLMOutputWithPast&#93;:
    r&quot;&quot;&quot;
    Args:
        labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*):
            Labels for computing the masked language modeling loss. Indices should either be in `&#91;0, ...,
            config.vocab_size&#93;` or -100 (see `input_ids` docstring). Tokens with indices set to `-100` are ignored
            (masked), the loss is only computed for the tokens with labels in `&#91;0, ..., config.vocab_size&#93;`.

    Returns:

    Example:

    ```python
    &gt;&gt;&gt; from PIL import Image
    &gt;&gt;&gt; import requests
    &gt;&gt;&gt; from transformers import AutoProcessor, Qwen2_5_VLForConditionalGeneration

    &gt;&gt;&gt; model = Qwen2_5_VLForConditionalGeneration.from_pretrained(&quot;Qwen/Qwen2.5-VL-7B-Instruct&quot;)
    &gt;&gt;&gt; processor = AutoProcessor.from_pretrained(&quot;Qwen/Qwen2.5-VL-7B-Instruct&quot;)

    &gt;&gt;&gt; messages = &#91;
        &#123;
            &quot;role&quot;: &quot;user&quot;,
            &quot;content&quot;: &#91;
                &#123;&quot;type&quot;: &quot;image&quot;&#125;,
                &#123;&quot;type&quot;: &quot;text&quot;, &quot;text&quot;: &quot;What is shown in this image?&quot;&#125;,
            &#93;,
        &#125;,
    &#93;
    &gt;&gt;&gt; url = &quot;https://www.ilankelman.org/stopsigns/australia.jpg&quot;
    &gt;&gt;&gt; image = Image.open(requests.get(url, stream=True).raw)

    &gt;&gt;&gt; text = processor.apply_chat_template(messages, tokenize=False, add_generation_prompt=True)
    &gt;&gt;&gt; inputs = processor(text=&#91;text&#93;, images=&#91;image&#93;, vision_infos=&#91;vision_infos&#93;)

    &gt;&gt;&gt; # Generate
    &gt;&gt;&gt; generate_ids = model.generate(inputs.input_ids, max_length=30)
    &gt;&gt;&gt; tokenizer.batch_decode(generate_ids, skip_special_tokens=True, clean_up_tokenization_spaces=False)&#91;0&#93;
    &quot;The image shows a street scene with a red stop sign in the foreground. In the background, there is a large red gate with Chinese characters ...&quot;
    ```&quot;&quot;&quot;

    output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions
    output_hidden_states = (output_hidden_states
                            if output_hidden_states is not None else self.config.output_hidden_states)
    return_dict = return_dict if return_dict is not None else self.config.use_return_dict

    if inputs_embeds is None:
        inputs_embeds = self.model.embed_tokens(input_ids)
        # This is a trick to handle TP for LLM but no TP for vision encoder, we need to convert DTensor to regular tensor later
        is_inputs_embeds_dtensor = isinstance(inputs_embeds, DTensor)  # This is True for TP&gt;1, False for TP=1
        if is_inputs_embeds_dtensor:
            target_device_mesh = inputs_embeds.device_mesh
            target_placements = inputs_embeds.placements
            inputs_embeds = inputs_embeds.full_tensor()

        if pixel_values is not None:
            pixel_values = pixel_values.type(self.visual.dtype)
            image_embeds = self.visual(pixel_values, grid_thw=image_grid_thw)
            n_image_tokens = (input_ids == self.config.image_token_id).sum().item()
            n_image_features = image_embeds.shape&#91;0&#93;
            if n_image_tokens != n_image_features:
                raise ValueError(
                    f&quot;Image features and image tokens do not match: tokens: &#123;n_image_tokens&#125;, features &#123;n_image_features&#125;&quot;
                )

            mask = input_ids == self.config.image_token_id
            mask_unsqueezed = mask.unsqueeze(-1)
            mask_expanded = mask_unsqueezed.expand_as(inputs_embeds)
            image_mask = mask_expanded.to(inputs_embeds.device)

            image_embeds = image_embeds.to(inputs_embeds.device, inputs_embeds.dtype)
            inputs_embeds = inputs_embeds.masked_scatter(image_mask, image_embeds)

        if pixel_values_videos is not None:
            pixel_values_videos = pixel_values_videos.type(self.visual.dtype)
            video_embeds = self.visual(pixel_values_videos, grid_thw=video_grid_thw)
            n_video_tokens = (input_ids == self.config.video_token_id).sum().item()
            n_video_features = video_embeds.shape&#91;0&#93;
            if n_video_tokens != n_video_features:
                raise ValueError(
                    f&quot;Video features and video tokens do not match: tokens: &#123;n_video_tokens&#125;, features &#123;n_video_features&#125;&quot;
                )

            mask = input_ids == self.config.video_token_id
            mask_unsqueezed = mask.unsqueeze(-1)
            mask_expanded = mask_unsqueezed.expand_as(inputs_embeds)
            video_mask = mask_expanded.to(inputs_embeds.device)

            video_embeds = video_embeds.to(inputs_embeds.device, inputs_embeds.dtype)
            inputs_embeds = inputs_embeds.masked_scatter(video_mask, video_embeds)
        if is_inputs_embeds_dtensor:
            inputs_embeds = (DTensor.from_local(
                inputs_embeds,
                device_mesh=target_device_mesh).redistribute(placements=target_placements).to_local())
        if attention_mask is not None:
            attention_mask = attention_mask.to(inputs_embeds.device)

    # if we get 4D attention mask we cannot calculate rope deltas anymore.
    if position_ids is None and (attention_mask is None or attention_mask.ndim == 2):
        # calculate RoPE index once per generation in the pre-fill stage only
        if ((cache_position is not None and cache_position&#91;0&#93; == 0) or self.rope_deltas is None
                or (past_key_values is None or past_key_values.get_seq_length() == 0)):
            position_ids, rope_deltas = self.get_rope_index(
                input_ids,
                image_grid_thw,
                video_grid_thw,
                second_per_grid_ts,
                attention_mask,
            )
            self.rope_deltas = rope_deltas
        # then use the prev pre-calculated rope-deltas to get the correct position ids
        else:
            batch_size, seq_length, _ = inputs_embeds.shape
            delta = ((cache_position&#91;0&#93; +
                      self.rope_deltas).to(inputs_embeds.device) if cache_position is not None else 0)
            position_ids = torch.arange(seq_length, device=inputs_embeds.device)
            position_ids = position_ids.view(1, -1).expand(batch_size, -1)
            if cache_position is not None:  # otherwise `deltas` is an int `0`
                delta = delta.repeat_interleave(batch_size // delta.shape&#91;0&#93;, dim=0)
            position_ids = position_ids.add(delta)
            position_ids = position_ids.unsqueeze(0).expand(3, -1, -1)

    outputs = self.model(
        input_ids=None,
        position_ids=position_ids,
        attention_mask=attention_mask,
        past_key_values=past_key_values,
        inputs_embeds=inputs_embeds,
        use_cache=use_cache,
        output_attentions=output_attentions,
        output_hidden_states=output_hidden_states,
        return_dict=return_dict,
        cache_position=cache_position,
    )

    hidden_states = outputs&#91;0&#93;
    logits = self.lm_head(hidden_states)

    loss = None
    if labels is not None:
        # Upcast to float if we need to compute the loss to avoid potential precision issues
        logits = logits.float()
        # Shift so that tokens &lt; n predict n
        shift_logits = logits&#91;..., :-1, :&#93;.contiguous()
        shift_labels = labels&#91;..., 1:&#93;.contiguous()
        # Flatten the tokens
        loss_fct = CrossEntropyLoss()
        shift_logits = shift_logits.view(-1, self.config.vocab_size)
        shift_labels = shift_labels.view(-1)
        # Enable model parallelism
        shift_labels = shift_labels.to(shift_logits.device)
        loss = loss_fct(shift_logits, shift_labels)

    if not return_dict:
        output = (logits, )  # + outputs&#91;1:&#93;
        return (loss, ) + output if loss is not None else output

    return Qwen2_5_VLCausalLMOutputWithPast(
        loss=loss,
        logits=logits,
        past_key_values=outputs.past_key_values,
        hidden_states=outputs.hidden_states,
        attentions=outputs.attentions,
        rope_deltas=self.rope_deltas,
    )

def prepare_inputs_for_generation(
    self,
    input_ids,
    past_key_values=None,
    attention_mask=None,
    inputs_embeds=None,
    cache_position=None,
    position_ids=None,
    use_cache=True,
    pixel_values=None,
    pixel_values_videos=None,
    image_grid_thw=None,
    video_grid_thw=None,
    second_per_grid_ts=None,
    **kwargs,
):
    # Overwritten -- in specific circumstances we don&#x27;t want to forward image inputs to the model

    # If we have cache: let&#x27;s slice `input_ids` through `cache_position`, to keep only the unprocessed tokens
    # Exception 1: when passing input_embeds, input_ids may be missing entries
    # Exception 2: some generation methods do special slicing of input_ids, so we don&#x27;t need to do it here
    # Exception 3: with synced GPUs cache_position may go out of bounds, but we only want dummy token in that case.
    #              (we can&#x27;t check exception 3 while compiling)
    # Exception 4: If input_embeds are passed then slice it through `cache_position`, to keep only the unprocessed tokens and
    # generate the first token for each sequence. Later use the generated Input ids for continuation.
    if past_key_values is not None:
        if inputs_embeds is not None and input_ids.shape&#91;1&#93; == 0:  # Exception 4
            inputs_embeds = inputs_embeds&#91;:, -cache_position.shape&#91;0&#93;:&#93;
        elif inputs_embeds is not None or (  # Exception 1
                is_torchdynamo_compiling() or cache_position&#91;-1&#93; &gt;= input_ids.shape&#91;1&#93;):  # Exception 3
            input_ids = input_ids&#91;:, -cache_position.shape&#91;0&#93;:&#93;
        elif input_ids.shape&#91;1&#93; != cache_position.shape&#91;0&#93;:  # Default case (the &quot;else&quot;, a no op, is Exception 2)
            input_ids = input_ids&#91;:, cache_position&#93;

    if cache_position&#91;0&#93; != 0:
        pixel_values = None
        pixel_values_videos = None

    # if `inputs_embeds` are passed, we only want to use them in the 1st generation step
    if inputs_embeds is not None and len(cache_position) == inputs_embeds.shape&#91;1&#93;:
        model_inputs = &#123;&quot;inputs_embeds&quot;: inputs_embeds, &quot;input_ids&quot;: None&#125;
    else:
        model_inputs = &#123;&quot;input_ids&quot;: input_ids, &quot;inputs_embeds&quot;: None&#125;

    if isinstance(past_key_values, StaticCache) and attention_mask.ndim == 2:
        if model_inputs&#91;&quot;inputs_embeds&quot;&#93; is not None:
            batch_size, sequence_length, _ = inputs_embeds.shape
            device = inputs_embeds.device
        else:
            batch_size, sequence_length = input_ids.shape
            device = input_ids.device

        attention_mask = self.model._prepare_4d_causal_attention_mask_with_cache_position(
            attention_mask,
            sequence_length=sequence_length,
            target_length=past_key_values.get_max_cache_shape(),
            dtype=self.lm_head.weight.dtype,
            device=device,
            cache_position=cache_position,
            batch_size=batch_size,
            config=self.config,
            past_key_values=past_key_values,
        )

    model_inputs.update(&#123;
        &quot;position_ids&quot;: position_ids,
        &quot;past_key_values&quot;: past_key_values,
        &quot;use_cache&quot;: use_cache,
        &quot;attention_mask&quot;: attention_mask,
        &quot;pixel_values&quot;: pixel_values,
        &quot;pixel_values_videos&quot;: pixel_values_videos,
        &quot;image_grid_thw&quot;: image_grid_thw,
        &quot;video_grid_thw&quot;: video_grid_thw,
        &quot;cache_position&quot;: cache_position,
        &quot;second_per_grid_ts&quot;: second_per_grid_ts,
    &#125;)
    return model_inputs</code></pre></details>

fastvideo.models.encoders.qwen2_5_vl_custom.Qwen2_5_VLForConditionalGenerationSimple.init_weights

init_weights(buffer_device: Optional[torch.device] = None)
Source
def init_weights(self, buffer_device: Optional[torch.device] = None):
    self.model.init_weights(buffer_device)
    self.visual.init_weights(buffer_device)

fastvideo.models.encoders.qwen2_5_vl_custom.Qwen2_5_VLForConditionalGenerationSimple.can_generate

can_generate()
Source
def can_generate(self):
    return True

fastvideo.models.encoders.qwen2_5_vl_custom.Qwen2_5_VLForConditionalGenerationSimple.get_input_embeddings

get_input_embeddings()
Source
def get_input_embeddings(self):
    return self.model.embed_tokens

fastvideo.models.encoders.qwen2_5_vl_custom.Qwen2_5_VLForConditionalGenerationSimple.set_input_embeddings

set_input_embeddings(value)
Source
def set_input_embeddings(self, value):
    self.model.embed_tokens = value

fastvideo.models.encoders.qwen2_5_vl_custom.Qwen2_5_VLForConditionalGenerationSimple.get_output_embeddings

get_output_embeddings()
Source
def get_output_embeddings(self):
    return self.lm_head

fastvideo.models.encoders.qwen2_5_vl_custom.Qwen2_5_VLForConditionalGenerationSimple.set_output_embeddings

set_output_embeddings(new_embeddings)
Source
def set_output_embeddings(self, new_embeddings):
    self.lm_head = new_embeddings

fastvideo.models.encoders.qwen2_5_vl_custom.Qwen2_5_VLForConditionalGenerationSimple.set_decoder

set_decoder(decoder)
Source
def set_decoder(self, decoder):
    self.model = decoder

fastvideo.models.encoders.qwen2_5_vl_custom.Qwen2_5_VLForConditionalGenerationSimple.get_decoder

get_decoder()
Source
def get_decoder(self):
    return self.model

fastvideo.models.encoders.qwen2_5_vl_custom.Qwen2_5_VLForConditionalGenerationSimple.get_rope_index

get_rope_index(input_ids: Optional[torch.LongTensor] = None, image_grid_thw: Optional[torch.LongTensor] = None, video_grid_thw: Optional[torch.LongTensor] = None, second_per_grid_ts: Optional[torch.Tensor] = None, attention_mask: Optional[torch.Tensor] = None) -> Tuple[torch.Tensor, torch.Tensor]

Calculate the 3D rope index based on image and video's temporal, height and width in LLM.

Explanation

Each embedding sequence contains vision embedding and text embedding or just contains text embedding.

For pure text embedding sequence, the rotary position embedding has no difference with modern LLMs. Examples: input_ids: [T T T T T], here T is for text. temporal position_ids: [0, 1, 2, 3, 4] height position_ids: [0, 1, 2, 3, 4] width position_ids: [0, 1, 2, 3, 4]

For vision and text embedding sequence, we calculate 3D rotary position embedding for vision part and 1D rotary position embeddin for text part. Examples: Temporal (Time): 3 patches, representing different segments of the video in time. Height: 2 patches, dividing each frame vertically. Width: 2 patches, dividing each frame horizontally. We also have some important parameters: fps (Frames Per Second): The video's frame rate, set to 1. This means one frame is processed each second. tokens_per_second: This is a crucial parameter. It dictates how many "time-steps" or "temporal tokens" are conceptually packed into a one-second interval of the video. In this case, we have 25 tokens per second. So each second of the video will be represented with 25 separate time points. It essentially defines the temporal granularity. temporal_patch_size: The number of frames that compose one temporal patch. Here, it's 2 frames. interval: The step size for the temporal position IDs, calculated as tokens_per_second * temporal_patch_size / fps. In this case, 25 * 2 / 1 = 50. This means that each temporal patch will be have a difference of 50 in the temporal position IDs. input_ids: [V V V V V V V V V V V V T T T T T], here V is for vision. vision temporal position_ids: [0, 0, 0, 0, 50, 50, 50, 50, 100, 100, 100, 100] vision height position_ids: [0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1] vision width position_ids: [0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1] text temporal position_ids: [101, 102, 103, 104, 105] text height position_ids: [101, 102, 103, 104, 105] text width position_ids: [101, 102, 103, 104, 105] Here we calculate the text start position_ids as the max vision position_ids plus 1.

Parameters

input_ids: `torch.LongTensor` of shape `(batch_size, sequence_length)`

Indices of input sequence tokens in the vocabulary. Padding will be ignored by default should you provide it.

image_grid_thw: `torch.LongTensor` of shape `(num_images, 3)`, *optional*

The temporal, height and width of feature shape of each image in LLM.

video_grid_thw: `torch.LongTensor` of shape `(num_videos, 3)`, *optional*

The temporal, height and width of feature shape of each video in LLM.

second_per_grid_ts: `torch.Tensor` of shape `(num_videos)`, *optional*

The time interval (in seconds) for each grid along the temporal dimension in the 3D position IDs.

attention_mask: `torch.Tensor` of shape `(batch_size, sequence_length)`, *optional*

Mask to avoid performing attention on padding token indices. Mask values selected in [0, 1]:

  • 1 for tokens that are not masked,
  • 0 for tokens that are masked.

Returns

torch.Tensor

position_ids (torch.LongTensor of shape (3, batch_size, sequence_length))

torch.Tensor

mrope_position_deltas (torch.Tensor of shape (batch_size))

Source
def get_rope_index(
    self,
    input_ids: Optional[torch.LongTensor] = None,
    image_grid_thw: Optional[torch.LongTensor] = None,
    video_grid_thw: Optional[torch.LongTensor] = None,
    second_per_grid_ts: Optional[torch.Tensor] = None,
    attention_mask: Optional[torch.Tensor] = None,
) -> Tuple[torch.Tensor, torch.Tensor]:
    """
    Calculate the 3D rope index based on image and video's temporal, height and width in LLM.
Explanation:
    Each embedding sequence contains vision embedding and text embedding or just contains text embedding.

    For pure text embedding sequence, the rotary position embedding has no difference with modern LLMs.
    Examples:
        input_ids: &#91;T T T T T&#93;, here T is for text.
        temporal position_ids: &#91;0, 1, 2, 3, 4&#93;
        height position_ids: &#91;0, 1, 2, 3, 4&#93;
        width position_ids: &#91;0, 1, 2, 3, 4&#93;

    For vision and text embedding sequence, we calculate 3D rotary position embedding for vision part
    and 1D rotary position embeddin for text part.
    Examples:
        Temporal (Time): 3 patches, representing different segments of the video in time.
        Height: 2 patches, dividing each frame vertically.
        Width: 2 patches, dividing each frame horizontally.
        We also have some important parameters:
        fps (Frames Per Second): The video&#x27;s frame rate, set to 1. This means one frame is processed each second.
        tokens_per_second: This is a crucial parameter. It dictates how many &quot;time-steps&quot; or &quot;temporal tokens&quot; are conceptually packed into a one-second interval of the video. In this case, we have 25 tokens per second. So each second of the video will be represented with 25 separate time points. It essentially defines the temporal granularity.
        temporal_patch_size: The number of frames that compose one temporal patch. Here, it&#x27;s 2 frames.
        interval: The step size for the temporal position IDs, calculated as tokens_per_second * temporal_patch_size / fps. In this case, 25 * 2 / 1 = 50. This means that each temporal patch will be have a difference of 50 in the temporal position IDs.
        input_ids: &#91;V V V V V V V V V V V V T T T T T&#93;, here V is for vision.
        vision temporal position_ids: &#91;0, 0, 0, 0, 50, 50, 50, 50, 100, 100, 100, 100&#93;
        vision height position_ids: &#91;0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1&#93;
        vision width position_ids: &#91;0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1&#93;
        text temporal position_ids: &#91;101, 102, 103, 104, 105&#93;
        text height position_ids: &#91;101, 102, 103, 104, 105&#93;
        text width position_ids: &#91;101, 102, 103, 104, 105&#93;
        Here we calculate the text start position_ids as the max vision position_ids plus 1.

Args:
    input_ids (`torch.LongTensor` of shape `(batch_size, sequence_length)`):
        Indices of input sequence tokens in the vocabulary. Padding will be ignored by default should you provide
        it.
    image_grid_thw (`torch.LongTensor` of shape `(num_images, 3)`, *optional*):
        The temporal, height and width of feature shape of each image in LLM.
    video_grid_thw (`torch.LongTensor` of shape `(num_videos, 3)`, *optional*):
        The temporal, height and width of feature shape of each video in LLM.
    second_per_grid_ts (`torch.Tensor` of shape `(num_videos)`, *optional*):
        The time interval (in seconds) for each grid along the temporal dimension in the 3D position IDs.
    attention_mask (`torch.Tensor` of shape `(batch_size, sequence_length)`, *optional*):
        Mask to avoid performing attention on padding token indices. Mask values selected in `&#91;0, 1&#93;`:

        - 1 for tokens that are **not masked**,
        - 0 for tokens that are **masked**.

Returns:
    position_ids (`torch.LongTensor` of shape `(3, batch_size, sequence_length)`)
    mrope_position_deltas (`torch.Tensor` of shape `(batch_size)`)
&quot;&quot;&quot;
spatial_merge_size = self.config.vision_config.spatial_merge_size
image_token_id = self.config.image_token_id
video_token_id = self.config.video_token_id
vision_start_token_id = self.config.vision_start_token_id
mrope_position_deltas = &#91;&#93;
if input_ids is not None and (image_grid_thw is not None or video_grid_thw is not None):
    total_input_ids = input_ids
    if attention_mask is None:
        attention_mask = torch.ones_like(total_input_ids)
    position_ids = torch.ones(
        3,
        input_ids.shape&#91;0&#93;,
        input_ids.shape&#91;1&#93;,
        dtype=input_ids.dtype,
        device=input_ids.device,
    )
    image_index, video_index = 0, 0
    attention_mask = attention_mask.to(total_input_ids.device)
    for i, input_ids in enumerate(total_input_ids):
        input_ids = input_ids&#91;attention_mask&#91;i&#93; == 1&#93;
        image_nums, video_nums = 0, 0
        vision_start_indices = torch.argwhere(input_ids == vision_start_token_id).squeeze(1)
        vision_tokens = input_ids&#91;vision_start_indices + 1&#93;
        image_nums = (vision_tokens == image_token_id).sum()
        video_nums = (vision_tokens == video_token_id).sum()
        input_tokens = input_ids.tolist()
        llm_pos_ids_list: list = &#91;&#93;
        st = 0
        remain_images, remain_videos = image_nums, video_nums
        for _ in range(image_nums + video_nums):
            if image_token_id in input_tokens and remain_images &gt; 0:
                ed_image = input_tokens.index(image_token_id, st)
            else:
                ed_image = len(input_tokens) + 1
            if video_token_id in input_tokens and remain_videos &gt; 0:
                ed_video = input_tokens.index(video_token_id, st)
            else:
                ed_video = len(input_tokens) + 1
            if ed_image &lt; ed_video:
                t, h, w = (
                    image_grid_thw&#91;image_index&#93;&#91;0&#93;,
                    image_grid_thw&#91;image_index&#93;&#91;1&#93;,
                    image_grid_thw&#91;image_index&#93;&#91;2&#93;,
                )
                second_per_grid_t = 0
                image_index += 1
                remain_images -= 1
                ed = ed_image

            else:
                t, h, w = (
                    video_grid_thw&#91;video_index&#93;&#91;0&#93;,
                    video_grid_thw&#91;video_index&#93;&#91;1&#93;,
                    video_grid_thw&#91;video_index&#93;&#91;2&#93;,
                )
                second_per_grid_t = second_per_grid_ts&#91;video_index&#93; if second_per_grid_ts is not None else 1.0
                video_index += 1
                remain_videos -= 1
                ed = ed_video
            llm_grid_t, llm_grid_h, llm_grid_w = (
                t.item(),
                h.item() // spatial_merge_size,
                w.item() // spatial_merge_size,
            )
            text_len = ed - st

            st_idx = llm_pos_ids_list&#91;-1&#93;.max() + 1 if len(llm_pos_ids_list) &gt; 0 else 0
            llm_pos_ids_list.append(
                torch.arange(text_len, device=input_ids.device).view(1, -1).expand(3, -1) + st_idx)

            range_tensor = torch.arange(llm_grid_t).view(-1, 1)
            expanded_range = range_tensor.expand(-1, llm_grid_h * llm_grid_w)

            time_tensor = expanded_range * second_per_grid_t * self.config.vision_config.tokens_per_second

            time_tensor_long = time_tensor.long()
            t_index = time_tensor_long.flatten()

            h_index = torch.arange(llm_grid_h).view(1, -1, 1).expand(llm_grid_t, -1, llm_grid_w).flatten()
            w_index = torch.arange(llm_grid_w).view(1, 1, -1).expand(llm_grid_t, llm_grid_h, -1).flatten()
            llm_pos_ids_list.append(torch.stack(&#91;t_index, h_index, w_index&#93;) + text_len + st_idx)
            st = ed + llm_grid_t * llm_grid_h * llm_grid_w

        if st &lt; len(input_tokens):
            st_idx = llm_pos_ids_list&#91;-1&#93;.max() + 1 if len(llm_pos_ids_list) &gt; 0 else 0
            text_len = len(input_tokens) - st
            llm_pos_ids_list.append(torch.arange(text_len).view(1, -1).expand(3, -1) + st_idx)

        llm_positions = torch.cat(llm_pos_ids_list, dim=1).reshape(3, -1)
        position_ids&#91;..., i, attention_mask&#91;i&#93; == 1&#93; = llm_positions.to(position_ids.device)
        mrope_position_deltas.append(llm_positions.max() + 1 - len(total_input_ids&#91;i&#93;))
    mrope_position_deltas = torch.tensor(mrope_position_deltas, device=input_ids.device).unsqueeze(1)
    return position_ids, mrope_position_deltas
else:
    if attention_mask is not None:
        position_ids = attention_mask.long().cumsum(-1) - 1
        position_ids.masked_fill_(attention_mask == 0, 1)
        position_ids = position_ids.unsqueeze(0).expand(3, -1, -1).to(attention_mask.device)
        max_position_ids = position_ids.max(0, keepdim=False)&#91;0&#93;.max(-1, keepdim=True)&#91;0&#93;
        mrope_position_deltas = max_position_ids + 1 - attention_mask.shape&#91;-1&#93;
    else:
        position_ids = (torch.arange(input_ids.shape&#91;1&#93;,
                                     device=input_ids.device).view(1, 1, -1).expand(3, input_ids.shape&#91;0&#93;, -1))
        mrope_position_deltas = torch.zeros(
            &#91;input_ids.shape&#91;0&#93;, 1&#93;,
            device=input_ids.device,
            dtype=input_ids.dtype,
        )

    return position_ids, mrope_position_deltas</code></pre></details>

fastvideo.models.encoders.qwen2_5_vl_custom.Qwen2_5_VLForConditionalGenerationSimple.forward

forward(input_ids: torch.LongTensor = None, attention_mask: Optional[torch.Tensor] = None, position_ids: Optional[torch.LongTensor] = None, past_key_values: Optional[List[torch.FloatTensor]] = None, inputs_embeds: Optional[torch.FloatTensor] = None, labels: Optional[torch.LongTensor] = None, use_cache: Optional[bool] = None, output_attentions: Optional[bool] = None, output_hidden_states: Optional[bool] = None, return_dict: Optional[bool] = None, pixel_values: Optional[torch.Tensor] = None, pixel_values_videos: Optional[torch.FloatTensor] = None, image_grid_thw: Optional[torch.LongTensor] = None, video_grid_thw: Optional[torch.LongTensor] = None, rope_deltas: Optional[torch.LongTensor] = None, cache_position: Optional[torch.LongTensor] = None, second_per_grid_ts: Optional[torch.Tensor] = None) -> Union[Tuple, Qwen2_5_VLCausalLMOutputWithPast]

Parameters

labels: `torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*

Labels for computing the masked language modeling loss. Indices should either be in [0, ..., config.vocab_size] or -100 (see input_ids docstring). Tokens with indices set to -100 are ignored (masked), the loss is only computed for the tokens with labels in [0, ..., config.vocab_size].

Returns:

Example:

>>> from PIL import Image
>>> import requests
>>> from transformers import AutoProcessor, Qwen2_5_VLForConditionalGeneration

>>> model = Qwen2_5_VLForConditionalGeneration.from_pretrained("Qwen/Qwen2.5-VL-7B-Instruct") >>> processor = AutoProcessor.from_pretrained("Qwen/Qwen2.5-VL-7B-Instruct")

>>> messages = [ { "role": "user", "content": [ {"type": "image"}, {"type": "text", "text": "What is shown in this image?"}, ], }, ] >>> url = "https://www.ilankelman.org/stopsigns/australia.jpg" >>> image = Image.open(requests.get(url, stream=True).raw)

>>> text = processor.apply_chat_template(messages, tokenize=False, add_generation_prompt=True) >>> inputs = processor(text=[text], images=[image], vision_infos=[vision_infos])

>>> # Generate >>> generate_ids = model.generate(inputs.input_ids, max_length=30) >>> tokenizer.batch_decode(generate_ids, skip_special_tokens=True, clean_up_tokenization_spaces=False)[0] "The image shows a street scene with a red stop sign in the foreground. In the background, there is a large red gate with Chinese characters …"

Source
def forward(
    self,
    input_ids: torch.LongTensor = None,
    attention_mask: Optional[torch.Tensor] = None,
    position_ids: Optional[torch.LongTensor] = None,
    past_key_values: Optional[List[torch.FloatTensor]] = None,
    inputs_embeds: Optional[torch.FloatTensor] = None,
    labels: Optional[torch.LongTensor] = None,
    use_cache: Optional[bool] = None,
    output_attentions: Optional[bool] = None,
    output_hidden_states: Optional[bool] = None,
    return_dict: Optional[bool] = None,
    pixel_values: Optional[torch.Tensor] = None,
    pixel_values_videos: Optional[torch.FloatTensor] = None,
    image_grid_thw: Optional[torch.LongTensor] = None,
    video_grid_thw: Optional[torch.LongTensor] = None,
    rope_deltas: Optional[torch.LongTensor] = None,
    cache_position: Optional[torch.LongTensor] = None,
    second_per_grid_ts: Optional[torch.Tensor] = None,
) -> Union[Tuple, Qwen2_5_VLCausalLMOutputWithPast]:
    r"""
    Args:
        labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*):
            Labels for computing the masked language modeling loss. Indices should either be in `[0, ...,
            config.vocab_size]` or -100 (see `input_ids` docstring). Tokens with indices set to `-100` are ignored
            (masked), the loss is only computed for the tokens with labels in `[0, ..., config.vocab_size]`.
Returns:

Example:

```python
&gt;&gt;&gt; from PIL import Image
&gt;&gt;&gt; import requests
&gt;&gt;&gt; from transformers import AutoProcessor, Qwen2_5_VLForConditionalGeneration

&gt;&gt;&gt; model = Qwen2_5_VLForConditionalGeneration.from_pretrained(&quot;Qwen/Qwen2.5-VL-7B-Instruct&quot;)
&gt;&gt;&gt; processor = AutoProcessor.from_pretrained(&quot;Qwen/Qwen2.5-VL-7B-Instruct&quot;)

&gt;&gt;&gt; messages = &#91;
    &#123;
        &quot;role&quot;: &quot;user&quot;,
        &quot;content&quot;: &#91;
            &#123;&quot;type&quot;: &quot;image&quot;&#125;,
            &#123;&quot;type&quot;: &quot;text&quot;, &quot;text&quot;: &quot;What is shown in this image?&quot;&#125;,
        &#93;,
    &#125;,
&#93;
&gt;&gt;&gt; url = &quot;https://www.ilankelman.org/stopsigns/australia.jpg&quot;
&gt;&gt;&gt; image = Image.open(requests.get(url, stream=True).raw)

&gt;&gt;&gt; text = processor.apply_chat_template(messages, tokenize=False, add_generation_prompt=True)
&gt;&gt;&gt; inputs = processor(text=&#91;text&#93;, images=&#91;image&#93;, vision_infos=&#91;vision_infos&#93;)

&gt;&gt;&gt; # Generate
&gt;&gt;&gt; generate_ids = model.generate(inputs.input_ids, max_length=30)
&gt;&gt;&gt; tokenizer.batch_decode(generate_ids, skip_special_tokens=True, clean_up_tokenization_spaces=False)&#91;0&#93;
&quot;The image shows a street scene with a red stop sign in the foreground. In the background, there is a large red gate with Chinese characters ...&quot;
```&quot;&quot;&quot;

output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions
output_hidden_states = (output_hidden_states
                        if output_hidden_states is not None else self.config.output_hidden_states)
return_dict = return_dict if return_dict is not None else self.config.use_return_dict

if inputs_embeds is None:
    inputs_embeds = self.model.embed_tokens(input_ids)
    # This is a trick to handle TP for LLM but no TP for vision encoder, we need to convert DTensor to regular tensor later
    is_inputs_embeds_dtensor = isinstance(inputs_embeds, DTensor)  # This is True for TP&gt;1, False for TP=1
    if is_inputs_embeds_dtensor:
        target_device_mesh = inputs_embeds.device_mesh
        target_placements = inputs_embeds.placements
        inputs_embeds = inputs_embeds.full_tensor()

    if pixel_values is not None:
        pixel_values = pixel_values.type(self.visual.dtype)
        image_embeds = self.visual(pixel_values, grid_thw=image_grid_thw)
        n_image_tokens = (input_ids == self.config.image_token_id).sum().item()
        n_image_features = image_embeds.shape&#91;0&#93;
        if n_image_tokens != n_image_features:
            raise ValueError(
                f&quot;Image features and image tokens do not match: tokens: &#123;n_image_tokens&#125;, features &#123;n_image_features&#125;&quot;
            )

        mask = input_ids == self.config.image_token_id
        mask_unsqueezed = mask.unsqueeze(-1)
        mask_expanded = mask_unsqueezed.expand_as(inputs_embeds)
        image_mask = mask_expanded.to(inputs_embeds.device)

        image_embeds = image_embeds.to(inputs_embeds.device, inputs_embeds.dtype)
        inputs_embeds = inputs_embeds.masked_scatter(image_mask, image_embeds)

    if pixel_values_videos is not None:
        pixel_values_videos = pixel_values_videos.type(self.visual.dtype)
        video_embeds = self.visual(pixel_values_videos, grid_thw=video_grid_thw)
        n_video_tokens = (input_ids == self.config.video_token_id).sum().item()
        n_video_features = video_embeds.shape&#91;0&#93;
        if n_video_tokens != n_video_features:
            raise ValueError(
                f&quot;Video features and video tokens do not match: tokens: &#123;n_video_tokens&#125;, features &#123;n_video_features&#125;&quot;
            )

        mask = input_ids == self.config.video_token_id
        mask_unsqueezed = mask.unsqueeze(-1)
        mask_expanded = mask_unsqueezed.expand_as(inputs_embeds)
        video_mask = mask_expanded.to(inputs_embeds.device)

        video_embeds = video_embeds.to(inputs_embeds.device, inputs_embeds.dtype)
        inputs_embeds = inputs_embeds.masked_scatter(video_mask, video_embeds)
    if is_inputs_embeds_dtensor:
        inputs_embeds = (DTensor.from_local(
            inputs_embeds,
            device_mesh=target_device_mesh).redistribute(placements=target_placements).to_local())
    if attention_mask is not None:
        attention_mask = attention_mask.to(inputs_embeds.device)

# if we get 4D attention mask we cannot calculate rope deltas anymore.
if position_ids is None and (attention_mask is None or attention_mask.ndim == 2):
    # calculate RoPE index once per generation in the pre-fill stage only
    if ((cache_position is not None and cache_position&#91;0&#93; == 0) or self.rope_deltas is None
            or (past_key_values is None or past_key_values.get_seq_length() == 0)):
        position_ids, rope_deltas = self.get_rope_index(
            input_ids,
            image_grid_thw,
            video_grid_thw,
            second_per_grid_ts,
            attention_mask,
        )
        self.rope_deltas = rope_deltas
    # then use the prev pre-calculated rope-deltas to get the correct position ids
    else:
        batch_size, seq_length, _ = inputs_embeds.shape
        delta = ((cache_position&#91;0&#93; +
                  self.rope_deltas).to(inputs_embeds.device) if cache_position is not None else 0)
        position_ids = torch.arange(seq_length, device=inputs_embeds.device)
        position_ids = position_ids.view(1, -1).expand(batch_size, -1)
        if cache_position is not None:  # otherwise `deltas` is an int `0`
            delta = delta.repeat_interleave(batch_size // delta.shape&#91;0&#93;, dim=0)
        position_ids = position_ids.add(delta)
        position_ids = position_ids.unsqueeze(0).expand(3, -1, -1)

outputs = self.model(
    input_ids=None,
    position_ids=position_ids,
    attention_mask=attention_mask,
    past_key_values=past_key_values,
    inputs_embeds=inputs_embeds,
    use_cache=use_cache,
    output_attentions=output_attentions,
    output_hidden_states=output_hidden_states,
    return_dict=return_dict,
    cache_position=cache_position,
)

hidden_states = outputs&#91;0&#93;
logits = self.lm_head(hidden_states)

loss = None
if labels is not None:
    # Upcast to float if we need to compute the loss to avoid potential precision issues
    logits = logits.float()
    # Shift so that tokens &lt; n predict n
    shift_logits = logits&#91;..., :-1, :&#93;.contiguous()
    shift_labels = labels&#91;..., 1:&#93;.contiguous()
    # Flatten the tokens
    loss_fct = CrossEntropyLoss()
    shift_logits = shift_logits.view(-1, self.config.vocab_size)
    shift_labels = shift_labels.view(-1)
    # Enable model parallelism
    shift_labels = shift_labels.to(shift_logits.device)
    loss = loss_fct(shift_logits, shift_labels)

if not return_dict:
    output = (logits, )  # + outputs&#91;1:&#93;
    return (loss, ) + output if loss is not None else output

return Qwen2_5_VLCausalLMOutputWithPast(
    loss=loss,
    logits=logits,
    past_key_values=outputs.past_key_values,
    hidden_states=outputs.hidden_states,
    attentions=outputs.attentions,
    rope_deltas=self.rope_deltas,
)</code></pre></details>

fastvideo.models.encoders.qwen2_5_vl_custom.Qwen2_5_VLForConditionalGenerationSimple.prepare_inputs_for_generation

prepare_inputs_for_generation(input_ids, past_key_values = None, attention_mask = None, inputs_embeds = None, cache_position = None, position_ids = None, use_cache = True, pixel_values = None, pixel_values_videos = None, image_grid_thw = None, video_grid_thw = None, second_per_grid_ts = None, **kwargs)
Source
def prepare_inputs_for_generation(
    self,
    input_ids,
    past_key_values=None,
    attention_mask=None,
    inputs_embeds=None,
    cache_position=None,
    position_ids=None,
    use_cache=True,
    pixel_values=None,
    pixel_values_videos=None,
    image_grid_thw=None,
    video_grid_thw=None,
    second_per_grid_ts=None,
    **kwargs,
):
    # Overwritten -- in specific circumstances we don't want to forward image inputs to the model
# If we have cache: let&#x27;s slice `input_ids` through `cache_position`, to keep only the unprocessed tokens
# Exception 1: when passing input_embeds, input_ids may be missing entries
# Exception 2: some generation methods do special slicing of input_ids, so we don&#x27;t need to do it here
# Exception 3: with synced GPUs cache_position may go out of bounds, but we only want dummy token in that case.
#              (we can&#x27;t check exception 3 while compiling)
# Exception 4: If input_embeds are passed then slice it through `cache_position`, to keep only the unprocessed tokens and
# generate the first token for each sequence. Later use the generated Input ids for continuation.
if past_key_values is not None:
    if inputs_embeds is not None and input_ids.shape&#91;1&#93; == 0:  # Exception 4
        inputs_embeds = inputs_embeds&#91;:, -cache_position.shape&#91;0&#93;:&#93;
    elif inputs_embeds is not None or (  # Exception 1
            is_torchdynamo_compiling() or cache_position&#91;-1&#93; &gt;= input_ids.shape&#91;1&#93;):  # Exception 3
        input_ids = input_ids&#91;:, -cache_position.shape&#91;0&#93;:&#93;
    elif input_ids.shape&#91;1&#93; != cache_position.shape&#91;0&#93;:  # Default case (the &quot;else&quot;, a no op, is Exception 2)
        input_ids = input_ids&#91;:, cache_position&#93;

if cache_position&#91;0&#93; != 0:
    pixel_values = None
    pixel_values_videos = None

# if `inputs_embeds` are passed, we only want to use them in the 1st generation step
if inputs_embeds is not None and len(cache_position) == inputs_embeds.shape&#91;1&#93;:
    model_inputs = &#123;&quot;inputs_embeds&quot;: inputs_embeds, &quot;input_ids&quot;: None&#125;
else:
    model_inputs = &#123;&quot;input_ids&quot;: input_ids, &quot;inputs_embeds&quot;: None&#125;

if isinstance(past_key_values, StaticCache) and attention_mask.ndim == 2:
    if model_inputs&#91;&quot;inputs_embeds&quot;&#93; is not None:
        batch_size, sequence_length, _ = inputs_embeds.shape
        device = inputs_embeds.device
    else:
        batch_size, sequence_length = input_ids.shape
        device = input_ids.device

    attention_mask = self.model._prepare_4d_causal_attention_mask_with_cache_position(
        attention_mask,
        sequence_length=sequence_length,
        target_length=past_key_values.get_max_cache_shape(),
        dtype=self.lm_head.weight.dtype,
        device=device,
        cache_position=cache_position,
        batch_size=batch_size,
        config=self.config,
        past_key_values=past_key_values,
    )

model_inputs.update(&#123;
    &quot;position_ids&quot;: position_ids,
    &quot;past_key_values&quot;: past_key_values,
    &quot;use_cache&quot;: use_cache,
    &quot;attention_mask&quot;: attention_mask,
    &quot;pixel_values&quot;: pixel_values,
    &quot;pixel_values_videos&quot;: pixel_values_videos,
    &quot;image_grid_thw&quot;: image_grid_thw,
    &quot;video_grid_thw&quot;: video_grid_thw,
    &quot;cache_position&quot;: cache_position,
    &quot;second_per_grid_ts&quot;: second_per_grid_ts,
&#125;)
return model_inputs</code></pre></details>

fastvideo.models.encoders.qwen2_5_vl_custom.get_rope_index

get_rope_index(model_config, input_ids: Optional[torch.LongTensor] = None, image_grid_thw: Optional[torch.LongTensor] = None, video_grid_thw: Optional[torch.LongTensor] = None, second_per_grid_ts: Optional[torch.Tensor] = None, attention_mask: Optional[torch.Tensor] = None) -> Tuple[torch.Tensor, torch.Tensor]

Calculate the 3D rope index based on image and video's temporal, height and width in LLM.

Explanation

Each embedding sequence contains vision embedding and text embedding or just contains text embedding.

For pure text embedding sequence, the rotary position embedding has no difference with modern LLMs. Examples: input_ids: [T T T T T], here T is for text. temporal position_ids: [0, 1, 2, 3, 4] height position_ids: [0, 1, 2, 3, 4] width position_ids: [0, 1, 2, 3, 4]

For vision and text embedding sequence, we calculate 3D rotary position embedding for vision part and 1D rotary position embeddin for text part. Examples: Temporal (Time): 3 patches, representing different segments of the video in time. Height: 2 patches, dividing each frame vertically. Width: 2 patches, dividing each frame horizontally. We also have some important parameters: fps (Frames Per Second): The video's frame rate, set to 1. This means one frame is processed each second. tokens_per_second: This is a crucial parameter. It dictates how many "time-steps" or "temporal tokens" are conceptually packed into a one-second interval of the video. In this case, we have 25 tokens per second. So each second of the video will be represented with 25 separate time points. It essentially defines the temporal granularity. temporal_patch_size: The number of frames that compose one temporal patch. Here, it's 2 frames. interval: The step size for the temporal position IDs, calculated as tokens_per_second * temporal_patch_size / fps. In this case, 25 * 2 / 1 = 50. This means that each temporal patch will be have a difference of 50 in the temporal position IDs. input_ids: [V V V V V V V V V V V V T T T T T], here V is for vision. vision temporal position_ids: [0, 0, 0, 0, 50, 50, 50, 50, 100, 100, 100, 100] vision height position_ids: [0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1] vision width position_ids: [0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1] text temporal position_ids: [101, 102, 103, 104, 105] text height position_ids: [101, 102, 103, 104, 105] text width position_ids: [101, 102, 103, 104, 105] Here we calculate the text start position_ids as the max vision position_ids plus 1.

Parameters

input_ids: `torch.LongTensor` of shape `(batch_size, sequence_length)`

Indices of input sequence tokens in the vocabulary. Padding will be ignored by default should you provide it.

image_grid_thw: `torch.LongTensor` of shape `(num_images, 3)`, *optional*

The temporal, height and width of feature shape of each image in LLM.

video_grid_thw: `torch.LongTensor` of shape `(num_videos, 3)`, *optional*

The temporal, height and width of feature shape of each video in LLM.

second_per_grid_ts: `torch.Tensor` of shape `(num_videos)`, *optional*

The time interval (in seconds) for each grid along the temporal dimension in the 3D position IDs.

attention_mask: `torch.Tensor` of shape `(batch_size, sequence_length)`, *optional*

Mask to avoid performing attention on padding token indices. Mask values selected in [0, 1]:

  • 1 for tokens that are not masked,
  • 0 for tokens that are masked.

Returns

torch.Tensor

position_ids (torch.LongTensor of shape (3, batch_size, sequence_length))

torch.Tensor

mrope_position_deltas (torch.Tensor of shape (batch_size))

Source
def get_rope_index(
    model_config,
    input_ids: Optional[torch.LongTensor] = None,
    image_grid_thw: Optional[torch.LongTensor] = None,
    video_grid_thw: Optional[torch.LongTensor] = None,
    second_per_grid_ts: Optional[torch.Tensor] = None,
    attention_mask: Optional[torch.Tensor] = None,
) -> Tuple[torch.Tensor, torch.Tensor]:
    """
    Calculate the 3D rope index based on image and video's temporal, height and width in LLM.
Explanation:
    Each embedding sequence contains vision embedding and text embedding or just contains text embedding.

    For pure text embedding sequence, the rotary position embedding has no difference with modern LLMs.
    Examples:
        input_ids: &#91;T T T T T&#93;, here T is for text.
        temporal position_ids: &#91;0, 1, 2, 3, 4&#93;
        height position_ids: &#91;0, 1, 2, 3, 4&#93;
        width position_ids: &#91;0, 1, 2, 3, 4&#93;

    For vision and text embedding sequence, we calculate 3D rotary position embedding for vision part
    and 1D rotary position embeddin for text part.
    Examples:
        Temporal (Time): 3 patches, representing different segments of the video in time.
        Height: 2 patches, dividing each frame vertically.
        Width: 2 patches, dividing each frame horizontally.
        We also have some important parameters:
        fps (Frames Per Second): The video&#x27;s frame rate, set to 1. This means one frame is processed each second.
        tokens_per_second: This is a crucial parameter. It dictates how many &quot;time-steps&quot; or &quot;temporal tokens&quot; are conceptually packed into a one-second interval of the video. In this case, we have 25 tokens per second. So each second of the video will be represented with 25 separate time points. It essentially defines the temporal granularity.
        temporal_patch_size: The number of frames that compose one temporal patch. Here, it&#x27;s 2 frames.
        interval: The step size for the temporal position IDs, calculated as tokens_per_second * temporal_patch_size / fps. In this case, 25 * 2 / 1 = 50. This means that each temporal patch will be have a difference of 50 in the temporal position IDs.
        input_ids: &#91;V V V V V V V V V V V V T T T T T&#93;, here V is for vision.
        vision temporal position_ids: &#91;0, 0, 0, 0, 50, 50, 50, 50, 100, 100, 100, 100&#93;
        vision height position_ids: &#91;0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1&#93;
        vision width position_ids: &#91;0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1&#93;
        text temporal position_ids: &#91;101, 102, 103, 104, 105&#93;
        text height position_ids: &#91;101, 102, 103, 104, 105&#93;
        text width position_ids: &#91;101, 102, 103, 104, 105&#93;
        Here we calculate the text start position_ids as the max vision position_ids plus 1.

Args:
    input_ids (`torch.LongTensor` of shape `(batch_size, sequence_length)`):
        Indices of input sequence tokens in the vocabulary. Padding will be ignored by default should you provide
        it.
    image_grid_thw (`torch.LongTensor` of shape `(num_images, 3)`, *optional*):
        The temporal, height and width of feature shape of each image in LLM.
    video_grid_thw (`torch.LongTensor` of shape `(num_videos, 3)`, *optional*):
        The temporal, height and width of feature shape of each video in LLM.
    second_per_grid_ts (`torch.Tensor` of shape `(num_videos)`, *optional*):
        The time interval (in seconds) for each grid along the temporal dimension in the 3D position IDs.
    attention_mask (`torch.Tensor` of shape `(batch_size, sequence_length)`, *optional*):
        Mask to avoid performing attention on padding token indices. Mask values selected in `&#91;0, 1&#93;`:

        - 1 for tokens that are **not masked**,
        - 0 for tokens that are **masked**.

Returns:
    position_ids (`torch.LongTensor` of shape `(3, batch_size, sequence_length)`)
    mrope_position_deltas (`torch.Tensor` of shape `(batch_size)`)
&quot;&quot;&quot;
spatial_merge_size = model_config.vision_config.spatial_merge_size
image_token_id = model_config.image_token_id
video_token_id = model_config.video_token_id
vision_start_token_id = model_config.vision_start_token_id
mrope_position_deltas = &#91;&#93;
if input_ids is not None and (image_grid_thw is not None or video_grid_thw is not None):
    total_input_ids = input_ids
    if attention_mask is None:
        attention_mask = torch.ones_like(total_input_ids)
    position_ids = torch.ones(
        3,
        input_ids.shape&#91;0&#93;,
        input_ids.shape&#91;1&#93;,
        dtype=input_ids.dtype,
        device=input_ids.device,
    )
    image_index, video_index = 0, 0
    attention_mask = attention_mask.to(total_input_ids.device)
    for i, input_ids in enumerate(total_input_ids):
        input_ids = input_ids&#91;attention_mask&#91;i&#93; == 1&#93;
        image_nums, video_nums = 0, 0
        vision_start_indices = torch.argwhere(input_ids == vision_start_token_id).squeeze(1)
        vision_tokens = input_ids&#91;vision_start_indices + 1&#93;
        image_nums = (vision_tokens == image_token_id).sum()
        video_nums = (vision_tokens == video_token_id).sum()
        input_tokens = input_ids.tolist()
        llm_pos_ids_list: list = &#91;&#93;
        st = 0
        remain_images, remain_videos = image_nums, video_nums
        for _ in range(image_nums + video_nums):
            if image_token_id in input_tokens and remain_images &gt; 0:
                ed_image = input_tokens.index(image_token_id, st)
            else:
                ed_image = len(input_tokens) + 1
            if video_token_id in input_tokens and remain_videos &gt; 0:
                ed_video = input_tokens.index(video_token_id, st)
            else:
                ed_video = len(input_tokens) + 1
            if ed_image &lt; ed_video:
                t, h, w = (
                    image_grid_thw&#91;image_index&#93;&#91;0&#93;,
                    image_grid_thw&#91;image_index&#93;&#91;1&#93;,
                    image_grid_thw&#91;image_index&#93;&#91;2&#93;,
                )
                second_per_grid_t = 0
                image_index += 1
                remain_images -= 1
                ed = ed_image

            else:
                t, h, w = (
                    video_grid_thw&#91;video_index&#93;&#91;0&#93;,
                    video_grid_thw&#91;video_index&#93;&#91;1&#93;,
                    video_grid_thw&#91;video_index&#93;&#91;2&#93;,
                )
                second_per_grid_t = second_per_grid_ts&#91;video_index&#93; if second_per_grid_ts is not None else 1.0
                video_index += 1
                remain_videos -= 1
                ed = ed_video
            llm_grid_t, llm_grid_h, llm_grid_w = (
                t.item(),
                h.item() // spatial_merge_size,
                w.item() // spatial_merge_size,
            )
            text_len = ed - st

            st_idx = llm_pos_ids_list&#91;-1&#93;.max() + 1 if len(llm_pos_ids_list) &gt; 0 else 0
            llm_pos_ids_list.append(
                torch.arange(text_len, device=input_ids.device).view(1, -1).expand(3, -1) + st_idx)

            range_tensor = torch.arange(llm_grid_t, device=input_ids.device).view(-1, 1)
            expanded_range = range_tensor.expand(-1, llm_grid_h * llm_grid_w)

            time_tensor = expanded_range * second_per_grid_t * model_config.vision_config.tokens_per_second

            time_tensor_long = time_tensor.long()
            t_index = time_tensor_long.flatten()

            h_index = (torch.arange(llm_grid_h, device=input_ids.device).view(1, -1,
                                                                              1).expand(llm_grid_t, -1,
                                                                                        llm_grid_w).flatten())
            w_index = (torch.arange(llm_grid_w,
                                    device=input_ids.device).view(1, 1, -1).expand(llm_grid_t, llm_grid_h,
                                                                                   -1).flatten())
            llm_pos_ids_list.append(torch.stack(&#91;t_index, h_index, w_index&#93;) + text_len + st_idx)
            st = ed + llm_grid_t * llm_grid_h * llm_grid_w

        if st &lt; len(input_tokens):
            st_idx = llm_pos_ids_list&#91;-1&#93;.max() + 1 if len(llm_pos_ids_list) &gt; 0 else 0
            text_len = len(input_tokens) - st
            llm_pos_ids_list.append(
                torch.arange(text_len, device=input_ids.device).view(1, -1).expand(3, -1) + st_idx)

        llm_positions = torch.cat(llm_pos_ids_list, dim=1).reshape(3, -1)
        position_ids&#91;..., i, attention_mask&#91;i&#93; == 1&#93; = llm_positions.to(position_ids.device)
        mrope_position_deltas.append(llm_positions.max() + 1 - len(total_input_ids&#91;i&#93;))
    mrope_position_deltas = torch.tensor(mrope_position_deltas, device=input_ids.device).unsqueeze(1)
    return position_ids, mrope_position_deltas
else:
    if attention_mask is not None:
        position_ids = attention_mask.long().cumsum(-1) - 1
        position_ids.masked_fill_(attention_mask == 0, 1)
        position_ids = position_ids.unsqueeze(0).expand(3, -1, -1).to(attention_mask.device)
        max_position_ids = position_ids.max(0, keepdim=False)&#91;0&#93;.max(-1, keepdim=True)&#91;0&#93;
        mrope_position_deltas = max_position_ids + 1 - attention_mask.shape&#91;-1&#93;
    else:
        position_ids = (torch.arange(input_ids.shape&#91;1&#93;,
                                     device=input_ids.device).view(1, 1, -1).expand(3, input_ids.shape&#91;0&#93;, -1))
        mrope_position_deltas = torch.zeros(
            &#91;input_ids.shape&#91;0&#93;, 1&#93;,
            device=input_ids.device,
            dtype=input_ids.dtype,
        )

    return position_ids, mrope_position_deltas</code></pre></details>

Was this page helpful?