deploy

Par nvidia · skills

Déployez, déboguez ou supprimez n'importe quel profil VSS via un workflow centré sur Compose — config (dry-run) avec surcharges d'env, examen du compose résolu, puis compose up. Utilisez cette skill lorsque l'utilisateur dit « deploy vss », « deploy `profile` », « debug deploy », « verify deployment » ou « why is my vss deploy broken ».

npx skills add https://github.com/nvidia/skills --skill deploy

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

  1. Chemin du repo — trouvez video-search-and-summarization/ sur disque. Vérifiez TOOLS.md si disponible.
  2. NGC CLI & API key — voir references/ngc.md. Vérifiez que $NGC_CLI_API_KEY est défini.
  3. 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 à dedicated ou un mode remote-*.
  • 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 + lvs sont attendus de débarquer pleinement localement ; alerts / search nécessitent actuellement un LLM remote. Voir references/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 standard nvcr.io/nim/nvidia/nvidia-nemotron-nano-9b-v2:1 a un manifeste arm64 cassé. Vous devez exécuter NVIDIA-Nemotron-Edge-4B-v2.1-EA-020126_FP8 comme 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érification HF_TOKEN sont dans references/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 777 sur 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 .env faisant 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 dans generated.env.

generated.env est un scratchpad que dev-profile.sh produit pendant son propre flux interne ; ce n'est PAS lu par le vérificateur et c'est effacé à l'invocation suivante. Un agent qui utilise dev-profile.sh comme un déploiement one-shot mais laisse le .env de base intact échouera silencieusement les vérifications env même quand la stack démarre proprement. Si vous avez utilisé dev-profile.sh et voyez generated.env sur disque, copiez ses lignes clé/valeur dans le .env de base, ou réappliquez vos commandes sed contre le .env de base après coup. Le .env de 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-recreate sur 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édent up -d a partiellement échoué, corrigez la cause racine (généralement perms ou une typo env) et juste re-exécutez up -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é. Voir references/prerequisites.md.
  • Erreur d'authentification NGC → réexportez NGC_CLI_API_KEY ou suivez references/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).

Skills similaires