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 Iterable ,TYPE_CHECKING 4 5import torch 6 7if TYPE_CHECKING : 8from torch import Tensor 9 10from .base import ModelBase ,TextModel ,gguf ,logger 11 12 13@ ModelBase . register ( "SmallThinkerForCausalLM" ) 14@ ModelBase . example ( "PowerInfer/SmallThinker-4BA0.6B-Instruct" ) 15class SmallThinkerModel (TextModel ): 16model_arch = gguf .MODEL_ARCH .SMALLTHINKER 17 18def set_gguf_parameters (self ): 19super ().set_gguf_parameters () 20if (n_experts := self .hparams .get ("moe_num_primary_experts" ))is not None : 21self .gguf_writer .add_expert_count (n_experts ) 22if (n_experts_used := self .hparams .get ("moe_num_active_primary_experts" ))is not None : 23self .gguf_writer .add_expert_used_count (n_experts_used ) 24if (moe_intermediate_size := self .hparams .get ("moe_ffn_hidden_size" ))is not None : 25self .gguf_writer .add_expert_feed_forward_length (moe_intermediate_size ) 26self .gguf_writer .add_feed_forward_length (moe_intermediate_size ) 27logger .info (f"gguf: expert feed forward length = { moe_intermediate_size } " ) 28if (self .hparams .get ('moe_primary_router_apply_softmax' )): 29self .gguf_writer .add_expert_gating_func (gguf .ExpertGatingFuncType .SOFTMAX ) 30else : 31self .gguf_writer .add_expert_gating_func (gguf .ExpertGatingFuncType .SIGMOID ) 32 33sliding_window_layout = self .hparams .get ("sliding_window_layout" ) 34if sliding_window_layout : 35for i in sliding_window_layout : 36if i != 0 : 37sliding_window = self .hparams .get ("sliding_window_size" ) 38if sliding_window : 39self .gguf_writer .add_sliding_window (sliding_window ) 40break 41 42_experts :list [dict [str ,Tensor ]]| None = None 43 44def modify_tensors (self ,data_torch :Tensor ,name :str ,bid :int | None )-> Iterable [tuple [str ,Tensor ]]: 45# process the experts separately 46if name .find ("experts" )!= - 1 : 47n_experts = self .hparams .get ("moe_num_primary_experts" )or self .find_hparam (["num_local_experts" ,"num_experts" ]) 48assert bid is not None 49 50if self ._experts is None : 51self ._experts = [{}for _ in range (self .block_count )] 52 53self ._experts [bid ][name ]= data_torch 54 55if len (self ._experts [bid ])>= n_experts * 3 : 56# merge the experts into a single 3d tensor 57for w_name in ["down" ,"gate" ,"up" ]: 58datas :list [Tensor ]= [] 59 60for xid in range (n_experts ): 61ename = f"model.layers. { bid } .block_sparse_moe.experts. { xid } . { w_name } .weight" 62datas .append (self ._experts [bid ][ename ]) 63del self ._experts [bid ][ename ] 64 65data_torch = torch .stack (datas ,dim = 0 ) 66 67merged_name = f"model.layers. { bid } .block_sparse_moe.experts. { w_name } .weight" 68 69yield from super ().modify_tensors (data_torch ,merged_name ,bid ) 70return 71else : 72return 73 74yield from super ().modify_tensors (data_torch ,name ,bid ) 75 76def prepare_tensors (self ): 77super ().prepare_tensors () 78 79if self ._experts is not None : 80# flatten `list[dict[str, Tensor]]` into `list[str]` 81experts = [k for d in self ._experts for k in d .keys ()] 82if len (experts )> 0 : 83raise ValueError (f"Unprocessed experts: { experts } " )