leideng/QCFuse / srt /models /points_v15_chat.py
leideng's picture
download
raw
6.42 kB
import copy
from typing import Iterable, List, Optional, Set, Tuple
import torch
import torch.nn.functional as F
from torch import nn
from sglang.srt.configs.points_v15_chat import POINTSV15ChatConfig
from sglang.srt.layers.quantization.base_config import QuantizationConfig
from sglang.srt.managers.mm_utils import (
MultiModalityDataPaddingPatternMultimodalTokens,
general_mm_embed_routine,
)
from sglang.srt.managers.schedule_batch import (
Modality,
MultimodalDataItem,
MultimodalInputs,
)
from sglang.srt.model_executor.forward_batch_info import ForwardBatch
from sglang.srt.model_loader.weight_utils import default_weight_loader
from sglang.srt.models.qwen2 import Qwen2ForCausalLM
from sglang.srt.models.qwen2_vl import Qwen2VisionPatchMerger, Qwen2VisionTransformer
from sglang.srt.utils import add_prefix
class Qwen2VisionTransformerForNavitPOINTS(Qwen2VisionTransformer):
def __init__(
self,
vision_config: POINTSV15ChatConfig,
norm_eps: float = 1e-6,
quant_config: Optional[QuantizationConfig] = None,
prefix: str = "",
) -> None:
super().__init__(
vision_config,
norm_eps=norm_eps,
quant_config=quant_config,
prefix=prefix,
)
def forward(
self,
x: torch.Tensor,
grid_thw: torch.Tensor,
) -> torch.Tensor:
# patchify
x = x.to(device=self.device, dtype=self.dtype)
x = self.patch_embed(x)
# compute position embedding
rotary_pos_emb = self.rot_pos_emb(grid_thw)
emb = torch.cat((rotary_pos_emb, rotary_pos_emb), dim=-1)
position_embeddings = (emb.cos(), emb.sin())
# compute cu_seqlens
cu_seqlens = torch.repeat_interleave(
grid_thw[:, 1] * grid_thw[:, 2], grid_thw[:, 0]
).cumsum(dim=0, dtype=torch.int32)
cu_seqlens = F.pad(cu_seqlens, (1, 0), "constant", 0)
# transformers
x = x.unsqueeze(1)
for blk in self.blocks:
x = blk(x, cu_seqlens=cu_seqlens, position_embeddings=position_embeddings)
return x
class POINTSV15ChatModel(nn.Module):
def __init__(
self,
config: POINTSV15ChatConfig,
quant_config: Optional[QuantizationConfig] = None,
prefix: str = "",
**kwargs,
) -> None:
super().__init__()
config.llm_config._attn_implementation = "flash_attention_2"
config._attn_implementation_autoset = False
self.config = config
self.quant_config = quant_config
llm_config = copy.deepcopy(config.llm_config)
llm_config.architectures = ["Qwen2ForCausalLM"]
self.llm = Qwen2ForCausalLM(
config=llm_config,
quant_config=quant_config,
prefix=add_prefix("llm", prefix),
)
self.vision_encoder = Qwen2VisionTransformerForNavitPOINTS(
config.vision_config,
quant_config=quant_config,
prefix=add_prefix("vision_encoder", prefix),
)
self.vision_projector = Qwen2VisionPatchMerger(
d_model=config.llm_config.hidden_size,
context_dim=1280,
quant_config=quant_config,
prefix=add_prefix("vision_projector", prefix),
)
def pad_input_ids(self, input_ids: List[int], mm_inputs: MultimodalInputs):
pattern = MultiModalityDataPaddingPatternMultimodalTokens()
return pattern.pad_input_tokens(input_ids, mm_inputs)
def get_image_feature(self, items: List[MultimodalDataItem]) -> torch.Tensor:
pixel_values = torch.cat([item.feature for item in items], dim=0).type(
self.vision_encoder.dtype
)
image_grid_thw = torch.concat([item.image_grid_thw for item in items], dim=0)
assert pixel_values.dim() == 2, pixel_values.dim()
assert image_grid_thw.dim() == 2, image_grid_thw.dim()
image_features = self.vision_encoder(pixel_values, grid_thw=image_grid_thw)
image_features = self.vision_projector(image_features)
return image_features
def forward(
self,
input_ids: torch.Tensor,
positions: torch.Tensor,
forward_batch: ForwardBatch,
get_embedding: bool = False,
):
hidden_states = general_mm_embed_routine(
input_ids=input_ids,
forward_batch=forward_batch,
language_model=self.llm,
data_embedding_funcs={
Modality.IMAGE: self.get_image_feature,
},
positions=positions,
)
return hidden_states
def load_weights(self, weights: Iterable[Tuple[str, torch.Tensor]]):
stacked_params_mapping = [
# (param_name, shard_name, shard_id)
("qkv_proj", "q_proj", "q"),
("qkv_proj", "k_proj", "k"),
("qkv_proj", "v_proj", "v"),
("gate_up_proj", "gate_proj", 0),
("gate_up_proj", "up_proj", 1),
]
params_dict = dict(self.named_parameters())
loaded_params: Set[str] = set()
for name, loaded_weight in weights:
if "rotary_emb.inv_freq" in name:
continue
for param_name, weight_name, shard_id in stacked_params_mapping:
if weight_name not in name:
continue
name = name.replace(weight_name, param_name)
if name.endswith(".bias") and name not in params_dict:
continue
param = params_dict[name]
weight_loader = param.weight_loader
weight_loader(param, loaded_weight, shard_id)
break
else:
if "vision_encoder" in name:
# adapt to VisionAttention
name = name.replace(r"attn.qkv.", r"attn.qkv_proj.")
try:
# Skip loading extra bias for GPTQ models.
if name.endswith(".bias") and name not in params_dict:
continue
param = params_dict[name]
except KeyError:
print(params_dict.keys())
raise
weight_loader = getattr(param, "weight_loader", default_weight_loader)
weight_loader(param, loaded_weight)
EntryClass = [POINTSV15ChatModel]

Xet Storage Details

Size:
6.42 kB
·
Xet hash:
bd7e404764de7c8b4885fb3147015565bfbe931ae7641940462db89da2de8a52

Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.