mirror of
https://github.com/R0m1k3/Loki.git
synced 2026-10-22 22:48:11 +02:00
Fix: garder l'inférence sur GPU et réparer l'erreur 400 de template
- agent_config: num_gpu auto (-1) par défaut au lieu de forcer un nombre de couches codé en dur (RTX 3060), qui faisait basculer Ollama sur CPU quand la config ne tenait pas en VRAM. num_gpu/main_gpu ne sont transmis que si l'utilisateur force explicitement une valeur (>= 0). - agent_config: migration v4 remettant a -1 les profils deja enregistres avec un num_gpu fige. - agent: la boucle de reparation d'appel d'outil reinjecte son rappel en role "user" au lieu de "system" (les templates Gemma/Mistral refusent un message system hors tete -> 400 "System message must be at the beginning"). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
1 parent
e24d397d31
commit
aed5f8148c
2 files changed
+23
-5
No files matched your search
@@ -122,9 +122,14 @@ async def run_agent(
|
|||||||
int(request_options.get("num_predict", 0)), 4096
|
int(request_options.get("num_predict", 0)), 4096
|
||||||
)
|
)
|
||||||
thinking_buf = ""
|
thinking_buf = ""
|
||||||
|
# NB : on réinjecte ce rappel en `user`, pas en `system`.
|
||||||
|
# Beaucoup de templates (Gemma, Mistral…) lèvent
|
||||||
|
# « System message must be at the beginning » dès qu'un
|
||||||
|
# message system apparaît ailleurs qu'en tête, ce qui
|
||||||
|
# ferait échouer toute la requête en 400.
|
||||||
convo.append(
|
convo.append(
|
||||||
{
|
{
|
||||||
"role": "system",
|
"role": "user",
|
||||||
"content": (
|
"content": (
|
||||||
"L'appel d'outil précédent contenait un JSON "
|
"L'appel d'outil précédent contenait un JSON "
|
||||||
"tronqué. Réessaie immédiatement avec des arguments "
|
"tronqué. Réessaie immédiatement avec des arguments "
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ from . import db
|
|||||||
CONFIG_KEY = "agent"
|
CONFIG_KEY = "agent"
|
||||||
MODEL_PROFILES_KEY = "model_profiles"
|
MODEL_PROFILES_KEY = "model_profiles"
|
||||||
PROFILE_STATE_KEY = "model_profiles_state"
|
PROFILE_STATE_KEY = "model_profiles_state"
|
||||||
PROFILE_VERSION = 3
|
PROFILE_VERSION = 4
|
||||||
|
|
||||||
DEFAULT_SYSTEM_PROMPT = (
|
DEFAULT_SYSTEM_PROMPT = (
|
||||||
"Tu es Loki, un assistant de développement local agentique. Tu disposes "
|
"Tu es Loki, un assistant de développement local agentique. Tu disposes "
|
||||||
@@ -57,7 +57,10 @@ RTX_3060_GEMMA4_PROFILE: dict = {
|
|||||||
**DEFAULT_GENERATION,
|
**DEFAULT_GENERATION,
|
||||||
"max_tokens": 4096,
|
"max_tokens": 4096,
|
||||||
"num_ctx": 8192,
|
"num_ctx": 8192,
|
||||||
"num_gpu": 49,
|
# num_gpu = -1 : laisse Ollama placer le plus de couches possible sur le GPU
|
||||||
|
# (auto-fit, comme `ollama run`). Forcer un nombre de couches qui ne tient pas
|
||||||
|
# en VRAM fait basculer toute l'inférence sur le CPU.
|
||||||
|
"num_gpu": -1,
|
||||||
}
|
}
|
||||||
|
|
||||||
DEFAULT_CONFIG: dict = {
|
DEFAULT_CONFIG: dict = {
|
||||||
@@ -87,6 +90,12 @@ def _migrate_profiles() -> None:
|
|||||||
if gemma_profile.get("max_tokens", 0) <= 2048:
|
if gemma_profile.get("max_tokens", 0) <= 2048:
|
||||||
gemma_profile["max_tokens"] = 4096
|
gemma_profile["max_tokens"] = 4096
|
||||||
profiles["gemma4:12b"] = gemma_profile
|
profiles["gemma4:12b"] = gemma_profile
|
||||||
|
# v4 : un ancien profil pouvait forcer num_gpu sur un nombre de couches codé
|
||||||
|
# en dur (ex. 49), ce qui basculait l'inférence sur le CPU quand ça ne tenait
|
||||||
|
# pas en VRAM. On repasse en auto (-1) pour laisser Ollama placer les couches.
|
||||||
|
for prof in profiles.values():
|
||||||
|
if prof.get("num_gpu", -1) is not None and prof.get("num_gpu", -1) > 0:
|
||||||
|
prof["num_gpu"] = -1
|
||||||
db.set_config_value(MODEL_PROFILES_KEY, profiles)
|
db.set_config_value(MODEL_PROFILES_KEY, profiles)
|
||||||
db.set_config_value(PROFILE_STATE_KEY, {"version": PROFILE_VERSION})
|
db.set_config_value(PROFILE_STATE_KEY, {"version": PROFILE_VERSION})
|
||||||
|
|
||||||
@@ -137,10 +146,14 @@ def ollama_options(cfg: dict) -> dict:
|
|||||||
"top_p": cfg["top_p"],
|
"top_p": cfg["top_p"],
|
||||||
"top_k": cfg["top_k"],
|
"top_k": cfg["top_k"],
|
||||||
"num_predict": cfg["max_tokens"],
|
"num_predict": cfg["max_tokens"],
|
||||||
"num_gpu": cfg["num_gpu"],
|
|
||||||
"main_gpu": 0,
|
|
||||||
"num_batch": cfg["num_batch"],
|
"num_batch": cfg["num_batch"],
|
||||||
}
|
}
|
||||||
|
# num_gpu n'est transmis que si l'utilisateur force explicitement un nombre
|
||||||
|
# de couches (≥ 0). En -1 (défaut), on laisse Ollama auto-ajuster l'offload
|
||||||
|
# GPU comme `ollama run` ; lui imposer une valeur peut le forcer sur le CPU.
|
||||||
|
if cfg.get("num_gpu", -1) >= 0:
|
||||||
|
opts["num_gpu"] = cfg["num_gpu"]
|
||||||
|
opts["main_gpu"] = 0
|
||||||
# num_ctx n'est envoyé que s'il est défini (> 0), sinon défaut du modèle.
|
# num_ctx n'est envoyé que s'il est défini (> 0), sinon défaut du modèle.
|
||||||
if cfg.get("num_ctx"):
|
if cfg.get("num_ctx"):
|
||||||
opts["num_ctx"] = cfg["num_ctx"]
|
opts["num_ctx"] = cfg["num_ctx"]
|
||||||
|
|||||||
Reference in new issue
Block a user