i4h Workflow — Finetune
Purpose
Fine-tune une politique GR00T ou openpi PI0 sur un dataset LeRobot existant. À utiliser quand on vous demande de fine-tuner, entraîner ou post-entraîner une politique sur des démos enregistrées.
Base Code
Ces étapes pilotent le code de base i4h-workflows (l'arborescence workflows/agentic/). Pour réutiliser un checkout existant, définissez I4H_WORKFLOWS sur son chemin (aucun clone ne se produit). Sinon, cela résout le repo courant, ou clone vers ~/i4h-workflows — choisissez cette valeur par défaut sans demander. Exécutez chaque commande ci-dessous à partir de 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"
Basics
- Le chemin du dataset doit être un répertoire LeRobot existant avec
meta/info.json. - Le support d'entraînement est déterminé par
policy.train_moduledansworkflows/agentic/config/environments/<env>.yaml. Une valeur nulle signifie inference-only. assemble_trocarest inference-only.
Stack Map
| Env | Stack | CLI |
|---|---|---|
scissor_pick_and_place |
gr00t_n15 |
i4h-agentic-gr00t-n15-train |
locomanip_tray_pick_and_place |
gr00t_n16 |
i4h-agentic-gr00t-n16-train |
locomanip_push_cart |
gr00t_n16 |
i4h-agentic-gr00t-n16-train |
ultrasound_liver_scan |
openpi_pi0 |
i4h-agentic-openpi-pi0-train |
Les envs locomanip N1.6 partagent policy.locomanip.train.
Preflight
test -f "${DATASET_PATH}/meta/info.json"
nvidia-smi --query-gpu=name --format=csv,noheader | wc -l
workflows/agentic/policy/<stack>/run.sh --list-envs
Run
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.
Step 1 — setup and resolve dataset
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
STACK_DIR=gr00t_n15
TRAIN_CLI=i4h-agentic-gr00t-n15-train
RUNS_ROOT="${REPO_ROOT}/workflows/agentic/runs"
# Point DATASET_PATH at a converted LeRobot dataset dir (absolute; must contain meta/info.json),
# produced by [[i4h-workflow-dataset-convert]]. List candidates:
# find "${RUNS_ROOT}" "${HF_LEROBOT_HOME:-$HOME/.cache/huggingface/lerobot}" -name info.json -path '*/meta/*' -printf '%h\n' | sed 's#/meta$##' | sort -u
DATASET_PATH="${DATASET_PATH:-}"
if [ ! -f "${DATASET_PATH%/}/meta/info.json" ]; then
echo "finetune: set DATASET_PATH to a LeRobot dataset dir with meta/info.json (got '${DATASET_PATH:-<unset>}'). Candidates:" >&2
find "${RUNS_ROOT}" "${HF_LEROBOT_HOME:-$HOME/.cache/huggingface/lerobot}" -name info.json -path '*/meta/*' -printf '%h\n' 2>/dev/null | sed 's#/meta$##' | sort -u | head
exit 1
fi
RUN_DIR="${RUNS_ROOT}/finetune_${ENV_ID}_$(date +%Y%m%d_%H%M%S)"
OUT="${RUN_DIR}/checkpoint"
export TMPDIR=/tmp # short path: torch DataLoader FD-sharing socket must fit AF_UNIX's 108-byte limit
mkdir -p "${OUT}" "${RUN_DIR}/logs"
ln -sfn "${RUN_DIR}" "${RUNS_ROOT}/.latest"
Step 2 — train
uv --directory "${REPO_ROOT}/workflows/agentic/policy/${STACK_DIR}" run "${TRAIN_CLI}" \
--env "${ENV_ID}" \
--dataset-path "${DATASET_PATH}" \
--output-dir "${OUT}" \
--max-steps 1000 \
--save-steps 1000 \
--num-gpus 1 \
2>&1 | tee "${RUN_DIR}/logs/finetune.log"
Les flags Tyro utilisent kebab case (--max-steps, pas --max_steps).
Common Flags
--dataset-path PATH(requis)--output-dir PATH--base-model-path PATH_OR_REPOsurcharge YAMLpolicy.model_repo--max-steps N,--save-steps N--batch-size N,--learning-rate FLOAT--no-tune-visual— gèle le backbone visuel (entraîne uniquement la head d'action + projector) : ~2× plus rapide, ~moitié de mémoire, moins d'overfitting. Bon défaut pour les petits datasets ; déverrouiller seulement avec beaucoup de données + une véritable différence de domaine visuel.--num-gpus N— ne doit pas dépasser les GPUs visibles--report-to tensorboard|wandb
Verify
- Le répertoire checkpoint
${OUT}/checkpoint-<N>contientmodel-0000*-of-*.safetensors,experiment_cfg/,processor/. - Le log contient les lignes
train_losset un résumé final'train_runtime': ....
Prerequisites
- Workflow configuré via [[i4h-workflow-setup]] (le
.venvdu stack doit exister). - Un répertoire LeRobot existant avec
meta/info.json. - Un env capable d'entraînement :
policy.train_modulenon-null dansworkflows/agentic/config/environments/<env>.yaml(assemble_trocarest inference-only). - Au moins une GPU visible (
--num-gpusne doit pas dépasser les GPUs visibles).
Limitations
- Les envs inference-only (null
policy.train_module, ex.assemble_trocar) ne peuvent pas être fine-tunés. - Nécessite GPU(s) ;
--num-gpusne doit pas dépasser le compte denvidia-smi. - Les envs locomanip N1.6 partagent
policy.locomanip.train. - Chaque env mappe à un stack/CLI (voir Stack Map) ; le dataset doit correspondre à cet env.
Troubleshooting
- Erreur : train CLI / module import échoue - Cause : workflow non configuré,
.venvdu stack manquant. Fix : exécutez [[i4h-workflow-setup]] d'abord. - Erreur : chemin dataset rejeté /
meta/info.jsonmanquant - Cause :--dataset-pathn'est pas un répertoire LeRobot valide. Fix : pointez vers un dataset LeRobot converti (voir Preflighttest -f). - Erreur : env est inference-only / pas de support d'entraînement - Cause :
policy.train_moduleest null pour cet env. Fix : choisissez un env capable d'entraînement du Stack Map. - Erreur : flag non reconnu comme
--max_steps- Cause : les flags Tyro utilisent kebab case. Fix : utilisez la forme--max-steps.
Final Response
Rapportez l'env, le stack, le chemin du dataset, le chemin du checkpoint de sortie, le résumé train_loss et les blocages.