102/102 encoder params load with 0 missing and 0 unmapped. A synthetic voxelised
sphere shell (16,934 voxels) encodes to 56 latent voxels in 135ms on m3ultra, and the
latent comes out mean +0.05 / std 0.92 - the approximately unit-normal distribution a
KL-trained VAE should produce, which is decent evidence the graph and the sparse conv
path are right.
Architecture is inferred from tensor shapes, not constructor defaults: upstream
defaults latent_dim to 8 but the released weights say 32, and attn_mode/pe_mode
defaults are likewise overridden by the trained config. infer_config() reads it off
the checkpoint.
Also added SparseDownsample. Upstream's docstring says average pooling but the code
passes reduce='amax' - following the code.
Kernel orientation: tried latent statistics as a cheap discriminator and it does NOT
work. The flip is not a no-op (max delta 3.53) but both orientations give a plausible
near-unit-normal latent (std 0.919 vs 0.945). Recorded as a negative result; it needs
the decoder and reconstruction quality to settle.
All verified against torch, which IS available here - only spconv was not. So unlike
the submanifold conv these compare against upstream's real semantics rather than a
hand-written paraphrase. 6/6 pass, max err 9.5e-7.
The norm distinction is the trap: LayerNorm32 is applied to x.feats (per-voxel over
channels) while SparseGroupNorm32 reshapes [N_b,C] -> [1,C,N_b] per batch item, so its
statistics span channels-in-group AND voxels. Both produce identical shapes, so a mixup
is numerically silent - there is an explicit test asserting the group norm does NOT
match a per-voxel group_norm.
Architecture confirmed from the converted weights rather than constructor defaults:
no rope, no qk_rms_norm, transformer norms non-affine, ResBlock norm1 affine/norm2 not.