i4h-workflow-dataset-annotate

Par nvidia · skills

Utilise un VLM pour vérifier si chaque épisode satisfait la description de tâche de l'environnement. À utiliser lorsque l'utilisateur demande d'annoter ou d'étiqueter des épisodes, de filtrer des démonstrations, ou de conditionner le fine-tuning à un classifieur de succès.

npx skills add https://github.com/nvidia/skills --skill i4h-workflow-dataset-annotate

Workflow i4h — Annoter un Dataset

Objectif

Utiliser un VLM pour vérifier que chaque épisode satisfait la description de tâche de l'env. À utiliser quand l'utilisateur demande d'annoter, d'étiqueter des épisodes, de filtrer des démos ou de valider un finetuning sur un classificateur de succès.

Code de Base

Ces étapes pilotent le code de base des workflows i4h (l'arborescence workflows/agentic/). Pour réutiliser un checkout existant, définissez I4H_WORKFLOWS à son chemin (aucun clone n'aura lieu). Sinon, cela résout le dépôt courant ou clone vers ~/i4h-workflows — acceptez cette valeur par défaut sans demander confirmation. Exécutez chaque commande ci-dessous depuis la racine résolue :

# Resolve the i4h-workflows base code (provides workflows/agentic/).
ROOT="${I4H_WORKFLOWS:-$(git rev-parse --show-toplevel 2>/dev/null)}"
if [ ! -d "$ROOT/workflows/agentic" ]; then
  ROOT="${I4H_WORKFLOWS:-$HOME/i4h-workflows}"
  [ -d "$ROOT/workflows/agentic" ] || git clone https://github.com/isaac-for-healthcare/i4h-workflows "$ROOT"
fi
export I4H_WORKFLOWS="$ROOT"; cd "$ROOT"

Bases

  • L'annotation est facultative. Ne l'exécutez pas lors de la validation sauf si l'utilisateur demande des étiquettes.
  • Pour les prompts en langage naturel tels que « Exécuter l'Annotation sur tous les épisodes enregistrés », annoter tous les épisodes dans un seul enregistrement HDF5 sélectionné, pas chaque HDF5 historique sous workflows/agentic/runs/. Si l'utilisateur ne nomme pas d'HDF5, choisir l'enregistrement annoté le plus récent : d'abord rechercher un HDF5 dans runs/.latest s'il en existe un, sinon choisir le plus récent .hdf5 non-annotation sous workflows/agentic/runs/. Traiter par lot plusieurs fichiers HDF5 seulement si l'utilisateur demande explicitement tous les enregistrements historiques, chaque fichier HDF5 ou une exécution d'annotation par lot.
  • Config de l'env (source de vérité) : l'annotateur lit le critère de succès (policy.task_description) depuis workflows/agentic/config/environments/<env>.yaml. Passez --task-description pour outrepasser.
  • Se connecte à un endpoint compatible OpenAI via --base-url (défaut http://localhost:8000/v1) et --model (défaut Qwen/Qwen3-VL-8B-Instruct). Pointez les deux vers un serveur de modèle de vision en cours d'exécution. N'utilisez pas de modèles texte uniquement/code tels que qwen3-coder-next ; l'annotation hors ligne envoie des entrées d'image et nécessite un VLM.
  • Gardez chaque artefact d'annotation dans workflows/agentic/runs/<run>/. Ne créez ou accédez pas à /tmp/annotate_* ou d'autres répertoires temporaires externes.

Démarrer le VLM

Ignorer cette section si un endpoint compatible OpenAI servant un modèle de vision est déjà en cours d'exécution — il suffit de définir VLM_BASE_URL/VLM_MODEL dans Run pour pointer vers lui. Un serveur local-agent exécutant qwen3-coder-next ne convient pas car il est texte uniquement. annotator/vllm.sh utilise le port 8000 par défaut, donc le démarrer au-dessus d'un serveur existant crée une collision ; ne le faites pas.

Exécutez les étapes ci-dessous dans l'ordre. Chaque étape est un appel bash distinct ; les variables persistent dans la session tmux de l'agent local.

Pour la disponibilité, utilisez workflows/agentic/annotator/vllm.sh ensure. Ne le remplacez pas par un docker ps brut, des suspensions fixes, des sondages HTTP ad hoc pour lister les modèles ou des étapes d'attente manuelles distinctes ; l'assistant possède la politique de démarrage et d'attente.

Étape 1 — démarrer le VLM (si nécessaire)

Exécutez cette commande exacte. N'ajoutez pas sleep, status, curl ou des opérateurs de contrôle shell autour :

REPO_ROOT="${I4H_WORKFLOWS:-$(git rev-parse --show-toplevel 2>/dev/null)}"; [ -d "$REPO_ROOT/workflows/agentic" ] || REPO_ROOT="$HOME/i4h-workflows"
"${REPO_ROOT}/workflows/agentic/annotator/vllm.sh" ensure

Exécuter (HDF5 Hors Ligne)

Exécutez les étapes ci-dessous dans l'ordre. Chaque étape est un appel bash distinct ; les variables persistent dans la session tmux de l'agent local.

Étape 1 — configuration et résolution du HDF5

REPO_ROOT="${I4H_WORKFLOWS:-$(git rev-parse --show-toplevel 2>/dev/null)}"; [ -d "$REPO_ROOT/workflows/agentic" ] || REPO_ROOT="$HOME/i4h-workflows"
ENV_ID=scissor_pick_and_place
RUNS_ROOT="${REPO_ROOT}/workflows/agentic/runs"

# LLM endpoint + model (OpenAI-compatible vLLM). Defaults match annotator/vllm.sh; override to use an
# external vision server — e.g. VLM_BASE_URL=http://localhost:8000/v1 VLM_MODEL=qwen3-vl-32b
VLM_BASE_URL="${VLM_BASE_URL:-http://localhost:8000/v1}"
VLM_MODEL="${VLM_MODEL:-Qwen/Qwen3-VL-8B-Instruct}"

# Point HDF5_PATH at a real recording (absolute path). Recordings come from teleop, mimic, or
# validate (which writes data/verify.hdf5 under each runs/eval_* dir). If HDF5_PATH is not set,
# choose one recording: an HDF5 inside runs/.latest if present, otherwise the newest non-annotation
# HDF5 under runs/. "All recorded episodes" means all episodes inside this one HDF5.
HDF5_PATH="${HDF5_PATH:-}"
if [ ! -f "${HDF5_PATH}" ]; then
  LATEST_RUN="$(readlink -f "${RUNS_ROOT}/.latest" 2>/dev/null || true)"
  if [ -n "${LATEST_RUN}" ] && [ -d "${LATEST_RUN}" ]; then
    HDF5_PATH="$(
      find "${LATEST_RUN}" -name '*.hdf5' -type f -printf '%T@ %p\n' 2>/dev/null \
        | sort -nr | awk 'NR==1 { $1=""; sub(/^ /, ""); print; exit }'
    )"
  fi
fi
if [ ! -f "${HDF5_PATH}" ]; then
  HDF5_PATH="$(
    find "${RUNS_ROOT}" \( -path '*/annotate_*' -o -path '*/.latest' \) -prune -o \
      -name '*.hdf5' -type f -printf '%T@ %p\n' 2>/dev/null \
      | sort -nr | awk 'NR==1 { $1=""; sub(/^ /, ""); print; exit }'
  )"
fi
if [ ! -f "${HDF5_PATH}" ]; then
  echo "annotate: set HDF5_PATH to an existing .hdf5 (got '${HDF5_PATH:-<unset>}'). Candidates:" >&2
  find "${RUNS_ROOT}" \( -path '*/annotate_*' -o -path '*/.latest' \) -prune -o \
    -name '*.hdf5' -type f -printf '%TY-%Tm-%Td %TH:%TM  %p\n' 2>/dev/null | sort -r | head
  exit 1
fi

RUN_DIR="${RUNS_ROOT}/annotate_${ENV_ID}_$(date +%Y%m%d_%H%M%S)"
mkdir -p "${RUN_DIR}/data" "${RUN_DIR}/logs" "${RUN_DIR}/tmp"
ln -sfn "${RUN_DIR}" "${RUNS_ROOT}/.latest"

Étape 2 — annoter hors ligne

TMPDIR="${RUN_DIR}/tmp" "${REPO_ROOT}/workflows/agentic/annotator/run.sh" \
  --env "${ENV_ID}" \
  --base-url "${VLM_BASE_URL}" \
  --model "${VLM_MODEL}" \
  --output "${RUN_DIR}/annotations.jsonl" \
  offline \
  --hdf5-path "${HDF5_PATH}" \
  --filter "${RUN_DIR}/data/filtered.hdf5" \
  > "${RUN_DIR}/logs/annotator.log" 2>&1

Étape 3 — résumer les annotations

SUCCESS_COUNT=$(grep -c '"success": true' "${RUN_DIR}/annotations.jsonl" 2>/dev/null || true)
FAILURE_COUNT=$(grep -c '"success": false' "${RUN_DIR}/annotations.jsonl" 2>/dev/null || true)
printf 'annotations: success=%s failure=%s\n' "${SUCCESS_COUNT}" "${FAILURE_COUNT}"
grep -E "Traceback|Error|FAILED" "${RUN_DIR}/logs/annotator.log" || true

Étape 4 — arrêter le VLM (seulement si vous l'avez démarré dans Démarrer le VLM)

Ignorer lors de l'utilisation d'un serveur externe (par ex. celui du local-agent) — cela tuerait ce serveur.

"${REPO_ROOT}/workflows/agentic/annotator/vllm.sh" stop

Mode En Temps Réel

Annoter les dernières images de la caméra d'une session policy/Arena en cours d'exécution sur Zenoh (les caméras utilisent par défaut la config de l'env). À utiliser seulement quand une telle session est active et que l'utilisateur demande une validation en direct.

Exécutez les étapes ci-dessous dans l'ordre. Chaque étape est un appel bash distinct ; les variables persistent dans la session tmux de l'agent local.

Étape 1 — configuration

REPO_ROOT="${I4H_WORKFLOWS:-$(git rev-parse --show-toplevel 2>/dev/null)}"; [ -d "$REPO_ROOT/workflows/agentic" ] || REPO_ROOT="$HOME/i4h-workflows"
ENV_ID=scissor_pick_and_place
RUNS_ROOT="${REPO_ROOT}/workflows/agentic/runs"
VLM_BASE_URL="${VLM_BASE_URL:-http://localhost:8000/v1}"
VLM_MODEL="${VLM_MODEL:-Qwen/Qwen3-VL-8B-Instruct}"
RUN_DIR="${RUNS_ROOT}/annotate_live_${ENV_ID}_$(date +%Y%m%d_%H%M%S)"
mkdir -p "${RUN_DIR}/tmp"

Étape 2 — annoter en temps réel

TMPDIR="${RUN_DIR}/tmp" "${REPO_ROOT}/workflows/agentic/annotator/run.sh" \
  --env "${ENV_ID}" \
  --base-url "${VLM_BASE_URL}" \
  --model "${VLM_MODEL}" \
  --output "${RUN_DIR}/live.jsonl" \
  live \
  --count 5 \
  --interval 2.0 \
  --timeout 30.0
  • --count 0 s'exécute indéfiniment ; --interval est les secondes entre les snapshots ; --timeout est le délai d'attente des premiers images de chaque caméra.
  • --min-success-frames N (nécessite un --count fini) sort avec un code d'erreur sauf si au moins N snapshots échantillonnés réussissent — à utiliser comme un filtre.
  • --dump-frames-dir DIR enregistre les snapshots échantillonnés ; ajoutez --dump-frames-only pour enregistrer sans appeler le VLM.
  • --cameras a,b outrepasse les noms de caméra Zenoh de l'env.

Vérifier

  • annotations.jsonl existe.
  • Le HDF5 filtré existe quand --filter a été passé.
  • Additionner les comptages succès/échecs du JSONL avant de les rapporter.

Prérequis

  • Workflow configuré via [[i4h-workflow-setup]] (le .venv doit exister).
  • Un enregistrement HDF5 existant à annoter (définissez HDF5_PATH à un chemin absolu ; le bloc Run liste les candidats s'il n'est pas défini ou incorrect).
  • Un endpoint compatible OpenAI accessible servant un modèle de vision — soit démarrer le sien propre (annotator/vllm.sh start) soit pointer VLM_BASE_URL/VLM_MODEL vers un serveur de vision existant. L'endpoint qwen3-coder-next du local-agent courant est insuffisant car il est texte uniquement.
  • L'annotation est facultative — ne l'exécutez que si l'utilisateur demande des étiquettes.

Limitations

  • L'annotation est facultative et n'est pas exécutée lors de la validation sauf demande.
  • Nécessite un serveur vLLM compatible OpenAI accessible ; par défaut localhost:8000/v1.
  • Le mode en temps réel s'applique seulement quand une session policy/Arena est déjà en cours d'exécution et que l'utilisateur demande une validation en direct.
  • L'annotateur lit le texte de la tâche depuis le YAML de l'env ; outrepassez par exécution avec --task-description.

Dépannage

  • Erreur : .venv non trouvé / l'import du module échoue - Cause : workflow non configuré. Correction : d'abord exécuter [[i4h-workflow-setup]].
  • Erreur : connexion refusée à localhost:8000/v1 - Cause : pas de vLLM à VLM_BASE_URL. Correction : en démarrer un (annotator/vllm.sh start) ou définir VLM_BASE_URL/VLM_MODEL vers un serveur en cours d'exécution.
  • Erreur : modèle non trouvé / 404 de l'endpoint - Cause : VLM_MODEL n'est pas l'id que le serveur sert réellement. Correction : définir VLM_MODEL au nom servi (par ex. qwen3-vl-32b ; vérifier curl ${VLM_BASE_URL}/models).
  • Erreur : entrée d'image non supportée / mauvaise requête d'un modèle texte - Cause : l'endpoint sert un modèle texte uniquement/code tel que qwen3-coder-next. Correction : utiliser un endpoint de modèle de vision tel que Qwen3-VL pour l'annotation.
  • Erreur : HDF5 en entrée non trouvé - Cause : HDF5_PATH non défini ou pas un fichier réel. Correction : choisir un chemin absolu parmi les candidats que le bloc Run affiche.
  • Erreur : HDF5 filtré manquant - Cause : --filter n'a pas été passé. Correction : ajouter --filter <path> pour écrire le dataset filtré.

Réponse Finale

Rapporter env, HDF5 en entrée, chemin des annotations, HDF5 filtré (si applicable), comptages succès/échecs, blocages du VLM.

Skills similaires