Visuo-tactile world model: 20 windows, seen and unseen, short and long

Ten held-out windows and ten training windows, each rolled out at both a single-window horizon and 16 seconds autoregressively — the full {test, train} × {short, long} matrix for two conditioning designs.

Diffusion-Forcing Mixture-of-Transformers over Wan2.2 latents (48 ch, 4 latent frames, 16×16). Both runs: 100 epochs, step 117 199, identical optimizer and seed, last.ckpt — the split warns that val aliases test, so selecting best-epoch=* would be selecting on the reported episodes.

The two models

gelz — the frozen pixel-space Stage-1 flow concatenated into both experts (exactly, via a zero-init projector: a conv is linear in its input channels), plus FiLM from the raw action vector. Its tactile FiLM vector is 11-D in the gel frame: [dp(3), Rot6D(6), log1p(force_N), contact], where +z is the measured gel normal, so channel 2 is press depth and the force rides on that same axis. That matches what the frozen tactile encoder pixc5_D already sees.

vecfilm — the control. Same architecture, but no flow concatenated, the tactile vector is the rigid-frame 9-D step, and no force. It exists because gelz changes three things at once, and without it none of them could be attributed.

Contact force reaches the tactile branch only; every video-branch input (12-ch ActionImage, camera frame, 2-ch flow, action[0:18]) is force-free by construction.

The four cells

short = one 16-frame window: 2 clean latent context frames, 2 generated, decoded to 13 pixel frames of which 5 come from the context. long = 16 s autoregressive sliding-window rollout, keep-1: seed with context, predict a window, keep one new latent frame, advance, repeat — so error compounds over ~22 model calls. test = the two held-out episodes; train = six seen episodes across all three recording dates, so the pair measures the generalisation gap, not just accuracy.

Results — decoded pixel PSNR (dB)

cellmodelcamera viewtactile lefttactile rightn
short / testgelz24.0045.4146.0510
vecfilm23.9745.5845.8310
short / traingelz25.5043.4345.2610
vecfilm24.9043.4444.7810
long / testgelz19.9832.2332.3410
vecfilm19.7432.3632.6310
long / traingelz21.8930.5431.1310
vecfilm21.0330.6631.4410

Generalisation gap (train − test)

horizonmodelcamera viewtactile lefttactile right
shortgelz+1.50-1.98-0.79
shortvecfilm+0.93-2.14-1.05
longgelz+1.91-1.69-1.21
longvecfilm+1.28-1.69-1.19

Positive = the model does better on episodes it trained on. A large positive number at long horizon and a small one at short horizon is the signature of memorised dynamics rather than memorised appearance.

Rollouts

Ground truth on top, then each model. Frames outlined in red are generated; the unoutlined leading frames are the clean context. Long-horizon strips subsample evenly across the 16 s. PSNR is over the whole clip, computed on the raw decoded tensors — the images are h264, which costs a little fidelity equally in every row.

short horizon — test split

005:0 — sample_000
camera view
tactile left
tactile right
005:34 — sample_001
camera view
tactile left
tactile right
005:68 — sample_002
camera view
tactile left
tactile right
005:102 — sample_003
camera view
tactile left
tactile right
005:136 — sample_004
camera view
tactile left
tactile right
006:0 — sample_005
camera view
tactile left
tactile right
006:150 — sample_006
camera view
tactile left
tactile right
006:300 — sample_007
camera view
tactile left
tactile right
006:450 — sample_008
camera view
tactile left
tactile right
006:600 — sample_009
camera view
tactile left
tactile right

short horizon — train split

001:0 — sample_000
camera view
tactile left
tactile right
001:400 — sample_001
camera view
tactile left
tactile right
001:800 — sample_002
camera view
tactile left
tactile right
004:0 — sample_003
camera view
tactile left
tactile right
004:150 — sample_004
camera view
tactile left
tactile right
005:0 — sample_005
camera view
tactile left
tactile right
005:400 — sample_006
camera view
tactile left
tactile right
013:0 — sample_007
camera view
tactile left
tactile right
013:300 — sample_008
camera view
tactile left
tactile right
002:0 — sample_009
camera view
tactile left
tactile right

long horizon — test split

005:0 — sample_000
camera view
tactile left
tactile right
005:34 — sample_001
camera view
tactile left
tactile right
005:68 — sample_002
camera view
tactile left
tactile right
005:102 — sample_003
camera view
tactile left
tactile right
005:136 — sample_004
camera view
tactile left
tactile right
006:0 — sample_005
camera view
tactile left
tactile right
006:150 — sample_006
camera view
tactile left
tactile right
006:300 — sample_007
camera view
tactile left
tactile right
006:450 — sample_008
camera view
tactile left
tactile right
006:600 — sample_009
camera view
tactile left
tactile right

long horizon — train split

001:0 — sample_000
camera view
tactile left
tactile right
001:400 — sample_001
camera view
tactile left
tactile right
001:800 — sample_002
camera view
tactile left
tactile right
004:0 — sample_003
camera view
tactile left
tactile right
004:150 — sample_004
camera view
tactile left
tactile right
005:0 — sample_005
camera view
tactile left
tactile right
005:400 — sample_006
camera view
tactile left
tactile right
013:0 — sample_007
camera view
tactile left
tactile right
013:300 — sample_008
camera view
tactile left
tactile right
002:0 — sample_009
camera view
tactile left
tactile right

Reproducing

sbatch vm_diffusion/run_eval_matrix20.sh 16      # 2 models x 2 splits x 2 horizons
python -m vm_diffusion.scripts.build_hf_space_matrix20 --push

Rollouts are teacher-forced on the conditioning streams: the frozen Stage-1 encoders read ground-truth frames, so these are an upper bound on what a closed-loop rollout would give. Both models are affected identically.