RealMan RM65 right-arm policies: pi0.5 (openpi) and ImageWAM (private)
This repo holds two policies finetuned on the same RealMan RM65 right-arm dataset. The dataset has 4 pick-and-hold tasks, 187 episodes and 58,399 frames. Each policy comes with its two latest checkpoints.
| model | training run | checkpoints | size each |
|---|---|---|---|
| pi0.5 (openpi) | pi05_rm65_4tasks_trim, 30k steps |
25000, 29999 (final) |
6.7G (params only, no optimizer state) |
| ImageWAM FLUX.2-klein-4B | rm65_4tasks_trim_flux2_klein_4b/2026-09-25_07-56-03, 10 epochs |
step_006000.pt, step_006020.pt (final) |
17.8G |
Robot interface (both models)
- State and action: each is
float32[7]=right_q1..right_q6(joint angles, rad) +right_gripper(0 = closed, 100 = open). Actions are absolute joint targets, not deltas. - Cameras:
top(head) andwrist(right wrist), both 640x480 RGB, recorded at 30 fps. - Prompts: use the exact strings the models were trained on. Each one names the object to pick:
Pick up the rightmost yellow Lay's canister with the right arm and retract while keeping it grasped.Pick up the rightmost Nongfu Spring water bottle with the right arm, retract, and hold it without releasing it.Pick up the rightmost hand soap bottle, retract the arm, and hold the bottle without releasing it.Pick up the rightmost Coca-Cola container, retract the arm, and hold it without releasing it.
Training data
The training data merges the 4 per-task deliveries (rm65_4tasks_187_20260921_delivery: yellow / nongfu /
handsoap / cocacola) and then trims them:
- Head: the static frames at the start of every episode are dropped.
- Tail: the static frames at the end are cut to 10.
- Middle: short pauses inside an episode are kept.
- Result: 66,121 frames down to 58,399.
To rebuild the dataset, run these two scripts in order:
openpi/code/scripts/merge_datasets.pyopenpi/code/scripts/trim_static_frames.py
openpi pi0.5 β openpi/
Checkpoints:
checkpoints/pi05_rm65_4tasks_trim/<step>/containsparams/andassets/rm65/4tasks_v1_trim/norm_stats.json. The norm stats must stay next to the params they came with.Code (
code/):rm65_config_excerpt.pyholdsLeRobotRM65DataConfigplus thepi05_rm65_4tasks_trimTrainConfig. Add both tosrc/openpi/training/config.py.b601_policy.pyprovides the input/output transforms. RM65 has the same 7-dim, two-camera layout as B601, so they are reused unchanged.
Model and training setup:
- pi0.5 base,
action_horizon=30(1 s of actions at 30 fps). - SigLIP trained fully, the Gemma-2B LLM with LoRA, the action expert fully.
- Batch 32, 30k steps.
- pi0.5 base,
Serving:
uv run scripts/serve_policy.py policy:checkpoint \ --policy.config=pi05_rm65_4tasks_trim \ --policy.dir=<this repo>/openpi/checkpoints/pi05_rm65_4tasks_trim/29999Inference input:
observation/top,observation/wrist(HxWx3 uint8),observation/state(7) andprompt.Inference output:
actionsof shape [30, 7].
ImageWAM β imagewam/
The layout mirrors the ImageWAM repo root, so you can copy this directory over <IW>/ImageWAM/:
- Weights and stats:
runs/rm65_4tasks_trim_flux2_klein_4b/2026-09-25_07-56-03/checkpoints/weights/step_*.ptare the full model weights, with LoRA merged.dataset_stats.jsonin the same run directory holds the normalization stats. It must always be paired with the checkpoints from this run.config.yamlin the same run directory is the resolved training config. Its absolute paths point to the original machine.
- Configs and launch script:
configs/data/rm65_4tasks_trim.yamlconfigs/task/rm65_4tasks_trim_flux2_klein_4b.yamlscripts/rm65/run_train_rm65_4tasks_trim.sh
- Text cache:
dataset/rm65_4tasks_trim/flux2_qwen3_cache_4b/holds the Qwen3 embeddings of the 4 prompts, so you don't need to run Qwen3 again for them.
How RM65 maps onto the model: the base checkpoint is the RoboTwin 14-dim joint-space model, with layout
[arm 6, gripper] x 2. RM65 occupies the left-arm slot:
- Action and state: the 7 dims sit at
[0:7]of the model's 14 dims.[7:14]is zero padding and is masked out of the loss. Takeaction[..., :7]from the model output. - Cameras: the robotwin 288x256 layout has three slots, filled like this:
cam_high<-topcam_left<-wristcam_right<- a black (all-zero) frame
- Action chunk: 16 steps at 30 fps.
Training setup:
- LoRA with rank 16 on the video expert; the action expert is trained fully.
- Learning rate 5e-5.
- Effective batch 96, 10 epochs.
- The loss is upweighted around gripper open/close transitions.
Serving: the ImageWAM repo only ships a G1 serving script (scripts/g1/serve_imagewam_g1.py,
which is 16-dim and G1-specific). An RM65 server has not been written yet. It has to reproduce the camera
and dimension mapping above.
Not included
- FLUX.2 base weights (needed to build ImageWAM):
flux-2-klein-base-4b.safetensorsfrom black-forest-labs/FLUX.2-klein-base-4Bae.safetensorsfrom black-forest-labs/FLUX.2-dev (gated)
- pi0.5 base weights: only needed for retraining, from
gs://openpi-assets/checkpoints/pi05_base. - The dataset itself.