pi0-sponge-marker-10k-nullstate-3k (PyTorch)

pi0 policy for the SO-101 sponge/marker task, with a classifier-free-guidance-style null-state capability so it can be run with or without proprioceptive state.

Format: PyTorch (model.safetensors), converted from the JAX/orbax training checkpoint.

Provenance

  • Base: mkpongm/pi0-sponge-marker-10k (stage-1 pi0, 10k steps)
  • Stage-2: action-head-only fine-tune, 3,000 steps, state_dropout_prob=0.2
  • Null token scope: dropout/null token restricted to the real state dims [0:6] (state_dropout_dim=6); the padded dims [6:32] are exactly zero, matching how real state is zero-padded from 6 → action_dim=32.
  • Precision: bf16 (frozen backbone was bf16 in the stage-2 checkpoint; inference computes in bf16).

The null-state embedding is baked into the model

Unlike a stock JAX→PyTorch conversion (which silently drops it), this checkpoint carries the learned null-state embedding as a real parameter, null_state_token — shape (32,), with dims [6:32] zero. Verified identical to the JAX source (max abs diff ~1.7e-6).

Dual inference (with / without proprioception)

The state token is fed through state_proj. Both branches use the same converted weights:

branch state fed to the model
with proprioception the real robot state, zero-padded 6 → 32
without proprioception model.null_state_token (32-dim), broadcast to batch
# null (no-proprioception) branch:
state = model.null_state_token.unsqueeze(0).expand(batch_size, -1)

Normalization

Z-score (mean/std) — this is a plain pi0 model (model_type == PI0), so openpi uses the mean/std branch of Normalize, not quantile or min-max. Stats come from assets/mkpongm/sponge_marker_merged/norm_stats.json (shipped here).

  • normalize (state in): (x - mean) / (std + 1e-6)
  • un-normalize (action out): x * (std + 1e-6) + mean

Un-normalize the action outputs with the inverse before sending to the robot.

Downloads last month
29
Safetensors
Model size
4B params
Tensor type
BF16
·
Video Preview
loading