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
Found by the post-0.3.0 Bonsai-8B KV re-validation (main d8d7463, release-perf, M5 Max, nax=288, temp=0, n=3 / n=1@64k, same harness as docs/models/bonsai/8B/rMLX.md).
Symptom: the *_sym family regressed at EVERY context
codec
4k (0.2.5 → now)
64k (0.2.5 → now)
iso3_sym
133.2 → 18.9 (−86%)
5.9 → 2.4 (−59%)
iso4_sym
131.4 → 17.6 (−87%)
5.7 → 1.8 (−68%)
rotor3_sym
136.2 → 18.0 (−87%)
5.8 → 2.3 (−60%)
rotor4_sym
132.7 → 16.9 (−87%)
7.3 → 1.7 (−77%)
The symv flash-decode kernel (#219/#220, always-on after the sole-store work #279/#281/#285) provably dispatches on GPU (iso_flash_decode_symv_sdpa/rotor_flash_decode_symv_sdpa ×182 per run). It was built to fix the 64k CPU-dequant collapse — instead it is now 2.4–4.3× SLOWER than the CPU path it replaced at 64k. A GPU kernel losing to CPU dequant is a defect, not a tradeoff.
Root cause is the quantized-V path, not flash-decode generally
Marginal decode cost, fit itl = a + b·kv_seq over 4k→64k (ms per 1k KV tokens):
family
marginal
vs none
none (bf16 K+V)
0.32
1×
K-only k_iso3/4, k_rotor3/4 (quant K, bf16 V)
2.32 / 3.34 / 2.94 / 3.01
7–10×
*_sym (quant K and V)
5.92 / 8.12 / 6.17 / 8.61
18–27×
Quantizing V roughly doubles the marginal cost on top of quantizing K. The K-only ratio to bf16 is flat (~5→7-9× across 4k→64k); the _sym ratio diverges (7.1× @4k → 15.5× @64k), so no crossover is reachable at any context. Consistent with the pre-existing "4-bit-V codecs crater decode" finding for k8v4/rot_k_tq4v on this model.
And the memory win doesn't materialize
At 64k: none10536 MB, iso3_sym 10640, k_iso3 10588, rotor3_sym 12928, k_rotor3 16255. The sole-store work shrank _sym a lot (30608 → 10640, −65%) but it still lands at or above bf16. So _sym costs the same memory as none and decodes 15× slower — strictly dominated on both axes, at every context.
Proposed fix
Stop routing *_sym decode through the symv kernel by default — it is strictly dominated today. Either restore a bf16-V decode path or gate the kernel off until it is competitive.
Attack the V-side dequant in the flash-decode step — that is where the extra ~3–5 ms/1k lives. The K-side path (K-only codecs) is already ~2.5× cheaper and stable, so the kernel scaffolding is not the problem.
Contrast — the K-only work is a genuine win (do not revert)
Same push rescued k_iso*/k_rotor* from CPU-bound unusability: 4k 0.7–5.8 → 21–26 TPS, and they now run the full range (baseline capped them at 8–16k). --rotor-qjl default off alone is ~30–34×.
Raw cells + kernel-dispatch proofs captured in the sweep checkpoint; real runs.db untouched (scratch RMLX_HOME).
Found by the post-0.3.0 Bonsai-8B KV re-validation (main
d8d7463, release-perf, M5 Max, nax=288, temp=0, n=3 / n=1@64k, same harness asdocs/models/bonsai/8B/rMLX.md).Symptom: the
*_symfamily regressed at EVERY contextThe symv flash-decode kernel (#219/#220, always-on after the sole-store work #279/#281/#285) provably dispatches on GPU (
iso_flash_decode_symv_sdpa/rotor_flash_decode_symv_sdpa×182 per run). It was built to fix the 64k CPU-dequant collapse — instead it is now 2.4–4.3× SLOWER than the CPU path it replaced at 64k. A GPU kernel losing to CPU dequant is a defect, not a tradeoff.Root cause is the quantized-V path, not flash-decode generally
Marginal decode cost, fit
itl = a + b·kv_seqover 4k→64k (ms per 1k KV tokens):none(bf16 K+V)k_iso3/4,k_rotor3/4(quant K, bf16 V)*_sym(quant K and V)Quantizing V roughly doubles the marginal cost on top of quantizing K. The K-only ratio to bf16 is flat (~5→7-9× across 4k→64k); the
_symratio diverges (7.1× @4k → 15.5× @64k), so no crossover is reachable at any context. Consistent with the pre-existing "4-bit-V codecs crater decode" finding fork8v4/rot_k_tq4von this model.And the memory win doesn't materialize
At 64k:
none10536 MB, iso3_sym 10640, k_iso3 10588, rotor3_sym 12928, k_rotor3 16255. The sole-store work shrank_syma lot (30608 → 10640, −65%) but it still lands at or above bf16. So_symcosts the same memory asnoneand decodes 15× slower — strictly dominated on both axes, at every context.Proposed fix
*_symdecode through the symv kernel by default — it is strictly dominated today. Either restore a bf16-V decode path or gate the kernel off until it is competitive.Contrast — the K-only work is a genuine win (do not revert)
Same push rescued
k_iso*/k_rotor*from CPU-bound unusability: 4k 0.7–5.8 → 21–26 TPS, and they now run the full range (baseline capped them at 8–16k).--rotor-qjldefaultoffalone is ~30–34×.Raw cells + kernel-dispatch proofs captured in the sweep checkpoint; real
runs.dbuntouched (scratch RMLX_HOME).🤖 Generated with Claude Code