Slots : SLOT_PERSIST garde l'état de la discussion à la bascule de preset, en opt-in

Passer de A à B puis revenir à A relance llama-server deux fois, et la
conversation de A est recalculée en entier au retour. Avec SLOT_PERSIST=on
(off par défaut), Loki demande au moteur d'écrire l'état du slot 0 juste
avant la bascule, et le recharge au retour avant le premier message de la
discussion — seulement si tout concorde, sinon calcul normal, en silence.

llama.cpp ne vérifie à la relecture que types et tailles : rien ne dit quel
build ni quels réglages ont calculé ce cache. La clé de validité est donc
l'empreinte de tout ce qui touche au calcul, prise par « loki serve » au
lancement : ligne de commande complète (modèle, CTX, types KV, NGL, lots,
gabarit, SPEC, EXTRA_ARGS…), LLAMA_ARG_*/GGML_*/CUDA_*, taille et date du
modèle et de ses tranches, du projecteur, du brouillon, du binaire et de
ses bibliothèques. Pas de cas « mise à jour du moteur » : elle change la clé.

- --slot-save-path posé aussi pour SLOT_PERSIST accepté, sous les mêmes
  conditions de sécurité que l'isolation du lot 1 (boucle locale ou clé
  d'API) ; refusé avec le décodage spéculatif (le save ne garde pas le
  brouillon ; /slots speculative revérifié à chaque fois), des poids sur
  CPU, un --slot-save-path à la main ; la ligne reste alors celle d'avant
- sauvegarde depuis l'interface ou une tâche, avant l'arrêt : le slot doit
  porter un tour de la discussion (tampon d'engineMarkMain), ≥ 4096 jetons,
  ≤ 8 Gio estimés, double de place libre ; nom provisoire, renommé
  seulement si aucune requête n'est partie pendant l'écriture
- rechargement avant la première requête de la discussion (ou son
  préchauffage) : même clé de moteur, même discussion, slot 0 vierge (/slots
  sans id_task) ; une seule tentative, fichier retiré ; toute erreur =
  calcul normal
- deux fichiers au plus ; clé retirée = tout effacé au lancement suivant ;
  SLOT_PERSIST préservé à la bascule comme HOST (sinon B effaçait l'état de A)
- README : SIDE_SLOT, le cache KV plein ne déclenche jamais de compaction
- tests : plan et refus, ligne inchangée, empreinte (clé d'API exclue,
  fichiers et réglages inclus), rotation, séquence save puis restore sur un
  faux moteur, refus à la sauvegarde et au rechargement, autre clé, défaut
  sans aucun appel

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
MichaelandClaude Opus 5.5 committed 2026-10-04 10:17:08 +02:00
1 parent 7a57322a62
commit 28ba44eb46
12 files changed
+1133 -23

No files matched your search

+33
View File
@@ -498,6 +498,39 @@ Ajoutées par ce fork :
requêtes partent sans `id_slot`, comme avant. Ce que voit le modèle ne
change pas : deux slots qui calculent en même temps donnent des logits égaux
au bruit de virgule flottante près, comme un découpage de lots différent.
Un « cache KV plein » sans nombre de jetons (le pool, pas le prompt) est
rejoué tel quel et ne déclenche jamais de compaction.
- **État du slot gardé à la bascule de preset** (clé `SLOT_PERSIST`, **off**
par défaut, `loki config set SLOT_PERSIST on`) : passer d'un preset A à B
puis revenir à A relance le moteur deux fois, et la conversation de A est
recalculée en entier au retour. Avec `on`, juste avant une bascule faite
depuis l'interface ou par une tâche, Loki demande au moteur d'écrire l'état
du slot de la discussion (`/slots/0?action=save`, sous `LOKI_HOME/slots`),
et le recharge au retour, avant le premier message de cette discussion.
Conditions strictes, sinon rien n'est écrit ou rechargé et le calcul est
normal : la dernière requête passée par le slot était bien un tour de
cette discussion (pas une vérification, une tâche, un préchauffage ou un
client `/v1`), au moins 4096 jetons, au plus 8 Gio estimés et le double
de place libre ; au retour, le moteur doit avoir **exactement** la même
empreinte — ligne de commande complète (modèle, `CTX`, types KV, `NGL`,
lots, gabarit, `EXTRA_ARGS`…), variables `LLAMA_ARG_*`/`GGML_*`/`CUDA_*`,
taille et date du modèle, du projecteur, du binaire et de ses bibliothèques
— et son slot 0 ne doit encore avoir servi aucune tâche. Une mise à jour du
moteur change l'empreinte : jamais de reprise d'un build à l'autre. Une
seule tentative par fichier, retiré ensuite ; deux fichiers au plus,
supprimés dès que la clé est retirée. Réglage de la machine : il survit aux
bascules comme `HOST` (un preset qui le pose l'emporte). Refusé au lancement (note au journal)
avec le décodage spéculatif (`SPEC`, brouillon dans `EXTRA_ARGS` : la
sauvegarde du moteur ne garde pas l'état du brouillon, et un brouillon MTP
détecté sur le slot bloque aussi), des poids sur CPU (MoE déporté), un
`--slot-save-path` déjà réglé, ou un moteur joignable par d'autres sans clé
d'API (`HOST` autre que `127.0.0.1`). `loki switch` en ligne de commande ne
garde rien (seul le process web sait ce que porte le slot). Le gain est
réel surtout sur un modèle dense ; sur un hybride (Qwen3.5/3.6), le fichier
n'a pas de points de reprise et ne sert que si le message suivant prolonge
exactement les jetons gardés (gabarit qui rend le dernier tour à
l'identique), sinon recalcul comme avant. Ce que voit le modèle ne change
pas : llama.cpp ne reprend un état que sur un préfixe de jetons identique.
- **Discussions multiples** : historique complet dans la barre latérale, titre
repris du premier message (renommable), suppression. **Chaque discussion a son
dossier de fichiers** (`workspace/discussions/<id>/`) : les pièces jointes