Commit Graph
17 Commits
Author SHA1 Message Date
MichaelandClaude Opus 5.5 3565b594ea Moteur : cache de prompts dimensionné et travaux annexes isolés — la conversation n'est plus recalculée après un vérificateur ou un sous-agent
llama-server garde en RAM hôte une copie exacte des états de slot qu'il quitte
(KV, état récurrent, points de reprise, brouillon MTP) et la recharge octet pour
octet. Mais son défaut de 8 Gio ne tient pas une conversation de 30 à 65 k
jetons à côté de l'état d'un vérificateur, d'un sous-agent, d'une tâche ou d'un
bench : à la requête suivante il évince la conversation pour sauver l'annexe, et
tout est recalculé (30 à 80 s sur un 27B). Rien de ce que voit le modèle ne
change ici : seul le bruit de découpage des lots, comme le cache_prompt actuel.

- CACHE_RAM (Mio ; vide/auto, nombre passé tel quel, -1, 0) → --cache-ram,
  seulement si l'aide du moteur le connaît. Loki se tait devant -cram
  d'EXTRA_ARGS et LLAMA_ARG_CACHE_RAM. L'auto ne descend JAMAIS sous le défaut :
  il agrandit seulement un modèle tout-GPU (VRAM NVIDIA connue, aucun poids ni
  KV sur CPU, NGL complet), d'après l'état mesuré dans le GGUF (2,5 × KV à CTX
  + état récurrent et points de reprise des hybrides), plafonné à 30 % de la RAM
  (limite cgroup comprise) et à la moitié de la RAM libre.
- --slot-save-path LOKI_HOME/slots (0700, purgé au lancement) uniquement si le
  moteur est en boucle locale ou protégé par clé, et si le dossier existe. Les
  proxys /v1 et du relais refusent désormais toute action /slots (405).
- engineSideJob efface le slot 0 APRÈS le sous-agent, la passe de vérification,
  la tâche planifiée et le bench (pas après la compaction : rien à y gagner).
  Synchrone, borné à 2 s, et seulement si : moteur local, build ≥ 8660 lu dans
  /props, total_slots == 1, slot 0 au repos, aucune requête de Loki en vol
  (compteur tenu par le chat, les résumés, le bench et les proxys).
  CACHE_ISOLATE=off le coupe.
- usage.prompt_tokens_details.cached_tokens : si la conversation revient avec
  moins de la moitié en cache, conseil (une fois) de relever CACHE_RAM.
- Éditeur de preset : champ « Cache de prompts » à côté d'UBATCH, avec la
  valeur auto calculée par le serveur (/api/preset/cacheram).
- Lecteur GGUF : embedding_length, head_count et dimensions ssm.*.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 23:37:55 +02:00
MichaelandClaude Opus 5.5 c4f051a0e9 Moteur : corrections de relecture des garde-fous de fidélité — les variables LLAMA_ARG_* et le glissement par défaut des anciens moteurs se voient aussi
Les garde-fous ne lisaient qu'EXTRA_ARGS et KV_TYPE. Or llama.cpp applique ses
variables LLAMA_ARG_* avant la ligne de commande : un conteneur lancé avec
LLAMA_ARG_CACHE_TYPE_K=q8_0 ou LLAMA_ARG_CACHE_REUSE=256 changeait les calculs
sans un mot. Et un llama-server d'avant --context-shift glisse le contexte PAR
DÉFAUT : il jetait des jetons alors que rien n'était écrit nulle part.

- Type de cache effectif : variables, puis KV_TYPE*, puis EXTRA_ARGS, la
  source la plus forte est nommée dans la note ; warnSlowKV suit.
- --context-shift et --cache-reuse lus aussi dans LLAMA_ARG_CONTEXT_SHIFT et
  LLAMA_ARG_CACHE_REUSE ; moteur ancien (aide sans --context-shift) : on dit
  qu'il glisse et que --no-context-shift l'en empêche. Aucun drapeau ajouté.
- Vision reconnue aussi par --mmproj d'EXTRA_ARGS et LLAMA_ARG_MMPROJ.
- Placement figé lu par tensorOverride : --n-cpu-moe 0 ne compte plus,
  --n-cpu-ffn et LLAMA_ARG_N_CPU_MOE si. Même règle dans l'interface.
- Test du paquet : les étiquettes json:"cache_prompt" des structures sont
  aussi refusées hors du benchmark.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 23:11:31 +02:00
MichaelandClaude Opus 5.5 2bf388f7b7 Moteur : garde-fous de fidélité — un cache KV quantifié ou un cache approché se voit, Loki n'en pose jamais
Le cache KV en q8_0 d'un preset MoE vivait dans EXTRA_ARGS : ni l'avertissement
de lenteur ni la liste de l'interface ne le voyaient, qui affichait « f16 (max
qualité) » pendant que le moteur tournait en q8_0. Rien n'empêchait non plus un
--context-shift ou un --cache-reuse de modifier en douce ce que voit le modèle.
Aucun drapeau n'est ajouté ni retiré : on DIT ce que la ligne finale change.

- Type de cache effectif (effectiveKVTypes) : KV_TYPE*, puis -ctk/-ctv et
  --cache-type-k/v d'EXTRA_ARGS par-dessus, la dernière occurrence gagne comme
  dans llama-server. warnSlowKV le reçoit désormais.
- Note au lancement quand ce cache n'est pas f16 : q8_0 modifie légèrement les
  sorties, q4_0 perte mesurable, bf16 numérique différente. Avec -ot ou
  --n-cpu-moe, --fit ne tourne pas : repasser en f16 demandera sans doute de
  relever --n-cpu-moe. Pas d'estimation de VRAM sans les métadonnées du GGUF.
- Avertissement pour --context-shift (jamais --no-context-shift) et
  --cache-reuse N>0 ; --swa-full, sans perte, n'en déclenche aucun. Vision
  chargée : llama.cpp les ignore, on le précise.
- Interface : options du cache KV étiquetées, sous-titre qui montre le type
  effectif (« défini par EXTRA_ARGS ») et les drapeaux de cache approché.
- Tests : notes et type effectif en table, aucun -ctk/-ctv sans KV_TYPE, corps
  réels du chat et de la compaction sans cache_prompt:false ni n_cache_reuse,
  et ces clés réservées au benchmark dans tout le paquet (arbre syntaxique).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 23:04:08 +02:00
MichaelandClaude Opus 5.5 9aa426a389 Moteur : trois réglages d'expert sur demande — marge VRAM par carte (FIT_TARGET), seuil d'offload des experts, branches Q/K/V parallèles
Sur deux cartes inégales (5060 Ti + 3060) ou un MoE aux experts sur CPU, il
reste quelques leviers de placement que llama.cpp expose mais que Loki ne
savait pas poser. Aucun ne touche au modèle (poids, contexte, cache,
échantillonnage) ; tous restent éteints tant que le preset ne les demande pas,
et le gain se décide à la mesure.

- FIT_TARGET=1024,3072 → --fit-target : marge libre par carte pour --fit.
  Validée (entiers, 8 valeurs au plus, jamais transmise brute : stoull ferait
  mourir le moteur en boucle), remontée à 1024 Mio au minimum. Seulement si
  l'aide la liste, sans -fitt ni LLAMA_ARG_FIT_TARGET déjà posés, avec un
  contexte chiffré (CTX=0 laisserait fit réduire le contexte) et si --fit
  tournera vraiment : NGL chiffré, --tensor-split, -ot, --n-cpu-moe, -cmoe,
  --fit off ou -sm row le coupent, et on le dit au lieu de ne rien faire.
- OP_OFFLOAD_MIN_BATCH=N → GGML_OP_OFFLOAD_MIN_BATCH : les lots de moins de N
  jetons restent sur CPU pour les poids en RAM. Utile pour des brouillons
  ngram de 32 jetons ou plus ; MTP vérifie déjà sous 32.
- CUDA_GRAPH_OPT=on → GGML_CUDA_GRAPH_OPT=1 : expérimental, sortie identique en
  amont, gain de 0 à quelques % ; refusé si -sm row/tensor ou un -ot sur
  l'attention pouvait séparer Q, K et V d'une couche. Le lancement rappelle
  « off puis redémarrer » en cas de GGML_ASSERT.
- une variable déjà dans l'environnement n'est jamais touchée ; elles ne vont
  qu'à llama-server via « loki serve ».
- tensorOverride, extrait de pipelineBlocker, sert aussi à la garde de --fit.
- --backend-sampling écarté : pas identique au bit près, et inactif sur les
  requêtes à outils (grammaire) qui font l'essentiel du trafic.
- clés documentées dans le squelette de « loki edit » ; tests de table.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 22:53:44 +02:00
MichaelandClaude Opus 5.5 2de20e0ab2 Moteur : corrections de relecture des files de lancement CUDA — les variables LLAMA_ARG_* lues comme llama.cpp les lit
La garde « pipeline possible » ne suivait pas tout à fait la façon dont
llama.cpp (common/arg.cpp) lit ses réglages. Faux positifs : 4x posé sans
pipeline possible, donc exposé au seul cas de panne connu sans aucun gain.
Faux négatifs : gain refusé à tort.

- surcharges de tenseurs cumulées : variable et drapeaux s'additionnent.
  Un --n-cpu-moe 0 n'annule donc ni un LLAMA_ARG_N_CPU_MOE=30 ni un
  --n-cpu-moe 20 placé avant lui.
- --n-cpu-ffn/-ncffn (FFN dense sur CPU) et LLAMA_ARG_OVERRIDE_TENSOR
  comptent comme des surcharges.
- cache KV : le dernier -kvo/-nkvo l'emporte. Sinon, la seule présence de
  LLAMA_ARG_NO_KV_OFFLOAD (même à 0) vaut « non », puis LLAMA_ARG_KV_OFFLOAD
  est lu comme un booléen.
- LLAMA_ARG_CPU_MOE n'est actif que pour on/enabled/true/1.
- NGL absent : Loki passe -ngl lui-même, donc LLAMA_ARG_N_GPU_LAYERS ne
  compte plus. NGL=Auto se lit sans tenir compte de la casse, comme nglArgs.
- buildServeArgs : le commentaire des threads retrouve son code.
- 12 cas de table en plus.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 22:47:38 +02:00
MichaelandClaude Opus 5.5 f7f1a30d08 Moteur : files de lancement CUDA élargies (4x) sur deux GPU quand le pipeline entre cartes est possible
Sur plusieurs cartes, llama.cpp fait travailler les GPU en pipeline quand le
modèle y tient en entier ; encore faut-il que le CPU empile assez de
lancements CUDA d'avance. CUDA_SCALE_LAUNCH_QUEUES=4x agrandit cette file du
pilote : mêmes noyaux, même ordre, sortie identique — seul le prompt peut
gagner (+10-25 % en amont sur un 70B, non mesuré ici), le décodage ne bouge pas.
llama.cpp l'a retiré de ses défauts après des blocages sur Jetson : Loki ne le
pose donc que là où le pipeline peut réellement exister.

- launchQueuesEnv (pure) : 4x seulement si ≥ 2 GPU CUDA servis (--device,
  sinon CUDA_VISIBLE_DEVICES, sinon nvidia-smi borné à 3 s) et aucun bloqueur :
  -ot, --cpu-moe, --n-cpu-moe ≠ 0, -nkvo, -sm autre que layer, NGL chiffré
  hors 999 — drapeaux d'EXTRA_ARGS ou LLAMA_ARG_* équivalents
- une variable déjà dans l'environnement n'est jamais touchée ;
  CUDA_LAUNCH_QUEUES=off la coupe, 0.25x/0.5x/2x/4x l'imposent, toute autre
  valeur est ignorée en le disant
- la valeur posée s'affiche sur la ligne « [loki serve] » ; la ligne de
  commande ne change pas, BATCH/UBATCH non plus
- CUDA_LAUNCH_QUEUES survit aux bascules de preset (réglage machine qu'un
  preset peut imposer)
- éditeur : « Experts MoE sur CPU » rappelle que ça coupe le pipeline sur 2 GPU

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 22:43:04 +02:00
MichaelandClaude Opus 5.5 c6c5dc2b7e Moteur : « auto » des threads CPU = les cœurs physiques, plus tous les threads logiques
Loki passait toujours « -t <THREADS|0> -tb <THREADS_BATCH|0> ». Pour
llama.cpp, 0 veut dire hardware_concurrency() : tous les threads logiques,
frères SMT compris. Avec l'attente active par défaut (--poll 50), deux
threads sur un même cœur se gênent, et c'est le décodage des experts MoE sur
CPU qui paie. Le vrai auto du moteur, c'est l'absence du drapeau : il prend
alors ses cœurs physiques (cœurs P seulement sur Intel hybride sous Linux).

- THREADS vide ou 0 : plus de -t ; THREADS_BATCH vide ou 0 : plus de -tb,
  le moteur recopie -t (prefill ET vérification spéculative MTP).
- Valeur illisible ou négative : ignorée et dite sur stderr, au lieu de
  faire boucler le moteur sur son analyse d'arguments.
- -t / -tb déjà dans EXTRA_ARGS : Loki ne double plus le drapeau.
- Linux, conteneur à l'étroit (cpuset restreint, quota CFS) : le moteur se
  rabattrait sur tous les cœurs de l'hôte. Une sonde compte les cœurs permis
  comme llama.cpp (thread_siblings, cœurs E écartés), plafonne au quota et
  ne pose -t que s'il est plus petit ; lecture ratée = rien. Muette si
  LLAMA_ARG_THREADS est posé ou si EXTRA_ARGS fixe l'affinité (-C, -Cr…).
- Libellés de l'interface et du gabarit de config corrigés.

Le calcul du modèle ne change pas. Gain non mesuré : comparer tg du preset
MoE à physiques, physiques-1 et logiques avant de conclure.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 22:32:14 +02:00
MichaelandClaude Opus 5.5 03eb56aee3 Moteur : corrections de relecture de la construction des arguments
buildServeArgs se disait pure, mais la traduction des drapeaux de chargement
qu'elle appelle écrivait encore sur stderr quand un --load-mode dio tombait sur
un moteur ancien. La note est désormais rendue comme les autres et affichée
par cmdServe, au même rang qu'avant (avant la note NGL).

- normalizeLoadFlags / downgradeLoadMode rendent la note au lieu de l'écrire.
- Table de tests : cas dio sur moteur ancien (drapeau retiré, une note), et
  TestNormalizeLoadFlags vérifie que seul ce cas produit une note.
- Aucun changement de ligne de commande.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 22:27:04 +02:00
MichaelandClaude Opus 5.5 76f5697487 Moteur : construction des arguments de llama-server isolée et testée
cmdServe mêlait deux métiers : sonder le monde (chemins du modèle et du
projecteur, aide du moteur, clé d'API, port) et composer la ligne de
commande. Tout réglage de lancement à venir devait donc se vérifier en
relançant un moteur. La composition passe dans buildServeArgs, pure, qui
reçoit ce que cmdServe a sondé et rend arguments, variables d'environnement
et notes ; cmdServe garde seul les effets (Setenv, chdir, port, exec).

- serveSysInfo porte l'aide du moteur, les chemins résolus et la clé.
- Les tests de capacité lisent le texte de l'aide (helpSupports*), plus le
  binaire : une aide fabriquée suffit à les exercer.
- La sélection GPU reste posée avant la lecture de l'aide, comme avant.
- Aucun changement de comportement : même ordre, mêmes valeurs. Une table
  de tests fige la ligne pour les presets courants (dense, NGL forcé,
  MoE avec -ot/--n-cpu-moe/-ctk, raisonnement on/off, vision, clé d'API,
  drapeaux de chargement, CUDA_VISIBLE_DEVICES).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 22:24:18 +02:00
MichaelandClaude Opus 5.5 1db987844e Chargement du modèle : --mlock seul ne coupe plus le mmap
UN VRAI BUG D'ABORD
normalizeLoadFlags traduisait --mlock seul en « --load-mode mlock ». Or,
pour llama.cpp (common/arg.cpp), « mlock » veut dire PAS de mmap + résident :
le modèle entier montait en RAM au lieu d'être mappé. L'ancien --mlock, lui,
gardait le mmap — son équivalent est « mmap+mlock ». Sur un modèle plus gros
que la RAM (Qwen3.8-Flash-Next, 82 Go pour 64 Go), un preset qui avait
coché « Garder en RAM » tournait donc à l'OOM dès qu'un moteur récent
prenait le relais. Correspondance alignée sur AJEAN 0.16.0 :
  --mlock seul → mmap+mlock · --no-mmap → none · les deux → mlock.

DANS LES DEUX SENS
Un moteur ancien (ou un fork) ne connaît pas --load-mode et sort en erreur
si on le lui passe : downgradeLoadMode le retraduit en anciens drapeaux
(dio, inconnu de ces moteurs, est abandonné avec un avertissement).

UN SÉLECTEUR À LA PLACE DE DEUX INTERRUPTEURS
« Garder en RAM » et « Charger tout en mémoire » ne disaient pas leur
combinaison. L'éditeur de preset propose les six modes de llama.cpp (auto,
mmap, none, mlock, mmap+mlock, dio), avec ce que fait chacun en sous-titre,
et écrit la forme moderne. Un preset aux anciens drapeaux s'affiche sur le
bon mode sans modification.

Au passage, q5_1 porte la mention « lent sur CUDA » dans la liste du cache
KV (voir le commit du port occupé : non accéléré en Flash-Attention).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 23:05:34 +02:00
MichaelandClaude Opus 5.5 20375d0e4c Moteur : port déjà occupé refusé, cache KV lent signalé
Deux reprises d'AJEAN 0.15.9, côté `loki serve`.

PORT OCCUPÉ
Un llama-server orphelin (un stop qui n'a pas tué, un relancement trop
rapide) peut encore tenir le port quand le suivant démarre. Deux moteurs
sur le même port se partagent alors les requêtes au hasard : VRAM saturée,
réponses du mauvais modèle. waitPortFree tente une connexion TCP (fiable
même en SO_REUSEADDR, là où un Listen de test réussirait), laisse 5 s à un
moteur qu'on vient d'arrêter pour libérer, puis refuse avec un message qui
dit quoi faire. argValue lit la DERNIÈRE occurrence de --port/--host, comme
llama-server, puisque EXTRA_ARGS peut les surcharger.

CACHE KV LENT
llama.cpp CUDA, compilé avec ses options par défaut (FA_ALL_QUANTS=OFF),
n'accélère en Flash-Attention que f16, bf16, q8_0 et q4_0 — et seulement à
l'identique pour K et V. C'est le cas du moteur de l'image server-cuda et de
ceux installés par OCI. q5_1 ou un couple mixte q8_0/q4_0 marchent mais sont
reconvertis en f16 à chaque pas. L'amont ne prévient que pour son binaire
précompilé ; chez nous tous les moteurs sont concernés, donc l'avertissement
part toujours dans loki-engine.log.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 23:04:10 +02:00
MichaelandClaude Opus 5 2585d2c2e1 NGL=999 : la sentinelle « toutes les couches » devient -ngl auto
Le correctif précédent ne pouvait pas s'appliquer. Il ne posait « -ngl auto »
que si la clé NGL était ABSENTE de config.env — or defaultConfig() y sème
NGL=999 sur chaque installation neuve. La quasi-totalité des configurations la
portent donc sans que personne ne l'ait choisie, le code la lisait comme un
choix délibéré, et l'abandon revenait intact :

  W common_fit_params: failed to fit params to free device memory:
    n_gpu_layers already set by user to 999, abort

999 n'a jamais été un nombre de couches : c'est la sentinelle historique
« toutes ». Sur un moteur qui sait mesurer la VRAM libre, elle devient donc
« -ngl auto », et Loki le dit sur stderr plutôt que de le faire en douce. Tout
autre nombre reste intouché — c'est un vrai choix. NGL=all force l'ancien
comportement, NGL=auto n'envoie toujours aucun drapeau, et un moteur ancien
reçoit toujours 999 (l'omettre le ferait tourner 100 % CPU).

- La décision sort dans nglArgs(), fonction pure : la seule question qui
  demande le moteur arrive déjà tranchée, donc elle se teste sans lancer
  llama-server. 10 cas couverts.
- binFitsLayersItself() double la lecture fine de l'aide par la présence de
  --load-mode. Les deux sont arrivés dans la même vague ; une description
  reformulée ou une colonne plus large ne doit pas faire conclure « moteur
  incapable » et réimposer 999.
- L'aide de la clé et le sous-titre du champ disent la nouvelle règle.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-21 09:47:32 +02:00
MichaelandClaude Opus 5 cbf8635c61 Moteur : drapeaux de chargement à jour, -ngl auto ; dictée qui dit pourquoi
Les llama-server récents ont fusionné --mlock, --mmap et --no-mmap dans un
seul --load-mode, et refusent désormais d'ajuster les couches GPU dès qu'on
leur impose un nombre : « n_gpu_layers already set by user to 999, abort ».
Le moteur pousse alors tout sur le GPU et meurt en cudaMalloc, ou se replie
à moitié sur le CPU — débit effondré, GPU à 100 %.

- Traduction des drapeaux dépréciés AU LANCEMENT, pas dans le preset :
  --mlock → --load-mode mlock, --no-mmap → --load-mode none, --mmap →
  --load-mode mmap. Les interrupteurs de l'interface continuent d'écrire
  l'ancienne forme, et un moteur antérieur la reçoit telle quelle. Un
  --load-mode écrit à la main dans EXTRA_ARGS gagne sur tout.
- -ngl auto par défaut quand le moteur propose la valeur, 999 sinon (l'omettre
  sur un moteur ancien le ferait tourner 100 % CPU). NGL=<nombre> dans le
  preset reste souverain.
- --parallel et -ngl ne sont plus ajoutés en double quand EXTRA_ARGS les porte
  déjà : le moteur râlait (« specified multiple times ») et, pire, c'est la
  dernière occurrence qui gagne — le réglage explicite du preset était donc
  silencieusement écrasé par le défaut de Loki.
- Les capacités se lisent dans « <bin> --help », une seule fois par binaire
  (binHelp met en cache) au lieu d'un lancement par question.

Dictée : quand le téléchargement du modèle whisper échoue (conteneur sans
réseau, Hugging Face injoignable), le serveur renvoyait bien la raison mais
l'interface affichait quand même « téléchargement (0 %) ». L'erreur cachée
laissait cliquer indéfiniment sur un micro qui n'écrira jamais rien.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-21 09:26:22 +02:00
MichaelandClaude Opus 5 608e7f7038 Moteur : --parallel 1 explicite — la VRAM d'avant est de retour
Les llama-server récents ouvrent 4 slots par défaut : des tampons de
calcul GPU multipliés par quatre, pour un serveur qui ne sert qu'un
utilisateur. Résultat vécu après une mise à jour du moteur : une config
27B qui tournait très bien meurt en « cudaMalloc failed: out of
memory » en pleine génération, sans qu'aucun réglage n'ait changé. On
repasse explicitement à un slot — le comportement historique — et
PARALLEL=n reste disponible dans le preset pour qui veut du parallèle.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-19 07:47:41 +02:00
Claude b518e98b43 Accès OpenAI : servi par Loki, par domaine ou par IP
L'endpoint compatible OpenAI n'était pas servi par Loki : le panneau annonçait
l'adresse de llama-server lui-même, http://<ip>:8080/v1. Dans le déploiement de
référence de ce fork, cette adresse ne peut joindre personne — le port 8080
n'est pas publié par le conteneur, l'entrypoint sème HOST=127.0.0.1, et l'IP
annoncée est celle du bridge Docker. L'autre voie proposée, « exposer en public
(ajean.link) », exigeait un jeton de relais que ce fork ne permet plus
d'obtenir : l'interrupteur ne pouvait que renvoyer vers un panneau supprimé.

Désormais, Loki sert /v1/* SUR SON PROPRE PORT et relaie vers le moteur. L'API
est donc joignable partout où l'interface l'est — IP du réseau local, nom de
domaine, reverse proxy — sans publier de second port ni ouvrir le moteur.

Serveur
- mountOAI (llm_oai.go) monte /v1/ sur le mux, et RIEN d'autre : ni /metrics,
  ni /props, ni /slots, qui divulgueraient le modèle chargé et l'état des slots.
  Le filtre interne d'oaiHandler reste en seconde barrière.
- requireCompletionKey (web_auth.go) garde cette surface avec la clé des
  COMPLÉTIONS, pas celle de pilotage : un client OpenAI n'a qu'un en-tête
  Authorization, et on veut pouvoir lui donner l'accès au modèle sans le droit
  de redémarrer la machine. Erreurs au format d'OpenAI (body.error.message), que
  les SDK savent présenter. Le préflight CORS passe sans clé — il n'en porte
  jamais, et le refuser casserait tout client tiers de navigateur.
- effectiveAPIKeyErr (backend_config.go) devient la source unique de la clé
  exigée : base d'abord, config.env en repli, exactement comme le moteur. Sans
  ce miroir, un API_KEY résiduel donnait un endpoint « ouvert » côté Loki et un
  401 côté moteur, sans rien pour l'expliquer. Lecture ratée = refus, jamais
  ouverture (même raisonnement que readWebKeyErr).
- oaiHandler passe à ReverseProxy.Rewrite : le port du moteur est relu à chaque
  requête au lieu d'être figé à la construction — il visait l'ancien port dès
  qu'on changeait PORT, jusqu'au redémarrage de Loki.
- withLocalAuth (relay_link.go) n'injecte plus la clé de pilotage sur /v1 : elle
  aurait été refusée par la garde, et surtout relayée au moteur. Le trafic du
  tunnel est marqué (en-tête effacé avant d'être posé, sinon un client le forge)
  et la surface y reste fermée tant que oai_public est faux — la promesse du
  tunnel est tenue.

Adresse affichée
- web_public_url.go : normalisation d'une adresse publique saisie à la main
  (schéma ajouté, /v1 recopié toléré, chemin refusé), origine de la requête via
  Host + X-Forwarded-Proto, et la règle de priorité entre les deux.
- Le calcul quitte le navigateur pour le serveur : c'est la concaténation côté
  client qui produisait l'adresse fantôme.

Interface
- Le panneau perd l'interrupteur ajean.link et l'interrupteur d'écoute LAN — ce
  dernier n'a plus d'objet, et deux interrupteurs pour « rendre l'IA joignable »
  était la confusion à lever. La route /api/network et `loki network` restent
  pour qui veut exposer le moteur en direct.
- Il gagne un champ « adresse publique » (facultatif, pour le reverse proxy) et
  un avertissement rouge tant qu'aucune clé n'est définie — l'endpoint est
  maintenant ouvert PARTOUT où l'interface l'est, ça ne se dit pas à voix basse.
  Le démarrage de `loki web` le crie aussi.

Vérifié bout en bout sur le serveur réel : liste des modèles à travers Loki avec
la clé (200), sans la clé (401), et complétion en streaming dont les tokens
arrivent espacés de 120 ms — le flux traverse bien le double proxy.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LPyFxVHNAN9u5pVzSYMwjd
2026-08-16 19:45:43 +00:00
Loki ecaa847439 NGL=auto : laisser llama.cpp ajuster les couches à la VRAM libre
Loki passait TOUJOURS -ngl, avec 999 comme repli quand le champ est vide :
vider « Couches sur GPU » ne changeait donc rien. Or llama.cpp sait ajuster
lui-même le nombre de couches à la mémoire libre (common_fit_params), mais y
renonce dès que la valeur est imposée — « n_gpu_layers already set by user to
999, abort ». D'où, sur une carte trop juste pour le contexte demandé, des
cudaMalloc en échec, un repli partiel sur le CPU, et un débit effondré alors
que le GPU tourne à 100 %.

NGL=auto n'envoie plus -ngl du tout. Le défaut reste 999 : omettre le drapeau
sur un llama.cpp antérieur à cet ajustement le ferait tourner 100 % CPU.
Le champ de l'UI passe en texte pour accepter « auto ».

Vérifié : NGL=auto → aucun -ngl dans la ligne de commande ; NGL=999 → -ngl 999.
2026-08-15 11:11:40 +00:00
Loki de6551a153 Rebaptise AJEAN en Loki (fork, lignée conservée)
- module github.com/R0m1k3/Loki, cmd/loki, internal/loki (package loki)
- LOKI_HOME, LOKI_MODEL_DIRS, LOKI_SERVICE, LOKI_DL_CONNS ; /etc/loki ;
  units loki-engine / loki-ui ; binaire et aide CLI
- updateRepo pointe sur R0m1k3/Loki (l'auto-update ne tirera plus les
  binaires AJEAN amont)

Conservé à l'identique : le domaine ajean.link (service de tunnel amont),
les littéraux de migration 0.7.x (migrate_07.go), RELEASE_NOTES.md et
LICENSE (historique et licence de l'amont).

go build/vet/test : verts.
2026-08-14 21:33:15 +00:00