mirror of
https://github.com/R0m1k3/Loki.git
synced 2026-10-11 17:26:57 +02:00
Chercher à la main le bon micro-lot, les threads ou la marge --fit d'un preset demandait de dupliquer, basculer et comparer des bench complets un par un. L'optimiseur le fait sur un moteur d'essai, sans jamais toucher à config.env ni à ce que calcule le modèle, et n'écrit rien sans un clic. - Isolation : moteur principal arrêté puis relancé ; chaque essai est une copie de la configuration (LOKI_HOME/tune/run), lancée par « loki serve » sur 127.0.0.1 et un port libre, groupe de processus tué en sortie - Verrou exclusif inter-processus (LOKI_HOME/tune.lock, PID + démarrage + binaire) vérifié par serviceAction start/restart et par le chat, les tâches, bash_bg, /v1, le bench, la bascule et l'enregistrement de preset, GPU, clé d'API, moteur ; essai orphelin arrêté avant tout démarrage du moteur - Essais : lots, threads, délestage, marges --fit, files CUDA ; placement --fit et SPEC/CUDA_GRAPH_OPT/--backend-sampling seulement sur demande - EXTRA_ARGS jeton par jeton, liste blanche seulement ; ligne de commande de chaque essai composée à blanc et comparée à la référence (« dénature »), contexte, slots et cache KV recontrôlés une fois chargé - Mesure : bench complet du lot 1 à profondeur fixe ; score = durée d'un tour type (médianes de la télémétrie) ; gain > max(3 %, écart entre passages) - Application sur clic : copie du preset, ou preset actuel sauvegardé, réécrit clé par clé, vérifié par une sonde et rétabli en cas d'échec Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
39 lines
1.1 KiB
Go
39 lines
1.1 KiB
Go
//go:build linux
|
|
|
|
package loki
|
|
|
|
import (
|
|
"os"
|
|
"strconv"
|
|
"strings"
|
|
)
|
|
|
|
// procIdentity : instant de démarrage (en tops d'horloge depuis le boot, champ
|
|
// 22 de /proc/<pid>/stat) et binaire d'un processus vivant. Un PID recyclé
|
|
// après un redémarrage de Loki a un autre instant de démarrage : l'optimiseur ne
|
|
// tue un essai orphelin que si les deux concordent (backend_tune_lock.go).
|
|
func procIdentity(pid int) (start, exe string, ok bool) {
|
|
if pid <= 0 {
|
|
return "", "", false
|
|
}
|
|
b, err := os.ReadFile("/proc/" + strconv.Itoa(pid) + "/stat")
|
|
if err != nil {
|
|
return "", "", false
|
|
}
|
|
// Le nom du processus (champ 2, entre parenthèses) peut contenir des blancs
|
|
// et des parenthèses : on repart de la DERNIÈRE parenthèse fermante.
|
|
s := string(b)
|
|
i := strings.LastIndexByte(s, ')')
|
|
if i < 0 {
|
|
return "", "", false
|
|
}
|
|
f := strings.Fields(s[i+1:])
|
|
// f[0] est le champ 3 (état) : le champ 22 est donc f[19]. Un zombie a fini
|
|
// de tourner, il ne compte plus comme vivant.
|
|
if len(f) < 20 || f[0] == "Z" {
|
|
return "", "", false
|
|
}
|
|
exe, _ = os.Readlink("/proc/" + strconv.Itoa(pid) + "/exe")
|
|
return f[19], exe, true
|
|
}
|