Commit Graph

2 Commits

Author SHA1 Message Date
John
95fd4496da Sparse layer set: linear, norms, activations, resblock, attention, transformer blocks
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.
2026-08-02 10:18:38 +10:00
John
97dcdfb54a MLX sparse core: SubMConv3d + SparseTensor + weight converter
The blocker for LATO.2 on Apple Silicon is one op, not the whole setup.sh --all
CUDA stack. Measured: 5 of 7 checkpoints are fully dense, and every SparseConv3d
in the model is constructed stride=1/padding=None, which upstream dispatches to
spconv's SubMConv3d. No strided or inverse sparse conv is ever instantiated.

- SubMConv3d in pure MLX via a sorted-key indice map (27 lookups/voxel vectorised,
  cached per coordinate set the way spconv uses indice_key)
- SparseTensor container + subdivide upsampling
- Converter handles the 5-D layout collision: spconv KRSC [O,kz,ky,kx,I] vs torch
  Conv3d [O,I,kz,ky,kx]. Rank alone is ambiguous; misreading it silently mangles
  the voxel encoder.
- 7/7 tests pass vs an independent naive reference, max err 3e-7. spconv has no
  Metal build so there is no upstream oracle; the reference shares no indexing code.

Kernel orientation (feats[c+d] vs feats[c-d]) remains unverified and is silent
when wrong; --flip-kernel builds the mirror for an end-to-end A/B.
2026-08-02 10:04:24 +10:00