tactile-act-screw-baselines / UPDATE_GUIDE.md
AllenBi21's picture
Reference inference stack + validated live_features.py + UPDATE_GUIDE for target-machine merge
121869d verified
|
Raw History Blame Contribute Delete
4.12 kB
# For the Claude on the target workstation — updating your inference code
`written: 2026-08-11` · applies to the bundle in
`hf.co/AllenBi21/tactile-act-screw-baselines`
This repo contains the **reference inference stack** the `screw_t3_50k` /
`screw_sitr5_50k` checkpoints were validated with: `inference.py`,
`act_policy/`, `data/dataset.py`, `tools/live_features.py`. Your local
inference code is known to have drifted slightly. **Update yours against this
reference — do not wholesale-replace it** (your local robot-IO, rate control,
logging, and device plumbing should survive), with one exception noted in §3.
## 1. Procedure
1. Download: `hf download AllenBi21/tactile-act-screw-baselines --local-dir ref`
2. Diff `ref/inference.py` and `ref/act_policy/` against your local versions.
3. Port every difference that touches the load-bearing contract (§2) from the
reference into your code. Keep your local plumbing everywhere else.
4. Run the verification in §4 before any robot use. Do not skip it.
## 2. Load-bearing contract (must match the reference exactly)
1. **Checkpoint loading**: the .pt is a dict
`{"step", "model", "config", "optimizer", ...}`; build `ACTConfig` from
`config`, `load_state_dict(ckpt["model"])` must report
**missing=[] unexpected=[]**. qpos/tactile/action normalization lives in
buffers inside the state_dict — never re-normalize inputs externally.
2. **Observation contract**: `{"state": (22,) float, "tactile": (3840,) float}`.
The tactile vector is 5 fingers × 768, **concatenated in finger order
0..4**, produced by `tools/live_features.py` (its preprocessing constants
are training-fixed — do not "improve" or recompute them).
3. **Chunking**: `chunk_size=30, n_action_steps=30` come from the checkpoint
config; `step()` pops from the action queue and re-queries every 30 frames;
`reset()` must be called at every episode start.
4. **Output semantics**: `step()`/`predict_chunk()` return **absolute target
joint positions** (22,), even for delta-trained checkpoints (integration
happens inside `policy.predict_action_chunk`).
5. `state_history = tactile_history = 1` for these checkpoints.
## 3. When to wholesale-replace instead
If your local `act_policy/` predates the May refactor (no `forward_context`
split, no `FlowMatchingHead`, no generalized tactile-key routing), take the
bundled `act_policy/` as-is — partial merges of the model code are how silent
weight-mismatch bugs happen. The gate is §2.1: if `load_state_dict` is not
clean, replace the package.
## 4. Verification (in order, all must pass)
1. **Feature parity** (needs any episode HDF5 that contains stored `/t3/<f>`
and `/sitr/<f>` datasets):
```bash
python -m tools.live_features --kind t3 --episode <episode.hdf5>
python -m tools.live_features --kind sitr --episode <episode.hdf5>
# must print PASS (worst cosine > 0.999)
```
2. **Clean checkpoint load**: load both act_best.pt; assert no missing /
unexpected keys, and `config.tactile_dim == 3840`.
3. **Offline eval sanity** (if the episode data is present):
```bash
python inference.py --checkpoint <...>/screw_t3_50k/act_best.pt \
--mode offline --data episodes/screwing \
--tactile-keys t3_0 t3_1 t3_2 t3_3 t3_4 --out-csv /tmp/t3.csv
```
Expect overall L1 ≈ 0.023 / val-episode L1 ≈ 0.032 (T3); ≈ 0.020 / 0.031
(SITR). A large deviation means a contract violation — stop and compare
against the reference again.
4. Only after 1–3 pass: dry-run the robot loop with `step()` on live data.
## 5. Environment notes
- `tools/live_features.py` needs the third-party encoder stacks:
tactile_fusion repo (`TACTILE_FUSION_ROOT` env; loads T3 via its
`load_baselines`) + t3 repo + t3_medium weights; gsrl repo (`GSRL_ROOT`) +
`checkpoints/SITR_B18.pth`. These are NOT in this bundle.
- Known import trap: tactile_act's `data/` package shadows tactile_fusion's;
`live_features.py` handles it (`_strip_shadowing_paths`) — keep that if you
port the file.
- torch ≥ 2.x; GPU strongly recommended for the SITR encoder (86M) at 30 Hz.