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 dansruns/.latests'il en existe un, sinon choisir le plus récent.hdf5non-annotation sousworkflows/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) depuisworkflows/agentic/config/environments/<env>.yaml. Passez--task-descriptionpour outrepasser. - Se connecte à un endpoint compatible OpenAI via
--base-url(défauthttp://localhost:8000/v1) et--model(défautQwen/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 queqwen3-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_MODELdans Run pour pointer vers lui. Un serveur local-agent exécutantqwen3-coder-nextne convient pas car il est texte uniquement.annotator/vllm.shutilise le port8000par 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 0s'exécute indéfiniment ;--intervalest les secondes entre les snapshots ;--timeoutest le délai d'attente des premiers images de chaque caméra.--min-success-frames N(nécessite un--countfini) sort avec un code d'erreur sauf si au moins N snapshots échantillonnés réussissent — à utiliser comme un filtre.--dump-frames-dir DIRenregistre les snapshots échantillonnés ; ajoutez--dump-frames-onlypour enregistrer sans appeler le VLM.--cameras a,boutrepasse les noms de caméra Zenoh de l'env.
Vérifier
annotations.jsonlexiste.- Le HDF5 filtré existe quand
--filtera été passé. - Additionner les comptages succès/échecs du JSONL avant de les rapporter.
Prérequis
- Workflow configuré via [[i4h-workflow-setup]] (le
.venvdoit 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 pointerVLM_BASE_URL/VLM_MODELvers un serveur de vision existant. L'endpointqwen3-coder-nextdu 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 :
.venvnon 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éfinirVLM_BASE_URL/VLM_MODELvers un serveur en cours d'exécution. - Erreur : modèle non trouvé / 404 de l'endpoint - Cause :
VLM_MODELn'est pas l'id que le serveur sert réellement. Correction : définirVLM_MODELau nom servi (par ex.qwen3-vl-32b; vérifiercurl ${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_PATHnon 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 :
--filtern'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.