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 {
3737 getTiktokenTokenizer,
3838 sentencepieceTokenizers,
3939 TEXT_COMPLETION_MODELS,
40+ webTokenizers,
41+ getWebTokenizer,
4042} from '../tokenizers.js';
4143
4244const API_OPENAI = 'https://api.openai.com/v1';
@@ -863,6 +865,14 @@ router.post('/bias', jsonParser, async function (request, response) {
863865 return response.send({});
864866 }
865867 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));
866876 } else {
867877 const tokenizer = getTiktokenTokenizer(model);
868878 encodeFunction = (tokenizer.encode.bind(tokenizer));
src/endpoints/tokenizers.js+42 -0
@@ -238,6 +238,15 @@ export const sentencepieceTokenizers = [
238238 'jamba',
239239];
240240
241+export const webTokenizers = [
242+ 'claude',
243+ 'llama3',
244+ 'command-r',
245+ 'qwen2',
246+ 'nemo',
247+ 'deepseek',
248+];
249+
241250/**
242251 * Gets the Sentencepiece tokenizer by the model name.
243252 * @param {string} model Sentencepiece model name
@@ -276,6 +285,39 @@ export function getSentencepiceTokenizer(model) {
276285}
277286
278287/**
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+/**
279321 * Counts the token ids for the given text using the Sentencepiece tokenizer.
280322 * @param {SentencePieceTokenizer} tokenizer Sentencepiece tokenizer
281323 * @param {string} text Text to tokenize