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).
This commit is contained in:
L'électron rare
2026-05-13 23:58:11 +02:00
parent 87b76a42d0
commit 4e7101c54e
+17
View File
@@ -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))