char-fork/llama.cpp
git clone https://git.t4t.associates/char-fork/llama.cpp
fa88ae936
char/aliceai-t5-moe
1from __future__import annotations 2 3from typing import Any ,Callable ,Iterable ,TYPE_CHECKING 4 5import numpy as np 6import torch 7 8if TYPE_CHECKING : 9from torch import Tensor 10 11from .base import MmprojModel ,ModelBase ,TextModel ,gguf 12 13 14@ ModelBase . register ( 15"Qwen2VLModel" , 16"Qwen2VLForConditionalGeneration" , 17"Qwen2_5_VLForConditionalGeneration" , 18"Qwen2_5OmniModel" , 19) 20@ ModelBase . example ( "Qwen/Qwen2-VL-2B-Instruct" , "Qwen/Qwen2.5-VL-3B-Instruct" ) 21class Qwen2VLModel (TextModel ): 22model_arch = gguf .MODEL_ARCH .QWEN2VL 23 24def set_gguf_parameters (self ): 25super ().set_gguf_parameters () 26 27def set_vocab (self ): 28try : 29self ._set_vocab_sentencepiece () 30except FileNotFoundError : 31self ._set_vocab_gpt2 () 32 33@classmethod 34def filter_tensors (cls ,item :tuple [str ,Callable [[],Tensor ]])-> tuple [str ,Callable [[],Tensor ]]| None : 35name ,gen = item 36 37if name .startswith ("thinker." ): 38name = name .replace ("thinker." ,"" ) 39 40return super ().filter_tensors ((name ,gen )) 41 42 43@ ModelBase . register ( "Qwen2VLModel" , "Qwen2VLForConditionalGeneration" , "Qwen2_5_VLForConditionalGeneration" ) 44@ ModelBase . example ( "Qwen/Qwen2-VL-2B-Instruct" , "Qwen/Qwen2.5-VL-3B-Instruct" ) 45class Qwen2VLVisionModel (MmprojModel ): 46def __init__ (self ,* args ,** kwargs ): 47super ().__init__ (* args ,** kwargs ) 48assert self .hparams_vision is not None 49self .hparams_vision ["image_size" ]= self .hparams_vision .get ("image_size" ,560 ) 50# rename config.json values 51self .hparams_vision ["num_attention_heads" ]= self .hparams_vision .get ("num_heads" ) 52self .hparams_vision ["num_hidden_layers" ]= self .hparams_vision .get ("depth" ) 53if "embed_dim" in self .hparams_vision :# qwen2vl 54self .hparams_vision ["intermediate_size" ]= self .hparams_vision .get ("hidden_size" ) 55self .hparams_vision ["hidden_size" ]= self .hparams_vision .get ("embed_dim" ) 56 57def set_gguf_parameters (self ): 58super ().set_gguf_parameters () 59assert self .hparams_vision is not None 60hparams = self .hparams_vision 61model_type = self .global_config ['model_type' ] 62if model_type == 'qwen2_vl' : 63self .gguf_writer .add_clip_projector_type (gguf .VisionProjectorType .QWEN2VL ) 64elif model_type == 'qwen2_5_vl' or model_type == 'qwen2_5_omni' : 65if model_type == 'qwen2_5_omni' : 66self .gguf_writer .add_clip_projector_type (gguf .VisionProjectorType .QWEN25O ) 67else : 68self .gguf_writer .add_clip_projector_type (gguf .VisionProjectorType .QWEN25VL ) 69self .gguf_writer .add_vision_use_silu (True ) 70# find n_wa_pattern (window attention pattern) 71fullatt_block_indexes = hparams .get ("fullatt_block_indexes" ) 72assert fullatt_block_indexes is not None ,"fullatt_block_indexes is required for qwen2_5_vl" 73n_wa_pattern = fullatt_block_indexes [0 ]+ 1 74# validate n_wa_pattern 75for i in range (1 ,len (fullatt_block_indexes )): 76if fullatt_block_indexes [i ]- fullatt_block_indexes [i - 1 ]!= n_wa_pattern : 77raise ValueError (f"Invalid fullatt_block_indexes: { fullatt_block_indexes } " ) 78self .gguf_writer .add_vision_n_wa_pattern (n_wa_pattern ) 79else : 80raise ValueError (f"Unknown QwenVL model type: { self . global_config [ 'model_type' ] } " ) 81# default values below are taken from HF tranformers code 82self .gguf_writer .add_vision_attention_layernorm_eps (self .global_config .get ("rms_norm_eps" ,1e-6 )) 83 84def tensor_force_quant (self ,name ,new_name ,bid ,n_dims ): 85if ".position_embd." in new_name : 86return gguf .GGMLQuantizationType .F32 87return super ().tensor_force_quant (name ,new_name ,bid ,n_dims ) 88 89@classmethod 90def filter_tensors (cls ,item :tuple [str ,Callable [[],Tensor ]])-> tuple [str ,Callable [[],Tensor ]]| None : 91name ,gen = item 92 93if not name .startswith ("visual." ): 94return None 95 96return super ().filter_tensors (item ) 97 98def modify_tensors (self ,data_torch :Tensor ,name :str ,bid :int | None )-> Iterable [tuple [str ,Tensor ]]: 99# split QKV tensors if needed 100if ".qkv." in name : 101if data_torch .ndim == 2 :# weight 102c3 ,_ = data_torch .shape 103else :# bias 104c3 = data_torch .shape [0 ] 105assert c3 % 3 == 0 106c = c3 // 3 107wq = data_torch [:c ] 108wk = data_torch [c :c * 2 ] 109wv = data_torch [c * 2 :] 110yield from super ().modify_tensors (wq ,name .replace ("qkv" ,"q" ),bid ) 111yield from super ().modify_tensors (wk ,name .replace ("qkv" ,"k" ),bid ) 112yield from super ().modify_tensors (wv ,name .replace ("qkv" ,"v" ),bid ) 113elif 'patch_embed.proj.weight' in name : 114# split Conv3D into Conv2Ds 115c1 ,c2 ,kt ,kh ,kw = data_torch .shape 116del c1 ,c2 ,kh ,kw # unused 117assert kt == 2 ,"Current implementation only support temporal_patch_size of 2" 118yield (gguf .TENSOR_NAMES [gguf .MODEL_TENSOR .V_ENC_EMBD_PATCH ]+ ".weight" ,data_torch [:, :,0 , ...]) 119yield (gguf .TENSOR_NAMES [gguf .MODEL_TENSOR .V_ENC_EMBD_PATCH ]+ ".weight.1" ,data_torch [:, :,1 , ...]) 120else : 121yield from super ().modify_tensors (data_torch ,name ,bid ) 122 123 124class Qwen25AudioModel (MmprojModel ): 125has_audio_encoder = True 126 127def __init__ (self ,* args ,** kwargs ): 128super ().__init__ (* args ,** kwargs ) 129assert self .hparams_audio is not None 130self .hparams_audio ["hidden_size" ]= self .hparams_audio ["d_model" ] 131self .hparams_audio ["intermediate_size" ]= self .hparams_audio ["encoder_ffn_dim" ] 132self .hparams_audio ["num_attention_heads" ]= self .hparams_audio ["encoder_attention_heads" ] 133 134def set_gguf_parameters (self ): 135super ().set_gguf_parameters () 136assert self .hparams_audio is not None 137self .gguf_writer .add_audio_num_mel_bins (self .hparams_audio ["num_mel_bins" ]) 138self .gguf_writer .add_audio_attention_layernorm_eps (self .hparams_audio .get ("layer_norm_eps" ,1e-5 )) 139 140def generate_extra_tensors (self )-> Iterable [tuple [str ,Tensor ]]: 141# SinusoidsPositionEmbedding 142assert self .hparams_audio is not None 143max_timescale = 10000 144length = 1500 145channels = self .hparams_audio ["hidden_size" ] 146log_timescale_increment = np .log (max_timescale )/ (channels // 2 - 1 ) 147inv_timescales = torch .exp (- log_timescale_increment * torch .arange (channels // 2 ).float ()) 148scaled_time = torch .arange (length )[:,np .newaxis ]* inv_timescales [np .newaxis , :] 149pos_embd = torch .cat ([torch .sin (scaled_time ),torch .cos (scaled_time )],dim = 1 ).to (dtype = torch .float32 ) 150yield ("audio_tower.embed_positions.weight" ,pos_embd ) 151 152def tensor_force_quant (self ,name ,new_name ,bid ,n_dims ): 153if ".conv" in name and ".weight" in name : 154return gguf .GGMLQuantizationType .F16 155return super ().tensor_force_quant (name ,new_name ,bid ,n_dims ) 156 157def modify_tensors (self ,data_torch :Tensor ,name :str ,bid :int | None )-> Iterable [tuple [str ,Tensor ]]: 158if "conv1.bias" in name or "conv2.bias" in name : 159# transpose conv1 and conv2 bias 160data_torch = data_torch .unsqueeze (- 1 ) 161 162yield from MmprojModel .modify_tensors (self ,data_torch ,name ,bid ) 163 164 165@ ModelBase . register ( "Qwen2_5OmniModel" ) 166@ ModelBase . example ( "Qwen/Qwen2.5-Omni-3B" ) 167class Qwen25OmniModel (Qwen2VLVisionModel ,Qwen25AudioModel ): 168has_audio_encoder = True 169has_vision_encoder = True 170 171def get_vision_config (self )-> dict [str ,Any ]| None : 172return self .global_config ["thinker_config" ].get ("vision_config" ) 173 174def get_audio_config (self )-> dict [str ,Any ]| None : 175return self .global_config ["thinker_config" ].get ("audio_config" ) 176 177def set_gguf_parameters (self ): 178super ().set_gguf_parameters () 179self .gguf_writer .add_clip_projector_type (gguf .VisionProjectorType .QWEN25O ) 180 181@classmethod 182def filter_tensors (cls ,item :tuple [str ,Callable [[],Tensor ]])-> tuple [str ,Callable [[],Tensor ]]| None : 183name ,gen = item 184 185if name .startswith ("thinker." ): 186name = name .replace ("thinker." ,"" ) 187 188if not name .startswith ("visual." )and not name .startswith ("audio_tower." ): 189return None 190 191if "audio_bos_eos_token" in name : 192# this tensor is left unused in transformers code 193# https://github.com/huggingface/transformers/blob/6e3063422c4b1c014aa60c32b9254fd2902f0f28/src/transformers/models/qwen2_5_omni/modular_qwen2_5_omni.py#L1809 194return None 195 196return MmprojModel .filter_tensors ((name ,gen )) 197 198def modify_tensors (self ,data_torch :Tensor ,name :str ,bid :int | None )-> Iterable [tuple [str ,Tensor ]]: 199if "visual." in name : 200yield from Qwen2VLVisionModel .modify_tensors (self ,data_torch ,name ,bid ) 201elif "audio_tower." in name : 202yield from Qwen25AudioModel .modify_tensors (self ,data_torch ,name ,bid ) 203return # skip other tensors