Fix logit bias for DeepSeek on OpenRouter

96143177ced2bb8c283af0510268f6582599950d

Cohee <18619528+Cohee1207@users.noreply.github.com>

2 files changed, +52 -0Ignore whitespace
src/endpoints/backends/chat-completions.js+10 -0
@@ -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';
4143
42const API_OPENAI = 'https://api.openai.com/v1';44const 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));
src/endpoints/tokenizers.js+42 -0
@@ -238,6 +238,15 @@ export const sentencepieceTokenizers = [
238 'jamba',238 'jamba',
239];239];
240240
241export 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 name252 * @param {string} model Sentencepiece model name
@@ -276,6 +285,39 @@ export function getSentencepiceTokenizer(model) {
276}285}
277286
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 */
292export 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 tokenizer322 * @param {SentencePieceTokenizer} tokenizer Sentencepiece tokenizer
281 * @param {string} text Text to tokenize323 * @param {string} text Text to tokenize