Merge pull request #10373 from dannyl1u/logit_bias

feat: logit bias
This commit is contained in:
Timothy Jaeryang Baek 2025-03-01 06:13:19 -08:00 committed by GitHub
commit 05c5e73304
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 66 additions and 0 deletions

View File

@ -68,6 +68,7 @@ from open_webui.utils.misc import (
get_last_user_message, get_last_user_message,
get_last_assistant_message, get_last_assistant_message,
prepend_to_first_user_message_content, prepend_to_first_user_message_content,
convert_logit_bias_input_to_json
) )
from open_webui.utils.tools import get_tools from open_webui.utils.tools import get_tools
from open_webui.utils.plugin import load_function_module_by_id from open_webui.utils.plugin import load_function_module_by_id
@ -610,6 +611,11 @@ def apply_params_to_form_data(form_data, model):
if "reasoning_effort" in params: if "reasoning_effort" in params:
form_data["reasoning_effort"] = params["reasoning_effort"] form_data["reasoning_effort"] = params["reasoning_effort"]
if "logit_bias" in params:
try:
form_data["logit_bias"] = json.loads(convert_logit_bias_input_to_json(params["logit_bias"]))
except Exception as e:
print(f"Error parsing logit_bias: {e}")
return form_data return form_data

View File

@ -6,6 +6,7 @@ import logging
from datetime import timedelta from datetime import timedelta
from pathlib import Path from pathlib import Path
from typing import Callable, Optional from typing import Callable, Optional
import json
import collections.abc import collections.abc
@ -450,3 +451,14 @@ def parse_ollama_modelfile(model_text):
data["params"]["messages"] = messages data["params"]["messages"] = messages
return data return data
def convert_logit_bias_input_to_json(user_input):
logit_bias_pairs = user_input.split(',')
logit_bias_json = {}
for pair in logit_bias_pairs:
token, bias = pair.split(':')
token = str(token.strip())
bias = int(bias.strip())
bias = 100 if bias > 100 else -100 if bias < -100 else bias
logit_bias_json[token] = bias
return json.dumps(logit_bias_json)

View File

@ -62,6 +62,7 @@ def apply_model_params_to_body_openai(params: dict, form_data: dict) -> dict:
"reasoning_effort": str, "reasoning_effort": str,
"seed": lambda x: x, "seed": lambda x: x,
"stop": lambda x: [bytes(s, "utf-8").decode("unicode_escape") for s in x], "stop": lambda x: [bytes(s, "utf-8").decode("unicode_escape") for s in x],
"logit_bias": lambda x: x,
} }
return apply_model_params_to_body(params, form_data, mappings) return apply_model_params_to_body(params, form_data, mappings)

View File

@ -17,6 +17,7 @@
stop: null, stop: null,
temperature: null, temperature: null,
reasoning_effort: null, reasoning_effort: null,
logit_bias: null,
frequency_penalty: null, frequency_penalty: null,
repeat_last_n: null, repeat_last_n: null,
mirostat: null, mirostat: null,
@ -298,6 +299,49 @@
{/if} {/if}
</div> </div>
<div class=" py-0.5 w-full justify-between">
<Tooltip
content={$i18n.t(
'Boosting or penalizing specific tokens for constrained responses. Bias values will be clamped between -100 and 100 (inclusive). (Default: none)'
)}
placement="top-start"
className="inline-tooltip"
>
<div class="flex w-full justify-between">
<div class=" self-center text-xs font-medium">
{$i18n.t('Logit Bias')}
</div>
<button
class="p-1 px-3 text-xs flex rounded-sm transition shrink-0 outline-hidden"
type="button"
on:click={() => {
params.logit_bias = (params?.logit_bias ?? null) === null ? '' : null;
}}
>
{#if (params?.logit_bias ?? null) === null}
<span class="ml-2 self-center"> {$i18n.t('Default')} </span>
{:else}
<span class="ml-2 self-center"> {$i18n.t('Custom')} </span>
{/if}
</button>
</div>
</Tooltip>
{#if (params?.logit_bias ?? null) !== null}
<div class="flex mt-0.5 space-x-2">
<div class=" flex-1">
<input
class="w-full rounded-lg pl-2 py-2 px-1 text-sm dark:text-gray-300 dark:bg-gray-850 outline-hidden"
type="text"
placeholder={$i18n.t('Enter comma-seperated "token:bias_value" pairs (example: 5432:100, 413:-100)')}
bind:value={params.logit_bias}
autocomplete="off"
/>
</div>
</div>
{/if}
</div>
<div class=" py-0.5 w-full justify-between"> <div class=" py-0.5 w-full justify-between">
<Tooltip <Tooltip
content={$i18n.t('Enable Mirostat sampling for controlling perplexity.')} content={$i18n.t('Enable Mirostat sampling for controlling perplexity.')}

View File

@ -50,6 +50,7 @@
seed: null, seed: null,
temperature: null, temperature: null,
reasoning_effort: null, reasoning_effort: null,
logit_bias: null,
frequency_penalty: null, frequency_penalty: null,
presence_penalty: null, presence_penalty: null,
repeat_penalty: null, repeat_penalty: null,
@ -348,6 +349,8 @@
temperature: params.temperature !== null ? params.temperature : undefined, temperature: params.temperature !== null ? params.temperature : undefined,
reasoning_effort: reasoning_effort:
params.reasoning_effort !== null ? params.reasoning_effort : undefined, params.reasoning_effort !== null ? params.reasoning_effort : undefined,
logit_bias:
params.logit_bias !== null ? params.logit_bias : undefined,
frequency_penalty: frequency_penalty:
params.frequency_penalty !== null ? params.frequency_penalty : undefined, params.frequency_penalty !== null ? params.frequency_penalty : undefined,
presence_penalty: presence_penalty: