# Architecture IA & GPU/VRAM — état au 2026-06-05 > Rapport consolidé (2 agents d'analyse + vérifications runtime directes). But : vue > unique « quel composant IA, quel modèle/lib, à quoi il sert, GPU ou CPU, quelle VRAM », > et signaler les anomalies vitesse/précision à trancher. > Source de vérité : code réel + runtime (`nvidia-smi`, `ss`, `ollama ps`), pas suppositions. ## 0. Fait majeur — Ollama tourne sur le DGX, pas en local `127.0.0.1:11434` est un **tunnel SSH** (vérifié `ss -tlnp`) : ``` ssh -N -T -L 127.0.0.1:11434:127.0.0.1:11434 aivanov@192.168.1.45 (pid 1883636) ``` → **Tous les VLM/LLM (grounding, reasoning, t2a) s'exécutent sur le DGX `192.168.1.45`.** Le RTX 5070 local ne porte plus que CLIP + contextes torch. **État VRAM RTX 5070 (instant t) :** `2534 / 12227 MiB utilisés → 9231 MiB libres`. ## 1. Tableau maître des composants IA | Composant / Rôle | Modèle / lib | Device actuel | VRAM | Où | Statut | |---|---|---|---|---|---| | VLM grounding bbox (clic) | `qwen2.5vl:7b-rpa` (Ollama) | **DGX** | ~5.5 Go (DGX) | `vlm_config.get_bbox_grounding_model`, `resolve_engine` | actif | | VLM reasoning V4 / ORA | `qwen2.5vl:7b-rpa` | DGX | partagé | `vlm_config.get_reasoning_model` | actif | | VLM généraliste (default) | `qwen2.5vl:7b-rpa` (fallbacks `qwen3-vl:8b`, `ui-tars`) | DGX | ~5.5 Go | `vlm_config.get_vlm_model` | actif | | VLM critic | `qwen2.5vl:7b-rpa` (hardcodé) | DGX | partagé | `stream_processor._CRITIC_MODEL` | actif | | VLM recording VWB | `gemma4:e4b` (env) | DGX | — | `catalog_routes_v2_vlm.py` | actif (recording) ⚠ default ≠ runtime | | t2a_decision | `qwen2.5:7b` (texte) | DGX | — | `core/llm/t2a_decision.py` | actif | | OCR cascade | **docTR** `ocr_predictor` | **CPU** | 0 | `resolve_engine._resolve_by_ocr_text` | actif | | OCR extraction/validation | **EasyOCR** fr+en (`gpu=False` défaut, flag `easyocr_gpu_enabled`) + tesseract | **CPU** | 0 | `core/llm/ocr_extractor.py`, `resolve_engine:2480` | actif | | Détection UI icônes (SoM) | **YOLOv8** (OmniParser weights, ultralytics) | **CPU** (`get_shared_engine` défaut cpu ; engine supporte cuda) | 0 | `core/detection/som_engine.py`, `resolve_engine._resolve_by_yolo` | actif | | Embeddings / vérif état | **CLIP open_clip ViT-B-32** | **GPU local (auto-cuda si VRAM libre)** | ~1 Go | `core/embedding/clip_embedder.py` | actif | | Index similarité | **FAISS** | **CPU** | 0 | `core/embedding/faiss_manager.py` | actif | | Template matching | `cv2.matchTemplate` | CPU | 0 | `resolve_engine`, `core/grounding/template_matcher.py` | actif | | pHash | `imagehash.phash` | CPU | 0 | `core/analytics/screen_change_detector.py` | actif | | UI-DETR-1 (overlays numérotés) | `rfdetr RFDETRMedium` (model.pth 535 Mo) | **CUDA si dispo** | ~1–2 Go | `visual_workflow_builder/.../ui_detection_service.py` | actif **recording VWB only** | | OmniParser / Florence2 | YOLOv8 + Florence2 | GPU (lazy) | ~2 Go si chargé | `resolve_engine.py:419 _get_omniparser`, `core/detection/omniparser_adapter.py` | **WIRED** dans la cascade serveur (lazy-load) ; désactivé **uniquement au recording VWB** par choix (UI-DETR-1) | | UI-TARS (grounder GUI) | `ui-tars-1.5-7b` (Ollama) | DGX | — | `core/execution/input_handler.py:390/568 _grounding_ui_tars`, appelé par `observe_reason_act` | **WIRED** — Niveau 2 de la cascade grounding (~3s) | | InfiGUI | infigui_server | — | — | `core/grounding/` | statut à confirmer (audit P1.g-hygiene) | | `qwen3.5:9b` (grounding JSON) | profil `get_grounding_profile` | DGX | — | `vlm_config.get_grounding_profile` | **absent DGX** → retombe sur qwen2.5vl ; chemin peu/pas exercé | | ONNX | — | — | — | — | **inexistant** (mentionné CLAUDE.md mais pas dans le code) | ## 2. Cascade de résolution UI (ordre réel implémenté) `OCR docTR (CPU)` → `template cv2 (CPU)` → `YOLO/SoM (CPU)` → `VLM (DGX)`, + vérification de sortie **CLIP** (sim ≥ 0.75, GPU local) + EasyOCR title-check (CPU). **Tout est CPU sauf le VLM final (DGX) et CLIP (GPU local).** Conforme au contrat « 100% vision ». Premier essai vLLM `:8100` pour le VLM, **actuellement down** → fallback Ollama DGX. ## 3. ⚠ Anomalies à trancher (vitesse / précision / qualité) ### 3.1 CPU alors que 9 Go de VRAM libres en local — sous-optimal La politique « OCR/YOLO sur CPU » était justifiée **quand Ollama tournait en local** (éviter de concurrencer la VRAM des VLM 7B sur 12 Go). **Depuis le passage Ollama → DGX, la RTX a 9 Go libres** : faire tourner OCR (docTR/EasyOCR) et YOLO/SoM en CPU est désormais un frein à la vitesse, sans raison VRAM. Les leviers existent déjà : flag `easyocr_gpu_enabled`, paramètre `device` de `SomEngine`/`get_shared_engine`, docTR `.cuda()`. → **Changement de config, pas réécriture.** CLIP s'auto-adapte déjà (cuda si VRAM libre). **À noter** : tout devra être réinstallé/validé sur le DGX ensuite — donc faire le travail GPU proprement (paramétrable par device) plutôt que de hardcoder cuda. ### 3.2 Statut des technos précision/qualité — CORRECTION (2026-06-05, suite QG Qwen) ⚠ **Rectification d'une première version erronée.** Une analyse initiale (agent, scope limité à `agent_v0/server_v1/` imports directs) avait classé OmniParser et UI-TARS comme « orphelins ». **C'est FAUX** — vérifié dans le code : - **OmniParser/Florence2 : WIRED.** `resolve_engine.py:419 _get_omniparser()` (lazy-load GPU singleton) dans la section « YOLO/OmniParser » de la cascade serveur. Le `False` hardcodé vu par l'agent était dans le **VWB recording** (`ui_detection_service.py`), désactivé là **par choix** (UI-DETR-1) — pas dans le runtime serveur. - **UI-TARS : WIRED.** `input_handler.py:390` l'appelle comme « Niveau 2 — UI-TARS grounding (~3s) » dans `_ground_text()` ; importé aussi par `observe_reason_act`. Niveau actif de la cascade de grounding V4. - **InfiGUI** : statut non confirmé → audit P1.g-hygiene. - **`qwen3.5:9b`** : default du profil grounding JSON, **absent du DGX** → à pull si on veut ce chemin, sinon nettoyer le code mort (seul vrai « débranché » du lot). - **ONNX** : référencé CLAUDE.md mais inexistant → corriger la doc. **Conclusion** : les technos de précision (OmniParser, UI-TARS, Florence2) **ne sont pas débranchées**. Le seul levier réellement ouvert ici est `qwen3.5:9b` (à pull ou nettoyer). Tout rebranchage/réévaluation doit s'appuyer sur un **bench précision**, pas par principe. ### 3.3 `vram_orchestrator` semi-inopérant Conçu pour Ollama-local (il fait `systemctl restart ollama` pour purger la VRAM). Avec Ollama sur DGX, ce restart local n'a plus d'effet sur la VRAM des VLM → à revoir / clarifier (utile seulement si plan B retour RTX-local). ## 4. Directive Dom (2026-06-05) > « Pas normal de tourner sur CPU alors qu'on a du GPU/VRAM suffisant en local sur la RTX > pour le moment ; tout devra être installé sur le DGX par la suite. Pourquoi ces technos > (OmniParser/Florence2, UI-TARS/InfiGUI, qwen3.5) ne sont plus branchées ? On cherche > vitesse, précision, qualité. » **Pistes d'action** (à cadrer avec Codex/Qwen) : 1. Basculer OCR (docTR/EasyOCR) + YOLO/SoM sur **GPU local** (paramétrable par device, pas hardcodé), tant qu'Ollama est sur DGX et la RTX libre — gain de vitesse immédiat, zéro risque VRAM. Prévoir le portage propre sur DGX. 2. Investiguer le statut réel (dette vs choix) de **UI-TARS/InfiGUI** et **OmniParser** : bench précision avant de rebrancher, ne pas rebrancher aveuglément. 3. Décider de **`qwen3.5:9b`** : pull sur DGX (réactiver profil grounding JSON) ou retirer le code mort. 4. Corriger CLAUDE.md (ONNX inexistant, préciser docTR/EasyOCR). ## 5. Synthèse (5 lignes) 1. Un seul VLM actif (`qwen2.5vl:7b-rpa`) pour grounding+reasoning+généraliste+critic, sur le **DGX** via tunnel SSH. 2. Toute la cascade vision (docTR, EasyOCR, YOLO, cv2, pHash, FAISS) tourne en **CPU local** ; seul **CLIP** utilise le GPU RTX (~1 Go). 3. La RTX a **9 Go libres** → opportunité immédiate de basculer OCR/YOLO sur GPU pour la vitesse. 4. **OmniParser, UI-TARS, Florence2 sont WIRED** dans la cascade serveur/V4 (correction post-QG Qwen) ; **UI-DETR-1** ne sert qu'au recording VWB ; seuls **qwen3.5:9b** (absent DGX) et **ONNX** (inexistant) sont réellement à traiter. 5. **`vram_orchestrator`** est semi-mort depuis le passage Ollama-DGX.