mirror of
https://github.com/R0m1k3/Loki.git
synced 2026-10-23 15:08:16 +02:00
Arrêt du moteur : attendre tout l'arbre, pas seulement le chef
En conteneur, userSvcStop n'attendait que le processus `loki serve`. Avec Strata, le moteur qui tient la VRAM (cache d'experts, ~9 Go) est un autre processus qui finit de s'arrêter après le serveur Python : la relance suivante démarrait llama-server sur une carte encore pleine (« cudaMalloc failed: out of memory » à l'encodeur de vision) et Strata mesurait la RAM disponible avec l'ancien moteur encore chargé (mode mmap choisi à tort). stopProcTree relève l'arbre (session, groupe et descendants) avant tout signal, SIGTERM puis SIGKILL aux survivants, et ne revient qu'une fois tout parti. Diagnostic : une pile d'appels citant load_model ne passe plus pour une nouvelle tentative (la cause mémoire était perdue), et le chat donne l'échec de chargement au lieu de « il démarre, réessaie ». Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014wfx8uW1un1WwWJ6xzAbkV
This commit is contained in:
6 files changed
+295
-13
No files matched your search
@@ -107,6 +107,13 @@ func modelLoadErrorFrom(log string) string {
|
||||
// On ne considère que ce qui suit la DERNIÈRE tentative de chargement.
|
||||
start := 0
|
||||
for i, l := range lines {
|
||||
// Une pile d'appels cite les fonctions traversées
|
||||
// (…server_context_impl10load_model…) : ce n'est pas une nouvelle
|
||||
// tentative, et repartir de là perdait la cause écrite juste avant
|
||||
// (« cudaMalloc failed: out of memory » devenait « a planté »).
|
||||
if isBacktraceFrame(l) {
|
||||
continue
|
||||
}
|
||||
// Un lancement refusé par LOAD_GUARD (backend_serve_moe.go) s'arrête
|
||||
// avant tout chargement : c'est lui, la dernière tentative.
|
||||
if strings.Contains(l, "loading model") || strings.Contains(l, "load_model") || strings.Contains(l, loadGuardMarker) ||
|
||||
@@ -159,7 +166,8 @@ func modelLoadErrorFrom(log string) string {
|
||||
strings.Contains(low, "cudamalloc failed"),
|
||||
strings.Contains(low, "failed to allocate"):
|
||||
// Prioritaire sur l'échec générique : la cause mémoire doit gagner.
|
||||
reason = "mémoire GPU insuffisante (VRAM) — réduis le contexte (CTX) ou prends une quantification plus petite"
|
||||
reason = "mémoire GPU insuffisante (VRAM) — réduis le contexte (CTX) ou prends une quantification plus petite, " +
|
||||
"et vérifie qu'aucun autre programme n'occupe la carte (nvidia-smi)"
|
||||
case strings.Contains(low, "ggml_cuda error"), strings.Contains(low, "cuda error"):
|
||||
if reason == "" {
|
||||
reason = "erreur CUDA — GPU indisponible ? (après un redémarrage du serveur : docker restart loki)"
|
||||
@@ -196,6 +204,10 @@ func modelLoadErrorFrom(log string) string {
|
||||
}
|
||||
}
|
||||
|
||||
// isBacktraceFrame : une ligne de pile d'appels de glibc
|
||||
// (« /chemin/lib.so(symbole+0x1c)[0x14bd…] »).
|
||||
func isBacktraceFrame(l string) bool { return strings.Contains(l, ")[0x") }
|
||||
|
||||
// handleServiceLog (GET /api/service/log) : dernières lignes du journal du
|
||||
// service, pour que l'UI puisse montrer POURQUOI le modèle ne se charge pas
|
||||
// (fichier .gguf illisible, VRAM insuffisante, bibliothèque manquante…) au lieu
|
||||
|
||||
Reference in new issue
Block a user