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 Callable ,Iterable ,TYPE_CHECKING 4 5import torch 6 7if TYPE_CHECKING : 8from torch import Tensor 9 10from .base import ModelBase ,TextModel ,gguf 11 12 13@ ModelBase . register ( "Rwkv6ForCausalLM" ) 14@ ModelBase . example ( "RWKV/v6-Finch-1B6-HF" ) 15class Rwkv6Model (TextModel ): 16model_arch = gguf .MODEL_ARCH .RWKV6 17 18def set_vocab (self ): 19self ._set_vocab_rwkv_world () 20 21def set_gguf_parameters (self ): 22head_size = self .hparams ["head_size" ] 23hidden_size = self .hparams ["hidden_size" ] 24layer_norm_eps = self .hparams ["layer_norm_epsilon" ] 25rescale_every_n_layers = self .hparams ["rescale_every" ] 26intermediate_size = self .hparams ["intermediate_size" ]if self .hparams ["intermediate_size" ]is not None else int ((hidden_size * 3.5 )// 32 * 32 ) 27time_mix_extra_dim = 64 if hidden_size == 4096 else 32 28time_decay_extra_dim = 128 if hidden_size == 4096 else 64 29 30# RWKV isn't context limited 31self .gguf_writer .add_context_length (1048576 ) 32self .gguf_writer .add_embedding_length (hidden_size ) 33self .gguf_writer .add_block_count (self .block_count ) 34self .gguf_writer .add_layer_norm_eps (layer_norm_eps ) 35self .gguf_writer .add_rescale_every_n_layers (rescale_every_n_layers ) 36self .gguf_writer .add_wkv_head_size (head_size ) 37self .gguf_writer .add_time_mix_extra_dim (time_mix_extra_dim ) 38self .gguf_writer .add_time_decay_extra_dim (time_decay_extra_dim ) 39self .gguf_writer .add_feed_forward_length (intermediate_size ) 40self .gguf_writer .add_file_type (self .ftype ) 41 42# required by llama.cpp, unused 43self .gguf_writer .add_head_count (0 ) 44 45lerp_weights :dict [int ,dict [str ,Tensor ]]= {} 46 47def modify_tensors (self ,data_torch :Tensor ,name :str ,bid :int | None )-> Iterable [tuple [str ,Tensor ]]: 48new_name = self .map_tensor_name (name ) 49 50if not (new_name .endswith (".weight" )or new_name .endswith (".bias" )): 51new_name += ".weight" 52 53if new_name .endswith ("time_mix_w1.weight" )or new_name .endswith ("time_mix_decay_w1.weight" )or new_name .endswith ("time_mix_decay_w2.weight" ): 54data_torch = data_torch .transpose (0 ,1 ) 55 56if new_name .endswith ("time_mix_w2.weight" ): 57data_torch = data_torch .permute (0 ,2 ,1 ) 58 59if new_name .endswith ("time_mix_decay.weight" )or "lerp" in new_name : 60data_torch = data_torch .squeeze () 61 62try : 63rescale_every_n_layers = self .hparams ["rescale_every" ] 64if rescale_every_n_layers > 0 : 65if new_name .endswith ("time_mix_output.weight" )or new_name .endswith ("channel_mix_value.weight" ): 66data_torch = data_torch .div_ (2 ** int (bid // rescale_every_n_layers )) 67except KeyError : 68pass 69 70# concat time_mix_lerp weights to reduce some cpu overhead 71# also reduces the number of tensors in the model 72if bid is not None and "time_mix_lerp" in new_name and "time_mix_lerp_x" not in new_name : 73try : 74self .lerp_weights [bid ][new_name ]= data_torch 75except KeyError : 76self .lerp_weights [bid ]= {new_name :data_torch } 77if all (f"blk. { bid } .time_mix_lerp_ { i } .weight" in self .lerp_weights [bid ].keys ()for i in ["w" ,"k" ,"v" ,"r" ,"g" ]): 78new_name = f"blk. { bid } .time_mix_lerp_fused.weight" 79data = torch .stack ([self .lerp_weights [bid ][f"blk. { bid } .time_mix_lerp_ { i } .weight" ].unsqueeze (0 )for i in ["w" ,"k" ,"v" ,"r" ,"g" ]],dim = 0 ).unsqueeze (1 ) 80yield (new_name ,data ) 81return 82 83yield (new_name ,data_torch ) 84 85 86@ ModelBase . register ( "RWKV6Qwen2ForCausalLM" ) 87@ ModelBase . example ( "recursal/QRWKV6-32B-Instruct-Preview-v0.1" ) 88class RWKV6Qwen2Model (Rwkv6Model ): 89model_arch = gguf .MODEL_ARCH .RWKV6QWEN2 90 91def set_vocab (self ): 92try : 93self ._set_vocab_sentencepiece () 94except FileNotFoundError : 95self ._set_vocab_gpt2 () 96 97def set_gguf_parameters (self ): 98num_attention_heads = self .hparams ["num_attention_heads" ] 99num_key_value_heads = self .hparams ["num_key_value_heads" ] 100hidden_size = self .hparams ["hidden_size" ] 101head_size = hidden_size // num_attention_heads 102rms_norm_eps = self .hparams ["rms_norm_eps" ] 103intermediate_size = self .hparams ["intermediate_size" ] 104time_mix_extra_dim = self .hparams .get ("lora_rank_tokenshift" ,64 if hidden_size >= 4096 else 32 ) 105time_decay_extra_dim = self .hparams .get ("lora_rank_decay" ,128 if hidden_size >= 4096 else 64 ) 106 107# RWKV isn't context limited 108self .gguf_writer .add_context_length (1048576 ) 109self .gguf_writer .add_embedding_length (hidden_size ) 110self .gguf_writer .add_block_count (self .block_count ) 111self .gguf_writer .add_wkv_head_size (head_size ) 112self .gguf_writer .add_time_mix_extra_dim (time_mix_extra_dim ) 113self .gguf_writer .add_time_decay_extra_dim (time_decay_extra_dim ) 114self .gguf_writer .add_feed_forward_length (intermediate_size ) 115self .gguf_writer .add_file_type (self .ftype ) 116 117# special parameters for time_mixing in RWKV6QWEN2 118self .gguf_writer .add_layer_norm_rms_eps (rms_norm_eps ) 119self .gguf_writer .add_token_shift_count (1 ) 120# RWKV6QWEN2 use grouped key/value like GQA 121self .gguf_writer .add_head_count_kv (num_key_value_heads ) 122 123# required by llama.cpp, unused 124self .gguf_writer .add_head_count (0 ) 125 126def modify_tensors (self ,data_torch :Tensor ,name :str ,bid :int | None )-> Iterable [tuple [str ,Tensor ]]: 127for new_name ,data in super ().modify_tensors (data_torch ,name ,bid ): 128if "time_mix_w1" in new_name or "time_mix_w2" in new_name : 129data = data .view (5 ,- 1 ,data .shape [- 1 ]) 130# rwkv6qwen2 has a different order of rkvwg instead of the original wkvrg 131# permute them here to avoid code changes 132data = torch .stack ([data [3 ],data [1 ],data [2 ],data [0 ],data [4 ]],dim = 0 ).view (- 1 ,data .shape [- 1 ]) 133if "w2" in new_name : 134data = data .view (5 ,- 1 ,data .shape [- 1 ]) 135yield (new_name ,data ) 136continue 137yield (new_name ,data ) 138 139 140@ ModelBase . register ( "Rwkv7ForCausalLM" , "RWKV7ForCausalLM" ) 141@ ModelBase . example ( "fla-hub/rwkv7-1.5B-world" ) 142class Rwkv7Model (TextModel ): 143model_arch = gguf .MODEL_ARCH .RWKV7 144 145def set_vocab (self ): 146self ._set_vocab_rwkv_world () 147 148def calc_lora_rank (self ,hidden_size ,exponent ,multiplier ): 149return max (1 ,round (hidden_size ** exponent * multiplier / 32 ))* 32 150 151def set_gguf_parameters (self ): 152try : 153head_size = self .hparams ["head_size" ] 154layer_norm_eps = self .hparams ["layer_norm_epsilon" ] 155except KeyError : 156head_size = self .hparams ["head_dim" ] 157layer_norm_eps = self .hparams ["norm_eps" ] 158hidden_size = self .hparams ["hidden_size" ] 159intermediate_size = self .hparams ["intermediate_size" ]if self .hparams ["intermediate_size" ]is not None else (hidden_size * 4 ) 160 161# ICLR: In-Context-Learning-Rate 162try : 163lora_rank_decay = self .hparams ["lora_rank_decay" ]if self .hparams ["lora_rank_decay" ]is not None else self .calc_lora_rank (hidden_size ,0.5 ,1.8 ) 164lora_rank_iclr = self .hparams ["lora_rank_iclr" ]if self .hparams ["lora_rank_iclr" ]is not None else self .calc_lora_rank (hidden_size ,0.5 ,1.8 ) 165lora_rank_value_residual_mix = self .hparams ["lora_rank_value_residual_mix" ]if self .hparams ["lora_rank_value_residual_mix" ]is not None else self .calc_lora_rank (hidden_size ,0.5 ,1.3 ) 166lora_rank_gate = self .hparams ["lora_rank_gate" ]if self .hparams ["lora_rank_gate" ]is not None else self .calc_lora_rank (hidden_size ,0.8 ,0.6 ) 167except KeyError : 168lora_rank_decay = self .hparams ["decay_low_rank_dim" ]if self .hparams ["decay_low_rank_dim" ]is not None else self .calc_lora_rank (hidden_size ,0.5 ,1.8 ) 169lora_rank_iclr = self .hparams ["a_low_rank_dim" ]if self .hparams ["a_low_rank_dim" ]is not None else self .calc_lora_rank (hidden_size ,0.5 ,1.8 ) 170lora_rank_value_residual_mix = self .hparams ["v_low_rank_dim" ]if self .hparams ["v_low_rank_dim" ]is not None else self .calc_lora_rank (hidden_size ,0.5 ,1.3 ) 171lora_rank_gate = self .hparams ["gate_low_rank_dim" ]if self .hparams ["gate_low_rank_dim" ]is not None else self .calc_lora_rank (hidden_size ,0.8 ,0.6 ) 172 173# RWKV isn't context limited 174self .gguf_writer .add_context_length (1048576 ) 175self .gguf_writer .add_embedding_length (hidden_size ) 176self .gguf_writer .add_block_count (self .block_count ) 177self .gguf_writer .add_layer_norm_eps (layer_norm_eps ) 178self .gguf_writer .add_wkv_head_size (head_size ) 179self .gguf_writer .add_decay_lora_rank (lora_rank_decay ) 180self .gguf_writer .add_iclr_lora_rank (lora_rank_iclr ) 181self .gguf_writer .add_value_residual_mix_lora_rank (lora_rank_value_residual_mix ) 182self .gguf_writer .add_gate_lora_rank (lora_rank_gate ) 183self .gguf_writer .add_feed_forward_length (intermediate_size ) 184self .gguf_writer .add_file_type (self .ftype ) 185 186# required by llama.cpp, unused 187self .gguf_writer .add_head_count (0 ) 188 189lerp_weights :dict [int ,dict [str ,Tensor ]]= {} 190lora_needs_transpose :bool = True 191 192@classmethod 193def filter_tensors (cls ,item :tuple [str ,Callable [[],Tensor ]])-> tuple [str ,Callable [[],Tensor ]]| None : 194name ,gen = item 195 196# unify tensor names here to make life easier 197name = name .replace ("blocks" ,"layers" ).replace ("ffn" ,"feed_forward" ) 198name = name .replace ("self_attn" ,"attention" ).replace ("attn" ,"attention" ) 199name = name .replace ("time_mixer." ,"" ) 200 201name = name .replace ("feed_forward_norm" ,"ln2" ) 202name = name .replace ("g_norm" ,"ln_x" ) 203 204return super ().filter_tensors ((name ,gen )) 205 206def modify_tensors (self ,data_torch :Tensor ,name :str ,bid :int | None )-> Iterable [tuple [str ,Tensor ]]: 207# lora layer names in fla-hub's impl 208if "_lora.lora" in name : 209self .lora_needs_transpose = False 210name = name .replace ("_lora.lora.0.weight" ,"1.weight" ) 211name = name .replace ("_lora.lora.2.weight" ,"2.weight" ) 212name = name .replace ("_lora.lora.2.bias" ,"0.weight" ) 213 214if "attention.v" in name and "value" not in self .map_tensor_name (name )and bid == 0 : 215# some models have dummy v0/v1/v2 on first layer while others don't 216# ignore them all since they are not used 217return 218 219wkv_has_gate = self .hparams .get ("wkv_has_gate" ,True ) 220lerp_list = ["r" ,"w" ,"k" ,"v" ,"a" ,"g" ]if wkv_has_gate else ["r" ,"w" ,"k" ,"v" ,"a" ] 221 222if bid is not None and "attention.x_" in name : 223if "attention.x_x" in name : 224# already concatenated 225new_name = f"blk. { bid } .time_mix_lerp_fused.weight" 226data = data_torch .reshape (len (lerp_list ),1 ,1 ,- 1 ) 227yield (new_name ,data ) 228else : 229try : 230self .lerp_weights [bid ][name ]= data_torch 231except KeyError : 232self .lerp_weights [bid ]= {name :data_torch } 233if all (f"model.layers. { bid } .attention.x_ { i } " in self .lerp_weights [bid ].keys ()for i in lerp_list ): 234new_name = f"blk. { bid } .time_mix_lerp_fused.weight" 235data = torch .stack ([self .lerp_weights [bid ][f"model.layers. { bid } .attention.x_ { i } " ]for i in lerp_list ],dim = 0 ) 236yield (new_name ,data ) 237return 238else : 239data_torch = data_torch .squeeze () 240new_name = self .map_tensor_name (name ) 241 242if not (new_name .endswith (".weight" )or new_name .endswith (".bias" )): 243new_name += ".weight" 244 245if self .lora_needs_transpose and any ( 246new_name .endswith (t )for t in [ 247"time_mix_w1.weight" ,"time_mix_w2.weight" , 248"time_mix_a1.weight" ,"time_mix_a2.weight" , 249"time_mix_v1.weight" ,"time_mix_v2.weight" , 250"time_mix_g1.weight" ,"time_mix_g2.weight" , 251 ] 252 ): 253data_torch = data_torch .transpose (0 ,1 ) 254 255if 'r_k' in new_name : 256data_torch = data_torch .flatten () 257 258if bid == 0 and "time_mix_a" in new_name : 259# dummy v0/v1/v2 on first layer 260# easiest way to make llama happy 261yield (new_name .replace ("time_mix_a" ,"time_mix_v" ),data_torch ) 262 263yield (new_name ,data_torch ) 264 265 266@ ModelBase . register ( "RwkvHybridForCausalLM" ) 267@ ModelBase . example ( "RWKV-Red-Team/ARWKV-7B-Preview-0.1" ) 268class ARwkv7Model (Rwkv7Model ): 269model_arch = gguf .MODEL_ARCH .ARWKV7 270 271def set_vocab (self ): 272try : 273self ._set_vocab_sentencepiece () 274except FileNotFoundError : 275self ._set_vocab_gpt2 () 276 277def set_gguf_parameters (self ): 278hidden_size = self .hparams ["hidden_size" ] 279head_size = self .hparams ["head_size" ] 280rms_norm_eps = self .hparams ["rms_norm_eps" ] 281intermediate_size = self .hparams ["intermediate_size" ] 282wkv_has_gate = self .hparams ["wkv_has_gate" ] 283assert self .hparams ["wkv_version" ]== 7 284 285# ICLR: In-Context-Learning-Rate 286lora_rank_decay = 64 287lora_rank_iclr = 64 288lora_rank_value_residual_mix = 32 289lora_rank_gate = 128 if wkv_has_gate else 0 290 291# RWKV isn't context limited 292self .gguf_writer .add_context_length (1048576 ) 293self .gguf_writer .add_embedding_length (hidden_size ) 294self .gguf_writer .add_block_count (self .block_count ) 295self .gguf_writer .add_layer_norm_rms_eps (rms_norm_eps ) 296self .gguf_writer .add_wkv_head_size (head_size ) 297self .gguf_writer .add_decay_lora_rank (lora_rank_decay ) 298self .gguf_writer .add_iclr_lora_rank (lora_rank_iclr ) 299self .gguf_writer .add_value_residual_mix_lora_rank (lora_rank_value_residual_mix ) 300self .gguf_writer .add_gate_lora_rank (lora_rank_gate ) 301self .gguf_writer .add_feed_forward_length (intermediate_size ) 302self .gguf_writer .add_file_type (self .ftype ) 303self .gguf_writer .add_token_shift_count (1 ) 304 305# required by llama.cpp, unused 306self .gguf_writer .add_head_count (0 )