From 4e7101c54ee1cb9f6493fd84172e23b881bf1a80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=27=C3=A9lectron=20rare?= <108685187+electron-rare@users.noreply.github.com> Date: Wed, 13 May 2026 23:58:11 +0200 Subject: [PATCH] fix(multi-hmr): NaN/Inf guard on v3d output Multi-HMR PyTorch MPS sort occasionnellement des v3d avec NaN/Inf ou vertices a magnitudes extremes (>5 m). Ces frames glissaient sans guard jusqu'a AVLiveBody et apparaissaient comme pics/trous sur le mesh. Approche : np.isfinite check sur v3d + transl_np, skip person si invalide. Plus sanity clamp sur |v3d|.max() > 5.0 m : humains ~2 m, au-dela = garbage du modele, skip aussi. Le receiver Swift garde le dernier good mesh pendant les frames skip via retain_window 500 ms (dc7de90). Tradeoff : on perd la frame entiere du pid au lieu de juste les verts NaN. Acceptable car corruption est globale au tensor v3d quand elle arrive (jamais juste 2-3 verts isoles). --- data_only_viz/multi_hmr_worker.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/data_only_viz/multi_hmr_worker.py b/data_only_viz/multi_hmr_worker.py index 916d703..a00b6dc 100644 --- a/data_only_viz/multi_hmr_worker.py +++ b/data_only_viz/multi_hmr_worker.py @@ -369,6 +369,23 @@ class MultiHMRWorker: shape_raw = hh["shape"].detach().cpu().numpy().flatten() expr_raw = hh["expression"].detach().cpu().numpy().flatten() + # Skip persons with NaN/Inf vertices or transl : MPS can + # occasionally emit garbage that propagates to AVLiveBody + # as spikes / holes. We drop the frame for that pid and + # let the receiver's retain window keep the last good mesh. + if (not np.isfinite(v3d).all() + or not np.isfinite(transl_np).all()): + LOG.warning("Multi-HMR NaN/Inf at pid=%d, skipping", pid) + continue + # Sanity clamp on extreme vertex magnitudes (humans are + # ~2 m ; vertices outside [-5, 5] m are model glitches). + if float(np.abs(v3d).max()) > 5.0: + LOG.warning( + "Multi-HMR v3d extreme |max|=%.1f at pid=%d, skipping", + float(np.abs(v3d).max()), pid, + ) + continue + pid_c = pid % self.num_persons shape_n = min(10, len(shape_raw)) expr_n = min(10, len(expr_raw))