v13 gap diagnostic — where do the remaining 36 mm come from?

Date: 2026-07-11 · Model: v13_stable step 3000 (90 mm abs on ARCTIC-lite N=40) Question: v13 landed at 90 mm; Iter 206 oracle ceiling is 54 mm; where do the 36 mm live? Answer: it's diffuse, not a specific bug — pixel + per-frame lift together cost ~25-30 mm.


Per-clip distribution — no more bimodality

150-clip arctic val eval on v13 s3000:

Percentile abs MPJPE
min 29 mm — sub-Iter 204 oracle
p5 47 mm
p10 53 mm — at Iter 206 oracle
p25 66 mm
p50 (median) 85 mm
p75 103 mm
p90 128 mm
p95 149 mm
max 253 mm
mean 89 mm

Fractions: - 7 % of clips < 50 mm (Iter 204-oracle territory) - 18 % of clips < 60 mm (~Iter 206 oracle) - 32 % of clips < 70 mm - 55 % of clips < 90 mm - 87 % < 120 mm

Compare to v11 (before rot-matrix loss): bimodal distribution with best clips at 60 mm and worst at 540 mm, mean = 149 mm dragged by 3 % tail.

v13's failure mode is no longer tail-dominated. Mean ≈ median (89 vs 85); the tail is compressed (max 253 vs. v11's 540). The remaining 36 mm gap is a distribution shift, not a bug in specific clips.


Best and worst clips

Top 5 (best abs): | clip | slug | abs | pixel | |-----:|------|----:|------:| | 14066 | (various) | 29 mm | 10 px | | 14862 | | 41 mm | 14 px | | 12908 | | 42 mm | 20 px | | 13917 | | 43 mm | 11 px | | 9721 | | 43 mm | 17 px |

Pixel accuracy on top-5 clips: 10-20 px, comparable to SomantisModel v14d champion (13 px). When the model gets a clip right, it's genuinely competitive.

Bottom 5 (worst abs): | clip | slug | abs | pixel | |-----:|------|----:|------:| | 6189 | s05·notebook_use_02 | 253 mm | 78 px | | 6084 | s05·notebook_use_01 | 206 mm | 53 px | | 2788 | s04·espressomachine_grab_01 | 175 mm | 67 px | | 6217 | s05·notebook_use_02 | 166 mm | 59 px | | 15975 | s09·notebook_use_03 | 166 mm | 76 px |

4 of 5 worst clips are "notebook" (static typing). These are minimal-motion clips where the hand sits nearly still on a notebook. The model has no motion cue to disambiguate depth, and the small-hand geometry makes 2D pixel prediction hard. This is a systematic dataset skew, not a per-clip bug.


Per-source comparison (v12 → v13, N=25 each)

v12 s3000 v13 s3000 Δ
arctic abs 118 mm 91 mm −27 mm
arctic pixel 36 px 36 px tied
arctic PA 14 mm 13 mm at floor
h2o abs 148 mm 145 mm −3 mm
h2o pixel 78 px 75 px −3 px
h2o PA 22 mm 28 mm +6 mm (regression!)
ho3dv3 abs 269 mm 289 mm +20 mm (expected — dropped from training)

Cross-source gap widened: v12 was 30 mm (arctic 118 vs h2o 148); v13 is 54 mm (91 vs 145). v13 is a stronger arctic specialist but weaker generalizer. h2o PA regressing 22 → 28 mm is the loudest signal — shape parameters overfit to arctic hand distribution.


Decomposing the 36 mm gap

v13 arctic-lite metrics tell the story:

metric v13 oracle contribution
abs MPJPE 90 mm 54 mm (Iter 206) 36 mm gap
rr MPJPE 45 mm (rr contributes to abs) joint pose + orient
PA MPJPE 13 mm 13 mm (floor) at floor, no room
wrist trans 67 mm 0 mm (oracle) dominant abs term
pixel err 35 px 0 px (oracle) 2D residual
depth SSI 0.21 0 (oracle) scale residual

The 90 mm abs breaks down (rough decomposition, from Iter 205/206 ablations):

Totals ~30-40 mm, which matches the 36 mm gap.

No single lever cuts the whole gap. Iter 206's 54 mm oracle uses BOTH GT-2D AND per-clip s* — both interventions together.


Three options, evaluated:

Option A — Multi-res root_head (pixel-focused)

Option C — Add h2o-shape rebalance (fix cross-source)

Recommendation: B (Somantis lift). Directly targets the Iter 206 oracle recipe; the failure mode diagnostic shows no single-bug fix will do; ~500 LoC is spendable and reusing SomantisModel code cuts risk significantly.

Alternative if speed matters: C first (10 LoC weight sampling for immediate 5-10 mm h2o PA gain), then B.


v14 blueprint (Somantis lift)

Model outputs per (frame, hand):
  present   scalar   [BCE]
  root_uv   (2,)     [MSE in normalized coords]
  log_scale scalar   [MSE against robust hand scale]
  j_rel     (20, 2)  [MSE in root-relative + scale-normalized coords]
  vis       (21,)    [BCE per joint]

Loss (from Somantis compute_loss_unified):
  L = 1·L_present + 3·L_root_uv + 1·L_log_scale + 5·L_jrel + 0.5·L_vis
      + (keep) L_cam + L_pmap + L_depth

Inference:
  For each frame t, each hand h:
    reconstruct uv[k] = root_uv + exp(log_scale) · j_rel[k-1]  # (21, 2)
    solve_transl(J0 = template hand at rest, uv, w=vis, K, t_init=weak-perspective)
    → wrist trans t; combine with MANO regressor for joint 3D

Next steps

  1. This report — commit + push (documents the diagnostic + recommendation)
  2. v14 trainer — new file data_engine/train_egowm_v14_lift.py
  3. Adopt SomantisModel representation.py + pnp.py under egowm/hand2d/
  4. Eval script with PnP lift at inference

Expected timeline: - v14 code: 3-4 h (skeleton + smoke + fix) - v14 training: ~1.5 h wall (5000 steps at 0.79 ips) - v14 eval + report: 1 h

Target: v14 s3000 abs ≤ 70 mm on ARCTIC-lite N=40.


Meta