Обеспечение повторяемости результатов при использовании LM Studio
nikitayev — 06.10.2025
Существует проблема — при отправке одного и того же запроса в LM
Studio используя LM Studio API мы получаем разные результаты даже
при установке температуры = 0.
Всё дело в том, что у LM Studio много дополнительных параметров, благодаря которым можно указать количество предыдущих токенов диалога необходимо использовать.
Т.е., когда мы обращаемся по токе подключения /v1/chat/completions — то LM Studio воспринимает это как продолжение предыдущего диалога.
И это проблема.
Вот что даёт исследование всех параметров с помощью Perplexiti.Ai: https://www.perplexity.ai/search/napishi-o-vsekh-parametrakh-dl-nqRQ8132SBOwMCFL_LHWkQ#0
Но не все параметры необходимо настраивать.
Параметр stream даже упоминать не нужно.
Самые успешные параметры для обеспечения детерминированности ответа такие:
try:
# Prepare JSON payload with deterministic parameters
json_data = {
"model": self.model,
"messages": [{"role": "user", "content": text_content}],
"temperature": 0.0,
# "ttl": self.ttl,
# "max_tokens": self.max_tokens,
"top_p": 1.0,
"top_k": 500,
"min_p": 0,
"repeat_penalty": 1.0,
"presence_penalty": 0,
"repeat_last_n": 0,
"seed": 0,
"dry_multiplier": 0.000,
"dry_base": 1.750,
"dry_allowed_length": 2,
"dry_penalty_last_n": -1,
"xtc_probability": 0.000,
"xtc_threshold": 0.100,
"mirostat": 0,
"mirostat_lr": 0.100,
"mirostat_ent": 5.000,
"typical_p": 1.0,
"dynatemp_range": 0.0,
"dynatemp_exp": 1.0,
"n_ctx": 131072,
"n_batch": 512,
"n_predict": -1,
"n_keep": 0
# "stream": "true"
}
# Convert to JSON string
body = json.dumps(json_data)
logging.info(f"Подготовлен JSON запрос, размер: {len(body)} байт")
# Send HTTP request
conn = http.client.HTTPConnection(self.host, self.port)
headers = {
"Content-Type": "application/json",
"Authorization": f"Bearer {self.api_key}"
}
logging.info(f"Отправка запроса на {self.host}:{self.port}")
conn.request("POST", "/v1/chat/completions", body, headers)
response = conn.getresponse()
response_data = response.read().decode()
conn.close()
logging.info(f"Получен ответ: статус {response.status}, размер данных: {len(response_data)} байт")
# Parse response
if response.status == 200:
response_json = json.loads(response_data)
content = response_json.get("choices", [{}])[0].get("message", {}).get("content", "")
logging.info(f"Успешный ответ: {content[:100]}...") # Логируем первые 100 символов
# Display response in upper panel
self.response_text.config(state=tk.NORMAL)
self.response_text.delete("1.0", tk.END)
self.response_text.insert(tk.END, content)
self.response_text.config(state=tk.DISABLED)
# Log the interaction
self.log_text.insert(tk.END, f"Запрос: {text_content}\n")
if file_path:
self.log_text.insert(tk.END, f"Изображение: {file_path}\n")
self.log_text.insert(tk.END, f"Ответ: {content}\n")
self.log_text.insert(tk.END, "-" * 50 + "\n")
self.log_text.see(tk.END)
else:
error_msg = f"Ошибка: {response.status} - {response_data}"
messagebox.showerror("Ошибка", error_msg)
self.log_text.insert(tk.END, error_msg + "\n")
logging.error(f"Ошибка ответа сервера: {error_msg}")
except Exception as e:
error_msg = f"Не удалось отправить запрос: {e}"
messagebox.showerror("Ошибка", error_msg)
self.log_text.insert(tk.END, error_msg + "\n")
logging.error(f"Исключение при отправке запроса: {e}")
И каждый запрос необходимо дублировать!
Только второй ответ на один и тот же запрос будет правильным.
|
|
</> |
Как Strive помогает внедрять OKR и повышать вовлеченность сотрудников
Советско-финская война 1939-1940
Две сказки от классика
Автора граффити «Миру — мир» в Петербурге проверяют на экстремизм и терроризм
Про забытую перемогу УПА
Дачный урожай.
11 симптомов того, что скоро сердце может остановиться

