Motion Asset Migration (Hugging Face)¶
Background¶
Motion assets (.npz / .csv) are no longer stored in the Git repository.
They are hosted on the Hugging Face dataset repo
unilabsim/unilab-motions
to keep the repo small and to improve clone and CI experience.
The local directory src/unilab/assets/motions/g1/ is preserved as the
download target, so existing path references stay valid.
First Use¶
Install dependencies (
huggingface_hubis part of the core dependencies):uv syncRun any training or evaluation command. Motion files are downloaded lazily when
MotionLoaderis initialized:uv run train --algo ppo --task g1_motion_tracking --sim mujoco
On first download the log shows:
INFO:unilab.assets.hub:Downloading motions/g1/dance1_subject2_part.npz from HF repo unilabsim/unilab-motions ... INFO:unilab.assets.hub:Downloaded to /path/to/src/unilab/assets/motions/g1/dance1_subject2_part.npz
Once downloaded, files are cached locally and later runs do not trigger another download.
Offline Use¶
Set the environment variable to forbid network requests:
export HF_HUB_OFFLINE=1
The resolver then only looks up local files and raises if a file is missing.
To pre-download every asset in an environment that does have network access:
huggingface-cli download unilabsim/unilab-motions \
--repo-type dataset \
--local-dir src/unilab/assets
After this completes the assets are available for offline use.
CI Caching¶
In CI, point HF_HOME at a persistent cache directory to avoid repeated
downloads:
env:
HF_HOME: /cache/huggingface
Alternatively, pre-download into the in-repo directory with --local-dir
(already excluded by .gitignore).
Adding New Motion Files¶
Generate the
.npzwith the existing pipeline (seescripts/motion/README.md).Upload to the HF repo, keeping the directory layout identical:
huggingface-cli upload unilabsim/unilab-motions \ src/unilab/assets/motions motions \ --repo-type dataset
Reference the new file path in the env config.
Robot Binary Assets¶
Robot binary meshes and textures (for example .STL, .obj, and .png) are
externalized the same way, on the Hugging Face dataset repo
unilabsim/unilab-robots.
The registered robots are a2, allegro_hand, g1, go2,
and x2 (ROBOT_ASSET_SPECS in src/unilab/assets/hub.py).
Their mesh/texture directories download lazily on first use and land under
their original paths (for example src/unilab/assets/robots/g1/assets/ and
robots/g1/textures/ for G1), so the original relative XML paths remain
valid. These directories are excluded from the wheel/sdist via
tool.uv.build-backend.source-exclude in pyproject.toml; after a pip
install, first use downloads them into the installed package tree, and later
runs reuse that local copy offline. Pre-fetch them without running a task:
uv run unilab-pull-assets --robot g1
uv run unilab-pull-assets --robot x2
uv run unilab-pull-assets --robot all # every registered robot
To add a new robot’s binary assets:
Upload each directory to the HF repo while keeping the directory layout identical. A robot with multiple asset directories requires one upload per directory. For example, G1 uses:
uv run hf upload unilabsim/unilab-robots \ src/unilab/assets/robots/g1/assets robots/g1/assets \ --repo-type dataset uv run hf upload unilabsim/unilab-robots \ src/unilab/assets/robots/g1/textures robots/g1/textures \ --repo-type dataset
Ignore the downloaded directory contents in
.gitignore, exclude the directory intool.uv.build-backend.source-exclude, and register it inROBOT_ASSET_SPECS.Scenes built through
create_backendare then covered automatically:ensure_robot_assets_for_pathsresolves the registered directories on a cold path before any backend parses the XML. Entry points that bypasscreate_backendresolve explicitly, e.g. the X2 task factory calls:resolve_robot_asset_dir("robots/x2/meshes", marker="pelvis.STL")
Architecture Notes¶
Asset resolver module:
src/unilab/assets/hub.py(resolve_motion_files).Motion integration point:
MotionLoader.__init__insrc/unilab/tasks/motion_tracking/common/motion_loader.py, which calls the resolver once on a cold path.Robot mesh integration point:
create_backendinsrc/unilab/base/backend_factory.pycallsensure_robot_assets_for_pathson the scene’smodel_file,visual_model_file, andfragment_filesbefore dispatching to a backend.Hot paths (
step/reset) never trigger any file download or parsing.ASSETS_ROOT_PATHis unchanged, so the download target matches the original local path exactly.Robot binary assets use the same directory resolver (
resolve_robot_asset_dir). The thin X2 task factory resolves its directory once before delegating to the shared manager environment factory. The resolver is also exposed through theunilab-pull-assetsCLI.