Felipe97/llama-cpp-compiled
01.1k
1from __future__ import annotations2 3from typing import Callable, Iterable, TYPE_CHECKING4 5if TYPE_CHECKING:6 from torch import Tensor7 8from .base import MmprojModel, ModelBase, gguf9 10from .llama import LlamaModel11 12 13@ModelBase.register("JanusForConditionalGeneration")14@ModelBase.example("deepseek-community/Janus-Pro-1B")15class JanusProModel(LlamaModel):16 model_arch = gguf.MODEL_ARCH.LLAMA # reuse Llama arch17 18 @classmethod19 def filter_tensors(cls, item: tuple[str, Callable[[], Tensor]]) -> tuple[str, Callable[[], Tensor]] | None:20 name, gen = item21 22 # Skip vision, aligner, and generation tensors23 skip_prefixes = (24 'model.vision_model.',25 'model.aligner.',26 'model.vqmodel.',27 'model.generation_embeddings.',28 'model.generation_aligner.',29 'model.generation_head.',30 )31 if name.startswith(skip_prefixes):32 return None33 34 return super().filter_tensors(item)35 36 37@ModelBase.register("JanusForConditionalGeneration")38@ModelBase.example("deepseek-community/Janus-Pro-1B")39class JanusProVisionModel(MmprojModel):40 def __init__(self, *args, **kwargs):41 super().__init__(*args, **kwargs)42 assert self.hparams_vision is not None43 if "intermediate_size" not in self.hparams_vision:44 mlp_ratio = self.hparams_vision.get("mlp_ratio")45 hidden_size = self.hparams_vision.get("hidden_size")46 if mlp_ratio is not None and hidden_size is not None:47 self.hparams_vision["intermediate_size"] = int(round(hidden_size * mlp_ratio))48 49 def set_gguf_parameters(self):50 super().set_gguf_parameters()51 assert self.hparams_vision is not None52 53 self.gguf_writer.add_clip_projector_type(gguf.VisionProjectorType.JANUS_PRO)54 55 self.gguf_writer.add_vision_attention_layernorm_eps(self.hparams_vision.get("layer_norm_eps", 1e-6))56 57 hidden_act = str(self.hparams_vision.get("hidden_act", "")).lower()58 if hidden_act == "gelu":59 self.gguf_writer.add_vision_use_gelu(True)60 elif hidden_act == "silu":61 self.gguf_writer.add_vision_use_silu(True)62 63 def _map_aligner_tensor(self, data_torch: Tensor, name: str) -> Iterable[tuple[str, Tensor]]:64 """Map aligner tensors to projector format"""65 suffix = ".bias" if name.endswith(".bias") else ".weight"66 67 if name.startswith("model.aligner."):68 local_name = name[len("model.aligner."):]69 elif name.startswith("aligner."):70 local_name = name[len("aligner."):]71 else:72 raise ValueError(f"Unsupported Janus aligner prefix: {name}")73 74 if local_name.startswith("fc1."):75 mm_index = 076 elif local_name.startswith("hidden_layers."):77 parts = local_name.split(".", 2)78 if len(parts) < 3:79 raise ValueError(f"Unexpected Janus aligner tensor name: {name}")80 mm_index = int(parts[1]) + 181 else:82 raise ValueError(f"Unsupported Janus aligner tensor: {name}")83 84 tensor_name = self.format_tensor_name(gguf.MODEL_TENSOR.V_MMPROJ, mm_index, suffix=suffix)85 return [(tensor_name, data_torch)]86 87 @classmethod88 def filter_tensors(cls, item: tuple[str, Callable[[], Tensor]]) -> tuple[str, Callable[[], Tensor]] | None:89 name, gen = item90 91 # Skip generation-related components92 skip_generation_prefixes = (93 'model.vqmodel.',94 'vqmodel.',95 'model.generation_embeddings.',96 'generation_embeddings.',97 'model.generation_aligner.',98 'generation_aligner.',99 'model.generation_head.',100 'generation_head.',101 )102 if name.startswith(skip_generation_prefixes):103 return None104 105 return super().filter_tensors(item)106 107 def modify_tensors(self, data_torch: Tensor, name: str, bid: int | None) -> Iterable[tuple[str, Tensor]]:108 # Handle aligner tensors109 if name.startswith(('model.aligner.', 'aligner.')):110 yield from self._map_aligner_tensor(data_torch, name)111 return112 113 # Handle vision tensors114 if name.startswith(('model.vision_model.', 'vision_model.')):115 yield from super().modify_tensors(data_torch, name, bid)116 return117 118 return119 