Claude 26e93f43ef Chercher et installer un modèle depuis Loki
Installer un modèle demandait d'aller sur huggingface.co, de naviguer dans
l'arborescence d'un dépôt et de coller un lien à la main. Rien ne disait si le
fichier tiendrait en mémoire, et surtout rien ne reliait un modèle à SON
projecteur vision : c'est ainsi qu'un mmproj-Qwen3VL-8B s'est retrouvé
configuré pour un Qwen3.8-27B — deux modèles sans rapport, moteur qui démarre
et ne voit rien.

La recherche Hugging Face arrive dans l'éditeur de preset. Elle ne remonte que
les dépôts GGUF ; déplier un dépôt montre ses quantifications avec leur taille
et un verdict mémoire, et propose le projecteur vision DU MÊME DÉPÔT — le seul
qui corresponde. Quand le dépôt n'en publie pas, Loki le dit au lieu d'aller en
chercher un ailleurs.

Le nouveau code ne télécharge rien : il produit des URL que le chemin existant
consomme tel quel (normalizeHFURL, shardURLSet, sonde d'espace disque, reprise
et annulation). Une file d'attente enchaîne modèle puis projecteur — le serveur
ne mène qu'un transfert à la fois, et le champ Vision ne se remplit que si le
modèle est déjà sélectionné.

Trois familles de .gguf cohabitent dans un dépôt et ne veulent pas dire la même
chose : mmproj-* (projecteur), mtp-* (poids de décodage spéculatif) et le
modèle. Les deux premières ressemblent à un modèle ; les proposer en vrac, ce
serait offrir de lancer llama-server sur un encodeur d'images. Les tranches
d'une famille sont repliées en une entrée de taille TOTALE : annoncer 15 Go
pour un modèle qui en occupe 45 promet une place qui n'existe pas.

Le verdict mémoire s'appuie enfin sur le GPU. detectHardware() ne renvoyait que
la RAM système alors que detectGPUs() existait déjà : sur un serveur à carte
NVIDIA, le verdict se prononçait sur la mauvaise grandeur. Le coût du cache KV
reste une estimation assumée — l'exact demanderait de parser l'en-tête GGUF —
et l'interface l'annonce comme telle plutôt que d'afficher un chiffre
faussement sûr.

Le catalogue ajean.link disparaît. Sa route n'avait aucun consommateur (l'écran
d'accueil qu'elle attendait n'a jamais existé), son repli embarqué proposait du
Qwen2.5 de 2024, et un fork qui laisse le serveur de l'amont décider de ce
qu'il propose n'est pas vraiment un fork.

Une piste écartée en cours de route : marquer les dépôts « vision » d'après les
tags Hugging Face. Ils mentent — des deux dépôts GGUF de Qwen3.8-27B qui
publient tous deux un mmproj, seul ggml-org est taggé image-text-to-text. Une
pastille sur l'un et pas sur l'autre aurait été pire que rien. La vision est
donc déduite de la seule source qui ne se trompe pas : la présence d'un
mmproj-*.gguf dans l'arborescence.

Vérifié : 8 tests unitaires sur les arborescences réelles des deux dépôts, puis
au navigateur contre le vrai Hugging Face — 25 dépôts trouvés, 3 quants listés
sans aucun mtp ni mmproj, projecteur Q8_0 proposé et coché, verdicts affichés
avec leur explication, modale dans l'écran. L'ordre de la file (modèle puis
projecteur) est testé en interceptant les appels, sans transfert.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VueWA9xcYadaYq65tBisix
2026-08-16 11:02:35 +00:00
2026-06-08 12:54:49 +02:00

Loki — assistant IA local en conteneur (fork d'AJEAN)

Loki est un fork de AJEAN de nathaninline, sous licence MIT — voir NOTICE.md et LICENSE. L'essentiel du code et des fonctionnalités vient d'AJEAN ; ce fork le rebaptise et le fait tourner dans un conteneur Docker GPU autonome, là où l'amont s'installe en binaire + systemd sur la machine hôte.

Loki fait tourner un modèle de langage 100 % en local : tchat, mémoire persistante, accès internet, outils MCP, agent (shell, fichiers), accès distant chiffré — serveur d'inférence llama.cpp compris, dans une seule image.

Architecture

┌────────────────── conteneur loki ──────────────────┐
│  loki web  (UI + API, port 8090, premier plan)     │
│     │ pilote (fichier PID — pas de systemd)        │
│  loki serve ──exec──► llama-server (CUDA, :8080)   │
│                        ▲ modèles .gguf             │
│  /data (config, bbolt, mémoire, workspace)         │
│  /models (GGUF déposés à la main)                  │
└────────────────────────────────────────────────────┘
  • Un seul conteneur : l'UI joint le moteur sur localhost (contrainte héritée de l'amont), les deux partagent donc le même conteneur.
  • Sans systemd : l'amont pilote le moteur via systemctl ; en conteneur, Loki bascule automatiquement sur une supervision par fichier PID (internal/loki/sys_service_container.go). Changer de modèle depuis l'UI redémarre le moteur normalement.
  • Le moteur (port 8080, non authentifié par défaut) n'est pas exposé ; seule l'UI (8090) l'est.

Démarrage rapide (Docker, GPU NVIDIA)

Pré-requis : pilote NVIDIA + NVIDIA Container Toolkit.

cp .env.example .env
docker compose up --build   # quelques minutes : llama-server vient précompilé
                            # de l'image officielle llama.cpp (server-cuda)

Interface : http://localhost:8090 — installe un modèle depuis la recherche Hugging Face intégrée (voir ci-dessous), il démarre tout seul.

Installer un modèle

Dans l'éditeur de preset, Chercher un modèle interroge Hugging Face et ne remonte que les dépôts GGUF. Choisir un dépôt déplie ses quantifications avec leur taille et un verdict mémoire (ok / juste / trop) calculé sur la VRAM réellement détectée — ou sur la RAM système s'il n'y a pas de GPU. C'est une estimation : le coût exact du cache KV dépend de l'architecture du modèle, que la seule liste des fichiers ne révèle pas.

Si le dépôt publie un projecteur vision (mmproj-*.gguf), Loki propose de l'installer avec le modèle et remplit le champ Vision du preset. C'est le seul moyen fiable d'avoir la vision : un projecteur encode dans l'espace latent de son modèle, donc un mmproj pris dans un autre dépôt donne un moteur qui démarre et ne voit rien. Quand le dépôt n'en publie pas, Loki le dit plutôt que d'aller en chercher un ailleurs.

Deux repères pour choisir un dépôt :

  • unsloth/* publie des quantifications Dynamic (UD-Q4_K_XL, UD-IQ3_XXS…) qui gardent en plus haute précision les tenseurs sensibles : à taille égale, elles se tiennent mieux qu'un Q4_K_M classique.
  • ggml-org/* est le dépôt de référence de l'équipe llama.cpp — c'est en général là que le projecteur vision est publié en premier.

Le champ Télécharger un modèle reste disponible pour coller un lien direct (dépôt privé, fichier hors des conventions). Un dépôt à accès restreint demande la variable d'environnement HF_TOKEN.

Installation sur Unraid

L'image est construite et publiée par GitHub Actions sur GHCR (ghcr.io/r0m1k3/loki:latest) à chaque push sur main — aucun build sur Unraid. Compose prêt à l'emploi : docker-compose.unraid.yml.

  1. Installe le plugin Nvidia Driver (Apps) et vérifie nvidia-smi.
  2. Crée les dossiers :
    mkdir -p /mnt/user/appdata/loki/data /mnt/user/appdata/loki/models
    
  3. Plugin Compose Manager → nouvelle stack → colle docker-compose.unraid.yml → Compose Up.
  4. Interface : http://<ip-unraid>:8090.

Configuration

Tout se règle dans l'UI (modèle, contexte, presets…) et survit aux redémarrages (volume /data). Variables d'environnement du conteneur :

Variable Rôle Défaut
LOKI_WEB_PORT port de l'UI 8090
LOKI_MODEL modèle initial (semé au 1er boot seulement) —
LOKI_CTX taille de contexte initiale 32768
LOKI_NGL couches GPU initiales 999 (tout)
LOKI_HOME données (volume) /data
LOKI_MODEL_DIRS dossiers .gguf additionnels /models

En CLI dans le conteneur : docker exec -it loki loki status (aussi : logs, restart, config, bench, test…).

Fonctionnalités (héritées d'AJEAN)

  • Tchat avec streaming, raisonnement visible, pièces jointes, vision (selon modèle), export de conversations.
  • Mémoire persistante (memory off|ondemand|always).
  • Accès internet : recherche + lecture de pages, moteur Go intégré ou Crawl4AI pour les pages JS.
  • Agent : shell, fichiers, workspace (agent on).
  • Serveurs MCP : Node.js est inclus dans l'image pour les serveurs npx.
  • Presets de configuration par modèle, bench, auto-détection GPU.
  • Accès distant chiffré via le relais ajean.link (service opéré par l'auteur de l'amont).
  • API OpenAI-compatible exposable (network on, protégée par clé).

Différences avec l'amont

AJEAN (amont) Loki (ce fork)
Installation binaire + sudo ajean install (systemd) docker compose up
Moteur llama.cpp compilé sur la machine (ajean llamacpp install) image officielle llama.cpp (server-cuda), précompilée
Supervision moteur systemd / launchd / PID (Windows) fichier PID (LOKI_CONTAINER=1)
Configuration initiale ajean edit ($EDITOR) entrypoint + loki config set
Mise à jour ajean update (binaire GitHub) docker compose pull

Le reste — UI, mémoire, outils, protocole — est celui d'AJEAN. Pour récupérer les évolutions de l'amont :

git fetch upstream && git merge upstream/main   # conflits de renommage à arbitrer

Build sans GPU / autres accélérateurs / version épinglée

L'image Loki se construit au-dessus de l'image serveur officielle de llama.cpp, choisie par le build-arg LLAMACPP_IMAGE :

# CPU seul (test sans GPU)
docker build --build-arg LLAMACPP_IMAGE=ghcr.io/ggml-org/llama.cpp:server .
# Vulkan (GPU AMD/Intel/NVIDIA sans CUDA)
docker build --build-arg LLAMACPP_IMAGE=ghcr.io/ggml-org/llama.cpp:server-vulkan .
# Version de llama.cpp épinglée (reproductible)
docker build --build-arg LLAMACPP_IMAGE=ghcr.io/ggml-org/llama.cpp:server-cuda-b10423 .

Aucune compilation de llama.cpp n'a lieu : le moteur est maintenu et précompilé par l'équipe amont (toutes architectures GPU courantes).

Licence

MIT — © les contributeurs d'AJEAN (« Jean contributors ») pour le code amont, voir LICENSE et NOTICE.md.

S
Description
No description provided
Readme MIT
21 MiB
0 Stars 1 Watchers 0 Forks
Languages
Go 68.2%
HTML 18.6%
JavaScript 9.5%
CSS 3.4%
Dockerfile 0.2%