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-2 \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) Download challenge assets (garments, scenes, robots)15huggingface-cli download lehome/asset_challenge --repo-type dataset --local-dir Assets
1617# 4) Download our checkpoint into the path the eval script expects18huggingface-cli download theo-zhou/lehome-groot-submission-2 \19 --include "pretrained_model/*"\20 --local-dir outputs/train/groot_four_types_merged_batch64_lr2e-4/checkpoints/012000/
2122# 5) Download per-category dataset metadata and stage it.23# HF download preserves repo-relative paths inside --local-dir, so files24# land at Datasets/_dataset_meta_staging/dataset_meta/<cat>_merged/meta/.25# We then mv each meta/ into the LeRobot dataset_root layout26# (<dataset_root>/meta/) and clean up the staging dir.27huggingface-cli download theo-zhou/lehome-groot-submission-2 \28 --include "dataset_meta/*"\29 --local-dir Datasets/_dataset_meta_staging
3031forcatin top_long top_short pant_long pant_short;do32mkdir -p Datasets/example/${cat}_merged
33mv Datasets/_dataset_meta_staging/dataset_meta/${cat}_merged/meta \34 Datasets/example/${cat}_merged/meta
35done36rm -rf Datasets/_dataset_meta_staging
3738# 6) (Recommended) Run a smoke test before the full eval (~5-15 min on CPU)39xvfb-run -a python -m scripts.eval \40 --policy_type lerobot \41 --policy_path outputs/train/groot_four_types_merged_batch64_lr2e-4/checkpoints/012000/pretrained_model \42 --garment_type top_long \43 --dataset_root Datasets/example/top_long_merged \44 --num_episodes 1\45 --max_steps 200\46 --enable_cameras --headless --device cpu \47 --log_suffix smoke
4849# 7) Snapshot our self-reported results before re-running the full eval50cp submission/rollout_results.txt /tmp/ours.txt
5152# 8) Run the full Release evaluation (4 categories × 12 garments × 5 episodes)53bash shs/evals/eval_groot.sh
5455# 9) Aggregate YOUR fresh logs into submission/rollout_results.txt and diff56bash shs/submit/roll_out_txt_generation.sh # MODE=self (default)57diff /tmp/ours.txt submission/rollout_results.txt # see "Reproducibility" note below5859# 9b) (Optional) Sanity-check that OUR shipped reference logs reproduce60# our self-reported numbers via the same aggregator:61MODE=ours bash shs/submit/roll_out_txt_generation.sh
62diff /tmp/ours.txt submission/rollout_results.txt # diff is metadata-only:63# - regeneration timestamp ("Generated:")64# - per-category "Log mtime:" reflects when you ran step 9b65# 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 ....
uv sync installs the exact versions listed in uv.lock, including
isaacsim==5.1.0, lerobot==0.4.3, and the local lehome package
(source/lehome). The environment matches the one 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-2.
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, 4, 5 in §3 Quick Start).
Download:
bash
1# Checkpoint into the location the eval script expects2huggingface-cli download theo-zhou/lehome-groot-submission-2 \3 --include "pretrained_model/*"\4 --local-dir outputs/train/groot_four_types_merged_batch64_lr2e-4/checkpoints/012000/
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-2 \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/.
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.
Wall-clock time: With both simulation and policy on CPU,
a full run (240 episodes = 4 categories × 12 garments × 5 episodes) takes
roughly 20-30 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 (within a few percentage points
given NUM_EPISODES=5). If you want tighter agreement, increase NUM_EPISODES
in the script — 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-batch64-12k (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-batch64-12k 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_2.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).