Fix logit bias for DeepSeek on OpenRouter
| @@ -37,6 +37,8 @@ import { | |||
| 37 | getTiktokenTokenizer, | 37 | getTiktokenTokenizer, |
| 38 | sentencepieceTokenizers, | 38 | sentencepieceTokenizers, |
| 39 | TEXT_COMPLETION_MODELS, | 39 | TEXT_COMPLETION_MODELS, |
| 40 | webTokenizers, | ||
| 41 | getWebTokenizer, | ||
| 40 | } from '../tokenizers.js'; | 42 | } from '../tokenizers.js'; |
| 41 | 43 | ||
| 42 | const API_OPENAI = 'https://api.openai.com/v1'; | 44 | const API_OPENAI = 'https://api.openai.com/v1'; |
| @@ -863,6 +865,14 @@ router.post('/bias', jsonParser, async function (request, response) { | |||
| 863 | return response.send({}); | 865 | return response.send({}); |
| 864 | } | 866 | } |
| 865 | encodeFunction = (text) => new Uint32Array(instance.encodeIds(text)); | 867 | encodeFunction = (text) => new Uint32Array(instance.encodeIds(text)); |
| 868 | } else if (webTokenizers.includes(model)) { | ||
| 869 | const tokenizer = getWebTokenizer(model); | ||
| 870 | const instance = await tokenizer?.get(); | ||
| 871 | if (!instance) { | ||
| 872 | console.warn('Tokenizer not initialized:', model); | ||
| 873 | return response.send({}); | ||
| 874 | } | ||
| 875 | encodeFunction = (text) => new Uint32Array(instance.encode(text)); | ||
| 866 | } else { | 876 | } else { |
| 867 | const tokenizer = getTiktokenTokenizer(model); | 877 | const tokenizer = getTiktokenTokenizer(model); |
| 868 | encodeFunction = (tokenizer.encode.bind(tokenizer)); | 878 | encodeFunction = (tokenizer.encode.bind(tokenizer)); |
| @@ -238,6 +238,15 @@ export const sentencepieceTokenizers = [ | |||
| 238 | 'jamba', | 238 | 'jamba', |
| 239 | ]; | 239 | ]; |
| 240 | 240 | ||
| 241 | export const webTokenizers = [ | ||
| 242 | 'claude', | ||
| 243 | 'llama3', | ||
| 244 | 'command-r', | ||
| 245 | 'qwen2', | ||
| 246 | 'nemo', | ||
| 247 | 'deepseek', | ||
| 248 | ]; | ||
| 249 | |||
| 241 | /** | 250 | /** |
| 242 | * Gets the Sentencepiece tokenizer by the model name. | 251 | * Gets the Sentencepiece tokenizer by the model name. |
| 243 | * @param {string} model Sentencepiece model name | 252 | * @param {string} model Sentencepiece model name |
| @@ -276,6 +285,39 @@ export function getSentencepiceTokenizer(model) { | |||
| 276 | } | 285 | } |
| 277 | 286 | ||
| 278 | /** | 287 | /** |
| 288 | * Gets the Web tokenizer by the model name. | ||
| 289 | * @param {string} model Web tokenizer model name | ||
| 290 | * @returns {WebTokenizer|null} Web tokenizer | ||
| 291 | */ | ||
| 292 | export function getWebTokenizer(model) { | ||
| 293 | if (model.includes('llama3')) { | ||
| 294 | return llama3_tokenizer; | ||
| 295 | } | ||
| 296 | |||
| 297 | if (model.includes('claude')) { | ||
| 298 | return claude_tokenizer; | ||
| 299 | } | ||
| 300 | |||
| 301 | if (model.includes('command-r')) { | ||
| 302 | return commandTokenizer; | ||
| 303 | } | ||
| 304 | |||
| 305 | if (model.includes('qwen2')) { | ||
| 306 | return qwen2Tokenizer; | ||
| 307 | } | ||
| 308 | |||
| 309 | if (model.includes('nemo')) { | ||
| 310 | return nemoTokenizer; | ||
| 311 | } | ||
| 312 | |||
| 313 | if (model.includes('deepseek')) { | ||
| 314 | return deepseekTokenizer; | ||
| 315 | } | ||
| 316 | |||
| 317 | return null; | ||
| 318 | } | ||
| 319 | |||
| 320 | /** | ||
| 279 | * Counts the token ids for the given text using the Sentencepiece tokenizer. | 321 | * Counts the token ids for the given text using the Sentencepiece tokenizer. |
| 280 | * @param {SentencePieceTokenizer} tokenizer Sentencepiece tokenizer | 322 | * @param {SentencePieceTokenizer} tokenizer Sentencepiece tokenizer |
| 281 | * @param {string} text Text to tokenize | 323 | * @param {string} text Text to tokenize |