Zexin Feng · Yixu Feng · Lingyu Xiao · Shang Su · Kexin Zheng
Chang Xu · Mengkai Shi · Shuo Feng · Xintao Yan
The University of Hong Kong · The University of Sydney · Tsinghua University · DenseAI
Cheap Training, Strong Control.
Copper-Policy jointly learns a compact world representation and a robot policy. Task-conditioned future embedding prediction shapes the representation, while current-frame visual features preserve spatial detail for action execution.
- Compact world modeling: predict future embeddings without reconstructing pixels.
- Efficient learning: a 2B model trained in 9.67 hours on 8 × RTX 5090 GPUs.
- Robust manipulation: evaluated on LIBERO, LIBERO-Plus, RoboTwin, and three real-robot tasks.
| LIBERO | LIBERO-Plus | RoboTwin clean | RoboTwin randomized | Real robot |
|---|---|---|---|---|
| 97.25% | 80.85% | 70.84% | 12.98% | 96.3% |
Results reported in the paper and project page.
- Policy inference and benchmark evaluation
- Encoder downloads and simulator setup
- Real-robot policy server
- Training code — coming soon
- Model checkpoints
- Datasets
Installation · Checkpoints · Evaluation · Real Robot · Citation
Coding agents should read AGENTS.md and follow the step-by-step
fresh reproduction guide. It covers isolated
downloads, simulator assets, compatibility fixes, actual policy smoke checks
and full evaluation with resuming. Portable helpers live in tools/;
local experiment records and environment manifests are excluded from Git.
The guide distinguishes smoke outcomes from full paper results.
After completing setup, start or resume the reference eight-GPU evaluation:
bash tools/fresh_run.sh -u tools/run_fresh_full.pyThe wrapper clears proxies automatically. Benchmark launchers select .venv-libero
for LIBERO / LIBERO-Plus and .venv for RoboTwin. Use --out-dir, --gpu-ids
and --order on the full launcher to customize the run; the guide includes a
fresh_full_v2 example and explains how to inspect logs and results.
Requirements: Linux x86_64, uv, an NVIDIA GPU, and ffmpeg. The provided lockfile records our tested environment (Python 3.10.16, PyTorch 2.9.0 / CUDA 13.0). Adapt the PyTorch/CUDA versions and package index in pyproject.toml to your GPU and driver, then regenerate uv.lock with uv lock before using the frozen commands below.
git clone https://github.com/mark4551124015/copper-policy.git
cd copper-policy
bash tools/setup_envs.sh
uv run --frozen --all-extras --no-sync python -m third_party.setup_sources allTwo independent uv environments keep simulator dependencies isolated:
| Evaluation | Environment | Lockfile | NumPy / Pillow |
|---|---|---|---|
| LIBERO / LIBERO-Plus | .venv-libero |
envs/libero/uv.lock |
1.26.4 / 12.1.1 |
| RoboTwin / real robot | .venv |
uv.lock |
1.26.4 / 11.3.0 |
Evaluation launchers select the environment automatically; no conda activation is needed. Each simulator family has its own pinned dependency versions. If adapting PyTorch/CUDA, update both pyproject.toml files and regenerate each lockfile (uv lock and uv lock --project envs/libero).
Install the simulator assets below before evaluation. The launchers select LIBERO and LIBERO-Plus independently, so both source trees can coexist in third_party/.
LIBERO & LIBERO-Plus setup
The separately locked envs/libero project contains their Python dependencies. Sources are fetched by the command above; see the upstream LIBERO and LIBERO-Plus installation guides for system requirements.
For LIBERO-Plus, install ImageMagick's shared library (Ubuntu: sudo apt-get install libmagickwand-dev) and download the additional assets:
uv run --frozen --all-extras --no-sync hf download Sylvest/LIBERO-plus assets.zip \
--repo-type dataset --local-dir third_party/LIBERO-plus
unzip third_party/LIBERO-plus/assets.zip -d third_party/LIBERO-plus/libero/liberoRoboTwin setup
Building cuRobo requires a C++ compiler and a CUDA toolkit compatible with your PyTorch installation. Adapt the toolkit version to your environment, set CUDA_HOME to its installation path, and set TORCH_CUDA_ARCH_LIST for your GPU. The architecture below (12.0+PTX) is an example for our RTX 5090 environment; replace it for your hardware.
# RTX 5090; set the architecture appropriately for other GPUs.
TORCH_CUDA_ARCH_LIST='12.0+PTX' uv run --frozen --all-extras --no-sync bash tools/setup_robotwin.sh
uv run --frozen --all-extras --no-sync bash -c \
'cd third_party/RoboTwin && bash script/_download_assets.sh'The setup uses SAPIEN 3.0.0b1, cuRobo v0.7.8 and RoboTwin revision c3ddfa8b97d5519efa828b075999bd0006778e5e. It also installs OIDN 2.3.3 for Blackwell rendering support. See the upstream RoboTwin installation guide.
Keep --inexact when synchronizing the environment: cuRobo is built separately, and an exact uv sync removes it. Rerun the setup after changing Python or PyTorch.
Download both policy checkpoints and all three encoder presets with one command:
uv run --frozen --all-extras --no-sync python -m tools.download_weights all --yesExisting caches are reused. The downloader reports estimated storage and available disk space before fetching missing weights.
| Encoder | Default preset | Source |
|---|---|---|
| World | vjepa2_1_vit_large_384 |
V-JEPA 2.1 |
| Vision | dinov2_with_registers_large |
DINOv2 |
| Text + tokenizer | wan22_ti2v_5b |
Wan 2.2 |
Manual encoder downloads
WORLD_DIR=pretrained_weights/world_encoder/vjepa2_1_vit_large_384
mkdir -p "$WORLD_DIR"
git clone --depth 1 https://github.com/facebookresearch/vjepa2.git "$WORLD_DIR/source"
curl -fL --retry 3 -o "$WORLD_DIR/vjepa2_1_vitl_dist_vitG_384.pt" \
https://dl.fbaipublicfiles.com/vjepa2/vjepa2_1_vitl_dist_vitG_384.pt
uv run --frozen --all-extras --no-sync hf download facebook/dinov2-with-registers-large \
config.json model.safetensors \
--local-dir pretrained_weights/vision_encoder/dinov2_with_registers_large
uv run --frozen --all-extras --no-sync hf download Wan-AI/Wan2.2-TI2V-5B-Diffusers \
--include 'tokenizer/*' 'text_encoder/*' \
--local-dir pretrained_weights/text_encoder/wan22_ti2v_5bEncoder presets and cache locations are defined in wan_va/modules/backbone_presets.py. A replacement encoder must match the policy checkpoint.
Download both checkpoints from Hugging Face:
uv run --frozen --all-extras --no-sync python -m tools.download_weights policy --yesUse policy libero --yes or policy robotwin --yes to download one checkpoint. all --yes downloads both policies and all three encoders. Existing complete checkpoints are reused.
The downloader places checkpoints at:
| Benchmark | Checkpoint path |
|---|---|
| LIBERO / LIBERO-Plus | pretrained_weights/copper_policy/libero/policy.pt |
| RoboTwin clean / randomized | pretrained_weights/copper_policy/robotwin/policy.pt |
LIBERO and LIBERO-Plus share one checkpoint. Each export contains policy parameters, the required model configuration, and normalization statistics. Inference uses the trained policy directly and needs no separate Wan transformer initialization weights.
uv run --frozen --all-extras --no-sync bash run.sh \
--out-dir outputs/evaluation/full_v1 \
--gpu-ids 0,1,2,3,4,5,6,7Runs RoboTwin clean → LIBERO → RoboTwin randomized → LIBERO-Plus, with compilation and rollout videos enabled.
| Benchmark | Full coverage | Episodes per task / instance |
|---|---|---|
| RoboTwin clean | 50 tasks | 50 |
| LIBERO | 40 tasks across four suites | 50 |
| RoboTwin randomized | 50 tasks | 50 |
| LIBERO-Plus | 10,030 perturbed instances | 1 |
Resume the same run after interruption:
uv run --frozen --all-extras --no-sync bash run.sh \
--out-dir outputs/evaluation/full_v1 \
--gpu-ids 0,1,2,3,4,5,6,7 --resumeuv run --frozen --all-extras --no-sync bash test_robotwin_clean.sh --all-tasks
uv run --frozen --all-extras --no-sync bash test_libero.sh --all-tasks
uv run --frozen --all-extras --no-sync bash test_robotwin_rand.sh --all-tasks
uv run --frozen --all-extras --no-sync bash test_libero_plus.sh --all-tasksSet EVAL_GPU_IDS=0 to use a single GPU. Set OUT_DIR to reuse an output directory and continue completed episodes. Without --all-tasks, the individual scripts use smaller task selections: 10 clean tasks, 6 randomized tasks, 10 LIBERO tasks, or 500 LIBERO-Plus instances.
Evaluation settings and outputs
| Setting | RoboTwin | LIBERO / LIBERO-Plus |
|---|---|---|
| Denoising steps | 10 | 10 |
| Replan steps | 24 | 10 |
| Inference seed | 0 | 7 |
| Compile | On | On |
| Video | On | On |
Each GPU keeps one policy, T5 and V-JEPA stack resident across tasks. LIBERO can run multiple environment clients per GPU with MAX_TASKS_PER_GPU; policy inference remains batch size 1. RoboTwin retains its expert check and evaluates accepted scenes.
Outputs include summary.json, task results, logs, and videos marked succ / fail. LIBERO-Plus's overall score is weighted by episodes. all_tasks_completed describes evaluation completion.
--smoke reduces episode counts; --dry-run previews commands. Use --no-compile on an individual launcher for eager inference. run.sh --help lists checkpoint, episode-count and inference-setting overrides.
Note: LIBERO language mapping
Language instructions in the LIBERO training dataset can differ from those provided by the evaluation benchmarks. We use an exact plaintext mapping from benchmark prompts to training instructions. LIBERO-Plus language perturbations are not mapped and retain their original benchmark prompts. Unmatched prompts also remain unchanged.
Launch the TCP policy server with your real-robot checkpoint:
uv run --frozen --all-extras --no-sync python wan_va/wan_va_server.py \
--checkpoint /path/to/realrobot.pt \
--t5-dir pretrained_weights/text_encoder/wan22_ti2v_5b \
--host 127.0.0.1 --port 8767 --compile-infer-action 0The server uses length-prefixed JSON requests. Model presets are in inference/; shared defaults are in inference/config_base.json.
@article{feng2026copper,
title={Copper-Policy: Focus on the Representation for Robust Robot Manipulation},
author={Feng, Zexin and Feng, Yixu and Xiao, Lingyu and Su, Shang and Zheng, Kexin and Xu, Chang and Shi, Mengkai and Feng, Shuo and Yan, Xintao},
journal={arXiv preprint arXiv:2609.32779},
year={2026}
}Our implementation builds on FastWAM and LingBot-VA. We thank their authors and the teams behind V-JEPA, DINOv2, Wan, LIBERO, LIBERO-Plus, and RoboTwin for sharing their work.
Dataset conversion to LMDB uses our lerobot-tools.
We also thank Codex for helping organize the code for this open-source release.
This code is released under Apache 2.0. External models, simulators, and assets retain their respective licenses.

