Add tokenizer for Gemma/Gemini
| @@ -3449,6 +3449,7 @@ | ||
| 3449 | 3449 | <!-- Option #2 was a legacy GPT-2/3 tokenizer --> |
| 3450 | 3450 | <option value="3">Llama 1/2</option> |
| 3451 | 3451 | <option value="12">Llama 3</option> |
| 3452 | + <option value="13">Gemma / Gemini</option> | |
| 3452 | 3453 | <option value="4">NerdStash (NovelAI Clio)</option> |
| 3453 | 3454 | <option value="5">NerdStash v2 (NovelAI Kayra)</option> |
| 3454 | 3455 | <option value="7">Mistral</option> |
| @@ -599,6 +599,10 @@ export function getCurrentOpenRouterModelTokenizer() { | ||
| 599 | 599 | return tokenizers.YI; |
| 600 | 600 | case 'Mistral': |
| 601 | 601 | return tokenizers.MISTRAL; |
| 602 | + case 'Gemini': | |
| 603 | + return tokenizers.GEMMA; | |
| 604 | + case 'Claude': | |
| 605 | + return tokenizers.CLAUDE; | |
| 602 | 606 | default: |
| 603 | 607 | return tokenizers.OPENAI; |
| 604 | 608 | } |
| @@ -26,6 +26,7 @@ export const tokenizers = { | ||
| 26 | 26 | API_KOBOLD: 10, |
| 27 | 27 | CLAUDE: 11, |
| 28 | 28 | LLAMA3: 12, |
| 29 | + GEMMA: 13, | |
| 29 | 30 | BEST_MATCH: 99, |
| 30 | 31 | }; |
| 31 | 32 | |
| @@ -34,6 +35,7 @@ export const SENTENCEPIECE_TOKENIZERS = [ | ||
| 34 | 35 | tokenizers.MISTRAL, |
| 35 | 36 | tokenizers.YI, |
| 36 | 37 | tokenizers.LLAMA3, |
| 38 | + tokenizers.GEMMA, | |
| 37 | 39 | // uncomment when NovelAI releases Kayra and Clio weights, lol |
| 38 | 40 | //tokenizers.NERD, |
| 39 | 41 | //tokenizers.NERD2, |
| @@ -91,6 +93,11 @@ const TOKENIZER_URLS = { | ||
| 91 | 93 | decode: '/api/tokenizers/llama3/decode', |
| 92 | 94 | count: '/api/tokenizers/llama3/encode', |
| 93 | 95 | }, |
| 96 | + [tokenizers.GEMMA]: { | |
| 97 | + encode: '/api/tokenizers/gemma/encode', | |
| 98 | + decode: '/api/tokenizers/gemma/decode', | |
| 99 | + count: '/api/tokenizers/gemma/encode', | |
| 100 | + }, | |
| 94 | 101 | [tokenizers.API_TEXTGENERATIONWEBUI]: { |
| 95 | 102 | encode: '/api/tokenizers/remote/textgenerationwebui/encode', |
| 96 | 103 | count: '/api/tokenizers/remote/textgenerationwebui/encode', |
| @@ -232,6 +239,9 @@ export function getTokenizerBestMatch(forApi) { | ||
| 232 | 239 | if (model.includes('mistral') || model.includes('mixtral')) { |
| 233 | 240 | return tokenizers.MISTRAL; |
| 234 | 241 | } |
| 242 | + if (model.includes('gemma')) { | |
| 243 | + return tokenizers.GEMMA; | |
| 244 | + } | |
| 235 | 245 | } |
| 236 | 246 | |
| 237 | 247 | return tokenizers.LLAMA; |
| @@ -441,12 +451,14 @@ export function getTokenizerModel() { | ||
| 441 | 451 | const turbo0301Tokenizer = 'gpt-3.5-turbo-0301'; |
| 442 | 452 | const turboTokenizer = 'gpt-3.5-turbo'; |
| 443 | 453 | const gpt4Tokenizer = 'gpt-4'; |
| 454 | + const gpt4oTokenizer = 'gpt-4o'; | |
| 444 | 455 | const gpt2Tokenizer = 'gpt2'; |
| 445 | 456 | const claudeTokenizer = 'claude'; |
| 446 | 457 | const llamaTokenizer = 'llama'; |
| 447 | 458 | const llama3Tokenizer = 'llama3'; |
| 448 | 459 | const mistralTokenizer = 'mistral'; |
| 449 | 460 | const yiTokenizer = 'yi'; |
| 461 | + const gemmaTokenizer = 'gemma'; | |
| 450 | 462 | |
| 451 | 463 | // Assuming no one would use it for different models.. right? |
| 452 | 464 | if (oai_settings.chat_completion_source == chat_completion_sources.SCALE) { |
| @@ -491,6 +503,12 @@ export function getTokenizerModel() { | ||
| 491 | 503 | else if (model?.architecture?.tokenizer === 'Yi') { |
| 492 | 504 | return yiTokenizer; |
| 493 | 505 | } |
| 506 | + else if (model?.architecture?.tokenizer === 'Gemini') { | |
| 507 | + return gemmaTokenizer; | |
| 508 | + } | |
| 509 | + else if (oai_settings.openrouter_model.includes('gpt-4o')) { | |
| 510 | + return gpt4oTokenizer; | |
| 511 | + } | |
| 494 | 512 | else if (oai_settings.openrouter_model.includes('gpt-4')) { |
| 495 | 513 | return gpt4Tokenizer; |
| 496 | 514 | } |
| @@ -509,7 +527,7 @@ export function getTokenizerModel() { | ||
| 509 | 527 | } |
| 510 | 528 | |
| 511 | 529 | if (oai_settings.chat_completion_source == chat_completion_sources.MAKERSUITE) { |
| 512 | 530 | return oai_settings.google_modelgemmaTokenizer; |
| 513 | 531 | } |
| 514 | 532 | |
| 515 | 533 | if (oai_settings.chat_completion_source == chat_completion_sources.CLAUDE) { |
| @@ -543,6 +561,9 @@ export function getTokenizerModel() { | ||
| 543 | 561 | if (oai_settings.groq_model.includes('mistral') || oai_settings.groq_model.includes('mixtral')) { |
| 544 | 562 | return mistralTokenizer; |
| 545 | 563 | } |
| 564 | + if (oai_settings.groq_model.includes('gemma')) { | |
| 565 | + return gemmaTokenizer; | |
| 566 | + } | |
| 546 | 567 | } |
| 547 | 568 | |
| 548 | 569 | if (oai_settings.chat_completion_source === chat_completion_sources.ZEROONEAI) { |
| @@ -143,6 +143,7 @@ const spp_nerd = new SentencePieceTokenizer('src/tokenizers/nerdstash.model'); | ||
| 143 | 143 | const spp_nerd_v2 = new SentencePieceTokenizer('src/tokenizers/nerdstash_v2.model'); |
| 144 | 144 | const spp_mistral = new SentencePieceTokenizer('src/tokenizers/mistral.model'); |
| 145 | 145 | const spp_yi = new SentencePieceTokenizer('src/tokenizers/yi.model'); |
| 146 | +const spp_gemma = new SentencePieceTokenizer('src/tokenizers/gemma.model'); | |
| 146 | 147 | const claude_tokenizer = new WebTokenizer('src/tokenizers/claude.json'); |
| 147 | 148 | const llama3_tokenizer = new WebTokenizer('src/tokenizers/llama3.json'); |
| 148 | 149 | |
| @@ -152,6 +153,7 @@ const sentencepieceTokenizers = [ | ||
| 152 | 153 | 'nerdstash_v2', |
| 153 | 154 | 'mistral', |
| 154 | 155 | 'yi', |
| 156 | + 'gemma', | |
| 155 | 157 | ]; |
| 156 | 158 | |
| 157 | 159 | /** |
| @@ -180,6 +182,10 @@ function getSentencepiceTokenizer(model) { | ||
| 180 | 182 | return spp_yi; |
| 181 | 183 | } |
| 182 | 184 | |
| 185 | + if (model.includes('gemma')) { | |
| 186 | + return spp_gemma; | |
| 187 | + } | |
| 188 | + | |
| 183 | 189 | return null; |
| 184 | 190 | } |
| 185 | 191 | |
| @@ -312,8 +318,8 @@ function getTokenizerModel(requestModel) { | ||
| 312 | 318 | return 'yi'; |
| 313 | 319 | } |
| 314 | 320 | |
| 315 | 321 | if (requestModel.includes('gemma') || requestModel.includes('gemini')) { |
| 316 | 322 | return 'gpt-4ogemma'; |
| 317 | 323 | } |
| 318 | 324 | |
| 319 | 325 | // default |
| @@ -583,6 +589,7 @@ router.post('/nerdstash/encode', jsonParser, createSentencepieceEncodingHandler( | ||
| 583 | 589 | router.post('/nerdstash_v2/encode', jsonParser, createSentencepieceEncodingHandler(spp_nerd_v2)); |
| 584 | 590 | router.post('/mistral/encode', jsonParser, createSentencepieceEncodingHandler(spp_mistral)); |
| 585 | 591 | router.post('/yi/encode', jsonParser, createSentencepieceEncodingHandler(spp_yi)); |
| 592 | +router.post('/gemma/encode', jsonParser, createSentencepieceEncodingHandler(spp_gemma)); | |
| 586 | 593 | router.post('/gpt2/encode', jsonParser, createTiktokenEncodingHandler('gpt2')); |
| 587 | 594 | router.post('/claude/encode', jsonParser, createWebTokenizerEncodingHandler(claude_tokenizer)); |
| 588 | 595 | router.post('/llama3/encode', jsonParser, createWebTokenizerEncodingHandler(llama3_tokenizer)); |
| @@ -591,6 +598,7 @@ router.post('/nerdstash/decode', jsonParser, createSentencepieceDecodingHandler( | ||
| 591 | 598 | router.post('/nerdstash_v2/decode', jsonParser, createSentencepieceDecodingHandler(spp_nerd_v2)); |
| 592 | 599 | router.post('/mistral/decode', jsonParser, createSentencepieceDecodingHandler(spp_mistral)); |
| 593 | 600 | router.post('/yi/decode', jsonParser, createSentencepieceDecodingHandler(spp_yi)); |
| 601 | +router.post('/gemma/decode', jsonParser, createSentencepieceDecodingHandler(spp_gemma)); | |
| 594 | 602 | router.post('/gpt2/decode', jsonParser, createTiktokenDecodingHandler('gpt2')); |
| 595 | 603 | router.post('/claude/decode', jsonParser, createWebTokenizerDecodingHandler(claude_tokenizer)); |
| 596 | 604 | router.post('/llama3/decode', jsonParser, createWebTokenizerDecodingHandler(llama3_tokenizer)); |
| @@ -624,6 +632,11 @@ router.post('/openai/encode', jsonParser, async function (req, res) { | ||
| 624 | 632 | return handler(req, res); |
| 625 | 633 | } |
| 626 | 634 | |
| 635 | + if (queryModel.includes('gemma') || queryModel.includes('gemini')) { | |
| 636 | + const handler = createSentencepieceEncodingHandler(spp_gemma); | |
| 637 | + return handler(req, res); | |
| 638 | + } | |
| 639 | + | |
| 627 | 640 | const model = getTokenizerModel(queryModel); |
| 628 | 641 | const handler = createTiktokenEncodingHandler(model); |
| 629 | 642 | return handler(req, res); |
| @@ -662,6 +675,11 @@ router.post('/openai/decode', jsonParser, async function (req, res) { | ||
| 662 | 675 | return handler(req, res); |
| 663 | 676 | } |
| 664 | 677 | |
| 678 | + if (queryModel.includes('gemma') || queryModel.includes('gemini')) { | |
| 679 | + const handler = createSentencepieceDecodingHandler(spp_gemma); | |
| 680 | + return handler(req, res); | |
| 681 | + } | |
| 682 | + | |
| 665 | 683 | const model = getTokenizerModel(queryModel); |
| 666 | 684 | const handler = createTiktokenDecodingHandler(model); |
| 667 | 685 | return handler(req, res); |
| @@ -708,6 +726,11 @@ router.post('/openai/count', jsonParser, async function (req, res) { | ||
| 708 | 726 | return res.send({ 'token_count': num_tokens }); |
| 709 | 727 | } |
| 710 | 728 | |
| 729 | + if (model === 'gemma' || model === 'gemini') { | |
| 730 | + num_tokens = await countSentencepieceArrayTokens(spp_gemma, req.body); | |
| 731 | + return res.send({ 'token_count': num_tokens }); | |
| 732 | + } | |
| 733 | + | |
| 711 | 734 | const tokensPerName = queryModel.includes('gpt-3.5-turbo-0301') ? -1 : 1; |
| 712 | 735 | const tokensPerMessage = queryModel.includes('gpt-3.5-turbo-0301') ? 4 : 3; |
| 713 | 736 | const tokensPadding = 3; |
Binary file