- Add SESSION-2026-07-20-JEAN-ROUTER.md (complete session journal) - Add ARCHITECTURE-JEAN-ROUTER.md (new architecture documentation) - Remove ARCHITECTURE-LITELLM.md (replaced by jean-router) - Update README.md with jean-router, Jean backend, and VRAM management - Document dynamic preset discovery and VRAM switching logic
9.0 KiB
Session 2026-07-20 : jean-router et gestion VRAM dynamique
Résumé
Création de jean-router, un proxy dynamique qui remplace LiteLLM pour router intelligemment entre Jean (llama.cpp) et Ollama, avec gestion automatique de la VRAM partagée.
Contexte
Problème initial
- OpenWebUI ne voyait pas les modèles Jean (Ornith) car configuré uniquement pour Ollama
- LiteLLM avait une configuration statique des modèles (codée en dur dans
litellm/config.yaml) - Nouveaux presets Jean nécessitaient de modifier manuellement la config LiteLLM
- Jean et Ollama partagent la même VRAM (RX 7800 XT, 16GB) → contention mémoire
Architecture avant
OpenWebUI → LiteLLM:4000 (config statique)
├→ jean-proxy:3012 → Jean (.11:8080)
└→ wol-proxy:3011 → Ollama (.11:11434)
Problèmes :
- LiteLLM ne faisait pas de pass-through de
/v1/models - Configuration statique :
qwen3.6-reason,qwen3.6-27b, etc. codés en dur - Jean faisait tourner Ornith mais LiteLLM attendait Qwen3.6
- Pas de gestion VRAM : Jean et Ollama pouvaient charger simultanément → OOM
Solution : jean-router
Architecture après
OpenWebUI → jean-router:3014 (routing dynamique)
├→ jean-proxy:3012 → Jean (.11:8080)
└→ wol-proxy:3011 → Ollama (.11:11434)
Fonctionnalités
1. Découverte dynamique des modèles
- Interroge
/api/presetsde Jean (port 8090) pour lister les presets disponibles - Interroge
/api/tagsd'Ollama (port 11434) pour lister les modèles - Expose tout via
/v1/models(API OpenAI-compatible) - Nouveaux presets Jean automatiquement visibles dans OpenWebUI
2. Routing intelligent
- Si le modèle demandé est un preset Jean → switch automatique + route vers Jean
- Si c'est un modèle Ollama → route vers Ollama
- Sinon → erreur 404
3. Gestion VRAM (RX 7800 XT, 16GB partagés)
| Backend | Modèle typique | VRAM utilisée |
|---|---|---|
| Jean | Ornith 35B Q6_K | ~28.5GB (déborde en RAM) |
| Ollama | mistral/qwen3.5 | ~4-6GB |
Logique de gestion :
Switch Jean → Ollama :
stop_jean()arrête Jean via son API web (port 8090)- Attend confirmation que Jean est arrêté (max 30s)
- Route la requête vers Ollama
Switch Ollama → Jean :
- Programme le déchargement d'Ollama dans 5 minutes (timer)
start_jean()redémarre Jean- Attend que le modèle soit chargé (max 90s)
- Route la requête vers Jean
Timer Ollama :
- Ollama reste en mémoire pendant 5 minutes après le dernier usage
- Chaque requête vers Ollama annule le timer
- Si retour sur Ollama avant expiration → déchargement annulé
- Après 5 min d'inactivité → déchargement automatique pour libérer VRAM
Fichiers créés/modifiés
Nouveau : jean-router/
app.py(320 lignes) : Service Flask avec routing dynamique + gestion VRAMDockerfile: Container Python 3.12-slim
Modifiés :
docker-compose.litellm.yml:- Ajout service jean-router
- Suppression service litellm
- OpenWebUI pointe directement vers jean-router:3014
litellm/config.yaml: Supprimé (plus nécessaire)
Configuration jean-router
environment:
- JEAN_WEB_HOST=${OLLAMA_HOST}
- JEAN_WEB_PORT=8090
- JEAN_PROXY_HOST=localhost
- JEAN_PROXY_PORT=3012
- OLLAMA_PROXY_HOST=localhost
- OLLAMA_PROXY_PORT=3011
- OLLAMA_DIRECT_HOST=${OLLAMA_HOST}
- OLLAMA_DIRECT_PORT=11434
- ENABLE_OLLAMA=true
- ENABLE_VRAM_MANAGEMENT=true
- OLLAMA_KEEP_ALIVE_MINUTES=5
- LISTEN_PORT=3014
- SWITCH_TIMEOUT=90
- CHECK_INTERVAL=2
- JEAN_STOP_TIMEOUT=30
- OLLAMA_UNLOAD_TIMEOUT=15
Déploiement sur effi-server
Initialisation du repo git
Le dossier /home/effi/effi n'était pas un repo git. Initialisation :
cd /home/effi/effi
git init
git remote add origin https://gitea.folzocorp.fr/Folzo/Effi.git
git fetch origin
git checkout -b main origin/main
Note : Conflits avec fichiers existants (docker-compose.yml, jean-proxy/, etc.) résolus en les déplaçant temporairement dans /tmp/effi-backup/.
Commandes de déploiement
cd /home/effi/effi
git pull
docker compose -f docker-compose.yml -f docker-compose.litellm.yml up -d --build jean-router
docker compose -f docker-compose.yml -f docker-compose.litellm.yml up -d --force-recreate open-webui
docker stop litellm && docker rm litellm # Suppression LiteLLM
Tests et validation
Modèles visibles dans OpenWebUI
Jean (5 presets) :
- ornith-35b-q6 (actif, Q6_K, reasoning)
- qwen3.6-27b-mtp (IQ4_XS, reasoning)
- qwen3.6-35b-moe-compact
- qwen3.6-35b-moe-compact-reason (reasoning)
- qwen3.6-35b-moe-nano
Ollama :
- mistral (7.2B, Q4_K_M, tools)
- qwen3.5:9b (9.7B, Q4_K_M, vision, thinking)
Logs observés
Switch Jean → Ollama :
[VRAM] Switch Jean → Ollama
[VRAM] Arrêt de Jean pour libérer la VRAM...
[VRAM] Jean arrêté via API web
[VRAM] Jean confirmé arrêté
[Router] → Ollama (gemma4:e4b)
Switch Ollama → Jean :
[VRAM] Switch Ollama → Jean
[VRAM] Déchargement Ollama programmé dans 5 minutes
[VRAM] Démarrage de Jean...
[VRAM] Jean prêt après 45s
[Router] → Jean (ornith-35b-q6)
Timer Ollama :
[VRAM] Timer écoulé (5min), déchargement Ollama...
[VRAM] Ollama déchargé via API
Avantages
- Dynamique : Nouveaux presets Jean automatiquement visibles sans modifier de config
- Simplifié : Une couche de moins (LiteLLM supprimé)
- VRAM-safe : Pas de contention mémoire entre Jean et Ollama
- Intelligent : Ollama reste en mémoire 5 min pour les usages répétés
- Transparent : OpenWebUI voit tous les modèles via un seul endpoint
Limitations et points d'attention
1. Jean n'a pas d'auto-unload natif
- Ollama décharge automatiquement après
OLLAMA_KEEP_ALIVE(défaut 5min) - Jean garde son modèle chargé tant que le service tourne
- Solution actuelle : Arrêt complet de Jean via API web
2. Latence de switch
- Jean → Ollama : ~3s (arrêt Jean)
- Ollama → Jean : ~45-90s (démarrage + chargement modèle)
- Impact : Première requête après switch plus lente
3. Timer Ollama non-persistant
- Si jean-router redémarre, le timer est perdu
- Ollama restera en mémoire indéfiniment (jusqu'à son propre timeout)
- Acceptable : Ollama gère son propre
keep_alive
4. Pas de failover
- Si Jean échoue (timeout, erreur), pas de fallback automatique vers Ollama
- À considérer : Ajouter un fallback dans jean-router si besoin
Commits Gitea
8b7c4fb feat: add VRAM management for Jean/Ollama switching
20767c2 feat: keep Ollama models in memory for 5 minutes
babe4ee chore: add OLLAMA_KEEP_ALIVE_MINUTES=5 to docker-compose
43aacc0 refactor: OpenWebUI points directly to jean-router (no LiteLLM needed)
856ba4a refactor: remove LiteLLM, jean-router handles all routing
fcad415 feat: jean-router — routing dynamique Jean + Ollama
b441f34 fix: jean-router syntax error (missing except block)
Réflexions et décisions
Pourquoi supprimer LiteLLM ?
- LiteLLM ne faisait pas de pass-through de
/v1/models - Configuration statique incompatible avec les presets dynamiques de Jean
- Couche supplémentaire inutile : jean-router fait le même travail
- Décision : OpenWebUI pointe directement vers jean-router:3014
Pourquoi garder Ollama en mémoire 5 min ?
- Ollama sert principalement pour la vision (modèles que Jean ne supporte pas)
- Usage typique : quelques requêtes vision consécutives, puis retour à Jean
- 5 min = bon compromis entre réactivité et libération VRAM
- Configurable :
OLLAMA_KEEP_ALIVE_MINUTESdans docker-compose
Pourquoi arrêter Jean complètement ?
- Jean n'a pas d'API pour décharger le modèle sans arrêter le service
- Le modèle reste en VRAM tant que llama-server tourne
- Alternative envisagée :
systemctl stop jean(mais nécessite sudo) - Solution retenue : API web de Jean (
/api/stop) plus simple
Architecture future possible
- JeanOrchestrator : Jean pourrait gérer lui-même le switch entre presets
- VRAM monitoring : jean-router pourrait vérifier la VRAM disponible avant de router
- Fallback automatique : Si Jean échoue, router vers Ollama
- Metrics : Exposer des statistiques (temps de switch, VRAM utilisée, etc.)
Prochaines étapes
- Monitorer : Vérifier que la gestion VRAM fonctionne bien en production
- Ajuster : Modifier
OLLAMA_KEEP_ALIVE_MINUTESselon l'usage réel - Documenter : Mettre à jour
docs/ARCHITECTURE-LITELLM.md(à renommerARCHITECTURE-JEAN-ROUTER.md) - Tester : Valider que les nouveaux presets Jean apparaissent bien automatiquement
Conclusion
jean-router remplace avantageusement LiteLLM avec :
- Routing dynamique basé sur les presets Jean
- Gestion automatique de la VRAM partagée
- Architecture simplifiée (une couche de moins)
- Nouveaux modèles automatiquement disponibles
L'architecture est maintenant prête pour Effi : quand un nouveau preset Jean est créé, il apparaît immédiatement dans OpenWebUI sans aucune configuration supplémentaire.