rtvi-cv-customize-model

Par nvidia · skills

Comment remplacer le modèle de détection CV DeepStream dans le mode de vérification (2d_cv) du VSS Alerts Blueprint — couvre l'export ONNX, les parseurs bbox personnalisés, les problèmes de montage avec compose, la configuration nvinfer, la construction du moteur TRT à l'exécution, le déploiement, ainsi qu'un addendum sur les modèles de segmentation.

npx skills add https://github.com/nvidia/skills --skill rtvi-cv-customize-model

Personnalisation du modèle de détection CV — Blueprint des alertes VSS (mode 2d_cv uniquement)

Le conteneur de perception RT-CV (vss-rt-cv) exécute un pipeline DeepStream avec un GIE (moteur d'inférence GPU) primaire configurable. Par défaut, il utilise GDINO ou RTDETR. Ce guide couvre le remplacement par n'importe quel modèle au format ONNX, en utilisant YOLOv11 COCO 80 comme exemple travaillé.

Ceci s'applique uniquement à --mode verification (2d_cv). Le mode alertes en temps réel (2d_vlm) n'a pas de détecteur CV.

Pour les modèles de segmentation d'instance ou détection-plus-masque, complétez references/segmentation-model-contract.md avant d'écrire un code parseur ou de handoff.


Quand utiliser

Utilisez cette compétence quand l'utilisateur veut :

  • remplacer le détecteur vss-rt-cv stock par un autre modèle ONNX en mode vérification,
  • déboguer un chemin ONNX staging cassé, un montage de liaison de répertoire fantôme, ou une build de moteur TRT runtime manquante,
  • corriger une défaillance de chargement de parseur DeepStream comme dlsym failed sur le symbole du parseur bbox.

N'utilisez pas cette compétence pour :

  • le mode alertes temps réel 2d_vlm,
  • l'échafaudage d'un microservice CV RTVI autonome tout neuf (utilisez rtvi-cv-scaffold-vss-service).

Instructions

  • Gardez la réponse limitée au mode vérification Blueprint VSS (2d_cv) sauf si l'utilisateur demande explicitement de comparer les modes.
  • Les chemins commençant par deploy/docker/ sont relatifs au dépôt VSS Blueprint, pas au dépôt DeepStream. Clonez ou réutilisez un checkout VSS de v3.2.1 ou compatible, puis exécutez ces commandes depuis la racine de ce dépôt (voir VSS Quickstart).
  • Si l'utilisateur pose une question sur le staging ONNX ou un montage compose, dites explicitement que monter un chemin de fichier manquant est incorrect : utilisez le montage du répertoire parent stock, conservez l'ONNX sous ${VSS_DATA_DIR}/models/yolo, et re-stagez le fichier ONNX après tout dev-profile.sh up qui recrée le répertoire models.
  • Si l'utilisateur pose une question sur les défaillances de chargement de parseur, alignez parse-bbox-func-name, le symbole de fonction extern "C", et CHECK_CUSTOM_PARSE_FUNC_PROTOTYPE(...), puis reconstruisez le .so avec les chemins d'inclusion DeepStream et CUDA présents.
  • Si le modèle est détection-plus-masque ou segmentation d'instance, routez d'abord la décision de contrat de masque via references/segmentation-model-contract.md avant d'éditer la logique de parseur ou de handoff.

Exemples

  • « Remplacez le détecteur de vérification Blueprint des alertes VSS par un modèle YOLO11 ONNX et redéployez perception-alerts. »
  • « DeepStream dit dlsym failed pour le parseur bbox après avoir chargé la bibliothèque parseur personnalisée. Que dois-je vérifier ? »
  • « J'ai monté le chemin du fichier ONNX directement dans compose avant que le fichier hôte n'existe. C'est bon ? »

Architecture

NVStreamer (RTSP) → SDR (port 9010) → DeepStream (perception-alerts)
                                            └─ primary-gie (nvinfer)
                                                  ├─ ONNX → TRT engine (construit une fois, puis mis en cache)
                                                  ├─ custom bbox parser (.so)
                                                  └─ label file (.txt)
                                            └─ Kafka → mdx-raw
                                                  └─ vss-behavior-analytics
                                                        └─ mdx-incidents
                                                              └─ vlm-as-verifier

Localisation source VSS

Cette compétence est documentation uniquement et ne livre pas les sources de déploiement VSS. Utilisez un checkout VSS v3.2.1 ou compatible ; exécutez tous les chemins et commandes depuis la racine de ce dépôt. Les configurations de clone/LFS, les fichiers de profil Alerts stock, et l'arborescence de personnalisation YOLOv11 se trouvent dans references/vss-source-layout.md.


Adaptation à un modèle différent

YOLOv11 COCO 80 est l'exemple travaillé dans toutes les étapes ci-dessous. Le même motif s'applique à n'importe quel détecteur au format ONNX — remplacez à ces points :

Étape Quoi changer
Étape 1 Remplacez la procédure d'export par ce que votre bibliothèque d'entraînement de modèle requiert. Confirmez que le .onnx résultant existe sur l'hôte avant de continuer.
Étapes 2–3 Inspectez le nom réel du tenseur de sortie de votre modèle, sa forme, son layout, et si NMS est appliqué dans le graphe. Ne supposez pas qu'il correspond à YOLOv11. La compétence deepstream-dev (skills/deepstream-dev/) a un tableau de format de sortie YOLO génération par génération et references/nvinfer_config.md pour la référence complète des propriétés.
Étape 4 Mettez à jour output-blob-names vers le nom du tenseur, infer-dims vers votre forme d'entrée, et cluster-mode pour correspondre si NMS est dans le graphe (4) ou non (2).
Étape 5 Mettez à jour le chemin --onnx, le nom du tenseur d'entrée dans --minShapes/--optShapes/--maxShapes (pas images pour les modèles non-YOLO), et les commandes sed pour référencer votre fichier nvinfer .txt. Ajoutez un nouveau bloc if [[ $MODEL_NAME_2D == "YOURMODEL" ]] plutôt que d'éditer le bloc YOLO.

Étape 1 : Stagez votre modèle ONNX (Hôte, une seule fois)

Obtenez un modèle ONNX compatible TensorRT et placez-le à ${VSS_DATA_DIR}/models/yolo/yolo11s.onnx avant de continuer.

Consultez references/yolov11-onnx-export.md pour les paramètres d'export et le layout de tenseur utilisés dans cette référence. Adaptez le parseur et la config nvinfer dans les étapes ultérieures pour correspondre à la sortie réelle de votre modèle.

Après chaque dev-profile.sh up complet, restaurez la propriété du répertoire models/yolo recréé et re-stagez votre fichier ONNX :

sudo mkdir -p "${VSS_DATA_DIR}/models/yolo"
sudo chown -R $(id -u):$(id -g) "${VSS_DATA_DIR}/models/yolo"
# Copiez votre modèle ONNX à ${VSS_DATA_DIR}/models/yolo/yolo11s.onnx

Étapes 2–3 : Inspectez la sortie du modèle et construisez le parseur

Lisez et suivez references/yolov11-parser.md avant de créer ${VSS_PROFILE_DIR}/deepstream/custom_parser/nvdsparseyolov11.cpp ou d'éditer la construction du parseur dans Dockerfiles/perception.Dockerfile.

Avant d'écrire du code parseur, confirmez ces quatre choses pour votre modèle :

  • Nom et forme du tenseur de sortie — détermine output-blob-names et infer-dims à l'étape 4
  • Pré-NMS ou post-NMS — détermine cluster-mode à l'étape 4 ; consultez la règle 13 de deepstream-dev pour la ventilation génération par génération
  • Sémantique des coordonnéescx/cy/w/h format centré ou x1/y1/x2/y2 format coin ; l'exemple YOLOv11 utilise le format centré (voir references/yolov11-parser.md)
  • Nom du symbole du parseur — le nom de la fonction extern "C" doit correspondre exactement à parse-bbox-func-name à l'étape 4 et à CHECK_CUSTOM_PARSE_FUNC_PROTOTYPE(...)

Confirmez le layout réel du tenseur de sortie du modèle au lieu de supposer qu'il correspond à YOLOv11. Gardez le symbole du parseur identique dans la fonction C++ exportée, CHECK_CUSTOM_PARSE_FUNC_PROTOTYPE(...), et le paramètre parse-bbox-func-name de l'étape 4.

Pour les modèles de segmentation d'instance ou détection-plus-masque, complétez le tableau de décisions du contrat dans references/segmentation-model-contract.md avant d'écrire du code parseur ou de handoff.


Étape 4 : Config nvinfer

${VSS_PROFILE_DIR}/deepstream/configs/yolov11.txt — la sous-config du GIE primaire référencée par la config d'exécution DeepStream.

model-engine-file et batch-size sont patchés au démarrage du conteneur par le bloc ds-start.sh à l'étape 5. Copiez les valeurs ci-dessous telles quelles ; l'étape 5 écrasera les deux avec le chemin d'engine correct et le nombre de capteurs avant que DeepStream ne lise le fichier.

[property]
gpu-id=0
net-scale-factor=0.0039215697906911373    # normalisation d'entrée 1/255
model-engine-file=/opt/storage/yolo11s_fp16.engine
onnx-file=/opt/storage/yolo/yolo11s.onnx
batch-size=1                             # patchée au démarrage depuis NUM_SENSORS
network-mode=2                           # 0=FP32, 1=INT8, 2=FP16
network-type=0                           # 0=Detector
num-detected-classes=80
interval=0
gie-unique-id=1
output-blob-names=output0               # doit correspondre au nom du tenseur de sortie de votre modèle
infer-dims=3;640;640                    # C;H;W
maintain-aspect-ratio=1
parse-bbox-func-name=NvDsInferParseCustomYoloE  # doit correspondre au nom de la fonction extern "C" dans .so
custom-lib-path=/opt/deepstream-yolo/libnvdsparseyolov11.so
labelfile-path=/opt/nvidia/deepstream/deepstream/sources/apps/sample_apps/metropolis_perception_app/mounted-configs/yolo-coco-labels.txt
cluster-mode=2                   # 2=NMS — obligatoire : ONNX Ultralytics n'a pas NMS dans le graphe

[class-attrs-all]
pre-cluster-threshold=0.25
topk=300
nms-iou-threshold=0.45

Étape 5 : Build TRT engine runtime (ds-start.sh)

Les engines TRT sont spécifiques à l'architecture GPU. Construisez l'engine au premier démarrage quand il manque, puis réutilisez-le aux redémarrages suivants. Reconstruisez un engine existant uniquement quand FORCE_REBUILD=true. Le fichier compose Alerts stock bind-monte ${VSS_DATA_DIR}/models/ à /opt/storage/, ainsi l'engine généré persiste sur l'hôte.

Quel ds-start.sh ? Les Alerts stock exécutent services/rtvi/rtvi-cv/ds-start.sh (via extends), pas ${VSS_PROFILE_DIR}/deepstream/init-scripts/ds-start.sh. Cette compétence édite la copie du profil, puis la remonte à l'étape 6 pour que ces édits s'exécutent réellement. Carte complète des trois chemins, compromis de remontage, et appairage DS_CONFIG_FILE : references/ds-start-entrypoint.md.

Éditez ${VSS_PROFILE_DIR}/deepstream/init-scripts/ds-start.sh, puis écrasez le montage bind stock ds-start.sh de rtvi-cv dans le fichier compose du profil Alerts comme montré à l'étape 6. Sans ce remplacement, les édits du script de profil ne s'exécutent jamais.

Critique — honorez DS_CONFIG_FILE. Le script du profil définit CONFIG_FILE=${1:-...} et ne lit jamais DS_CONFIG_FILE. Le command compose Alerts appelle ds-start.sh sans arguments positionnels, tandis que l'étape 6 définit DS_CONFIG_FILE à la config d'exécution mounted-configs absolue (pas le chemin stock .../configs/...). Remplacez l'assignation existante CONFIG_FILE=... du script par :

# Préférez $1 quand fourni ; sinon utilisez DS_CONFIG_FILE depuis compose (chemin absolu).
# Sans ceci, YOLO_CONFIG se résout en ./yolov11.txt et le détecteur stock continue de tourner.
CONFIG_FILE="${1:-${DS_CONFIG_FILE:-/opt/nvidia/deepstream/deepstream/sources/apps/sample_apps/metropolis_perception_app/mounted-configs/run_config-api-rtdetr-protobuf.txt}}"

Puis ajoutez le bloc YOLO (avant les branches du modèle GDINO/RT-DETR va bien) :

if [[ $MODEL_NAME_2D == "YOLO" ]]; then
    YOLO_ONNX=/opt/storage/yolo/yolo11s.onnx
    YOLO_ENGINE=/opt/storage/yolo11s_fp16.engine
    YOLO_ENGINE_TMP="${YOLO_ENGINE}.building"
    FORCE_REBUILD=${FORCE_REBUILD:-false}

    if [[ ! -f "$YOLO_ONNX" ]]; then
        echo "ERROR: ONNX not found at ${YOLO_ONNX}. Stage your model there before starting."
        exit 1
    fi

    if [[ ! -s "$YOLO_ENGINE" || "${FORCE_REBUILD,,}" == "true" ]]; then
        echo "Building TensorRT engine: ${YOLO_ENGINE}"
        rm -f "$YOLO_ENGINE_TMP"
        if /usr/src/tensorrt/bin/trtexec \
            --onnx=${YOLO_ONNX} \
            --minShapes=images:1x3x640x640 \
            --optShapes=images:${NUM_SENSORS}x3x640x640 \
            --maxShapes=images:${NUM_SENSORS}x3x640x640 \
            --fp16 --saveEngine=${YOLO_ENGINE_TMP}; then
            mv "$YOLO_ENGINE_TMP" "$YOLO_ENGINE"
        else
            rm -f "$YOLO_ENGINE_TMP"
            echo "ERROR: TensorRT engine build failed; existing engine was preserved."
            exit 1
        fi
    else
        echo "Reusing cached TensorRT engine: ${YOLO_ENGINE}"
    fi

    # Patchez la config d'exécution pour utiliser yolov11.txt pour le GIE primaire
    # (le nom relatif est intentionnel : DeepStream le résout par rapport au répertoire du CONFIG_FILE)
    sed -i '/^\[primary-gie\]/,/^\[/{s/config-file=.*/config-file=yolov11.txt/;}' "$CONFIG_FILE"
    # Patchez le chemin d'engine et la taille du batch dans yolov11.txt (même répertoire que CONFIG_FILE)
    YOLO_CONFIG="$(dirname "${CONFIG_FILE}")/yolov11.txt"
    sed -i "s|model-engine-file=.*|model-engine-file=${YOLO_ENGINE}|" "${YOLO_CONFIG}"
    sed -i "/^\[property\]/,/^\[/{s/^batch-size=.*/batch-size=${NUM_SENSORS}/;}" "${YOLO_CONFIG}"
fi

Pour ajouter un modèle différent, ajoutez un nouveau bloc if [[ $MODEL_NAME_2D == "YOURMODEL" ]]. Mettez à jour :

  • le chemin --onnx et le chemin de sortie --saveEngine
  • le nom du tenseur d'entrée et les dimensions dans --minShapes/--optShapes/--maxShapes pour votre modèle
  • les commandes sed pour pointer vers votre fichier nvinfer .txt

Étape 6 : Compose + Env

Dans le fichier ${VSS_PROFILE_DIR}/compose.yml existant, mettez à jour le service perception-alerts :

perception-alerts:
  build:
    context: $VSS_APPS_DIR/developer-profiles/dev-profile-alerts
    dockerfile: Dockerfiles/perception.Dockerfile
  volumes:
    # Gardez le montage du répertoire parent stock. Ne le remplacez pas par un
    # montage direct de yolo11s.onnx : Docker crée un répertoire fantôme si le
    # fichier hôte n'existe pas.
    - $VSS_DATA_DIR/models/:/opt/storage/
    - $VSS_APPS_DIR/developer-profiles/dev-profile-alerts/deepstream/configs/:/opt/nvidia/deepstream/deepstream/sources/apps/sample_apps/metropolis_perception_app/mounted-configs/
    # Écrasez le ds-start.sh stock de rtvi-cv (montage extends). Sans ceci,
    # les édits sous deepstream/init-scripts/ ne s'exécutent jamais — voir
    # references/ds-start-entrypoint.md.
    - $VSS_APPS_DIR/developer-profiles/dev-profile-alerts/deepstream/init-scripts/ds-start.sh:/opt/nvidia/deepstream/deepstream/sources/apps/sample_apps/metropolis_perception_app/ds-start.sh:ro
  environment:
    MODEL_NAME_2D: ${MODEL_NAME_2D}
    NUM_SENSORS: ${NUM_SENSORS}
    FORCE_REBUILD: ${FORCE_REBUILD:-false}
    # Utilisez mounted-configs (où yolov11.txt vit), pas le stock .../configs/...
    DS_CONFIG_FILE: /opt/nvidia/deepstream/deepstream/sources/apps/sample_apps/metropolis_perception_app/mounted-configs/run_config-api-rtdetr-protobuf.txt

Définissez dans ${VSS_PROFILE_DIR}/.env :

MODEL_NAME_2D="YOLO"
NUM_SENSORS=1
FORCE_REBUILD=false

Gardez FORCE_REBUILD=false pour les démarrages normaux. L'option --force-recreate de Compose recrée le conteneur mais ne recrée pas l'engine TensorRT sauf si FORCE_REBUILD=true.

Piège — generated.env gagne au redémarrage. Le redéploiement de l'étape 7 utilise --env-file .../generated.env, produit par dev-profile.sh depuis .env. Éditer .env seul ne change pas FORCE_REBUILD pour cette commande compose. Pour une reconstruction d'engine ponctuelle, passez le remplacement sur le shell (voir étape 7). Pour persister la valeur pour les exécutions ultérieures de dev-profile.sh, éditez .env et re-exécutez dev-profile.sh pour qu'il régénère generated.env.


Étape 7 : Déployer

Exécutez depuis la racine du dépôt video-search-and-summarization (VSS_ROOT / VSS_DEPLOY_DIR / VSS_PROFILE_DIR depuis la localisation source VSS) :

: "${VSS_ROOT:=$PWD}"
: "${VSS_DEPLOY_DIR:=${VSS_ROOT}/deploy/docker}"
: "${VSS_PROFILE_DIR:=${VSS_DEPLOY_DIR}/developer-profiles/dev-profile-alerts}"

1. Hôte single-GPU (GPU 0 uniquement) : éditez ${VSS_PROFILE_DIR}/.env pour que ces clés correspondent aux valeurs finales requises ci-dessous. Éditez le fichier env du profil source, pas generated.env (dev-profile.sh recrée celui-ci). Alerts stock réserve le GPU 0 et met RT-VLM / LLM / VLM sur GPU 1 ; les drapeaux CLI de dev-profile.sh ne peuvent pas effacer RESERVED_DEVICE_IDS ni définir FIXED_SHARED_DEVICE_IDS. Confirmez que les IDs de dispositif existent avec nvidia-smi --query-gpu=index --format=csv,noheader,nounits avant de déployer.

RESERVED_DEVICE_IDS=''
FIXED_SHARED_DEVICE_IDS='0'
RT_CV_DEVICE_ID='0'
RT_VLM_DEVICE_ID='0'
LLM_DEVICE_ID='0'
VLM_DEVICE_ID='0'

2. Déployer le profil de vérification Alerts officiel. Sélectionnez le profil matériel supporté par votre hôte, comme documenté par le VSS Quickstart. Ne présentez pas les commandes restantes comme un handoff à copier-coller à moins que l'exécution ne soit bloquée.

"${VSS_DEPLOY_DIR}/scripts/dev-profile.sh" up \
  -p alerts \
  -m verification \
  -H <H100|L40S|RTXPRO4500BW|RTXPRO6000BW|DGX-SPARK|IGX-THOR|AGX-THOR|OTHER>

# 3. dev-profile.sh recrée le répertoire model. Restaurez la propriété et
# re-stagez votre modèle ONNX.
export VSS_DATA_DIR="${VSS_DEPLOY_DIR}/data-dir"
sudo mkdir -p "${VSS_DATA_DIR}/models/yolo"
sudo chown -R $(id -u):$(id -g) "${VSS_DATA_DIR}/models/yolo"
# Copiez votre modèle ONNX à ${VSS_DATA_DIR}/models/yolo/yolo11s.onnx

# 4. Reconstruisez et recréez le service de perception personnalisé en utilisant le projet
# compose généré par dev-profile.sh.
cd "${VSS_DEPLOY_DIR}"
docker compose \
  --env-file developer-profiles/dev-profile-alerts/generated.env \
  up -d --build --force-recreate perception-alerts

# Reconstruction TensorRT ponctuelle (après changements ONNX / shape / GPU / TRT).
# Le remplacement inline FORCE_REBUILD écrase generated.env pour cette invocation uniquement :
# FORCE_REBUILD=true docker compose \
#   --env-file developer-profiles/dev-profile-alerts/generated.env \
#   up -d --build --force-recreate perception-alerts

La construction du moteur TRT prend approximativement 15–30 secondes sur le matériel Blackwell. Les redémarrages ultérieurs réutilisent l'engine persisté sous ${VSS_DATA_DIR}/models/.


Pièges courants

Consultez references/common-gotchas.md pour les défaillances de réservation single-GPU, wipe/restage après dev-profile.sh up, montages de fichiers fantômes, discordances de parseur dlsym, et contamination du flux Redis.

Skills similaires