PACE-SimplerEnv: released checkpoint, config, statistics, model card
Browse files- README.md +95 -0
- config.yaml +83 -0
- dataset_statistics.json +133 -0
- pytorch_model.pt +3 -0
README.md
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
---
|
| 2 |
+
license: mit
|
| 3 |
+
library_name: pytorch
|
| 4 |
+
pipeline_tag: robotics
|
| 5 |
+
tags:
|
| 6 |
+
- vision-language-action
|
| 7 |
+
- robotics
|
| 8 |
+
- simplerenv
|
| 9 |
+
- widowx
|
| 10 |
+
- bridge
|
| 11 |
+
- progress-estimation
|
| 12 |
+
- failure-detection
|
| 13 |
+
- flow-matching
|
| 14 |
+
base_model: Qwen/Qwen3-VL-4B-Instruct
|
| 15 |
+
---
|
| 16 |
+
|
| 17 |
+
# PACE · SimplerEnv (WidowX)
|
| 18 |
+
|
| 19 |
+
> ✍️ **Fei Ni**, Zhuo Chen, Xianze Yao, Zerui Chen, Changrui Chen, Yifu Yuan, Shan Luo, Jianye Hao, Jiankang Deng<br>
|
| 20 |
+
> 💻 Code: [github.com/Fei-Ni/PACE](https://github.com/Fei-Ni/PACE)
|
| 21 |
+
|
| 22 |
+
PACE is a vision-language-action policy that internalizes task progress: it predicts a *foresight anchor* (an embedding of the finished task), reads its current progress and a forward commitment against it, and conditions its action decoder on them. This repository holds the WidowX checkpoint evaluated on SimplerEnv.
|
| 23 |
+
|
| 24 |
+
## Result
|
| 25 |
+
|
| 26 |
+
SimplerEnv WidowX success rate (%), ManiSkill3 environments, 24 episodes per task (seeds 0–23), StarVLA's default adaptive action ensembling, evaluated with `examples/SimplerEnv/eval_simpler.sh` from the code repository.
|
| 27 |
+
|
| 28 |
+
| Put Spoon on Towel | Put Carrot on Plate | Stack Green Block on Yellow Block | Put Eggplant in Basket | **Average** |
|
| 29 |
+
|---|---|---|---|---|
|
| 30 |
+
| 87.5 | 70.8 | 62.5 | 100.0 | **80.2** |
|
| 31 |
+
|
| 32 |
+
The paper (Table 1) reports an average of 75.0. This checkpoint was retrained with the released code.
|
| 33 |
+
|
| 34 |
+
## Failure alarm
|
| 35 |
+
|
| 36 |
+
Every response of the policy server also carries a failure alarm (`audit_flag`, with `audit_score` and `audit_stall`): it fires when the progress the policy commits to keeps going undelivered, or when its progress reading stops rising. With the thresholds in `config.yaml` (a shared 0.4 for unmet commitments; the stall limit calibrated on other checkpoints, never on this one), it flags 6 of the 19 failed episodes of the evaluation above and 5 of the 77 successful ones; most of the failures it misses are near misses (the block lands on the other block and slides off) whose progress reads like a success. It only reports and never changes the actions. Details and a calibration script: `docs/PROGRESS.md` in the code repository.
|
| 37 |
+
|
| 38 |
+
## Architecture
|
| 39 |
+
|
| 40 |
+
| Component | Choice |
|
| 41 |
+
|---|---|
|
| 42 |
+
| Vision-language backbone | Qwen3-VL-4B-Instruct |
|
| 43 |
+
| Action head | flow-matching DiT-B (16 layers), chunk of 16 actions, 4 denoising steps |
|
| 44 |
+
| Progress encoder | DINOv2 ViT-B/14, frozen (CLS, 768-d) |
|
| 45 |
+
| Progress interface | 4 goal-query tokens → foresight anchor; p<sub>cur</sub>, Δp<sub>cur</sub> readouts; Δp<sub>prev</sub> input token; anchor + p<sub>cur</sub> + Δp<sub>cur</sub> prepended to the DiT |
|
| 46 |
+
| Inputs | third-person image (224 × 224) at t and t − 15, instruction; no proprioception |
|
| 47 |
+
| Actions | 7-D end-effector delta (xyz, rpy, gripper), normalized with `dataset_statistics.json` (key `oxe_bridge`) |
|
| 48 |
+
|
| 49 |
+
## Training
|
| 50 |
+
|
| 51 |
+
Training scripts and recipes are in the code repository (`docs/TRAINING.md`).
|
| 52 |
+
|
| 53 |
+
## Files
|
| 54 |
+
|
| 55 |
+
```
|
| 56 |
+
PACE-SimplerEnv/
|
| 57 |
+
├── README.md
|
| 58 |
+
├── config.yaml # model config (base_vlm = Qwen/Qwen3-VL-4B-Instruct)
|
| 59 |
+
├── dataset_statistics.json # action normalization statistics
|
| 60 |
+
└── pytorch_model.pt # full model state dict
|
| 61 |
+
```
|
| 62 |
+
|
| 63 |
+
## How to load
|
| 64 |
+
|
| 65 |
+
```bash
|
| 66 |
+
huggingface-cli download spikefly/PACE-SimplerEnv --local-dir ./PACE-SimplerEnv
|
| 67 |
+
```
|
| 68 |
+
|
| 69 |
+
```python
|
| 70 |
+
from pace.model.framework.base_framework import baseframework
|
| 71 |
+
|
| 72 |
+
policy = baseframework.from_pretrained("./PACE-SimplerEnv").cuda().eval() # or "spikefly/PACE-SimplerEnv"
|
| 73 |
+
```
|
| 74 |
+
|
| 75 |
+
Qwen3-VL-4B-Instruct (processor and architecture) and the DINOv2 ViT-B/14 weights are fetched on first use; set `BASE_VLM` / `DINOV2_WEIGHTS` to local copies to skip the downloads. For evaluation, see `examples/SimplerEnv/` in the code repository.
|
| 76 |
+
|
| 77 |
+
## Sibling checkpoint
|
| 78 |
+
|
| 79 |
+
| Checkpoint | Benchmark |
|
| 80 |
+
|---|---|
|
| 81 |
+
| [spikefly/PACE-LIBERO](https://huggingface.co/spikefly/PACE-LIBERO) | LIBERO (4 suites) |
|
| 82 |
+
|
| 83 |
+
## Citation
|
| 84 |
+
|
| 85 |
+
```bibtex
|
| 86 |
+
@misc{ni2026pace,
|
| 87 |
+
title = {{PACE}: Progress Actively-internalized Conditioning Execution for Long-horizon Manipulation},
|
| 88 |
+
author = {Ni, Fei and Chen, Zhuo and Yao, Xianze and Chen, Zerui and Chen, Changrui and Yuan, Yifu and Luo, Shan and Hao, Jianye and Deng, Jiankang},
|
| 89 |
+
year = {2026}
|
| 90 |
+
}
|
| 91 |
+
```
|
| 92 |
+
|
| 93 |
+
## License
|
| 94 |
+
|
| 95 |
+
MIT for the PACE weights and code. The weights derive from StarVLA's Qwen3VL-GR00T-Bridge-RT-1 checkpoint (see its model card) and from Qwen3-VL-4B-Instruct (Apache-2.0); the progress encoder is DINOv2 (Apache-2.0); BridgeData V2 and SimplerEnv follow their own licenses.
|
config.yaml
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# PACE-SimplerEnv: model config of the released PACE checkpoint, read by the PACE code together with pytorch_model.pt
|
| 2 |
+
# and dataset_statistics.json in this directory:
|
| 3 |
+
# from pace.model.framework.base_framework import baseframework
|
| 4 |
+
# policy = baseframework.from_pretrained("./PACE-SimplerEnv")
|
| 5 |
+
# Training recipes and launchers are in the code repository (docs/TRAINING.md).
|
| 6 |
+
run_id: PACE-SimplerEnv
|
| 7 |
+
run_root_dir: runs
|
| 8 |
+
seed: 42
|
| 9 |
+
trackers: [jsonl] # "jsonl" -> <run>/metrics.jsonl; add "wandb" for Weights & Biases (entity: wandb_entity or $WANDB_ENTITY)
|
| 10 |
+
wandb_entity: null
|
| 11 |
+
wandb_project: pace
|
| 12 |
+
|
| 13 |
+
framework:
|
| 14 |
+
# "PACE"; the long alias "ProgressVLA_DinoTargetQueryProgressTripleReadoutFullGoal" is the name used by the
|
| 15 |
+
# original training runs and is still accepted.
|
| 16 |
+
name: PACE
|
| 17 |
+
qwenvl:
|
| 18 |
+
base_vlm: Qwen/Qwen3-VL-4B-Instruct # env BASE_VLM (local directory or HF id) takes precedence
|
| 19 |
+
attn_implementation: flash_attention_2 # env PACE_ATTN_IMPLEMENTATION (e.g. sdpa) overrides
|
| 20 |
+
action_model:
|
| 21 |
+
action_model_type: DiT-B # 12 heads x 64, 16 layers (diffusion_model_cfg.num_layers)
|
| 22 |
+
hidden_size: 1024
|
| 23 |
+
add_pos_embed: true
|
| 24 |
+
max_seq_len: 1024
|
| 25 |
+
action_dim: 7
|
| 26 |
+
state_dim: 7 # the state encoder exists in the checkpoint, but no proprioceptive state is fed
|
| 27 |
+
future_action_window_size: 15
|
| 28 |
+
action_horizon: 16 # action chunk H = future_action_window_size + 1
|
| 29 |
+
past_action_window_size: 0
|
| 30 |
+
noise_beta_alpha: 1.5
|
| 31 |
+
noise_beta_beta: 1.0
|
| 32 |
+
noise_s: 0.999
|
| 33 |
+
num_timestep_buckets: 1000
|
| 34 |
+
num_inference_timesteps: 4 # flow-matching (Euler) denoising steps
|
| 35 |
+
num_target_vision_tokens: 32
|
| 36 |
+
diffusion_model_cfg:
|
| 37 |
+
dropout: 0.2
|
| 38 |
+
final_dropout: true
|
| 39 |
+
interleave_self_attention: true
|
| 40 |
+
norm_type: ada_norm
|
| 41 |
+
num_layers: 16
|
| 42 |
+
output_dim: 1024
|
| 43 |
+
positional_embeddings: null
|
| 44 |
+
progress:
|
| 45 |
+
layer_idx: 18 # query readouts from the hidden states of VLM layer 18
|
| 46 |
+
num_goal_queries: 4 # K goal queries, mean-pooled into the foresight-anchor head
|
| 47 |
+
use_goal_dit_token: true # the predicted anchor is a DiT conditioning token (besides p_cur and dp_cur)
|
| 48 |
+
lambda_long: 0.1 # goal-anchor loss (MSE in DINOv2 space)
|
| 49 |
+
lambda_pcur: 0.1 # current-progress loss
|
| 50 |
+
lambda_dpcur: 0.1 # forward-commitment loss
|
| 51 |
+
lambda_cons: 0.1 # consistency: p_cur readout vs projection onto the predicted anchor
|
| 52 |
+
cons_detach_anchor: true
|
| 53 |
+
query_init_std: 0.01
|
| 54 |
+
train_query_token_rows_only: true # new token rows are trained; the rest of the VLM is fully fine-tuned
|
| 55 |
+
progress_future_offset: 15 # Delta (history / commitment horizon in env steps); equals datasets.vla_data value
|
| 56 |
+
use_history_images: true # the frame at t - Delta is an extra VLM input
|
| 57 |
+
use_dp_prev_input: true # the historical pace dp_prev enters the VLM as a token
|
| 58 |
+
use_full_goal_anchor_at_inference: true
|
| 59 |
+
infer_history_mode: step_aligned
|
| 60 |
+
dino_variant: vitb14 # frozen DINOv2 ViT-B/14 (progress geometry)
|
| 61 |
+
dino_target_dim: 768
|
| 62 |
+
dino_head_hidden_dim: 1024
|
| 63 |
+
dino_repo_root: null # null -> vendored third_party/dinov2 (env DINO_REPO_ROOT overrides)
|
| 64 |
+
dino_weights: null # null -> $PACE_CACHE/dinov2 download (env DINOV2_WEIGHTS overrides)
|
| 65 |
+
# Commitment audit (inference-time failure detector, never changes actions): alarm when the shortfall CUSUM
|
| 66 |
+
# exceeds audit_threshold or p_cur has not risen for more than audit_stall_chunks action chunks.
|
| 67 |
+
# audit_threshold is shared by all benchmarks (unmet commitments adding up to 0.4 of the task); the stall limit is
|
| 68 |
+
# calibrated per benchmark on held-out checkpoints (2.5% false alarms on successful episodes); see docs/PROGRESS.md.
|
| 69 |
+
audit_kappa: 0.0
|
| 70 |
+
audit_threshold: 0.4
|
| 71 |
+
audit_stall_chunks: 2.12
|
| 72 |
+
|
| 73 |
+
datasets:
|
| 74 |
+
vla_data:
|
| 75 |
+
dataset_py: lerobot_datasets
|
| 76 |
+
image_size: [224, 224] # inference-time resize of the client images
|
| 77 |
+
CoT_prompt: "Your task is {instruction}. To identify the key objects for your task. Locate their bounding boxes in [x1,y1,x2,y2] format."
|
| 78 |
+
return_progress_anchors: true
|
| 79 |
+
progress_future_offset: 15
|
| 80 |
+
|
| 81 |
+
trainer: # inference only reads these
|
| 82 |
+
repeated_diffusion_steps: 4
|
| 83 |
+
pretrained_checkpoint: null
|
dataset_statistics.json
ADDED
|
@@ -0,0 +1,133 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"oxe_bridge": {
|
| 3 |
+
"action": {
|
| 4 |
+
"mean": [
|
| 5 |
+
0.0002773650048766285,
|
| 6 |
+
0.0014112474163994193,
|
| 7 |
+
-0.002177168382331729,
|
| 8 |
+
0.0012878610286861658,
|
| 9 |
+
-0.0006637657643295825,
|
| 10 |
+
-0.0013808400835841894,
|
| 11 |
+
0.48941874504089355
|
| 12 |
+
],
|
| 13 |
+
"std": [
|
| 14 |
+
0.007248211186379194,
|
| 15 |
+
0.00935471709817648,
|
| 16 |
+
0.007867519743740559,
|
| 17 |
+
0.008995266631245613,
|
| 18 |
+
0.01312138419598341,
|
| 19 |
+
0.03811909258365631,
|
| 20 |
+
0.49976852536201477
|
| 21 |
+
],
|
| 22 |
+
"max": [
|
| 23 |
+
0.024597473442554474,
|
| 24 |
+
0.03418400138616562,
|
| 25 |
+
0.027751661837100983,
|
| 26 |
+
0.04975418746471405,
|
| 27 |
+
0.05278987064957619,
|
| 28 |
+
0.17337754368782043,
|
| 29 |
+
1.0
|
| 30 |
+
],
|
| 31 |
+
"min": [
|
| 32 |
+
-0.028021691367030144,
|
| 33 |
+
-0.03409120813012123,
|
| 34 |
+
-0.01872537098824978,
|
| 35 |
+
-0.049071602523326874,
|
| 36 |
+
-0.07113438844680786,
|
| 37 |
+
-0.1954353153705597,
|
| 38 |
+
0.0
|
| 39 |
+
],
|
| 40 |
+
"q01": [
|
| 41 |
+
-0.019584143050014973,
|
| 42 |
+
-0.0220843755826354,
|
| 43 |
+
-0.017999999225139618,
|
| 44 |
+
-0.02028746746480465,
|
| 45 |
+
-0.039075395241379735,
|
| 46 |
+
-0.13674069732427596,
|
| 47 |
+
0.0
|
| 48 |
+
],
|
| 49 |
+
"q99": [
|
| 50 |
+
0.018000008538365364,
|
| 51 |
+
0.027028543427586555,
|
| 52 |
+
0.018489821143448354,
|
| 53 |
+
0.027515749111771584,
|
| 54 |
+
0.03291637361049652,
|
| 55 |
+
0.09465932577848439,
|
| 56 |
+
1.0
|
| 57 |
+
],
|
| 58 |
+
"mask": [
|
| 59 |
+
true,
|
| 60 |
+
true,
|
| 61 |
+
true,
|
| 62 |
+
true,
|
| 63 |
+
true,
|
| 64 |
+
true,
|
| 65 |
+
false
|
| 66 |
+
]
|
| 67 |
+
},
|
| 68 |
+
"state": {
|
| 69 |
+
"mean": [
|
| 70 |
+
-0.14767758548259735,
|
| 71 |
+
0.043697014451026917,
|
| 72 |
+
0.9524780511856079,
|
| 73 |
+
0.7070820927619934,
|
| 74 |
+
1.4519420862197876,
|
| 75 |
+
-0.5473507642745972,
|
| 76 |
+
0.0,
|
| 77 |
+
0.8345086574554443
|
| 78 |
+
],
|
| 79 |
+
"std": [
|
| 80 |
+
0.05807220935821533,
|
| 81 |
+
0.08871077001094818,
|
| 82 |
+
0.040571380406617945,
|
| 83 |
+
2.519221782684326,
|
| 84 |
+
0.062114473432302364,
|
| 85 |
+
1.0391074419021606,
|
| 86 |
+
0.0,
|
| 87 |
+
0.17330019176006317
|
| 88 |
+
],
|
| 89 |
+
"max": [
|
| 90 |
+
-0.02664360962808132,
|
| 91 |
+
0.28091055154800415,
|
| 92 |
+
1.0775935649871826,
|
| 93 |
+
3.141587257385254,
|
| 94 |
+
1.5700854063034058,
|
| 95 |
+
3.1414706707000732,
|
| 96 |
+
0.0,
|
| 97 |
+
1.0
|
| 98 |
+
],
|
| 99 |
+
"min": [
|
| 100 |
+
-0.3056122064590454,
|
| 101 |
+
-0.12712988257408142,
|
| 102 |
+
0.8853299617767334,
|
| 103 |
+
-3.141592264175415,
|
| 104 |
+
0.760077953338623,
|
| 105 |
+
-3.1413702964782715,
|
| 106 |
+
0.0,
|
| 107 |
+
0.4054054021835327
|
| 108 |
+
],
|
| 109 |
+
"q01": [
|
| 110 |
+
-0.26134765684604644,
|
| 111 |
+
-0.10280996695160866,
|
| 112 |
+
0.887357097864151,
|
| 113 |
+
-3.131689777374268,
|
| 114 |
+
1.2599540305137635,
|
| 115 |
+
-2.9032644557952882,
|
| 116 |
+
0.0,
|
| 117 |
+
0.4054054021835327
|
| 118 |
+
],
|
| 119 |
+
"q99": [
|
| 120 |
+
-0.04747171513736247,
|
| 121 |
+
0.2269416329264641,
|
| 122 |
+
1.0707375693321228,
|
| 123 |
+
3.131361107826233,
|
| 124 |
+
1.5486225652694703,
|
| 125 |
+
2.8186778545379645,
|
| 126 |
+
0.0,
|
| 127 |
+
1.0
|
| 128 |
+
]
|
| 129 |
+
},
|
| 130 |
+
"num_transitions": 157471,
|
| 131 |
+
"num_trajectories": 4402
|
| 132 |
+
}
|
| 133 |
+
}
|
pytorch_model.pt
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:b6d590b8e1a877d469ce3de62638ab6fde78e558c375cc62873e7aa0137c9f15
|
| 3 |
+
size 10172092487
|