Three experiments on the same Diffusion-Forcing U-DiT backbone predicting GelSight-style tactile futures in Wan2.2 VAE latent space: ① tactile-only with an 18-D action (9-D relative SE(3) step per sensor), ② visual-tactile with a 36-D action (18 absolute view dims + the 18 tactile dims), and ③ flow-supervised tactile — AllTracker optical flow enters both as a frozen motion-encoder conditioning signal and as an auxiliary loss through a frozen latent-flow probe.
shared backbone: U-DiT · patch 2 · dim 384 · depth 12 · heads 6 · RoPE · spatial-bidirectional / temporal-causal · per-frame noise (Diffusion Forcing, pred-v)
Blue = frozen, orange = trainable, dashed = data. All three share the identical U-DiT denoiser; the differences are entirely in the token groups, the action vector, and (for ③) an extra spatial conditioning stream.
*③'s val_loss includes the 0.05-weighted flow auxiliary — it is not comparable to ①/②'s plain denoising val_loss. Checkpoints: 612 MB (①/②) vs 618 MB (③; +frozen aux modules + projector).
| experiment | loss | flow's role | inactive-but-configured |
|---|---|---|---|
| ① tactile-only | L_DF (pred-v, per-frame noise) | — | — |
| ② visual-tactile | L_DF over 3 streams | — | — |
| ③ flow-supervised | L_DF + 0.05 · L_pred_flow | input side: frozen Gφ token-bias · loss side: frozen probe readout | motion_loss (gated off — Gφ frozen), flow_head (never enabled) |
AllTracker measures motion in pixels; the world model predicts Wan2.2 VAE latents (48 ch, 16×16 grid, 4× temporal compression). The two never meet in pixel space — there is no VAE decode anywhere in the training loop. Instead, three alignment steps bring the supervision to the latents:
Distinct from the loss above — this is conditioning, computed from given (not predicted) latents at both train and inference time.
Tactile pixel PSNR (tl/tr average), error bars ±1 sd across samples. ②'s view stream (not shown) sits far lower: 24.1 dB short-test, ~21 dB long — the visual stream is much harder than tactile at this model size.
| cell | ① PSNR (n) | ② tac PSNR (n) | ③ PSNR (n) | Stage 2 (n) | Stage 3 (n) |
|---|
Held-out (test) samples. Left half = GT, right half = model rollout.
Every stage initializes from the previous one's checkpoint (weights + conditioning path carry through) and changes exactly one variable, so attribution stays clean. Vision is never used in this lineage — tactile latents (tl+tr) and 18-D sensor actions only.
World model untouched; train only the tiny encoder. The 3-way ablation answered it: a→F 1.36 < z→F 1.17 < (z,a)→F 1.13 (zero-flow 1.61) — tactile says where, action says which way; the physics prior adds nothing.
No auxiliary losses at all — clean attribution. val_loss 0.0354 exactly matches the no-flow baseline; every long-horizon test cell at-or-above it. (The one-shot version of this idea had lost 6 dB; staging recovered all of it.)
The AllTracker anchor keeps Gφ interpretable: after finetuning its weights moved substantially (‖ΔW‖≈33) yet it predicts flow better than its pretrained self (EPE 1.123 vs 1.130). Short test 42.98 dB.
Scheduled sampling trains on the model's OWN drifted context (targets exposure bias); relaxing snr_clip restores gradient on the low-noise denoising steps where fine detail forms. Contact-rich 16 s texture energy 0.66→0.72, hardest segment 0.57→0.77, +0.9 dB.
A latent gradient-domain loss directly supervises the spatial high-frequency structure of predicted latents — attacking the root cause: for unpredictable texture phase, plain MSE rewards averaging (= blur). Outcome: texture mean 0.72→0.84 (gate 0.85, ceiling 0.86); hard segments 0.89–0.96; short test 43.08 dB — the staged line's best.
Tactile context anchors imprints that already exist; a frozen-encoder vision conditioning could announce imprints about to form (the scene camera is the only source of "what is about to touch"). Triggered only if Stage 5 misses the 0.85 texture gate (VAE ceiling 0.86).
Inference-side, orthogonal to training: best-of-N seed selection with the texture-energy criterion (rescues short-horizon collapse), and the texture evaluation protocol itself (gradient-energy ratio / gradient correlation — PSNR is blind to this failure mode).
amx12_* runs, 12 epochs, held-out episodes 005/006. Active-pixel EPE (target motion > 0.5 px), lower is better.
| variant | inputs | active-EPE ↓ | full EPE | dir cos ↑ |
|---|---|---|---|---|
| zero-flow baseline | — | 1.612 | 1.155 | — |
| physics prior | — | 1.606 | 1.308 | — |
| A: physics-only | prior | 1.381 | 1.016 | 0.557 |
| B: a → F | action map | 1.362 | 1.005 | 0.553 |
| C: z → F | tactile state | 1.168 | 0.852 | 0.694 |
| D: (z, a) → F — winner | both | 1.130 | 0.837 | 0.726 |
| E: all | both + prior | 1.135 | 0.843 | 0.720 |
Rows = held-out transitions; columns = raw tactile frame, the action motion-map input (affine over the gel — direction only, no localization), predictions from the three ablations, and AllTracker ground truth. The tactile state answers where motion happens (violet localizes to the imprint), the action answers which way (orange has direction but smears it everywhere); (z, a) combines both. The sharp high-magnitude bands in the GT that no variant captures are the contact-region-shape structure discussed above.
③ wired flow in with pretrained-elsewhere, frozen modules and underperformed the plain baseline. The staged plan below isolates why, one question at a time: Gφ is the (tiny) motion encoder, F is AllTracker flow, and the expensive world model only trains once the flow representation has proven itself.
The critical ablation: if action alone predicts flow as well as (z, a), the tactile state adds nothing; if neither beats a zero-flow baseline, flow conditioning can't help downstream. Existing analogues: runs/action_motion/amx_A…E + latent_flow_probe — rerun as this explicit 3-way comparison.
Clean attribution: any gain comes from the conditioning signal, not from moving Gφ. Experiment ③ is essentially this stage (frozen amx_E + token-bias injection) — and its −6 dB result says the Stage-1 question needs a sharper answer first.
The AllTracker loss anchors Gφ to real motion instead of letting the DiT repurpose it as an arbitrary hidden feature. This run's motion_loss block (currently gated off by freeze: true) is exactly the L_action-flow needed — unfreeze and go.
Five windows from tactile_test_set whose first frame already has firm GelSight contact (raw contact area > 0.25, ranked by first-frame area, one window per episode). 2 latent frames given, 2 predicted. The sensor carrying the active contact is the hard one (31–42 dB); the quiet sensor exceeds 50 dB. Aggregate over the 5 contact windows: tl 37.98 dB · tr 44.54 dB. All six windows are from training episodes — the top contact-area windows in this test set happen not to be from the held-out episodes. *Sample 005 is the opposite regime, added on request: a push-T window starting almost contact-free (area 0.077) but with the highest tactile activity in the whole test set (0.92) — the model tracks it well on both sensors.
| sample | episode @ fps6 start | first-frame area | tl PSNR | tr PSNR |
|---|---|---|---|---|
| 000 | 0511_ep017 @ 2423 | 0.544 | 42.33 | 31.53 |
| 001 | 0510_ep009 @ 159 | 0.461 | 39.04 | 51.91 |
| 002 | 0511_ep005 @ 2365 | 0.435 | 37.92 | 52.05 |
| 003 | 0519_ep001 @ 69 | 0.410 | 34.47 | 35.50 |
| 004 | 0511_ep008 @ 993 | 0.400 | 36.16 | 51.69 |
| 005* | pusht_ep001 @ 900 | 0.077 | 45.89 | 47.66 |
Rollout imprint texture (e.g. connector ribs) often collapses to blur. Diagnosis: it is seed-dependent diffusion mode selection, not a model ceiling — some seeds sample sharp texture, more DDIM steps (100→250) change nothing, and PSNR cannot see the difference (sharp-but-phase-shifted texture scores the same as blur). Fix: sample N seeds and pick, with a GT-free criterion — match the predicted frames' Sobel texture energy to the context imprint's energy (penalizes both blur and hallucination). On 5 contact windows the picker lands within 0.01–0.02 gradient-correlation of the GT-oracle on 4/5.
Ceiling first: the Wan2.2 VAE round-trip itself keeps 86% ± 6% of raw texture energy — so most of the long-horizon gap is the world model, not the representation. First training fix (tac_s4_ss): enable scheduled sampling (the model trains on its own drifted context — directly targets AR exposure bias; previously never enabled) + relax snr_clip 5→20 (restores training weight on the low-noise denoising steps where fine detail forms). 50-epoch finetune from Stage 3.
| contact-rich 16 s segment | s3 default | s3 best-of-4/step | s4 + sched. sampling |
|---|---|---|---|
| late-third texture-energy ratio (avg tl/tr over 3 segments) | 0.66 | 0.67 | 0.72 |
| pixel PSNR (3 segments) | 29.41 | 29.76 | 30.32 |
| contact-rich 16 s segment (tl/tr) | Stage 3 | + sched. sampling | + gradient loss (final) |
|---|---|---|---|
| ep005@24 (held-out) | 0.72/0.76 | 0.70/0.75 | 0.71/0.76 |
| 017@1332 | 0.57/0.60 | 0.59/0.64 | 0.89/0.96 |
| 017@1512 | 0.75/0.57 | 0.84/0.77 | 0.86/0.89 |
| mean (gate 0.85 · VAE ceiling 0.86) | 0.66 | 0.71 | 0.84 |
| contact-segment PSNR | 29.41 | 30.32 | 31.12 |
① tactile-world-model-rollouts · ② view-tactile-world-model-rollouts · ③ tactile-wm-actionflow-rollouts — each hosts every rollout clip, per-cell metrics, and drift curves.
Data: 36 episodes (motherboard + push-T), Wan2.2 VAE latents @ 6 fps, 16-frame windows (8 history + 8 future → 4 latent frames, 2 given). Eval: short = one window; long = autoregressive keep-first-future-frame, 8/16 s. Decode: Wan2.2 VAE + the encode-time LoRA adapter. AllTracker flow pooled to the 16×16 latent grid at build time (build_flow_latent_targets.py).