screw_sitr5_ingraph_50k: in-graph fine-tuned SITR ACT (snapshot step 7200) + TS encoder export + code (sitr branch, bf16 flag, feature_policy in-graph loading)
Browse files- act_policy/policy.py +9 -3
- act_policy/sitr_branch.py +88 -0
- qistee_integration/feature_policy.py +8 -1
- screw_sitr5_ingraph_50k/DEPLOY.md +62 -0
- screw_sitr5_ingraph_50k/act_best.pt +3 -0
- screw_sitr5_ingraph_50k/args.json +74 -0
- screw_sitr5_ingraph_50k/sitr_ingraph_feature_encoder.ts.pt +3 -0
- train.py +9 -2
act_policy/policy.py
CHANGED
|
@@ -16,6 +16,7 @@ from torch import Tensor, nn
|
|
| 16 |
|
| 17 |
from .config import ACTConfig
|
| 18 |
from .model import ACT, FlowMatchingHead
|
|
|
|
| 19 |
from .tactile_fusion_branch import TactileFusionBranch
|
| 20 |
|
| 21 |
|
|
@@ -74,10 +75,15 @@ class ACTPolicy(nn.Module):
|
|
| 74 |
self.tactile_norm = _Normalizer(config.tactile_dim)
|
| 75 |
self.action_norm = _Normalizer(config.action_dim)
|
| 76 |
|
| 77 |
-
# In-graph tactile
|
| 78 |
-
|
|
|
|
|
|
|
| 79 |
if config.tactile_image_keys:
|
| 80 |
-
|
|
|
|
|
|
|
|
|
|
| 81 |
|
| 82 |
# ImageNet stats for the torchvision-pretrained ResNet backbone.
|
| 83 |
self.register_buffer("image_mean", torch.tensor([0.485, 0.456, 0.406]).view(1, 3, 1, 1))
|
|
|
|
| 16 |
|
| 17 |
from .config import ACTConfig
|
| 18 |
from .model import ACT, FlowMatchingHead
|
| 19 |
+
from .sitr_branch import SITRBranch
|
| 20 |
from .tactile_fusion_branch import TactileFusionBranch
|
| 21 |
|
| 22 |
|
|
|
|
| 75 |
self.tactile_norm = _Normalizer(config.tactile_dim)
|
| 76 |
self.action_norm = _Normalizer(config.action_dim)
|
| 77 |
|
| 78 |
+
# In-graph tactile encoder (joint-trained or frozen). Modality "sitr"
|
| 79 |
+
# gets the raw-single-frame SITR branch; anything else the
|
| 80 |
+
# tactile-fusion (HTT) branch.
|
| 81 |
+
self.tactile_branch: nn.Module | None = None
|
| 82 |
if config.tactile_image_keys:
|
| 83 |
+
if config.tactile_encoder_modality == "sitr":
|
| 84 |
+
self.tactile_branch = SITRBranch(config)
|
| 85 |
+
else:
|
| 86 |
+
self.tactile_branch = TactileFusionBranch(config)
|
| 87 |
|
| 88 |
# ImageNet stats for the torchvision-pretrained ResNet backbone.
|
| 89 |
self.register_buffer("image_mean", torch.tensor([0.485, 0.456, 0.406]).view(1, 3, 1, 1))
|
act_policy/sitr_branch.py
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""In-graph SITR encoder branch for ACT.
|
| 2 |
+
|
| 3 |
+
Counterpart of ``TactileFusionBranch`` for ``tactile_encoder_modality="sitr"``.
|
| 4 |
+
SITR's released convention: raw single frames, no background subtraction, no
|
| 5 |
+
frame pairs. The per-episode bg tensor is still accepted (and ignored) so the
|
| 6 |
+
dataset/policy interface stays identical to the HTT in-graph path.
|
| 7 |
+
|
| 8 |
+
Preprocessing mirrors tools/encode_sitr.py: /255 -> replicate to 3 channels ->
|
| 9 |
+
bilinear 224x224 -> normalize with SITR's training stats -> forward_encoder,
|
| 10 |
+
cls token. With ``tactile_image_group="tactile_imgs"`` the frames arrive
|
| 11 |
+
pre-resized to 224x224 and the resize is a no-op.
|
| 12 |
+
"""
|
| 13 |
+
from __future__ import annotations
|
| 14 |
+
|
| 15 |
+
import os
|
| 16 |
+
import sys
|
| 17 |
+
|
| 18 |
+
import torch
|
| 19 |
+
import torch.nn as nn
|
| 20 |
+
import torch.nn.functional as F
|
| 21 |
+
|
| 22 |
+
from .config import ACTConfig
|
| 23 |
+
|
| 24 |
+
GSRL_ROOT = os.environ.get("GSRL_ROOT", "/home/allenbi/projects_25/gsrl")
|
| 25 |
+
DEFAULT_SITR_CKPT = os.path.join(GSRL_ROOT, "checkpoints/SITR_B18.pth")
|
| 26 |
+
|
| 27 |
+
# SITR training normalization (gsrl/dataloaders.py), applied on [0,1] input.
|
| 28 |
+
SITR_MEAN = (-1.2223, -1.8114, -1.7090)
|
| 29 |
+
SITR_STD = (11.7932, 12.7956, 13.6452)
|
| 30 |
+
|
| 31 |
+
|
| 32 |
+
class SITRBranch(nn.Module):
|
| 33 |
+
"""SITR_base (ViT-B/16) run per finger frame, cls-token readout.
|
| 34 |
+
|
| 35 |
+
Inputs at forward:
|
| 36 |
+
frames: (B, n_fingers, T, H, W) uint8 grayscale — only frames[:, :, -1]
|
| 37 |
+
(the current frame) is encoded; pass ``tactile_image_pair=1``.
|
| 38 |
+
bg: ignored (SITR consumes raw frames).
|
| 39 |
+
|
| 40 |
+
Output: (B, n_fingers * 768) float32 tactile vector.
|
| 41 |
+
"""
|
| 42 |
+
|
| 43 |
+
def __init__(self, config: ACTConfig):
|
| 44 |
+
super().__init__()
|
| 45 |
+
if not config.tactile_image_keys:
|
| 46 |
+
raise ValueError("SITRBranch requires non-empty tactile_image_keys.")
|
| 47 |
+
if int(config.tactile_encoder_feature_dim) != 768:
|
| 48 |
+
raise ValueError(
|
| 49 |
+
"SITR_base emits 768-d cls features; set --tactile-encoder-feature-dim 768."
|
| 50 |
+
)
|
| 51 |
+
if GSRL_ROOT not in sys.path:
|
| 52 |
+
sys.path.insert(0, GSRL_ROOT)
|
| 53 |
+
from models.networks import SITR_base # noqa: E402
|
| 54 |
+
|
| 55 |
+
model = SITR_base(num_calibration=0) # calibration-free, as in encode_sitr.py
|
| 56 |
+
ckpt_path = config.tactile_encoder_ckpt or DEFAULT_SITR_CKPT
|
| 57 |
+
ckpt = torch.load(ckpt_path, map_location="cpu", weights_only=False)
|
| 58 |
+
state = ckpt.get("state_dict", ckpt) if isinstance(ckpt, dict) else ckpt
|
| 59 |
+
missing, unexpected = model.load_state_dict(state, strict=False)
|
| 60 |
+
print(f"[sitr-branch] loaded {ckpt_path} missing={len(missing)} unexpected={len(unexpected)}")
|
| 61 |
+
# forward_encoder never touches the decoder/contrastive heads; keep them
|
| 62 |
+
# out of the optimizer.
|
| 63 |
+
for p in model.decoder_pred.parameters():
|
| 64 |
+
p.requires_grad = False
|
| 65 |
+
for p in model.contrastive_head.parameters():
|
| 66 |
+
p.requires_grad = False
|
| 67 |
+
self.model = model
|
| 68 |
+
|
| 69 |
+
self.register_buffer("image_mean", torch.tensor(SITR_MEAN).view(1, 3, 1, 1))
|
| 70 |
+
self.register_buffer("image_std", torch.tensor(SITR_STD).view(1, 3, 1, 1))
|
| 71 |
+
self.target_hw = tuple(config.tactile_encoder_target_hw)
|
| 72 |
+
self.feature_dim = int(config.tactile_encoder_feature_dim)
|
| 73 |
+
self.n_fingers = len(config.tactile_image_keys)
|
| 74 |
+
|
| 75 |
+
if config.tactile_encoder_freeze:
|
| 76 |
+
for p in self.model.parameters():
|
| 77 |
+
p.requires_grad = False
|
| 78 |
+
|
| 79 |
+
def forward(self, frames: torch.Tensor, bg: torch.Tensor | None = None) -> torch.Tensor:
|
| 80 |
+
B, n_fingers, T, H, W = frames.shape
|
| 81 |
+
x = frames[:, :, -1] # (B, nF, H, W)
|
| 82 |
+
x = (x.float() if x.dtype == torch.uint8 else x) / 255.0
|
| 83 |
+
x = x.reshape(B * n_fingers, 1, H, W).expand(-1, 3, -1, -1)
|
| 84 |
+
if (H, W) != self.target_hw:
|
| 85 |
+
x = F.interpolate(x, size=self.target_hw, mode="bilinear", align_corners=False)
|
| 86 |
+
x = (x - self.image_mean) / self.image_std
|
| 87 |
+
f = self.model.forward_encoder(x, c=None)[:, 0, :] # cls (B*nF, 768)
|
| 88 |
+
return f.reshape(B, n_fingers * self.feature_dim)
|
qistee_integration/feature_policy.py
CHANGED
|
@@ -75,7 +75,14 @@ def load_feature_policy(checkpoint: str, device: torch.device) -> FeaturePolicy:
|
|
| 75 |
f"{FINGER_COUNT * FEATURE_DIM} — is this a T3/SITR checkpoint? "
|
| 76 |
"(HTT in-graph checkpoints belong to htt_policy.py)")
|
| 77 |
policy = FeaturePolicy(config)
|
| 78 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 79 |
return policy.to(device).eval()
|
| 80 |
|
| 81 |
|
|
|
|
| 75 |
f"{FINGER_COUNT * FEATURE_DIM} — is this a T3/SITR checkpoint? "
|
| 76 |
"(HTT in-graph checkpoints belong to htt_policy.py)")
|
| 77 |
policy = FeaturePolicy(config)
|
| 78 |
+
# Feature checkpoints (screw_t3_50k / screw_sitr5_50k) have no tactile_branch.
|
| 79 |
+
# In-graph checkpoints (screw_sitr5_ingraph_50k) carry the fine-tuned encoder
|
| 80 |
+
# under tactile_branch.* — at deploy those weights live in the run's exported
|
| 81 |
+
# TorchScript encoder instead, so drop them here. Their tactile_norm was never
|
| 82 |
+
# initialized (identity), hence the same predict path is exact for both.
|
| 83 |
+
state = {k: v for k, v in payload["model"].items()
|
| 84 |
+
if not k.startswith("tactile_branch.")}
|
| 85 |
+
policy.load_state_dict(state, strict=True)
|
| 86 |
return policy.to(device).eval()
|
| 87 |
|
| 88 |
|
screw_sitr5_ingraph_50k/DEPLOY.md
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# screw_sitr5_ingraph_50k — SITR fine-tuned IN-GRAPH ACT (screw task)
|
| 2 |
+
|
| 3 |
+
`2026-08-12` · **snapshot of a still-running training** — `act_best.pt` here is
|
| 4 |
+
the best-val checkpoint at global step 7,200 (train-val L1 0.2652, already below
|
| 5 |
+
every other SITR/HTT condition's all-time best). It will be replaced by the
|
| 6 |
+
final best when the run stops (patience 5 × 200 steps on val).
|
| 7 |
+
|
| 8 |
+
## What it is
|
| 9 |
+
|
| 10 |
+
Same 50K protocol as the other `screw_*_50k` runs (bs=32, lr 2e-5 warmup 5K →
|
| 11 |
+
cosine 2e-6, chunk 30, CVAE, val = last 2 episodes), but the SITR encoder
|
| 12 |
+
(`SITR_base`, ViT-B/16, calibration-free) runs **inside the graph** on raw
|
| 13 |
+
single frames and is **fine-tuned jointly** (0.1× LR, i.e. 2e-6). Training
|
| 14 |
+
forward/backward ran under bf16 autocast; the checkpoint is ordinary fp32.
|
| 15 |
+
Naive/full setting: all 5 fingers, full 768-d cls per finger → 3840-d tactile.
|
| 16 |
+
|
| 17 |
+
Unlike the frozen-feature `screw_sitr5_50k`, the encoder weights here differ
|
| 18 |
+
from `SITR_B18.pth` — you MUST use this folder's TorchScript export, not
|
| 19 |
+
`exported/sitr_feature_encoder.ts.pt`.
|
| 20 |
+
|
| 21 |
+
## Files
|
| 22 |
+
|
| 23 |
+
| File | Meaning |
|
| 24 |
+
|---|---|
|
| 25 |
+
| `act_best.pt` | full checkpoint (model incl. fine-tuned encoder + config + optimizer + scheduler) |
|
| 26 |
+
| `sitr_ingraph_feature_encoder.ts.pt` | TorchScript of the FINE-TUNED encoder; contract identical to `exported/*.ts.pt`: input (B,3,224,224) float in [0,1], SITR normalization baked in, output (B,768) cls |
|
| 27 |
+
| `args.json` | training invocation |
|
| 28 |
+
|
| 29 |
+
## Robot loop (identical to the T3/SITR feature policies)
|
| 30 |
+
|
| 31 |
+
Raw frames only — NO background capture, NO frame pairs, finger order 0..4
|
| 32 |
+
(camera order, same as training):
|
| 33 |
+
|
| 34 |
+
```python
|
| 35 |
+
from feature_policy import load_feature_policy, TSFeatureEncoder # repo ≥ this commit
|
| 36 |
+
policy = load_feature_policy("screw_sitr5_ingraph_50k/act_best.pt", device)
|
| 37 |
+
encoder = TSFeatureEncoder("screw_sitr5_ingraph_50k/sitr_ingraph_feature_encoder.ts.pt", device)
|
| 38 |
+
...
|
| 39 |
+
feats = encoder(hand.raw_frame()) # (5,240,320) uint8 -> (1,3840)
|
| 40 |
+
chunk = policy.predict_action_chunk(qpos_t, feats)[0]
|
| 41 |
+
```
|
| 42 |
+
|
| 43 |
+
Requires the updated `qistee_integration/feature_policy.py` (this commit): it
|
| 44 |
+
drops the `tactile_branch.*` weights when loading in-graph checkpoints (they
|
| 45 |
+
live in the TS encoder at deploy). This is exact, not approximate: in-graph
|
| 46 |
+
checkpoints never initialize `tactile_norm` (identity), and the split path was
|
| 47 |
+
validated bit-identical (feature maxdiff 0.0, action-chunk maxdiff 0.0 vs the
|
| 48 |
+
reference in-graph `ACTPolicy` on training frames).
|
| 49 |
+
|
| 50 |
+
Alternative (tactile_act repo on the machine): `ACTInference.from_checkpoint`
|
| 51 |
+
loads `act_best.pt` directly — needs `act_policy/sitr_branch.py` (this commit)
|
| 52 |
+
plus the gsrl repo for the `SITR_base` class definition and `SITR_B18.pth`
|
| 53 |
+
(constructor init only; weights are immediately overwritten from the ACT
|
| 54 |
+
checkpoint). The TorchScript path avoids the third-party dependency entirely.
|
| 55 |
+
|
| 56 |
+
## Caveat carried over from the feature-SITR analysis
|
| 57 |
+
|
| 58 |
+
Fine-tuning does NOT add a reference-frame mechanism: the encoder still
|
| 59 |
+
consumes raw frames, so fingertip-camera appearance drift between the training
|
| 60 |
+
data and the rig shifts features with nothing to anchor them (HTT's bg-capture
|
| 61 |
+
anchors it; SITR-in-graph has no bg). Same deployment interpretation guardrails
|
| 62 |
+
as `screw_sitr5_50k` / `screw_t3_50k` (see FEATURE_PREPROCESSING.md).
|
screw_sitr5_ingraph_50k/act_best.pt
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:fe4b6e0fda53a53c8a2e1060bdc548edffbb8106304cd2a7da5aa5898d3dc937
|
| 3 |
+
size 1537168989
|
screw_sitr5_ingraph_50k/args.json
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"data": "./episodes/screwing",
|
| 3 |
+
"smoke": false,
|
| 4 |
+
"episode_glob": "episode_*.hdf5",
|
| 5 |
+
"state_dim": 22,
|
| 6 |
+
"action_dim": 22,
|
| 7 |
+
"image_keys": [],
|
| 8 |
+
"image_shape": [
|
| 9 |
+
3,
|
| 10 |
+
240,
|
| 11 |
+
320
|
| 12 |
+
],
|
| 13 |
+
"tactile_dim": 0,
|
| 14 |
+
"tactile_keys": [],
|
| 15 |
+
"tactile_image_keys": [
|
| 16 |
+
"raw_0",
|
| 17 |
+
"raw_1",
|
| 18 |
+
"raw_2",
|
| 19 |
+
"raw_3",
|
| 20 |
+
"raw_4"
|
| 21 |
+
],
|
| 22 |
+
"tactile_image_pair": 1,
|
| 23 |
+
"tactile_image_group": "tactile_imgs",
|
| 24 |
+
"tactile_bg_group": "tactile_bg_224",
|
| 25 |
+
"tactile_encoder_modality": "sitr",
|
| 26 |
+
"tactile_encoder_ckpt": "/home/allenbi/projects_25/gsrl/checkpoints/SITR_B18.pth",
|
| 27 |
+
"tactile_encoder_pretrain_config": "/home/allenbi/projects_25/tactile_fusion/config/model/pretrain.yaml",
|
| 28 |
+
"tactile_encoder_feature_dim": 768,
|
| 29 |
+
"tactile_encoder_target_hw": [
|
| 30 |
+
224,
|
| 31 |
+
224
|
| 32 |
+
],
|
| 33 |
+
"tactile_encoder_lr_scale": 0.1,
|
| 34 |
+
"freeze_tactile_encoder": false,
|
| 35 |
+
"state_history": 1,
|
| 36 |
+
"tactile_history": 1,
|
| 37 |
+
"delta_actions": false,
|
| 38 |
+
"state_indices": null,
|
| 39 |
+
"action_indices": null,
|
| 40 |
+
"chunk_size": 30,
|
| 41 |
+
"n_action_steps": 30,
|
| 42 |
+
"no_vae": false,
|
| 43 |
+
"use_flow_matching": false,
|
| 44 |
+
"fm_hidden_dim": 512,
|
| 45 |
+
"fm_n_mlp_layers": 3,
|
| 46 |
+
"fm_time_embed_dim": 128,
|
| 47 |
+
"fm_inference_steps": 10,
|
| 48 |
+
"lr": 2e-05,
|
| 49 |
+
"lr_backbone": 1e-05,
|
| 50 |
+
"weight_decay": 0.0001,
|
| 51 |
+
"lr_warmup_steps": 5000,
|
| 52 |
+
"lr_warmup_init": 1e-06,
|
| 53 |
+
"lr_cosine": true,
|
| 54 |
+
"lr_min": 2e-06,
|
| 55 |
+
"batch_size": 32,
|
| 56 |
+
"num_workers": 4,
|
| 57 |
+
"bf16": true,
|
| 58 |
+
"steps": 50000,
|
| 59 |
+
"log_every": 200,
|
| 60 |
+
"save_every": 10000,
|
| 61 |
+
"out": "./checkpoints",
|
| 62 |
+
"device": "cuda",
|
| 63 |
+
"resume": null,
|
| 64 |
+
"run_name": "screw_sitr5_ingraph_50k",
|
| 65 |
+
"tb_dir": "./runs",
|
| 66 |
+
"no_tb": false,
|
| 67 |
+
"no_stats": false,
|
| 68 |
+
"stats_batch_size": 32,
|
| 69 |
+
"stats_num_workers": 4,
|
| 70 |
+
"val_episodes": 2,
|
| 71 |
+
"val_every": 200,
|
| 72 |
+
"val_batches": 0,
|
| 73 |
+
"patience": 5
|
| 74 |
+
}
|
screw_sitr5_ingraph_50k/sitr_ingraph_feature_encoder.ts.pt
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:a9b05621e199620a49c63d6ceadd3d64cd7f3b19360af0f50f1f0a034b342f9e
|
| 3 |
+
size 346358387
|
train.py
CHANGED
|
@@ -65,7 +65,9 @@ def parse_args() -> argparse.Namespace:
|
|
| 65 |
help="HDF5 group for per-episode bg images. Use 'tactile_bg_224' alongside "
|
| 66 |
"the resized tactile_imgs.")
|
| 67 |
p.add_argument("--tactile-encoder-modality", type=str, default="9dtact",
|
| 68 |
-
choices=["9dtact", "gsmini"
|
|
|
|
|
|
|
| 69 |
p.add_argument("--tactile-encoder-ckpt", type=str,
|
| 70 |
default="/home/allenbi/projects_25/tactile_fusion/checkpoints/pretrain_joint_alignscratch/"
|
| 71 |
"pretrain_multimodal_20260521_005341/checkpoint_step_34000.pth")
|
|
@@ -123,6 +125,9 @@ def parse_args() -> argparse.Namespace:
|
|
| 123 |
|
| 124 |
p.add_argument("--batch-size", type=int, default=8)
|
| 125 |
p.add_argument("--num-workers", type=int, default=4)
|
|
|
|
|
|
|
|
|
|
| 126 |
p.add_argument("--steps", type=int, default=100_000)
|
| 127 |
p.add_argument("--log-every", type=int, default=50)
|
| 128 |
p.add_argument("--save-every", type=int, default=5000)
|
|
@@ -480,7 +485,9 @@ def main() -> None:
|
|
| 480 |
if step >= args.steps or early_stop:
|
| 481 |
break
|
| 482 |
batch = move_to(batch, args.device)
|
| 483 |
-
|
|
|
|
|
|
|
| 484 |
optimizer.zero_grad(set_to_none=True)
|
| 485 |
loss.backward()
|
| 486 |
optimizer.step()
|
|
|
|
| 65 |
help="HDF5 group for per-episode bg images. Use 'tactile_bg_224' alongside "
|
| 66 |
"the resized tactile_imgs.")
|
| 67 |
p.add_argument("--tactile-encoder-modality", type=str, default="9dtact",
|
| 68 |
+
choices=["9dtact", "gsmini", "sitr"],
|
| 69 |
+
help="In-graph tactile encoder: tactile-fusion modality, or 'sitr' "
|
| 70 |
+
"for the raw-single-frame SITR branch (SITR_base, 768-d cls).")
|
| 71 |
p.add_argument("--tactile-encoder-ckpt", type=str,
|
| 72 |
default="/home/allenbi/projects_25/tactile_fusion/checkpoints/pretrain_joint_alignscratch/"
|
| 73 |
"pretrain_multimodal_20260521_005341/checkpoint_step_34000.pth")
|
|
|
|
| 125 |
|
| 126 |
p.add_argument("--batch-size", type=int, default=8)
|
| 127 |
p.add_argument("--num-workers", type=int, default=4)
|
| 128 |
+
p.add_argument("--bf16", action="store_true",
|
| 129 |
+
help="Run the training forward/backward under torch.autocast(bfloat16). "
|
| 130 |
+
"Weights, optimizer, checkpoints and validation stay fp32.")
|
| 131 |
p.add_argument("--steps", type=int, default=100_000)
|
| 132 |
p.add_argument("--log-every", type=int, default=50)
|
| 133 |
p.add_argument("--save-every", type=int, default=5000)
|
|
|
|
| 485 |
if step >= args.steps or early_stop:
|
| 486 |
break
|
| 487 |
batch = move_to(batch, args.device)
|
| 488 |
+
with torch.autocast(device_type="cuda" if "cuda" in args.device else "cpu",
|
| 489 |
+
dtype=torch.bfloat16, enabled=args.bf16):
|
| 490 |
+
loss, info = policy(batch)
|
| 491 |
optimizer.zero_grad(set_to_none=True)
|
| 492 |
loss.backward()
|
| 493 |
optimizer.step()
|