33800 Docs

← Retour

Proposition : Réactivation GPU1 (2070S) + Routing intelligent

Date : 13/02/2026 23:00 Status : EN ATTENTE VALIDATION

Contexte

La RTX 2070 Super (GPU1, 8 Go VRAM) a été désactivée lors du fix ulias-org v0.8.0 pour simplifier le debug. Mais son rôle initial était de gérer les requêtes Ollama légères pendant que la RTX 3090 (GPU0) fait du Wan2.1, ComfyUI, etc. Ca marchait bien sur connectors.

Problème actuel

  1. ulias-org hardcode gpu: 0 dans interpreter.ts et client.ts → l'orchestrator ne peut jamais router vers GPU1
  2. Seuil GPU1 trop bas : 2000 MB max dans determine_preferred_gpu() → seuls les ≤3B passent, alors que des 7B (4.5 Go) tiennent sur la 2070S (~6.5 Go utilisables)
  3. Pas d'optimisation unload : pas d'analyse des pending jobs avant de décharger un modèle

Plan

Etape 1 : Réactiver ollama-gpu1 sur Win11

Etape 2 : ulias-org — Laisser l'orchestrator décider

Etape 3 : ai-orchestrator — Routing plus intelligent

a) Whitelist modèles GPU1 (basée sur VRAM réelle)

Remplacer le seuil fixe 2000 MB par une whitelist dynamique basée sur _estimate_ollama_vram() :

GPU1_VRAM_MAX = 6000  # 8192 total - ~2 Go driver/OS = ~6 Go utilisable

def can_fit_gpu1(model: str) -> bool:
    vram = _estimate_ollama_vram(model)
    return vram <= GPU1_VRAM_MAX

Modèles qui passent sur GPU1 (6 Go max) : | Modèle | VRAM estimée | GPU1 ? | |--------|-------------|--------| | nomic-embed-text | 400 MB | OK | | llama3.2 (3b) | 2000 MB | OK | | gemma3:4b | 2500 MB | OK | | qwen2.5:7b | 4500 MB | OK | | mistral:7b | 4500 MB | OK | | qwen3:8b | 5000 MB | OK (juste) | | phi3:14b | 9000 MB | NON | | devstral-small-2 (24B) | 15000 MB | NON |

b) Routing amélioré dans determine_preferred_gpu()

def determine_preferred_gpu(job_data, gpu_slots):
    vram_needed = estimate_vram(job_data)

    # Modèle trop gros pour GPU1 → GPU0 direct
    if vram_needed > GPU1_VRAM_MAX:
        return 0

    # GPU0 occupé par tâche exclusive (Wan2.1, ComfyUI...) → GPU1
    gpu0_busy_exclusive = any(not is_server_tool(s) for s in gpu_slots[0])
    if gpu0_busy_exclusive and can_dispatch(1, ...):
        return 1

    # Modèle déjà chargé sur un GPU → préférer celui-là (évite reload)
    if model_loaded_on_gpu(model, 1):
        return 1
    if model_loaded_on_gpu(model, 0):
        return 0

    # Petit modèle (embeddings, ≤3B) → GPU1 par défaut
    if vram_needed <= 2000:
        return 1

    # Modèle moyen (7B-8B) → GPU0 par défaut, GPU1 en fallback
    return 0

c) Analyse des pending avant unload

Avant de décharger un modèle sur GPU1, vérifier la queue :

def should_keep_model_loaded(gpu_id, current_model):
    # Regarder les N prochains jobs en attente
    pending = get_pending_jobs(limit=10)
    for job in pending:
        if job.model == current_model and can_fit_gpu(gpu_id, job):
            return True  # Même modèle arrive → garder chargé
    return False

Note : GPU1 a déjà keep_alive = -1 (garde le modèle indéfiniment), donc ce point est surtout utile si on change cette stratégie.

Etape 4 : Test et validation

Risques

Fichiers modifiés

Projet Fichier Changement
ulias-org packages/server/src/tools/client.ts Retirer hardcode gpu: 0
ulias-org packages/server/src/agents/interpreter.ts Retirer gpu: 0
ai-orchestrator app/main.py Seuil GPU1 2000→6000, routing amélioré

Validation requise