You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
feat(v4-path-e): remove Dk%32 forward shape limit via in-MSL remainder-mask
The fast gated_delta Metal kernel silently truncated the Dk tail (n_per_t=Dk/32 floor dropped
the trailing Dk%32 keys -> wrong answer for non-mult-32 Dk). Fixed in the actual MSL: ceil
tiling n_per_t=(Dk+31)/32 + per-i s_idx<Dk guards on every k/q/state load (additive identity 0
past Dk), and the hard part -- the VECTORIZED KDA gate tail-masked to decay exp(0)=1 (never reads
g_[s_idx] OOB) so the pre-slice simd_sum(kv_mem) is not poisoned. Same mask in the VJP fwd-save +
both backward kernels (incl. guarded [4*Dk] shared-tile writes). Forward now runs for ANY Dk.
Eligibility: shape_uses_fast_kernel True for all shapes (forward); new shape_uses_fast_kernel_backward
keeps Dv%4 for the VJP cooperative reduction. Training still fail-closes to the Python-ops VJP for
Dv%4!=0 (deferred). Gate-sign behavior UNCHANGED (inherent GDN model-math: the kernel has no clamp;
KDA feeds exp(g)>1 into the same kernel and amplifies; the (0,1] bound is the GDN parameterization
a=softplus_inverse(-g)); only the reason string reworded. Provenance: the two kernel files
reclassified verbatim->derived with upstream_base_sha256 + delta note.
Metal parity vs gated_delta_ops (fp32): scalar fwd 65/65 rel<1e-6 (incl Dk 40/96/100/192); KDA
vectorized-gate Dk%32!=0 rel ~1e-7..1e-6; asymmetric, group-expansion, state round-trip bit-exact;
VJP odd-Dk (Dv%4==0) rel ~1e-6. 133 tests pass (65 new odd-shape); 6 unrelated pre-existing; v3 untouched.
"notes": "Snapshot includes the PR #1066 Kahan-compensated kv_mem accumulation + 4-way time-loop unroll; this is NOT identical to an older mlx-lm checkout that predates PR #1066."
"notes": "Was 'verbatim' (PR #1217 snapshot, incl. PR #1066 Kahan kv_mem + 4-way unroll). Reclassified 'derived': cppmega added an in-MSL Dk remainder-mask (ceil tiling n_per_t=(Dk+31)/32 + per-i s_idx<Dk guards; vectorized gate uses decay=1.0 on the masked tail) so the fast Metal forward kernel is correct for ANY Dk, not just Dk%32==0 — upstream silently truncated the trailing Dk%32 keys. upstream_base_sha256 records the pre-delta PR #1217 snapshot; the only delta is this remainder-mask."
26
27
},
27
28
{
28
29
"file": "_mlx_lm_fp8_dequant_vendored.py",
@@ -41,8 +42,9 @@
41
42
"upstream_path": "mlx_lm/models/gated_delta.py (kernel reused; VJP is cppmega-authored)",
42
43
"kind": "derived",
43
44
"used_by": "GDN Path E training backward (fused Metal VJP)",
"notes": "cppmega-authored fused Metal VJP built on the vendored PR #1217 gated_delta_kernel; upstream has no registered VJP. DELTA over upstream_base_sha256: same in-MSL Dk remainder-mask as the forward (ceil tiling + per-i s_idx<Dk guards in fwd-save and both bwd kernels; vectorized gate tail decay=1.0) so the VJP handles any Dk. Still requires Dv%4==0 (four-SIMD-group cooperative reduction over a fixed [4*Dk] tile) — ragged-Dv backward deferred."
0 commit comments