Backup état complet après enregistrement vidéo démo de bout en bout. À utiliser comme point de référence pour la consolidation post-démo. Changements majeurs de la session 18-19 mai : - AIVA-URGENCE : page autonome avec preset URL + auto-focus chain - Workflow Demo_urgence_3_db : merge linux_db + steps AIVA + pause humaine NoMachine - Bypass LLM (static_result / static_text) dans replay_engine pour démos déterministes sans appel Ollama - Fix api_stream:3013 — replay_paused au premier polling /next - dag_execute : lift duration_ms vers top-level pour wait runtime - NPM bypass auth /aiva-urgence/ via location ^~ (proxy_host/10.conf hors git) - scripts/cancel-replays.sh — workaround Stop VWB qui ne purge pas la queue Anchors visuels (468) forcés dans le commit pour garantir restorabilité. DB workflows actuelle + ~12 .bak DB de la journée incluses. Sujets identifiés pour consolidation post-démo (TODO) : 1. Bug VWB recapture anchor ne régénère pas le PNG 2. Léa client accumule état mémoire (restart périodique requis) 3. Stop VWB ne purge pas la queue serveur (lien manquant vers /replay/cancel) 4. Bug coord client mss tronqué 2560x60 → mapping Y cassé 5. delay_before/delay_after ignorés au runtime (fix partiel duration_ms) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
131 lines
5.3 KiB
Markdown
131 lines
5.3 KiB
Markdown
# Budget VRAM — RPA Vision V3
|
||
|
||
GPU cible : **NVIDIA RTX 5070, 12 GB VRAM**.
|
||
|
||
Ce document fige les choix d'allocation pour éviter les chevauchements et crashs CUDA quand plusieurs services tournent en parallèle. À jour au 26 avril 2026 (Phase 1A — service grounding persistant).
|
||
|
||
## Hypothèse d'usage
|
||
|
||
Dom fait soit du **RECORD** (création de workflow dans le VWB), soit du **REPLAY** (exécution d'un workflow), mais pas les deux en même temps. C'est cette hypothèse qui rend les modes ci-dessous compatibles.
|
||
|
||
## Modèles résidents permanents (3.6 GB)
|
||
|
||
Ces modèles restent en VRAM en permanence pour éviter le coût de chargement à chaque appel.
|
||
|
||
| Modèle | VRAM | Hébergement | Pourquoi permanent |
|
||
|---|---|---|---|
|
||
| **InfiGUI-G1-3B** (4-bit NF4) | 2.4 GB | `rpa-grounding.service` (Unix socket) | Sinon ~15 s de chargement par clic. |
|
||
| **CLIP ViT-B/32** | 0.7 GB | Singleton in-process (`core/gpu/clip_manager.py`) | Appelé sur chaque frame du pipeline. |
|
||
| **EasyOCR fr+en** | 0.5 GB | Singleton in-process (DialogHandler, TitleVerifier, input_handler) | Polling 500 ms, CPU = 5–10× plus lent. |
|
||
|
||
**Note** : CLIP et EasyOCR ne sont PAS mutualisés dans le service. Le gain serait nul tant qu'un seul processus consommateur tourne à la fois (record OU replay). À envisager en Phase 1B si on mesure une vraie contention multi-process.
|
||
|
||
## VLM Ollama — un seul à la fois (config `ollama-vram-policy.conf`)
|
||
|
||
`OLLAMA_MAX_LOADED_MODELS=1` force Ollama à ne garder qu'un VLM en VRAM. Le swap a lieu au changement de mode (~5 s, une fois).
|
||
|
||
| Mode | VLM Ollama | VRAM Ollama | Usage |
|
||
|---|---|---|---|
|
||
| **REPLAY** | `qwen2.5vl:7b` | ~5.5 GB | Raisonnement haut niveau (`observe_reason_act`) |
|
||
| **RECORD** | `qwen2.5vl:3b` | ~3.0 GB | Description d'ancres (`capture.py`) |
|
||
|
||
Modèles référencés mais NON résidents (chargés à la demande, soumis au `MAX_LOADED_MODELS=1`) : `qwen3-vl:8b`, `gemma4:e4b`, `gemma4:latest`.
|
||
|
||
## Matrice VRAM totale
|
||
|
||
| Mode | Résidents | Ollama | **Total** | **Marge sur 12 GB** |
|
||
|---|---|---|---|---|
|
||
| Idle (lazy) | 2.4 (InfiGUI seul) | 0 | **2.4 GB** | 9.6 GB |
|
||
| RECORD actif | 3.6 | 3.0 (qwen 3b) | **6.6 GB** | 5.4 GB ✅ |
|
||
| REPLAY actif | 3.6 | 5.5 (qwen 7b) | **9.1 GB** | 2.9 GB ✅ |
|
||
|
||
La marge couvre les pics CUDA et la fragmentation VRAM observée à long run.
|
||
|
||
## Configuration systemd
|
||
|
||
### 1. Service grounding (déjà créé)
|
||
|
||
```
|
||
deploy/systemd/rpa-grounding.service
|
||
```
|
||
|
||
Crée le `RuntimeDirectory=rpa` (= `/run/rpa/`) qui héberge :
|
||
- `grounding.sock` — socket de communication
|
||
- `infigui_screen.png`, `infigui_anchor.png` — images d'inférence (passées par fichier, pas par socket)
|
||
|
||
### 2. Services consommateurs
|
||
|
||
Patchés pour pointer sur le socket et partager `/run/rpa/` :
|
||
|
||
```ini
|
||
Environment="RPA_GROUNDING_SOCKET=/run/rpa/grounding.sock"
|
||
Environment="RPA_GROUNDING_IMG_DIR=/run/rpa"
|
||
RuntimeDirectory=rpa
|
||
RuntimeDirectoryMode=0755
|
||
RuntimeDirectoryPreserve=yes
|
||
```
|
||
|
||
Units patchées : `rpa-vision-v3-api.service`, `rpa-vision-v3-worker.service`, `rpa-streaming.service`.
|
||
|
||
### 3. Drop-in Ollama
|
||
|
||
```
|
||
deploy/systemd/ollama-vram-policy.conf
|
||
```
|
||
|
||
Installation :
|
||
```bash
|
||
sudo mkdir -p /etc/systemd/system/ollama.service.d/
|
||
sudo cp deploy/systemd/ollama-vram-policy.conf /etc/systemd/system/ollama.service.d/vram-policy.conf
|
||
sudo systemctl daemon-reload
|
||
sudo systemctl restart ollama
|
||
```
|
||
|
||
## Activation complète
|
||
|
||
```bash
|
||
# 1. Service grounding
|
||
sudo cp deploy/systemd/rpa-grounding.service /etc/systemd/system/
|
||
# 2. Drop-in Ollama
|
||
sudo mkdir -p /etc/systemd/system/ollama.service.d/
|
||
sudo cp deploy/systemd/ollama-vram-policy.conf /etc/systemd/system/ollama.service.d/vram-policy.conf
|
||
# 3. Recharger les units patchées (api, worker, streaming)
|
||
sudo cp deploy/systemd/rpa-vision-v3-api.service /etc/systemd/system/
|
||
sudo cp deploy/systemd/rpa-vision-v3-worker.service /etc/systemd/system/
|
||
sudo cp deploy/systemd/rpa-streaming.service /etc/systemd/system/
|
||
|
||
sudo systemctl daemon-reload
|
||
sudo systemctl enable --now rpa-grounding
|
||
sudo systemctl restart ollama
|
||
sudo systemctl restart rpa-vision-v3-api rpa-vision-v3-worker rpa-streaming
|
||
```
|
||
|
||
## Vérification
|
||
|
||
```bash
|
||
# 1. Service grounding actif et socket en place
|
||
systemctl status rpa-grounding
|
||
ls -la /run/rpa/grounding.sock
|
||
|
||
# 2. VRAM réelle après warm-up
|
||
nvidia-smi --query-gpu=memory.used,memory.free --format=csv,noheader
|
||
|
||
# 3. Test d'un ground via socket
|
||
python -c "
|
||
from core.grounding.ui_tars_grounder import UITarsGrounder
|
||
from PIL import Image
|
||
g = UITarsGrounder.get_instance()
|
||
# Devrait afficher [InfiGUI/server/...] (et non [InfiGUI/subprocess/...])
|
||
print(g.ground(target_text='Save', screen_pil=Image.new('RGB', (800, 600))))
|
||
"
|
||
```
|
||
|
||
Si tu vois `[InfiGUI/subprocess/...]` dans les logs, c'est que le client est tombé en fallback — vérifier `journalctl -u rpa-grounding`.
|
||
|
||
## Garde-fous
|
||
|
||
- **Pas de chevauchement** : InfiGUI tourne dans son process, Ollama dans le sien. Aucun ne peut écraser l'autre.
|
||
- **Pas de double VLM** : `OLLAMA_MAX_LOADED_MODELS=1` empêche qu'un appel qwen 3b traîne pendant qu'on demande qwen 7b.
|
||
- **Pas de crash CUDA héritage parent** : l'unit `rpa-grounding` force `CUDA_VISIBLE_DEVICES=0` explicitement et démarre dans son propre process tree (pas hérité de systemd directement).
|
||
- **Fallback subprocess** : si `rpa-grounding` n'est pas démarré ou crash, le code client retombe sur l'ancien subprocess one-shot (cf. `ui_tars_grounder.py`). Aucune régression possible.
|