char-fork/llama.cpp
git clone https://git.t4t.associates/char-fork/llama.cpp
3d10bcd19
char/aliceai-t5-moe
1from __future__import annotations 2 3from typing import Iterable ,TYPE_CHECKING ,cast 4 5import torch 6 7if TYPE_CHECKING : 8from torch import Tensor 9 10from .base import LazyTorchTensor ,ModelBase ,TextModel ,gguf 11 12 13@ ModelBase . register ( "MapleForCausalLM" ) 14@ ModelBase . example ( "deepgrove/maple-preview" ) 15class MapleModel (TextModel ): 16model_arch = gguf .MODEL_ARCH .MAPLE 17 18def set_gguf_parameters (self ): 19super ().set_gguf_parameters () 20hparams = self .hparams 21 22assert hparams ["hidden_act" ]== "silu" 23assert hparams .get ("num_shared_experts" ,0 )== 0 24assert hparams .get ("norm_topk_prob" ,True ) 25assert hparams .get ("nope_on_global_attention" ,False ) 26 27head_dim = hparams .get ("head_dim" ,hparams ["hidden_size" ]// hparams ["num_attention_heads" ]) 28partial_rotary_factor = self .rope_parameters .get ("partial_rotary_factor" ,1.0 ) 29 30self .gguf_writer .add_vocab_size (hparams ["vocab_size" ]) 31self .gguf_writer .add_rope_dimension_count (int (head_dim * partial_rotary_factor )) 32self .gguf_writer .add_sliding_window (hparams ["sliding_window" ]) 33self .gguf_writer .add_sliding_window_pattern ([layer_type == "sliding_attention" for layer_type in hparams ["layer_types" ]]) 34self .gguf_writer .add_expert_feed_forward_length (hparams ["moe_intermediate_size" ]) 35# the reference clamps the MoE SwiGLU gate/up at 7.0 (modeling_maple.py) 36self .gguf_writer .add_swiglu_clamp_exp ([7.0 ]* self .block_count ) 37 38_experts :list [dict [str ,Tensor ]]| None = None 39 40@staticmethod 41def _stack_experts (tensors :list [Tensor ])-> Tensor : 42shape = (len (tensors ),* tensors [0 ].shape ) 43dtype = tensors [0 ].dtype 44meta = LazyTorchTensor .meta_with_dtype_and_shape (dtype ,shape ) 45 46# tensors goes through args, not the closure, so that `func` matches 47# LazyBase's single-argument shape 48def stack (ts :list [Tensor ])-> Tensor : 49result = torch .empty (shape ,dtype = dtype ) 50for expert_id ,tensor in enumerate (ts ): 51result [expert_id ].copy_ (LazyTorchTensor .to_eager (tensor )) 52ts .clear () 53return result 54 55return cast (torch .Tensor ,LazyTorchTensor (meta = meta ,args = (tensors ,),func = stack )) 56 57def modify_tensors (self ,data_torch :Tensor ,name :str ,bid :int | None )-> Iterable [tuple [str ,Tensor ]]: 58if "mlp.experts" in name : 59n_experts = self .hparams ["num_experts" ] 60assert bid is not None 61 62if self ._experts is None : 63self ._experts = [{}for _ in range (self .block_count )] 64 65self ._experts [bid ][name ]= data_torch 66 67if len (self ._experts [bid ])>= n_experts * 3 : 68for weight_name in ("down_proj" ,"gate_proj" ,"up_proj" ): 69tensors = [] 70 71for expert_id in range (n_experts ): 72expert_name = f"model.layers. { bid } .mlp.experts. { expert_id } . { weight_name } .weight" 73tensors .append (self ._experts [bid ].pop (expert_name )) 74 75merged_name = f"model.layers. { bid } .mlp.experts. { weight_name } .weight" 76yield from super ().modify_tensors (self ._stack_experts (tensors ),merged_name ,bid ) 77return 78 79yield from super ().modify_tensors (data_torch ,name ,bid ) 80 81def prepare_tensors (self ): 82super ().prepare_tensors () 83 84if self ._experts is not None : 85experts = [name for layer in self ._experts for name in layer ] 86if experts : 87raise ValueError (f"Unprocessed experts: { experts } " )