Files
Effi/docs/ARCHITECTURE-JEAN-ROUTER.md
T
Folzo e9cd1edbff docs: add jean-router architecture and session journal
- 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
2026-07-20 11:22:47 +02:00

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 :

  1. Découverte dynamique : Interroge /api/presets (Jean) et /api/tags (Ollama)
  2. Routing intelligent : Route vers Jean ou Ollama selon le modèle demandé
  3. Switch automatique : Change de preset Jean si nécessaire
  4. 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 :3012 sur le host (network_mode: host)
  • Health-check : GET /health sur 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 :3011 sur le host
  • Health-check : GET /api/version sur 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_MINUTES selon 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