[VLM] Support cos sin cache for Ernie4.5-VL (#19743)

Co-authored-by: luoyuan.luo <luoyuan.luo@antgroup.com>
This commit is contained in:
Yuan Luo
2026-03-04 10:54:23 +08:00
committed by GitHub
co-authored by luoyuan.luo
parent 525d046990
commit 82e7139c06
+34 -12
View File
@@ -30,6 +30,7 @@ from sglang.srt.layers.linear import ColumnParallelLinear, RowParallelLinear
from sglang.srt.layers.logits_processor import LogitsProcessor from sglang.srt.layers.logits_processor import LogitsProcessor
from sglang.srt.layers.moe.fused_moe_triton.layer import FusedMoE from sglang.srt.layers.moe.fused_moe_triton.layer import FusedMoE
from sglang.srt.layers.quantization.base_config import QuantizationConfig from sglang.srt.layers.quantization.base_config import QuantizationConfig
from sglang.srt.layers.rotary_embedding import get_rope
from sglang.srt.layers.vocab_parallel_embedding import ParallelLMHead from sglang.srt.layers.vocab_parallel_embedding import ParallelLMHead
from sglang.srt.managers.mm_utils import ( from sglang.srt.managers.mm_utils import (
MultiModalityDataPaddingPatternMultimodalTokens, MultiModalityDataPaddingPatternMultimodalTokens,
@@ -120,14 +121,16 @@ class Ernie4_5_VisionBlock(nn.Module):
self, self,
x: torch.Tensor, x: torch.Tensor,
cu_seqlens: torch.Tensor, cu_seqlens: torch.Tensor,
position_embeddings: torch.Tensor, rotary_pos_emb_cos: torch.Tensor,
rotary_pos_emb_sin: torch.Tensor,
) -> torch.Tensor: ) -> torch.Tensor:
hidden_states = self.norm1(x) hidden_states = self.norm1(x)
hidden_states = rearrange(hidden_states, "s b ... -> b s ...") hidden_states = rearrange(hidden_states, "s b ... -> b s ...")
attn = self.attn( attn = self.attn(
hidden_states, hidden_states,
cu_seqlens=cu_seqlens, cu_seqlens=cu_seqlens,
position_embeddings=position_embeddings, rotary_pos_emb_cos=rotary_pos_emb_cos,
rotary_pos_emb_sin=rotary_pos_emb_sin,
) )
attn = rearrange(attn, "b s ... -> s b ...") attn = rearrange(attn, "b s ... -> s b ...")
x = x + attn x = x + attn
@@ -388,7 +391,13 @@ class Ernie4_5_VisionTransformer(nn.Module):
norm_layer = partial(nn.LayerNorm, eps=norm_eps) norm_layer = partial(nn.LayerNorm, eps=norm_eps)
head_dim = embed_dim // num_heads head_dim = embed_dim // num_heads
self.rotary_pos_emb = Ernie4_5_VisionRotaryEmbedding(head_dim // 2) self.rotary_pos_emb = get_rope(
head_size=head_dim,
rotary_dim=head_dim // 2,
max_position=8192,
base=10000.0,
is_neox_style=True,
)
self.blocks = nn.ModuleList( self.blocks = nn.ModuleList(
[ [
Ernie4_5_VisionBlock( Ernie4_5_VisionBlock(
@@ -413,7 +422,9 @@ class Ernie4_5_VisionTransformer(nn.Module):
def device(self) -> torch.device: def device(self) -> torch.device:
return self.blocks[0].mlp.fc2.weight.device return self.blocks[0].mlp.fc2.weight.device
def rot_pos_emb(self, grid_thw: torch.Tensor) -> torch.Tensor: def rot_pos_emb(
self, grid_thw: torch.Tensor
) -> tuple[torch.Tensor, torch.Tensor, torch.Tensor]:
pos_ids = [] pos_ids = []
for i in range(grid_thw.size(0)): for i in range(grid_thw.size(0)):
t, h, w = grid_thw[i].tolist() t, h, w = grid_thw[i].tolist()
@@ -440,11 +451,15 @@ class Ernie4_5_VisionTransformer(nn.Module):
.flatten() .flatten()
) )
pos_ids.append(torch.stack([hpos_ids, wpos_ids], dim=-1).repeat(t, 1)) pos_ids.append(torch.stack([hpos_ids, wpos_ids], dim=-1).repeat(t, 1))
pos_ids = torch.cat(pos_ids, dim=0) pos_ids = torch.cat(pos_ids, dim=0).to(self.device, non_blocking=True)
max_grid_size = grid_thw[:, 1:].max() max_grid_size = grid_thw[:, 1:].max()
rotary_pos_emb_full = self.rotary_pos_emb(max_grid_size)
rotary_pos_emb = rotary_pos_emb_full[pos_ids].flatten(1) # Use pre-computed cos_sin_cache from RotaryEmbedding
return rotary_pos_emb cos, sin = self.rotary_pos_emb.get_cos_sin(max_grid_size)
cos_combined = cos[pos_ids].flatten(1)
sin_combined = sin[pos_ids].flatten(1)
return cos_combined, sin_combined, pos_ids
def forward( def forward(
self, self,
@@ -456,9 +471,11 @@ class Ernie4_5_VisionTransformer(nn.Module):
x = self.patch_embed(x) x = self.patch_embed(x)
# compute position embedding # compute position embedding
rotary_pos_emb = self.rot_pos_emb(grid_thw) rotary_pos_emb_cos, rotary_pos_emb_sin, image_type_ids = self.rot_pos_emb(
emb = torch.cat((rotary_pos_emb, rotary_pos_emb), dim=-1) grid_thw
position_embeddings = (emb.cos(), emb.sin()) )
rotary_pos_emb_cos = torch.cat([rotary_pos_emb_cos, rotary_pos_emb_cos], dim=-1)
rotary_pos_emb_sin = torch.cat([rotary_pos_emb_sin, rotary_pos_emb_sin], dim=-1)
# compute cu_seqlens # compute cu_seqlens
cu_seqlens = torch.repeat_interleave( cu_seqlens = torch.repeat_interleave(
grid_thw[:, 1] * grid_thw[:, 2], grid_thw[:, 0] grid_thw[:, 1] * grid_thw[:, 2], grid_thw[:, 0]
@@ -468,7 +485,12 @@ class Ernie4_5_VisionTransformer(nn.Module):
# transformers # transformers
x = x.unsqueeze(1) x = x.unsqueeze(1)
for blk in self.blocks: for blk in self.blocks:
x = blk(x, cu_seqlens=cu_seqlens, position_embeddings=position_embeddings) x = blk(
x,
cu_seqlens=cu_seqlens,
rotary_pos_emb_cos=rotary_pos_emb_cos,
rotary_pos_emb_sin=rotary_pos_emb_sin,
)
final_output = self.ln(x) final_output = self.ln(x)