File size: 3,926 Bytes
7848e16 04af0e2 7848e16 04af0e2 7848e16 04af0e2 7848e16 04af0e2 7848e16 04af0e2 7848e16 04af0e2 7848e16 1537ea1 7848e16 04af0e2 7848e16 1537ea1 04af0e2 7848e16 04af0e2 7848e16 1537ea1 7848e16 04af0e2 7848e16 1537ea1 7848e16 04af0e2 1537ea1 04af0e2 7848e16 04af0e2 ec12548 04af0e2 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 | ---
license: other
license_name: gemma-terms-of-use
license_link: https://ai.google.dev/gemma/terms
library_name: n0vtla
tags:
- robotics
- vision-language-action
- tactile
- pi0.5
---
# $\mathcal{N}_0$-VTLA — pretrained base
Pretrained base weights for [N0-VTLA](https://github.com/neoteai/N0-VTLA), a
vision–tactile–language–action policy: a π0.5-style VLA with a latent tactile pathway.
## Files
```
model.safetensors the full checkpoint (~8.25 GB): π0.5 VLM, flow-matching action expert,
latent tactile predictor, and frozen DINOv2, in one state dict
config.json architecture summary
```
## Load
```python
from huggingface_hub import snapshot_download
import safetensors.torch as st
from n0vtla.training.config import get_config
from n0vtla.models_pytorch.n0vtla_policy import N0VTLAPolicy
ckpt = snapshot_download("NeoteAI/n0-vtla-base")
cfg = get_config("vtla_tactile_posttrain")
model = N0VTLAPolicy(cfg.model).eval().cuda()
missing, unexpected = st.load_model(model, f"{ckpt}/model.safetensors", strict=False, device="cuda")
assert not unexpected, unexpected
```
`missing` is expected to contain exactly
`paligemma_with_expert.paligemma.model.language_model.embed_tokens.weight`: it is tied to
`lm_head.weight` and safetensors stores tied weights once. `unexpected` must be empty.
In practice you do not call this yourself — point `VTLA_PRETRAINED_CHECKPOINT` at the download
directory and use the post-training recipe:
```bash
hf download NeoteAI/n0-vtla-base --local-dir checkpoints/n0-vtla-base
export VTLA_PRETRAINED_CHECKPOINT="$PWD/checkpoints/n0-vtla-base"
```
See **Post-training on your own robot data** in the
[repository README](https://github.com/neoteai/N0-VTLA).
## Normalization statistics
**Not included, by design.** Normalization depends on your dataset, robot action layout, and
delta-action convention, so it has to be computed on your own data:
```bash
python scripts/compute_canonical_norm.py \
--repo-id /path/to/your/canonical_dataset \
--robot flexiv \
--train-config-name vtla_tactile_posttrain \
--asset-id your_asset_id
```
The result lands in `assets/vtla_tactile_posttrain/<asset-id>/norm_stats.json`, and
`VTLA_ASSET_ID` must match the `--asset-id` you used.
## Action format
The policy outputs normalized element-wise delta actions. To run them on a robot:
1. **De-normalize** in the same element-wise (subtraction) space the model was trained in.
The quantile inverse is `x = (x_norm + 1) / 2 * (q99 - q01) + q01`, applied to the active
dims only — 10 for single-arm, 20 for dual-arm.
2. **Add back to the current state**, `abs = state + delta`, on the delta dims. Grippers and
padding are already absolute. This is the standard `AbsoluteActions` step; there is no
relative-rotation or rotation-matrix math, because the rotation delta is element-wise.
3. **Execute the full chunk.** The action horizon is 50 — execute all 50 steps before
requesting the next prediction. Executing fewer clips the tail of the chunk, which is where
the grasp-closing motion lives, and the gripper will look stuck open.
### 32-dim action/state layout
```
left arm [0:10]: xyz [0:3], rot6d [3:9], gripper [9]
right arm [10:20]: xyz [10:13], rot6d [13:19], gripper [19]
[20:32]: reserved / unused
```
Rotation is rot6d, not quaternion or Euler. On disk the `action` field is the absolute
end-effector pose; the training transforms form the delta target as `action[t+k] - state[t]`.
## License
These weights are derived from Google's PaliGemma/Gemma parameters and are therefore made
available under the [Gemma Terms of Use](https://ai.google.dev/gemma/terms) and the
[Gemma Prohibited Use Policy](https://ai.google.dev/gemma/prohibited_use_policy), **not** under
the CC BY-SA 4.0 licence that covers the source code. This is inherited from the base model, not
a restriction added on top.
|