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 ,TYPE_CHECKING 4 5if TYPE_CHECKING : 6from torch import Tensor 7 8from .base import ModelBase ,SentencePieceTokenTypes ,TextModel ,gguf 9 10 11@ ModelBase . register ( "GlmForCausalLM" , "ChatGLMModel" , "ChatGLMForConditionalGeneration" ) 12@ ModelBase . example ( "THUDM/chatglm3-6b" , "zai-org/glm-4-9b-chat-hf" ) 13class ChatGLMModel (TextModel ): 14model_arch = gguf .MODEL_ARCH .CHATGLM 15 16def set_vocab_chatglm3 (self ): 17dir_model = self .dir_model 18hparams = self .hparams 19tokens :list [bytes ]= [] 20toktypes :list [int ]= [] 21scores :list [float ]= [] 22 23from transformers import AutoTokenizer 24tokenizer = AutoTokenizer .from_pretrained (dir_model ,trust_remote_code = True ) 25vocab_size = hparams .get ("padded_vocab_size" ,len (tokenizer .get_vocab ()))# ty: ignore[unresolved-attribute] 26assert max (tokenizer .get_vocab ().values ())< vocab_size # ty: ignore[unresolved-attribute] 27role_special_tokens = ["<|system|>" ,"<|user|>" ,"<|assistant|>" ,"<|observation|>" ] 28special_tokens = ["[MASK]" ,"[gMASK]" ,"[sMASK]" ,"sop" ,"eop" ]+ role_special_tokens 29for token_id in range (vocab_size ): 30piece = tokenizer ._convert_id_to_token (token_id )# ty: ignore[unresolved-attribute] 31if token_id == 0 : 32piece = "<unk>" 33elif token_id == 1 : 34piece = "<bos>" 35elif token_id == 2 : 36piece = "<eos>" 37 38text = piece .encode ("utf-8" )# ty: ignore[unresolved-attribute] 39score = 0.0 40# Referencing the tokenizer Python implementation(https://huggingface.co/THUDM/chatglm3-6b/blob/main/tokenization_chatglm.py), 41# it is only valid if it is less than tokenizer.tokenizer.sp_model.vocab_size() 42if len (piece )!= 0 and token_id < tokenizer .tokenizer .sp_model .vocab_size ():# ty: ignore[unresolved-attribute, invalid-argument-type] 43score = tokenizer .tokenizer .sp_model .get_score (token_id )# ty: ignore[unresolved-attribute] 44 45if token_id >= tokenizer .tokenizer .sp_model .vocab_size ():# ty: ignore[unresolved-attribute] 46if piece in special_tokens : 47toktype = SentencePieceTokenTypes .CONTROL 48elif len (piece )== 0 :# ty: ignore[invalid-argument-type] 49text = f"[PAD { token_id } ]" .encode ("utf-8" ) 50toktype = SentencePieceTokenTypes .UNUSED 51else : 52toktype = SentencePieceTokenTypes .USER_DEFINED 53tokens .append (text ) 54scores .append (score ) 55toktypes .append (toktype ) 56continue 57 58toktype = SentencePieceTokenTypes .NORMAL 59if tokenizer .tokenizer .sp_model .is_unknown (token_id ):# ty: ignore[unresolved-attribute] 60toktype = SentencePieceTokenTypes .UNKNOWN 61elif tokenizer .tokenizer .sp_model .is_control (token_id ):# ty: ignore[unresolved-attribute] 62toktype = SentencePieceTokenTypes .CONTROL 63elif tokenizer .tokenizer .sp_model .is_unused (token_id ):# ty: ignore[unresolved-attribute] 64toktype = SentencePieceTokenTypes .UNUSED 65elif tokenizer .tokenizer .sp_model .is_byte (token_id ):# ty: ignore[unresolved-attribute] 66toktype = SentencePieceTokenTypes .BYTE 67 68tokens .append (text ) 69scores .append (score ) 70toktypes .append (toktype ) 71 72self .gguf_writer .add_tokenizer_model ("llama" ) 73# glm3 needs prefix and suffix formatted as: 74# prompt = "[gMASK]sop<|user|>\n" + prompt + "<|assistant|>" 75self .gguf_writer .add_tokenizer_pre ("chatglm-spm" ) 76self .gguf_writer .add_token_list (tokens ) 77self .gguf_writer .add_token_scores (scores ) 78self .gguf_writer .add_token_types (toktypes ) 79 80special_vocab = gguf .SpecialVocab (self .dir_model ,n_vocab = len (tokens )) 81special_vocab .add_to_gguf (self .gguf_writer ) 82 83@staticmethod 84def token_bytes_to_string (b ): 85from transformers .convert_slow_tokenizer import bytes_to_unicode 86byte_encoder = bytes_to_unicode () 87return '' .join ([byte_encoder [ord (char )]for char in b .decode ('latin-1' )]) 88 89@staticmethod 90def bpe (mergeable_ranks :dict [bytes ,int ],token :bytes ,max_rank :int | None = None )-> list [bytes ]: 91parts = [bytes ([b ])for b in token ] 92while True : 93min_idx = None 94min_rank = None 95for i ,pair in enumerate (zip (parts [:- 1 ],parts [1 :])): 96rank = mergeable_ranks .get (pair [0 ]+ pair [1 ]) 97if rank is not None and (min_rank is None or rank < min_rank ): 98min_idx = i 99min_rank = rank 100if min_rank is None or (max_rank is not None and min_rank >= max_rank ): 101break 102assert min_idx is not None 103parts = parts [:min_idx ]+ [parts [min_idx ]+ parts [min_idx + 1 ]]+ parts [min_idx + 2 :] 104return parts 105 106def set_vocab (self ): 107if "THUDM/chatglm3-6b" in self .hparams .get ("_name_or_path" ,"" ): 108self .set_vocab_chatglm3 () 109return 110 111dir_model = self .dir_model 112hparams = self .hparams 113tokens :list [str ]= [] 114toktypes :list [int ]= [] 115 116from transformers import AutoTokenizer 117tokenizer = AutoTokenizer .from_pretrained (dir_model ,trust_remote_code = True ) 118vocab_size = hparams .get ("padded_vocab_size" ,hparams ["vocab_size" ]) 119assert max (tokenizer .get_vocab ().values ())< vocab_size # ty: ignore[unresolved-attribute] 120 121tokens ,toktypes ,tokpre = self .get_vocab_base () 122self .gguf_writer .add_tokenizer_model ("gpt2" ) 123self .gguf_writer .add_tokenizer_pre (tokpre ) 124self .gguf_writer .add_token_list (tokens ) 125self .gguf_writer .add_token_types (toktypes ) 126special_vocab = gguf .SpecialVocab (self .dir_model ,load_merges = True ) 127# only add special tokens when they were not already loaded from config.json 128special_vocab ._set_special_token ("eos" ,tokenizer .get_added_vocab ()["<|endoftext|>" ])# ty: ignore[unresolved-attribute] 129special_vocab ._set_special_token ("eot" ,tokenizer .get_added_vocab ()["<|user|>" ])# ty: ignore[unresolved-attribute] 130# this one is usually not in config.json anyway 131special_vocab ._set_special_token ("unk" ,tokenizer .get_added_vocab ()["<|endoftext|>" ])# ty: ignore[unresolved-attribute] 132special_vocab .add_to_gguf (self .gguf_writer ) 133 134def set_gguf_parameters (self ): 135n_embed = self .hparams .get ("hidden_size" ,self .hparams .get ("n_embed" )) 136assert n_embed is not None 137n_head = self .hparams .get ("n_head" ,self .hparams .get ("num_attention_heads" )) 138assert n_head is not None 139n_head_kv = self .hparams .get ("multi_query_group_num" ,self .hparams .get ("num_key_value_heads" ,n_head )) 140self .gguf_writer .add_context_length (self .hparams .get ("seq_length" ,n_embed )) 141self .gguf_writer .add_embedding_length (n_embed ) 142self .gguf_writer .add_feed_forward_length (self .hparams .get ("ffn_hidden_size" ,self .hparams .get ("intermediate_size" ,4 * n_embed ))) 143self .gguf_writer .add_block_count (self .block_count ) 144self .gguf_writer .add_head_count (n_head ) 145self .gguf_writer .add_head_count_kv (n_head_kv ) 146self .gguf_writer .add_layer_norm_rms_eps (self .hparams .get ("layernorm_epsilon" ,1e-5 )) 147self .gguf_writer .add_file_type (self .ftype ) 148if "attention_dim" in self .hparams : 149rope_dim = self .hparams ["attention_dim" ] 150else : 151rope_dim = self .hparams ["hidden_size" ]// self .hparams ["num_attention_heads" ] 152self .gguf_writer .add_rope_dimension_count (int (rope_dim * self .rope_parameters .get ("partial_rotary_factor" ,0.5 ))) 153self .gguf_writer .add_add_bos_token (False ) 154rope_freq = 10000 155if "rope_ratio" in self .hparams : 156rope_freq = rope_freq * self .hparams ["rope_ratio" ] 157self .gguf_writer .add_rope_freq_base (rope_freq ) 158 159@classmethod 160def filter_tensors (cls ,item :tuple [str ,Callable [[],Tensor ]])-> tuple [str ,Callable [[],Tensor ]]| None : 161name ,gen = item 162 163if name .endswith (".rotary_pos_emb.inv_freq" ): 164return None 165 166name = name .removeprefix ("transformer." ) 167 168return super ().filter_tensors ((name ,gen ))