52588b9910
Root cause of v3d/transl NaN identified: roma.rotmat_to_rotvec uses torch.empty + 8 index_put_ on a buffer that CoreML mlprogram translates as scatter_nd over a garbage-initialised tensor. Cells that the scatter chain misses keep NaN; the subsequent quat / norm propagates NaN to every vertex. Patch: branchless atan2 formulation (stack/clamp/norm/atan2 only), no torch.empty, no index_put_. Precision drift vs roma original: 2.26e-6 L_inf on random batches. Mlpackage now validates all outputs finite (1.27e-4 L_inf vs PyTorch eager on v3d). Bench standalone: 65 ms median FP16 (15.3 fps, target met). Live with 3 parallel workers: 8 fps Multi-HMR keyframe rate (2.3x speedup vs PyTorch MPS baseline 3.5 fps); rigging still ships at 15-20 fps perceived. Output names shifted post-patch (var_2541 -> var_2412 etc) so multihmr_coreml.py constants updated.