This HuggingFace repository contains our submission to the LeHome Challenge 2026
(Garment Manipulation Skill Learning in Household Scenarios). It is a derivative
of the official lehome-challenge starter code, fine-tuned with GR00T N1.5 via
the LeRobot training framework.
It is intended to be self-contained — you can clone or download this single
HF repo and reproduce our evaluation end-to-end without any external code source.
The same source tree is also attached as a zip in our Google form submission;
both contain identical contents.
Recommended for policy inference (auto-detected via torch.cuda.is_available(), no flag needed); simulation runs on CPU regardless
NVIDIA Omniverse / IsaacSim requires accepting an EULA. Our shs/evals/eval_groot.sh exports the required environment variables (OMNI_KIT_ACCEPT_EULA=YES, ACCEPT_EULA=Y, PRIVACY_CONSENT=Y) before launching the simulator, so no manual prompt should appear.
3. Quick Start (Evaluator's Path)
bash
1# 1) Get the submission tree.2# Option A — pull straight from HuggingFace (source code + checkpoint + metadata):3huggingface-cli download theo-zhou/lehome-groot-submission-4 \4 --exclude "pretrained_model/*" --exclude "dataset_meta/*"\5 --local-dir lehome-challenge
6cd lehome-challenge
78# Option B — extract the zip we attached in the Google form submission, then `cd` in.910# 2) Set up the environment with uv11uv sync12source .venv/bin/activate
1314# 3) Install extra build/runtime packages used by the GR00T policy stack15uv pip install packaging ninja
16uv pip install flash-attn --no-build-isolation
1718# 4) Clone and install IsaacLab19mkdir -p third_party
20git clone https://github.com/lehome-official/IsaacLab.git third_party/IsaacLab
21./third_party/IsaacLab/isaaclab.sh -i none
2223# 5) Install the local LeHome package in editable mode24uv pip install -e ./source/lehome
2526# 6) Download challenge assets (garments, scenes, robots)27huggingface-cli download lehome/asset_challenge --repo-type dataset --local-dir Assets
2829# 7) Download our checkpoint into the path the eval script expects30huggingface-cli download theo-zhou/lehome-groot-submission-4 \31 --include "pretrained_model/*"\32 --local-dir outputs/train/groot_harvest_v4_from012k/checkpoints/004000/
3334# 8) Download per-category dataset metadata and stage it.35# HF download preserves repo-relative paths inside --local-dir, so files36# land at Datasets/_dataset_meta_staging/dataset_meta/<cat>_merged/meta/.37# We then mv each meta/ into the LeRobot dataset_root layout38# (<dataset_root>/meta/) and clean up the staging dir.39huggingface-cli download theo-zhou/lehome-groot-submission-4 \40 --include "dataset_meta/*"\41 --local-dir Datasets/_dataset_meta_staging
4243forcatin top_long top_short pant_long pant_short;do44mkdir -p Datasets/example/${cat}_merged
45mv Datasets/_dataset_meta_staging/dataset_meta/${cat}_merged/meta \46 Datasets/example/${cat}_merged/meta
47done48rm -rf Datasets/_dataset_meta_staging
4950# 9) (Recommended) Run a smoke test before the full eval (~5-15 min on CPU)51xvfb-run -a python -m scripts.eval \52 --policy_type lerobot \53 --policy_path outputs/train/groot_harvest_v4_from012k/checkpoints/004000/pretrained_model \54 --garment_type top_long \55 --dataset_root Datasets/example/top_long_merged \56 --num_episodes 1\57 --max_steps 200\58 --enable_cameras --headless --device cpu \59 --log_suffix smoke
6061# 10) Snapshot our self-reported results before re-running the full eval62cp submission/rollout_results.txt /tmp/ours.txt
6364# 11) Run the full Release evaluation (4 categories × 12 garments × 2 episodes)65bash shs/evals/eval_groot.sh
6667# 12) Aggregate YOUR fresh logs into submission/rollout_results.txt and diff68bash shs/submit/roll_out_txt_generation.sh # MODE=self (default)69diff /tmp/ours.txt submission/rollout_results.txt # see "Reproducibility" note below7071# 13) (Optional) Sanity-check that OUR shipped reference logs reproduce72# our self-reported numbers via the same aggregator:73MODE=ours bash shs/submit/roll_out_txt_generation.sh
74diff /tmp/ours.txt submission/rollout_results.txt # diff is metadata-only:75# - regeneration timestamp ("Generated:")76# - per-category "Log mtime:" reflects when you ran step 1377# all numeric metrics should match exactly
Note on huggingface-cli vs hf: We use the legacy huggingface-cli name throughout
the README because it is what ships with the huggingface_hub version pinned in uv.lock.
If you have upgraded to huggingface_hub>=1.0, the equivalent commands are hf download ....
4. Detailed Setup
4.1 Environment
We use uv to manage the Python 3.11 environment.
IsaacLab is installed from the official LeHome fork under third_party/, and
the local source/lehome package is installed in editable mode.
bash
1uv sync2source .venv/bin/activate
34# Extra packages used during our environment setup.5uv pip install packaging ninja
6uv pip install flash-attn --no-build-isolation
78# IsaacLab from the LeHome fork.9mkdir -p third_party
10git clone https://github.com/lehome-official/IsaacLab.git third_party/IsaacLab
11./third_party/IsaacLab/isaaclab.sh -i none
1213# Local LeHome package.14uv pip install -e ./source/lehome
uv sync installs the exact versions listed in uv.lock, including
isaacsim==5.1.0 and lerobot==0.4.3. The additional commands above match the
environment used during training and the evaluations whose results are reported
here.
4.2 Simulation Assets
The challenge garments, scenes, and robots come from the official
lehome/asset_challenge
HuggingFace dataset. They are not redistributed in our submission.
The full submission — source code, trained checkpoint, dataset metadata, and
reference eval logs — is hosted at
theo-zhou/lehome-groot-submission-4.
Top-level layout on the Hub:
pretrained_model/ and dataset_meta/ are kept separate from the source tree
so they can be downloaded selectively via --include / --exclude flags
(see steps 1, 7, 8 in §3 Quick Start).
Download:
bash
1# Checkpoint into the location the eval script expects2huggingface-cli download theo-zhou/lehome-groot-submission-4 \3 --include "pretrained_model/*"\4 --local-dir outputs/train/groot_harvest_v4_from012k/checkpoints/004000/
56# Per-category dataset metadata. Staged under Datasets/_dataset_meta_staging/7# (HF download preserves repo paths inside --local-dir), then moved into the8# LeRobot dataset_root layout (<dataset_root>/meta/).9huggingface-cli download theo-zhou/lehome-groot-submission-4 \10 --include "dataset_meta/*"\11 --local-dir Datasets/_dataset_meta_staging
1213forcatin top_long top_short pant_long pant_short;do14mkdir -p Datasets/example/${cat}_merged
15mv Datasets/_dataset_meta_staging/dataset_meta/${cat}_merged/meta \16 Datasets/example/${cat}_merged/meta
17done18rm -rf Datasets/_dataset_meta_staging
The dataset metadata is used by LeRobotDatasetMetadata to load feature schemas;
the policy's normalization parameters are baked into its own preprocessor
safetensors and do not depend on the dataset stats.
5. Running Evaluation
The end-to-end evaluation entrypoint is shs/evals/eval_groot.sh.
It iterates over the four garment categories (top_long, top_short,
pant_long, pant_short), and for each category runs scripts.eval against
the full Release garment list in Assets/objects/Challenge_Garment/Release/.
2 per garment (matches our self-reported reference logs)
--device
cpu (simulation only supports CPU per the challenge framework)
--headless
enabled (no GUI)
Logs are written to logs/<garment_type>/<MM-DD_HH-MM-SS>_eval_<log_suffix>.log.
Each category produces one log file containing per-episode Return / Length / Success,
a per-garment summary, and an overall summary block. The reference logs shipped
with this submission were generated with 2 episodes per garment, for 96 total
episodes across the four categories.
Wall-clock time: With both simulation and policy on CPU,
a full run with the default settings (96 episodes = 4 categories × 12 garments ×
2 episodes) takes roughly 8-12 hours total on a typical workstation. If a
CUDA-capable GPU is visible and the installed PyTorch is a CUDA build, the
policy will automatically run on GPU — see scripts/utils/evaluation.py:242
(device = "cuda" if torch.cuda.is_available() else "cpu"); no CLI flag is
required. The --device cpu in shs/evals/eval_groot.sh
is IsaacLab's AppLauncher flag and only controls the simulator, which the
challenge framework requires to be CPU.
5.1 Reproducibility Note
Each episode samples a random initial garment pose, so per-episode Return /
Length / Success values will differ between runs. We do not pin a seed
because the official challenge protocol uses random initialization.
These should be statistically close to ours, but note that the shipped reference
logs and the default evaluation script use 2 episodes per garment. Increase
NUM_EPISODES in shs/evals/eval_groot.sh if you want
tighter agreement. Wall-clock time scales linearly with the value.
MODE=self (default) — your own freshly-generated logs
bash shs/submit/roll_out_txt_generation.sh
Picks the latest log per category under logs/<category>/ matching
--log_suffix groot-n1.5-augmented-lr5e-5-4k (the suffix written by shs/evals/eval_groot.sh)
and writes the aggregated report to submission/rollout_results.txt.
Aggregates the four log files we shipped under
submission/reference_logs// — these
are the exact logs that produced the numbers in our self-reported
submission/rollout_results.txt. Useful for
sanity-checking that the aggregator deterministically reproduces our reported
numbers from the raw logs (the diff against a snapshot of the shipped
rollout_results.txt should be empty modulo the regeneration timestamp at the
top).
Underlying behavior
In both modes the aggregator:
Picks the latest log per category matching --log_suffix groot-n1.5-augmented-lr5e-5-4k under the
resolved --logs_dir. Explicit per-category --<category>_log overrides
are also supported by the Python script directly.
Parses per-episode results, per-garment summaries, and overall metrics
directly from the logs.
Auto-extracts metadata (policy_type, policy_path, action_dim,
episodes_per_garment, eval list source) from each log header.
Overwritessubmission/rollout_results.txt in place — snapshot it first
(cp submission/rollout_results.txt /tmp/ours.txt) if you want to diff
against our self-reported numbers afterward.
Source code is also attached as a zip (submission_4.zip) in our Google form
submission; both are byte-for-byte identical to this repo's source tree
(excluding the pretrained_model/ and dataset_meta/ folders which are only
on HuggingFace due to size).