[Unit] Description=RPA Vision V3 - Service grounding persistant (InfiGUI-G1-3B) # Dépend du GPU NVIDIA prêt et du réseau pour le téléchargement HuggingFace au premier run. After=network-online.target nvidia-persistenced.service Wants=network-online.target [Service] Type=simple # ---- Runtime ---- User=dom Group=dom WorkingDirectory=/home/dom/ai/rpa_vision_v3 EnvironmentFile=-/home/dom/ai/rpa_vision_v3/.env.local Environment="PYTHONUNBUFFERED=1" Environment="PYTHONDONTWRITEBYTECODE=1" Environment="ENVIRONMENT=production" Environment="RPA_SERVICE_NAME=rpa-grounding" # Socket + répertoire d'images partagé avec les autres services RPA # via RuntimeDirectory=rpa (cf. plus bas). PrivateTmp=true reste activé : # /tmp serait isolé par service systemd, donc on n'utilise plus /tmp pour # les transferts client/serveur — tout passe par /run/rpa/. Environment="RPA_GROUNDING_SOCKET=/run/rpa/grounding.sock" Environment="RPA_GROUNDING_IMG_DIR=/run/rpa" # Forcer la visibilité GPU (cf. note sur héritage CUDA dans ui_tars_grounder.py) Environment="CUDA_VISIBLE_DEVICES=0" Environment="NVIDIA_VISIBLE_DEVICES=all" ExecStart=/home/dom/ai/rpa_vision_v3/.venv/bin/python3 -m core.grounding.infigui_server # ---- Socket partagé ---- # /run/rpa/ est créé par systemd au démarrage et nettoyé à l'arrêt. # Les autres services (api, worker, dashboard, vwb) doivent lire ce répertoire : # ils ne le créent pas, ils s'attendent à ce qu'il existe et que le socket soit dedans. RuntimeDirectory=rpa RuntimeDirectoryMode=0755 # ---- Resilience ---- # Le chargement initial du modèle prend 10–15s. Restart=on-failure couvre les # crashs CUDA ; le client a un fallback subprocess pour la fenêtre de redémarrage. Restart=on-failure RestartSec=5 # Le modèle est gros (~2.4GB VRAM, ~6GB RAM). Laisser largement le temps de charger. TimeoutStartSec=120 TimeoutStopSec=30 # ---- Hardening ---- # PrivateTmp=true : OK car les transferts d'images se font via /run/rpa/ # (RuntimeDirectory) et non plus via /tmp. Tous les services consommateurs # doivent déclarer RuntimeDirectory=rpa pour voir le même répertoire. PrivateTmp=true NoNewPrivileges=true # Logs -> journald StandardOutput=journal StandardError=journal SyslogIdentifier=rpa-grounding [Install] WantedBy=multi-user.target