char-fork/llama.cpp
git clone https://git.t4t.associates/char-fork/llama.cpp
c8ac02fa1
char/aliceai-t5-moe
1# Test libllama tokenizer == AutoTokenizer. 2# Brute force random words/text generation. 3# 4# Sample usage: 5# 6# python3 tests/test-tokenizer-random.py ./models/ggml-vocab-llama-bpe.gguf ./models/tokenizers/llama-bpe 7# 8 9from __future__import annotations 10 11import time 12import logging 13import argparse 14import subprocess 15import random 16import unicodedata 17 18from pathlib import Path 19from typing import Any ,Iterator 20 21import cffi 22from transformers import AutoTokenizer ,PreTrainedTokenizer 23 24 25logger = logging .getLogger ("test-tokenizer-random" ) 26 27 28class LibLlama : 29 30DEFAULT_PATH_LLAMA_H = "./include/llama.h" 31DEFAULT_PATH_INCLUDES = ["./ggml/include/" ,"./include/" ] 32DEFAULT_PATH_LIBLLAMA = "./build/src/libllama.so" # CMakeLists.txt: BUILD_SHARED_LIBS ON 33 34def __init__ (self ,path_llama_h :str | None = None ,path_includes :list [str ]= [],path_libllama :str | None = None ): 35path_llama_h = path_llama_h or self .DEFAULT_PATH_LLAMA_H 36path_includes = path_includes or self .DEFAULT_PATH_INCLUDES 37path_libllama = path_libllama or self .DEFAULT_PATH_LIBLLAMA 38 (self .ffi ,self .lib )= self ._load_libllama_cffi (path_llama_h ,path_includes ,path_libllama ) 39self .lib .llama_backend_init () 40 41def _load_libllama_cffi (self ,path_llama_h :str ,path_includes :list [str ],path_libllama :str )-> tuple [cffi .FFI ,Any ]: 42cmd = ["gcc" ,"-O0" ,"-E" ,"-P" ,"-D__restrict=" ,"-D__attribute__(x)=" ,"-D__asm__(x)=" ] 43cmd += ["-I" + path for path in path_includes ]+ [path_llama_h ] 44res = subprocess .run (cmd ,stdout = subprocess .PIPE ) 45assert (res .returncode == 0 ) 46source = res .stdout .decode () 47ffi = cffi .FFI () 48if True :# workarounds for pycparser 49source = "typedef struct { } __builtin_va_list;" + "\n" + source 50source = source .replace ("sizeof (int)" ,str (ffi .sizeof ("int" ))) 51source = source .replace ("sizeof (void *)" ,str (ffi .sizeof ("void*" ))) 52source = source .replace ("sizeof (size_t)" ,str (ffi .sizeof ("size_t" ))) 53source = source .replace ("sizeof(int32_t)" ,str (ffi .sizeof ("int32_t" ))) 54ffi .cdef (source ,override = True ) 55lib = ffi .dlopen (path_libllama ) 56return (ffi ,lib ) 57 58def model_default_params (self ,** kwargs ): 59mparams = self .lib .llama_model_default_params () 60for k ,v in kwargs .items (): 61setattr (mparams ,k ,v ) 62return mparams 63 64def context_default_params (self ,** kwargs ): 65cparams = self .lib .llama_context_default_params () 66for k ,v in kwargs .items (): 67setattr (cparams ,k ,v ) 68return cparams 69 70 71class LibLlamaModel : 72 73def __init__ (self ,libllama :LibLlama ,path_model :str ,mparams = {},cparams = {}): 74self .lib :Any = libllama .lib 75self .ffi = libllama .ffi 76if isinstance (mparams ,dict ): 77mparams = libllama .model_default_params (** mparams ) 78self .model = self .lib .llama_model_load_from_file (path_model .encode (),mparams ) 79if not self .model : 80raise RuntimeError ("error: failed to load model '%s'" % path_model ) 81if isinstance (cparams ,dict ): 82cparams = libllama .context_default_params (** cparams ) 83self .ctx = self .lib .llama_new_context_with_model (self .model ,cparams ) 84if not self .ctx : 85raise RuntimeError ("error: failed to create context for model '%s'" % path_model ) 86n_tokens_max = self .lib .llama_n_ctx (self .ctx ) 87self .token_ids = self .ffi .new ("llama_token[]" ,n_tokens_max ) 88self .text_buff = self .ffi .new ("uint8_t[]" ,1024 ) 89 90def free (self ): 91if self .ctx : 92self .lib .llama_free (self .ctx ) 93if self .model : 94self .lib .llama_model_free (self .model ) 95self .ctx = None 96self .model = None 97self .lib = None 98 99def tokenize (self ,text :str ,add_special :bool = False ,parse_special :bool = False )-> list [int ]: 100encoded_text :bytes = text .encode ("utf-8" ) 101num = self .lib .llama_tokenize (self .model ,encoded_text ,len (encoded_text ),self .token_ids ,len (self .token_ids ),add_special ,parse_special ) 102while num < 0 and len (self .token_ids )< (16 << 20 ): 103self .token_ids = self .ffi .new ("llama_token[]" ,- 2 * num ) 104num = self .lib .llama_tokenize (self .model ,encoded_text ,len (encoded_text ),self .token_ids ,len (self .token_ids ),add_special ,parse_special ) 105return list (self .token_ids [0 :num ]) 106 107def detokenize (self ,ids :list [int ],remove_special :bool = False ,unparse_special :bool = False )-> str : 108if len (self .token_ids )< len (ids ): 109self .token_ids = self .ffi .new ("llama_token[]" ,2 * len (ids )) 110for i ,id in enumerate (ids ): 111self .token_ids [i ]= id 112num = self .lib .llama_detokenize (self .model ,self .token_ids ,len (ids ),self .text_buff ,len (self .text_buff ),remove_special ,unparse_special ) 113while num < 0 and len (self .text_buff )< (16 << 20 ): 114self .text_buff = self .ffi .new ("uint8_t[]" ,- 2 * num ) 115num = self .lib .llama_detokenize (self .model ,self .token_ids ,len (ids ),self .text_buff ,len (self .text_buff ),remove_special ,unparse_special ) 116return str (self .ffi .buffer (self .text_buff ,num ),encoding = "utf-8" ,errors = "replace" )# replace errors with '\uFFFD' # pyright: ignore[reportArgumentType] 117 118 119class Tokenizer : 120 121def encode (self ,text :str )-> list [int ]: 122raise NotImplementedError 123 124def decode (self ,ids :list [int ])-> str : 125raise NotImplementedError 126 127 128class TokenizerGroundtruth (Tokenizer ): 129 130def __init__ (self ,dir_tokenizer :str ): 131self .model :PreTrainedTokenizer = AutoTokenizer .from_pretrained (dir_tokenizer )# ty: ignore[invalid-assignment] 132# guess BOS and EOS 133ids = self .encode ("a" ) 134assert 1 <= len (ids )<= 3 135add_bos_token = len (ids )> 1 and self .model .bos_token_id == ids [0 ] 136add_eos_token = len (ids )> 1 and self .model .eos_token_id == ids [- 1 ] 137self .add_bos_token = getattr (self .model ,"add_bos_token" ,add_bos_token ) 138self .add_eos_token = getattr (self .model ,"add_eos_token" ,add_eos_token ) 139# build vocab 140tokens = list (self .model .get_vocab ().values ()) 141self .vocab = self .model .batch_decode (tokens ,skip_special_tokens = True ) 142self .vocab = list (sorted (self .vocab )) 143# tokens and lists 144self .special_tokens = list (self .model .all_special_tokens ) 145self .added_tokens = self .model .batch_decode (list (self .model .added_tokens_encoder .values ()),skip_special_tokens = False ) 146self .bos_token = self .model .bos_token 147self .eos_token = self .model .eos_token 148 149def encode (self ,text :str )-> list [int ]: 150return self .model .encode (text ,add_special_tokens = True ) 151 152def decode (self ,ids :list [int ])-> str : 153return self .model .decode (ids ,skip_special_tokens = False )# ty: ignore[invalid-return-type] 154 155 156class TokenizerLlamaCpp (Tokenizer ): 157 158libllama :LibLlama | None = None 159 160def __init__ (self ,vocab_file :str ): 161if not self .libllama : 162self .libllama = LibLlama () 163self .model = LibLlamaModel (self .libllama ,vocab_file ,mparams = dict (vocab_only = True ),cparams = dict (n_ctx = 4096 )) 164 165def encode (self ,text :str )-> list [int ]: 166return self .model .tokenize (text ,add_special = True ,parse_special = True ) 167 168def decode (self ,ids :list [int ])-> str : 169return self .model .detokenize (ids ,remove_special = False ,unparse_special = True ) 170 171 172def generator_custom_text ()-> Iterator [str ]: 173"""General tests""" 174yield from [ 175"" , 176" " , 177" " , 178" " , 179"\t" , 180"\n" , 181"\n\n" , 182"\n\n\n" , 183"\t\n" , 184"Hello world" , 185" Hello world" , 186"Hello World" , 187" Hello World" , 188" Hello World!" , 189"Hello, world!" , 190" Hello, world!" , 191" this is 🦙.cpp" , 192"w048 7tuijk dsdfhu" , 193"нещо на Български" , 194"កាន់តែពិសេសអាចខលចេញ" , 195"🚀 (normal) 😶🌫️ (multiple emojis concatenated) ✅ (only emoji that has its own token)" , 196"Hello" , 197" Hello" , 198" Hello" , 199" Hello" , 200" Hello" , 201" Hello\n Hello" , 202" (" , 203"\n =" , 204"' era" , 205"Hello, y'all! How are you 😁 ?我想在apple工作1314151天~" , 206"3" , 207"33" , 208"333" , 209"3333" , 210"33333" , 211"333333" , 212"3333333" , 213"33333333" , 214"333333333" , 215 ] 216 217 218def generator_custom_text_edge_cases ()-> Iterator [str ]: 219"""Edge cases found while debugging""" 220yield from [ 221'\x1f-a' ,# unicode_ranges_control, {0x00001C, 0x00001F} 222'¼-a' ,# unicode_ranges_digit, 0x00BC 223'½-a' ,# unicode_ranges_digit, 0x00BD 224'¾-a' ,# unicode_ranges_digit, 0x00BE 225'a 〇b' ,# unicode_ranges_digit, 0x3007 226'Ⅵ-a' ,# unicode_ranges_digit, {0x00002150, 0x0000218F} // Number Forms 227'\uFEFF//' ,# unicode_ranges_control, 0xFEFF (BOM) 228'Cửa Việt' ,# llama-3, ignore_merges = true 229'<s>a' ,# Phi-3 fail 230'<unk><|endoftext|><s>' ,# Phi-3 fail 231'a\na' ,# bert fail 232'"`' ,# falcon 233' \u2e4e' ,# falcon 234'\n\x0b ' ,# falcon 235'a\xa0\xa0\x00b' ,# jina-v2-es 236'one <mask>' ,# jina-v2-es <mask> lstrip=true 237'a </s> b' ,# rstrip phi-3 238'a <mask> b' ,# lstrip jina-v2 239'\xa0aC' ,# deepseek 240'\u2029 \uA3E4' ,# deepseek-llm 241"a ?" , 242'å' ,# mpt 243'\U000ac517' ,# utf-8 encode error, falcon 244'\U000522f4' ,# utf-8 encode error, starcoder 245"<s><s><unk><s>a<s>b<s>c<unk>d<unk></s>" , 246"<s> <s> <unk><s>a<s>b<s>c<unk>d<unk></s>" , 247 ] 248 249 250def generator_vocab_words (tokenizer :TokenizerGroundtruth )-> Iterator [str ]: 251"""Brute force check all vocab words""" 252yield from tokenizer .vocab 253 254 255def generator_ascii_lr_strip ()-> Iterator [str ]: 256WHITESPACES = ["" ," " ," " ] 257CHARACTERS = list (chr (i )for i in range (1 ,0x80 ))+ ["" ] 258for char1 in CHARACTERS : 259for char2 in CHARACTERS : 260for lstrip in WHITESPACES : 261for rstrip in WHITESPACES : 262yield lstrip + char1 + char2 + rstrip 263yield lstrip + char1 + rstrip + char2 264yield char1 + lstrip + char2 + rstrip 265 266 267def generator_apostrophe ()-> Iterator [str ]: 268WHITESPACES = ["" ," " ," " ] 269CHARACTERS = list (chr (i )for i in range (1 ,0x80 ))+ ["" ] 270for char1 in CHARACTERS : 271for char2 in CHARACTERS : 272for lstrip in WHITESPACES : 273for rstrip in WHITESPACES : 274yield char1 + lstrip + "'" + rstrip + char2 275yield char1 + char2 + lstrip + "'" + rstrip + "z" 276yield "a" + lstrip + "'" + rstrip + char1 + char2 277 278 279def generator_added_lr_strip (tokenizer :TokenizerGroundtruth )-> Iterator [str ]: 280WHITESPACES = ["" ," " ," " ,"\n" ,"\r\n" ,"\n\n" ,"\t" ,"\t\t" ] 281all_tokens = list (sorted (set (tokenizer .special_tokens + tokenizer .added_tokens ))) 282for token in all_tokens : 283for lstrip in WHITESPACES : 284for rstrip in WHITESPACES : 285yield lstrip + token + rstrip 286yield "a" + lstrip + token + rstrip 287yield lstrip + token + rstrip + "z" 288yield "a" + lstrip + token + rstrip + "z" 289 290 291def generator_random_added_tokens (tokenizer :TokenizerGroundtruth ,iterations = 100 )-> Iterator [str ]: 292separations = [" " ,"\n" ,"\t" ,"-" ,"!" ,"one" ,"1" ,"<s>" ,"</s>" ] 293all_tokens = list (sorted (set (tokenizer .special_tokens + tokenizer .added_tokens + separations ))) 294rand = random .Random () 295for m in range (iterations ): 296rand .seed (m ) 297words = rand .choices (all_tokens ,k = 500 ) 298if words and words [0 ]== tokenizer .bos_token :# skip spam warning of double BOS 299while len (words )> 1 and words [1 ]== tokenizer .bos_token :# leave one starting BOS 300words .pop (0 ) 301if tokenizer .add_bos_token :# drop all starting BOS 302words .pop (0 ) 303if words and words [- 1 ]== tokenizer .eos_token :# skip spam warning of double EOS 304while len (words )> 1 and words [- 2 ]== tokenizer .eos_token :# leave one trailing EOS 305words .pop (- 1 ) 306if tokenizer .add_bos_token :# drop all trailing EOS 307words .pop (- 1 ) 308yield "" .join (words ) 309 310 311def generator_random_chars (iterations = 100 )-> Iterator [str ]: 312"""Brute force random text with simple characters""" 313 314NUM_WORDS = 400 315WHITESPACES = list (" " * 20 + "\n" * 5 + "\r\n" * 5 + "\t" * 5 ) 316CHARS = list (sorted (set (""" 317ABCDEFGHIJKLMNOPQRSTUVWXYZ 318abcdefghijklmnopqrstuvwxyz 319ÁÉÍÓÚÀÈÌÒÙÂÊÎÔÛÄËÏÖÜ 320áéíóúàèìòùâêîôûäëïöü 321.-,*/-+ª!"·$%&/()=?¿[]{}<>\\|@#~½¬~;:_ 322""" ))) 323 324rand = random .Random () 325for m in range (iterations ): 326rand .seed (m ) 327text = [] 328for _ in range (NUM_WORDS ): 329k = rand .randint (1 ,7 ) 330word = rand .choices (CHARS ,k = k ) 331word .append (rand .choice (WHITESPACES )) 332text .append ("" .join (word )) 333yield "" .join (text ) 334 335 336def generator_unicodes ()-> Iterator [str ]: 337"""Iterate unicode characters""" 338 339MAX_CODEPOINTS = 0x30000 # 0x110000 340 341def _valid (cpt ): 342if cpt >= 0x30000 :# unassigned and supplementary 343return False 344# if cpt == 0x2029: # deepseek-llm 345# return False 346if unicodedata .category (chr (cpt ))in ("Cn" ,"Cs" ,"Co" ):# undefined, surrogates, private 347return False 348return True 349 350characters = [chr (cpt )for cpt in range (0 ,MAX_CODEPOINTS )if _valid (cpt )] 351 352yield from characters 353 354 355def generator_random_unicodes (iterations = 100 )-> Iterator [str ]: 356"""Brute force random text with unicode characters""" 357 358NUM_WORDS = 200 359WHITESPACES = list (" " * 20 + "\n" * 5 + "\r\n" * 5 + "\t" * 5 ) 360 361characters = list (generator_unicodes ()) 362 363rand = random .Random () 364for m in range (iterations ): 365rand .seed (m ) 366text = [] 367for _ in range (NUM_WORDS ): 368k = rand .randint (1 ,7 ) 369word = rand .choices (characters ,k = k ) 370word .append (rand .choice (WHITESPACES )) 371text .append ("" .join (word )) 372yield "" .join (text ) 373 374 375def generator_random_vocab_chars (tokenizer :TokenizerGroundtruth ,iterations = 100 )-> Iterator [str ]: 376"""Brute force random text with vocab characters""" 377 378vocab_chars = set () 379for word in tokenizer .vocab : 380vocab_chars .update (word ) 381vocab_chars = list (sorted (vocab_chars )) 382 383rand = random .Random () 384for m in range (iterations ): 385rand .seed (m ) 386text = rand .choices (vocab_chars ,k = 1024 ) 387yield "" .join (text ) 388 389 390def generator_random_vocab_words (tokenizer :TokenizerGroundtruth ,iterations = 100 )-> Iterator [str ]: 391"""Brute force random text from vocab words""" 392 393vocab = [w .strip ()for w in tokenizer .vocab ] 394yield from vocab 395 396rand = random .Random () 397for m in range (iterations ): 398rand .seed (m ) 399text = [] 400num_words = rand .randint (300 ,400 ) 401for i in range (num_words ): 402k = rand .randint (1 ,3 ) 403words = rand .choices (vocab ,k = k ) 404sep = rand .choice (" \n\r\t" ) 405text .append ("" .join (words )+ sep ) 406yield "" .join (text ) 407 408 409def compare_tokenizers (tokenizer1 :TokenizerGroundtruth ,tokenizer2 :TokenizerLlamaCpp ,generator :Iterator [str ]): 410 411def find_first_mismatch (ids1 :list [int ]| str ,ids2 :list [int ]| str ): 412for i , (a ,b )in enumerate (zip (ids1 ,ids2 )): 413if a != b : 414return i 415if len (ids1 )== len (ids2 ): 416return - 1 417return min (len (ids1 ),len (ids2 )) 418 419def check_detokenizer (text :str ,text1 :str ,text2 :str )-> bool : 420if text1 == text2 :# equal to TokenizerGroundtruth? 421return True 422# equal to source text? 423if tokenizer1 .add_bos_token and tokenizer1 .bos_token and isinstance (tokenizer1 .bos_token ,str ):# remove BOS 424if text2 .startswith (tokenizer1 .bos_token ): 425text2 = text2 [len (tokenizer1 .bos_token ):] 426if tokenizer1 .add_eos_token and tokenizer1 .eos_token and isinstance (tokenizer1 .eos_token ,str ):# remove EOS 427if text2 .endswith (tokenizer1 .eos_token ): 428text2 = text2 [:- len (tokenizer1 .eos_token )] 429return text == text2 430 431t_encode1 = 0 432t_encode2 = 0 433t_decode1 = 0 434t_decode2 = 0 435t_start = time .perf_counter () 436encode_errors = 0 437decode_errors = 0 438MAX_ERRORS = 10 439 440logger .info ("%s: %s" % (getattr (generator ,"__qualname__" ,"" ),"ini" )) 441for text in generator : 442# print(repr(text), text.encode()) 443# print(repr(text), hex(ord(text[0])), text.encode()) 444t0 = time .perf_counter () 445ids1 = tokenizer1 .encode (text ) 446t1 = time .perf_counter () 447ids2 = tokenizer2 .encode (text ) 448t2 = time .perf_counter () 449text1 = tokenizer1 .decode (ids1 ) 450t3 = time .perf_counter () 451text2 = tokenizer2 .decode (ids1 ) 452t4 = time .perf_counter () 453t_encode1 += t1 - t0 454t_encode2 += t2 - t1 455t_decode1 += t3 - t2 456t_decode2 += t4 - t3 457if encode_errors < MAX_ERRORS and ids1 != ids2 : 458i = find_first_mismatch (ids1 ,ids2 ) 459ids1 = list (ids1 )[max (0 ,i - 2 ) :i + 5 + 1 ] 460ids2 = list (ids2 )[max (0 ,i - 2 ) :i + 5 + 1 ] 461logger .error (" Expected: " + str (ids1 )) 462logger .error (" Result: " + str (ids2 )) 463encode_errors += 1 464logger .error (f" { encode_errors = } " ) 465if decode_errors < MAX_ERRORS and not check_detokenizer (text ,text1 ,text2 ): 466i = find_first_mismatch (text1 ,text2 ) 467text1 = list (text1 [max (0 ,i - 2 ) :i + 5 + 1 ]) 468text2 = list (text2 [max (0 ,i - 2 ) :i + 5 + 1 ]) 469logger .error (" Expected: " + " " .join (hex (ord (x ))for x in text1 )) 470logger .error (" Result: " + " " .join (hex (ord (x ))for x in text2 )) 471decode_errors += 1 472logger .error (f" { decode_errors = } " ) 473if encode_errors >= MAX_ERRORS and decode_errors >= MAX_ERRORS : 474logger .error (f" EXIT: { encode_errors = } { decode_errors = } " ) 475# raise Exception() 476break 477 478t_total = time .perf_counter ()- t_start 479logger .info (f" { getattr ( generator , '__qualname__' , '' ) } : end, { t_encode1 = :.3f } { t_encode2 = :.3f } { t_decode1 = :.3f } { t_decode2 = :.3f } { t_total = :.3f } " ) 480 481 482def main (argv :list [str ]| None = None ): 483parser = argparse .ArgumentParser () 484parser .add_argument ("vocab_file" ,type = str ,help = "path to vocab 'gguf' file" ) 485parser .add_argument ("dir_tokenizer" ,type = str ,help = "directory containing 'tokenizer.model' file" ) 486parser .add_argument ("--verbose" ,action = "store_true" ,help = "increase output verbosity" ) 487args = parser .parse_args (argv ) 488 489logging .basicConfig (level = logging .DEBUG if args .verbose else logging .INFO ) 490logger .info (f"VOCABFILE: ' { args . vocab_file } '" ) 491 492tokenizer1 = TokenizerGroundtruth (args .dir_tokenizer ) 493tokenizer2 = TokenizerLlamaCpp (args .vocab_file ) 494 495# compare_tokenizers(tokenizer1, tokenizer2, generator_custom_text()) 496# compare_tokenizers(tokenizer1, tokenizer2, generator_custom_text_edge_cases()) 497compare_tokenizers (tokenizer1 ,tokenizer2 ,generator_ascii_lr_strip ()) 498compare_tokenizers (tokenizer1 ,tokenizer2 ,generator_apostrophe ()) 499compare_tokenizers (tokenizer1 ,tokenizer2 ,generator_unicodes ()) 500compare_tokenizers (tokenizer1 ,tokenizer2 ,generator_vocab_words (tokenizer1 )) 501compare_tokenizers (tokenizer1 ,tokenizer2 ,generator_added_lr_strip (tokenizer1 )) 502# compare_tokenizers(tokenizer1, tokenizer2, generator_random_added_tokens(tokenizer1, 10_000)) 503# compare_tokenizers(tokenizer1, tokenizer2, generator_random_chars(10_000)) 504# compare_tokenizers(tokenizer1, tokenizer2, generator_random_unicodes(10_000)) 505# compare_tokenizers(tokenizer1, tokenizer2, generator_random_vocab_chars(tokenizer1, 10_000)) 506# compare_tokenizers(tokenizer1, tokenizer2, generator_random_vocab_words(tokenizer1, 5_000)) 507 508tokenizer2 .model .free () 509 510 511if __name__ == "__main__" : 512# main() 513 514if True : 515logging .basicConfig ( 516level = logging .DEBUG , 517format = "%(asctime)s.%(msecs)03d %(name)s %(levelname)s %(message)s" , 518datefmt = "%Y-%m-%d %H:%M:%S" , 519filename = logger .name + ".log" , 520filemode = "a" 521 ) 522logging .basicConfig ( 523level = logging .DEBUG , 524format = "%(levelname)s %(message)s" , 525 ) 526 527path_tokenizers = Path ("./models/tokenizers/" ) 528path_vocab_format = "./models/ggml-vocab-%s.gguf" 529 530tokenizers = [ 531"llama-spm" ,# SPM 532"phi-3" ,# SPM 533"gemma" ,# SPM 534"gemma-2" ,# SPM 535"baichuan" ,# SPM 536"bert-bge" ,# WPM 537"jina-v2-en" ,# WPM 538"llama-bpe" ,# BPE 539"phi-2" ,# BPE 540"deepseek-llm" ,# BPE 541"deepseek-coder" ,# BPE 542"falcon" ,# BPE 543"mpt" ,# BPE 544"starcoder" ,# BPE 545"gpt-2" ,# BPE 546"stablelm2" ,# BPE 547"refact" ,# BPE 548"qwen2" ,# BPE 549"olmo" ,# BPE 550"jina-v2-es" ,# BPE 551"jina-v2-de" ,# BPE 552"smaug-bpe" ,# BPE 553"poro-chat" ,# BPE 554"jina-v2-code" ,# BPE 555"viking" ,# BPE 556"jais" ,# BPE 557 ] 558 559logger .info ("=" * 50 ) 560for tokenizer in tokenizers : 561logger .info ("-" * 50 ) 562logger .info (f"TOKENIZER: ' { tokenizer } '" ) 563vocab_file = Path (path_vocab_format % tokenizer ) 564dir_tokenizer = path_tokenizers / tokenizer 565main ([str (vocab_file ),str (dir_tokenizer ),"--verbose" ])