Files
Loki/docs/superpowers/specs/2026-10-15-rust-migration-lot14-serve-design.md
T
Claude 13bcbc74fe Lot 14 : ligne de commande du moteur composée en Rust (LOKI_SERVE=rust)
loki-rs engine serve fait ce que faisait loki serve : lire la
configuration (par l'API interne du Go), sonder le monde (aide du moteur,
--version, --list-devices, GGUF, RAM, VRAM, cgroup, cpuset, variables
LLAMA_ARG_*/GGML_*), composer la ligne de llama-server, vérifier le port,
garder la commande pour l'interface, puis exec. Le superviseur le lance à
la place de loki serve quand LOKI_SERVE=rust (expérimental ; le Go reste
le défaut).

serve/ porte backend_serve*.go fonction par fonction (couches GPU, --fit
et sa marge, threads, files CUDA, second slot, mode tensor, cache de
prompts, points de reprise, décodage spéculatif, fidélité, LOAD_GUARD,
SLOT_PERSIST), toute la décision restant pure. Strata, l'essai de
l'optimiseur et un lancement sans API interne passent toujours par
loki serve (Go). La façade donne au Go l'adresse de son API interne
(LOKI_GO_ADDR), héritée par le superviseur.

Parité : parity_serve_test.go tire du Go 1 872 lancements (12 machines ×
112 presets × 3 aides de moteur × 13 jeux de variables) et les sondes
pures, rejoués argument par argument par tests/serve.rs ; deux essais de
bout en bout lancent le vrai binaire contre un faux Go et un faux moteur.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016tcGfJWefW5kUGoC2wL8cv
2026-10-15 17:58:24 +00:00

4.1 KiB

Lot 14 — loki serve composé en Rust

Contexte

Depuis le lot 3, la supervision du moteur est en Rust : loki-rs engine start|stop|restart. Mais elle lançait encore loki serve (Go), qui compose la ligne de commande de llama-server avant de lui céder la place.

Cette ligne vit dans backend_serve*.go, environ 4 000 lignes. Chaque option y a été réglée contre un défaut mesuré :

  • couches GPU et placement automatique (--fit, --fit-target) ;
  • threads et sonde de conteneur ;
  • files de lancement CUDA ;
  • second slot, parallélisme de tenseurs ;
  • cache de prompts, points de reprise des hybrides ;
  • décodage spéculatif (MTP, brouillon, n-grammes) ;
  • garde-fous de fidélité, garde-fou de chargement (LOAD_GUARD) ;
  • état des slots gardé à la bascule.

Lot 14 : loki-rs engine serve fait ce travail quand LOKI_SERVE=rust (expérimental). Le superviseur le lance à la place de loki serve. Sans la variable, rien ne change.

Découpage

  • serve/ : port fonction par fonction. mod.rs contient build_serve_args et les outils de drapeaux. Les modules suivent les fichiers Go :

    • threads, queues, expert, fidelity ;
    • side, split, cache, ckpt ;
    • spec, moe, persist.

    Tout ce qui décide est pur.

  • serve/run.rs porte cmdServe. Il lit la configuration, la clé d'API, les dossiers de modèles et le jeton de tentative de SPEC=auto par l'API interne du Go. Il sonde ensuite :

    • l'aide du moteur, --version, --list-devices (bornés dans le temps, avec les bibliothèques du moteur) ;
    • le GGUF ;
    • la RAM, la VRAM (nvidia-smi), le cgroup et le cpuset ;
    • les variables LLAMA_ARG_* et GGML_*.

    Il vérifie que le port est libre et écrit le marqueur de SLOT_PERSIST. Il garde la commande en base pour l'interface (engine_cmdline), puis fait exec du moteur.

  • La façade passe au Go l'adresse de son API interne (LOKI_GO_ADDR), à côté du jeton. Le superviseur, lancé par le Go, en hérite, et engine serve aussi.

Restent au Go

loki serve (Go) est lancé à notre place dans ces cas, à l'identique :

  • un preset Strata (son propre serveur, lot à venir) ;
  • le moteur d'essai de l'optimiseur (LOKI_TUNE_TRIAL) ;
  • l'absence d'API interne (lancement à la main hors de la façade).

Restent aussi au Go les aperçus de l'éditeur de preset (/api/preset/cacheram, /api/preset/moe, « Dupliquer en placement auto »). Ils viendront avec le lot des presets.

Écarts assumés

  • Le message d'un brouillon (MODEL_DRAFT) introuvable cite l'erreur système au format Rust.
  • Pas de cache de l'aide ni du build par binaire : engine serve ne compose qu'une ligne par lancement, le cache du Go ne servait qu'au process web.
  • Le jeton de tentative de SPEC=auto est lu puis réécrit par l'API interne, sans transaction : le Go seul l'efface, une fois le moteur prêt.

Parité

internal/loki/parity_serve_test.go tire du Go 1 872 lancements, chacun avec sa ligne de commande, son environnement et ses notes. Les lancements croisent :

  • 12 machines (VRAM, RAM, GGUF dense, MoE, hybride, par couches, architecture exclue, brouillons, mémoire unifiée, conteneur à l'étroit) ;
  • 112 presets ;
  • 3 aides de moteur (récent, ancien, inconnu) ;
  • 13 jeux de variables LLAMA_ARG_*, et des variables GGML_*.

Le journal comprend aussi les sondes pures :

  • listes de CPU, cpuset et quotas, mémoire du cgroup ;
  • sortie de nvidia-smi, --list-devices, build du moteur ;
  • forme copiable de la commande ;
  • verdicts de SPEC=auto ;
  • drapeaux de chargement, taille d'état par jeton.

tests/serve.rs rejoue le tout contre serve::build_serve_args, argument par argument. Une mutation du calcul du cache, des files CUDA ou des bornes des n-grammes fait échouer le rejeu.

Deux essais de bout en bout lancent le vrai loki-rs engine serve contre un faux Go et un faux llama-server. Ils vérifient :

  • la ligne exécutée et le chemin des bibliothèques ;
  • la commande gardée en base ;
  • le refus d'un port pris, d'un modèle absent ;
  • la sortie propre d'un preset externe ;
  • la délégation au Go (sans API interne, essai de l'optimiseur, Strata).