# Wholebody Loco-manipulation ```{admonition} End-to-end quick start :class: tip **Download a trained Psi-0 checkpoint, serve it, and evaluate it on the whole-body carry-box task — producing evaluation videos.** Two terminals: **A** serves the policy, **B** runs the simulation client. Everything below runs headless — no display required — and produces an MP4 per camera plus a success rate. ``` | | Terminal A — policy server | Terminal B — evaluation client | |---|---|---| | Repository | [Psi-0](https://github.com/physical-superintelligence-lab/Psi0) | [SIMPLE](https://github.com/physical-superintelligence-lab/SIMPLE) | | Needs a GPU | yes (loads the checkpoint) | yes (Isaac Sim + MuJoCo) | | Setup | Docker **or** `uv`, [step 1](#step-1-set-up-the-psi-0-environment) | Docker **or** native `uv`, [step 2](#step-2-set-up-the-evaluation-client) | Each side can run **either** from Docker (nothing to build, recommended for a first run) **or** natively in a `uv` environment. The two choices are independent — a containerised server happily serves a native client and vice versa, because both compose stacks use `network_mode: host`. ## Step 1: Set up the Psi-0 environment Skip if you already have a working $\Psi_0$. ```bash git clone git@github.com:physical-superintelligence-lab/Psi0.git cd Psi0 ``` Copy `.env.sample` to `.env` and fill in at least `HF_TOKEN` (a read token, for the checkpoint download) and `PSI_HOME` (where checkpoints and data live by convention). Both options below read that file — the native server loads it on startup, and the compose services declare it as `env_file`. ### Option A — Docker Pull the official image from the GitHub Container Registry: ```bash docker pull ghcr.io/physical-superintelligence-lab/psi0:latest docker tag ghcr.io/physical-superintelligence-lab/psi0:latest psi:train ``` The retag is what lets `docker compose` find it — `docker-compose.yml` refers to the image as `psi:${PSI_TAG:-train}`, and `PSI_TAG` overrides the tag only, not the registry path. Pin an exact build with a dated tag such as `:260830`. Requirements: Docker with the NVIDIA Container Toolkit; the services run with `runtime: nvidia`. The image carries **dependencies only** — `src/`, `.runs/` and `$PSI_HOME` are bind-mounted, so checkpoints you download on the host are visible inside the container and code edits need only a restart, never a rebuild. To build it yourself instead: ```bash docker compose build psi ``` `psi` is the only service that declares `build:`, so a bare `docker compose build` does the same thing. Every other service — including the server in [step 5](#step-5-serve-the-policy) — consumes the image and never rebuilds it. Verify: ```bash docker compose run --rm serve-psi0-sonic-http --help ``` ### Option B — Native `uv` ```bash # uv manages the Python dependencies curl -LsSf https://astral.sh/uv/install.sh | sh uv venv .venv-psi --python 3.11 source .venv-psi/bin/activate GIT_LFS_SKIP_SMUDGE=1 uv sync \ --group serve \ --group viz \ --group psi \ --index-strategy unsafe-best-match \ --active uv pip install flash_attn==2.7.4.post1 --no-build-isolation ``` Verify: ```bash python -c "import psi; print(psi.__version__)" ``` See the [Psi-0 README](https://github.com/physical-superintelligence-lab/Psi0#installation) for the full installation notes. ## Step 2: Set up the evaluation client ### Option A — Docker (recommended) The published image already contains Isaac Sim, the SIMPLE package, and a **prebuilt SONIC whole-body controller**, so there is nothing to compile: ```bash docker pull ghcr.io/physical-superintelligence-lab/simple:latest docker tag ghcr.io/physical-superintelligence-lab/simple:latest simple:latest ``` The `docker tag` is what lets `docker compose` find it — `docker-compose.yml` refers to the image as `simple:${DATE:-latest}`. Requirements: Docker with the NVIDIA Container Toolkit (`runtime: nvidia`), and an NVIDIA driver **at least as new as** the image's CUDA toolkit release. The image is large; allow room for it. ```{note} The image is published from the SIMPLE GitHub project's package registry. If `docker pull` reports the package is not found, it has not been published for your platform yet — use Option B, or build locally with `docker compose build isaac-sim`. ``` ### Option B — Native `uv`, no Docker Runs the same client directly on the host. This one **does** need the SONIC whole-body stack compiled locally: ```bash git clone git@github.com:physical-superintelligence-lab/SIMPLE.git cd SIMPLE uv sync # creates ./.venv bash scripts/setup_teleop_wbc.sh # builds the SONIC controller into ~/tools ``` See [Setup](../sonic-wbc/setup.md) for the whole-body stack in detail. Verify: ```bash ./.venv/bin/python -c "import simple; print(simple.__version__)" ls third_party/GR00T-WholeBodyControl/gear_sonic_deploy/target/release/g1_deploy_onnx_ref ``` The evaluation refuses to start if that binary is missing — unlike teleop and replay, it does not build it on demand. ## Step 3: Download the checkpoint From your Psi-0 workspace, with `PSI_HOME` set: ```bash export RUN=sonic-wbcbox.neckle.flow1000.cosine.lr1.0e-04.b256.gpus8.2608260223 hf download USC-PSI-Lab/psi-model \ --include="psi0/simple-checkpoints/$RUN/*" \ --local-dir=.runs/finetune/ \ --repo-type=model ``` The run directory ships a single checkpoint, `checkpoints/ckpt_40000/`, and lands at `$PSI_HOME/.runs/psi0/simple-checkpoints/$RUN` (~6 GB). ## Step 4: Download the evaluation dataset The client loads domain randomized **SIMPLE eval dataset**: it reads each episode's `environment_config` from `meta/episodes.jsonl` to rebuild the scene, then lets the policy drive. ```{warning} A *training-converted* LeRobot copy of the same task will **not** work — it has the parquet files but no `environment_config`, and the evaluation stops with: ValueError: no environment_config in