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 ( "GroveMoeForCausalLM" , "modeling_grove_moe.GroveMoeForCausalLM" ) 14@ ModelBase . example ( "inclusionAI/GroveMoE-Inst" ) 15class GroveMoeModel (TextModel ): 16model_arch = gguf .MODEL_ARCH .GROVEMOE 17 18def set_gguf_parameters (self ): 19super ().set_gguf_parameters () 20if (moe_intermediate_size := self .hparams .get ("moe_intermediate_size" ))is not None : 21self .gguf_writer .add_expert_feed_forward_length (moe_intermediate_size ) 22logger .info (f"gguf: expert feed forward length = { moe_intermediate_size } " ) 23# FIXME?: Hardcoded https://huggingface.co/inclusionAI/GroveMoE-Inst/blob/c4c69e5970d18907b5e6ddccdfd55176fe292df1/modeling_grove_moe.py#L299 24self .gguf_writer .add_expert_chunk_feed_forward_length (self .hparams .get ("head_dim" )or 128 ) 25# FIXME?: Hardcoded https://huggingface.co/inclusionAI/GroveMoE-Inst/blob/c4c69e5970d18907b5e6ddccdfd55176fe292df1/modeling_grove_moe.py#L298 26self .gguf_writer .add_experts_per_group (2 ) 27# FIXME?: Hardcoded https://huggingface.co/inclusionAI/GroveMoE-Inst/blob/c4c69e5970d18907b5e6ddccdfd55176fe292df1/modeling_grove_moe.py#L376 28self .gguf_writer .add_expert_group_scale (0.05 ) 29 30_experts :list [dict [str ,Tensor ]]| None = None 31_chunk_experts :list [dict [str ,Tensor ]]| None = None 32 33def modify_tensors (self ,data_torch :Tensor ,name :str ,bid :int | None )-> Iterable [tuple [str ,Tensor ]]: 34if name .endswith (".expert_bias" ): 35# FIXME?: Unused https://huggingface.co/inclusionAI/GroveMoE-Inst/blob/c4c69e5970d18907b5e6ddccdfd55176fe292df1/modeling_grove_moe.py#L303 36return 37 38# process the experts separately 39if name .find ("chunk_experts" )!= - 1 : 40n_experts = self .find_hparam (["num_local_experts" ,"num_experts" ])// 2 # see add_experts_per_group 41assert bid is not None 42 43if self ._chunk_experts is None : 44self ._chunk_experts = [{}for _ in range (self .block_count )] 45 46self ._chunk_experts [bid ][name ]= data_torch 47 48if len (self ._chunk_experts [bid ])>= n_experts * 3 : 49# merge the experts into a single 3d tensor 50for w_name in ["down_proj" ,"gate_proj" ,"up_proj" ]: 51datas :list [Tensor ]= [] 52 53for xid in range (n_experts ): 54ename = f"model.layers. { bid } .mlp.chunk_experts. { xid } . { w_name } .weight" 55datas .append (self ._chunk_experts [bid ][ename ]) 56del self ._chunk_experts [bid ][ename ] 57 58data_torch = torch .stack (datas ,dim = 0 ) 59 60merged_name = f"model.layers. { bid } .mlp.chunk_experts. { w_name } .weight" 61 62yield from super ().modify_tensors (data_torch ,merged_name ,bid ) 63return 64else : 65return 66elif name .find ("experts" )!= - 1 : 67n_experts = self .find_hparam (["num_local_experts" ,"num_experts" ]) 68assert bid is not None 69 70if self ._experts is None : 71self ._experts = [{}for _ in range (self .block_count )] 72 73self ._experts [bid ][name ]= data_torch 74 75if len (self ._experts [bid ])>= n_experts * 3 : 76# merge the experts into a single 3d tensor 77for w_name in ["down_proj" ,"gate_proj" ,"up_proj" ]: 78datas :list [Tensor ]= [] 79 80for xid in range (n_experts ): 81ename = f"model.layers. { bid } .mlp.experts. { xid } . { w_name } .weight" 82datas .append (self ._experts [bid ][ename ]) 83del self ._experts [bid ][ename ] 84 85data_torch = torch .stack (datas ,dim = 0 ) 86 87merged_name = f"model.layers. { bid } .mlp.experts. { w_name } .weight" 88 89yield from super ().modify_tensors (data_torch ,merged_name ,bid ) 90return 91else : 92return 93 94yield from super ().modify_tensors (data_torch ,name ,bid ) 95 96def prepare_tensors (self ): 97super ().prepare_tensors () 98 99if self ._chunk_experts is not None : 100# flatten `list[dict[str, Tensor]]` into `list[str]` 101chunk_experts = [k for d in self ._chunk_experts for k in d .keys ()] 102if len (chunk_experts )> 0 : 103raise ValueError (f"Unprocessed adjugate experts: { chunk_experts } " ) 104 105if self ._experts is not None : 106# flatten `list[dict[str, Tensor]]` into `list[str]` 107experts = [k for d in self ._experts for k in d .keys ()] 108if len (experts )> 0 : 109raise ValueError (f"Unprocessed experts: { experts } " )