vss-benchmark-vlm-qa

Par nvidia-ai-blueprints · video-search-and-summarization

Évalue la précision et la latence de questions-réponses vidéo d'un RT-VLM déployé (Cosmos Reason 3) via `vss vlm run`, en utilisant des questions et des vidéos issues du dataset DSS `vss-devx-base`. Remplace le chemin d'évaluation obsolète `nat eval` / `vss-agent` QA. Non applicable aux évaluations de tool-calling ou de trajectoire, ni à la mesure de débit de résumé LVS.

npx skills add https://github.com/nvidia-ai-blueprints/video-search-and-summarization --skill vss-benchmark-vlm-qa

Benchmark video Q&A via vss vlm

Mesurez la précision (LLM-as-judge vs vérité terrain) et la latence de la réponse à des questions vidéo de bout en bout en appelant vss vlm run sur un Cosmos Reason 3 RT-VLM déployé. Les questions et clips proviennent du dataset DSS vss-devx-base (nvdataset).

Cela remplace docker exec vss-agent nat eval pour la tranche QA. Il ne note pas l'appel d'outils ou les trajectoires.

Quand l'utiliser

  • L'utilisateur demande à benchmarker / évaluer la vidéo VLM Q&A après la suppression de vss-agent / NAT eval.
  • L'utilisateur souhaite la latence et la précision des réponses sur vss-devx-base.

Quand ne pas l'utiliser

  • Évaluation du tool-calling ou des trajectoires — hors de portée.
  • Débit de résumé LVS — utilisez vss-benchmark-video-summarization.
  • Questions ponctuelles ad-hoc — utilisez /vss-ask-video.

Prérequis

  • Une pile VSS avec RT-VLM servant Cosmos Reason 3, et vss configure déjà exécuté de sorte que vss configure check liste rt_vlm comme ok et vst comme ok.

    Configurez avec une adresse routable, pas localhost. Les clips sont adressés comme capteurs VIOS, donc RT-VLM les récupère par URL ; l'URL que VIOS crée est construite à partir de l'origine configurée. Une origine loopback crée une URL loopback, ce qui ne signifie rien à l'intérieur du conteneur RT-VLM, donc le CLI se replie sur l'inline du clip en base64 et le VLM rejette tout ce qui est volumineux avec HTTP 422 ... content ... valid string. vss configure --base-url http://<host-ip>:7777 évite cela — --base-url est un flag vss configure, pas un flag de benchmark. --inline-media est un flag de benchmark ; il force l'ancien comportement inline et n'est sûr que pour les clips sous ~10 MB.

  • uv et ce checkout (CLI via uv run --project libs/vss vss).

  • Le CLI nvdataset. Il n'est pas sur PyPI, et l'index utilisé par l'ancien eval deep-search (urm.nvidia.com/.../sw-ngc-data-platform-pypi) retourne 403. Installez à partir de l'index en lecture seule documenté à la place — aucune credential nécessaire :

    uv tool install --index https://artifactory.pdx.nvidia.com/artifactory/api/pypi/sw-ngc-data-platform-pypi-local/simple nvdataset
  • Accès DSS, l'un des suivants :

    • NVDATASET_API_KEY — une Personal Key depuis org.ngc.nvidia.com/setup/personal-keys scoped au service NVIDIA Dataset Service, avec l'org NGC basculée vers celle propriétaire du dataset. Ce n'est pas la clé NGC globale utilisée par le CLI NGC ; une clé globale retourne 403. NVDATASET_NGC_API_KEY et NGC_API_KEY sont aussi lues, dans cet ordre, pour la compatibilité rétroactive uniquement — le run affiche la variable qu'il a choisie comme dss credential: <name>, donc vérifiez cette ligne si un 403 vous surprend.
    • nvdataset auth login (Starfleet SSO), qui ne nécessite aucune clé. Ajoutez --flow device sur une machine distante sans navigateur. L'accès groupe nécessite l'appartenance à ngc-datasetservice-viewer-<tenant>-<group> (lecteur) ou ...-user-... (writer).

    Plus la tenancy, que SSO n'approvisionne pas — après auth login, nvdataset auth status signale toujours "tenant_id": null et chaque appel échoue avec Did not find tenant_id. Le script ne nomme aucune tenant, alors définissez-en une vous-même : exportez NVDATASET_TENANTID et NVDATASET_GROUPID, ou sauvegardez-les une fois avec nvdataset auth context add. Demandez à l'équipe propriétaire du dataset ses coordonnées. Un autre dataset ne nécessite aucun changement au script.

  • Un LLM judge compatible OpenAI : EVAL_LLM_JUDGE_BASE_URL et EVAL_LLM_JUDGE_NAME, authentifiés avec EVAL_LLM_JUDGE_API_KEY. NGC_API_KEY est délibérément pas envoyé aux hôtes judge non-NVIDIA — il est défini pour le téléchargement du dataset et ne doit pas atteindre un tiers. N'importe quel endpoint chat-completions fera l'affaire ; le judge déplace les scores absolus de son propre chef, donc maintenez-le fixe entre les runs que vous entendez comparer, et lisez judge_model dans summary.json avant de comparer deux nombres. --skip-judge donne la latence uniquement.

Le bootstrap est dans AGENTS.md à la racine du repo. Ne construisez pas d'URLs RT-VLM ; vss vlm run lit la config enregistrée.

Exécution

export NVDATASET_API_KEY=<personal-key>            # ou : nvdataset auth login [--flow device]
export NVDATASET_TENANTID=<tenant>                 # SSO ne définit pas ceci ; voir Prérequis
export NVDATASET_GROUPID=<group>
export EVAL_LLM_JUDGE_BASE_URL="${LLM_BASE_URL}"   # Origine OpenAI-compat, ex. http://127.0.0.1:8000
export EVAL_LLM_JUDGE_NAME="${LLM_NAME}"

# Optionnel : dataset déjà extrait
# export VSS_EVAL_DATASET=/path/to/vss-devx-base

<repo>/skills/benchmarking/vss-benchmark-vlm-qa/scripts/run_vlm_qa_benchmark.sh \
  --dataset-name vss-devx-base \
  --dataset-file dataset_single_turn.json

Les deux flags de dataset sont requis — le script ne porte aucun dataset par défaut, donc il ne suppose jamais les coordonnées DSS d'une équipe.

Flags utiles (transférés à benchmark_vlm_qa.py) :

Flag Objectif
--dry-run Résoudre les items QA et fichiers vidéo ; pas d'appels VLM
--limit N Les N premiers items QA (smoke)
--skip-judge Latence uniquement
--skip-download Utiliser un vss-devx-base déjà téléchargé
--timeout SEC Transmis comme vss vlm run --timeout (défaut 300)
--num-frames N Budget de frames (défaut 20, correspondant à l'ancienne config agent RT-VLM)
--model ID Remplacer le modèle RT-VLM que vss configure a enregistré

Les sorties sont sous <dataset>/../../results/vlm_qa/ (ou --output-dir) :

  • summary.json — précision moyenne, latence moyenne / p50 / p90 / p95 / p99, et le modèle que le déploiement a signalé servir, de sorte qu'un nombre n'est jamais laissé sans attribution
  • qa_evaluator_output.json — scores judge par item (même shape que la sortie NAT QA)
  • latency_summary.json — wall-clock par item autour de vss vlm run
  • workflow_output.json — réponses brutes
  • summary.csv

Règles

  • Pilotez le VLM uniquement via vss vlm run. Jamais POST /generate ou /v1/chat/completions construit à la main.
  • N'encapsulez pas vss dans des retries. --timeout est la limite ; le script n'ajoute qu'un hard kill 60 s après, donc un CLI qui ne retourne jamais ne peut pas coûter la totalité du run. Un item tué est enregistré comme une erreur nommant la watchdog, jamais comme un score bas.
  • Les items doivent déclarer evaluation_method contenant qa et porter une ground_truth textuelle. Les items report, trajectory-only, et unmarked sont ignorés.

Défaillances

Branchez sur le code de sortie ; n'extrayez jamais stdout pour le mot « error ».

Sortie Signification Que faire
0 Chaque item répondu Lisez summary.json
2 Précondition mauvaise — un flag de dataset manquant, pas de credential DSS, pas de judge configuré, dataset ou vidéos introuvables, pas d'items QA Fixez la configuration. Réexécuter sans changement échoue identiquement
3 Le téléchargement a échoué, ou au moins un item a errored Lisez l'error de chaque item dans summary.json

Un appel vss qui quitte 4 (service manquant de la config enregistrée) remonte comme une erreur d'item, donc le run termine à la sortie 3 — la correction est vss configure, pas un flag.

Défaillances dignes d'être reconnues par leur message :

  • HTTP 422 ... content ... valid string sur les gros clips — l'origine enregistrée est loopback, donc les clips sont inlinés en base64. Reconfigurez avec une adresse routable.
  • Did not find tenant_id — SSO vous a connecté mais n'a sélectionné aucune tenant. Exportez NVDATASET_TENANTID, ou nvdataset auth context use.
  • LLM judge HTTP 403 ... key_model_access_denied ou 400 Invalid model name sur chaque item — l'id du judge n'est pas ce que cette passerelle appelle le modèle. Les passerelles qui font face à plusieurs fournisseurs veulent généralement un id pleinement qualifié et rejettent le nom nu. GET <judge-base-url>/models liste les ids que la clé peut utiliser ; copiez-en un textuellement dans EVAL_LLM_JUDGE_NAME. Les réponses VLM ne sont pas affectées, donc seul le scoring est perdu.
  • Une erreur d'item nommant la watchdog — le CLI n'a jamais retourné et a été tué à --timeout + 60 s. C'est enregistré comme une erreur, jamais comme un score bas. Ne réessayez pas.
  • La précision loin du baseline ~0.465 n'est pas une défaillance du harnais. Le modèle judge et --num-frames la déplacent tous deux ; vérifiez judge_model et model_served avant de déposer un signalement.

Implémentation : scripts/benchmark_vlm_qa.py, testée par scripts/tests/. Contrat de téléchargement du dataset : README_eval.md.

Skills similaires