Instructions to use AlexWortega/tinyvla with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- LeRobot
How to use AlexWortega/tinyvla with LeRobot:
- Notebooks
- Google Colab
- Kaggle
Upload folder using huggingface_hub
Browse filesThis view is limited to 50 files because it contains too many changes. See raw diff
- .gitattributes +12 -0
- tinyvla2/CLAUDE.md +153 -0
- tinyvla2/REPORT.md +171 -0
- tinyvla2/assets/so_arm/assets/base_motor_holder_so101_v1.stl +3 -0
- tinyvla2/assets/so_arm/assets/base_so101_v2.stl +3 -0
- tinyvla2/assets/so_arm/assets/motor_holder_so101_base_v1.stl +3 -0
- tinyvla2/assets/so_arm/assets/motor_holder_so101_wrist_v1.stl +3 -0
- tinyvla2/assets/so_arm/assets/moving_jaw_so101_v1.stl +3 -0
- tinyvla2/assets/so_arm/assets/rotation_pitch_so101_v1.stl +3 -0
- tinyvla2/assets/so_arm/assets/sts3215_03a_no_horn_v1.stl +3 -0
- tinyvla2/assets/so_arm/assets/sts3215_03a_v1.stl +3 -0
- tinyvla2/assets/so_arm/assets/under_arm_so101_v1.stl +3 -0
- tinyvla2/assets/so_arm/assets/upper_arm_so101_v1.stl +3 -0
- tinyvla2/assets/so_arm/assets/waveshare_mounting_plate_so101_v2.stl +0 -0
- tinyvla2/assets/so_arm/assets/wrist_roll_follower_so101_v1.stl +3 -0
- tinyvla2/assets/so_arm/assets/wrist_roll_pitch_so101_v2.stl +3 -0
- tinyvla2/assets/so_arm/so101_new_calib.urdf +453 -0
- tinyvla2/assets/so_arm/so101_nomesh.urdf +453 -0
- tinyvla2/configs/ablation_nolatent.yaml +25 -0
- tinyvla2/configs/ablation_nospatial.yaml +25 -0
- tinyvla2/configs/libero_ft.yaml +31 -0
- tinyvla2/configs/libero_ft2.yaml +33 -0
- tinyvla2/configs/libero_ft3.yaml +33 -0
- tinyvla2/configs/libero_ft4.yaml +33 -0
- tinyvla2/configs/morphology/descriptors.yaml +277 -0
- tinyvla2/configs/morphology/robot_prompts.yaml +13 -0
- tinyvla2/configs/stage2_mixture.yaml +37 -0
- tinyvla2/configs/stage3_distill.yaml +40 -0
- tinyvla2/configs/tv2_A.yaml +42 -0
- tinyvla2/configs/tv2_B.yaml +42 -0
- tinyvla2/configs/tv2_C.yaml +42 -0
- tinyvla2/configs/tv2_C_diverse.yaml +67 -0
- tinyvla2/configs/tv2_C_diverse_slow.yaml +68 -0
- tinyvla2/configs/tv2_C_incontext.yaml +72 -0
- tinyvla2/configs/tv2_C_incontext_v2.yaml +73 -0
- tinyvla2/configs/tv2_C_incontext_v3.yaml +77 -0
- tinyvla2/configs/tv2_C_mega.yaml +71 -0
- tinyvla2/configs/tv2_C_qwen_morph.yaml +73 -0
- tinyvla2/configs/tv2_C_scaled.yaml +76 -0
- tinyvla2/configs/tv2_demoonly.yaml +89 -0
- tinyvla2/configs/tv2_richslow.yaml +83 -0
- tinyvla2/configs/tv2_robocasa.yaml +77 -0
- tinyvla2/configs/tv2_vlm_native.yaml +83 -0
- tinyvla2/scripts/__pycache__/fewshot_grid.cpython-312.pyc +0 -0
- tinyvla2/scripts/_eval_richslow_10k.py +141 -0
- tinyvla2/scripts/audit_so101_fk.py +103 -0
- tinyvla2/scripts/build_ee_sidecar.py +169 -0
- tinyvla2/scripts/diag_obs_gap.py +131 -0
- tinyvla2/scripts/download_subsets.py +77 -0
- tinyvla2/scripts/eval_canonical.py +186 -0
.gitattributes
CHANGED
|
@@ -39,3 +39,15 @@ videos/ep02_task2_succ.mp4 filter=lfs diff=lfs merge=lfs -text
|
|
| 39 |
videos/ep03_task3_fail.mp4 filter=lfs diff=lfs merge=lfs -text
|
| 40 |
videos/ep04_task4_succ.mp4 filter=lfs diff=lfs merge=lfs -text
|
| 41 |
videos/ep05_task5_fail.mp4 filter=lfs diff=lfs merge=lfs -text
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 39 |
videos/ep03_task3_fail.mp4 filter=lfs diff=lfs merge=lfs -text
|
| 40 |
videos/ep04_task4_succ.mp4 filter=lfs diff=lfs merge=lfs -text
|
| 41 |
videos/ep05_task5_fail.mp4 filter=lfs diff=lfs merge=lfs -text
|
| 42 |
+
tinyvla2/assets/so_arm/assets/base_motor_holder_so101_v1.stl filter=lfs diff=lfs merge=lfs -text
|
| 43 |
+
tinyvla2/assets/so_arm/assets/base_so101_v2.stl filter=lfs diff=lfs merge=lfs -text
|
| 44 |
+
tinyvla2/assets/so_arm/assets/motor_holder_so101_base_v1.stl filter=lfs diff=lfs merge=lfs -text
|
| 45 |
+
tinyvla2/assets/so_arm/assets/motor_holder_so101_wrist_v1.stl filter=lfs diff=lfs merge=lfs -text
|
| 46 |
+
tinyvla2/assets/so_arm/assets/moving_jaw_so101_v1.stl filter=lfs diff=lfs merge=lfs -text
|
| 47 |
+
tinyvla2/assets/so_arm/assets/rotation_pitch_so101_v1.stl filter=lfs diff=lfs merge=lfs -text
|
| 48 |
+
tinyvla2/assets/so_arm/assets/sts3215_03a_no_horn_v1.stl filter=lfs diff=lfs merge=lfs -text
|
| 49 |
+
tinyvla2/assets/so_arm/assets/sts3215_03a_v1.stl filter=lfs diff=lfs merge=lfs -text
|
| 50 |
+
tinyvla2/assets/so_arm/assets/under_arm_so101_v1.stl filter=lfs diff=lfs merge=lfs -text
|
| 51 |
+
tinyvla2/assets/so_arm/assets/upper_arm_so101_v1.stl filter=lfs diff=lfs merge=lfs -text
|
| 52 |
+
tinyvla2/assets/so_arm/assets/wrist_roll_follower_so101_v1.stl filter=lfs diff=lfs merge=lfs -text
|
| 53 |
+
tinyvla2/assets/so_arm/assets/wrist_roll_pitch_so101_v2.stl filter=lfs diff=lfs merge=lfs -text
|
tinyvla2/CLAUDE.md
ADDED
|
@@ -0,0 +1,153 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# TinyVLA — project context
|
| 2 |
+
|
| 3 |
+
Small vision-language-action models. Two lines of work:
|
| 4 |
+
|
| 5 |
+
- **v1 (shipped)** — dual-rate VLA for LIBERO: slow Qwen3.5 semantic path (cacheable,
|
| 6 |
+
0.5–2 Hz) + fast flow-matching expert (10–20 Hz). **86% LIBERO-spatial, 84% 4-suite
|
| 7 |
+
average** — beats OpenVLA-7B on every suite at 0.64B params / 140M online.
|
| 8 |
+
- **v2 (research)** — cross-embodiment: canonical action space + morphology
|
| 9 |
+
conditioning across 10 robots. Best: `tv2_C_scaled` (ratio-to-baseline **0.81**
|
| 10 |
+
in-training / **0.88** held-out; was 0.99/1.17 before scaling).
|
| 11 |
+
|
| 12 |
+
Everything (checkpoints, results, wiring) lives in the **private** HF repo
|
| 13 |
+
`AlexWortega/tinyvla` (v1 at the root, v2 under `tinyvla2/`).
|
| 14 |
+
|
| 15 |
+
## Environment
|
| 16 |
+
|
| 17 |
+
```bash
|
| 18 |
+
source ~/tinyvla_venv/bin/activate # NOT physics_venv
|
| 19 |
+
```
|
| 20 |
+
|
| 21 |
+
Pinned, non-obvious, and hard-won:
|
| 22 |
+
- lerobot **0.6.1**, torch **2.10.0+cu128**, transformers **5.5.4** (lerobot's
|
| 23 |
+
`transformers-dep` extra; older breaks `eo1`).
|
| 24 |
+
- **torchcodec 0.10 CPU build from PyPI** — the cu128 wheel clashes with the system
|
| 25 |
+
NPP libs. Video decode is the training bottleneck, use 12+ dataloader workers.
|
| 26 |
+
- `placo` for SO-101 forward kinematics; needs `assets/so_arm/so101_new_calib.urdf`
|
| 27 |
+
**plus the 13 STL meshes** (placo loads collision geometry, it won't run without them).
|
| 28 |
+
- `fla-core` + `causal-conv1d` give Qwen3.5 linear-attention its fast path (~5×);
|
| 29 |
+
they require CUDA — any CPU-only smoke test of the model will crash inside
|
| 30 |
+
`causal_conv1d`.
|
| 31 |
+
- Data lives in `~/tinyvla_data` (gitignored), HF cache in `~/.cache/huggingface`.
|
| 32 |
+
|
| 33 |
+
## Architecture
|
| 34 |
+
|
| 35 |
+
```
|
| 36 |
+
SLOW (cacheable @1Hz) FAST (10–20 Hz, ~140M online)
|
| 37 |
+
image → Qwen3.5-0.8B vision tower ─┬────► 64 spatial tokens/cam ──┐
|
| 38 |
+
instruction ──────────────────────┤ │
|
| 39 |
+
▼ proprio ┤
|
| 40 |
+
LM (first 12 of 24 layers) morphology/ID ┤
|
| 41 |
+
▼ ▼
|
| 42 |
+
8–16 readout latents ────────────────► flow-matching expert
|
| 43 |
+
(38M, chunk 50, 10 Euler)
|
| 44 |
+
```
|
| 45 |
+
|
| 46 |
+
Variant switches in `TinyVLAConfig`:
|
| 47 |
+
- `conditioning`: `id` (learned embedding) | `morph` (16-number descriptor → MLP) |
|
| 48 |
+
`morph_qwen` (robot text through the shared LM)
|
| 49 |
+
- `action_space`: `native` | `canonical` (base-frame EE deltas)
|
| 50 |
+
- `vlm_native`: demos + robot text go INTO the LM sequence (dual-rate preserved)
|
| 51 |
+
- `use_demo_conditioning`, `demo_only`: in-context exemplar channels (all dead, see below)
|
| 52 |
+
|
| 53 |
+
## Data pipeline
|
| 54 |
+
|
| 55 |
+
```
|
| 56 |
+
LeRobot dataset → scripts/build_ee_sidecar.py (offline, once, NO video decode)
|
| 57 |
+
SO-101: FK(joints) via placo; others: EE pose from state
|
| 58 |
+
→ ~/tinyvla_data/ee_sidecar/<name>.parquet
|
| 59 |
+
→ src/tinyvla/data/canonical.py (10 Hz resample, base-frame
|
| 60 |
+
left-delta rotvec, gripper q1–q99, quantile norm to [-1,1])
|
| 61 |
+
→ CanonicalSource → WeightedMixtureDataset → policy
|
| 62 |
+
```
|
| 63 |
+
|
| 64 |
+
`docs/WIRING.md` has the full embodiment registry (id ↔ morph_key ↔ dataset ↔
|
| 65 |
+
canonicalization source ↔ weight ↔ train/held-out).
|
| 66 |
+
|
| 67 |
+
Robot pool: SO-101 (40 community sets, FK), Bridge/WidowX 53K eps, RT-1/Google 87K eps,
|
| 68 |
+
UR5, xArm, DLR-EDAN, TidyBot, Stretch, Jaco, LeKiwi (held out), RoboCasa365/PandaOmron.
|
| 69 |
+
|
| 70 |
+
## Running things
|
| 71 |
+
|
| 72 |
+
```bash
|
| 73 |
+
# training (any variant — the config picks the mode)
|
| 74 |
+
PYTHONUNBUFFERED=1 python scripts/train.py --config configs/tv2_C_scaled.yaml
|
| 75 |
+
|
| 76 |
+
# physical-space eval across robots (the metric that matters)
|
| 77 |
+
python scripts/eval_similar_robots.py # ratio = endpoint err ÷ zero-floor
|
| 78 |
+
|
| 79 |
+
# LIBERO closed-loop (v1)
|
| 80 |
+
MUJOCO_GL=egl python scripts/eval_libero.py --checkpoint <ckpt> \
|
| 81 |
+
--suite libero_spatial --episodes 100 --n-action-steps 10 --action-repeat 1
|
| 82 |
+
```
|
| 83 |
+
|
| 84 |
+
Long runs: launch with `nohup`, watch via checkpoints (stdout is block-buffered
|
| 85 |
+
under nohup — use `PYTHONUNBUFFERED=1` or you see nothing for hours).
|
| 86 |
+
|
| 87 |
+
## Evaluation — read this before trusting any number
|
| 88 |
+
|
| 89 |
+
1. **Always run the zero-prediction control.** Per-step action error is degenerate
|
| 90 |
+
(jaco moves ~3.6 mm/step; predicting zeros scores ~4 mm). Use the
|
| 91 |
+
**integrated-trajectory endpoint error over the 50-step chunk**, and divide by the
|
| 92 |
+
per-robot **zero-floor** (what "predict mean motion" achieves). Only the ratio is
|
| 93 |
+
comparable across robots; ratio < 1.0 means the model beats the trivial baseline.
|
| 94 |
+
2. **Check both held-out robots, not one.** "canonical ≫ native" looked decisive on
|
| 95 |
+
jaco and reversed on stretch.
|
| 96 |
+
3. Absolute mm are meaningless across robots — different motion scales.
|
| 97 |
+
|
| 98 |
+
## Results
|
| 99 |
+
|
| 100 |
+
### v1 — LIBERO (closed-loop success)
|
| 101 |
+
| suite | TinyVLA | OpenVLA-7B |
|
| 102 |
+
|---|---|---|
|
| 103 |
+
| spatial | **86%** (dual-rate @1 Hz; 79% full-rate) | 84.7% |
|
| 104 |
+
| object | **94%** | 88.4% |
|
| 105 |
+
| goal | **86%** | 79.2% |
|
| 106 |
+
| long | **70%** | 53.7% |
|
| 107 |
+
| **avg** | **84.0%** | 76.5% |
|
| 108 |
+
|
| 109 |
+
Dual-rate (semantic latent refreshed at 1 Hz) matched or beat full-rate — the core
|
| 110 |
+
architectural claim, verified closed-loop.
|
| 111 |
+
|
| 112 |
+
### v2 — cross-embodiment (ratio to zero-floor, lower is better)
|
| 113 |
+
| | in-training | held-out |
|
| 114 |
+
|---|---|---|
|
| 115 |
+
| C-diverse (8 robots, 20k steps, frozen LM) | 0.99 | 1.17 |
|
| 116 |
+
| **C-scaled (9.1M frames, 60k steps, LM unfrozen)** | **0.81** | **0.88** |
|
| 117 |
+
|
| 118 |
+
Per-robot final: jaco 0.69, xarm 0.64, dlr_edan 0.69, stretch 0.69, LeKiwi (held-out)
|
| 119 |
+
1.07, ur5 1.22 (hardest — the fastest robot, 9.9 mm/step; its canonicalization is fine).
|
| 120 |
+
|
| 121 |
+
**Negative results (all documented in `tinyvla2/RESULTS.md`):**
|
| 122 |
+
- Robot description as text in the prompt (frozen LM) — hurts.
|
| 123 |
+
- Morphology via the shared Qwen + unfrozen LM — 3× more content-sensitive, no
|
| 124 |
+
absolute gain.
|
| 125 |
+
- In-context demo conditioning — **five architectures**, all dead (real vs garbage
|
| 126 |
+
exemplars indistinguishable): MLP same-task → MLP cross-task → 24× capacity →
|
| 127 |
+
demos inside the LM attention stream → demos as the only identity channel.
|
| 128 |
+
|
| 129 |
+
## Lessons
|
| 130 |
+
|
| 131 |
+
1. **Check against the trivial baseline before running ablations.** Five conditioning
|
| 132 |
+
mechanisms moved nothing while the model sat at ratio 0.99 — we were comparing
|
| 133 |
+
variants of an underfit model and measuring noise. Data + steps + unfreezing the LM
|
| 134 |
+
moved everything.
|
| 135 |
+
2. **Silent data-convention bugs cost the most time.** LIBERO went 0% → 60% purely by
|
| 136 |
+
fixing three of them: robosuite renders are **180°-rotated** (a vertical flip alone
|
| 137 |
+
leaves a mirror), eef rotvec is antipodal vs the dataset, and the dataset's
|
| 138 |
+
`fps: 10` metadata is wrong (frames are native 20 Hz). A **GT-action replay
|
| 139 |
+
harness** (`scripts/replay_libero.py`) diagnoses all of these independently of the
|
| 140 |
+
policy — build it first.
|
| 141 |
+
3. **Unfreezing the LM is the single biggest lever** (LIBERO 60% → 86%).
|
| 142 |
+
4. Cross-morphology transfer converges slowest — LeKiwi was still improving at 60k
|
| 143 |
+
(1.24 → 1.13 → 1.07) when in-training had plateaued at 40k.
|
| 144 |
+
5. Some community datasets are broken at source (meta frame count ≠ parquet rows);
|
| 145 |
+
validate `len(reader.hf_dataset) == meta.total_frames` and quarantine mismatches.
|
| 146 |
+
|
| 147 |
+
## State
|
| 148 |
+
|
| 149 |
+
Best checkpoints: **v1** `outputs/libero_ft4/final` (86% LIBERO) · **v2**
|
| 150 |
+
`outputs/tv2_C_scaled/final` (0.81/0.88). Currently training: `tv2_robocasa` —
|
| 151 |
+
continue-train from C-scaled on RoboCasa365 (sim kitchens, PandaOmron mobile
|
| 152 |
+
manipulator, 1.5M frames) at weight 0.5 with the old robots replayed at 0.5, to
|
| 153 |
+
separate new-domain integration from catastrophic forgetting.
|
tinyvla2/REPORT.md
ADDED
|
@@ -0,0 +1,171 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
---
|
| 2 |
+
license: apache-2.0
|
| 3 |
+
base_model: Qwen/Qwen3.5-0.8B
|
| 4 |
+
tags:
|
| 5 |
+
- robotics
|
| 6 |
+
- vla
|
| 7 |
+
- lerobot
|
| 8 |
+
- libero
|
| 9 |
+
- dual-rate
|
| 10 |
+
pipeline_tag: robotics
|
| 11 |
+
---
|
| 12 |
+
|
| 13 |
+
# TinyVLA: a dual-rate VLA that beats OpenVLA-7B on LIBERO-Spatial at 0.64B params
|
| 14 |
+
|
| 15 |
+
**Headline result: 86% success on LIBERO-Spatial (n=100) in dual-rate mode (semantic latent
|
| 16 |
+
refreshed at 1 Hz), 79% full-rate — vs OpenVLA-7B's 84.7% — with 140M parameters on the
|
| 17 |
+
online control path.** Built and trained end-to-end in ~5 days on a single RTX A6000.
|
| 18 |
+
|
| 19 |
+
## 1. Architecture
|
| 20 |
+
|
| 21 |
+
```
|
| 22 |
+
SLOW / SMART path (0.5–2 Hz, cached)
|
| 23 |
+
instruction ─────────────────────┐
|
| 24 |
+
camera → Qwen3.5-0.8B vision tower → Qwen3.5 language stack (first 12 of 24 layers)
|
| 25 |
+
│ │
|
| 26 |
+
│ 8 readout tokens → linear → semantic latent (8×512)
|
| 27 |
+
│ │ cached between refreshes
|
| 28 |
+
──────────────────┼───────────────────────┼──────────────────────────
|
| 29 |
+
│ FAST / MOTOR path (10–20 Hz, ~140M online)
|
| 30 |
+
└── 64 spatial tokens per camera ─┐
|
| 31 |
+
proprio (padded 16d) ───────────────────────────────┤
|
| 32 |
+
embodiment-id embedding ────────────────────────────┤
|
| 33 |
+
▼
|
| 34 |
+
flow-matching action expert (38M, 12 blocks,
|
| 35 |
+
interleaved cross-/self-attention, AdaLN-free)
|
| 36 |
+
▼
|
| 37 |
+
50-step action chunk (padded 8d + validity mask)
|
| 38 |
+
```
|
| 39 |
+
|
| 40 |
+
- **Single shared encoder**: the Qwen3.5-0.8B native ViT (100.6M) feeds both paths.
|
| 41 |
+
- **Slow path**: image + instruction + 8 trailing pad-token "readout" slots through the
|
| 42 |
+
truncated language stack (L/2 layer-skip a la SmolVLA); their hidden states → latent 8×512.
|
| 43 |
+
- **Fast path**: raw vision-tower spatial tokens (bypassing the LM) + proprio + embodiment
|
| 44 |
+
token, cross-attended by the flow expert. 10 Euler steps at inference.
|
| 45 |
+
- **Flow matching**: linear-OT path, t ~ Beta(1.5, 1), velocity target, masked MSE.
|
| 46 |
+
- Totals: 643M stored / 39.5M–575M trainable depending on stage / ~140M online per tick.
|
| 47 |
+
- Implemented as an **out-of-tree LeRobot policy plugin**
|
| 48 |
+
(`--policy.type=tinyvla --policy.discover_packages_path=tinyvla`, lerobot 0.6.1).
|
| 49 |
+
|
| 50 |
+
## 2. Training recipe
|
| 51 |
+
|
| 52 |
+
| Stage | Data | Steps | Trainable | Result |
|
| 53 |
+
|---|---|---|---|---|
|
| 54 |
+
| 1. Overfit smoke | svla_so100_stacking (56 eps) | 5k | expert+proj (40M) | loss 1.885→0.099 |
|
| 55 |
+
| 2. Mixture pretrain | 40 SO100/101 community datasets (~10.7K eps, weight 0.65, per-dataset proportional) + Bridge V2 10K eps (0.35) | 40k, bs 64×2, lr 1e-4 | 39.5M (backbone frozen) | held-out RMSE@t0 0.30σ; **stale-latent 2s == fresh** |
|
| 56 |
+
| 2b. Staleness aug | same | from step 20k | — | latent from frame t−k, k~U(0,2s), p=0.5 |
|
| 57 |
+
| 3. Spatial distillation | + 132K teacher labels (Qwen3.5-4B, center-point → 32×32 grid), CE ×0.15 on cam0 tokens | 20k, lr 5e-5 | same + head | head top-1 20.8%, top-5 44.8% (random 0.1%) |
|
| 58 |
+
| 4. LIBERO FT (ft4) | HuggingFaceVLA/libero (1693 eps, all suites) | 40k, bs 48, lr 1e-4 / backbone 0.1× | **575M** (LM layers + vision unfrozen; vocab embeddings frozen) | loss 0.066 |
|
| 59 |
+
|
| 60 |
+
Ablation FTs: ft1 (all frozen) → 0% closed-loop; ft2 (vision unfrozen) → 60%;
|
| 61 |
+
ft3 (= ft2 from distilled ckpt) → 61%; **ft4 (LM+vision unfrozen) → 79/86%**.
|
| 62 |
+
Unfreezing the LM was the single largest gain; distillation was neutral on LIBERO
|
| 63 |
+
(likely overwritten by vision unfreezing during FT — bake it into pretraining next time).
|
| 64 |
+
|
| 65 |
+
Cross-embodiment handling: canonical schema (cam0=scene/cam1=wrist via regex mapping,
|
| 66 |
+
per-dataset mean/std normalization, action pad-to-8 + validity mask, state pad-to-16,
|
| 67 |
+
learned embodiment-id token). Weighted mixture sampler with per-source retry on corrupt
|
| 68 |
+
frames (IndexError/KeyError/decode RuntimeError).
|
| 69 |
+
|
| 70 |
+
## 3. Results
|
| 71 |
+
|
| 72 |
+
### LIBERO — all four suites (dual-rate, latent @ 1 Hz)
|
| 73 |
+
|
| 74 |
+
| Suite | TinyVLA | OpenVLA-7B (published) |
|
| 75 |
+
|---|---|---|
|
| 76 |
+
| Spatial | **86%** (n=100; full-rate 79%) | 84.7% |
|
| 77 |
+
| Object | **94%** (n=50) | 88.4% |
|
| 78 |
+
| Goal | **86%** (n=50) | 79.2% |
|
| 79 |
+
| Long (libero_10) | **70%** (n=50) | 53.7% |
|
| 80 |
+
| **Average** | **84.0%** | 76.5% |
|
| 81 |
+
|
| 82 |
+
Beats OpenVLA-7B on every suite at 1/11 the parameters and ~1/50 the online compute.
|
| 83 |
+
XS-VLA (90.3 avg) remains ahead — their latent flow matching is future work for us.
|
| 84 |
+
|
| 85 |
+
### LIBERO-Spatial (100 episodes, 10 per task, init states 0-9)
|
| 86 |
+
|
| 87 |
+
| Mode | Success |
|
| 88 |
+
|---|---|
|
| 89 |
+
| Full-rate (latent every chunk) | 79/100 = **79%** |
|
| 90 |
+
| **Dual-rate (latent @ 1 Hz)** | 86/100 = **86%** |
|
| 91 |
+
|
| 92 |
+
Dual-rate ≥ full-rate consistently across all evals (also 65% vs 58% at ft3, n=50) —
|
| 93 |
+
a stable cached latent appears to act as temporal regularization.
|
| 94 |
+
|
| 95 |
+
### Context (published numbers, their own eval protocols)
|
| 96 |
+
|
| 97 |
+
| Model | Params | LIBERO-Spatial | 4-suite avg |
|
| 98 |
+
|---|---|---|---|
|
| 99 |
+
| MolmoAct2-LIBERO | 5B | 98.4% (**97.2% re-measured on our rig**, n=500) | **98.25%** |
|
| 100 |
+
| π0 | 3.3B | 98% | — |
|
| 101 |
+
| SmolVLA-2.25B | 2.25B | 93% | — |
|
| 102 |
+
| XS-VLA | 0.26B | ~93% | 90.3% |
|
| 103 |
+
| MolmoAct-7B (v1) | 7B | 87.0% | 86.6% |
|
| 104 |
+
| **TinyVLA (this)** | **0.64B (140M online)** | **86% dual-rate** | **84.0%** |
|
| 105 |
+
| OpenVLA | 7B | 84.7% | 76.5% |
|
| 106 |
+
|
| 107 |
+
**MolmoAct2 context** (from their cards/repo, no numeric tables published outside the
|
| 108 |
+
LIBERO-LeRobot card): 5B params on Molmo2-ER backbone + flow expert; claims to beat π0.5;
|
| 109 |
+
Molmo2-ER reportedly surpasses GPT-5 / Gemini-Robotics-ER-1.5 on 13 embodied-reasoning
|
| 110 |
+
benchmarks; #1 VLA on the MolmoSpace leaderboard. Inference needs ~26GB fp32 (16GB bf16),
|
| 111 |
+
cuda-graphs for ~2× speedup — H100-class serving vs our Raspberry-Pi-class 140M fast path.
|
| 112 |
+
Notably they ship **MolmoAct2-SO100_101** (absolute joint control) — a 5B competitor on our
|
| 113 |
+
target embodiment; a head-to-head offline eval on SO101 held-out data is an obvious next test.
|
| 114 |
+
|
| 115 |
+
Honesty notes: our n=100 (±8pp) vs their 500; single suite; eval covers init states 0–9
|
| 116 |
+
per task (demos of same tasks/init states are in training data — this is the standard
|
| 117 |
+
LIBERO protocol used by all listed models). Multi-suite evals (object/goal/long) and an
|
| 118 |
+
identically-protocoled SmolVLA baseline run are in progress.
|
| 119 |
+
|
| 120 |
+
### Dual-rate validation (the architectural claim)
|
| 121 |
+
|
| 122 |
+
- Offline: held-out chunk MSE with latent from a frame 2s earlier == fresh (0.772 vs 0.772).
|
| 123 |
+
- Closed-loop: 86% @ 1 Hz refresh vs 79% full-rate.
|
| 124 |
+
- Deployment implication (Raspberry Pi 5): the 0.5B slow path can run at 0.5–1 Hz
|
| 125 |
+
(llama.cpp GGUF Q4 territory), only the 140M fast path needs real-time rates.
|
| 126 |
+
|
| 127 |
+
## 4. Pitfalls we hit (read before reproducing)
|
| 128 |
+
|
| 129 |
+
1. **robosuite/LIBERO renders are 180°-rotated** vs recorded datasets. A vertical flip
|
| 130 |
+
alone leaves a horizontal MIRROR — the policy reaches to the wrong side and scores 0%.
|
| 131 |
+
Use `img[::-1, ::-1]`. (lerobot's `LiberoEnv.render()` flips for visualization but
|
| 132 |
+
`_format_raw_obs` feeds policies raw rotated frames — check your eval path.)
|
| 133 |
+
2. **eef orientation antipodal ambiguity**: env quat → rotvec gives −π-ish x-component,
|
| 134 |
+
datasets store +π-ish. Canonicalize (flip antipodal representation when rotvec_x < 0)
|
| 135 |
+
or your normalized state input is off by ~17σ.
|
| 136 |
+
3. **HuggingFaceVLA/libero meta says fps=10 but frames are native 20 Hz** (~161
|
| 137 |
+
frames/episode ≈ 8s demos). Do NOT action-repeat at eval.
|
| 138 |
+
4. **GT-replay harness is the decisive convention test**: replay dataset actions in the env
|
| 139 |
+
(first episode per task ↔ init_state 0). 4/5 success = conventions right; policy-independent.
|
| 140 |
+
5. HuggingFaceVLA community_dataset v1/v3 are aggregates of v2.1 sub-datasets → convert with
|
| 141 |
+
lerobot's `convert_dataset_v21_to_v30.py`; 4/44 sources have meta≠parquet row counts
|
| 142 |
+
(broken at source) — validate `len(reader.hf_dataset) == meta.total_frames`.
|
| 143 |
+
6. Qwen3.5 custom forwards need `mm_token_type_ids` for M-RoPE; patchify must match the
|
| 144 |
+
official processor bit-exact (verify!). Linear-attention needs fla-core + causal-conv1d
|
| 145 |
+
or you get a 5× slower torch fallback.
|
| 146 |
+
7. Flow-matching loss can drop while conditioning is ignored — A/B with shuffled
|
| 147 |
+
observations to verify the model actually uses them.
|
| 148 |
+
|
| 149 |
+
## 5. Repository layout
|
| 150 |
+
|
| 151 |
+
```
|
| 152 |
+
src/tinyvla/ # LeRobot plugin: configuration/modeling/processor + modules
|
| 153 |
+
scripts/train.py # accelerate loop: weighted mixture, staleness aug, distill loss, resume
|
| 154 |
+
scripts/eval_libero.py # closed-loop LIBERO eval (all convention fixes, dual-rate, video)
|
| 155 |
+
scripts/replay_libero.py, diag_obs_gap.py # convention diagnostics
|
| 156 |
+
scripts/prepare_community_v3.py, label_spatial.py, eval_offline.py
|
| 157 |
+
configs/ # stage2/stage3/libero_ft* yaml
|
| 158 |
+
checkpoints/ # stage2_final, stage3_final, libero_ft4_final (main)
|
| 159 |
+
videos/ # sample eval episodes
|
| 160 |
+
```
|
| 161 |
+
|
| 162 |
+
## 6. Quick start
|
| 163 |
+
|
| 164 |
+
```python
|
| 165 |
+
from tinyvla.modeling_tinyvla import TinyVLAPolicy
|
| 166 |
+
policy = TinyVLAPolicy.from_pretrained("AlexWortega/tinyvla") # ft4 checkpoint at root
|
| 167 |
+
# closed-loop LIBERO: python scripts/eval_libero.py --checkpoint <ckpt> \
|
| 168 |
+
# --suite libero_spatial --episodes 100 --n-action-steps 10 --refresh-s 1.0
|
| 169 |
+
```
|
| 170 |
+
|
| 171 |
+
Trained 2026-08-14 → 2026-08-19 on 1× RTX A6000 (48GB), lerobot 0.6.1, torch 2.10, transformers 5.5.4.
|
tinyvla2/assets/so_arm/assets/base_motor_holder_so101_v1.stl
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:8cd2f241037ea377af1191fffe0dd9d9006beea6dcc48543660ed41647072424
|
| 3 |
+
size 1877084
|
tinyvla2/assets/so_arm/assets/base_so101_v2.stl
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:bb12b7026575e1f70ccc7240051f9d943553bf34e5128537de6cd86fae33924d
|
| 3 |
+
size 471584
|
tinyvla2/assets/so_arm/assets/motor_holder_so101_base_v1.stl
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:31242ae6fb59d8b15c66617b88ad8e9bded62d57c35d11c0c43a70d2f4caa95b
|
| 3 |
+
size 1129384
|
tinyvla2/assets/so_arm/assets/motor_holder_so101_wrist_v1.stl
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:887f92e6013cb64ea3a1ab8675e92da1e0beacfd5e001f972523540545e08011
|
| 3 |
+
size 1052184
|
tinyvla2/assets/so_arm/assets/moving_jaw_so101_v1.stl
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:785a9dded2f474bc1d869e0d3dae398a3dcd9c0c345640040472210d2861fa9d
|
| 3 |
+
size 1413584
|
tinyvla2/assets/so_arm/assets/rotation_pitch_so101_v1.stl
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:9be900cc2a2bf718102841ef82ef8d2873842427648092c8ed2ca1e2ef4ffa34
|
| 3 |
+
size 883684
|
tinyvla2/assets/so_arm/assets/sts3215_03a_no_horn_v1.stl
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:75ef3781b752e4065891aea855e34dc161a38a549549cd0970cedd07eae6f887
|
| 3 |
+
size 865884
|
tinyvla2/assets/so_arm/assets/sts3215_03a_v1.stl
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:a37c871fb502483ab96c256baf457d36f2e97afc9205313d9c5ab275ef941cd0
|
| 3 |
+
size 954084
|
tinyvla2/assets/so_arm/assets/under_arm_so101_v1.stl
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:d01d1f2de365651dcad9d6669e94ff87ff7652b5bb2d10752a66a456a86dbc71
|
| 3 |
+
size 1975884
|
tinyvla2/assets/so_arm/assets/upper_arm_so101_v1.stl
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:475056e03a17e71919b82fd88ab9a0b898ab50164f2a7943652a6b2941bb2d4f
|
| 3 |
+
size 1303484
|
tinyvla2/assets/so_arm/assets/waveshare_mounting_plate_so101_v2.stl
ADDED
|
Binary file (62.8 kB). View file
|
|
|
tinyvla2/assets/so_arm/assets/wrist_roll_follower_so101_v1.stl
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:4b17b410a12d64ec39554abc3e8054d8a97384b2dc4a8d95a5ecb2a93670f5f4
|
| 3 |
+
size 1439884
|
tinyvla2/assets/so_arm/assets/wrist_roll_pitch_so101_v2.stl
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:6c7ec5525b4d8b9e397a30ab4bb0037156a5d5f38a4adf2c7d943d6c56eda5ae
|
| 3 |
+
size 2699784
|
tinyvla2/assets/so_arm/so101_new_calib.urdf
ADDED
|
@@ -0,0 +1,453 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?xml version="1.0" encoding="utf-8"?>
|
| 2 |
+
<!-- Generated using onshape-to-robot -->
|
| 3 |
+
<!-- Onshape https://cad.onshape.com/documents/7715cc284bb430fe6dab4ffd/w/4fd0791b683777b02f8d975a/e/826c553ede3b7592eb9ca800 -->
|
| 4 |
+
<robot name="so101_new_calib">
|
| 5 |
+
|
| 6 |
+
<!-- Materials -->
|
| 7 |
+
<material name="3d_printed">
|
| 8 |
+
<color rgba="1.0 0.82 0.12 1.0"/>
|
| 9 |
+
</material>
|
| 10 |
+
<material name="sts3215">
|
| 11 |
+
<color rgba="0.1 0.1 0.1 1.0"/>
|
| 12 |
+
</material>
|
| 13 |
+
|
| 14 |
+
<!-- Link base -->
|
| 15 |
+
<link name="base_link">
|
| 16 |
+
<inertial>
|
| 17 |
+
<origin xyz="0.0137179 -5.19711e-05 0.0334843" rpy="0 0 0"/>
|
| 18 |
+
<mass value="0.147"/>
|
| 19 |
+
<inertia ixx="0.000114686" ixy="-4.59787e-07" ixz="4.97151e-06" iyy="0.000136117" iyz="9.75275e-08" izz="0.000130364"/>
|
| 20 |
+
</inertial>
|
| 21 |
+
<!-- Part base_motor_holder_so101_v1 -->
|
| 22 |
+
<visual>
|
| 23 |
+
<origin xyz="-0.00636471 -9.94414e-05 -0.0024" rpy="1.5708 -1.67685e-15 1.5708"/>
|
| 24 |
+
<geometry>
|
| 25 |
+
<mesh filename="assets/base_motor_holder_so101_v1.stl"/>
|
| 26 |
+
</geometry>
|
| 27 |
+
<material name="3d_printed"/>
|
| 28 |
+
</visual>
|
| 29 |
+
<collision>
|
| 30 |
+
<origin xyz="-0.00636471 -9.94414e-05 -0.0024" rpy="1.5708 -1.67685e-15 1.5708"/>
|
| 31 |
+
<geometry>
|
| 32 |
+
<mesh filename="assets/base_motor_holder_so101_v1.stl"/>
|
| 33 |
+
</geometry>
|
| 34 |
+
</collision>
|
| 35 |
+
<!-- Part base_so101_v2 -->
|
| 36 |
+
<visual>
|
| 37 |
+
<origin xyz="-0.00636471 -8.97657e-09 -0.0024" rpy="1.5708 -2.78073e-29 1.5708"/>
|
| 38 |
+
<geometry>
|
| 39 |
+
<mesh filename="assets/base_so101_v2.stl"/>
|
| 40 |
+
</geometry>
|
| 41 |
+
<material name="3d_printed"/>
|
| 42 |
+
</visual>
|
| 43 |
+
<collision>
|
| 44 |
+
<origin xyz="-0.00636471 -8.97657e-09 -0.0024" rpy="1.5708 -2.78073e-29 1.5708"/>
|
| 45 |
+
<geometry>
|
| 46 |
+
<mesh filename="assets/base_so101_v2.stl"/>
|
| 47 |
+
</geometry>
|
| 48 |
+
</collision>
|
| 49 |
+
<!-- Part sts3215_03a_v1 -->
|
| 50 |
+
<visual>
|
| 51 |
+
<origin xyz="0.0263353 -8.97657e-09 0.0437" rpy="-8.21148e-16 7.84513e-18 1.249e-15"/>
|
| 52 |
+
<geometry>
|
| 53 |
+
<mesh filename="assets/sts3215_03a_v1.stl"/>
|
| 54 |
+
</geometry>
|
| 55 |
+
<material name="sts3215"/>
|
| 56 |
+
</visual>
|
| 57 |
+
<collision>
|
| 58 |
+
<origin xyz="0.0263353 -8.97657e-09 0.0437" rpy="-8.21148e-16 7.84513e-18 1.249e-15"/>
|
| 59 |
+
<geometry>
|
| 60 |
+
<mesh filename="assets/sts3215_03a_v1.stl"/>
|
| 61 |
+
</geometry>
|
| 62 |
+
</collision>
|
| 63 |
+
<!-- Part waveshare_mounting_plate_so101_v2 -->
|
| 64 |
+
<visual>
|
| 65 |
+
<origin xyz="-0.0309827 -0.000199441 0.0474" rpy="1.5708 -1.35493e-14 1.5708"/>
|
| 66 |
+
<geometry>
|
| 67 |
+
<mesh filename="assets/waveshare_mounting_plate_so101_v2.stl"/>
|
| 68 |
+
</geometry>
|
| 69 |
+
<material name="3d_printed"/>
|
| 70 |
+
</visual>
|
| 71 |
+
<collision>
|
| 72 |
+
<origin xyz="-0.0309827 -0.000199441 0.0474" rpy="1.5708 -1.35493e-14 1.5708"/>
|
| 73 |
+
<geometry>
|
| 74 |
+
<mesh filename="assets/waveshare_mounting_plate_so101_v2.stl"/>
|
| 75 |
+
</geometry>
|
| 76 |
+
</collision>
|
| 77 |
+
</link>
|
| 78 |
+
|
| 79 |
+
<!-- Link shoulder -->
|
| 80 |
+
<link name="shoulder_link">
|
| 81 |
+
<inertial>
|
| 82 |
+
<origin xyz="-0.0307604 -1.66727e-05 -0.0252713" rpy="0 0 0"/>
|
| 83 |
+
<mass value="0.100006"/>
|
| 84 |
+
<inertia ixx="8.3759e-05" ixy="7.55525e-08" ixz="-1.16342e-06" iyy="8.10403e-05" iyz="1.54663e-07" izz="2.39783e-05"/>
|
| 85 |
+
</inertial>
|
| 86 |
+
<!-- Part sts3215_03a_v1_2 -->
|
| 87 |
+
<visual>
|
| 88 |
+
<origin xyz="-0.0303992 0.000422241 -0.0417" rpy="1.5708 1.5708 0"/>
|
| 89 |
+
<geometry>
|
| 90 |
+
<mesh filename="assets/sts3215_03a_v1.stl"/>
|
| 91 |
+
</geometry>
|
| 92 |
+
<material name="sts3215"/>
|
| 93 |
+
</visual>
|
| 94 |
+
<collision>
|
| 95 |
+
<origin xyz="-0.0303992 0.000422241 -0.0417" rpy="1.5708 1.5708 0"/>
|
| 96 |
+
<geometry>
|
| 97 |
+
<mesh filename="assets/sts3215_03a_v1.stl"/>
|
| 98 |
+
</geometry>
|
| 99 |
+
</collision>
|
| 100 |
+
<!-- Part motor_holder_so101_base_v1 -->
|
| 101 |
+
<visual>
|
| 102 |
+
<origin xyz="-0.0675992 -0.000177759 0.0158499" rpy="1.5708 -1.5708 0"/>
|
| 103 |
+
<geometry>
|
| 104 |
+
<mesh filename="assets/motor_holder_so101_base_v1.stl"/>
|
| 105 |
+
</geometry>
|
| 106 |
+
<material name="3d_printed"/>
|
| 107 |
+
</visual>
|
| 108 |
+
<collision>
|
| 109 |
+
<origin xyz="-0.0675992 -0.000177759 0.0158499" rpy="1.5708 -1.5708 0"/>
|
| 110 |
+
<geometry>
|
| 111 |
+
<mesh filename="assets/motor_holder_so101_base_v1.stl"/>
|
| 112 |
+
</geometry>
|
| 113 |
+
</collision>
|
| 114 |
+
<!-- Part rotation_pitch_so101_v1 -->
|
| 115 |
+
<visual>
|
| 116 |
+
<origin xyz="0.0122008 2.22413e-05 0.0464" rpy="-1.5708 2.35221e-33 0"/>
|
| 117 |
+
<geometry>
|
| 118 |
+
<mesh filename="assets/rotation_pitch_so101_v1.stl"/>
|
| 119 |
+
</geometry>
|
| 120 |
+
<material name="3d_printed"/>
|
| 121 |
+
</visual>
|
| 122 |
+
<collision>
|
| 123 |
+
<origin xyz="0.0122008 2.22413e-05 0.0464" rpy="-1.5708 2.35221e-33 0"/>
|
| 124 |
+
<geometry>
|
| 125 |
+
<mesh filename="assets/rotation_pitch_so101_v1.stl"/>
|
| 126 |
+
</geometry>
|
| 127 |
+
</collision>
|
| 128 |
+
</link>
|
| 129 |
+
|
| 130 |
+
<!-- Link upper_arm -->
|
| 131 |
+
<link name="upper_arm_link">
|
| 132 |
+
<inertial>
|
| 133 |
+
<origin xyz="-0.0898471 -0.00838224 0.0184089" rpy="0 0 0"/>
|
| 134 |
+
<mass value="0.103"/>
|
| 135 |
+
<inertia ixx="4.08002e-05" ixy="-1.97819e-05" ixz="-4.03016e-08" iyy="0.000147318" iyz="8.97326e-09" izz="0.000142487"/>
|
| 136 |
+
</inertial>
|
| 137 |
+
<!-- Part sts3215_03a_v1_3 -->
|
| 138 |
+
<visual>
|
| 139 |
+
<origin xyz="-0.11257 -0.0155 0.0187" rpy="-3.14159 -5.27356e-16 -1.5708"/>
|
| 140 |
+
<geometry>
|
| 141 |
+
<mesh filename="assets/sts3215_03a_v1.stl"/>
|
| 142 |
+
</geometry>
|
| 143 |
+
<material name="sts3215"/>
|
| 144 |
+
</visual>
|
| 145 |
+
<collision>
|
| 146 |
+
<origin xyz="-0.11257 -0.0155 0.0187" rpy="-3.14159 -5.27356e-16 -1.5708"/>
|
| 147 |
+
<geometry>
|
| 148 |
+
<mesh filename="assets/sts3215_03a_v1.stl"/>
|
| 149 |
+
</geometry>
|
| 150 |
+
</collision>
|
| 151 |
+
<!-- Part upper_arm_so101_v1 -->
|
| 152 |
+
<visual>
|
| 153 |
+
<origin xyz="-0.065085 0.012 0.0182" rpy="3.14159 -0 -1.30911e-30"/>
|
| 154 |
+
<geometry>
|
| 155 |
+
<mesh filename="assets/upper_arm_so101_v1.stl"/>
|
| 156 |
+
</geometry>
|
| 157 |
+
<material name="3d_printed"/>
|
| 158 |
+
</visual>
|
| 159 |
+
<collision>
|
| 160 |
+
<origin xyz="-0.065085 0.012 0.0182" rpy="3.14159 -0 -1.30911e-30"/>
|
| 161 |
+
<geometry>
|
| 162 |
+
<mesh filename="assets/upper_arm_so101_v1.stl"/>
|
| 163 |
+
</geometry>
|
| 164 |
+
</collision>
|
| 165 |
+
</link>
|
| 166 |
+
|
| 167 |
+
<!-- Link lower_arm -->
|
| 168 |
+
<link name="lower_arm_link">
|
| 169 |
+
<inertial>
|
| 170 |
+
<origin xyz="-0.0980701 0.00324376 0.0182831" rpy="0 0 0"/>
|
| 171 |
+
<mass value="0.104"/>
|
| 172 |
+
<inertia ixx="2.87438e-05" ixy="7.41152e-06" ixz="1.26409e-06" iyy="0.000159844" iyz="-4.90188e-08" izz="0.00014529"/>
|
| 173 |
+
</inertial>
|
| 174 |
+
<!-- Part under_arm_so101_v1 -->
|
| 175 |
+
<visual>
|
| 176 |
+
<origin xyz="-0.0648499 -0.032 0.0182" rpy="3.14159 -0 6.67202e-31"/>
|
| 177 |
+
<geometry>
|
| 178 |
+
<mesh filename="assets/under_arm_so101_v1.stl"/>
|
| 179 |
+
</geometry>
|
| 180 |
+
<material name="3d_printed"/>
|
| 181 |
+
</visual>
|
| 182 |
+
<collision>
|
| 183 |
+
<origin xyz="-0.0648499 -0.032 0.0182" rpy="3.14159 -0 6.67202e-31"/>
|
| 184 |
+
<geometry>
|
| 185 |
+
<mesh filename="assets/under_arm_so101_v1.stl"/>
|
| 186 |
+
</geometry>
|
| 187 |
+
</collision>
|
| 188 |
+
<!-- Part motor_holder_so101_wrist_v1 -->
|
| 189 |
+
<visual>
|
| 190 |
+
<origin xyz="-0.0648499 -0.032 0.018" rpy="-3.14159 -2.55351e-15 -1.83387e-30"/>
|
| 191 |
+
<geometry>
|
| 192 |
+
<mesh filename="assets/motor_holder_so101_wrist_v1.stl"/>
|
| 193 |
+
</geometry>
|
| 194 |
+
<material name="3d_printed"/>
|
| 195 |
+
</visual>
|
| 196 |
+
<collision>
|
| 197 |
+
<origin xyz="-0.0648499 -0.032 0.018" rpy="-3.14159 -2.55351e-15 -1.83387e-30"/>
|
| 198 |
+
<geometry>
|
| 199 |
+
<mesh filename="assets/motor_holder_so101_wrist_v1.stl"/>
|
| 200 |
+
</geometry>
|
| 201 |
+
</collision>
|
| 202 |
+
<!-- Part sts3215_03a_v1_4 -->
|
| 203 |
+
<visual>
|
| 204 |
+
<origin xyz="-0.1224 0.0052 0.0187" rpy="-3.14159 -7.88861e-31 -3.14159"/>
|
| 205 |
+
<geometry>
|
| 206 |
+
<mesh filename="assets/sts3215_03a_v1.stl"/>
|
| 207 |
+
</geometry>
|
| 208 |
+
<material name="sts3215"/>
|
| 209 |
+
</visual>
|
| 210 |
+
<collision>
|
| 211 |
+
<origin xyz="-0.1224 0.0052 0.0187" rpy="-3.14159 -7.88861e-31 -3.14159"/>
|
| 212 |
+
<geometry>
|
| 213 |
+
<mesh filename="assets/sts3215_03a_v1.stl"/>
|
| 214 |
+
</geometry>
|
| 215 |
+
</collision>
|
| 216 |
+
</link>
|
| 217 |
+
|
| 218 |
+
<!-- Link wrist -->
|
| 219 |
+
<link name="wrist_link">
|
| 220 |
+
<inertial>
|
| 221 |
+
<origin xyz="-0.000103312 -0.0386143 0.0281156" rpy="0 0 0"/>
|
| 222 |
+
<mass value="0.079"/>
|
| 223 |
+
<inertia ixx="3.68263e-05" ixy="1.7893e-08" ixz="-5.28128e-08" iyy="2.5391e-05" iyz="3.6412e-06" izz="2.1e-05"/>
|
| 224 |
+
</inertial>
|
| 225 |
+
<!-- Part sts3215_03a_no_horn_v1 -->
|
| 226 |
+
<visual>
|
| 227 |
+
<origin xyz="8.32667e-17 -0.0424 0.0306" rpy="1.5708 1.5708 0"/>
|
| 228 |
+
<geometry>
|
| 229 |
+
<mesh filename="assets/sts3215_03a_no_horn_v1.stl"/>
|
| 230 |
+
</geometry>
|
| 231 |
+
<material name="sts3215"/>
|
| 232 |
+
</visual>
|
| 233 |
+
<collision>
|
| 234 |
+
<origin xyz="8.32667e-17 -0.0424 0.0306" rpy="1.5708 1.5708 0"/>
|
| 235 |
+
<geometry>
|
| 236 |
+
<mesh filename="assets/sts3215_03a_no_horn_v1.stl"/>
|
| 237 |
+
</geometry>
|
| 238 |
+
</collision>
|
| 239 |
+
<!-- Part wrist_roll_pitch_so101_v2 -->
|
| 240 |
+
<visual>
|
| 241 |
+
<origin xyz="0 -0.028 0.0181" rpy="-1.5708 -1.5708 0"/>
|
| 242 |
+
<geometry>
|
| 243 |
+
<mesh filename="assets/wrist_roll_pitch_so101_v2.stl"/>
|
| 244 |
+
</geometry>
|
| 245 |
+
<material name="3d_printed"/>
|
| 246 |
+
</visual>
|
| 247 |
+
<collision>
|
| 248 |
+
<origin xyz="0 -0.028 0.0181" rpy="-1.5708 -1.5708 0"/>
|
| 249 |
+
<geometry>
|
| 250 |
+
<mesh filename="assets/wrist_roll_pitch_so101_v2.stl"/>
|
| 251 |
+
</geometry>
|
| 252 |
+
</collision>
|
| 253 |
+
</link>
|
| 254 |
+
|
| 255 |
+
<!-- Link gripper -->
|
| 256 |
+
<link name="gripper_link">
|
| 257 |
+
<inertial>
|
| 258 |
+
<origin xyz="0.000213627 0.000245138 -0.025187" rpy="0 0 0"/>
|
| 259 |
+
<mass value="0.087"/>
|
| 260 |
+
<inertia ixx="2.75087e-05" ixy="-3.35241e-07" ixz="-5.7352e-06" iyy="4.33657e-05" iyz="-5.17847e-08" izz="3.45059e-05"/>
|
| 261 |
+
</inertial>
|
| 262 |
+
<!-- Part sts3215_03a_v1_5 -->
|
| 263 |
+
<visual>
|
| 264 |
+
<origin xyz="0.0077 0.0001 -0.0234" rpy="-1.5708 -5.19179e-17 -1.66533e-16"/>
|
| 265 |
+
<geometry>
|
| 266 |
+
<mesh filename="assets/sts3215_03a_v1.stl"/>
|
| 267 |
+
</geometry>
|
| 268 |
+
<material name="sts3215"/>
|
| 269 |
+
</visual>
|
| 270 |
+
<collision>
|
| 271 |
+
<origin xyz="0.0077 0.0001 -0.0234" rpy="-1.5708 -5.19179e-17 -1.66533e-16"/>
|
| 272 |
+
<geometry>
|
| 273 |
+
<mesh filename="assets/sts3215_03a_v1.stl"/>
|
| 274 |
+
</geometry>
|
| 275 |
+
</collision>
|
| 276 |
+
<!-- Part wrist_roll_follower_so101_v1 -->
|
| 277 |
+
<visual>
|
| 278 |
+
<origin xyz="8.32667e-17 -0.000218214 0.000949706" rpy="-3.14159 -5.55112e-17 0"/>
|
| 279 |
+
<geometry>
|
| 280 |
+
<mesh filename="assets/wrist_roll_follower_so101_v1.stl"/>
|
| 281 |
+
</geometry>
|
| 282 |
+
<material name="3d_printed"/>
|
| 283 |
+
</visual>
|
| 284 |
+
<collision>
|
| 285 |
+
<origin xyz="8.32667e-17 -0.000218214 0.000949706" rpy="-3.14159 -5.55112e-17 0"/>
|
| 286 |
+
<geometry>
|
| 287 |
+
<mesh filename="assets/wrist_roll_follower_so101_v1.stl"/>
|
| 288 |
+
</geometry>
|
| 289 |
+
</collision>
|
| 290 |
+
</link>
|
| 291 |
+
|
| 292 |
+
<!-- Gripper frame (dummy link + fixed joint) -->
|
| 293 |
+
<link name="gripper_frame_link">
|
| 294 |
+
<origin xyz="0 0 0" rpy="0 -0 0"/>
|
| 295 |
+
<inertial>
|
| 296 |
+
<origin xyz="0 0 0" rpy="0 0 0"/>
|
| 297 |
+
<mass value="1e-9"/>
|
| 298 |
+
<inertia ixx="0" ixy="0" ixz="0" iyy="0" iyz="0" izz="0"/>
|
| 299 |
+
</inertial>
|
| 300 |
+
</link>
|
| 301 |
+
|
| 302 |
+
<joint name="gripper_frame_joint" type="fixed">
|
| 303 |
+
<origin xyz="-0.0079 -0.000218121 -0.0981274" rpy="0 3.14159 0"/>
|
| 304 |
+
<parent link="gripper_link"/>
|
| 305 |
+
<child link="gripper_frame_link"/>
|
| 306 |
+
<axis xyz="0 0 0"/>
|
| 307 |
+
</joint>
|
| 308 |
+
|
| 309 |
+
<!-- Link moving_jaw_so101_v1 -->
|
| 310 |
+
<link name="moving_jaw_so101_v1_link">
|
| 311 |
+
<inertial>
|
| 312 |
+
<origin xyz="-0.00157495 -0.0300244 0.0192755" rpy="0 0 0"/>
|
| 313 |
+
<mass value="0.012"/>
|
| 314 |
+
<inertia ixx="6.61427e-06" ixy="-3.19807e-07" ixz="-5.90717e-09" iyy="1.89032e-06" iyz="-1.09945e-07" izz="5.28738e-06"/>
|
| 315 |
+
</inertial>
|
| 316 |
+
<!-- Part moving_jaw_so101_v1 -->
|
| 317 |
+
<visual>
|
| 318 |
+
<origin xyz="-5.55112e-17 -5.55112e-17 0.0189" rpy="9.53145e-17 6.93889e-18 1.24077e-24"/>
|
| 319 |
+
<geometry>
|
| 320 |
+
<mesh filename="assets/moving_jaw_so101_v1.stl"/>
|
| 321 |
+
</geometry>
|
| 322 |
+
<material name="3d_printed"/>
|
| 323 |
+
</visual>
|
| 324 |
+
<collision>
|
| 325 |
+
<origin xyz="-5.55112e-17 -5.55112e-17 0.0189" rpy="9.53145e-17 6.93889e-18 1.24077e-24"/>
|
| 326 |
+
<geometry>
|
| 327 |
+
<mesh filename="assets/moving_jaw_so101_v1.stl"/>
|
| 328 |
+
</geometry>
|
| 329 |
+
</collision>
|
| 330 |
+
</link>
|
| 331 |
+
|
| 332 |
+
<!-- Joint from gripper to moving_jaw_so101_v1 -->
|
| 333 |
+
<joint name="gripper" type="revolute">
|
| 334 |
+
<origin xyz="0.0202 0.0188 -0.0234" rpy="1.5708 -5.24284e-08 -1.41553e-15"/>
|
| 335 |
+
<parent link="gripper_link"/>
|
| 336 |
+
<child link="moving_jaw_so101_v1_link"/>
|
| 337 |
+
<axis xyz="0 0 1"/>
|
| 338 |
+
<limit effort="10" velocity="10" lower="-0.174533" upper="1.74533"/>
|
| 339 |
+
</joint>
|
| 340 |
+
|
| 341 |
+
<transmission name="gripper_trans">
|
| 342 |
+
<type>transmission_interface/SimpleTransmission</type>
|
| 343 |
+
<joint name="gripper">
|
| 344 |
+
<hardwareInterface>hardware_interface/PositionJointInterface</hardwareInterface>
|
| 345 |
+
</joint>
|
| 346 |
+
<actuator name="motor6">
|
| 347 |
+
<hardwareInterface>hardware_interface/PositionJointInterface</hardwareInterface>
|
| 348 |
+
<mechanicalReduction>1</mechanicalReduction>
|
| 349 |
+
</actuator>
|
| 350 |
+
</transmission>
|
| 351 |
+
|
| 352 |
+
<!-- Joint from wrist to gripper -->
|
| 353 |
+
<joint name="wrist_roll" type="revolute">
|
| 354 |
+
<origin xyz="5.55112e-17 -0.0611 0.0181" rpy="1.5708 0.0486795 3.14159"/>
|
| 355 |
+
<parent link="wrist_link"/>
|
| 356 |
+
<child link="gripper_link"/>
|
| 357 |
+
<axis xyz="0 0 1"/>
|
| 358 |
+
<limit effort="10" velocity="10" lower="-2.74385" upper="2.84121"/>
|
| 359 |
+
</joint>
|
| 360 |
+
|
| 361 |
+
<transmission name="wrist_roll_trans">
|
| 362 |
+
<type>transmission_interface/SimpleTransmission</type>
|
| 363 |
+
<joint name="wrist_roll">
|
| 364 |
+
<hardwareInterface>hardware_interface/PositionJointInterface</hardwareInterface>
|
| 365 |
+
</joint>
|
| 366 |
+
<actuator name="motor5">
|
| 367 |
+
<hardwareInterface>hardware_interface/PositionJointInterface</hardwareInterface>
|
| 368 |
+
<mechanicalReduction>1</mechanicalReduction>
|
| 369 |
+
</actuator>
|
| 370 |
+
</transmission>
|
| 371 |
+
|
| 372 |
+
<!-- Joint from lower_arm to wrist -->
|
| 373 |
+
<joint name="wrist_flex" type="revolute">
|
| 374 |
+
<origin xyz="-0.1349 0.0052 3.62355e-17" rpy="4.02456e-15 8.67362e-16 -1.5708"/>
|
| 375 |
+
<parent link="lower_arm_link"/>
|
| 376 |
+
<child link="wrist_link"/>
|
| 377 |
+
<axis xyz="0 0 1"/>
|
| 378 |
+
<limit effort="10" velocity="10" lower="-1.65806" upper="1.65806"/>
|
| 379 |
+
</joint>
|
| 380 |
+
|
| 381 |
+
<transmission name="wrist_flex_trans">
|
| 382 |
+
<type>transmission_interface/SimpleTransmission</type>
|
| 383 |
+
<joint name="wrist_flex">
|
| 384 |
+
<hardwareInterface>hardware_interface/PositionJointInterface</hardwareInterface>
|
| 385 |
+
</joint>
|
| 386 |
+
<actuator name="motor4">
|
| 387 |
+
<hardwareInterface>hardware_interface/PositionJointInterface</hardwareInterface>
|
| 388 |
+
<mechanicalReduction>1</mechanicalReduction>
|
| 389 |
+
</actuator>
|
| 390 |
+
</transmission>
|
| 391 |
+
|
| 392 |
+
<!-- Joint from upper_arm to lower_arm -->
|
| 393 |
+
<!-- Note: 5-degree calibration offset applied to joint limits -->
|
| 394 |
+
<joint name="elbow_flex" type="revolute">
|
| 395 |
+
<origin xyz="-0.11257 -0.028 1.73763e-16" rpy="-3.63608e-16 8.74301e-16 1.5708"/>
|
| 396 |
+
<parent link="upper_arm_link"/>
|
| 397 |
+
<child link="lower_arm_link"/>
|
| 398 |
+
<axis xyz="0 0 1"/>
|
| 399 |
+
<limit effort="10" velocity="10" lower="-1.69" upper="1.69"/>
|
| 400 |
+
</joint>
|
| 401 |
+
|
| 402 |
+
<transmission name="elbow_flex_trans">
|
| 403 |
+
<type>transmission_interface/SimpleTransmission</type>
|
| 404 |
+
<joint name="elbow_flex">
|
| 405 |
+
<hardwareInterface>hardware_interface/PositionJointInterface</hardwareInterface>
|
| 406 |
+
</joint>
|
| 407 |
+
<actuator name="motor3">
|
| 408 |
+
<hardwareInterface>hardware_interface/PositionJointInterface</hardwareInterface>
|
| 409 |
+
<mechanicalReduction>1</mechanicalReduction>
|
| 410 |
+
</actuator>
|
| 411 |
+
</transmission>
|
| 412 |
+
|
| 413 |
+
<!-- Joint from shoulder to upper_arm -->
|
| 414 |
+
<joint name="shoulder_lift" type="revolute">
|
| 415 |
+
<origin xyz="-0.0303992 -0.0182778 -0.0542" rpy="-1.5708 -1.5708 0"/>
|
| 416 |
+
<parent link="shoulder_link"/>
|
| 417 |
+
<child link="upper_arm_link"/>
|
| 418 |
+
<axis xyz="0 0 1"/>
|
| 419 |
+
<limit effort="10" velocity="10" lower="-1.74533" upper="1.74533"/>
|
| 420 |
+
</joint>
|
| 421 |
+
|
| 422 |
+
<transmission name="shoulder_lift_trans">
|
| 423 |
+
<type>transmission_interface/SimpleTransmission</type>
|
| 424 |
+
<joint name="shoulder_lift">
|
| 425 |
+
<hardwareInterface>hardware_interface/PositionJointInterface</hardwareInterface>
|
| 426 |
+
</joint>
|
| 427 |
+
<actuator name="motor2">
|
| 428 |
+
<hardwareInterface>hardware_interface/PositionJointInterface</hardwareInterface>
|
| 429 |
+
<mechanicalReduction>1</mechanicalReduction>
|
| 430 |
+
</actuator>
|
| 431 |
+
</transmission>
|
| 432 |
+
|
| 433 |
+
<!-- Joint from base to shoulder -->
|
| 434 |
+
<joint name="shoulder_pan" type="revolute">
|
| 435 |
+
<origin xyz="0.0388353 -8.97657e-09 0.0624" rpy="3.14159 4.18253e-17 -3.14159"/>
|
| 436 |
+
<parent link="base_link"/>
|
| 437 |
+
<child link="shoulder_link"/>
|
| 438 |
+
<axis xyz="0 0 1"/>
|
| 439 |
+
<limit effort="10" velocity="10" lower="-1.91986" upper="1.91986"/>
|
| 440 |
+
</joint>
|
| 441 |
+
|
| 442 |
+
<transmission name="shoulder_pan_trans">
|
| 443 |
+
<type>transmission_interface/SimpleTransmission</type>
|
| 444 |
+
<joint name="shoulder_pan">
|
| 445 |
+
<hardwareInterface>hardware_interface/PositionJointInterface</hardwareInterface>
|
| 446 |
+
</joint>
|
| 447 |
+
<actuator name="motor1">
|
| 448 |
+
<hardwareInterface>hardware_interface/PositionJointInterface</hardwareInterface>
|
| 449 |
+
<mechanicalReduction>1</mechanicalReduction>
|
| 450 |
+
</actuator>
|
| 451 |
+
</transmission>
|
| 452 |
+
|
| 453 |
+
</robot>
|
tinyvla2/assets/so_arm/so101_nomesh.urdf
ADDED
|
@@ -0,0 +1,453 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?xml version="1.0" encoding="utf-8"?>
|
| 2 |
+
<!-- Generated using onshape-to-robot -->
|
| 3 |
+
<!-- Onshape https://cad.onshape.com/documents/7715cc284bb430fe6dab4ffd/w/4fd0791b683777b02f8d975a/e/826c553ede3b7592eb9ca800 -->
|
| 4 |
+
<robot name="so101_new_calib">
|
| 5 |
+
|
| 6 |
+
<!-- Materials -->
|
| 7 |
+
<material name="3d_printed">
|
| 8 |
+
<color rgba="1.0 0.82 0.12 1.0"/>
|
| 9 |
+
</material>
|
| 10 |
+
<material name="sts3215">
|
| 11 |
+
<color rgba="0.1 0.1 0.1 1.0"/>
|
| 12 |
+
</material>
|
| 13 |
+
|
| 14 |
+
<!-- Link base -->
|
| 15 |
+
<link name="base_link">
|
| 16 |
+
<inertial>
|
| 17 |
+
<origin xyz="0.0137179 -5.19711e-05 0.0334843" rpy="0 0 0"/>
|
| 18 |
+
<mass value="0.147"/>
|
| 19 |
+
<inertia ixx="0.000114686" ixy="-4.59787e-07" ixz="4.97151e-06" iyy="0.000136117" iyz="9.75275e-08" izz="0.000130364"/>
|
| 20 |
+
</inertial>
|
| 21 |
+
<!-- Part base_motor_holder_so101_v1 -->
|
| 22 |
+
<visual>
|
| 23 |
+
<origin xyz="-0.00636471 -9.94414e-05 -0.0024" rpy="1.5708 -1.67685e-15 1.5708"/>
|
| 24 |
+
<geometry>
|
| 25 |
+
<mesh filename=""/>
|
| 26 |
+
</geometry>
|
| 27 |
+
<material name="3d_printed"/>
|
| 28 |
+
</visual>
|
| 29 |
+
<collision>
|
| 30 |
+
<origin xyz="-0.00636471 -9.94414e-05 -0.0024" rpy="1.5708 -1.67685e-15 1.5708"/>
|
| 31 |
+
<geometry>
|
| 32 |
+
<mesh filename=""/>
|
| 33 |
+
</geometry>
|
| 34 |
+
</collision>
|
| 35 |
+
<!-- Part base_so101_v2 -->
|
| 36 |
+
<visual>
|
| 37 |
+
<origin xyz="-0.00636471 -8.97657e-09 -0.0024" rpy="1.5708 -2.78073e-29 1.5708"/>
|
| 38 |
+
<geometry>
|
| 39 |
+
<mesh filename=""/>
|
| 40 |
+
</geometry>
|
| 41 |
+
<material name="3d_printed"/>
|
| 42 |
+
</visual>
|
| 43 |
+
<collision>
|
| 44 |
+
<origin xyz="-0.00636471 -8.97657e-09 -0.0024" rpy="1.5708 -2.78073e-29 1.5708"/>
|
| 45 |
+
<geometry>
|
| 46 |
+
<mesh filename=""/>
|
| 47 |
+
</geometry>
|
| 48 |
+
</collision>
|
| 49 |
+
<!-- Part sts3215_03a_v1 -->
|
| 50 |
+
<visual>
|
| 51 |
+
<origin xyz="0.0263353 -8.97657e-09 0.0437" rpy="-8.21148e-16 7.84513e-18 1.249e-15"/>
|
| 52 |
+
<geometry>
|
| 53 |
+
<mesh filename=""/>
|
| 54 |
+
</geometry>
|
| 55 |
+
<material name="sts3215"/>
|
| 56 |
+
</visual>
|
| 57 |
+
<collision>
|
| 58 |
+
<origin xyz="0.0263353 -8.97657e-09 0.0437" rpy="-8.21148e-16 7.84513e-18 1.249e-15"/>
|
| 59 |
+
<geometry>
|
| 60 |
+
<mesh filename=""/>
|
| 61 |
+
</geometry>
|
| 62 |
+
</collision>
|
| 63 |
+
<!-- Part waveshare_mounting_plate_so101_v2 -->
|
| 64 |
+
<visual>
|
| 65 |
+
<origin xyz="-0.0309827 -0.000199441 0.0474" rpy="1.5708 -1.35493e-14 1.5708"/>
|
| 66 |
+
<geometry>
|
| 67 |
+
<mesh filename=""/>
|
| 68 |
+
</geometry>
|
| 69 |
+
<material name="3d_printed"/>
|
| 70 |
+
</visual>
|
| 71 |
+
<collision>
|
| 72 |
+
<origin xyz="-0.0309827 -0.000199441 0.0474" rpy="1.5708 -1.35493e-14 1.5708"/>
|
| 73 |
+
<geometry>
|
| 74 |
+
<mesh filename=""/>
|
| 75 |
+
</geometry>
|
| 76 |
+
</collision>
|
| 77 |
+
</link>
|
| 78 |
+
|
| 79 |
+
<!-- Link shoulder -->
|
| 80 |
+
<link name="shoulder_link">
|
| 81 |
+
<inertial>
|
| 82 |
+
<origin xyz="-0.0307604 -1.66727e-05 -0.0252713" rpy="0 0 0"/>
|
| 83 |
+
<mass value="0.100006"/>
|
| 84 |
+
<inertia ixx="8.3759e-05" ixy="7.55525e-08" ixz="-1.16342e-06" iyy="8.10403e-05" iyz="1.54663e-07" izz="2.39783e-05"/>
|
| 85 |
+
</inertial>
|
| 86 |
+
<!-- Part sts3215_03a_v1_2 -->
|
| 87 |
+
<visual>
|
| 88 |
+
<origin xyz="-0.0303992 0.000422241 -0.0417" rpy="1.5708 1.5708 0"/>
|
| 89 |
+
<geometry>
|
| 90 |
+
<mesh filename=""/>
|
| 91 |
+
</geometry>
|
| 92 |
+
<material name="sts3215"/>
|
| 93 |
+
</visual>
|
| 94 |
+
<collision>
|
| 95 |
+
<origin xyz="-0.0303992 0.000422241 -0.0417" rpy="1.5708 1.5708 0"/>
|
| 96 |
+
<geometry>
|
| 97 |
+
<mesh filename=""/>
|
| 98 |
+
</geometry>
|
| 99 |
+
</collision>
|
| 100 |
+
<!-- Part motor_holder_so101_base_v1 -->
|
| 101 |
+
<visual>
|
| 102 |
+
<origin xyz="-0.0675992 -0.000177759 0.0158499" rpy="1.5708 -1.5708 0"/>
|
| 103 |
+
<geometry>
|
| 104 |
+
<mesh filename=""/>
|
| 105 |
+
</geometry>
|
| 106 |
+
<material name="3d_printed"/>
|
| 107 |
+
</visual>
|
| 108 |
+
<collision>
|
| 109 |
+
<origin xyz="-0.0675992 -0.000177759 0.0158499" rpy="1.5708 -1.5708 0"/>
|
| 110 |
+
<geometry>
|
| 111 |
+
<mesh filename=""/>
|
| 112 |
+
</geometry>
|
| 113 |
+
</collision>
|
| 114 |
+
<!-- Part rotation_pitch_so101_v1 -->
|
| 115 |
+
<visual>
|
| 116 |
+
<origin xyz="0.0122008 2.22413e-05 0.0464" rpy="-1.5708 2.35221e-33 0"/>
|
| 117 |
+
<geometry>
|
| 118 |
+
<mesh filename=""/>
|
| 119 |
+
</geometry>
|
| 120 |
+
<material name="3d_printed"/>
|
| 121 |
+
</visual>
|
| 122 |
+
<collision>
|
| 123 |
+
<origin xyz="0.0122008 2.22413e-05 0.0464" rpy="-1.5708 2.35221e-33 0"/>
|
| 124 |
+
<geometry>
|
| 125 |
+
<mesh filename=""/>
|
| 126 |
+
</geometry>
|
| 127 |
+
</collision>
|
| 128 |
+
</link>
|
| 129 |
+
|
| 130 |
+
<!-- Link upper_arm -->
|
| 131 |
+
<link name="upper_arm_link">
|
| 132 |
+
<inertial>
|
| 133 |
+
<origin xyz="-0.0898471 -0.00838224 0.0184089" rpy="0 0 0"/>
|
| 134 |
+
<mass value="0.103"/>
|
| 135 |
+
<inertia ixx="4.08002e-05" ixy="-1.97819e-05" ixz="-4.03016e-08" iyy="0.000147318" iyz="8.97326e-09" izz="0.000142487"/>
|
| 136 |
+
</inertial>
|
| 137 |
+
<!-- Part sts3215_03a_v1_3 -->
|
| 138 |
+
<visual>
|
| 139 |
+
<origin xyz="-0.11257 -0.0155 0.0187" rpy="-3.14159 -5.27356e-16 -1.5708"/>
|
| 140 |
+
<geometry>
|
| 141 |
+
<mesh filename=""/>
|
| 142 |
+
</geometry>
|
| 143 |
+
<material name="sts3215"/>
|
| 144 |
+
</visual>
|
| 145 |
+
<collision>
|
| 146 |
+
<origin xyz="-0.11257 -0.0155 0.0187" rpy="-3.14159 -5.27356e-16 -1.5708"/>
|
| 147 |
+
<geometry>
|
| 148 |
+
<mesh filename=""/>
|
| 149 |
+
</geometry>
|
| 150 |
+
</collision>
|
| 151 |
+
<!-- Part upper_arm_so101_v1 -->
|
| 152 |
+
<visual>
|
| 153 |
+
<origin xyz="-0.065085 0.012 0.0182" rpy="3.14159 -0 -1.30911e-30"/>
|
| 154 |
+
<geometry>
|
| 155 |
+
<mesh filename=""/>
|
| 156 |
+
</geometry>
|
| 157 |
+
<material name="3d_printed"/>
|
| 158 |
+
</visual>
|
| 159 |
+
<collision>
|
| 160 |
+
<origin xyz="-0.065085 0.012 0.0182" rpy="3.14159 -0 -1.30911e-30"/>
|
| 161 |
+
<geometry>
|
| 162 |
+
<mesh filename=""/>
|
| 163 |
+
</geometry>
|
| 164 |
+
</collision>
|
| 165 |
+
</link>
|
| 166 |
+
|
| 167 |
+
<!-- Link lower_arm -->
|
| 168 |
+
<link name="lower_arm_link">
|
| 169 |
+
<inertial>
|
| 170 |
+
<origin xyz="-0.0980701 0.00324376 0.0182831" rpy="0 0 0"/>
|
| 171 |
+
<mass value="0.104"/>
|
| 172 |
+
<inertia ixx="2.87438e-05" ixy="7.41152e-06" ixz="1.26409e-06" iyy="0.000159844" iyz="-4.90188e-08" izz="0.00014529"/>
|
| 173 |
+
</inertial>
|
| 174 |
+
<!-- Part under_arm_so101_v1 -->
|
| 175 |
+
<visual>
|
| 176 |
+
<origin xyz="-0.0648499 -0.032 0.0182" rpy="3.14159 -0 6.67202e-31"/>
|
| 177 |
+
<geometry>
|
| 178 |
+
<mesh filename=""/>
|
| 179 |
+
</geometry>
|
| 180 |
+
<material name="3d_printed"/>
|
| 181 |
+
</visual>
|
| 182 |
+
<collision>
|
| 183 |
+
<origin xyz="-0.0648499 -0.032 0.0182" rpy="3.14159 -0 6.67202e-31"/>
|
| 184 |
+
<geometry>
|
| 185 |
+
<mesh filename=""/>
|
| 186 |
+
</geometry>
|
| 187 |
+
</collision>
|
| 188 |
+
<!-- Part motor_holder_so101_wrist_v1 -->
|
| 189 |
+
<visual>
|
| 190 |
+
<origin xyz="-0.0648499 -0.032 0.018" rpy="-3.14159 -2.55351e-15 -1.83387e-30"/>
|
| 191 |
+
<geometry>
|
| 192 |
+
<mesh filename=""/>
|
| 193 |
+
</geometry>
|
| 194 |
+
<material name="3d_printed"/>
|
| 195 |
+
</visual>
|
| 196 |
+
<collision>
|
| 197 |
+
<origin xyz="-0.0648499 -0.032 0.018" rpy="-3.14159 -2.55351e-15 -1.83387e-30"/>
|
| 198 |
+
<geometry>
|
| 199 |
+
<mesh filename=""/>
|
| 200 |
+
</geometry>
|
| 201 |
+
</collision>
|
| 202 |
+
<!-- Part sts3215_03a_v1_4 -->
|
| 203 |
+
<visual>
|
| 204 |
+
<origin xyz="-0.1224 0.0052 0.0187" rpy="-3.14159 -7.88861e-31 -3.14159"/>
|
| 205 |
+
<geometry>
|
| 206 |
+
<mesh filename=""/>
|
| 207 |
+
</geometry>
|
| 208 |
+
<material name="sts3215"/>
|
| 209 |
+
</visual>
|
| 210 |
+
<collision>
|
| 211 |
+
<origin xyz="-0.1224 0.0052 0.0187" rpy="-3.14159 -7.88861e-31 -3.14159"/>
|
| 212 |
+
<geometry>
|
| 213 |
+
<mesh filename=""/>
|
| 214 |
+
</geometry>
|
| 215 |
+
</collision>
|
| 216 |
+
</link>
|
| 217 |
+
|
| 218 |
+
<!-- Link wrist -->
|
| 219 |
+
<link name="wrist_link">
|
| 220 |
+
<inertial>
|
| 221 |
+
<origin xyz="-0.000103312 -0.0386143 0.0281156" rpy="0 0 0"/>
|
| 222 |
+
<mass value="0.079"/>
|
| 223 |
+
<inertia ixx="3.68263e-05" ixy="1.7893e-08" ixz="-5.28128e-08" iyy="2.5391e-05" iyz="3.6412e-06" izz="2.1e-05"/>
|
| 224 |
+
</inertial>
|
| 225 |
+
<!-- Part sts3215_03a_no_horn_v1 -->
|
| 226 |
+
<visual>
|
| 227 |
+
<origin xyz="8.32667e-17 -0.0424 0.0306" rpy="1.5708 1.5708 0"/>
|
| 228 |
+
<geometry>
|
| 229 |
+
<mesh filename=""/>
|
| 230 |
+
</geometry>
|
| 231 |
+
<material name="sts3215"/>
|
| 232 |
+
</visual>
|
| 233 |
+
<collision>
|
| 234 |
+
<origin xyz="8.32667e-17 -0.0424 0.0306" rpy="1.5708 1.5708 0"/>
|
| 235 |
+
<geometry>
|
| 236 |
+
<mesh filename=""/>
|
| 237 |
+
</geometry>
|
| 238 |
+
</collision>
|
| 239 |
+
<!-- Part wrist_roll_pitch_so101_v2 -->
|
| 240 |
+
<visual>
|
| 241 |
+
<origin xyz="0 -0.028 0.0181" rpy="-1.5708 -1.5708 0"/>
|
| 242 |
+
<geometry>
|
| 243 |
+
<mesh filename=""/>
|
| 244 |
+
</geometry>
|
| 245 |
+
<material name="3d_printed"/>
|
| 246 |
+
</visual>
|
| 247 |
+
<collision>
|
| 248 |
+
<origin xyz="0 -0.028 0.0181" rpy="-1.5708 -1.5708 0"/>
|
| 249 |
+
<geometry>
|
| 250 |
+
<mesh filename=""/>
|
| 251 |
+
</geometry>
|
| 252 |
+
</collision>
|
| 253 |
+
</link>
|
| 254 |
+
|
| 255 |
+
<!-- Link gripper -->
|
| 256 |
+
<link name="gripper_link">
|
| 257 |
+
<inertial>
|
| 258 |
+
<origin xyz="0.000213627 0.000245138 -0.025187" rpy="0 0 0"/>
|
| 259 |
+
<mass value="0.087"/>
|
| 260 |
+
<inertia ixx="2.75087e-05" ixy="-3.35241e-07" ixz="-5.7352e-06" iyy="4.33657e-05" iyz="-5.17847e-08" izz="3.45059e-05"/>
|
| 261 |
+
</inertial>
|
| 262 |
+
<!-- Part sts3215_03a_v1_5 -->
|
| 263 |
+
<visual>
|
| 264 |
+
<origin xyz="0.0077 0.0001 -0.0234" rpy="-1.5708 -5.19179e-17 -1.66533e-16"/>
|
| 265 |
+
<geometry>
|
| 266 |
+
<mesh filename=""/>
|
| 267 |
+
</geometry>
|
| 268 |
+
<material name="sts3215"/>
|
| 269 |
+
</visual>
|
| 270 |
+
<collision>
|
| 271 |
+
<origin xyz="0.0077 0.0001 -0.0234" rpy="-1.5708 -5.19179e-17 -1.66533e-16"/>
|
| 272 |
+
<geometry>
|
| 273 |
+
<mesh filename=""/>
|
| 274 |
+
</geometry>
|
| 275 |
+
</collision>
|
| 276 |
+
<!-- Part wrist_roll_follower_so101_v1 -->
|
| 277 |
+
<visual>
|
| 278 |
+
<origin xyz="8.32667e-17 -0.000218214 0.000949706" rpy="-3.14159 -5.55112e-17 0"/>
|
| 279 |
+
<geometry>
|
| 280 |
+
<mesh filename=""/>
|
| 281 |
+
</geometry>
|
| 282 |
+
<material name="3d_printed"/>
|
| 283 |
+
</visual>
|
| 284 |
+
<collision>
|
| 285 |
+
<origin xyz="8.32667e-17 -0.000218214 0.000949706" rpy="-3.14159 -5.55112e-17 0"/>
|
| 286 |
+
<geometry>
|
| 287 |
+
<mesh filename=""/>
|
| 288 |
+
</geometry>
|
| 289 |
+
</collision>
|
| 290 |
+
</link>
|
| 291 |
+
|
| 292 |
+
<!-- Gripper frame (dummy link + fixed joint) -->
|
| 293 |
+
<link name="gripper_frame_link">
|
| 294 |
+
<origin xyz="0 0 0" rpy="0 -0 0"/>
|
| 295 |
+
<inertial>
|
| 296 |
+
<origin xyz="0 0 0" rpy="0 0 0"/>
|
| 297 |
+
<mass value="1e-9"/>
|
| 298 |
+
<inertia ixx="0" ixy="0" ixz="0" iyy="0" iyz="0" izz="0"/>
|
| 299 |
+
</inertial>
|
| 300 |
+
</link>
|
| 301 |
+
|
| 302 |
+
<joint name="gripper_frame_joint" type="fixed">
|
| 303 |
+
<origin xyz="-0.0079 -0.000218121 -0.0981274" rpy="0 3.14159 0"/>
|
| 304 |
+
<parent link="gripper_link"/>
|
| 305 |
+
<child link="gripper_frame_link"/>
|
| 306 |
+
<axis xyz="0 0 0"/>
|
| 307 |
+
</joint>
|
| 308 |
+
|
| 309 |
+
<!-- Link moving_jaw_so101_v1 -->
|
| 310 |
+
<link name="moving_jaw_so101_v1_link">
|
| 311 |
+
<inertial>
|
| 312 |
+
<origin xyz="-0.00157495 -0.0300244 0.0192755" rpy="0 0 0"/>
|
| 313 |
+
<mass value="0.012"/>
|
| 314 |
+
<inertia ixx="6.61427e-06" ixy="-3.19807e-07" ixz="-5.90717e-09" iyy="1.89032e-06" iyz="-1.09945e-07" izz="5.28738e-06"/>
|
| 315 |
+
</inertial>
|
| 316 |
+
<!-- Part moving_jaw_so101_v1 -->
|
| 317 |
+
<visual>
|
| 318 |
+
<origin xyz="-5.55112e-17 -5.55112e-17 0.0189" rpy="9.53145e-17 6.93889e-18 1.24077e-24"/>
|
| 319 |
+
<geometry>
|
| 320 |
+
<mesh filename=""/>
|
| 321 |
+
</geometry>
|
| 322 |
+
<material name="3d_printed"/>
|
| 323 |
+
</visual>
|
| 324 |
+
<collision>
|
| 325 |
+
<origin xyz="-5.55112e-17 -5.55112e-17 0.0189" rpy="9.53145e-17 6.93889e-18 1.24077e-24"/>
|
| 326 |
+
<geometry>
|
| 327 |
+
<mesh filename=""/>
|
| 328 |
+
</geometry>
|
| 329 |
+
</collision>
|
| 330 |
+
</link>
|
| 331 |
+
|
| 332 |
+
<!-- Joint from gripper to moving_jaw_so101_v1 -->
|
| 333 |
+
<joint name="gripper" type="revolute">
|
| 334 |
+
<origin xyz="0.0202 0.0188 -0.0234" rpy="1.5708 -5.24284e-08 -1.41553e-15"/>
|
| 335 |
+
<parent link="gripper_link"/>
|
| 336 |
+
<child link="moving_jaw_so101_v1_link"/>
|
| 337 |
+
<axis xyz="0 0 1"/>
|
| 338 |
+
<limit effort="10" velocity="10" lower="-0.174533" upper="1.74533"/>
|
| 339 |
+
</joint>
|
| 340 |
+
|
| 341 |
+
<transmission name="gripper_trans">
|
| 342 |
+
<type>transmission_interface/SimpleTransmission</type>
|
| 343 |
+
<joint name="gripper">
|
| 344 |
+
<hardwareInterface>hardware_interface/PositionJointInterface</hardwareInterface>
|
| 345 |
+
</joint>
|
| 346 |
+
<actuator name="motor6">
|
| 347 |
+
<hardwareInterface>hardware_interface/PositionJointInterface</hardwareInterface>
|
| 348 |
+
<mechanicalReduction>1</mechanicalReduction>
|
| 349 |
+
</actuator>
|
| 350 |
+
</transmission>
|
| 351 |
+
|
| 352 |
+
<!-- Joint from wrist to gripper -->
|
| 353 |
+
<joint name="wrist_roll" type="revolute">
|
| 354 |
+
<origin xyz="5.55112e-17 -0.0611 0.0181" rpy="1.5708 0.0486795 3.14159"/>
|
| 355 |
+
<parent link="wrist_link"/>
|
| 356 |
+
<child link="gripper_link"/>
|
| 357 |
+
<axis xyz="0 0 1"/>
|
| 358 |
+
<limit effort="10" velocity="10" lower="-2.74385" upper="2.84121"/>
|
| 359 |
+
</joint>
|
| 360 |
+
|
| 361 |
+
<transmission name="wrist_roll_trans">
|
| 362 |
+
<type>transmission_interface/SimpleTransmission</type>
|
| 363 |
+
<joint name="wrist_roll">
|
| 364 |
+
<hardwareInterface>hardware_interface/PositionJointInterface</hardwareInterface>
|
| 365 |
+
</joint>
|
| 366 |
+
<actuator name="motor5">
|
| 367 |
+
<hardwareInterface>hardware_interface/PositionJointInterface</hardwareInterface>
|
| 368 |
+
<mechanicalReduction>1</mechanicalReduction>
|
| 369 |
+
</actuator>
|
| 370 |
+
</transmission>
|
| 371 |
+
|
| 372 |
+
<!-- Joint from lower_arm to wrist -->
|
| 373 |
+
<joint name="wrist_flex" type="revolute">
|
| 374 |
+
<origin xyz="-0.1349 0.0052 3.62355e-17" rpy="4.02456e-15 8.67362e-16 -1.5708"/>
|
| 375 |
+
<parent link="lower_arm_link"/>
|
| 376 |
+
<child link="wrist_link"/>
|
| 377 |
+
<axis xyz="0 0 1"/>
|
| 378 |
+
<limit effort="10" velocity="10" lower="-1.65806" upper="1.65806"/>
|
| 379 |
+
</joint>
|
| 380 |
+
|
| 381 |
+
<transmission name="wrist_flex_trans">
|
| 382 |
+
<type>transmission_interface/SimpleTransmission</type>
|
| 383 |
+
<joint name="wrist_flex">
|
| 384 |
+
<hardwareInterface>hardware_interface/PositionJointInterface</hardwareInterface>
|
| 385 |
+
</joint>
|
| 386 |
+
<actuator name="motor4">
|
| 387 |
+
<hardwareInterface>hardware_interface/PositionJointInterface</hardwareInterface>
|
| 388 |
+
<mechanicalReduction>1</mechanicalReduction>
|
| 389 |
+
</actuator>
|
| 390 |
+
</transmission>
|
| 391 |
+
|
| 392 |
+
<!-- Joint from upper_arm to lower_arm -->
|
| 393 |
+
<!-- Note: 5-degree calibration offset applied to joint limits -->
|
| 394 |
+
<joint name="elbow_flex" type="revolute">
|
| 395 |
+
<origin xyz="-0.11257 -0.028 1.73763e-16" rpy="-3.63608e-16 8.74301e-16 1.5708"/>
|
| 396 |
+
<parent link="upper_arm_link"/>
|
| 397 |
+
<child link="lower_arm_link"/>
|
| 398 |
+
<axis xyz="0 0 1"/>
|
| 399 |
+
<limit effort="10" velocity="10" lower="-1.69" upper="1.69"/>
|
| 400 |
+
</joint>
|
| 401 |
+
|
| 402 |
+
<transmission name="elbow_flex_trans">
|
| 403 |
+
<type>transmission_interface/SimpleTransmission</type>
|
| 404 |
+
<joint name="elbow_flex">
|
| 405 |
+
<hardwareInterface>hardware_interface/PositionJointInterface</hardwareInterface>
|
| 406 |
+
</joint>
|
| 407 |
+
<actuator name="motor3">
|
| 408 |
+
<hardwareInterface>hardware_interface/PositionJointInterface</hardwareInterface>
|
| 409 |
+
<mechanicalReduction>1</mechanicalReduction>
|
| 410 |
+
</actuator>
|
| 411 |
+
</transmission>
|
| 412 |
+
|
| 413 |
+
<!-- Joint from shoulder to upper_arm -->
|
| 414 |
+
<joint name="shoulder_lift" type="revolute">
|
| 415 |
+
<origin xyz="-0.0303992 -0.0182778 -0.0542" rpy="-1.5708 -1.5708 0"/>
|
| 416 |
+
<parent link="shoulder_link"/>
|
| 417 |
+
<child link="upper_arm_link"/>
|
| 418 |
+
<axis xyz="0 0 1"/>
|
| 419 |
+
<limit effort="10" velocity="10" lower="-1.74533" upper="1.74533"/>
|
| 420 |
+
</joint>
|
| 421 |
+
|
| 422 |
+
<transmission name="shoulder_lift_trans">
|
| 423 |
+
<type>transmission_interface/SimpleTransmission</type>
|
| 424 |
+
<joint name="shoulder_lift">
|
| 425 |
+
<hardwareInterface>hardware_interface/PositionJointInterface</hardwareInterface>
|
| 426 |
+
</joint>
|
| 427 |
+
<actuator name="motor2">
|
| 428 |
+
<hardwareInterface>hardware_interface/PositionJointInterface</hardwareInterface>
|
| 429 |
+
<mechanicalReduction>1</mechanicalReduction>
|
| 430 |
+
</actuator>
|
| 431 |
+
</transmission>
|
| 432 |
+
|
| 433 |
+
<!-- Joint from base to shoulder -->
|
| 434 |
+
<joint name="shoulder_pan" type="revolute">
|
| 435 |
+
<origin xyz="0.0388353 -8.97657e-09 0.0624" rpy="3.14159 4.18253e-17 -3.14159"/>
|
| 436 |
+
<parent link="base_link"/>
|
| 437 |
+
<child link="shoulder_link"/>
|
| 438 |
+
<axis xyz="0 0 1"/>
|
| 439 |
+
<limit effort="10" velocity="10" lower="-1.91986" upper="1.91986"/>
|
| 440 |
+
</joint>
|
| 441 |
+
|
| 442 |
+
<transmission name="shoulder_pan_trans">
|
| 443 |
+
<type>transmission_interface/SimpleTransmission</type>
|
| 444 |
+
<joint name="shoulder_pan">
|
| 445 |
+
<hardwareInterface>hardware_interface/PositionJointInterface</hardwareInterface>
|
| 446 |
+
</joint>
|
| 447 |
+
<actuator name="motor1">
|
| 448 |
+
<hardwareInterface>hardware_interface/PositionJointInterface</hardwareInterface>
|
| 449 |
+
<mechanicalReduction>1</mechanicalReduction>
|
| 450 |
+
</actuator>
|
| 451 |
+
</transmission>
|
| 452 |
+
|
| 453 |
+
</robot>
|
tinyvla2/configs/ablation_nolatent.yaml
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Stage-2 gate baseline: same mixture, 5k steps, nolatent ablation
|
| 2 |
+
output_dir: /home/alexw/tinyvla/outputs/ablation_nolatent
|
| 3 |
+
wandb: null
|
| 4 |
+
datasets:
|
| 5 |
+
- root_glob: /home/alexw/tinyvla_data/so101_v3/*
|
| 6 |
+
weight: 0.65
|
| 7 |
+
- repo_id: nvidia/BridgeData2_LeRobot_v3
|
| 8 |
+
root: /home/alexw/tinyvla_data/bridge_v3_10k
|
| 9 |
+
revision: main
|
| 10 |
+
episodes: 10000
|
| 11 |
+
weight: 0.35
|
| 12 |
+
policy:
|
| 13 |
+
chunk_size: 50
|
| 14 |
+
n_action_steps: 50
|
| 15 |
+
image_size: 256
|
| 16 |
+
use_semantic_latent: false
|
| 17 |
+
batch_size: 64
|
| 18 |
+
grad_accum: 2
|
| 19 |
+
num_workers: 12
|
| 20 |
+
lr: 1.0e-4
|
| 21 |
+
warmup_steps: 500
|
| 22 |
+
steps: 5000
|
| 23 |
+
log_freq: 50
|
| 24 |
+
save_freq: 2500
|
| 25 |
+
mixed_precision: bf16
|
tinyvla2/configs/ablation_nospatial.yaml
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Stage-2 gate baseline: same mixture, 5k steps, nospatial ablation
|
| 2 |
+
output_dir: /home/alexw/tinyvla/outputs/ablation_nospatial
|
| 3 |
+
wandb: null
|
| 4 |
+
datasets:
|
| 5 |
+
- root_glob: /home/alexw/tinyvla_data/so101_v3/*
|
| 6 |
+
weight: 0.65
|
| 7 |
+
- repo_id: nvidia/BridgeData2_LeRobot_v3
|
| 8 |
+
root: /home/alexw/tinyvla_data/bridge_v3_10k
|
| 9 |
+
revision: main
|
| 10 |
+
episodes: 10000
|
| 11 |
+
weight: 0.35
|
| 12 |
+
policy:
|
| 13 |
+
chunk_size: 50
|
| 14 |
+
n_action_steps: 50
|
| 15 |
+
image_size: 256
|
| 16 |
+
use_spatial_tokens: false
|
| 17 |
+
batch_size: 64
|
| 18 |
+
grad_accum: 2
|
| 19 |
+
num_workers: 12
|
| 20 |
+
lr: 1.0e-4
|
| 21 |
+
warmup_steps: 500
|
| 22 |
+
steps: 5000
|
| 23 |
+
log_freq: 50
|
| 24 |
+
save_freq: 2500
|
| 25 |
+
mixed_precision: bf16
|
tinyvla2/configs/libero_ft.yaml
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# LIBERO fine-tune from the Stage-2 pretrained checkpoint (XS-VLA/SmolVLA protocol).
|
| 2 |
+
# LIBERO = new embodiment (id 2): Franka 7-DoF EE @10fps, two 256^2 cameras.
|
| 3 |
+
|
| 4 |
+
output_dir: /home/alexw/tinyvla/outputs/libero_ft
|
| 5 |
+
wandb: null
|
| 6 |
+
|
| 7 |
+
datasets:
|
| 8 |
+
- repo_id: HuggingFaceVLA/libero
|
| 9 |
+
weight: 1.0
|
| 10 |
+
embodiment_id: 2
|
| 11 |
+
|
| 12 |
+
policy:
|
| 13 |
+
chunk_size: 50
|
| 14 |
+
n_action_steps: 50
|
| 15 |
+
image_size: 256
|
| 16 |
+
freeze_lm: true
|
| 17 |
+
freeze_vision_encoder: true
|
| 18 |
+
|
| 19 |
+
resume_from: /home/alexw/tinyvla/outputs/stage2_mixture/final
|
| 20 |
+
resume_step: 0
|
| 21 |
+
|
| 22 |
+
batch_size: 64
|
| 23 |
+
grad_accum: 1
|
| 24 |
+
num_workers: 12
|
| 25 |
+
lr: 5.0e-5
|
| 26 |
+
warmup_steps: 500
|
| 27 |
+
steps: 15000
|
| 28 |
+
grad_clip: 10.0
|
| 29 |
+
log_freq: 50
|
| 30 |
+
save_freq: 2500
|
| 31 |
+
mixed_precision: bf16
|
tinyvla2/configs/libero_ft2.yaml
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# LIBERO fine-tune v2: unfreeze the vision tower (sim renders are OOD for the
|
| 2 |
+
# real-world-pretrained encoder), longer schedule.
|
| 3 |
+
|
| 4 |
+
output_dir: /home/alexw/tinyvla/outputs/libero_ft2
|
| 5 |
+
wandb: null
|
| 6 |
+
|
| 7 |
+
datasets:
|
| 8 |
+
- repo_id: HuggingFaceVLA/libero
|
| 9 |
+
weight: 1.0
|
| 10 |
+
embodiment_id: 2
|
| 11 |
+
|
| 12 |
+
policy:
|
| 13 |
+
chunk_size: 50
|
| 14 |
+
n_action_steps: 50
|
| 15 |
+
image_size: 256
|
| 16 |
+
freeze_lm: true
|
| 17 |
+
freeze_vision_encoder: false
|
| 18 |
+
|
| 19 |
+
backbone_lr_mult: 0.1
|
| 20 |
+
|
| 21 |
+
resume_from: /home/alexw/tinyvla/outputs/stage2_mixture/final
|
| 22 |
+
resume_step: 0
|
| 23 |
+
|
| 24 |
+
batch_size: 48
|
| 25 |
+
grad_accum: 1
|
| 26 |
+
num_workers: 12
|
| 27 |
+
lr: 1.0e-4
|
| 28 |
+
warmup_steps: 1000
|
| 29 |
+
steps: 30000
|
| 30 |
+
grad_clip: 10.0
|
| 31 |
+
log_freq: 50
|
| 32 |
+
save_freq: 5000
|
| 33 |
+
mixed_precision: bf16
|
tinyvla2/configs/libero_ft3.yaml
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# LIBERO fine-tune v2: unfreeze the vision tower (sim renders are OOD for the
|
| 2 |
+
# real-world-pretrained encoder), longer schedule.
|
| 3 |
+
|
| 4 |
+
output_dir: /home/alexw/tinyvla/outputs/libero_ft3
|
| 5 |
+
wandb: null
|
| 6 |
+
|
| 7 |
+
datasets:
|
| 8 |
+
- repo_id: HuggingFaceVLA/libero
|
| 9 |
+
weight: 1.0
|
| 10 |
+
embodiment_id: 2
|
| 11 |
+
|
| 12 |
+
policy:
|
| 13 |
+
chunk_size: 50
|
| 14 |
+
n_action_steps: 50
|
| 15 |
+
image_size: 256
|
| 16 |
+
freeze_lm: true
|
| 17 |
+
freeze_vision_encoder: false
|
| 18 |
+
|
| 19 |
+
backbone_lr_mult: 0.1
|
| 20 |
+
|
| 21 |
+
resume_from: /home/alexw/tinyvla/outputs/stage3_distill/final
|
| 22 |
+
resume_step: 0
|
| 23 |
+
|
| 24 |
+
batch_size: 48
|
| 25 |
+
grad_accum: 1
|
| 26 |
+
num_workers: 12
|
| 27 |
+
lr: 1.0e-4
|
| 28 |
+
warmup_steps: 1000
|
| 29 |
+
steps: 30000
|
| 30 |
+
grad_clip: 10.0
|
| 31 |
+
log_freq: 50
|
| 32 |
+
save_freq: 5000
|
| 33 |
+
mixed_precision: bf16
|
tinyvla2/configs/libero_ft4.yaml
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# LIBERO fine-tune v4: unfreeze BOTH vision tower and language stack
|
| 2 |
+
# (12 truncated layers; vocab embeddings stay frozen) at 0.1x lr, longer schedule.
|
| 3 |
+
|
| 4 |
+
output_dir: /home/alexw/tinyvla/outputs/libero_ft4
|
| 5 |
+
wandb: null
|
| 6 |
+
|
| 7 |
+
datasets:
|
| 8 |
+
- repo_id: HuggingFaceVLA/libero
|
| 9 |
+
weight: 1.0
|
| 10 |
+
embodiment_id: 2
|
| 11 |
+
|
| 12 |
+
policy:
|
| 13 |
+
chunk_size: 50
|
| 14 |
+
n_action_steps: 50
|
| 15 |
+
image_size: 256
|
| 16 |
+
freeze_lm: false
|
| 17 |
+
freeze_vision_encoder: false
|
| 18 |
+
|
| 19 |
+
backbone_lr_mult: 0.1
|
| 20 |
+
|
| 21 |
+
resume_from: /home/alexw/tinyvla/outputs/stage3_distill/final
|
| 22 |
+
resume_step: 0
|
| 23 |
+
|
| 24 |
+
batch_size: 48
|
| 25 |
+
grad_accum: 1
|
| 26 |
+
num_workers: 12
|
| 27 |
+
lr: 1.0e-4
|
| 28 |
+
warmup_steps: 1000
|
| 29 |
+
steps: 40000
|
| 30 |
+
grad_clip: 10.0
|
| 31 |
+
log_freq: 50
|
| 32 |
+
save_freq: 5000
|
| 33 |
+
mixed_precision: bf16
|
tinyvla2/configs/morphology/descriptors.yaml
ADDED
|
@@ -0,0 +1,277 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Per-embodiment morphology descriptors (variant C).
|
| 2 |
+
# Fields hand-normalized to O(1); order MUST match MORPH_FIELDS in
|
| 3 |
+
# src/tinyvla/modules/embodiment.py. Values: raw → normalized applied at load.
|
| 4 |
+
# arm_dof/10, reach_m*2, gripper_width_m*10, num_cameras/3, is_mobile ±1,
|
| 5 |
+
# control_hz/30, joint_lo_mean/pi, joint_hi_mean/pi, workspace_xyz*2,
|
| 6 |
+
# payload_kg/5, ee_type_parallel ±1, ee_type_multi ±1, base_holonomic ±1, reserved.
|
| 7 |
+
|
| 8 |
+
so101: # SO-100/101 5-DOF + gripper
|
| 9 |
+
arm_dof: 5
|
| 10 |
+
reach_m: 0.35
|
| 11 |
+
gripper_width_m: 0.03
|
| 12 |
+
num_cameras: 2
|
| 13 |
+
is_mobile: -1
|
| 14 |
+
control_hz: 30
|
| 15 |
+
joint_lo_mean: -1.9
|
| 16 |
+
joint_hi_mean: 1.9
|
| 17 |
+
workspace_x: 0.30
|
| 18 |
+
workspace_y: 0.30
|
| 19 |
+
workspace_z: 0.25
|
| 20 |
+
payload_kg: 0.25
|
| 21 |
+
ee_type_parallel: 1
|
| 22 |
+
ee_type_multi: -1
|
| 23 |
+
base_holonomic: -1
|
| 24 |
+
reserved: 0
|
| 25 |
+
|
| 26 |
+
bridge: # WidowX 250 6-DOF
|
| 27 |
+
arm_dof: 6
|
| 28 |
+
reach_m: 0.60
|
| 29 |
+
gripper_width_m: 0.06
|
| 30 |
+
num_cameras: 1
|
| 31 |
+
is_mobile: -1
|
| 32 |
+
control_hz: 5
|
| 33 |
+
joint_lo_mean: -2.6
|
| 34 |
+
joint_hi_mean: 2.6
|
| 35 |
+
workspace_x: 0.40
|
| 36 |
+
workspace_y: 0.40
|
| 37 |
+
workspace_z: 0.35
|
| 38 |
+
payload_kg: 0.25
|
| 39 |
+
ee_type_parallel: 1
|
| 40 |
+
ee_type_multi: -1
|
| 41 |
+
base_holonomic: -1
|
| 42 |
+
reserved: 0
|
| 43 |
+
|
| 44 |
+
rt1: # Google robot (mobile manipulator, 7-DOF arm)
|
| 45 |
+
arm_dof: 7
|
| 46 |
+
reach_m: 0.90
|
| 47 |
+
gripper_width_m: 0.08
|
| 48 |
+
num_cameras: 1
|
| 49 |
+
is_mobile: 1
|
| 50 |
+
control_hz: 3
|
| 51 |
+
joint_lo_mean: -2.9
|
| 52 |
+
joint_hi_mean: 2.9
|
| 53 |
+
workspace_x: 0.70
|
| 54 |
+
workspace_y: 0.70
|
| 55 |
+
workspace_z: 0.60
|
| 56 |
+
payload_kg: 1.0
|
| 57 |
+
ee_type_parallel: 1
|
| 58 |
+
ee_type_multi: -1
|
| 59 |
+
base_holonomic: 1
|
| 60 |
+
reserved: 0
|
| 61 |
+
|
| 62 |
+
droid: # Franka Panda 7-DOF
|
| 63 |
+
arm_dof: 7
|
| 64 |
+
reach_m: 0.85
|
| 65 |
+
gripper_width_m: 0.08
|
| 66 |
+
num_cameras: 2
|
| 67 |
+
is_mobile: -1
|
| 68 |
+
control_hz: 15
|
| 69 |
+
joint_lo_mean: -2.8
|
| 70 |
+
joint_hi_mean: 2.8
|
| 71 |
+
workspace_x: 0.60
|
| 72 |
+
workspace_y: 0.60
|
| 73 |
+
workspace_z: 0.55
|
| 74 |
+
payload_kg: 3.0
|
| 75 |
+
ee_type_parallel: 1
|
| 76 |
+
ee_type_multi: -1
|
| 77 |
+
base_holonomic: -1
|
| 78 |
+
reserved: 0
|
| 79 |
+
|
| 80 |
+
libero: # Franka Panda (sim) — same morphology as droid
|
| 81 |
+
arm_dof: 7
|
| 82 |
+
reach_m: 0.85
|
| 83 |
+
gripper_width_m: 0.08
|
| 84 |
+
num_cameras: 2
|
| 85 |
+
is_mobile: -1
|
| 86 |
+
control_hz: 20
|
| 87 |
+
joint_lo_mean: -2.8
|
| 88 |
+
joint_hi_mean: 2.8
|
| 89 |
+
workspace_x: 0.60
|
| 90 |
+
workspace_y: 0.60
|
| 91 |
+
workspace_z: 0.55
|
| 92 |
+
payload_kg: 3.0
|
| 93 |
+
ee_type_parallel: 1
|
| 94 |
+
ee_type_multi: -1
|
| 95 |
+
base_holonomic: -1
|
| 96 |
+
reserved: 0
|
| 97 |
+
|
| 98 |
+
# --- held-out (never in pretraining; descriptors ready for zero-shot variant C) ---
|
| 99 |
+
jaco: # Kinova Jaco 6-DOF, 3-finger gripper
|
| 100 |
+
arm_dof: 6
|
| 101 |
+
reach_m: 0.90
|
| 102 |
+
gripper_width_m: 0.10
|
| 103 |
+
num_cameras: 1
|
| 104 |
+
is_mobile: -1
|
| 105 |
+
control_hz: 10
|
| 106 |
+
joint_lo_mean: -3.1
|
| 107 |
+
joint_hi_mean: 3.1
|
| 108 |
+
workspace_x: 0.60
|
| 109 |
+
workspace_y: 0.60
|
| 110 |
+
workspace_z: 0.55
|
| 111 |
+
payload_kg: 1.6
|
| 112 |
+
ee_type_parallel: -1
|
| 113 |
+
ee_type_multi: 1
|
| 114 |
+
base_holonomic: -1
|
| 115 |
+
reserved: 0
|
| 116 |
+
|
| 117 |
+
fanuc: # Fanuc Mate 6-DOF industrial
|
| 118 |
+
arm_dof: 6
|
| 119 |
+
reach_m: 0.70
|
| 120 |
+
gripper_width_m: 0.05
|
| 121 |
+
num_cameras: 1
|
| 122 |
+
is_mobile: -1
|
| 123 |
+
control_hz: 10
|
| 124 |
+
joint_lo_mean: -3.1
|
| 125 |
+
joint_hi_mean: 3.1
|
| 126 |
+
workspace_x: 0.50
|
| 127 |
+
workspace_y: 0.50
|
| 128 |
+
workspace_z: 0.45
|
| 129 |
+
payload_kg: 4.0
|
| 130 |
+
ee_type_parallel: 1
|
| 131 |
+
ee_type_multi: -1
|
| 132 |
+
base_holonomic: -1
|
| 133 |
+
reserved: 0
|
| 134 |
+
|
| 135 |
+
lekiwi: # LeKiwi — SO-100 (5-DOF) arm on a 3-wheel holonomic kiwi base (mobile manipulator)
|
| 136 |
+
arm_dof: 5
|
| 137 |
+
reach_m: 0.35
|
| 138 |
+
gripper_width_m: 0.03
|
| 139 |
+
num_cameras: 2
|
| 140 |
+
is_mobile: 1
|
| 141 |
+
control_hz: 30
|
| 142 |
+
joint_lo_mean: -1.9
|
| 143 |
+
joint_hi_mean: 1.9
|
| 144 |
+
workspace_x: 1.5
|
| 145 |
+
workspace_y: 1.5
|
| 146 |
+
workspace_z: 0.30
|
| 147 |
+
payload_kg: 0.25
|
| 148 |
+
ee_type_parallel: 1
|
| 149 |
+
ee_type_multi: -1
|
| 150 |
+
base_holonomic: 1
|
| 151 |
+
reserved: 0
|
| 152 |
+
|
| 153 |
+
ur5: # Universal Robots UR5e — 6-DOF industrial arm, fixed base
|
| 154 |
+
arm_dof: 6
|
| 155 |
+
reach_m: 0.85
|
| 156 |
+
gripper_width_m: 0.085
|
| 157 |
+
num_cameras: 1
|
| 158 |
+
is_mobile: -1
|
| 159 |
+
control_hz: 5
|
| 160 |
+
joint_lo_mean: -3.1
|
| 161 |
+
joint_hi_mean: 3.1
|
| 162 |
+
workspace_x: 0.70
|
| 163 |
+
workspace_y: 0.70
|
| 164 |
+
workspace_z: 0.60
|
| 165 |
+
payload_kg: 5.0
|
| 166 |
+
ee_type_parallel: 1
|
| 167 |
+
ee_type_multi: -1
|
| 168 |
+
base_holonomic: -1
|
| 169 |
+
reserved: 0
|
| 170 |
+
|
| 171 |
+
xarm: # UFactory xArm — 6-DOF arm, fixed base
|
| 172 |
+
arm_dof: 6
|
| 173 |
+
reach_m: 0.70
|
| 174 |
+
gripper_width_m: 0.08
|
| 175 |
+
num_cameras: 1
|
| 176 |
+
is_mobile: -1
|
| 177 |
+
control_hz: 5
|
| 178 |
+
joint_lo_mean: -3.1
|
| 179 |
+
joint_hi_mean: 3.1
|
| 180 |
+
workspace_x: 0.55
|
| 181 |
+
workspace_y: 0.55
|
| 182 |
+
workspace_z: 0.50
|
| 183 |
+
payload_kg: 3.5
|
| 184 |
+
ee_type_parallel: 1
|
| 185 |
+
ee_type_multi: -1
|
| 186 |
+
base_holonomic: -1
|
| 187 |
+
reserved: 0
|
| 188 |
+
|
| 189 |
+
dlr_edan: # DLR EDAN — 7-DOF assistive arm on a wheelchair (mobile assistive)
|
| 190 |
+
arm_dof: 7
|
| 191 |
+
reach_m: 0.80
|
| 192 |
+
gripper_width_m: 0.07
|
| 193 |
+
num_cameras: 1
|
| 194 |
+
is_mobile: 1
|
| 195 |
+
control_hz: 5
|
| 196 |
+
joint_lo_mean: -2.9
|
| 197 |
+
joint_hi_mean: 2.9
|
| 198 |
+
workspace_x: 0.65
|
| 199 |
+
workspace_y: 0.65
|
| 200 |
+
workspace_z: 0.55
|
| 201 |
+
payload_kg: 2.0
|
| 202 |
+
ee_type_parallel: 1
|
| 203 |
+
ee_type_multi: -1
|
| 204 |
+
base_holonomic: -1
|
| 205 |
+
reserved: 0
|
| 206 |
+
|
| 207 |
+
tidybot: # holonomic wheeled mobile manipulator (Kinova arm on omni base), whole-body EE control
|
| 208 |
+
arm_dof: 7
|
| 209 |
+
reach_m: 0.90
|
| 210 |
+
gripper_width_m: 0.08
|
| 211 |
+
num_cameras: 2
|
| 212 |
+
is_mobile: 1
|
| 213 |
+
control_hz: 10
|
| 214 |
+
joint_lo_mean: -2.9
|
| 215 |
+
joint_hi_mean: 2.9
|
| 216 |
+
workspace_x: 2.0
|
| 217 |
+
workspace_y: 2.0
|
| 218 |
+
workspace_z: 1.0
|
| 219 |
+
payload_kg: 1.0
|
| 220 |
+
ee_type_parallel: 1
|
| 221 |
+
ee_type_multi: -1
|
| 222 |
+
base_holonomic: 1
|
| 223 |
+
reserved: 0
|
| 224 |
+
|
| 225 |
+
uav: # quadrotor drone — free-flying 6-DOF body, no arm, no gripper (max morphology gap)
|
| 226 |
+
arm_dof: 0
|
| 227 |
+
reach_m: 0.0
|
| 228 |
+
gripper_width_m: 0.0
|
| 229 |
+
num_cameras: 6
|
| 230 |
+
is_mobile: 1
|
| 231 |
+
control_hz: 30
|
| 232 |
+
joint_lo_mean: 0.0
|
| 233 |
+
joint_hi_mean: 0.0
|
| 234 |
+
workspace_x: 5.0
|
| 235 |
+
workspace_y: 5.0
|
| 236 |
+
workspace_z: 5.0
|
| 237 |
+
payload_kg: 0.5
|
| 238 |
+
ee_type_parallel: -1
|
| 239 |
+
ee_type_multi: -1
|
| 240 |
+
base_holonomic: 1
|
| 241 |
+
reserved: 1
|
| 242 |
+
|
| 243 |
+
hello_stretch: # Hello Robot Stretch — mobile base + prismatic lift
|
| 244 |
+
arm_dof: 4
|
| 245 |
+
reach_m: 0.52
|
| 246 |
+
gripper_width_m: 0.08
|
| 247 |
+
num_cameras: 1
|
| 248 |
+
is_mobile: 1
|
| 249 |
+
control_hz: 10
|
| 250 |
+
joint_lo_mean: -1.5
|
| 251 |
+
joint_hi_mean: 1.5
|
| 252 |
+
workspace_x: 0.50
|
| 253 |
+
workspace_y: 0.30
|
| 254 |
+
workspace_z: 1.10
|
| 255 |
+
payload_kg: 1.5
|
| 256 |
+
ee_type_parallel: 1
|
| 257 |
+
ee_type_multi: -1
|
| 258 |
+
base_holonomic: -1
|
| 259 |
+
reserved: 0
|
| 260 |
+
|
| 261 |
+
panda_omron: # RoboCasa PandaOmron — Franka 7-DOF arm on a holonomic omni mobile base (kitchen scenes)
|
| 262 |
+
arm_dof: 7
|
| 263 |
+
reach_m: 0.85
|
| 264 |
+
gripper_width_m: 0.08
|
| 265 |
+
num_cameras: 3
|
| 266 |
+
is_mobile: 1
|
| 267 |
+
control_hz: 20
|
| 268 |
+
joint_lo_mean: -2.8
|
| 269 |
+
joint_hi_mean: 2.8
|
| 270 |
+
workspace_x: 2.0
|
| 271 |
+
workspace_y: 2.0
|
| 272 |
+
workspace_z: 1.2
|
| 273 |
+
payload_kg: 3.0
|
| 274 |
+
ee_type_parallel: 1
|
| 275 |
+
ee_type_multi: -1
|
| 276 |
+
base_holonomic: 1
|
| 277 |
+
reserved: 0
|
tinyvla2/configs/morphology/robot_prompts.yaml
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Natural-language robot descriptions prepended to the task instruction (Qwen slow path).
|
| 2 |
+
# Complements the numeric morphology descriptor (C scheme) with a text channel.
|
| 3 |
+
so101: "Robot: SO-101, a 5-DOF tabletop arm with a parallel-jaw gripper on a fixed base."
|
| 4 |
+
bridge: "Robot: WidowX 250, a 6-DOF tabletop arm with a parallel gripper on a fixed base."
|
| 5 |
+
rt1: "Robot: Google Robot, a 7-DOF arm mounted on a wheeled mobile base."
|
| 6 |
+
ur5: "Robot: UR5e, a 6-DOF industrial arm with a parallel gripper on a fixed base."
|
| 7 |
+
xarm: "Robot: xArm, a 6-DOF arm with a parallel gripper on a fixed base."
|
| 8 |
+
dlr_edan: "Robot: DLR EDAN, a 7-DOF assistive arm mounted on a wheelchair mobile base."
|
| 9 |
+
tidybot: "Robot: TidyBot, a 7-DOF arm on a holonomic omnidirectional wheeled base; whole-body end-effector control."
|
| 10 |
+
hello_stretch: "Robot: Hello Stretch, an arm on a telescoping prismatic lift atop a mobile base."
|
| 11 |
+
jaco: "Robot: Kinova Jaco, a 6-DOF arm with a three-finger gripper on a fixed base."
|
| 12 |
+
lekiwi: "Robot: LeKiwi, a 5-DOF SO-100 arm mounted on a three-wheel holonomic mobile base."
|
| 13 |
+
panda_omron: "Robot: RoboCasa PandaOmron, a 7-DOF Franka arm on a holonomic omnidirectional mobile base, operating in kitchen scenes."
|
tinyvla2/configs/stage2_mixture.yaml
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Stage 2: small-scale mixture pretraining on one A6000.
|
| 2 |
+
# SO-100/101 community slice (converted v3.0) 0.65 + Bridge V2 0.35.
|
| 3 |
+
# Fractal dropped for MVP (v2.0, unconvertible in lerobot 0.6.1).
|
| 4 |
+
|
| 5 |
+
output_dir: /home/alexw/tinyvla/outputs/stage2_mixture
|
| 6 |
+
wandb: null # set a project name to enable
|
| 7 |
+
|
| 8 |
+
datasets:
|
| 9 |
+
- root_glob: /home/alexw/tinyvla_data/so101_v3/*
|
| 10 |
+
weight: 0.65
|
| 11 |
+
- repo_id: nvidia/BridgeData2_LeRobot_v3
|
| 12 |
+
root: /home/alexw/tinyvla_data/bridge_v3_10k
|
| 13 |
+
revision: main
|
| 14 |
+
episodes: 10000
|
| 15 |
+
weight: 0.35
|
| 16 |
+
|
| 17 |
+
policy:
|
| 18 |
+
chunk_size: 50
|
| 19 |
+
n_action_steps: 50
|
| 20 |
+
image_size: 256
|
| 21 |
+
freeze_lm: true
|
| 22 |
+
freeze_vision_encoder: true
|
| 23 |
+
|
| 24 |
+
batch_size: 64
|
| 25 |
+
grad_accum: 2
|
| 26 |
+
num_workers: 14
|
| 27 |
+
resume_from: /home/alexw/tinyvla/outputs/stage2_mixture/step_2000
|
| 28 |
+
resume_step: 2000
|
| 29 |
+
lr: 1.0e-4
|
| 30 |
+
warmup_steps: 1000
|
| 31 |
+
steps: 40000
|
| 32 |
+
grad_clip: 10.0
|
| 33 |
+
log_freq: 50
|
| 34 |
+
save_freq: 2000
|
| 35 |
+
mixed_precision: bf16
|
| 36 |
+
staleness_start_step: 20000
|
| 37 |
+
staleness_prob: 0.5
|
tinyvla2/configs/stage3_distill.yaml
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Stage 3: continue SO101+Bridge pretraining with the spatial-distillation
|
| 2 |
+
# aux CE loss (teacher labels from Qwen3.5-4B) and staleness aug from the start.
|
| 3 |
+
|
| 4 |
+
output_dir: /home/alexw/tinyvla/outputs/stage3_distill
|
| 5 |
+
wandb: null
|
| 6 |
+
|
| 7 |
+
spatial_labels_dir: /home/alexw/tinyvla_data/spatial_labels
|
| 8 |
+
|
| 9 |
+
datasets:
|
| 10 |
+
- root_glob: /home/alexw/tinyvla_data/so101_v3/*
|
| 11 |
+
weight: 0.65
|
| 12 |
+
- repo_id: nvidia/BridgeData2_LeRobot_v3
|
| 13 |
+
root: /home/alexw/tinyvla_data/bridge_v3_10k
|
| 14 |
+
revision: main
|
| 15 |
+
episodes: 10000
|
| 16 |
+
weight: 0.35
|
| 17 |
+
|
| 18 |
+
policy:
|
| 19 |
+
chunk_size: 50
|
| 20 |
+
n_action_steps: 50
|
| 21 |
+
image_size: 256
|
| 22 |
+
freeze_lm: true
|
| 23 |
+
freeze_vision_encoder: true
|
| 24 |
+
spatial_loss_weight: 0.15
|
| 25 |
+
|
| 26 |
+
resume_from: /home/alexw/tinyvla/outputs/stage2_mixture/final
|
| 27 |
+
resume_step: 0
|
| 28 |
+
|
| 29 |
+
batch_size: 64
|
| 30 |
+
grad_accum: 2
|
| 31 |
+
num_workers: 14
|
| 32 |
+
lr: 5.0e-5
|
| 33 |
+
warmup_steps: 500
|
| 34 |
+
steps: 20000
|
| 35 |
+
grad_clip: 10.0
|
| 36 |
+
log_freq: 50
|
| 37 |
+
save_freq: 2500
|
| 38 |
+
mixed_precision: bf16
|
| 39 |
+
staleness_start_step: 0
|
| 40 |
+
staleness_prob: 0.5
|
tinyvla2/configs/tv2_A.yaml
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# TinyVLA-2 variant A: conditioning=id, action_space=native
|
| 2 |
+
# Identical data/weights/seed across A/B/C (matched-pairs design).
|
| 3 |
+
output_dir: /home/alexw/tinyvla/outputs/tv2_A_id_native
|
| 4 |
+
wandb: null
|
| 5 |
+
seed: 42
|
| 6 |
+
morphology_descriptors: /home/alexw/tinyvla/configs/morphology/descriptors.yaml
|
| 7 |
+
|
| 8 |
+
datasets:
|
| 9 |
+
- root_glob: /home/alexw/tinyvla_data/so101_v3/*
|
| 10 |
+
weight: 0.40
|
| 11 |
+
morph_key: so101
|
| 12 |
+
- repo_id: MolmoAct2-Bridge-Dataset
|
| 13 |
+
root: /home/alexw/tinyvla_data/MolmoAct2-Bridge-Dataset
|
| 14 |
+
episodes: 20000
|
| 15 |
+
weight: 0.30
|
| 16 |
+
morph_key: bridge
|
| 17 |
+
- repo_id: MolmoAct2-RT-1-Dataset
|
| 18 |
+
root: /home/alexw/tinyvla_data/MolmoAct2-RT-1-Dataset
|
| 19 |
+
episodes: 20000
|
| 20 |
+
weight: 0.30
|
| 21 |
+
morph_key: rt1
|
| 22 |
+
|
| 23 |
+
policy:
|
| 24 |
+
chunk_size: 50
|
| 25 |
+
n_action_steps: 50
|
| 26 |
+
image_size: 256
|
| 27 |
+
freeze_lm: true
|
| 28 |
+
freeze_vision_encoder: true
|
| 29 |
+
num_embodiments: 16
|
| 30 |
+
conditioning: id
|
| 31 |
+
action_space: native
|
| 32 |
+
|
| 33 |
+
batch_size: 64
|
| 34 |
+
grad_accum: 2
|
| 35 |
+
num_workers: 12
|
| 36 |
+
lr: 1.0e-4
|
| 37 |
+
warmup_steps: 1000
|
| 38 |
+
steps: 40000
|
| 39 |
+
grad_clip: 10.0
|
| 40 |
+
log_freq: 50
|
| 41 |
+
save_freq: 5000
|
| 42 |
+
mixed_precision: bf16
|
tinyvla2/configs/tv2_B.yaml
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# TinyVLA-2 variant B: conditioning=id, action_space=canonical
|
| 2 |
+
# Identical data/weights/seed across A/B/C (matched-pairs design).
|
| 3 |
+
output_dir: /home/alexw/tinyvla/outputs/tv2_B_id_canon
|
| 4 |
+
wandb: null
|
| 5 |
+
seed: 42
|
| 6 |
+
morphology_descriptors: /home/alexw/tinyvla/configs/morphology/descriptors.yaml
|
| 7 |
+
|
| 8 |
+
datasets:
|
| 9 |
+
- root_glob: /home/alexw/tinyvla_data/so101_v3/*
|
| 10 |
+
weight: 0.40
|
| 11 |
+
morph_key: so101
|
| 12 |
+
- repo_id: MolmoAct2-Bridge-Dataset
|
| 13 |
+
root: /home/alexw/tinyvla_data/MolmoAct2-Bridge-Dataset
|
| 14 |
+
episodes: 20000
|
| 15 |
+
weight: 0.30
|
| 16 |
+
morph_key: bridge
|
| 17 |
+
- repo_id: MolmoAct2-RT-1-Dataset
|
| 18 |
+
root: /home/alexw/tinyvla_data/MolmoAct2-RT-1-Dataset
|
| 19 |
+
episodes: 20000
|
| 20 |
+
weight: 0.30
|
| 21 |
+
morph_key: rt1
|
| 22 |
+
|
| 23 |
+
policy:
|
| 24 |
+
chunk_size: 50
|
| 25 |
+
n_action_steps: 50
|
| 26 |
+
image_size: 256
|
| 27 |
+
freeze_lm: true
|
| 28 |
+
freeze_vision_encoder: true
|
| 29 |
+
num_embodiments: 16
|
| 30 |
+
conditioning: id
|
| 31 |
+
action_space: canonical
|
| 32 |
+
|
| 33 |
+
batch_size: 64
|
| 34 |
+
grad_accum: 2
|
| 35 |
+
num_workers: 12
|
| 36 |
+
lr: 1.0e-4
|
| 37 |
+
warmup_steps: 1000
|
| 38 |
+
steps: 40000
|
| 39 |
+
grad_clip: 10.0
|
| 40 |
+
log_freq: 50
|
| 41 |
+
save_freq: 5000
|
| 42 |
+
mixed_precision: bf16
|
tinyvla2/configs/tv2_C.yaml
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# TinyVLA-2 variant C: conditioning=morph, action_space=canonical
|
| 2 |
+
# Identical data/weights/seed across A/B/C (matched-pairs design).
|
| 3 |
+
output_dir: /home/alexw/tinyvla/outputs/tv2_C_morph_canon
|
| 4 |
+
wandb: null
|
| 5 |
+
seed: 42
|
| 6 |
+
morphology_descriptors: /home/alexw/tinyvla/configs/morphology/descriptors.yaml
|
| 7 |
+
|
| 8 |
+
datasets:
|
| 9 |
+
- root_glob: /home/alexw/tinyvla_data/so101_v3/*
|
| 10 |
+
weight: 0.40
|
| 11 |
+
morph_key: so101
|
| 12 |
+
- repo_id: MolmoAct2-Bridge-Dataset
|
| 13 |
+
root: /home/alexw/tinyvla_data/MolmoAct2-Bridge-Dataset
|
| 14 |
+
episodes: 20000
|
| 15 |
+
weight: 0.30
|
| 16 |
+
morph_key: bridge
|
| 17 |
+
- repo_id: MolmoAct2-RT-1-Dataset
|
| 18 |
+
root: /home/alexw/tinyvla_data/MolmoAct2-RT-1-Dataset
|
| 19 |
+
episodes: 20000
|
| 20 |
+
weight: 0.30
|
| 21 |
+
morph_key: rt1
|
| 22 |
+
|
| 23 |
+
policy:
|
| 24 |
+
chunk_size: 50
|
| 25 |
+
n_action_steps: 50
|
| 26 |
+
image_size: 256
|
| 27 |
+
freeze_lm: true
|
| 28 |
+
freeze_vision_encoder: true
|
| 29 |
+
num_embodiments: 16
|
| 30 |
+
conditioning: morph
|
| 31 |
+
action_space: canonical
|
| 32 |
+
|
| 33 |
+
batch_size: 64
|
| 34 |
+
grad_accum: 2
|
| 35 |
+
num_workers: 12
|
| 36 |
+
lr: 1.0e-4
|
| 37 |
+
warmup_steps: 1000
|
| 38 |
+
steps: 40000
|
| 39 |
+
grad_clip: 10.0
|
| 40 |
+
log_freq: 50
|
| 41 |
+
save_freq: 5000
|
| 42 |
+
mixed_precision: bf16
|
tinyvla2/configs/tv2_C_diverse.yaml
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Continue-train variant C on an EXPANDED, morphology-diverse mixture to fix the
|
| 2 |
+
# OOD descriptor extrapolation (original C's morph-encoder saw only 3 arm-ish
|
| 3 |
+
# embodiments → failed zero-shot on mobile TidyBot). Now 8 embodiments spanning
|
| 4 |
+
# fixed arms (SO101, WidowX, UR5, xArm) + mobile (Google-robot, dlr_edan wheelchair,
|
| 5 |
+
# TidyBot holonomic, Stretch). jaco held out entirely for the transfer test.
|
| 6 |
+
output_dir: /home/alexw/tinyvla/outputs/tv2_C_diverse
|
| 7 |
+
wandb: null
|
| 8 |
+
seed: 42
|
| 9 |
+
morphology_descriptors: /home/alexw/tinyvla/configs/morphology/descriptors.yaml
|
| 10 |
+
resume_from: /home/alexw/tinyvla/outputs/tv2_C_morph_canon/final
|
| 11 |
+
resume_step: 0
|
| 12 |
+
|
| 13 |
+
datasets:
|
| 14 |
+
- root_glob: /home/alexw/tinyvla_data/so101_v3/*
|
| 15 |
+
weight: 0.25
|
| 16 |
+
morph_key: so101
|
| 17 |
+
- repo_id: MolmoAct2-Bridge-Dataset
|
| 18 |
+
root: /home/alexw/tinyvla_data/MolmoAct2-Bridge-Dataset
|
| 19 |
+
episodes: 15000
|
| 20 |
+
weight: 0.18
|
| 21 |
+
morph_key: bridge
|
| 22 |
+
- repo_id: MolmoAct2-RT-1-Dataset
|
| 23 |
+
root: /home/alexw/tinyvla_data/MolmoAct2-RT-1-Dataset
|
| 24 |
+
episodes: 15000
|
| 25 |
+
weight: 0.18
|
| 26 |
+
morph_key: rt1
|
| 27 |
+
- repo_id: div_ur5
|
| 28 |
+
root: /home/alexw/tinyvla_data/diverse/div_ur5
|
| 29 |
+
weight: 0.10
|
| 30 |
+
morph_key: ur5
|
| 31 |
+
- repo_id: div_xarm
|
| 32 |
+
root: /home/alexw/tinyvla_data/diverse/div_xarm
|
| 33 |
+
weight: 0.09
|
| 34 |
+
morph_key: xarm
|
| 35 |
+
- repo_id: div_dlr_edan
|
| 36 |
+
root: /home/alexw/tinyvla_data/diverse/div_dlr_edan
|
| 37 |
+
weight: 0.05
|
| 38 |
+
morph_key: dlr_edan
|
| 39 |
+
- repo_id: heldout_tidybot
|
| 40 |
+
root: /home/alexw/tinyvla_data/heldout/heldout_tidybot
|
| 41 |
+
weight: 0.08
|
| 42 |
+
morph_key: tidybot
|
| 43 |
+
- repo_id: heldout_cmu_stretch
|
| 44 |
+
root: /home/alexw/tinyvla_data/heldout/heldout_cmu_stretch
|
| 45 |
+
weight: 0.07
|
| 46 |
+
morph_key: hello_stretch
|
| 47 |
+
|
| 48 |
+
policy:
|
| 49 |
+
chunk_size: 50
|
| 50 |
+
n_action_steps: 50
|
| 51 |
+
image_size: 256
|
| 52 |
+
freeze_lm: true
|
| 53 |
+
freeze_vision_encoder: true
|
| 54 |
+
num_embodiments: 16
|
| 55 |
+
conditioning: morph
|
| 56 |
+
action_space: canonical
|
| 57 |
+
|
| 58 |
+
batch_size: 64
|
| 59 |
+
grad_accum: 2
|
| 60 |
+
num_workers: 12
|
| 61 |
+
lr: 7.0e-5
|
| 62 |
+
warmup_steps: 500
|
| 63 |
+
steps: 25000
|
| 64 |
+
grad_clip: 10.0
|
| 65 |
+
log_freq: 50
|
| 66 |
+
save_freq: 5000
|
| 67 |
+
mixed_precision: bf16
|
tinyvla2/configs/tv2_C_diverse_slow.yaml
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Continue-train variant C on an EXPANDED, morphology-diverse mixture to fix the
|
| 2 |
+
# OOD descriptor extrapolation (original C's morph-encoder saw only 3 arm-ish
|
| 3 |
+
# embodiments → failed zero-shot on mobile TidyBot). Now 8 embodiments spanning
|
| 4 |
+
# fixed arms (SO101, WidowX, UR5, xArm) + mobile (Google-robot, dlr_edan wheelchair,
|
| 5 |
+
# TidyBot holonomic, Stretch). jaco held out entirely for the transfer test.
|
| 6 |
+
output_dir: /home/alexw/tinyvla/outputs/tv2_C_diverse_slow
|
| 7 |
+
wandb: null
|
| 8 |
+
seed: 42
|
| 9 |
+
morphology_descriptors: /home/alexw/tinyvla/configs/morphology/descriptors.yaml
|
| 10 |
+
resume_from: /home/alexw/tinyvla/outputs/tv2_C_diverse/final
|
| 11 |
+
resume_step: 0
|
| 12 |
+
|
| 13 |
+
datasets:
|
| 14 |
+
- root_glob: /home/alexw/tinyvla_data/so101_v3/*
|
| 15 |
+
weight: 0.25
|
| 16 |
+
morph_key: so101
|
| 17 |
+
- repo_id: MolmoAct2-Bridge-Dataset
|
| 18 |
+
root: /home/alexw/tinyvla_data/MolmoAct2-Bridge-Dataset
|
| 19 |
+
episodes: 15000
|
| 20 |
+
weight: 0.18
|
| 21 |
+
morph_key: bridge
|
| 22 |
+
- repo_id: MolmoAct2-RT-1-Dataset
|
| 23 |
+
root: /home/alexw/tinyvla_data/MolmoAct2-RT-1-Dataset
|
| 24 |
+
episodes: 15000
|
| 25 |
+
weight: 0.18
|
| 26 |
+
morph_key: rt1
|
| 27 |
+
- repo_id: div_ur5
|
| 28 |
+
root: /home/alexw/tinyvla_data/diverse/div_ur5
|
| 29 |
+
weight: 0.10
|
| 30 |
+
morph_key: ur5
|
| 31 |
+
- repo_id: div_xarm
|
| 32 |
+
root: /home/alexw/tinyvla_data/diverse/div_xarm
|
| 33 |
+
weight: 0.09
|
| 34 |
+
morph_key: xarm
|
| 35 |
+
- repo_id: div_dlr_edan
|
| 36 |
+
root: /home/alexw/tinyvla_data/diverse/div_dlr_edan
|
| 37 |
+
weight: 0.05
|
| 38 |
+
morph_key: dlr_edan
|
| 39 |
+
- repo_id: heldout_tidybot
|
| 40 |
+
root: /home/alexw/tinyvla_data/heldout/heldout_tidybot
|
| 41 |
+
weight: 0.08
|
| 42 |
+
morph_key: tidybot
|
| 43 |
+
- repo_id: heldout_cmu_stretch
|
| 44 |
+
root: /home/alexw/tinyvla_data/heldout/heldout_cmu_stretch
|
| 45 |
+
weight: 0.07
|
| 46 |
+
morph_key: hello_stretch
|
| 47 |
+
|
| 48 |
+
policy:
|
| 49 |
+
chunk_size: 50
|
| 50 |
+
n_action_steps: 50
|
| 51 |
+
image_size: 256
|
| 52 |
+
freeze_lm: true
|
| 53 |
+
freeze_vision_encoder: true
|
| 54 |
+
num_embodiments: 16
|
| 55 |
+
conditioning: morph
|
| 56 |
+
morph_to_slow: true
|
| 57 |
+
action_space: canonical
|
| 58 |
+
|
| 59 |
+
batch_size: 64
|
| 60 |
+
grad_accum: 2
|
| 61 |
+
num_workers: 12
|
| 62 |
+
lr: 7.0e-5
|
| 63 |
+
warmup_steps: 500
|
| 64 |
+
steps: 25000
|
| 65 |
+
grad_clip: 10.0
|
| 66 |
+
log_freq: 50
|
| 67 |
+
save_freq: 5000
|
| 68 |
+
mixed_precision: bf16
|
tinyvla2/configs/tv2_C_incontext.yaml
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Variant: in-context few-shot DEMO conditioning — a few (obs, action) exemplar
|
| 2 |
+
# pairs from the target robot's own data, encoded via the shared spatial-aware
|
| 3 |
+
# vision encoder + a small MLP, WITHOUT any gradient update to adapt to that robot.
|
| 4 |
+
# Composed with the text-via-Qwen morphology channel (both active). Resumes from
|
| 5 |
+
# tv2_C_qwen_morph/final (LM already unfrozen, morph_out_proj already trained).
|
| 6 |
+
output_dir: /home/alexw/tinyvla/outputs/tv2_C_incontext
|
| 7 |
+
wandb: null
|
| 8 |
+
seed: 42
|
| 9 |
+
robot_prompts: /home/alexw/tinyvla/configs/morphology/robot_prompts.yaml
|
| 10 |
+
resume_from: /home/alexw/tinyvla/outputs/tv2_C_qwen_morph/final
|
| 11 |
+
resume_step: 0
|
| 12 |
+
|
| 13 |
+
datasets:
|
| 14 |
+
- root_glob: /home/alexw/tinyvla_data/so101_v3/*
|
| 15 |
+
weight: 0.25
|
| 16 |
+
morph_key: so101
|
| 17 |
+
- repo_id: MolmoAct2-Bridge-Dataset
|
| 18 |
+
root: /home/alexw/tinyvla_data/MolmoAct2-Bridge-Dataset
|
| 19 |
+
episodes: 15000
|
| 20 |
+
weight: 0.18
|
| 21 |
+
morph_key: bridge
|
| 22 |
+
- repo_id: MolmoAct2-RT-1-Dataset
|
| 23 |
+
root: /home/alexw/tinyvla_data/MolmoAct2-RT-1-Dataset
|
| 24 |
+
episodes: 15000
|
| 25 |
+
weight: 0.18
|
| 26 |
+
morph_key: rt1
|
| 27 |
+
- repo_id: div_ur5
|
| 28 |
+
root: /home/alexw/tinyvla_data/diverse/div_ur5
|
| 29 |
+
weight: 0.10
|
| 30 |
+
morph_key: ur5
|
| 31 |
+
- repo_id: div_xarm
|
| 32 |
+
root: /home/alexw/tinyvla_data/diverse/div_xarm
|
| 33 |
+
weight: 0.09
|
| 34 |
+
morph_key: xarm
|
| 35 |
+
- repo_id: div_dlr_edan
|
| 36 |
+
root: /home/alexw/tinyvla_data/diverse/div_dlr_edan
|
| 37 |
+
weight: 0.05
|
| 38 |
+
morph_key: dlr_edan
|
| 39 |
+
- repo_id: heldout_tidybot
|
| 40 |
+
root: /home/alexw/tinyvla_data/heldout/heldout_tidybot
|
| 41 |
+
weight: 0.08
|
| 42 |
+
morph_key: tidybot
|
| 43 |
+
- repo_id: heldout_cmu_stretch
|
| 44 |
+
root: /home/alexw/tinyvla_data/heldout/heldout_cmu_stretch
|
| 45 |
+
weight: 0.07
|
| 46 |
+
morph_key: hello_stretch
|
| 47 |
+
|
| 48 |
+
policy:
|
| 49 |
+
chunk_size: 50
|
| 50 |
+
n_action_steps: 50
|
| 51 |
+
image_size: 256
|
| 52 |
+
freeze_lm: false
|
| 53 |
+
freeze_vision_encoder: true
|
| 54 |
+
num_embodiments: 16
|
| 55 |
+
conditioning: morph_qwen
|
| 56 |
+
num_morph_readout: 4
|
| 57 |
+
morph_text_max_len: 32
|
| 58 |
+
action_space: canonical
|
| 59 |
+
use_demo_conditioning: true
|
| 60 |
+
n_support: 3
|
| 61 |
+
|
| 62 |
+
backbone_lr_mult: 0.1
|
| 63 |
+
batch_size: 40
|
| 64 |
+
grad_accum: 2
|
| 65 |
+
num_workers: 12
|
| 66 |
+
lr: 7.0e-5
|
| 67 |
+
warmup_steps: 500
|
| 68 |
+
steps: 20000
|
| 69 |
+
grad_clip: 10.0
|
| 70 |
+
log_freq: 50
|
| 71 |
+
save_freq: 5000
|
| 72 |
+
mixed_precision: bf16
|
tinyvla2/configs/tv2_C_incontext_v2.yaml
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Variant: in-context few-shot DEMO conditioning — a few (obs, action) exemplar
|
| 2 |
+
# pairs from the target robot's own data, encoded via the shared spatial-aware
|
| 3 |
+
# vision encoder + a small MLP, WITHOUT any gradient update to adapt to that robot.
|
| 4 |
+
# Composed with the text-via-Qwen morphology channel (both active). Resumes from
|
| 5 |
+
# tv2_C_qwen_morph/final (LM already unfrozen, morph_out_proj already trained).
|
| 6 |
+
output_dir: /home/alexw/tinyvla/outputs/tv2_C_incontext_v2
|
| 7 |
+
wandb: null
|
| 8 |
+
seed: 42
|
| 9 |
+
robot_prompts: /home/alexw/tinyvla/configs/morphology/robot_prompts.yaml
|
| 10 |
+
resume_from: /home/alexw/tinyvla/outputs/tv2_C_qwen_morph/final
|
| 11 |
+
resume_step: 0
|
| 12 |
+
|
| 13 |
+
datasets:
|
| 14 |
+
- root_glob: /home/alexw/tinyvla_data/so101_v3/*
|
| 15 |
+
weight: 0.25
|
| 16 |
+
morph_key: so101
|
| 17 |
+
- repo_id: MolmoAct2-Bridge-Dataset
|
| 18 |
+
root: /home/alexw/tinyvla_data/MolmoAct2-Bridge-Dataset
|
| 19 |
+
episodes: 15000
|
| 20 |
+
weight: 0.18
|
| 21 |
+
morph_key: bridge
|
| 22 |
+
- repo_id: MolmoAct2-RT-1-Dataset
|
| 23 |
+
root: /home/alexw/tinyvla_data/MolmoAct2-RT-1-Dataset
|
| 24 |
+
episodes: 15000
|
| 25 |
+
weight: 0.18
|
| 26 |
+
morph_key: rt1
|
| 27 |
+
- repo_id: div_ur5
|
| 28 |
+
root: /home/alexw/tinyvla_data/diverse/div_ur5
|
| 29 |
+
weight: 0.10
|
| 30 |
+
morph_key: ur5
|
| 31 |
+
- repo_id: div_xarm
|
| 32 |
+
root: /home/alexw/tinyvla_data/diverse/div_xarm
|
| 33 |
+
weight: 0.09
|
| 34 |
+
morph_key: xarm
|
| 35 |
+
- repo_id: div_dlr_edan
|
| 36 |
+
root: /home/alexw/tinyvla_data/diverse/div_dlr_edan
|
| 37 |
+
weight: 0.05
|
| 38 |
+
morph_key: dlr_edan
|
| 39 |
+
- repo_id: heldout_tidybot
|
| 40 |
+
root: /home/alexw/tinyvla_data/heldout/heldout_tidybot
|
| 41 |
+
weight: 0.08
|
| 42 |
+
morph_key: tidybot
|
| 43 |
+
- repo_id: heldout_cmu_stretch
|
| 44 |
+
root: /home/alexw/tinyvla_data/heldout/heldout_cmu_stretch
|
| 45 |
+
weight: 0.07
|
| 46 |
+
morph_key: hello_stretch
|
| 47 |
+
|
| 48 |
+
policy:
|
| 49 |
+
chunk_size: 50
|
| 50 |
+
n_action_steps: 50
|
| 51 |
+
image_size: 256
|
| 52 |
+
freeze_lm: false
|
| 53 |
+
freeze_vision_encoder: true
|
| 54 |
+
num_embodiments: 16
|
| 55 |
+
conditioning: morph_qwen
|
| 56 |
+
num_morph_readout: 4
|
| 57 |
+
morph_text_max_len: 32
|
| 58 |
+
action_space: canonical
|
| 59 |
+
use_demo_conditioning: true
|
| 60 |
+
n_support: 3
|
| 61 |
+
support_other_task: true
|
| 62 |
+
|
| 63 |
+
backbone_lr_mult: 0.1
|
| 64 |
+
batch_size: 40
|
| 65 |
+
grad_accum: 2
|
| 66 |
+
num_workers: 12
|
| 67 |
+
lr: 7.0e-5
|
| 68 |
+
warmup_steps: 500
|
| 69 |
+
steps: 20000
|
| 70 |
+
grad_clip: 10.0
|
| 71 |
+
log_freq: 50
|
| 72 |
+
save_freq: 5000
|
| 73 |
+
mixed_precision: bf16
|
tinyvla2/configs/tv2_C_incontext_v3.yaml
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Variant: in-context few-shot DEMO conditioning — a few (obs, action) exemplar
|
| 2 |
+
# pairs from the target robot's own data, encoded via the shared spatial-aware
|
| 3 |
+
# vision encoder + a small MLP, WITHOUT any gradient update to adapt to that robot.
|
| 4 |
+
# Composed with the text-via-Qwen morphology channel (both active). Resumes from
|
| 5 |
+
# tv2_C_qwen_morph/final (LM already unfrozen, morph_out_proj already trained).
|
| 6 |
+
output_dir: /home/alexw/tinyvla/outputs/tv2_C_incontext_v3
|
| 7 |
+
wandb: null
|
| 8 |
+
seed: 42
|
| 9 |
+
robot_prompts: /home/alexw/tinyvla/configs/morphology/robot_prompts.yaml
|
| 10 |
+
resume_from: /home/alexw/tinyvla/outputs/tv2_C_qwen_morph/final
|
| 11 |
+
resume_step: 0
|
| 12 |
+
|
| 13 |
+
datasets:
|
| 14 |
+
- root_glob: /home/alexw/tinyvla_data/so101_v3/*
|
| 15 |
+
weight: 0.25
|
| 16 |
+
morph_key: so101
|
| 17 |
+
- repo_id: MolmoAct2-Bridge-Dataset
|
| 18 |
+
root: /home/alexw/tinyvla_data/MolmoAct2-Bridge-Dataset
|
| 19 |
+
episodes: 15000
|
| 20 |
+
weight: 0.18
|
| 21 |
+
morph_key: bridge
|
| 22 |
+
- repo_id: MolmoAct2-RT-1-Dataset
|
| 23 |
+
root: /home/alexw/tinyvla_data/MolmoAct2-RT-1-Dataset
|
| 24 |
+
episodes: 15000
|
| 25 |
+
weight: 0.18
|
| 26 |
+
morph_key: rt1
|
| 27 |
+
- repo_id: div_ur5
|
| 28 |
+
root: /home/alexw/tinyvla_data/diverse/div_ur5
|
| 29 |
+
weight: 0.10
|
| 30 |
+
morph_key: ur5
|
| 31 |
+
- repo_id: div_xarm
|
| 32 |
+
root: /home/alexw/tinyvla_data/diverse/div_xarm
|
| 33 |
+
weight: 0.09
|
| 34 |
+
morph_key: xarm
|
| 35 |
+
- repo_id: div_dlr_edan
|
| 36 |
+
root: /home/alexw/tinyvla_data/diverse/div_dlr_edan
|
| 37 |
+
weight: 0.05
|
| 38 |
+
morph_key: dlr_edan
|
| 39 |
+
- repo_id: heldout_tidybot
|
| 40 |
+
root: /home/alexw/tinyvla_data/heldout/heldout_tidybot
|
| 41 |
+
weight: 0.08
|
| 42 |
+
morph_key: tidybot
|
| 43 |
+
- repo_id: heldout_cmu_stretch
|
| 44 |
+
root: /home/alexw/tinyvla_data/heldout/heldout_cmu_stretch
|
| 45 |
+
weight: 0.07
|
| 46 |
+
morph_key: hello_stretch
|
| 47 |
+
|
| 48 |
+
policy:
|
| 49 |
+
chunk_size: 50
|
| 50 |
+
n_action_steps: 50
|
| 51 |
+
image_size: 256
|
| 52 |
+
freeze_lm: false
|
| 53 |
+
freeze_vision_encoder: true
|
| 54 |
+
num_embodiments: 16
|
| 55 |
+
conditioning: morph_qwen
|
| 56 |
+
num_morph_readout: 4
|
| 57 |
+
morph_text_max_len: 32
|
| 58 |
+
action_space: canonical
|
| 59 |
+
use_demo_conditioning: true
|
| 60 |
+
n_support: 3
|
| 61 |
+
support_other_task: true
|
| 62 |
+
demo_tokens_per_example: 4
|
| 63 |
+
demo_visual_groups: 4
|
| 64 |
+
demo_action_keys: 8
|
| 65 |
+
demo_hidden_mult: 4
|
| 66 |
+
|
| 67 |
+
backbone_lr_mult: 0.1
|
| 68 |
+
batch_size: 40
|
| 69 |
+
grad_accum: 2
|
| 70 |
+
num_workers: 12
|
| 71 |
+
lr: 7.0e-5
|
| 72 |
+
warmup_steps: 500
|
| 73 |
+
steps: 20000
|
| 74 |
+
grad_clip: 10.0
|
| 75 |
+
log_freq: 50
|
| 76 |
+
save_freq: 5000
|
| 77 |
+
mixed_precision: bf16
|
tinyvla2/configs/tv2_C_mega.yaml
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Continue-train C on the MAXIMALLY diverse robot set (9 embodiments) with BOTH
|
| 2 |
+
# channels describing the robot: numeric morphology descriptor (C scheme) AND a
|
| 3 |
+
# natural-language robot description in the Qwen prompt (slow path). Held out: LeKiwi
|
| 4 |
+
# (mobile SO-100 + kiwi base) — we have its zero-shot baseline (295mm) to compare.
|
| 5 |
+
output_dir: /home/alexw/tinyvla/outputs/tv2_C_mega
|
| 6 |
+
wandb: null
|
| 7 |
+
seed: 42
|
| 8 |
+
morphology_descriptors: /home/alexw/tinyvla/configs/morphology/descriptors.yaml
|
| 9 |
+
robot_prompts: /home/alexw/tinyvla/configs/morphology/robot_prompts.yaml
|
| 10 |
+
resume_from: /home/alexw/tinyvla/outputs/tv2_C_diverse/final
|
| 11 |
+
resume_step: 0
|
| 12 |
+
|
| 13 |
+
datasets:
|
| 14 |
+
- root_glob: /home/alexw/tinyvla_data/so101_v3/*
|
| 15 |
+
weight: 0.20
|
| 16 |
+
morph_key: so101
|
| 17 |
+
- repo_id: MolmoAct2-Bridge-Dataset
|
| 18 |
+
root: /home/alexw/tinyvla_data/MolmoAct2-Bridge-Dataset
|
| 19 |
+
episodes: 12000
|
| 20 |
+
weight: 0.15
|
| 21 |
+
morph_key: bridge
|
| 22 |
+
- repo_id: MolmoAct2-RT-1-Dataset
|
| 23 |
+
root: /home/alexw/tinyvla_data/MolmoAct2-RT-1-Dataset
|
| 24 |
+
episodes: 12000
|
| 25 |
+
weight: 0.15
|
| 26 |
+
morph_key: rt1
|
| 27 |
+
- repo_id: div_ur5
|
| 28 |
+
root: /home/alexw/tinyvla_data/diverse/div_ur5
|
| 29 |
+
weight: 0.10
|
| 30 |
+
morph_key: ur5
|
| 31 |
+
- repo_id: div_xarm
|
| 32 |
+
root: /home/alexw/tinyvla_data/diverse/div_xarm
|
| 33 |
+
weight: 0.09
|
| 34 |
+
morph_key: xarm
|
| 35 |
+
- repo_id: div_dlr_edan
|
| 36 |
+
root: /home/alexw/tinyvla_data/diverse/div_dlr_edan
|
| 37 |
+
weight: 0.06
|
| 38 |
+
morph_key: dlr_edan
|
| 39 |
+
- repo_id: heldout_tidybot
|
| 40 |
+
root: /home/alexw/tinyvla_data/heldout/heldout_tidybot
|
| 41 |
+
weight: 0.09
|
| 42 |
+
morph_key: tidybot
|
| 43 |
+
- repo_id: heldout_cmu_stretch
|
| 44 |
+
root: /home/alexw/tinyvla_data/heldout/heldout_cmu_stretch
|
| 45 |
+
weight: 0.08
|
| 46 |
+
morph_key: hello_stretch
|
| 47 |
+
- repo_id: heldout_jaco_play
|
| 48 |
+
root: /home/alexw/tinyvla_data/heldout/heldout_jaco_play
|
| 49 |
+
weight: 0.08
|
| 50 |
+
morph_key: jaco
|
| 51 |
+
|
| 52 |
+
policy:
|
| 53 |
+
chunk_size: 50
|
| 54 |
+
n_action_steps: 50
|
| 55 |
+
image_size: 256
|
| 56 |
+
freeze_lm: true
|
| 57 |
+
freeze_vision_encoder: true
|
| 58 |
+
num_embodiments: 16
|
| 59 |
+
conditioning: morph
|
| 60 |
+
action_space: canonical
|
| 61 |
+
|
| 62 |
+
batch_size: 64
|
| 63 |
+
grad_accum: 2
|
| 64 |
+
num_workers: 12
|
| 65 |
+
lr: 7.0e-5
|
| 66 |
+
warmup_steps: 500
|
| 67 |
+
steps: 20000
|
| 68 |
+
grad_clip: 10.0
|
| 69 |
+
log_freq: 50
|
| 70 |
+
save_freq: 5000
|
| 71 |
+
mixed_precision: bf16
|
tinyvla2/configs/tv2_C_qwen_morph.yaml
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Variant: morphology conditioning via the SAME shared Qwen (text-only pass over a
|
| 2 |
+
# robot description, e.g. "Robot: LeKiwi, a 5-DOF SO-100 arm on a three-wheel
|
| 3 |
+
# holonomic mobile base."), replacing the from-scratch MLP-over-numbers encoder.
|
| 4 |
+
# ALSO unfreezes the LM (freeze_lm: false) — per user request, since the frozen LM
|
| 5 |
+
# was the likely reason the earlier text-prompt-in-instruction experiment failed to
|
| 6 |
+
# learn to use new text. Resumes from C-diverse (8 robots, our best checkpoint:
|
| 7 |
+
# 150mm on held-out jaco). LeKiwi held out again for direct comparison (prior
|
| 8 |
+
# baselines: C-diverse numeric-only zero-shot 295mm; C-mega text-in-prompt 522mm).
|
| 9 |
+
output_dir: /home/alexw/tinyvla/outputs/tv2_C_qwen_morph
|
| 10 |
+
wandb: null
|
| 11 |
+
seed: 42
|
| 12 |
+
robot_prompts: /home/alexw/tinyvla/configs/morphology/robot_prompts.yaml
|
| 13 |
+
resume_from: /home/alexw/tinyvla/outputs/tv2_C_diverse/final
|
| 14 |
+
resume_step: 0
|
| 15 |
+
|
| 16 |
+
datasets:
|
| 17 |
+
- root_glob: /home/alexw/tinyvla_data/so101_v3/*
|
| 18 |
+
weight: 0.25
|
| 19 |
+
morph_key: so101
|
| 20 |
+
- repo_id: MolmoAct2-Bridge-Dataset
|
| 21 |
+
root: /home/alexw/tinyvla_data/MolmoAct2-Bridge-Dataset
|
| 22 |
+
episodes: 15000
|
| 23 |
+
weight: 0.18
|
| 24 |
+
morph_key: bridge
|
| 25 |
+
- repo_id: MolmoAct2-RT-1-Dataset
|
| 26 |
+
root: /home/alexw/tinyvla_data/MolmoAct2-RT-1-Dataset
|
| 27 |
+
episodes: 15000
|
| 28 |
+
weight: 0.18
|
| 29 |
+
morph_key: rt1
|
| 30 |
+
- repo_id: div_ur5
|
| 31 |
+
root: /home/alexw/tinyvla_data/diverse/div_ur5
|
| 32 |
+
weight: 0.10
|
| 33 |
+
morph_key: ur5
|
| 34 |
+
- repo_id: div_xarm
|
| 35 |
+
root: /home/alexw/tinyvla_data/diverse/div_xarm
|
| 36 |
+
weight: 0.09
|
| 37 |
+
morph_key: xarm
|
| 38 |
+
- repo_id: div_dlr_edan
|
| 39 |
+
root: /home/alexw/tinyvla_data/diverse/div_dlr_edan
|
| 40 |
+
weight: 0.05
|
| 41 |
+
morph_key: dlr_edan
|
| 42 |
+
- repo_id: heldout_tidybot
|
| 43 |
+
root: /home/alexw/tinyvla_data/heldout/heldout_tidybot
|
| 44 |
+
weight: 0.08
|
| 45 |
+
morph_key: tidybot
|
| 46 |
+
- repo_id: heldout_cmu_stretch
|
| 47 |
+
root: /home/alexw/tinyvla_data/heldout/heldout_cmu_stretch
|
| 48 |
+
weight: 0.07
|
| 49 |
+
morph_key: hello_stretch
|
| 50 |
+
|
| 51 |
+
policy:
|
| 52 |
+
chunk_size: 50
|
| 53 |
+
n_action_steps: 50
|
| 54 |
+
image_size: 256
|
| 55 |
+
freeze_lm: false
|
| 56 |
+
freeze_vision_encoder: true
|
| 57 |
+
num_embodiments: 16
|
| 58 |
+
conditioning: morph_qwen
|
| 59 |
+
num_morph_readout: 4
|
| 60 |
+
morph_text_max_len: 32
|
| 61 |
+
action_space: canonical
|
| 62 |
+
|
| 63 |
+
backbone_lr_mult: 0.1
|
| 64 |
+
batch_size: 48
|
| 65 |
+
grad_accum: 2
|
| 66 |
+
num_workers: 12
|
| 67 |
+
lr: 7.0e-5
|
| 68 |
+
warmup_steps: 500
|
| 69 |
+
steps: 20000
|
| 70 |
+
grad_clip: 10.0
|
| 71 |
+
log_freq: 50
|
| 72 |
+
save_freq: 5000
|
| 73 |
+
mixed_precision: bf16
|
tinyvla2/configs/tv2_C_scaled.yaml
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# SCALED C: the setup that works (canonical actions + numeric morphology
|
| 2 |
+
# descriptor), given a real budget. The reality check showed the model barely beat
|
| 3 |
+
# the trivial baseline (mean ratio 0.99 in-training) because 40k+20k steps were
|
| 4 |
+
# spread across 8 morphologies with a frozen backbone. This run scales:
|
| 5 |
+
# data : full Bridge (53K eps) + full RT-1 (87K eps) instead of 12-15K subsets
|
| 6 |
+
# -> pool 4.4M -> ~9.1M frames
|
| 7 |
+
# steps: 60k (was 20k) at eff batch 128 -> 7.7M samples (~0.85 epoch)
|
| 8 |
+
# model: LM UNFROZEN at 0.1x lr (the single biggest lever in TinyVLA v1:
|
| 9 |
+
# frozen 60% -> unfrozen 86% on LIBERO)
|
| 10 |
+
# Held out: LeKiwi (mobile) + jaco stays in for training here, so held-out
|
| 11 |
+
# comparison uses LeKiwi; jaco numbers become in-distribution reference.
|
| 12 |
+
output_dir: /home/alexw/tinyvla/outputs/tv2_C_scaled
|
| 13 |
+
wandb: null
|
| 14 |
+
seed: 42
|
| 15 |
+
morphology_descriptors: /home/alexw/tinyvla/configs/morphology/descriptors.yaml
|
| 16 |
+
resume_from: /home/alexw/tinyvla/outputs/tv2_C_diverse/final
|
| 17 |
+
resume_step: 0
|
| 18 |
+
|
| 19 |
+
datasets:
|
| 20 |
+
- root_glob: /home/alexw/tinyvla_data/so101_v3/*
|
| 21 |
+
weight: 0.22
|
| 22 |
+
morph_key: so101
|
| 23 |
+
- repo_id: MolmoAct2-Bridge-Dataset # FULL 53,192 eps (1.89M frames)
|
| 24 |
+
root: /home/alexw/tinyvla_data/MolmoAct2-Bridge-Dataset
|
| 25 |
+
weight: 0.22
|
| 26 |
+
morph_key: bridge
|
| 27 |
+
- repo_id: MolmoAct2-RT-1-Dataset # FULL 87,212 eps (3.79M frames)
|
| 28 |
+
root: /home/alexw/tinyvla_data/MolmoAct2-RT-1-Dataset
|
| 29 |
+
weight: 0.22
|
| 30 |
+
morph_key: rt1
|
| 31 |
+
- repo_id: div_ur5
|
| 32 |
+
root: /home/alexw/tinyvla_data/diverse/div_ur5
|
| 33 |
+
weight: 0.09
|
| 34 |
+
morph_key: ur5
|
| 35 |
+
- repo_id: div_xarm
|
| 36 |
+
root: /home/alexw/tinyvla_data/diverse/div_xarm
|
| 37 |
+
weight: 0.08
|
| 38 |
+
morph_key: xarm
|
| 39 |
+
- repo_id: div_dlr_edan
|
| 40 |
+
root: /home/alexw/tinyvla_data/diverse/div_dlr_edan
|
| 41 |
+
weight: 0.04
|
| 42 |
+
morph_key: dlr_edan
|
| 43 |
+
- repo_id: heldout_tidybot
|
| 44 |
+
root: /home/alexw/tinyvla_data/heldout/heldout_tidybot
|
| 45 |
+
weight: 0.05
|
| 46 |
+
morph_key: tidybot
|
| 47 |
+
- repo_id: heldout_cmu_stretch
|
| 48 |
+
root: /home/alexw/tinyvla_data/heldout/heldout_cmu_stretch
|
| 49 |
+
weight: 0.04
|
| 50 |
+
morph_key: hello_stretch
|
| 51 |
+
- repo_id: heldout_jaco_play
|
| 52 |
+
root: /home/alexw/tinyvla_data/heldout/heldout_jaco_play
|
| 53 |
+
weight: 0.04
|
| 54 |
+
morph_key: jaco
|
| 55 |
+
|
| 56 |
+
policy:
|
| 57 |
+
chunk_size: 50
|
| 58 |
+
n_action_steps: 50
|
| 59 |
+
image_size: 256
|
| 60 |
+
freeze_lm: false # the biggest known lever
|
| 61 |
+
freeze_vision_encoder: true
|
| 62 |
+
num_embodiments: 16
|
| 63 |
+
conditioning: morph # numeric descriptor: the channel that actually works
|
| 64 |
+
action_space: canonical
|
| 65 |
+
|
| 66 |
+
backbone_lr_mult: 0.1
|
| 67 |
+
batch_size: 48
|
| 68 |
+
grad_accum: 3 # eff batch 144
|
| 69 |
+
num_workers: 12
|
| 70 |
+
lr: 1.0e-4
|
| 71 |
+
warmup_steps: 1000
|
| 72 |
+
steps: 60000
|
| 73 |
+
grad_clip: 10.0
|
| 74 |
+
log_freq: 100
|
| 75 |
+
save_freq: 10000
|
| 76 |
+
mixed_precision: bf16
|
tinyvla2/configs/tv2_demoonly.yaml
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# DEMO-ONLY: every robot-identity channel removed (no embodiment ID, no
|
| 2 |
+
# morphology descriptor, no robot text) — the K demo exemplars in the LM
|
| 3 |
+
# attention stream are the ONLY cue for which robot this is. Per-source action
|
| 4 |
+
# normalization creates the pressure: to predict correctly the model MUST infer
|
| 5 |
+
# the robot's action scale, and only the demos carry it.
|
| 6 |
+
# (was: RICH SLOW PATH) demos + robot text + instruction + image all inside the LM
|
| 7 |
+
# sequence (demos in the ATTENTION STREAM), LM emits latent tokens conditioning
|
| 8 |
+
# the fast path. Dual-rate PRESERVED (fast path unchanged, latent cacheable).
|
| 9 |
+
# (was: in-context few-shot DEMO conditioning) — a few (obs, action) exemplar
|
| 10 |
+
# pairs from the target robot's own data, encoded via the shared spatial-aware
|
| 11 |
+
# vision encoder + a small MLP, WITHOUT any gradient update to adapt to that robot.
|
| 12 |
+
# Composed with the text-via-Qwen morphology channel (both active). Resumes from
|
| 13 |
+
# tv2_C_qwen_morph/final (LM already unfrozen, morph_out_proj already trained).
|
| 14 |
+
output_dir: /home/alexw/tinyvla/outputs/tv2_demoonly
|
| 15 |
+
wandb: null
|
| 16 |
+
seed: 42
|
| 17 |
+
robot_prompts: /home/alexw/tinyvla/configs/morphology/robot_prompts.yaml
|
| 18 |
+
resume_from: /home/alexw/tinyvla/outputs/tv2_C_qwen_morph/final
|
| 19 |
+
resume_step: 0
|
| 20 |
+
|
| 21 |
+
datasets:
|
| 22 |
+
- root_glob: /home/alexw/tinyvla_data/so101_v3/*
|
| 23 |
+
weight: 0.25
|
| 24 |
+
morph_key: so101
|
| 25 |
+
- repo_id: MolmoAct2-Bridge-Dataset
|
| 26 |
+
root: /home/alexw/tinyvla_data/MolmoAct2-Bridge-Dataset
|
| 27 |
+
episodes: 15000
|
| 28 |
+
weight: 0.18
|
| 29 |
+
morph_key: bridge
|
| 30 |
+
- repo_id: MolmoAct2-RT-1-Dataset
|
| 31 |
+
root: /home/alexw/tinyvla_data/MolmoAct2-RT-1-Dataset
|
| 32 |
+
episodes: 15000
|
| 33 |
+
weight: 0.18
|
| 34 |
+
morph_key: rt1
|
| 35 |
+
- repo_id: div_ur5
|
| 36 |
+
root: /home/alexw/tinyvla_data/diverse/div_ur5
|
| 37 |
+
weight: 0.10
|
| 38 |
+
morph_key: ur5
|
| 39 |
+
- repo_id: div_xarm
|
| 40 |
+
root: /home/alexw/tinyvla_data/diverse/div_xarm
|
| 41 |
+
weight: 0.09
|
| 42 |
+
morph_key: xarm
|
| 43 |
+
- repo_id: div_dlr_edan
|
| 44 |
+
root: /home/alexw/tinyvla_data/diverse/div_dlr_edan
|
| 45 |
+
weight: 0.05
|
| 46 |
+
morph_key: dlr_edan
|
| 47 |
+
- repo_id: heldout_tidybot
|
| 48 |
+
root: /home/alexw/tinyvla_data/heldout/heldout_tidybot
|
| 49 |
+
weight: 0.08
|
| 50 |
+
morph_key: tidybot
|
| 51 |
+
- repo_id: heldout_cmu_stretch
|
| 52 |
+
root: /home/alexw/tinyvla_data/heldout/heldout_cmu_stretch
|
| 53 |
+
weight: 0.07
|
| 54 |
+
morph_key: hello_stretch
|
| 55 |
+
|
| 56 |
+
policy:
|
| 57 |
+
chunk_size: 50
|
| 58 |
+
n_action_steps: 50
|
| 59 |
+
image_size: 256
|
| 60 |
+
freeze_lm: false
|
| 61 |
+
freeze_vision_encoder: true
|
| 62 |
+
num_embodiments: 16
|
| 63 |
+
conditioning: morph_qwen
|
| 64 |
+
num_morph_readout: 4
|
| 65 |
+
morph_text_max_len: 32
|
| 66 |
+
action_space: canonical
|
| 67 |
+
use_demo_conditioning: false # demos now go INTO the LM sequence, not the MLP encoder
|
| 68 |
+
n_support: 4
|
| 69 |
+
support_other_task: true
|
| 70 |
+
demo_tokens_per_example: 4
|
| 71 |
+
demo_visual_groups: 4
|
| 72 |
+
demo_action_keys: 8
|
| 73 |
+
demo_hidden_mult: 4
|
| 74 |
+
vlm_native: true
|
| 75 |
+
num_action_readout: 16
|
| 76 |
+
demo_action_keys_lm: 4
|
| 77 |
+
demo_only: true
|
| 78 |
+
|
| 79 |
+
backbone_lr_mult: 0.1
|
| 80 |
+
batch_size: 24
|
| 81 |
+
grad_accum: 3
|
| 82 |
+
num_workers: 12
|
| 83 |
+
lr: 7.0e-5
|
| 84 |
+
warmup_steps: 500
|
| 85 |
+
steps: 20000
|
| 86 |
+
grad_clip: 10.0
|
| 87 |
+
log_freq: 50
|
| 88 |
+
save_freq: 5000
|
| 89 |
+
mixed_precision: bf16
|
tinyvla2/configs/tv2_richslow.yaml
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# RICH SLOW PATH: demos + robot text + instruction + image all inside the LM
|
| 2 |
+
# sequence (demos in the ATTENTION STREAM), LM emits latent tokens conditioning
|
| 3 |
+
# the fast path. Dual-rate PRESERVED (fast path unchanged, latent cacheable).
|
| 4 |
+
# (was: in-context few-shot DEMO conditioning) — a few (obs, action) exemplar
|
| 5 |
+
# pairs from the target robot's own data, encoded via the shared spatial-aware
|
| 6 |
+
# vision encoder + a small MLP, WITHOUT any gradient update to adapt to that robot.
|
| 7 |
+
# Composed with the text-via-Qwen morphology channel (both active). Resumes from
|
| 8 |
+
# tv2_C_qwen_morph/final (LM already unfrozen, morph_out_proj already trained).
|
| 9 |
+
output_dir: /home/alexw/tinyvla/outputs/tv2_richslow
|
| 10 |
+
wandb: null
|
| 11 |
+
seed: 42
|
| 12 |
+
robot_prompts: /home/alexw/tinyvla/configs/morphology/robot_prompts.yaml
|
| 13 |
+
resume_from: /home/alexw/tinyvla/outputs/tv2_C_qwen_morph/final
|
| 14 |
+
resume_step: 0
|
| 15 |
+
|
| 16 |
+
datasets:
|
| 17 |
+
- root_glob: /home/alexw/tinyvla_data/so101_v3/*
|
| 18 |
+
weight: 0.25
|
| 19 |
+
morph_key: so101
|
| 20 |
+
- repo_id: MolmoAct2-Bridge-Dataset
|
| 21 |
+
root: /home/alexw/tinyvla_data/MolmoAct2-Bridge-Dataset
|
| 22 |
+
episodes: 15000
|
| 23 |
+
weight: 0.18
|
| 24 |
+
morph_key: bridge
|
| 25 |
+
- repo_id: MolmoAct2-RT-1-Dataset
|
| 26 |
+
root: /home/alexw/tinyvla_data/MolmoAct2-RT-1-Dataset
|
| 27 |
+
episodes: 15000
|
| 28 |
+
weight: 0.18
|
| 29 |
+
morph_key: rt1
|
| 30 |
+
- repo_id: div_ur5
|
| 31 |
+
root: /home/alexw/tinyvla_data/diverse/div_ur5
|
| 32 |
+
weight: 0.10
|
| 33 |
+
morph_key: ur5
|
| 34 |
+
- repo_id: div_xarm
|
| 35 |
+
root: /home/alexw/tinyvla_data/diverse/div_xarm
|
| 36 |
+
weight: 0.09
|
| 37 |
+
morph_key: xarm
|
| 38 |
+
- repo_id: div_dlr_edan
|
| 39 |
+
root: /home/alexw/tinyvla_data/diverse/div_dlr_edan
|
| 40 |
+
weight: 0.05
|
| 41 |
+
morph_key: dlr_edan
|
| 42 |
+
- repo_id: heldout_tidybot
|
| 43 |
+
root: /home/alexw/tinyvla_data/heldout/heldout_tidybot
|
| 44 |
+
weight: 0.08
|
| 45 |
+
morph_key: tidybot
|
| 46 |
+
- repo_id: heldout_cmu_stretch
|
| 47 |
+
root: /home/alexw/tinyvla_data/heldout/heldout_cmu_stretch
|
| 48 |
+
weight: 0.07
|
| 49 |
+
morph_key: hello_stretch
|
| 50 |
+
|
| 51 |
+
policy:
|
| 52 |
+
chunk_size: 50
|
| 53 |
+
n_action_steps: 50
|
| 54 |
+
image_size: 256
|
| 55 |
+
freeze_lm: false
|
| 56 |
+
freeze_vision_encoder: true
|
| 57 |
+
num_embodiments: 16
|
| 58 |
+
conditioning: morph_qwen
|
| 59 |
+
num_morph_readout: 4
|
| 60 |
+
morph_text_max_len: 32
|
| 61 |
+
action_space: canonical
|
| 62 |
+
use_demo_conditioning: false # demos now go INTO the LM sequence, not the MLP encoder
|
| 63 |
+
n_support: 3
|
| 64 |
+
support_other_task: true
|
| 65 |
+
demo_tokens_per_example: 4
|
| 66 |
+
demo_visual_groups: 4
|
| 67 |
+
demo_action_keys: 8
|
| 68 |
+
demo_hidden_mult: 4
|
| 69 |
+
vlm_native: true
|
| 70 |
+
num_action_readout: 16
|
| 71 |
+
demo_action_keys_lm: 4
|
| 72 |
+
|
| 73 |
+
backbone_lr_mult: 0.1
|
| 74 |
+
batch_size: 24
|
| 75 |
+
grad_accum: 3
|
| 76 |
+
num_workers: 12
|
| 77 |
+
lr: 7.0e-5
|
| 78 |
+
warmup_steps: 500
|
| 79 |
+
steps: 20000
|
| 80 |
+
grad_clip: 10.0
|
| 81 |
+
log_freq: 50
|
| 82 |
+
save_freq: 5000
|
| 83 |
+
mixed_precision: bf16
|
tinyvla2/configs/tv2_robocasa.yaml
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Continue-train the best checkpoint (C-scaled, 60k) on RoboCasa365 — the first
|
| 2 |
+
# genuinely NEW domain in this project: simulated kitchen scenes (everything before
|
| 3 |
+
# was real-world tabletops) with PandaOmron, a Franka arm on a holonomic mobile base.
|
| 4 |
+
# 7356 eps / 1.5M frames / 20fps / 3 cameras.
|
| 5 |
+
#
|
| 6 |
+
# RoboCasa gets half the sampling weight; the other half replays the previous robots
|
| 7 |
+
# so we can tell integration from catastrophic forgetting (all old robots stay
|
| 8 |
+
# measurable with the same eval). LeKiwi remains fully held out.
|
| 9 |
+
output_dir: /home/alexw/tinyvla/outputs/tv2_robocasa
|
| 10 |
+
wandb: null
|
| 11 |
+
seed: 42
|
| 12 |
+
morphology_descriptors: /home/alexw/tinyvla/configs/morphology/descriptors.yaml
|
| 13 |
+
resume_from: /home/alexw/tinyvla/outputs/tv2_C_scaled/final
|
| 14 |
+
resume_step: 0
|
| 15 |
+
|
| 16 |
+
datasets:
|
| 17 |
+
- repo_id: robocasa365 # NEW domain: sim kitchens, PandaOmron
|
| 18 |
+
root: /home/alexw/tinyvla_data/robocasa365
|
| 19 |
+
weight: 0.50
|
| 20 |
+
morph_key: panda_omron
|
| 21 |
+
- root_glob: /home/alexw/tinyvla_data/so101_v3/*
|
| 22 |
+
weight: 0.12
|
| 23 |
+
morph_key: so101
|
| 24 |
+
- repo_id: MolmoAct2-Bridge-Dataset
|
| 25 |
+
root: /home/alexw/tinyvla_data/MolmoAct2-Bridge-Dataset
|
| 26 |
+
weight: 0.11
|
| 27 |
+
morph_key: bridge
|
| 28 |
+
- repo_id: MolmoAct2-RT-1-Dataset
|
| 29 |
+
root: /home/alexw/tinyvla_data/MolmoAct2-RT-1-Dataset
|
| 30 |
+
weight: 0.11
|
| 31 |
+
morph_key: rt1
|
| 32 |
+
- repo_id: div_ur5
|
| 33 |
+
root: /home/alexw/tinyvla_data/diverse/div_ur5
|
| 34 |
+
weight: 0.05
|
| 35 |
+
morph_key: ur5
|
| 36 |
+
- repo_id: div_xarm
|
| 37 |
+
root: /home/alexw/tinyvla_data/diverse/div_xarm
|
| 38 |
+
weight: 0.04
|
| 39 |
+
morph_key: xarm
|
| 40 |
+
- repo_id: div_dlr_edan
|
| 41 |
+
root: /home/alexw/tinyvla_data/diverse/div_dlr_edan
|
| 42 |
+
weight: 0.02
|
| 43 |
+
morph_key: dlr_edan
|
| 44 |
+
- repo_id: heldout_tidybot
|
| 45 |
+
root: /home/alexw/tinyvla_data/heldout/heldout_tidybot
|
| 46 |
+
weight: 0.02
|
| 47 |
+
morph_key: tidybot
|
| 48 |
+
- repo_id: heldout_cmu_stretch
|
| 49 |
+
root: /home/alexw/tinyvla_data/heldout/heldout_cmu_stretch
|
| 50 |
+
weight: 0.02
|
| 51 |
+
morph_key: hello_stretch
|
| 52 |
+
- repo_id: heldout_jaco_play
|
| 53 |
+
root: /home/alexw/tinyvla_data/heldout/heldout_jaco_play
|
| 54 |
+
weight: 0.01
|
| 55 |
+
morph_key: jaco
|
| 56 |
+
|
| 57 |
+
policy:
|
| 58 |
+
chunk_size: 50
|
| 59 |
+
n_action_steps: 50
|
| 60 |
+
image_size: 256
|
| 61 |
+
freeze_lm: false
|
| 62 |
+
freeze_vision_encoder: true
|
| 63 |
+
num_embodiments: 16
|
| 64 |
+
conditioning: morph
|
| 65 |
+
action_space: canonical
|
| 66 |
+
|
| 67 |
+
backbone_lr_mult: 0.1
|
| 68 |
+
batch_size: 48
|
| 69 |
+
grad_accum: 3
|
| 70 |
+
num_workers: 12
|
| 71 |
+
lr: 7.0e-5
|
| 72 |
+
warmup_steps: 500
|
| 73 |
+
steps: 30000
|
| 74 |
+
grad_clip: 10.0
|
| 75 |
+
log_freq: 100
|
| 76 |
+
save_freq: 10000
|
| 77 |
+
mixed_precision: bf16
|
tinyvla2/configs/tv2_vlm_native.yaml
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# LLaVA-style: ALL modalities as tokens in one LM sequence, policy conditions on
|
| 2 |
+
# latent readout tokens. Demos live IN the attention stream (fix for v1-v3 failure).
|
| 3 |
+
# Trades away the dual-rate fast path.
|
| 4 |
+
# (was: in-context few-shot DEMO conditioning) — a few (obs, action) exemplar
|
| 5 |
+
# pairs from the target robot's own data, encoded via the shared spatial-aware
|
| 6 |
+
# vision encoder + a small MLP, WITHOUT any gradient update to adapt to that robot.
|
| 7 |
+
# Composed with the text-via-Qwen morphology channel (both active). Resumes from
|
| 8 |
+
# tv2_C_qwen_morph/final (LM already unfrozen, morph_out_proj already trained).
|
| 9 |
+
output_dir: /home/alexw/tinyvla/outputs/tv2_vlm_native
|
| 10 |
+
wandb: null
|
| 11 |
+
seed: 42
|
| 12 |
+
robot_prompts: /home/alexw/tinyvla/configs/morphology/robot_prompts.yaml
|
| 13 |
+
resume_from: /home/alexw/tinyvla/outputs/tv2_C_qwen_morph/final
|
| 14 |
+
resume_step: 0
|
| 15 |
+
|
| 16 |
+
datasets:
|
| 17 |
+
- root_glob: /home/alexw/tinyvla_data/so101_v3/*
|
| 18 |
+
weight: 0.25
|
| 19 |
+
morph_key: so101
|
| 20 |
+
- repo_id: MolmoAct2-Bridge-Dataset
|
| 21 |
+
root: /home/alexw/tinyvla_data/MolmoAct2-Bridge-Dataset
|
| 22 |
+
episodes: 15000
|
| 23 |
+
weight: 0.18
|
| 24 |
+
morph_key: bridge
|
| 25 |
+
- repo_id: MolmoAct2-RT-1-Dataset
|
| 26 |
+
root: /home/alexw/tinyvla_data/MolmoAct2-RT-1-Dataset
|
| 27 |
+
episodes: 15000
|
| 28 |
+
weight: 0.18
|
| 29 |
+
morph_key: rt1
|
| 30 |
+
- repo_id: div_ur5
|
| 31 |
+
root: /home/alexw/tinyvla_data/diverse/div_ur5
|
| 32 |
+
weight: 0.10
|
| 33 |
+
morph_key: ur5
|
| 34 |
+
- repo_id: div_xarm
|
| 35 |
+
root: /home/alexw/tinyvla_data/diverse/div_xarm
|
| 36 |
+
weight: 0.09
|
| 37 |
+
morph_key: xarm
|
| 38 |
+
- repo_id: div_dlr_edan
|
| 39 |
+
root: /home/alexw/tinyvla_data/diverse/div_dlr_edan
|
| 40 |
+
weight: 0.05
|
| 41 |
+
morph_key: dlr_edan
|
| 42 |
+
- repo_id: heldout_tidybot
|
| 43 |
+
root: /home/alexw/tinyvla_data/heldout/heldout_tidybot
|
| 44 |
+
weight: 0.08
|
| 45 |
+
morph_key: tidybot
|
| 46 |
+
- repo_id: heldout_cmu_stretch
|
| 47 |
+
root: /home/alexw/tinyvla_data/heldout/heldout_cmu_stretch
|
| 48 |
+
weight: 0.07
|
| 49 |
+
morph_key: hello_stretch
|
| 50 |
+
|
| 51 |
+
policy:
|
| 52 |
+
chunk_size: 50
|
| 53 |
+
n_action_steps: 50
|
| 54 |
+
image_size: 256
|
| 55 |
+
freeze_lm: false
|
| 56 |
+
freeze_vision_encoder: true
|
| 57 |
+
num_embodiments: 16
|
| 58 |
+
conditioning: id # unused in vlm_native; robot text goes into the LM sequence
|
| 59 |
+
num_morph_readout: 4
|
| 60 |
+
morph_text_max_len: 32
|
| 61 |
+
action_space: canonical
|
| 62 |
+
use_demo_conditioning: true
|
| 63 |
+
n_support: 3
|
| 64 |
+
support_other_task: true
|
| 65 |
+
demo_tokens_per_example: 4
|
| 66 |
+
demo_visual_groups: 4
|
| 67 |
+
demo_action_keys: 8
|
| 68 |
+
demo_hidden_mult: 4
|
| 69 |
+
vlm_native: true
|
| 70 |
+
num_action_readout: 16
|
| 71 |
+
demo_action_keys_lm: 4
|
| 72 |
+
|
| 73 |
+
backbone_lr_mult: 0.1
|
| 74 |
+
batch_size: 20
|
| 75 |
+
grad_accum: 4
|
| 76 |
+
num_workers: 12
|
| 77 |
+
lr: 7.0e-5
|
| 78 |
+
warmup_steps: 500
|
| 79 |
+
steps: 20000
|
| 80 |
+
grad_clip: 10.0
|
| 81 |
+
log_freq: 50
|
| 82 |
+
save_freq: 5000
|
| 83 |
+
mixed_precision: bf16
|
tinyvla2/scripts/__pycache__/fewshot_grid.cpython-312.pyc
ADDED
|
Binary file (5.77 kB). View file
|
|
|
tinyvla2/scripts/_eval_richslow_10k.py
ADDED
|
@@ -0,0 +1,141 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env python
|
| 2 |
+
"""Auto-eval for in-context demo conditioning on held-out LeKiwi.
|
| 3 |
+
|
| 4 |
+
The key test: give the model K=3 REAL (obs, action) example pairs from LeKiwi's
|
| 5 |
+
OWN data at test time — NO gradient update, NO fine-tuning — and see if that beats
|
| 6 |
+
zero-shot with no examples, wrong examples, or the numeric/text descriptor alone.
|
| 7 |
+
"""
|
| 8 |
+
|
| 9 |
+
from __future__ import annotations
|
| 10 |
+
|
| 11 |
+
import numpy as np
|
| 12 |
+
import torch
|
| 13 |
+
import yaml
|
| 14 |
+
from lerobot.datasets.lerobot_dataset import LeRobotDataset, LeRobotDatasetMetadata
|
| 15 |
+
from transformers import AutoTokenizer
|
| 16 |
+
|
| 17 |
+
from tinyvla.data.canonical import CanonicalChunkStore, quantile_normalize
|
| 18 |
+
from tinyvla.modeling_tinyvla import TinyVLAPolicy
|
| 19 |
+
|
| 20 |
+
CKPT = "outputs/tv2_richslow/step_10000"
|
| 21 |
+
DS = "lekiwi_cleanup"
|
| 22 |
+
ROOT = f"/home/alexw/tinyvla_data/lekiwi/{DS}"
|
| 23 |
+
K = 3
|
| 24 |
+
|
| 25 |
+
|
| 26 |
+
@torch.no_grad()
|
| 27 |
+
def main():
|
| 28 |
+
pol = TinyVLAPolicy.from_pretrained(CKPT).cuda().eval()
|
| 29 |
+
cfg = pol.config
|
| 30 |
+
tok = AutoTokenizer.from_pretrained(cfg.lm_model_name)
|
| 31 |
+
prompts = yaml.safe_load(open("configs/morphology/robot_prompts.yaml"))
|
| 32 |
+
|
| 33 |
+
m = LeRobotDatasetMetadata(DS, root=ROOT)
|
| 34 |
+
ds = LeRobotDataset(DS, root=ROOT, delta_timestamps={"action": [t / m.fps for t in range(50)]},
|
| 35 |
+
video_backend="torchcodec")
|
| 36 |
+
store = CanonicalChunkStore(DS, src_fps=m.fps, chunk=50)
|
| 37 |
+
st = store.compute_stats()
|
| 38 |
+
q01, q99 = np.asarray(st["q01"]), np.asarray(st["q99"])
|
| 39 |
+
span = np.maximum(q99 - q01, 0.01 * np.median(np.abs(np.concatenate([q01, q99])) + 1e-6))
|
| 40 |
+
mid = 0.5 * (q01 + q99)
|
| 41 |
+
|
| 42 |
+
imk = sorted(k for k in ds.meta.features if k.startswith("observation.images"))
|
| 43 |
+
prim = next((k for k in imk if "front" in k or "base" in k), imk[0])
|
| 44 |
+
|
| 45 |
+
def integ(d):
|
| 46 |
+
return np.cumsum(d[:, :3], 0)
|
| 47 |
+
|
| 48 |
+
def img_at(idx, ep, ep_start):
|
| 49 |
+
it = ds[idx]
|
| 50 |
+
im = torch.nn.functional.interpolate(it[prim][None], size=(256, 256), mode="bilinear")[0]
|
| 51 |
+
raw = quantile_normalize(store.chunk_for(ep, idx - ep_start), q01, q99)
|
| 52 |
+
act = torch.from_numpy(raw[:, :7]).float()
|
| 53 |
+
act = torch.nn.functional.pad(act, (0, cfg.max_action_dim - 7))
|
| 54 |
+
return im, act
|
| 55 |
+
|
| 56 |
+
# REAL LeKiwi demo pairs from early episodes (support pool), disjoint from test
|
| 57 |
+
support_pool_eps = range(0, min(20, m.total_episodes - 15))
|
| 58 |
+
test = range(max(0, m.total_episodes - 15), m.total_episodes)
|
| 59 |
+
|
| 60 |
+
def get_real_support(k):
|
| 61 |
+
imgs, acts = [], []
|
| 62 |
+
for _ in range(k):
|
| 63 |
+
ep = int(np.random.choice(list(support_pool_eps)))
|
| 64 |
+
s = int(m.episodes["dataset_from_index"][ep])
|
| 65 |
+
e = int(m.episodes["dataset_to_index"][ep])
|
| 66 |
+
idx = int(np.random.randint(s, max(s + 1, e - 1)))
|
| 67 |
+
im, act = img_at(idx, ep, s)
|
| 68 |
+
imgs.append(im)
|
| 69 |
+
acts.append(act)
|
| 70 |
+
return torch.stack(imgs), torch.stack(acts)
|
| 71 |
+
|
| 72 |
+
def get_wrong_support(k):
|
| 73 |
+
# random noise images + random actions — a garbage support set control
|
| 74 |
+
return torch.rand(k, 3, 256, 256), torch.randn(k, 50, cfg.max_action_dim) * 0.3
|
| 75 |
+
|
| 76 |
+
|
| 77 |
+
# control: demos from a DIFFERENT ROBOT (jaco) — if the model truly extracts
|
| 78 |
+
# robot-specific dynamics from exemplars, these should be worse than LeKiwi's own
|
| 79 |
+
def get_otherrobot_support(k):
|
| 80 |
+
from lerobot.datasets.lerobot_dataset import LeRobotDataset as _LD, LeRobotDatasetMetadata as _LM
|
| 81 |
+
from tinyvla.data.canonical import CanonicalChunkStore as _CS
|
| 82 |
+
jr = "/home/alexw/tinyvla_data/heldout/heldout_jaco_play"
|
| 83 |
+
jm = _LM("heldout_jaco_play", root=jr)
|
| 84 |
+
jds = _LD("heldout_jaco_play", root=jr, delta_timestamps={"action": [t / jm.fps for t in range(50)]}, video_backend="torchcodec")
|
| 85 |
+
jstore = _CS("heldout_jaco_play", src_fps=jm.fps, chunk=50)
|
| 86 |
+
jst = jstore.compute_stats(200)
|
| 87 |
+
jq01, jq99 = np.asarray(jst["q01"]), np.asarray(jst["q99"])
|
| 88 |
+
jimk = sorted(kk for kk in jds.meta.features if kk.startswith("observation.images"))[0]
|
| 89 |
+
imgs, acts = [], []
|
| 90 |
+
for _ in range(k):
|
| 91 |
+
ep = int(np.random.randint(0, 50))
|
| 92 |
+
s = int(jm.episodes["dataset_from_index"][ep]); e = int(jm.episodes["dataset_to_index"][ep])
|
| 93 |
+
idx = int(np.random.randint(s, max(s + 1, e - 1)))
|
| 94 |
+
it = jds[idx]
|
| 95 |
+
im = torch.nn.functional.interpolate(it[jimk][None], size=(256, 256), mode="bilinear")[0]
|
| 96 |
+
raw = quantile_normalize(jstore.chunk_for(ep, idx - s), jq01, jq99)
|
| 97 |
+
act = torch.nn.functional.pad(torch.from_numpy(raw[:, :7]).float(), (0, cfg.max_action_dim - 7))
|
| 98 |
+
imgs.append(im); acts.append(act)
|
| 99 |
+
return torch.stack(imgs), torch.stack(acts)
|
| 100 |
+
|
| 101 |
+
def run(support_fn, desc_text):
|
| 102 |
+
ids_t = tok([desc_text] if desc_text else [""], padding="max_length", truncation=True,
|
| 103 |
+
max_length=cfg.morph_text_max_len, return_tensors="pt")
|
| 104 |
+
errs = []
|
| 105 |
+
for ep in test:
|
| 106 |
+
s = int(m.episodes["dataset_from_index"][ep])
|
| 107 |
+
e = int(m.episodes["dataset_to_index"][ep])
|
| 108 |
+
for idx in range(s, e - 1, 30):
|
| 109 |
+
item = ds[idx]
|
| 110 |
+
task = item.get("task") or ""
|
| 111 |
+
t = tok([task], padding=True, truncation=True, max_length=48, return_tensors="pt")
|
| 112 |
+
img = torch.nn.functional.interpolate(item[prim][None], size=(256, 256), mode="bilinear")[0]
|
| 113 |
+
stt = torch.nn.functional.pad(item["observation.state"].float()[:6], (0, cfg.max_state_dim - 6))
|
| 114 |
+
sup_img, sup_act = support_fn(K)
|
| 115 |
+
b = {"observation.images.cam0": img[None].cuda(),
|
| 116 |
+
"observation.images.cam1": torch.zeros_like(img)[None].cuda(),
|
| 117 |
+
"observation.state": stt[None].cuda(),
|
| 118 |
+
"observation.language.tokens": t["input_ids"].cuda(),
|
| 119 |
+
"observation.language.attention_mask": t["attention_mask"].bool().cuda(),
|
| 120 |
+
"morph_text_ids": ids_t["input_ids"].cuda(),
|
| 121 |
+
"morph_text_mask": ids_t["attention_mask"].bool().cuda(),
|
| 122 |
+
"support_images": sup_img[None].cuda(), "support_actions": sup_act[None].cuda(),
|
| 123 |
+
"embodiment_id": torch.tensor([0]).cuda()}
|
| 124 |
+
with torch.autocast("cuda", torch.bfloat16):
|
| 125 |
+
pr = pol.predict_action_chunk(b)[0].cpu().float().numpy()
|
| 126 |
+
gu = quantile_normalize(store.chunk_for(ep, idx - s), q01, q99)[:, :7] * span / 2 + mid
|
| 127 |
+
pu = pr[:, :7] * span / 2 + mid
|
| 128 |
+
errs.append(np.linalg.norm(integ(pu)[-1] - integ(gu)[-1]) * 1000)
|
| 129 |
+
return np.mean(errs)
|
| 130 |
+
|
| 131 |
+
print("=== RICH-SLOW (demos in LM attention stream, no FT) on held-out LeKiwi ===")
|
| 132 |
+
print(f"REAL LeKiwi demos (K={K}) + desc=lekiwi endpoint {run(get_real_support, prompts['lekiwi']):.1f}mm")
|
| 133 |
+
print(f"REAL LeKiwi demos (K={K}) + desc=none endpoint {run(get_real_support, None):.1f}mm")
|
| 134 |
+
print(f"WRONG/garbage demos + desc=lekiwi endpoint {run(get_wrong_support, prompts['lekiwi']):.1f}mm")
|
| 135 |
+
print(f"WRONG/garbage demos + desc=none endpoint {run(get_wrong_support, None):.1f}mm")
|
| 136 |
+
print(f"OTHER-ROBOT (jaco) demos + desc=none endpoint {run(get_otherrobot_support, None):.1f}mm")
|
| 137 |
+
print("\nprior baselines: C-diverse 295mm | C-qwen-morph desc=none 294mm | v1 demo(same-task) real=290.6 garbage=288.5 (dead)")
|
| 138 |
+
|
| 139 |
+
|
| 140 |
+
if __name__ == "__main__":
|
| 141 |
+
main()
|
tinyvla2/scripts/audit_so101_fk.py
ADDED
|
@@ -0,0 +1,103 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env python
|
| 2 |
+
"""Gate 1: per-dataset SO101 FK calibration audit.
|
| 3 |
+
|
| 4 |
+
Same recorded degrees can map to different physical poses across lerobot
|
| 5 |
+
zero-conventions → FK garbage that would poison B/C canonical labels while
|
| 6 |
+
leaving A untouched (a confound AGAINST the hypothesis). Drop datasets whose
|
| 7 |
+
FK produces non-physical EE trajectories.
|
| 8 |
+
|
| 9 |
+
Checks per dataset (sampled frames across episodes):
|
| 10 |
+
- reach in [0.02, 0.40] m (SO101 max reach ~0.35)
|
| 11 |
+
- z above a floor (> -0.20 m; base frame origin at arm mount)
|
| 12 |
+
- trajectory smoothness (median consecutive EE step < 0.05 m at 30fps)
|
| 13 |
+
- FK(state) vs FK(action-target) diffs correlate (both go through FK, deltas
|
| 14 |
+
should track since action = commanded target of the same arm)
|
| 15 |
+
|
| 16 |
+
Writes ~/tinyvla_data/so101_fk_audit.json with per-dataset verdict.
|
| 17 |
+
"""
|
| 18 |
+
|
| 19 |
+
from __future__ import annotations
|
| 20 |
+
|
| 21 |
+
import json
|
| 22 |
+
from pathlib import Path
|
| 23 |
+
|
| 24 |
+
import numpy as np
|
| 25 |
+
|
| 26 |
+
DATA_ROOT = Path.home() / "tinyvla_data" / "so101_v3"
|
| 27 |
+
OUT = Path.home() / "tinyvla_data" / "so101_fk_audit.json"
|
| 28 |
+
|
| 29 |
+
|
| 30 |
+
def audit_one(name, root, fk, n_frames=200):
|
| 31 |
+
from lerobot.datasets.lerobot_dataset import LeRobotDataset
|
| 32 |
+
|
| 33 |
+
ds = LeRobotDataset(name, root=root)
|
| 34 |
+
anames = ds.meta.features["action"]["shape"][0]
|
| 35 |
+
if anames != 6:
|
| 36 |
+
return {"verdict": "SKIP", "reason": f"action dim {anames} != 6"}
|
| 37 |
+
# smoothness needs CONSECUTIVE frames → sample a few contiguous windows;
|
| 38 |
+
# reach/corr can use sparse knots across the whole dataset
|
| 39 |
+
n = len(ds)
|
| 40 |
+
eps = ds.meta.episodes
|
| 41 |
+
sparse = np.linspace(0, n - 1, min(n_frames, n)).astype(int)
|
| 42 |
+
pos_state, pos_act = [], []
|
| 43 |
+
for i in sparse:
|
| 44 |
+
item = ds[int(i)]
|
| 45 |
+
pos_state.append(fk.ee_pose(item["observation.state"].numpy())[:3, 3])
|
| 46 |
+
pos_act.append(fk.ee_pose(item["action"].numpy())[:3, 3])
|
| 47 |
+
ps = np.array(pos_state)
|
| 48 |
+
pa = np.array(pos_act)
|
| 49 |
+
reach = np.linalg.norm(ps, axis=1)
|
| 50 |
+
|
| 51 |
+
# consecutive-frame EE steps within the first episode (real per-frame motion)
|
| 52 |
+
e0, e1 = int(eps["dataset_from_index"][0]), int(eps["dataset_to_index"][0])
|
| 53 |
+
consec = []
|
| 54 |
+
prev = None
|
| 55 |
+
for i in range(e0, min(e1, e0 + 150)):
|
| 56 |
+
p = fk.ee_pose(ds[i]["observation.state"].numpy())[:3, 3]
|
| 57 |
+
if prev is not None:
|
| 58 |
+
consec.append(np.linalg.norm(p - prev))
|
| 59 |
+
prev = p
|
| 60 |
+
steps = np.array(consec) if consec else np.array([0.0])
|
| 61 |
+
# correlation of state-vs-target displacement over sampled knots
|
| 62 |
+
d_state = np.diff(ps, axis=0).flatten()
|
| 63 |
+
d_act = np.diff(pa, axis=0).flatten()
|
| 64 |
+
corr = float(np.corrcoef(d_state, d_act)[0, 1]) if d_state.std() > 1e-9 else 0.0
|
| 65 |
+
|
| 66 |
+
ok_reach = bool(0.02 < reach.mean() < 0.40 and reach.max() < 0.50)
|
| 67 |
+
ok_z = bool(ps[:, 2].min() > -0.20)
|
| 68 |
+
ok_smooth = bool(np.median(steps) < 0.06)
|
| 69 |
+
ok_corr = bool(corr > 0.5)
|
| 70 |
+
verdict = "KEEP" if (ok_reach and ok_z and ok_smooth and ok_corr) else "DROP"
|
| 71 |
+
return {
|
| 72 |
+
"verdict": verdict,
|
| 73 |
+
"reach_mean": round(float(reach.mean()), 3),
|
| 74 |
+
"reach_max": round(float(reach.max()), 3),
|
| 75 |
+
"z_min": round(float(ps[:, 2].min()), 3),
|
| 76 |
+
"step_median": round(float(np.median(steps)), 4),
|
| 77 |
+
"corr_state_target": round(corr, 3),
|
| 78 |
+
"flags": {"reach": ok_reach, "z": ok_z, "smooth": ok_smooth, "corr": ok_corr},
|
| 79 |
+
}
|
| 80 |
+
|
| 81 |
+
|
| 82 |
+
def main():
|
| 83 |
+
from tinyvla.data.kinematics_so101 import SO101FK
|
| 84 |
+
|
| 85 |
+
fk = SO101FK()
|
| 86 |
+
results = {}
|
| 87 |
+
roots = sorted(DATA_ROOT.iterdir())
|
| 88 |
+
for r in roots:
|
| 89 |
+
if not (r / "meta" / "info.json").exists():
|
| 90 |
+
continue
|
| 91 |
+
try:
|
| 92 |
+
res = audit_one(r.name, r, fk)
|
| 93 |
+
except Exception as e:
|
| 94 |
+
res = {"verdict": "ERROR", "reason": f"{type(e).__name__}: {str(e)[:120]}"}
|
| 95 |
+
results[r.name] = res
|
| 96 |
+
print(f"{res['verdict']:6} {r.name}: {res}")
|
| 97 |
+
OUT.write_text(json.dumps(results, indent=1))
|
| 98 |
+
keep = sum(1 for v in results.values() if v["verdict"] == "KEEP")
|
| 99 |
+
print(f"\nKEEP {keep}/{len(results)} -> {OUT}")
|
| 100 |
+
|
| 101 |
+
|
| 102 |
+
if __name__ == "__main__":
|
| 103 |
+
main()
|
tinyvla2/scripts/build_ee_sidecar.py
ADDED
|
@@ -0,0 +1,169 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env python
|
| 2 |
+
"""Build per-frame canonical EE-pose sidecars (offline, once).
|
| 3 |
+
|
| 4 |
+
For each frame stores the absolute end-effector pose implied by BOTH the
|
| 5 |
+
observation state and the action target, in the robot base frame:
|
| 6 |
+
cols: episode_index, frame_index,
|
| 7 |
+
s_px s_py s_pz s_qx s_qy s_qz s_qw (state EE pose)
|
| 8 |
+
a_px a_py a_pz a_qx a_qy a_qz a_qw (action-target EE pose)
|
| 9 |
+
grip (raw gripper channel, for q1-q99 later)
|
| 10 |
+
|
| 11 |
+
Canonical chunk deltas are assembled at train time from these poses (anchor,
|
| 12 |
+
frequency, rotation convention are all decided there — this file is convention-free).
|
| 13 |
+
|
| 14 |
+
Source kinds:
|
| 15 |
+
so101 : FK(joint_deg) for state and action (both are joint vectors).
|
| 16 |
+
ee : state/action already EE; reconstruct absolute pose. Bridge/LIBERO/DROID
|
| 17 |
+
store EE pose in observation.state; action is a delta → target = state ⊕ action.
|
| 18 |
+
(implemented per-source as adapters are verified.)
|
| 19 |
+
|
| 20 |
+
Usage:
|
| 21 |
+
python scripts/build_ee_sidecar.py --kind so101 --glob '~/tinyvla_data/so101_v3/*'
|
| 22 |
+
"""
|
| 23 |
+
|
| 24 |
+
from __future__ import annotations
|
| 25 |
+
|
| 26 |
+
import argparse
|
| 27 |
+
from pathlib import Path
|
| 28 |
+
|
| 29 |
+
import numpy as np
|
| 30 |
+
import pyarrow as pa
|
| 31 |
+
import pyarrow.parquet as pq
|
| 32 |
+
|
| 33 |
+
OUT_DIR = Path.home() / "tinyvla_data" / "ee_sidecar"
|
| 34 |
+
|
| 35 |
+
|
| 36 |
+
def _read_cols(name, root):
|
| 37 |
+
"""State/action/ep/frame columns WITHOUT video decode (raw parquet)."""
|
| 38 |
+
from lerobot.datasets.lerobot_dataset import LeRobotDataset
|
| 39 |
+
|
| 40 |
+
ds = LeRobotDataset(name, root=root)
|
| 41 |
+
hf = ds.reader.hf_dataset.with_format("numpy")
|
| 42 |
+
return (
|
| 43 |
+
np.asarray(hf["observation.state"], dtype=np.float64),
|
| 44 |
+
np.asarray(hf["action"], dtype=np.float64),
|
| 45 |
+
np.asarray(hf["episode_index"]).astype(int),
|
| 46 |
+
np.asarray(hf["frame_index"]).astype(int),
|
| 47 |
+
)
|
| 48 |
+
|
| 49 |
+
|
| 50 |
+
def build_so101(name, root, fk):
|
| 51 |
+
from scipy.spatial.transform import Rotation
|
| 52 |
+
|
| 53 |
+
state, action, ep, fr = _read_cols(name, root)
|
| 54 |
+
n = len(state)
|
| 55 |
+
cols = ["episode_index", "frame_index",
|
| 56 |
+
"s_px", "s_py", "s_pz", "s_qx", "s_qy", "s_qz", "s_qw",
|
| 57 |
+
"a_px", "a_py", "a_pz", "a_qx", "a_qy", "a_qz", "a_qw", "grip"]
|
| 58 |
+
buf = {k: np.empty(n, dtype=np.float64) for k in cols}
|
| 59 |
+
buf["episode_index"] = ep.astype(np.float64)
|
| 60 |
+
buf["frame_index"] = fr.astype(np.float64)
|
| 61 |
+
for i in range(n):
|
| 62 |
+
Ts = fk.ee_pose(state[i])
|
| 63 |
+
Ta = fk.ee_pose(action[i])
|
| 64 |
+
sp, sq = Ts[:3, 3], Rotation.from_matrix(Ts[:3, :3]).as_quat()
|
| 65 |
+
ap, aq = Ta[:3, 3], Rotation.from_matrix(Ta[:3, :3]).as_quat()
|
| 66 |
+
for j, k in enumerate(("s_px", "s_py", "s_pz")): buf[k][i] = sp[j]
|
| 67 |
+
for j, k in enumerate(("s_qx", "s_qy", "s_qz", "s_qw")): buf[k][i] = sq[j]
|
| 68 |
+
for j, k in enumerate(("a_px", "a_py", "a_pz")): buf[k][i] = ap[j]
|
| 69 |
+
for j, k in enumerate(("a_qx", "a_qy", "a_qz", "a_qw")): buf[k][i] = aq[j]
|
| 70 |
+
buf["grip"][i] = action[i, 5]
|
| 71 |
+
return pa.table(buf)
|
| 72 |
+
|
| 73 |
+
|
| 74 |
+
def build_ee_from_state(name, root):
|
| 75 |
+
"""EE-native sources (Bridge, RT-1): state carries absolute EE pose.
|
| 76 |
+
|
| 77 |
+
Bridge state = [x y z roll pitch yaw pad gripper]; RT-1 state =
|
| 78 |
+
[x y z rx ry rz rw gripper] (quat). We store the STATE pose as canonical
|
| 79 |
+
absolute pose (both s_* and a_* set to state pose; targets reconstructed at
|
| 80 |
+
train time as state ⊕ action-delta if needed, but state-derived deltas are
|
| 81 |
+
the uniform choice per plan → a_* == next-frame not needed here).
|
| 82 |
+
"""
|
| 83 |
+
from lerobot.datasets.lerobot_dataset import LeRobotDataset
|
| 84 |
+
from scipy.spatial.transform import Rotation
|
| 85 |
+
|
| 86 |
+
ds = LeRobotDataset(name, root=root)
|
| 87 |
+
snames = ds.meta.features["observation.state"].get("names", {})
|
| 88 |
+
flat = snames.get("motors", snames) if isinstance(snames, dict) else snames
|
| 89 |
+
state, _, ep, fr = _read_cols(name, root)
|
| 90 |
+
n = len(state)
|
| 91 |
+
# RoboCasa/PandaOmron: state = base_pos(3) base_quat(4) ee_pos(3) ee_quat(4) grip(2)
|
| 92 |
+
# -> the EE block is not at the front, slice it out first
|
| 93 |
+
if state.shape[1] == 16:
|
| 94 |
+
state = np.concatenate([state[:, 7:14], state[:, 14:15]], axis=1) # pos,quat,grip
|
| 95 |
+
# detect quaternion: named "rw", or 8-dim state whose dims 3:7 are unit-norm
|
| 96 |
+
is_quat = ("rw" in flat) or (
|
| 97 |
+
state.shape[1] >= 8 and abs(np.linalg.norm(state[:200, 3:7], axis=1).mean() - 1.0) < 1e-2
|
| 98 |
+
)
|
| 99 |
+
cols = ["episode_index", "frame_index",
|
| 100 |
+
"s_px", "s_py", "s_pz", "s_qx", "s_qy", "s_qz", "s_qw",
|
| 101 |
+
"a_px", "a_py", "a_pz", "a_qx", "a_qy", "a_qz", "a_qw", "grip"]
|
| 102 |
+
buf = {k: np.empty(n, dtype=np.float64) for k in cols}
|
| 103 |
+
buf["episode_index"] = ep.astype(np.float64)
|
| 104 |
+
buf["frame_index"] = fr.astype(np.float64)
|
| 105 |
+
pos = state[:, :3]
|
| 106 |
+
if is_quat: # [x y z rx ry rz rw gripper]
|
| 107 |
+
quat = state[:, 3:7]
|
| 108 |
+
grip = state[:, 7]
|
| 109 |
+
else: # [x y z roll pitch yaw (pad) (gripper)]
|
| 110 |
+
quat = Rotation.from_euler("xyz", state[:, 3:6]).as_quat()
|
| 111 |
+
grip = state[:, 7] if state.shape[1] > 7 else np.zeros(n) # free-body (UAV): no gripper
|
| 112 |
+
for j, k in enumerate(("s_px", "s_py", "s_pz")): buf[k] = pos[:, j]
|
| 113 |
+
for j, k in enumerate(("s_qx", "s_qy", "s_qz", "s_qw")): buf[k] = quat[:, j]
|
| 114 |
+
for j, k in enumerate(("a_px", "a_py", "a_pz")): buf[k] = pos[:, j]
|
| 115 |
+
for j, k in enumerate(("a_qx", "a_qy", "a_qz", "a_qw")): buf[k] = quat[:, j]
|
| 116 |
+
buf["grip"] = grip
|
| 117 |
+
return pa.table(buf)
|
| 118 |
+
|
| 119 |
+
|
| 120 |
+
def main():
|
| 121 |
+
parser = argparse.ArgumentParser()
|
| 122 |
+
parser.add_argument("--kind", choices=["so101", "ee"], required=True)
|
| 123 |
+
parser.add_argument("--glob", required=True)
|
| 124 |
+
parser.add_argument("--audit", default=str(Path.home() / "tinyvla_data/so101_fk_audit.json"),
|
| 125 |
+
help="skip datasets not marked KEEP")
|
| 126 |
+
args = parser.parse_args()
|
| 127 |
+
|
| 128 |
+
import glob as _glob
|
| 129 |
+
import json
|
| 130 |
+
|
| 131 |
+
OUT_DIR.mkdir(parents=True, exist_ok=True)
|
| 132 |
+
keep = None
|
| 133 |
+
audit_path = Path(args.audit).expanduser()
|
| 134 |
+
if args.kind == "so101" and audit_path.exists():
|
| 135 |
+
audit = json.loads(audit_path.read_text())
|
| 136 |
+
keep = {k for k, v in audit.items() if v.get("verdict") == "KEEP"}
|
| 137 |
+
|
| 138 |
+
fk = None
|
| 139 |
+
if args.kind == "so101":
|
| 140 |
+
from tinyvla.data.kinematics_so101 import SO101FK
|
| 141 |
+
fk = SO101FK()
|
| 142 |
+
|
| 143 |
+
roots = sorted(Path(p) for p in _glob.glob(str(Path(args.glob).expanduser())))
|
| 144 |
+
done = 0
|
| 145 |
+
for r in roots:
|
| 146 |
+
if not (r / "meta" / "info.json").exists():
|
| 147 |
+
continue
|
| 148 |
+
if keep is not None and r.name not in keep:
|
| 149 |
+
print(f"skip {r.name} (not KEEP)")
|
| 150 |
+
continue
|
| 151 |
+
out = OUT_DIR / f"{r.name}.parquet"
|
| 152 |
+
if out.exists():
|
| 153 |
+
done += 1
|
| 154 |
+
continue
|
| 155 |
+
try:
|
| 156 |
+
if args.kind == "so101":
|
| 157 |
+
tbl = build_so101(r.name, r, fk)
|
| 158 |
+
else:
|
| 159 |
+
tbl = build_ee_from_state(r.name, r)
|
| 160 |
+
pq.write_table(tbl, out)
|
| 161 |
+
done += 1
|
| 162 |
+
print(f"[{done}] {r.name}: {tbl.num_rows} frames -> {out}")
|
| 163 |
+
except Exception as e:
|
| 164 |
+
print(f"FAIL {r.name}: {type(e).__name__}: {str(e)[:150]}")
|
| 165 |
+
print(f"done {done}")
|
| 166 |
+
|
| 167 |
+
|
| 168 |
+
if __name__ == "__main__":
|
| 169 |
+
main()
|
tinyvla2/scripts/diag_obs_gap.py
ADDED
|
@@ -0,0 +1,131 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env python
|
| 2 |
+
"""Diagnose the env-obs adapter: compare policy predictions from env-rendered
|
| 3 |
+
observations vs dataset observations at the SAME init state.
|
| 4 |
+
|
| 5 |
+
If pred(dataset obs) is close to GT but pred(env obs) differs, the observation
|
| 6 |
+
adapter (image orientation/cameras/state) is the remaining gap.
|
| 7 |
+
"""
|
| 8 |
+
|
| 9 |
+
from __future__ import annotations
|
| 10 |
+
|
| 11 |
+
import argparse
|
| 12 |
+
|
| 13 |
+
import numpy as np
|
| 14 |
+
import torch
|
| 15 |
+
from scipy.spatial.transform import Rotation
|
| 16 |
+
|
| 17 |
+
|
| 18 |
+
@torch.no_grad()
|
| 19 |
+
def main():
|
| 20 |
+
parser = argparse.ArgumentParser()
|
| 21 |
+
parser.add_argument("--checkpoint", default="outputs/libero_ft2/step_15000")
|
| 22 |
+
parser.add_argument("--suite", default="libero_spatial")
|
| 23 |
+
parser.add_argument("--tasks", type=int, default=3)
|
| 24 |
+
args = parser.parse_args()
|
| 25 |
+
|
| 26 |
+
from lerobot.datasets.lerobot_dataset import LeRobotDataset, LeRobotDatasetMetadata
|
| 27 |
+
from lerobot.envs.factory import make_env, make_env_config
|
| 28 |
+
from transformers import AutoTokenizer
|
| 29 |
+
from tinyvla.data.mixture import CanonicalSource
|
| 30 |
+
from tinyvla.modeling_tinyvla import TinyVLAPolicy
|
| 31 |
+
|
| 32 |
+
policy = TinyVLAPolicy.from_pretrained(args.checkpoint).cuda().eval()
|
| 33 |
+
cfg = policy.config
|
| 34 |
+
tok = AutoTokenizer.from_pretrained(cfg.lm_model_name)
|
| 35 |
+
|
| 36 |
+
meta = LeRobotDatasetMetadata("HuggingFaceVLA/libero")
|
| 37 |
+
ds = LeRobotDataset(
|
| 38 |
+
"HuggingFaceVLA/libero",
|
| 39 |
+
delta_timestamps={"action": [t / meta.fps for t in range(cfg.chunk_size)]},
|
| 40 |
+
video_backend="torchcodec",
|
| 41 |
+
)
|
| 42 |
+
src = CanonicalSource(ds, 2, cfg.image_size, cfg.max_state_dim, cfg.max_action_dim)
|
| 43 |
+
s_stats = meta.stats["observation.state"]
|
| 44 |
+
s_mean = torch.as_tensor(s_stats["mean"]).flatten().float()
|
| 45 |
+
s_std = torch.as_tensor(s_stats["std"]).flatten().float().clamp(min=1e-6)
|
| 46 |
+
|
| 47 |
+
env_cfg = make_env_config("libero", task=args.suite)
|
| 48 |
+
task_envs = make_env(env_cfg, n_envs=1)[args.suite]
|
| 49 |
+
env_by_task = {}
|
| 50 |
+
for tid, env in task_envs.items():
|
| 51 |
+
desc = env.get_attr("task_description")[0]
|
| 52 |
+
env_by_task[desc.strip().lower()] = (tid, env)
|
| 53 |
+
|
| 54 |
+
eps_meta = ds.meta.episodes
|
| 55 |
+
first_ep_by_task = {}
|
| 56 |
+
for ep in range(ds.num_episodes):
|
| 57 |
+
start = int(eps_meta["dataset_from_index"][ep])
|
| 58 |
+
task = ds[start]["task"].strip().lower()
|
| 59 |
+
if task in env_by_task and task not in first_ep_by_task:
|
| 60 |
+
first_ep_by_task[task] = ep
|
| 61 |
+
|
| 62 |
+
def tok_batch(task_text):
|
| 63 |
+
t = tok([task_text], padding=True, truncation=True,
|
| 64 |
+
max_length=cfg.tokenizer_max_length, return_tensors="pt")
|
| 65 |
+
return t["input_ids"].cuda(), t["attention_mask"].bool().cuda()
|
| 66 |
+
|
| 67 |
+
def env_to_batch(obs, task_text):
|
| 68 |
+
imgs = {}
|
| 69 |
+
for slot, key in (("cam0", "image"), ("cam1", "image2")):
|
| 70 |
+
x = torch.as_tensor(np.asarray(obs["pixels"][key]))[0].flip(0).flip(1)
|
| 71 |
+
x = x.permute(2, 0, 1).float() / 255.0
|
| 72 |
+
x = torch.nn.functional.interpolate(x[None], size=(cfg.image_size, cfg.image_size),
|
| 73 |
+
mode="bilinear", align_corners=False)[0]
|
| 74 |
+
imgs[slot] = x
|
| 75 |
+
rs = obs["robot_state"]
|
| 76 |
+
pos = np.asarray(rs["eef"]["pos"]).flatten()
|
| 77 |
+
quat = np.asarray(rs["eef"]["quat"]).flatten()
|
| 78 |
+
rotvec = Rotation.from_quat(quat).as_rotvec()
|
| 79 |
+
if rotvec[0] < 0:
|
| 80 |
+
th = np.linalg.norm(rotvec)
|
| 81 |
+
rotvec = rotvec * (th - 2 * np.pi) / th
|
| 82 |
+
grip = np.asarray(rs["gripper"]["qpos"]).flatten()
|
| 83 |
+
state = torch.tensor(np.concatenate([pos, rotvec, grip]), dtype=torch.float32)
|
| 84 |
+
state = (state - s_mean) / s_std
|
| 85 |
+
state = torch.nn.functional.pad(state, (0, cfg.max_state_dim - state.shape[-1]))
|
| 86 |
+
ids, mask = tok_batch(task_text)
|
| 87 |
+
return {
|
| 88 |
+
"observation.images.cam0": imgs["cam0"][None].cuda(),
|
| 89 |
+
"observation.images.cam1": imgs["cam1"][None].cuda(),
|
| 90 |
+
"observation.state": state[None].cuda(),
|
| 91 |
+
"observation.language.tokens": ids,
|
| 92 |
+
"observation.language.attention_mask": mask,
|
| 93 |
+
"embodiment_id": torch.tensor([2], device="cuda"),
|
| 94 |
+
}
|
| 95 |
+
|
| 96 |
+
def ds_to_batch(item):
|
| 97 |
+
ids, mask = tok_batch(item.pop("task"))
|
| 98 |
+
b = {k: v[None].cuda() for k, v in item.items() if torch.is_tensor(v)}
|
| 99 |
+
b["observation.language.tokens"] = ids
|
| 100 |
+
b["observation.language.attention_mask"] = mask
|
| 101 |
+
return b
|
| 102 |
+
|
| 103 |
+
for task, ep in list(first_ep_by_task.items())[: args.tasks]:
|
| 104 |
+
tid, env = env_by_task[task]
|
| 105 |
+
obs, _ = env.reset(seed=0)
|
| 106 |
+
start = int(eps_meta["dataset_from_index"][ep])
|
| 107 |
+
item = src[start]
|
| 108 |
+
gt = item["action"].clone()[None].cuda()
|
| 109 |
+
|
| 110 |
+
env_b = env_to_batch(obs, task)
|
| 111 |
+
ds_b = ds_to_batch(dict(item))
|
| 112 |
+
|
| 113 |
+
torch.manual_seed(0)
|
| 114 |
+
pred_env = policy.predict_action_chunk(env_b)
|
| 115 |
+
torch.manual_seed(0)
|
| 116 |
+
pred_ds = policy.predict_action_chunk(ds_b)
|
| 117 |
+
|
| 118 |
+
m = item["action_dim_mask"]
|
| 119 |
+
d_env_gt = ((pred_env[0, :, m].cpu() - gt[0, :, m].cpu()) ** 2).mean().sqrt().item()
|
| 120 |
+
d_ds_gt = ((pred_ds[0, :, m].cpu() - gt[0, :, m].cpu()) ** 2).mean().sqrt().item()
|
| 121 |
+
d_env_ds = ((pred_env[0, :, m] - pred_ds[0, :, m]) ** 2).mean().sqrt().item()
|
| 122 |
+
|
| 123 |
+
# also compare the raw inputs
|
| 124 |
+
img_gap = (env_b["observation.images.cam0"] - ds_b["observation.images.cam0"]).abs().mean().item()
|
| 125 |
+
st_gap = (env_b["observation.state"] - ds_b["observation.state"]).abs().max().item()
|
| 126 |
+
print(f"task {tid}: RMSE(pred_env, GT)={d_env_gt:.3f} | RMSE(pred_ds, GT)={d_ds_gt:.3f} "
|
| 127 |
+
f"| RMSE(pred_env, pred_ds)={d_env_ds:.3f} | img L1 gap={img_gap:.4f} | state max gap={st_gap:.2f}")
|
| 128 |
+
|
| 129 |
+
|
| 130 |
+
if __name__ == "__main__":
|
| 131 |
+
main()
|
tinyvla2/scripts/download_subsets.py
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env python
|
| 2 |
+
"""Download Stage-2 dataset subsets under a hard disk budget.
|
| 3 |
+
|
| 4 |
+
Usage:
|
| 5 |
+
python scripts/download_subsets.py --root ~/tinyvla_data [--dry-run]
|
| 6 |
+
|
| 7 |
+
Downloads metadata first, measures actual on-disk size of a small episode
|
| 8 |
+
sample, then extrapolates before committing to the full subset download.
|
| 9 |
+
"""
|
| 10 |
+
|
| 11 |
+
from __future__ import annotations
|
| 12 |
+
|
| 13 |
+
import argparse
|
| 14 |
+
import shutil
|
| 15 |
+
from pathlib import Path
|
| 16 |
+
|
| 17 |
+
DISK_BUDGET_GB = 400
|
| 18 |
+
|
| 19 |
+
# (repo_id, num_episodes or None for all)
|
| 20 |
+
SUBSETS = [
|
| 21 |
+
("HuggingFaceVLA/community_dataset_v1", None),
|
| 22 |
+
("nvidia/BridgeData2_LeRobot_v3", 10_000),
|
| 23 |
+
("IPEC-COMMUNITY/fractal20220817_data_lerobot", 8_000),
|
| 24 |
+
]
|
| 25 |
+
|
| 26 |
+
|
| 27 |
+
def free_gb(path: Path) -> float:
|
| 28 |
+
return shutil.disk_usage(path).free / 1e9
|
| 29 |
+
|
| 30 |
+
|
| 31 |
+
def used_gb(path: Path) -> float:
|
| 32 |
+
return sum(f.stat().st_size for f in path.rglob("*") if f.is_file()) / 1e9
|
| 33 |
+
|
| 34 |
+
|
| 35 |
+
def main():
|
| 36 |
+
parser = argparse.ArgumentParser()
|
| 37 |
+
parser.add_argument("--root", type=Path, default=Path.home() / "tinyvla_data")
|
| 38 |
+
parser.add_argument("--dry-run", action="store_true")
|
| 39 |
+
parser.add_argument("--only", type=str, default=None, help="substring filter on repo_id")
|
| 40 |
+
args = parser.parse_args()
|
| 41 |
+
|
| 42 |
+
args.root.mkdir(parents=True, exist_ok=True)
|
| 43 |
+
|
| 44 |
+
from lerobot.datasets.lerobot_dataset import LeRobotDataset, LeRobotDatasetMetadata
|
| 45 |
+
|
| 46 |
+
for repo_id, n_eps in SUBSETS:
|
| 47 |
+
if args.only and args.only not in repo_id:
|
| 48 |
+
continue
|
| 49 |
+
print(f"\n=== {repo_id} (episodes: {n_eps or 'all'}) ===")
|
| 50 |
+
meta = LeRobotDatasetMetadata(repo_id)
|
| 51 |
+
total_eps = meta.total_episodes
|
| 52 |
+
print(f"total episodes: {total_eps}, fps: {meta.fps}")
|
| 53 |
+
|
| 54 |
+
episodes = list(range(min(n_eps, total_eps))) if n_eps else None
|
| 55 |
+
|
| 56 |
+
# probe with 1% to estimate size
|
| 57 |
+
probe_n = max(10, (len(episodes) if episodes else total_eps) // 100)
|
| 58 |
+
probe_dir = args.root / "_probe" / repo_id.replace("/", "__")
|
| 59 |
+
if not args.dry_run and not probe_dir.exists():
|
| 60 |
+
LeRobotDataset(repo_id, root=probe_dir, episodes=list(range(probe_n)))
|
| 61 |
+
probe_gb = used_gb(probe_dir)
|
| 62 |
+
est_gb = probe_gb / probe_n * (len(episodes) if episodes else total_eps)
|
| 63 |
+
print(f"probe: {probe_n} eps = {probe_gb:.2f}GB -> estimated full subset {est_gb:.0f}GB")
|
| 64 |
+
if est_gb > free_gb(args.root) - 100 or used_gb(args.root) + est_gb > DISK_BUDGET_GB:
|
| 65 |
+
print(f"SKIP {repo_id}: would exceed budget ({DISK_BUDGET_GB}GB) or disk")
|
| 66 |
+
continue
|
| 67 |
+
|
| 68 |
+
if args.dry_run:
|
| 69 |
+
continue
|
| 70 |
+
|
| 71 |
+
target = args.root / repo_id.replace("/", "__")
|
| 72 |
+
LeRobotDataset(repo_id, root=target, episodes=episodes)
|
| 73 |
+
print(f"downloaded {repo_id}: {used_gb(target):.1f}GB, total used {used_gb(args.root):.1f}GB")
|
| 74 |
+
|
| 75 |
+
|
| 76 |
+
if __name__ == "__main__":
|
| 77 |
+
main()
|
tinyvla2/scripts/eval_canonical.py
ADDED
|
@@ -0,0 +1,186 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env python
|
| 2 |
+
"""Physical-space canonical-action eval (variants A/B/C, TinyVLA-2 headline metric).
|
| 3 |
+
|
| 4 |
+
Compares A/B/C in ONE fair space: canonical base-frame EE deltas, unnormalized to
|
| 5 |
+
physical units — position error (mm), rotation error (deg), gripper error ([0,1]).
|
| 6 |
+
|
| 7 |
+
- B/C predict canonical directly → unnormalize with dataset canonical stats.
|
| 8 |
+
- A predicts NATIVE actions → for SO101 map joint predictions through FK to EE deltas;
|
| 9 |
+
for EE-native sources A's native deltas are already comparable (convention aside).
|
| 10 |
+
- Held-out embodiment: A/B have no ID row → oracle over trained IDs (best), making any
|
| 11 |
+
C win conservative. C uses the written descriptor (zero-shot by construction).
|
| 12 |
+
|
| 13 |
+
Usage:
|
| 14 |
+
python scripts/eval_canonical.py --checkpoint outputs/tv2_C_morph_canon/final \
|
| 15 |
+
--dataset heldout_jaco_play --root ~/tinyvla_data/heldout/heldout_jaco_play \
|
| 16 |
+
--morph-key jaco --episodes 20
|
| 17 |
+
"""
|
| 18 |
+
|
| 19 |
+
from __future__ import annotations
|
| 20 |
+
|
| 21 |
+
import argparse
|
| 22 |
+
from pathlib import Path
|
| 23 |
+
|
| 24 |
+
import numpy as np
|
| 25 |
+
import torch
|
| 26 |
+
|
| 27 |
+
|
| 28 |
+
@torch.no_grad()
|
| 29 |
+
def main():
|
| 30 |
+
ap = argparse.ArgumentParser()
|
| 31 |
+
ap.add_argument("--checkpoint", type=Path, required=True)
|
| 32 |
+
ap.add_argument("--dataset", required=True)
|
| 33 |
+
ap.add_argument("--root", required=True)
|
| 34 |
+
ap.add_argument("--morph-key", default=None, help="descriptor key for variant C zero-shot")
|
| 35 |
+
ap.add_argument("--oracle-ids", type=int, default=8, help="A/B: try IDs 0..N-1, report best")
|
| 36 |
+
ap.add_argument("--episodes", type=int, default=20)
|
| 37 |
+
ap.add_argument("--ep-start", type=int, default=0, help="first episode index (few-shot: eval on held-out test split after FT episodes)")
|
| 38 |
+
ap.add_argument("--stride", type=int, default=30)
|
| 39 |
+
args = ap.parse_args()
|
| 40 |
+
|
| 41 |
+
import yaml
|
| 42 |
+
from lerobot.datasets.lerobot_dataset import LeRobotDataset, LeRobotDatasetMetadata
|
| 43 |
+
from scipy.spatial.transform import Rotation
|
| 44 |
+
from transformers import AutoTokenizer
|
| 45 |
+
|
| 46 |
+
from tinyvla.data.canonical import CanonicalChunkStore, quantile_normalize
|
| 47 |
+
from tinyvla.modeling_tinyvla import TinyVLAPolicy
|
| 48 |
+
from tinyvla.modules.embodiment import MORPH_FIELDS
|
| 49 |
+
|
| 50 |
+
policy = TinyVLAPolicy.from_pretrained(args.checkpoint).cuda().eval()
|
| 51 |
+
cfg = policy.config
|
| 52 |
+
tok = AutoTokenizer.from_pretrained(cfg.lm_model_name)
|
| 53 |
+
chunk = cfg.chunk_size
|
| 54 |
+
|
| 55 |
+
meta = LeRobotDatasetMetadata(args.dataset, root=args.root)
|
| 56 |
+
ds = LeRobotDataset(args.dataset, root=args.root,
|
| 57 |
+
delta_timestamps={"action": [t / meta.fps for t in range(chunk)]},
|
| 58 |
+
video_backend="torchcodec")
|
| 59 |
+
store = CanonicalChunkStore(args.dataset, src_fps=ds.fps, chunk=chunk)
|
| 60 |
+
stats = store.compute_stats()
|
| 61 |
+
q01, q99 = np.asarray(stats["q01"]), np.asarray(stats["q99"])
|
| 62 |
+
|
| 63 |
+
# morphology descriptor (variant C)
|
| 64 |
+
morph = None
|
| 65 |
+
if cfg.conditioning == "morph" and args.morph_key:
|
| 66 |
+
raw = yaml.safe_load(open("configs/morphology/descriptors.yaml"))[args.morph_key]
|
| 67 |
+
_sc = {"arm_dof": 0.1, "reach_m": 2, "gripper_width_m": 10, "num_cameras": 1 / 3,
|
| 68 |
+
"control_hz": 1 / 30, "joint_lo_mean": 1 / 3.1416, "joint_hi_mean": 1 / 3.1416,
|
| 69 |
+
"workspace_x": 2, "workspace_y": 2, "workspace_z": 2, "payload_kg": 0.2}
|
| 70 |
+
morph = torch.tensor([raw.get(f, 0) * _sc.get(f, 1) for f in MORPH_FIELDS],
|
| 71 |
+
dtype=torch.float32)
|
| 72 |
+
|
| 73 |
+
image_keys = sorted(k for k in ds.meta.features if k.startswith("observation.images"))
|
| 74 |
+
|
| 75 |
+
def to_batch(item, emb_id, morph_vec):
|
| 76 |
+
import re
|
| 77 |
+
from tinyvla.data.mixture import PRIMARY_RE, WRIST_RE
|
| 78 |
+
prim = next((k for k in image_keys if PRIMARY_RE.search(k)), image_keys[0])
|
| 79 |
+
wr = next((k for k in image_keys if k != prim and WRIST_RE.search(k)), None)
|
| 80 |
+
|
| 81 |
+
def img(x):
|
| 82 |
+
if x.shape[-2:] != (cfg.image_size, cfg.image_size):
|
| 83 |
+
x = torch.nn.functional.interpolate(x[None], size=(cfg.image_size, cfg.image_size),
|
| 84 |
+
mode="bilinear", align_corners=False)[0]
|
| 85 |
+
return x
|
| 86 |
+
cam0 = img(item[prim])
|
| 87 |
+
cam1 = img(item[wr]) if wr else torch.zeros_like(cam0)
|
| 88 |
+
state = item["observation.state"].float()
|
| 89 |
+
state = torch.nn.functional.pad(state, (0, cfg.max_state_dim - state.shape[-1]))
|
| 90 |
+
t = tok([item.get("task") or ""], padding=True, truncation=True,
|
| 91 |
+
max_length=cfg.tokenizer_max_length, return_tensors="pt")
|
| 92 |
+
b = {"observation.images.cam0": cam0[None].cuda(),
|
| 93 |
+
"observation.images.cam1": cam1[None].cuda(),
|
| 94 |
+
"observation.state": state[None].cuda(),
|
| 95 |
+
"observation.language.tokens": t["input_ids"].cuda(),
|
| 96 |
+
"observation.language.attention_mask": t["attention_mask"].bool().cuda(),
|
| 97 |
+
"embodiment_id": torch.tensor([emb_id], device="cuda")}
|
| 98 |
+
if morph_vec is not None:
|
| 99 |
+
b["morphology"] = morph_vec[None].cuda()
|
| 100 |
+
return b
|
| 101 |
+
|
| 102 |
+
# native action stats (for variant A unnormalization) — physical EE deltas
|
| 103 |
+
native_stats = ds.meta.stats.get("action", {})
|
| 104 |
+
nat_mean = np.asarray(native_stats.get("mean", np.zeros(7)))
|
| 105 |
+
nat_std = np.asarray(native_stats.get("std", np.ones(7)))
|
| 106 |
+
is_native = cfg.action_space == "native"
|
| 107 |
+
|
| 108 |
+
def _unnorm_canon(x):
|
| 109 |
+
span = np.maximum(q99 - q01, 0.01 * np.median(np.abs(np.concatenate([q01, q99])) + 1e-6))
|
| 110 |
+
mid = 0.5 * (q01 + q99)
|
| 111 |
+
return x[:, :7] * span / 2 + mid
|
| 112 |
+
|
| 113 |
+
def _integrate(deltas):
|
| 114 |
+
"""(T,6+) physical per-step EE deltas -> (T,3) cumulative positions,
|
| 115 |
+
list of cumulative rotations. Amplifies per-step differences into a
|
| 116 |
+
trajectory with real dynamic range (per-step motion is tiny)."""
|
| 117 |
+
pos = np.cumsum(deltas[:, :3], axis=0)
|
| 118 |
+
R = Rotation.identity()
|
| 119 |
+
rots = []
|
| 120 |
+
for k in range(len(deltas)):
|
| 121 |
+
R = Rotation.from_rotvec(deltas[k, 3:6]) * R
|
| 122 |
+
rots.append(R)
|
| 123 |
+
return pos, rots
|
| 124 |
+
|
| 125 |
+
def canonical_phys_err(pred_norm, gt_canon):
|
| 126 |
+
"""Integrated-trajectory error (the per-step delta floor ~3.6mm has no
|
| 127 |
+
dynamic range — see control). Returns:
|
| 128 |
+
ep_mm : endpoint position error over the 5s chunk (mm)
|
| 129 |
+
path_mm: mean cumulative-position error along the chunk (mm)
|
| 130 |
+
ep_deg : endpoint cumulative-rotation error (deg)
|
| 131 |
+
"""
|
| 132 |
+
gu = _unnorm_canon(gt_canon)
|
| 133 |
+
if is_native:
|
| 134 |
+
d = pred_norm.shape[-1]
|
| 135 |
+
pu = pred_norm[:, : min(d, 7)] * nat_std[: min(d, 7)] + nat_mean[: min(d, 7)]
|
| 136 |
+
if pu.shape[-1] < 7:
|
| 137 |
+
pu = np.concatenate([pu, gu[:, pu.shape[-1]:7]], axis=1)
|
| 138 |
+
else:
|
| 139 |
+
pu = _unnorm_canon(pred_norm)
|
| 140 |
+
gp, gr = _integrate(gu)
|
| 141 |
+
pp, pr = _integrate(pu)
|
| 142 |
+
ep_mm = np.linalg.norm(pp[-1] - gp[-1]) * 1000
|
| 143 |
+
path_mm = np.linalg.norm(pp - gp, axis=1).mean() * 1000
|
| 144 |
+
ep_deg = np.degrees((pr[-1] * gr[-1].inv()).magnitude())
|
| 145 |
+
return ep_mm, path_mm, ep_deg
|
| 146 |
+
pos_mm = np.linalg.norm(pu[:, :3] - gu[:, :3], axis=1).mean() * 1000
|
| 147 |
+
# rotation error: geodesic between rotvec deltas
|
| 148 |
+
rp = Rotation.from_rotvec(pu[:, 3:6])
|
| 149 |
+
rg = Rotation.from_rotvec(gu[:, 3:6])
|
| 150 |
+
rot_deg = np.degrees((rp * rg.inv()).magnitude()).mean()
|
| 151 |
+
grip = np.abs(pu[:, 6] - gu[:, 6]).mean()
|
| 152 |
+
return pos_mm, rot_deg, grip
|
| 153 |
+
|
| 154 |
+
eps = list(range(args.ep_start, min(args.ep_start + args.episodes, ds.num_episodes)))
|
| 155 |
+
# candidate embodiment conditionings
|
| 156 |
+
if cfg.conditioning == "morph":
|
| 157 |
+
candidates = [("morph", morph)]
|
| 158 |
+
else:
|
| 159 |
+
candidates = [(f"id{i}", i) for i in range(args.oracle_ids)]
|
| 160 |
+
|
| 161 |
+
best = None
|
| 162 |
+
for label, cand in candidates:
|
| 163 |
+
errs = []
|
| 164 |
+
for ep in eps:
|
| 165 |
+
start = int(ds.meta.episodes["dataset_from_index"][ep])
|
| 166 |
+
end = int(ds.meta.episodes["dataset_to_index"][ep])
|
| 167 |
+
for idx in range(start, end - 1, args.stride):
|
| 168 |
+
gt = quantile_normalize(store.chunk_for(ep, idx - start), q01, q99)
|
| 169 |
+
if cfg.conditioning == "morph":
|
| 170 |
+
b = to_batch(ds[idx], 0, cand)
|
| 171 |
+
else:
|
| 172 |
+
b = to_batch(ds[idx], cand, None)
|
| 173 |
+
pred = policy.predict_action_chunk(b)[0].cpu().numpy()
|
| 174 |
+
errs.append(canonical_phys_err(pred, gt))
|
| 175 |
+
errs = np.array(errs)
|
| 176 |
+
m = errs.mean(0)
|
| 177 |
+
if best is None or m[0] < best[1][0]:
|
| 178 |
+
best = (label, m)
|
| 179 |
+
print(f" {label}: endpoint {m[0]:.1f}mm path {m[1]:.1f}mm rot {m[2]:.1f}deg")
|
| 180 |
+
|
| 181 |
+
print(f"\n=== {args.dataset} | {args.checkpoint.name} | cond={cfg.conditioning} ===")
|
| 182 |
+
print(f"BEST ({best[0]}): endpoint {best[1][0]:.1f}mm path {best[1][1]:.1f}mm rot {best[1][2]:.1f}deg")
|
| 183 |
+
|
| 184 |
+
|
| 185 |
+
if __name__ == "__main__":
|
| 186 |
+
main()
|