- 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
11 KiB
Architecture LLM — jean-router (routing dynamique + gestion VRAM)
Vue d'ensemble
┌─────────────────────────────────────────────────────────────────┐
│ OpenWebUI (:3000) │
│ http://192.168.1.27:3000 │
└────────────────────────┬────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ jean-router (:3014) │
│ Routing dynamique + Gestion VRAM automatique │
│ │
│ • Interroge Jean /api/presets (découverte dynamique) │
│ • Interroge Ollama /api/tags (modèles vision) │
│ • Switch automatique de preset Jean │
│ • Arrête Jean quand on passe sur Ollama (libère VRAM) │
│ • Garde Ollama 5 min en mémoire avant déchargement │
└────────┬──────────────────────────────────────┬────────────────┘
│ │
▼ ▼
┌────────────────────────┐ ┌────────────────────────┐
│ jean-proxy (:3012) │ │ wol-proxy (:3011) │
│ + WOL si PC éteint │ │ + WOL si PC éteint │
└────────┬───────────────┘ └────────┬───────────────┘
│ │
▼ ▼
┌────────────────────────┐ ┌────────────────────────┐
│ Jean (.11:8080) │ │ Ollama (.11:11434) │
│ llama.cpp server │ │ Modèles vision │
│ Presets dynamiques │ │ mistral, qwen3.5 │
│ Ornith, Qwen3.6... │ │ │
└────────────────────────┘ └────────────────────────┘
Composants
jean-router (/jean-router/) — Proxy dynamique
Rôle : Router intelligemment entre Jean et Ollama avec gestion VRAM
Fonctionnalités :
- Découverte dynamique : Interroge
/api/presets(Jean) et/api/tags(Ollama) - Routing intelligent : Route vers Jean ou Ollama selon le modèle demandé
- Switch automatique : Change de preset Jean si nécessaire
- Gestion VRAM : Évite la contention mémoire entre Jean et Ollama
Endpoints :
GET /v1/models: Liste tous les modèles (Jean + Ollama)POST /v1/chat/completions: Route vers le bon backend
Configuration :
JEAN_WEB_HOST=192.168.1.11 # Jean Web UI (API presets)
JEAN_WEB_PORT=8090
JEAN_PROXY_HOST=localhost # jean-proxy (backend Jean)
JEAN_PROXY_PORT=3012
OLLAMA_PROXY_HOST=localhost # wol-proxy (backend Ollama)
OLLAMA_PROXY_PORT=3011
OLLAMA_DIRECT_HOST=192.168.1.11 # Ollama direct (pour unload)
OLLAMA_DIRECT_PORT=11434
ENABLE_OLLAMA=true
ENABLE_VRAM_MANAGEMENT=true
OLLAMA_KEEP_ALIVE_MINUTES=5 # Ollama reste 5 min en mémoire
SWITCH_TIMEOUT=90 # Timeout chargement Jean (s)
JEAN_STOP_TIMEOUT=30 # Timeout arrêt Jean (s)
LISTEN_PORT=3014
jean-proxy (/jean-proxy/) — Reverse-proxy Jean + WOL
Rôle : Proxy vers Jean avec Wake-on-LAN si le PC gaming est éteint
Fonctionnalités :
- Écoute
:3012sur le host (network_mode: host) - Health-check :
GET /healthsur Jean - Si cible DOWN → envoi paquets WOL vers
TARGET_MAC - Attente jusqu'à
WAKE_TIMEOUT(60s) - Route toutes les requêtes vers
http://${OLLAMA_HOST}:8080
Configuration :
TARGET_HOST=192.168.1.11
TARGET_PORT=8080
TARGET_MAC=04:D9:F5:D1:EC:DF
LISTEN_PORT=3012
WAKE_TIMEOUT=60
CHECK_INTERVAL=5
BROADCAST_IP=192.168.1.255
HEALTH_PATH=/health
wol-proxy (/wol-proxy/) — Reverse-proxy Ollama + WOL
Rôle : Proxy vers Ollama avec Wake-on-LAN
Fonctionnalités :
- Écoute
:3011sur le host - Health-check :
GET /api/versionsur Ollama - Si cible DOWN → envoi paquets WOL
- Route toutes les requêtes vers
http://${OLLAMA_HOST}:11434
Configuration :
TARGET_HOST=192.168.1.11
TARGET_PORT=11434
TARGET_MAC=04:D9:F5:D1:EC:DF
LISTEN_PORT=3011
WAKE_TIMEOUT=180
CHECK_INTERVAL=5
BROADCAST_IP=192.168.1.255
Gestion VRAM
Problème
Jean et Ollama partagent la même carte graphique (RX 7800 XT, 16GB VRAM). Charger les deux simultanément cause une contention mémoire.
| Backend | Modèle typique | VRAM utilisée |
|---|---|---|
| Jean | Ornith 35B Q6_K | ~28.5GB (déborde en RAM) |
| Ollama | mistral 7B Q4_K_M | ~4GB |
| Ollama | qwen3.5:9b Q4_K_M | ~6GB |
Solution : Switch automatique
Switch Jean → Ollama :
1. Arrêt de Jean via API web (/api/stop)
2. Attente confirmation (max 30s)
3. Route requête vers Ollama
Switch Ollama → Jean :
1. Programme déchargement Ollama dans 5 min (timer)
2. Démarrage de Jean via API web (/api/start)
3. Attente chargement modèle (max 90s)
4. Route 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
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
Modèles disponibles
Jean (presets dynamiques)
Les presets sont découverts automatiquement via /api/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
Note : Nouveaux presets Jean apparaissent automatiquement dans OpenWebUI sans configuration.
Ollama (modèles vision)
- mistral (7.2B, Q4_K_M, tools)
- qwen3.5:9b (9.7B, Q4_K_M, vision, thinking)
Note : Ollama sert principalement pour les modèles avec vision que Jean ne supporte pas.
Déploiement
Commandes (sur effi-server .27)
cd /home/effi/effi
git pull
# Build et démarrage jean-router
docker compose -f docker-compose.yml -f docker-compose.litellm.yml up -d --build jean-router
# Recréer open-webui avec nouvelle config
docker compose -f docker-compose.yml -f docker-compose.litellm.yml up -d --force-recreate open-webui
# Vérifier
docker logs jean-router --tail 20
curl -s http://localhost:3014/v1/models | jq
Tests
1. Liste des modèles :
curl -s http://localhost:3014/v1/models | python3 -m json.tool
2. Requête Jean :
curl -X POST http://localhost:3014/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "ornith-35b-q6",
"messages": [{"role": "user", "content": "Bonjour"}],
"max_tokens": 50
}'
3. Requête Ollama :
curl -X POST http://localhost:3014/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "mistral",
"messages": [{"role": "user", "content": "Hello"}],
"max_tokens": 30
}'
4. Vérifier logs VRAM :
docker logs jean-router -f | grep -E "VRAM|Router"
Avantages vs LiteLLM
| Aspect | LiteLLM | jean-router |
|---|---|---|
| Configuration | Statique (config.yaml) | Dynamique (API Jean) |
| Nouveaux presets | Modifier config + restart | Automatique |
| Pass-through /v1/models | Non | Oui |
| Gestion VRAM | Aucune | Automatique |
| Couches | 2 (LiteLLM + jean-proxy) | 1 (jean-router) |
| Complexité | Élevée | Faible |
Limitations
1. 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
2. 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
3. Pas de failover
- Si Jean échoue (timeout, erreur), pas de fallback automatique vers Ollama
- À considérer : Ajouter un fallback dans jean-router si besoin
4. 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
Évolution possible
Court terme
- Monitorer : Vérifier que la gestion VRAM fonctionne bien en production
- Ajuster : Modifier
OLLAMA_KEEP_ALIVE_MINUTESselon l'usage réel - Tester : Valider que les nouveaux presets Jean apparaissent bien automatiquement
Moyen terme
- 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.)
Long terme
- JeanOrchestrator : Jean pourrait gérer lui-même le switch entre presets
- Multi-GPU : Si plusieurs GPU, router vers celui avec le plus de VRAM libre
- Load balancing : Si plusieurs instances Jean/Ollama, répartir la charge
Historique
2026-06-27 : Architecture initiale avec LiteLLM
- Routing statique par nom de modèle
- Configuration codée en dur dans
litellm/config.yaml
2026-07-20 : Migration vers jean-router
- Routing dynamique basé sur les presets Jean
- Gestion automatique de la VRAM
- Suppression de LiteLLM (une couche de moins)
- Nouveaux modèles automatiquement disponibles
Références
- Code jean-router :
/jean-router/app.py - Docker compose :
/docker-compose.litellm.yml - Journal de session :
/docs/05-journal/SESSION-2026-07-20-JEAN-ROUTER.md - Repo Gitea : https://gitea.folzocorp.fr/Folzo/Effi