VSS Deploy
Déployez n'importe quel profil VSS en utilisant un workflow centré sur compose : construire les overrides env, générer la compose résolue (dry-run), vérifier, puis déployer. Remplace l'exécution directe de dev-profile.sh par des étapes validées et auditables.
Profile Routing
| User dit | Profile | Référence |
|---|---|---|
| "deploy vss" / "deploy base" | base |
references/base.md |
| "deploy alerts" / "alert verification" / "real-time alerts" | alerts |
references/alerts.md |
| "deploy for incident report" | alerts |
references/alerts.md |
| "deploy lvs" / "video summarization" | lvs |
references/lvs.md |
| "deploy search" / "video search" | search |
references/search.md |
Profile routing edge hardware (DGX Spark, AGX/IGX Thor) : voir references/edge.md
pour la recette 4B-LLM (config_edge.yml + vLLM standalone sur port 30081). Les plateformes edge partagent une GPU à mémoire unifiée unique entre LLM et VLM, donc Nemotron Edge 4B est le défaut et Nemotron Nano 9B v2 FP8 est une option quand la mémoire le permet.
Quand l'utiliser
- Déployer VSS / démarrer VSS / lancer un profil
- Déployer un profil spécifique (base, alerts, lvs, search)
- Faire un dry-run / prévisualiser ce qui sera déployé
- Changer la config de déploiement (hardware, mode LLM, assignation GPU)
- Arrêter un déploiement en cours
- Déboguer ou vérifier un déploiement existant (voir Déboguer un déploiement)
Comment ça marche
Exécutez docker compose directement sur l'hôte :
# 1. Appliquer les env overrides au fichier .env du profil
# 2. docker compose --env-file .env config > resolved.yml (dry-run)
# 3. Vérifier resolved.yml
# 4. docker compose -f resolved.yml up -d
Avant de déployer
- Chemin du repo — trouvez
video-search-and-summarization/sur disque. VérifiezTOOLS.mdsi disponible. - NGC CLI & API key — voir
references/ngc.md. Vérifiez que$NGC_CLI_API_KEYest défini. - Prérequis système (GPU VRAM, driver, Docker, NVIDIA Container Toolkit) — la référence canonique est la page des prérequis VSS. Cette page liste le hardware supporté, les besoins GPU par profil, et la version minimale de driver/CUDA par NIM. Lisez-la et choisissez le placement LLM/VLM qui convient à l'hôte — ne devinez pas les seuils à partir de cette skill.
Pre-flight Check
À exécuter avant chaque déploiement. Ne pas procéder si une vérification échoue.
# 1. GPU visible
nvidia-smi --query-gpu=index,name --format=csv,noheader
# 2. NVIDIA runtime dans Docker
docker info 2>/dev/null | grep -i "runtimes"
# 3. NVIDIA runtime fonctionne de bout en bout
docker run --rm --gpus all ubuntu:22.04 nvidia-smi 2>&1 | head -5
Si la vérification 2 ou 3 échoue, voir references/prerequisites.md.
Flux de déploiement
Suivez toujours cette séquence. Ne sautez jamais le dry-run.
Step 0 — Arrêter tout déploiement existant
Si un déploiement existe déjà, arrêtez-le d'abord. La procédure complète (chemin piloté par resolved.yml, patterns catch-all couvrant les fichiers compose dev-profile, pourquoi les résidus causent des 502 /sensor/list) se trouve dans references/teardown.md.
# Si un resolved.yml d'un déploiement antérieur existe, préférez-le — il
# connaît tous les services compose-profile qui ont été lancés.
if [ -f "$REPO/deployments/resolved.yml" ]; then
docker compose -f "$REPO/deployments/resolved.yml" down --remove-orphans
fi
# Catch-all : supprimer tous les containers VSS-stack que les fichiers
# compose dev-profile lancent. Sans cela, les résidus d'un déploiement
# antérieur persistent (notamment l'ensemble *-smc, que le profil alerts
# partage avec l'ensemble *-dev sur host networking et port 30000) et soit :
# - bind les ports dont le nouveau déploiement a besoin → second sensor-ms
# échoue à binder → /sensor/list retourne 502 (issue #151), ou
# - passent les health checks du nouveau déploiement tout en servant
# des données périmées de la DB du déploiement antérieur.
# Les patterns ci-dessous couvrent tout ce qui est déclaré dans
# deployments/vst/{2d,3d,smc,developer,ps}/, deployments/foundational/,
# deployments/agents/, deployments/proxy/, et les fichiers
# compose dev-profile-*.
docker ps -a --format '{{.Names}}' \
| grep -E '^(vss-|mdx-|perception-|rtvi-|alert-|nvstreamer-|sensor-ms-|vst-ingress-|vst-mcp-|vst-file-proxy|centralizedb-|storage-ms-|streamprocessing-ms-|sdr-(http|streamprocessing)-|envoy-(http|streamprocessing)-|rtspserver-ms-|recorder-ms-|replaystream-ms-|livestream-ms-|metropolis-vss-ui|phoenix)' \
| xargs -r docker rm -f
Si c'est le premier déploiement de l'hôte, la ligne docker compose down
est un no-op (exit 0 sans containers à arrêter) — sûr d'exécuter inconditionnellement.
Step 1 — Recueillir le contexte
Découvrez ce qui est disponible sur l'hôte et faites un renvoi croisé avec la page des prérequis VSS pour choisir une forme de déploiement qui convient.
| Valeur | Comment déterminer |
|---|---|
| Profile | Faites correspondre l'intention de l'utilisateur à la table de routing ci-dessus. Défaut : base |
| Chemin du repo | Trouvez video-search-and-summarization/ sur disque |
| Hardware | nvidia-smi --query-gpu=name,memory.total --format=csv,noheader → cherchez la VRAM par GPU sur la page des prérequis |
| Placement LLM/VLM | Choisissez local_shared, local, ou remote par LLM/VLM en fonction des GPUs disponibles + $LLM_REMOTE_URL / $VLM_REMOTE_URL / $NGC_CLI_API_KEY. Si aucune combinaison sur cet hôte ne satisfait les prérequis, arrêtez et signalez le blocage au lieu de silencieusement choisir une autre forme. |
| API keys | NGC_CLI_API_KEY pour les NIMs locaux, NVIDIA_API_KEY pour les remote |
| Host IP | hostname -I \| awk '{print $1}' |
Mappage de profil hardware :
| Le nom de la GPU contient | HARDWARE_PROFILE | Chemin LLM recommandé |
|---|---|---|
| H100 | H100 |
Nano 9B v2 (NIM) |
| L40S | L40S |
Nano 9B v2 (NIM) |
| RTX 6000 Ada, RTX PRO 6000 | RTXPRO6000BW |
Nano 9B v2 (NIM) |
| GB10 (DGX Spark) | DGX-SPARK |
Edge 4B (vLLM) — voir references/edge.md |
| IGX | IGX-THOR |
Edge 4B (vLLM) — voir references/edge.md |
| AGX | AGX-THOR |
Edge 4B (vLLM) — voir references/edge.md |
| Autre | OTHER |
— |
Nombre minimum de GPUs par (profile × mode × platform). La source canonique est la page des prérequis VSS ; reproduite ici pour que la skill échoue rapidement quand l'hôte est trop petit :
| Profile | Mode | H100 / RTX PRO 6000 (Blackwell) | L40S | DGX-Spark / IGX-Thor / AGX-Thor |
|---|---|---|---|---|
base |
shared (local_shared LLM + VLM) |
1 | — (48 GB/GPU trop petit) | 1 (Edge 4B + VLM, mémoire unifiée) |
base |
dedicated (local LLM + VLM) |
2 | 2 | — |
base |
remote-llm |
1 (VLM local) | 1 (VLM local) | 1 (LLM remote seulement) |
base |
remote-vlm |
1 (LLM local) | 1 (LLM local) | — |
base |
remote-all |
0 | 0 | 0 |
lvs |
shared | 1 | — | - |
lvs |
dedicated | 2 | 2 | — |
lvs |
remote-llm/vlm |
1 | 1 | - |
lvs |
remote-all |
0 | 0 | - |
alerts (verification / CV) |
shared | 2 | — | — |
alerts (verification / CV) |
dedicated | 3 | 3 | — |
alerts (verification / CV) |
remote-all |
1 | 1 | 1 |
alerts (verification / CV) |
remote-llm/vlm |
2 | 2 | 1 |
alerts (real-time / VLM) |
shared | 2 | — | — |
alerts (real-time / VLM) |
dedicated | 3 | 3 | — |
alerts (real-time / VLM) |
remote-llm |
2 | 2 | 1 |
search |
shared | 2 | — | - |
search |
dedicated | 3 | 3 | — |
search |
remote-* |
2 | 2 | - |
Quelques règles dures encodées dans le tableau :
- L40S ne peut pas faire
shared. 48 GB n'est pas assez de VRAM pour LLM + VLM sur une seule GPU. Revenez àdedicatedou un moderemote-*. - L40S a besoin de +1 GPU pour alerts / search vs H100 car l'astuce shared-sur-une-GPU ne fonctionne pas — RT-CV / Embed1 doivent prendre leur propre GPU, et LLM+VLM ont toujours besoin d'une seconde.
- DGX-Spark / Thor sont early-access pour la plupart des profils. Seuls
base+lvssont attendus de débarquer pleinement localement ;alerts/searchnécessitent actuellement un LLM remote. Voirreferences/edge.md.
Si la combinaison (nombre GPU × VRAM) de l'hôte n'apparaît pas ci-dessus, arrêtez et signalez le blocage — ne choisissez pas silencieusement un autre mode.
Le mode shared edge requiert Edge 4B +
HF_TOKEN. Sur DGX Spark et AGX/IGX Thor, LLM et VLM doivent tous deux tenir en mémoire unifiée, ET l'image standardnvcr.io/nim/nvidia/nvidia-nemotron-nano-9b-v2:1a un manifeste arm64 cassé. Vous devez exécuterNVIDIA-Nemotron-Edge-4B-v2.1-EA-020126_FP8comme container vLLM standalone sur port 30081 avec l'agent pointé dessus via--use-remote-llm. La recette complète et l'étape obligatoire de vérificationHF_TOKENsont dansreferences/edge.md.
Step 1b — Préparer le répertoire de données
La disposition du répertoire de données (chemins asset, propriété, points de montage, sous-répertoires spécifiques au profil) est documentée dans references/data-directory.md. Lisez ce fichier avant de déployer pour la première fois sur un hôte ou quand vous changez de profil.
# Sous-répertoires spécifiques au profil :
# alerts → mkdir -p "$DATA/data_log/vss_video_analytics_api" "$DATA/videos/dev-profile-alerts" "$DATA/models/rtdetr-its" "$DATA/models/gdino"
# search → mkdir -p "$DATA/models"
chmod -R 777 "$DATA/data_log" "$DATA/agent_eval"
# Si vous avez créé $DATA/models ci-dessus, aussi : chmod -R 777 "$DATA/models"
INTERDIT :
chown -R ubuntu:ubuntu $MDX_DATA_DIR(ou tout chown récursif).C'est du « bon ménage » selon l'instinct d'un shell-admin mais c'est la commande qui casse le déploiement dans cette stack. Vous observerez un déploiement « sain » (containers Up, endpoints 200) tandis que le pipeline vidéo est silencieusement cassé. Utilisez
chmod -R 777sur les sous-répertoires spécifiques ci-dessus — rien d'autre.
Gotchas uid connus par container (chacun utilise un bind mount sous $DATA) :
| Container | Image | Exécuté en tant que | Chemin de montage | Symptôme si les permissions sont incorrectes |
|---|---|---|---|---|
centralizedb-dev |
postgres:17.6-alpine | uid 70 | $DATA/data_log/vst/postgres/db |
Impossible de lire son propre PGDATA → requête VST sensor_details échoue → vidéos uploadées n'apparaissent jamais dans /vst/api/v1/sensor/streams → vérification warehouse E2E retourne vide |
mdx-redis |
redis:8.2.2-alpine | uid 999 | $DATA/data_log/redis/log, /redis/data |
"Can't open the log file: Permission denied" → redis meurt → envoy-streamprocessing meurt (a besoin du script Lua Redis) → pipeline stream cassé |
elasticsearch |
elasticsearch | uid 1000 | $DATA/data_log/elastic/{data,logs} |
"AccessDeniedException" au démarrage → ES refuse de démarrer |
vst / sensor-ms-dev |
vst | uid 1000 | $DATA/data_log/vst/* (vidéos, clips) |
403 sur ingest ou stream write |
chmod -R 777 $DATA/data_log couvre tous ceux-ci. NE FAITES PAS chown à des uids
individuels — les containers qui initialisent leurs propres répertoires au premier
démarrage (comme postgres) re-chowneront ensuite à leur uid et un chown ultérieur
vers ubuntu les cassera.
Si postgres est déjà cassé (courant quand on redéploie sans un nettoyage de
data-dir) :
sudo rm -rf "$DATA/data_log/vst/postgres" # postgres se réinitialise au prochain démarrage
docker restart centralizedb-dev
Step 1c — Si vous déployez sur Brev, configurez les env vars secure-link
Les env vars spécifiques à Brev (BREV_ENV_ID, patterns secure-link) sont documentées dans references/brev.md.
Step 2 — Construire env_overrides
Produisez un dict env_overrides à partir de la requête utilisateur et du contexte recueilli : choisir LLM/VLM remote/local, définir les credentials, pointer vers les endpoints, définir les flags spécifiques à la plateforme. Le mappage complet (chaque clé override, quand elle s'applique, défauts, différences spécifiques au profil) se trouve dans references/env-overrides.md.
Step 3 — Config / dry-run
Emplacement du fichier env : <repo>/deployments/developer-workflow/dev-profile-<profile>/.env
C'est le
.envfaisant autorité. Chaque vérificateur, healthcheck, et outil post-déploiement lit depuis ce chemin. Quand vous appliquez les env overrides (à partir de Step 2 ou du prompt de l'utilisateur), écrivez-les directement dans ce fichier — pas dansgenerated.env.
generated.envest un scratchpad quedev-profile.shproduit pendant son propre flux interne ; ce n'est PAS lu par le vérificateur et c'est effacé à l'invocation suivante. Un agent qui utilisedev-profile.shcomme un déploiement one-shot mais laisse le.envde base intact échouera silencieusement les vérifications env même quand la stack démarre proprement. Si vous avez utilisédev-profile.shet voyezgenerated.envsur disque, copiez ses lignes clé/valeur dans le.envde base, ou réappliquez vos commandessedcontre le.envde base après coup. Le.envde base est la source de vérité.
REPO=/path/to/video-search-and-summarization
PROFILE=base
ENV_FILE=$REPO/deployments/developer-workflow/dev-profile-$PROFILE/.env
# Lire le .env actuel, appliquer les overrides, écrire en retour
# (lire les lignes, mettre à jour les clés correspondantes, ajouter les nouvelles clés, écrire)
# Résoudre la compose
cd $REPO/deployments
docker compose --env-file $ENV_FILE config > resolved.yml
Le YAML résolu est sauvegardé dans <repo>/deployments/resolved.yml.
Step 3b — Vérifier que resolved.yml n'a pas de tokens ${...} non développés
Les tokens ${VAR} non développés dans resolved.yml signifient que compose n'a pas vu ces valeurs env. La procédure de diagnostic et les coupables courants se trouvent dans references/troubleshooting.md.
Step 4 — Vérifier
Montrez à l'utilisateur un résumé de ce qui sera déployé :
- Nom du profil et hardware
- Modèles LLM/VLM et mode (local/remote/local_shared)
- Services qui vont démarrer
- Assignation device GPU
- Endpoints clés (port UI, port agent)
Demandez : « Ça semble bon — déployer maintenant ? » et attendez la confirmation avant Step 5.
Exception — mode autonome. Si la requête de l'utilisateur vous demande déjà d'exécuter de façon autonome (par exemple « deploy X autonomously », « run without confirmation », « non-interactive »), sautez la demande de confirmation et procédez directement à Step 5. Ce chemin existe pour que les invocations eval automatisées / CI ne se bloquent pas en attendant une réponse humaine qu'elles ne recevront jamais. Dans tous les autres cas, un humain doit approuver.
Step 5 — Déployer
cd $REPO/deployments
docker compose -f resolved.yml up -d
N'utilisez PAS
--force-recreatesur les retries. Ça détruit les containers NIM déjà chauds, forçant une autre 3–5 min torch.compile + CUDA-graph capture par NIM. Si le précédentup -da partiellement échoué, corrigez la cause racine (généralement perms ou une typo env) et juste re-exécutezup -d— Docker ne recréera que les containers dont la config a changé ou qui sont down.
Le déploiement prend ~10-20 min en première exécution (tire images + télécharge modèles). Supervisez :
# Statut des containers
docker ps --format 'table {{.Names}}\t{{.Status}}\t{{.Ports}}'
# Logs pour un service spécifique
docker compose -f $REPO/deployments/resolved.yml logs --tail 50 <service>
Le déploiement est complet quand tous les containers mdx-* affichent le statut Up.
Step 6 — Signaler les endpoints
| Profile | Agent UI | REST API | Autre |
|---|---|---|---|
| base | :3000 |
:8000 (Swagger à /docs) |
— |
| alerts | :3000 |
:8000 |
Dashboard VIOS :30888/vst/ |
| lvs | :3000 |
:8000 |
— |
| search | :3000 |
:8000 |
— |
Utilisez les skills workflow après déploiement :
- alerts / incident-report → gestion des alertes et requêtes incidents
- video-search → recherche vidéo sémantique
- video-summarization → résumé de longue vidéo
- vios → gestion caméra/stream via VIOS
- video-analytics → requêtes Elasticsearch
Arrêter
cd $REPO/deployments
docker compose -f resolved.yml down
Déboguer un déploiement
Utilisez ce workflow quand l'utilisateur demande de « déboguer le déploiement », « vérifier que ça marche », « pourquoi l'agent ne répond pas », ou similaire. L'objectif est de confirmer le chemin complet d'ingestion vidéo vers réponse agent, pas juste que les containers soient « Up ».
Chaque doc de référence de profil (par exemple references/base.md) a une
section Debugging listant les commandes exactes à exécuter pour ce profil.
Vérifications rapides (tous les profils)
# 1. Tous les containers attendus Up
docker ps --format 'table {{.Names}}\t{{.Status}}'
# 2. Agent API + UI répondant
curl -sf http://localhost:8000/docs >/dev/null && echo "agent OK"
curl -sf http://localhost:3000/ >/dev/null && echo "ui OK"
# 3. VLM NIM répondant (profils base/lvs)
curl -sf http://localhost:30082/v1/models | python3 -m json.tool
# 4. LLM NIM répondant
curl -sf http://localhost:30081/v1/models | python3 -m json.tool
Vérification santé vidéo de bout en bout
Après que les vérifications rapides ci-dessus passent, lancez une vraie requête à travers l'agent — par exemple,
demandez-lui via l'API REST ou l'UI de décrire une vidéo que vous avez uploadée vers VST.
Si l'agent retourne une réponse non-vide, le chemin upload → ingest → inference →
reply est sain. S'il échoue, docker logs vss-agent montre quel stage a échoué.
Troubleshooting
unknown or invalid runtime name: nvidia→ NVIDIA Container Toolkit non installé ou Docker non redémarré. Voirreferences/prerequisites.md.- Erreur d'authentification NGC → réexportez
NGC_CLI_API_KEYou suivezreferences/ngc.md. - GPU non détectée → exécutez
sudo modprobe nvidia && sudo modprobe nvidia_uvm, puis réessayez. docker compose upéchoue avec « no resolved.yml » → exécutez d'abord le dry-run (docker compose config > resolved.yml, Step 3).- cosmos-reason2-8b crash → doit redéployer la stack entière (problème connu : NIM ne peut pas redémarrer seul).