mlx-bun 0.0.12 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (226) hide show
  1. package/README.md +40 -24
  2. package/bin/mlx-bun.mjs +1 -1
  3. package/docs/{design → archive}/hlg-sampling.md +3 -3
  4. package/docs/{investigations → archive/investigations}/hlg-sampling-investigation.md +1 -1
  5. package/docs/archive/investigations/pareto-specialized-runtime-findings.md +92 -0
  6. package/docs/{planning → archive/planning}/chat-ui-vision.md +1 -1
  7. package/docs/archive/planning/release-notes-v0.0.13.md +77 -0
  8. package/docs/{planning → archive/planning}/release-notes-v0.0.9.md +1 -1
  9. package/docs/{planning → archive/planning}/website-readme-pass-plan.md +1 -1
  10. package/docs/design/colibri-glm52-port.md +8 -1
  11. package/docs/design/compat-cli-surface-design.md +1 -1
  12. package/docs/design/decode-speed-program.md +1 -1
  13. package/docs/design/docs-reorg-plan.md +1 -1
  14. package/docs/design/dspark-serving-program.md +1 -1
  15. package/docs/design/dspark-speculative-decoding.md +53 -3
  16. package/docs/design/grammar-spec-batching-integration.md +1 -1
  17. package/docs/design/mlx-lm-serving-execution-seam.md +81 -0
  18. package/docs/design/orpo-dynamic-lambda.md +1 -1
  19. package/docs/design/orpo-future-enhancements.md +1 -1
  20. package/docs/design/orpo-training.md +2 -2
  21. package/docs/design/parity-tier-dag.md +1 -1
  22. package/docs/design/repo-cleanup-plan.md +46 -4
  23. package/docs/design/segmented-backward-training.md +2 -2
  24. package/docs/design/ssd-kv-cold-tier.md +127 -0
  25. package/docs/design/turboquant-weights.md +467 -0
  26. package/docs/design/w4a16-compute-precision-spike.md +1 -1
  27. package/docs/design/web-chat-redesign.md +5 -5
  28. package/docs/planning/chunk-task-roadmap.md +1 -1
  29. package/docs/planning/curve-sampler-research-plan.md +4 -4
  30. package/docs/planning/memory-docs-and-dag-plan.md +1 -1
  31. package/docs/planning/release-notes-v0.2.0.md +49 -0
  32. package/docs/planning/video-series.md +421 -0
  33. package/docs/reference/cli.md +15 -4
  34. package/docs/reference/distribution.md +1 -0
  35. package/docs/reference/features-matrix.md +3 -1
  36. package/docs/reference/library-api.md +41 -1
  37. package/docs/reference/models.md +33 -0
  38. package/docs/reference/server-api.md +86 -19
  39. package/docs/reference/server-config.md +57 -33
  40. package/package.json +2 -2
  41. package/src/anthropic.ts +92 -3
  42. package/src/chat-template.ts +34 -1
  43. package/src/cli.ts +131 -36
  44. package/src/config.ts +10 -0
  45. package/src/eval/kl.ts +27 -20
  46. package/src/eval/runner.ts +23 -4
  47. package/src/eval/tasks/bfcl.ts +2 -1
  48. package/src/eval/tasks/gsm8k.ts +2 -1
  49. package/src/eval/tasks/hashhop.ts +2 -1
  50. package/src/eval/tasks/humaneval.ts +5 -4
  51. package/src/eval/tasks/ifeval.ts +2 -1
  52. package/src/eval/tasks/mmlu.ts +2 -1
  53. package/src/expert-io.ts +3 -1
  54. package/src/expert-offload.ts +3 -1
  55. package/src/expert-trace.ts +3 -1
  56. package/src/fit.ts +24 -43
  57. package/src/flags.ts +7 -9
  58. package/src/generate.ts +107 -92
  59. package/src/grammar.ts +2 -1
  60. package/src/harness-pi.ts +1 -1
  61. package/src/index.ts +20 -0
  62. package/src/jobs/job-entry.ts +3 -2
  63. package/src/kv-scheme.ts +199 -0
  64. package/src/kv-store.ts +370 -205
  65. package/src/media-fetch.ts +19 -3
  66. package/src/memory/model.ts +2 -1
  67. package/src/memory/vault.ts +2 -1
  68. package/src/memory-plan.ts +18 -0
  69. package/src/mlx/ffi.ts +8 -11
  70. package/src/mlx/ops.ts +31 -6
  71. package/src/model/batched-mask.ts +1 -1
  72. package/src/model/batched-quant.ts +1 -1
  73. package/src/model/batched-rotating-quant.ts +43 -97
  74. package/src/model/batched-rotating-state.ts +73 -0
  75. package/src/model/batched-rotating.ts +56 -105
  76. package/src/model/batched-row-storage.ts +127 -0
  77. package/src/model/compiled-decode.ts +3 -2
  78. package/src/model/factory.ts +44 -49
  79. package/src/model/gemma4-base.ts +163 -10
  80. package/src/model/generated/gemma4-12b.ts +50 -146
  81. package/src/model/generated/gemma4-26b.ts +32 -92
  82. package/src/model/generated/gemma4-e4b.ts +26 -74
  83. package/src/model/glm52-cache.ts +19 -9
  84. package/src/model/glm52-memory.ts +28 -1
  85. package/src/model/minicpm5.ts +2 -1
  86. package/src/model/profile.ts +433 -0
  87. package/src/model/qwen3-delta.ts +98 -2
  88. package/src/model/qwen3-mrope.ts +252 -0
  89. package/src/model/qwen3_5.ts +217 -25
  90. package/src/native/frame_extract.swift +140 -0
  91. package/src/native-pack.ts +13 -6
  92. package/src/pi-web.ts +6 -5
  93. package/src/prompt-cache.ts +2 -2
  94. package/src/quantize/atomic-output.ts +38 -0
  95. package/src/quantize/calibration.ts +2 -1
  96. package/src/quantize/config-writer.ts +6 -0
  97. package/src/quantize/index.ts +28 -1
  98. package/src/quantize/job.ts +11 -0
  99. package/src/quantize/quantizer.ts +265 -100
  100. package/src/quantize/rotate.ts +603 -0
  101. package/src/quantize/safetensors-writer.ts +79 -1
  102. package/src/quantize/sensitivity.ts +41 -59
  103. package/src/quantize/weight-transform.ts +292 -0
  104. package/src/responses.ts +102 -2
  105. package/src/runtime-config.ts +67 -0
  106. package/src/sampler.ts +272 -0
  107. package/src/serve/admin-routes.ts +184 -0
  108. package/src/serve/aux-routes.ts +132 -0
  109. package/src/serve/batch-scheduler.ts +200 -87
  110. package/src/serve/completion-executor.ts +346 -0
  111. package/src/serve/completion-sink.ts +157 -0
  112. package/src/serve/discovery-routes.ts +205 -0
  113. package/src/serve/generation-gateway.ts +116 -109
  114. package/src/serve/kv-budget.ts +14 -0
  115. package/src/serve/lab-routes.ts +338 -0
  116. package/src/serve/model-admin-routes.ts +153 -0
  117. package/src/serve/prompt-response-trace.ts +147 -0
  118. package/src/serve/request-plan.ts +158 -0
  119. package/src/serve/static-routes.ts +101 -0
  120. package/src/server.ts +768 -1367
  121. package/src/spec/dflash-source.ts +2 -1
  122. package/src/spec/dspark/module-dflash.ts +1 -1
  123. package/src/spec/glm52-mtp-source.ts +8 -0
  124. package/src/spec/qwen-mtp-source.ts +431 -0
  125. package/src/spec/serve-loop.ts +36 -68
  126. package/src/ssd-cache.ts +17 -14
  127. package/src/ssd-durability.ts +195 -0
  128. package/src/train/flash-cce.ts +12 -11
  129. package/src/train/forward.ts +32 -1
  130. package/src/train/loss.ts +2 -1
  131. package/src/train/segmented.ts +4 -3
  132. package/src/train/trainer.ts +3 -2
  133. package/src/vision/preprocess.ts +1 -1
  134. package/src/vision/prompt.ts +47 -1
  135. package/src/vision/qwen3vl-preprocess.ts +409 -0
  136. package/src/vision/qwen3vl-prompt.ts +196 -0
  137. package/src/vision/qwen3vl-tower.ts +513 -0
  138. package/src/vision/video-frames.ts +148 -0
  139. package/src/web/app.js +10 -3
  140. package/src/web/src/chat.ts +12 -5
  141. package/src/weights.ts +81 -26
  142. /package/docs/{investigations → archive/investigations}/chunk-finetune-experiment.md +0 -0
  143. /package/docs/{investigations → archive/investigations}/colibri-oracle-pin.md +0 -0
  144. /package/docs/{investigations → archive/investigations}/curve-bisector-routing.md +0 -0
  145. /package/docs/{investigations → archive/investigations}/curve-runs/bisector-route.json +0 -0
  146. /package/docs/{investigations → archive/investigations}/curve-runs/bisector-trace.json +0 -0
  147. /package/docs/{investigations → archive/investigations}/curve-runs/curve-terrain.json +0 -0
  148. /package/docs/{investigations → archive/investigations}/curve-runs/curve-terrain.svg +0 -0
  149. /package/docs/{investigations → archive/investigations}/curve-terrain.html +0 -0
  150. /package/docs/{investigations → archive/investigations}/decode-roofline-lookagain.md +0 -0
  151. /package/docs/{investigations → archive/investigations}/dspark-handoff.md +0 -0
  152. /package/docs/{investigations → archive/investigations}/expert-offload-single-user-moe.md +0 -0
  153. /package/docs/{investigations → archive/investigations}/hlg-ab.html +0 -0
  154. /package/docs/{investigations → archive/investigations}/hlg-explorer.html +0 -0
  155. /package/docs/{investigations → archive/investigations}/hlg-figs/cliff.svg +0 -0
  156. /package/docs/{investigations → archive/investigations}/hlg-figs/cross.svg +0 -0
  157. /package/docs/{investigations → archive/investigations}/hlg-figs/edges.svg +0 -0
  158. /package/docs/{investigations → archive/investigations}/hlg-figs/k20-grids.svg +0 -0
  159. /package/docs/{investigations → archive/investigations}/hlg-figs/k20-peaks.svg +0 -0
  160. /package/docs/{investigations → archive/investigations}/hlg-figs/lw-curve.svg +0 -0
  161. /package/docs/{investigations → archive/investigations}/hlg-figs/terrain.svg +0 -0
  162. /package/docs/{investigations → archive/investigations}/hlg-report.html +0 -0
  163. /package/docs/{investigations → archive/investigations}/hlg-runs/hlg-ab.json +0 -0
  164. /package/docs/{investigations → archive/investigations}/hlg-runs/hlg-blind-prompts.md +0 -0
  165. /package/docs/{investigations → archive/investigations}/hlg-runs/hlg-blind.json +0 -0
  166. /package/docs/{investigations → archive/investigations}/hlg-runs/hlg-cliff.json +0 -0
  167. /package/docs/{investigations → archive/investigations}/hlg-runs/hlg-cross.json +0 -0
  168. /package/docs/{investigations → archive/investigations}/hlg-runs/hlg-edge.json +0 -0
  169. /package/docs/{investigations → archive/investigations}/hlg-runs/hlg-eval1.json +0 -0
  170. /package/docs/{investigations → archive/investigations}/hlg-runs/hlg-frontier.json +0 -0
  171. /package/docs/{investigations → archive/investigations}/hlg-runs/hlg-grid.json +0 -0
  172. /package/docs/{investigations → archive/investigations}/hlg-runs/hlg-grid2.json +0 -0
  173. /package/docs/{investigations → archive/investigations}/hlg-runs/hlg-lw-coarse.json +0 -0
  174. /package/docs/{investigations → archive/investigations}/hlg-runs/hlg-map.json +0 -0
  175. /package/docs/{investigations → archive/investigations}/hlg-runs/run0-original.log +0 -0
  176. /package/docs/{investigations → archive/investigations}/hlg-runs/runA-recommended.log +0 -0
  177. /package/docs/{investigations → archive/investigations}/hlg-runs/runAA-cliff-cpm5.log +0 -0
  178. /package/docs/{investigations → archive/investigations}/hlg-runs/runAB-grid2-e4b.log +0 -0
  179. /package/docs/{investigations → archive/investigations}/hlg-runs/runAC-peak-e4b-partial.log +0 -0
  180. /package/docs/{investigations → archive/investigations}/hlg-runs/runAD-ab-samples.log +0 -0
  181. /package/docs/{investigations → archive/investigations}/hlg-runs/runAE-edge-e4b.log +0 -0
  182. /package/docs/{investigations → archive/investigations}/hlg-runs/runAF-logit-calibration.log +0 -0
  183. /package/docs/{investigations → archive/investigations}/hlg-runs/runAG-eval-config2.log +0 -0
  184. /package/docs/{investigations → archive/investigations}/hlg-runs/runB-gain-variants.log +0 -0
  185. /package/docs/{investigations → archive/investigations}/hlg-runs/runC-pivots.log +0 -0
  186. /package/docs/{investigations → archive/investigations}/hlg-runs/runD-oetf.log +0 -0
  187. /package/docs/{investigations → archive/investigations}/hlg-runs/runE-eotf.log +0 -0
  188. /package/docs/{investigations → archive/investigations}/hlg-runs/runF-shaper-working.log +0 -0
  189. /package/docs/{investigations → archive/investigations}/hlg-runs/runG-shaper-sweep.log +0 -0
  190. /package/docs/{investigations → archive/investigations}/hlg-runs/runH-wsweep.log +0 -0
  191. /package/docs/{investigations → archive/investigations}/hlg-runs/runI-asweep.log +0 -0
  192. /package/docs/{investigations → archive/investigations}/hlg-runs/runJ-knobmap.log +0 -0
  193. /package/docs/{investigations → archive/investigations}/hlg-runs/runK-frontier.log +0 -0
  194. /package/docs/{investigations → archive/investigations}/hlg-runs/runL-widemap.log +0 -0
  195. /package/docs/{investigations → archive/investigations}/hlg-runs/runM-frontier-emb.log +0 -0
  196. /package/docs/{investigations → archive/investigations}/hlg-runs/runN-verify.log +0 -0
  197. /package/docs/{investigations → archive/investigations}/hlg-runs/runO-frontier-seed5000.log +0 -0
  198. /package/docs/{investigations → archive/investigations}/hlg-runs/runP-grid-AxSm.log +0 -0
  199. /package/docs/{investigations → archive/investigations}/hlg-runs/runQ-grid-tgW.log +0 -0
  200. /package/docs/{investigations → archive/investigations}/hlg-runs/runR-blind-transcript.log +0 -0
  201. /package/docs/{investigations → archive/investigations}/hlg-runs/runS-cross-coherence.log +0 -0
  202. /package/docs/{investigations → archive/investigations}/hlg-runs/runT-cross-cpm5.log +0 -0
  203. /package/docs/{investigations → archive/investigations}/hlg-runs/runU-cross-12b.log +0 -0
  204. /package/docs/{investigations → archive/investigations}/hlg-runs/runV-lw-e4b.log +0 -0
  205. /package/docs/{investigations → archive/investigations}/hlg-runs/runW-lw-12b.log +0 -0
  206. /package/docs/{investigations → archive/investigations}/hlg-runs/runX-lw-cpm5.log +0 -0
  207. /package/docs/{investigations → archive/investigations}/hlg-runs/runY-cliff-e4b.log +0 -0
  208. /package/docs/{investigations → archive/investigations}/hlg-runs/runZ-cliff-12b.log +0 -0
  209. /package/docs/{investigations → archive/investigations}/indexshare-performance-spike.md +0 -0
  210. /package/docs/{investigations → archive/investigations}/kernel-perf-review-2026-07.md +0 -0
  211. /package/docs/{investigations → archive/investigations}/lab-build-journal.md +0 -0
  212. /package/docs/{investigations → archive/investigations}/openwiki-evaluation.md +0 -0
  213. /package/docs/{investigations → archive/investigations}/orpo-base-uf-experiment-and-directions.md +0 -0
  214. /package/docs/{investigations → archive/investigations}/orpo-flash-cce-pin-leak.md +0 -0
  215. /package/docs/{investigations → archive/investigations}/orpo-uf-testing-handoff.md +0 -0
  216. /package/docs/{investigations → archive/investigations}/pi-builtin-investigation.md +0 -0
  217. /package/docs/{investigations → archive/investigations}/segmented-backward-handoff.md +0 -0
  218. /package/docs/{investigations → archive/investigations}/starter-model-port-handoff.md +0 -0
  219. /package/docs/{investigations → archive/investigations}/steel-flash-cce-handoff.md +0 -0
  220. /package/docs/{investigations → archive/investigations}/trainer-validation-experiment.md +0 -0
  221. /package/docs/{planning → archive/planning}/chat-ui-vision-memory-first.md +0 -0
  222. /package/docs/{planning → archive/planning}/journal.md +0 -0
  223. /package/docs/{planning → archive/planning}/release-notes-v0.0.10.md +0 -0
  224. /package/docs/{planning → archive/planning}/release-notes-v0.0.11.md +0 -0
  225. /package/docs/{planning → archive/planning}/release-notes-v0.0.12.md +0 -0
  226. /package/docs/{planning → archive/planning}/web-ui-pass-plan.md +0 -0
@@ -0,0 +1,467 @@
1
+ # TurboQuant weights — rotation-folded quantization (design)
2
+
3
+ Status: active. Fold recipes and artifact-pipeline integration are implemented;
4
+ quality/release gates remain in PLAN.md "TurboQuant weights". Companion to
5
+ docs/design/turboquant-kv.md (the landed KV leg).
6
+
7
+ ## What it is
8
+
9
+ Fold an orthogonal rotation R offline into producer/consumer weight
10
+ pairs so every weight matrix is quantized in a rotated basis where
11
+ outlier channels are smeared into near-Gaussian marginals — then
12
+ quantize with mlx's EXISTING formats (affine / mxfp4 / nvfp4). Zero
13
+ runtime cost, zero new kernels, output loadable by stock mlx-lm. The
14
+ QuaRot/SpinQuant family; composes with (does not replace) per-layer
15
+ allocation (OptiQ-style) and calibration.
16
+
17
+ Target: `Qwen3.8-27B-MTP-turbo` beating OptiQ-4bit / plain 4bit at
18
+ equal effective bpw (gate: ppl + frozen 6-task eval, eval DB rows).
19
+
20
+ ## Oracle chain
21
+
22
+ "The oracle is whoever ships it": the folding mechanics come from the
23
+ reference repos, read 2026-08-17 (agent fan-out, full-file reads):
24
+
25
+ - **QuaRot** (arXiv:2404.00456, github spcl/QuaRot):
26
+ `fake_quant/rotation_utils.py` (fuse_ln_linear, fuse_layer_norms,
27
+ rotate_model), `fake_quant/hadamard_utils.py` (get_hadK, matmul_hadU,
28
+ random_hadamard_matrix), `fake_quant/model_utils.py`.
29
+ - **SpinQuant** (arXiv:2405.16406, github facebookresearch/SpinQuant):
30
+ `utils/fuse_norm_utils.py` (a copy of QuaRot's γ-fold),
31
+ `eval_utils/rotation_utils.py` (R1/R2 folds), `optimize_rotation.py`
32
+ (Cayley-SGD learned R — deferred to W5).
33
+
34
+ Weight layout: torch and MLX `nn.Linear` are both `[out, in]`,
35
+ `y = x @ W.T` — their fold table transfers verbatim.
36
+
37
+ ## The recipe (weight-only, fully offline)
38
+
39
+ Order matters: γ-fold FIRST (R1 commutes only with gain-free RMSNorm),
40
+ then R1, then R2, then quantize.
41
+
42
+ **0. Untie embeddings** if `tie_word_embeddings` (clone into a separate
43
+ lm_head, set the flag false). Required: step 1 transforms lm_head but
44
+ not embed_tokens. (SpinQuant `ptq.py` does exactly this.)
45
+
46
+ **1. γ-fold (norm fusion)** — for each RMSNorm feeding linears,
47
+ `W' = W · diag(γ)` on the INPUT dim (columns of [out,in]), then set that
48
+ norm's γ to ones (keep the module + its eps — do NOT copy QuaRot's
49
+ replacement RMSN, which hardcodes eps=1e-5; our subjects use 1e-6):
50
+ - input_layernorm → q/k/v_proj
51
+ - post_attention_layernorm → gate/up_proj
52
+ - final norm → lm_head
53
+
54
+ **2. R1 residual fold** — one hidden-size orthogonal R1:
55
+
56
+ | matrix | transform | reason |
57
+ |---|---|---|
58
+ | embed_tokens | `W @ R1` | writes residual (rows are embeddings) |
59
+ | q/k/v_proj | `W @ R1` | reads residual (input dim) |
60
+ | o_proj (+bias) | `R1ᵀ @ W` | writes residual (output dim) |
61
+ | gate/up_proj | `W @ R1` | reads residual |
62
+ | down_proj (+bias) | `R1ᵀ @ W` | writes residual |
63
+ | lm_head | `W @ R1` | reads residual |
64
+
65
+ Q/K outputs untouched → RoPE unaffected. Input-side folds never touch
66
+ biases (bias lives on the output).
67
+
68
+ **3. R2 per-head v/o fold — SpinQuant's version, NOT QuaRot's.** Per
69
+ layer, one head_dim-sized orthogonal R2 applied block-diagonally:
70
+ v_proj output blocks get R2ᵀ, o_proj input blocks get R2; softmax
71
+ weights are R2-invariant so it cancels exactly, incl. under GQA (same
72
+ R2 for all heads; repeat_kv replicates whole heads). QuaRot's variant
73
+ folds a FULL Hadamard into o_proj and needs an ONLINE cross-head
74
+ Hadamard (`online_partial_had`) to cancel — folding its v-side alone
75
+ breaks the network. Skip QuaRot's pairing entirely.
76
+
77
+ **4. Quantize** the folded weights with the stock convert path
78
+ (affine g64 / mxfp4 / nvfp4 arms).
79
+
80
+ Implementation seam (2026-08-20): `WeightTransform` separates pure tensor-name
81
+ planning from lazy tensor application. Llama, Qwen3.5 trunk, and Qwen MTP are
82
+ adapters over that contract; `quantizeModelDir` applies the selected plan in its
83
+ existing module walk. `mlx-bun convert --rotate-weights` selects the adapter,
84
+ and `optiq_metadata.json` records the transform id, family, seed, and deviations.
85
+ Mixed-precision calibration receives a `ProbeSource`; its default builds an
86
+ 8-bit probe through the lower-level writer instead of recursively re-entering
87
+ the top-level quantizer.
88
+
89
+ ### Deviations from the references (decided, with reasons)
90
+
91
+ - **No embedding mean-centering.** Their `fuse_layer_norms`
92
+ mean-centers embedding rows (SliceGPT LayerNorm→RMSNorm trick). For
93
+ RMSNorm models this is NOT an exact-invariance (RMSNorm doesn't
94
+ subtract means) — they do it anyway; we don't, because W0's exit
95
+ criterion is logit parity of the folded bf16 model.
96
+ - **Delete the hidden R4 half-fold.** BOTH repos'
97
+ `rotate_mlp_output` unconditionally applies a full Hadamard to
98
+ down_proj's input dim right after the R1ᵀ fold — that is the offline
99
+ HALF of R4 and requires the runtime `online_full_had` on down_proj's
100
+ activation. Weight-only must skip both halves together (their line:
101
+ QuaRot rotation_utils.py:173 / SpinQuant eval_utils/rotation_utils.py
102
+ 98-100). The `R1ᵀ @ W_down` part stays.
103
+ - **No R3.** Post-RoPE Q/K rotation exists only for KV-cache quant
104
+ (their code registers it only when k_bits < 16). Our KV story is the
105
+ landed TurboQuant KV codec — online rotation remains KV-only.
106
+ - **Fold precision: fp32, not fp64.** References fold in fp64 (fp16-era
107
+ caution). Our weights are bf16 (8-bit mantissa); fp32 accumulation at
108
+ n≲6k leaves ample headroom. Escape hatch if the W0 parity gate fails:
109
+ generate fold goldens in the oracle venv (mlx CPU float64).
110
+
111
+ ### R generation
112
+
113
+ - Random-Hadamard R1 = `diag(±1 signs) · H_n / √n` (QuIP#-style).
114
+ Non-pow-2 n via Kronecker: n = K·2^m with hardcoded H_K, K ∈ {12, 20,
115
+ 28, 36, 40, 44, 52, 60, 108, 140, 156, 172}; else n must be pow-2.
116
+ QR-of-Gaussian `random` mode works for any n (fold-time only, speed
117
+ irrelevant).
118
+ - R2 default: plain Hadamard of head_dim (must be pow-2) or any
119
+ orthogonal.
120
+ - Seed-pin and persist R1/R2 (sidecar JSON in the output snapshot) for
121
+ reproducible artifacts; R is never needed at runtime.
122
+ - W5 (only if random-R wins first): SpinQuant Cayley-SGD learned R1 +
123
+ per-layer R2, folded identically afterward.
124
+
125
+ ## W1 — Qwen3.8 (qwen3_5) corridor map (2026-08-18, from src/model/qwen3_5.ts
126
+ + src/spec/qwen-mtp-source.ts + src/vision/qwen3vl-tower.ts + tensor dumps)
127
+
128
+ **R2 is architecturally OFF for this family:** full attention computes
129
+ `o_proj(attention_output · σ(gate))` — q_proj emits 2×head_dim per head and
130
+ the gate multiplies the attention output ELEMENTWISE in head space. An
131
+ elementwise gate does not commute with a per-head rotation, so only γ+R1
132
+ apply. hidden 5120 = 20·256 — mlx's hadamard_transform takes it natively
133
+ (m·2^k, m ∈ {1,12,20,28}; verified live).
134
+
135
+ Trunk corridors (prefix `language_model.`):
136
+ - readers (@R1 input dim, γ folded in): self_attn.q/k/v_proj,
137
+ linear_attn.in_proj_{qkv,z,b,a}, mlp.gate/up_proj, lm_head (γ = model.norm)
138
+ - writers (R1ᵀ output dim): self_attn.o_proj, linear_attn.out_proj,
139
+ mlp.down_proj
140
+ - vision: `vision_tower.merger.linear_fc2` weight+bias is the ONLY
141
+ vision→residual seam (deepstack is empty for qwen3_5 and not ported) —
142
+ output-dim fold; everything else in the tower passes through bf16
143
+ - untouched internal bases: q_norm/k_norm (head-space), linear_attn.{norm,
144
+ A_log, conv1d, dt_bias} (post-projection), rotary
145
+ - 27B trunk is untied; the 0.8B proof subject is tied (untie step exercised)
146
+
147
+ MTP companion (separate artifact, same seed/R1 — shared residual basis):
148
+ - `fc [H,2H]`: input block 0 = embedding stream (γ = pre_fc_norm_embedding),
149
+ block 1 = hidden stream (γ = pre_fc_norm_hidden) — per-block γ+@R1 — plus
150
+ an output-dim R1ᵀ fold; both pre-fc norms → ones
151
+ - `layers.0`: standard full-attention corridor treatment
152
+ - **final `norm` γ is DROPPED (→ ones):** it feeds the SHARED trunk lm_head,
153
+ which already carries the trunk's final γ. Draft logits therefore see
154
+ γ_trunk instead of γ_mtp — draft-quality-only (the verified target path is
155
+ exact); revisit lever = ship a private folded head inside the companion.
156
+
157
+ Small-scale proof (0.8B, dequantized from OptiQ-4bit since no bf16 is
158
+ published; fold-parity on dequant-vs-folded-dequant tests the fold exactly):
159
+ teacher-forced logits through STOCK mlx-lm (also the W2 cross-stack check) —
160
+ worst per-position KL 0.00353, argmax flips 2/42 positions BOTH at reference
161
+ margin 0.0 (exact ties). scripts/experiments/{dequant-model,fold-qwen35}.ts +
162
+ tq-fold-parity.py.
163
+
164
+ Quantization packaging (CORRECTED 2026-08-18: OptiQ does NOT fully strip
165
+ vision — its main weights omit it but `optiq/optiq_vision.safetensors`
166
+ carries it, and `optiq/mtp.safetensors` bundles MTP; their artifact also
167
+ publishes `optiq/sensitivity.json` — per-layer KL sensitivities for
168
+ {4,8}-bit g64 against the SAME bf16 trunk, the ready-made allocation
169
+ input for a GPTQ+sensitivity mixed pass. No kv_config.json is published.)
170
+ Our packaging: language modules quantize uniformly (embed + lm_head
171
+ included), `vision_tower.*` is predicate-excluded and stays bf16 both
172
+ IN-MAIN (mlx-vlm compatible — OptiQ's sidecar-only vision is not) and as
173
+ the `optiq/` sidecar, so one self-contained artifact serves text+vision
174
+ across stacks.
175
+
176
+ ## Subject models
177
+
178
+ - **W0/W3: mlx-community/Llama-3.2-1B-Instruct-bf16** (~2.5 GB; the
179
+ reference repos' literal target family; 4bit sibling already proven
180
+ in our engine; TIED embeddings → exercises step 0). MiniCPM5-1B has
181
+ no published mlx bf16 (would need a dtype-convert of openbmb's torch
182
+ weights) — alternate subject if Llama surprises us; its geometry is
183
+ fold-friendly too (model_type llama, untied, head_dim 128,
184
+ hidden 1536 = had12 ⊗ H128, eps 1e-6).
185
+ - **W4: mlx-community/Qwen3.8-27B-bf16** (11 shards, 54.7 GB) +
186
+ `Qwen3.8-27B-MTP-bf16` companion (~850 MB, local). The companion
187
+ shares the trunk's residual basis → must fold consistently (W1
188
+ decision). DeltaNet linear-attention corridors: folding math not in
189
+ the papers; derive or fall back to allocation-only for those blocks
190
+ (community quants mark exactly those projections sensitive).
191
+
192
+ ## W3/W4 measured curve (2026-08-18, RTN affine g64, ppl via stock mlx-lm
193
+ on the local UF-derived corpus, seq 512; M1 Max 32 GB)
194
+
195
+ **Headline: rotation-only + RTN does NOT beat plain RTN at the 4-bit
196
+ operating point; it wins decisively at 3-bit — the paper's law, reproduced.**
197
+ Per-module function-space Frobenius error is a wash at 4-bit (~0.091 all
198
+ arms, scripts/experiments/tq-quant-error.py — γs are tame, 0.7–2.7, no
199
+ module class is the culprit); the 4-bit regression is the anisotropy story
200
+ (isotropic rotated error vs activation-aligned plain error), which is
201
+ exactly what GPTQ-style calibration fixes — the composition the paper and
202
+ this doc already name as the real win.
203
+
204
+ 0.8B lab (dequant-OptiQ source; PAIRED arms; bf16 anchor 6.41, 48×512):
205
+
206
+ | arm | bpw | ppl |
207
+ |---|---|---|
208
+ | plain 4-bit | 4.50 | 7.01 |
209
+ | TQ(R1+γ) 4-bit | 4.50 | 7.39 ← regression, reproduces 27B |
210
+ | plain 3-bit | 3.50 | 19.19 ← RTN collapse |
211
+ | **TQ 3-bit** | 3.50 | **14.54** ← rotation −24% ppl |
212
+ | plain mixed (3-bit MLP, 4-bit attn/embed) | 4.15 | 9.69 |
213
+ | **TQ mixed (same profile)** | 4.24 | **9.22** ← paired rotation win |
214
+
215
+ 27B (32×512, same corpus): plain 4-bit 4.659 ±0.093 (4.50 bpw, 15.0 GB) ·
216
+ TQ 4-bit 4.923 ±0.102 (+5.7%, consistent with the lab) · **TQ-mixed
217
+ (4-bit attn/embed + 3-bit MLP) 4.932 ±0.098 at 3.86 bpw / 13.9 GB** —
218
+ matches rotated-uniform-4-bit quality at −0.64 bpw; the artifact of
219
+ record for the 14z M4-Pro fit lever.
220
+
221
+ AWQ-style equalization spike (norm-carried per-channel scales, α=0.5,
222
+ function-preservation verified at KL 0.0037/0 flips): TQ+eq 7.363 (≈no
223
+ change), plain+eq 7.809 (HURT — per-channel scales inside a g64 group
224
+ widen group ranges; real AWQ grid-searches a far gentler α and the real
225
+ 4-bit fix is GPTQ-style compensated rounding). Scripts kept:
226
+ tq-collect-actstats.py + tq-equalize.ts.
227
+
228
+ **End-to-end validation of the TQ-mixed 27B artifact (2026-08-18, M1
229
+ Max, busy box — correctness only):** server chat with correct arithmetic
230
+ reasoning (thinking → `reasoning` field); vision through the folded
231
+ merger + sidecar correctly identifies the gradient fixture's colors over
232
+ HTTP; MTP via the 14g harness with the same-seed folded companion: 71%
233
+ acceptance, 2.40 tok/target-forward, arms token-identical (losslessness),
234
+ ON/OFF 0.726× (consistent with the stock 0.821× correct-but-slower
235
+ verdict; MTP stays opt-in).
236
+
237
+ Consequences for the release recipe: do NOT ship rotated uniform-4-bit
238
+ (loses to the trivial baseline); the shipping artifact is the TQ-mixed
239
+ ≤4 bpw band where rotation is decisively ahead (paired no-rotation
240
+ control worse; uniform-3-bit −24% ppl). The 4.5-bpw flagship win waits
241
+ for the calibration composition (GPTQ on ROTATED weights — the W5 leg).
242
+
243
+ ## W5a corrected-GPTQ matrix (2026-08-18; 0.8B lab, 4.5 bpw arms, 48×512
244
+ ppl, anchor = dequant-OptiQ 6.41 — verified lossless: original OptiQ
245
+ scores 6.4077)
246
+
247
+ mlx-lm's shipped GPTQ (`mlx_lm/quant/gptq.py`) has TWO real defects that
248
+ partially cancel: the in-loop update window is `k:k+j` (over-propagates
249
+ past the block edge; must be `k:j` — the k term itself writes the
250
+ quantized value since e·Hinv[k,k] = w−q) and `err[..., k:k+1]` indexes a
251
+ group-local buffer with the GLOBAL k (mlx out-of-range slice assignment
252
+ silently no-ops → cross-group propagation lost after block 0). Fixing
253
+ only err DOUBLE-compensates [j, k+j) and REGRESSES below RTN (measured:
254
+ 7.22/7.50); fixing both = paper GPTQ. Worth an upstream report.
255
+ Fork: scripts/experiments/tq-gptq.py (also restricts GPTQ+fallback to
256
+ language modules — vision H is a zero scalar and stays bf16).
257
+
258
+ | arm | ppl |
259
+ |---|---|
260
+ | **plain + GPTQ (fixed)** | **6.741** |
261
+ | TQ(R1) + GPTQ (fixed) | 6.847 |
262
+ | plain RTN | 7.010 |
263
+ | TQ RTN | 7.390 |
264
+
265
+ **Verdict: calibration is the main course; rotation SUBTRACTS at the
266
+ 4-bit band even under GPTQ on this family** (gap −1.6%; GPTQ closes half
267
+ the RTN→anchor gap). Rotation remains the sub-4-bpw lever (−24% at
268
+ 3-bit). Flagship recipe = plain + GPTQ 4-bit; TQ-mixed stays the
269
+ small-footprint variant. 27B needs a chunked Hessian/GPTQ driver (stock
270
+ flow = whole bf16 model + all Hessians resident; down_proj H = 1.2 GB
271
+ f32 each).
272
+
273
+ ## W5c 27B production results (2026-08-18)
274
+
275
+ **v2 run (uniform GPTQ-4): BROKEN artifact (ppl 306k).** Root cause,
276
+ evidence-backed: the compensation loop DIVERGED on layers with
277
+ rank-deficient calibration Hessians (layer-0 down_proj group scales grew
278
+ 0.003 → 27 monotonically across columns, max 2.8e7; cosine ~0 vs source;
279
+ neighbors healthy). Early layers see low-rank activations (layer-0 input
280
+ = raw embeddings; rank ≤ distinct calibration tokens), so 5120 dims
281
+ outran the standard 1% damping — the 0.8B (1024 dims) never hit it,
282
+ which is why validation passed there.
283
+
284
+ **v3 fixes (all landed):** divergence guard in `gptq_one_guarded`
285
+ (GPTQ scales vs 4× the RTN scale ceiling per matrix; damping escalation
286
+ 1e-2→10; RTN fallback = never worse than RTN); 4× calibration (128×512);
287
+ sensitivity-driven per-module bits from OptiQ's published
288
+ sensitivity.json (semantics: `sensitivities[b]` = measured KL GAIN at b
289
+ bits — first read had the sign flipped and allocated 0 modules); greedy
290
+ benefit-per-param to `--target-bpw`. v3 27B: 169 modules @8-bit,
291
+ 4.80 bpw, 17.0 GB, ZERO guard triggers (the calibration bump fixed
292
+ conditioning outright), 64 layers in 166 min, per-layer checkpoints.
293
+
294
+ **27B ppl ladder (73×512, UF corpus, stock mlx-lm):** plain RTN-4
295
+ 4.570 ±0.060 · OptiQ 5.14 bpw 4.574 ±0.061 · GPTQ+sens 4.80 bpw
296
+ 4.618 ±0.061. **At 27B every sane ≥4.5-bpw recipe SATURATES this
297
+ instrument** — OptiQ's +0.6 bpw buys nothing measurable, and GPTQ shows
298
+ a small consistent deficit (likely calibration-domain mismatch:
299
+ calibration_v5 vs chat-flavored eval text). This contradicts the 0.8B
300
+ lab ordering (GPTQ clearly won there) — quantization robustness grows
301
+ with scale. Decision moves to task benchmarks: MMLU-100 + GSM8K-50
302
+ across {GPTQ-v3, plain4, OptiQ, TQ-mixed}, eval DB rows.
303
+
304
+ ## FINAL BOARD + DECISION (2026-08-18 night 2)
305
+
306
+ Task evals (lean mlx-lm runner, paired items; in-engine sweep swap-thrashed
307
+ the box — 73 GB swap at 0.7 GB resident — killed, gap recorded below):
308
+
309
+ | arm | bpw | GB | ppl(73×512) | MMLU-100 | GSM8K-50 |
310
+ |---|---|---|---|---|---|
311
+ | **GPTQ+sens v3 (SHIPPED as mjriii/Qwen3.8-27B)** | 4.80 | 16.3 | 4.618 | 87 | **96** |
312
+ | plain RTN 4-bit | 4.50 | 15.0 | **4.570** | 88 | 94 |
313
+ | OptiQ published | 5.14 | 18.1 | 4.574 | **89** | 92 |
314
+ | TQ-mixed (staged, small-footprint variant) | 3.86 | 13.0 | 4.93 | 82 | 96 |
315
+
316
+ All ≥4.5-bpw arms statistically tied on every instrument — 27B quality
317
+ SATURATES at 4-bit; recipes differentiate below 4 bpw and on
318
+ completeness. THE artifact = v3 (never trails; protective recipe;
319
+ one-repo vision+video+MTP; additive to the ecosystem where plain-4bit
320
+ already exists publicly). Serve gauntlet on THE artifact through OUR
321
+ engine: text ✓ (23×19), image ✓ ("Green and pink"), video ✓ (gradient
322
+ motion described; AVFoundation chain), MTP harness 76% accept /
323
+ 2.53 tok-per-forward with an output-divergence flag vs plain greedy
324
+ (consistent with verify-width reduction-order near-ties, 12B step-0
325
+ class — margin analysis queued; NOT claimed lossless on the card).
326
+
327
+ ## Territory-mapping campaign (2026-08-18/19, Josh-directed: "map all the
328
+ levers before concluding TQ-off")
329
+
330
+ **sens3 arm (Josh's recipe: rotated 3-bit base + sensitivity-driven 8-bit,
331
+ 4.26 bpw / 15.25 GB incl. vision):** ppl 4.630 ±0.058 — TIED with the
332
+ 4.80-bpw flagship (4.618) at −0.54 bpw, and a full recovery over
333
+ unprotected TQ-mixed (4.93). GSM8K 46/50 = 92% (plateau band). **MMLU
334
+ 83/100 — the 3-bit-base dip persists** (TQ-mixed scored 82): two
335
+ independent 3-bit-base arms at 82–83 vs the 87–89 plateau → the
336
+ knowledge-recall damage is SMEARED across the MLP long tail; KL-derived
337
+ sensitivity shields fluency, not recall. Lever under test next: rotated
338
+ 4-bit g128 (4.25 bpw — same size, 4-bit granularity everywhere).
339
+
340
+ Perplexity proxy calibration (from our own table): deltas <~0.1 ppl are
341
+ task-invisible; ~0.3+ coincides with visible MMLU damage; ppl's
342
+ remaining role is catastrophe detection + screening. mlx kernel bound:
343
+ group_size ∈ {32, 64, 128} — 256+ needs custom kernels (non-goal).
344
+
345
+ **Group-size lab (0.8B ppl) + 27B g128 arm:** rotation does NOT buy
346
+ coarse-group tolerance at 4-bit (tax +4.7% rotated vs +4.2% plain); at
347
+ 3-bit the dividend is real but partial (+29% vs +47%; rotated 3.25 bpw ≈
348
+ plain 3.5 bpw). 27B plain-4bit-g128 (4.25 bpw): ppl 4.714 (+3%), MMLU 88
349
+ (plateau!), **GSM8K 62% — COLLAPSE via generation-behavior damage**
350
+ (eyeballed: correct-but-rambling truncations + instant-EOS empty
351
+ outputs; single-forward instruments blind to it). Lessons: (1) ppl deltas
352
+ DO NOT bound task damage (+0.14 ppl ↔ −32 GSM8K pts) — the earlier
353
+ "~0.3 ppl = visible damage" calibration is WRONG; every finalist needs
354
+ generative tasks; (2) g128 disqualified for generative work.
355
+
356
+ **Run B — the full suite (rotation + GPTQ + sensitivity, 4.80 bpw,
357
+ 17.0 GB, zero guard triggers):** ppl **4.5965** (best quantized arm,
358
+ tied w/ plain-4bit) · MMLU 84 · raw-completion GSM8K **24% — and the
359
+ collapse is a FORMAT CLIFF, not a reasoning failure**: when it answers
360
+ it is flawless, but 3/4 raw few-shot prompts get INSTANT EOS; under the
361
+ native chat template it always answers (3/5 correct at a tight token
362
+ cap). g128's 62% was the same failure at lower frequency. **Methodology
363
+ consequence: the raw-completion GSM8K column conflates math ability
364
+ with EOS-cliff robustness** — different quant-noise realizations
365
+ displace a razor-thin answer-vs-stop margin at token 0. The map now
366
+ carries TWO generative columns: templated GSM8K (serving-path
367
+ reasoning, re-run across all live arms) and raw-completion GSM8K
368
+ (format-robustness probe). Neither ppl nor MMLU sees any of this.
369
+
370
+ ## THE FRONTIER (campaign complete, 2026-08-19 — map:
371
+ reports/frontier-map-2026-08-19.html)
372
+
373
+ | arm | bpw | GB | ppl | MMLU | tGSM | rawGSM | tok/s* | Pareto |
374
+ |---|---|---|---|---|---|---|---|---|
375
+ | **rot+sens48 RTN (Josh's recipe)** | 4.79 | 17.0 | 4.680 | **90** | 94 | 84 | **11.80** | **YES** |
376
+ | GPTQ+sens (staged flagship) | 4.80 | 17.0 | 4.618 | 87 | 94 | **96** | 11.42 | — |
377
+ | rot+GPTQ+sens (full suite) | 4.80 | 17.0 | **4.597** | 84 | 94 | 24 | 11.77 | — |
378
+ | OptiQ published | 5.14 | 18.1 | 4.574 | 89 | 94 | 92 | 8.92 | — (dominated) |
379
+ | **TQ-mixed** | 3.86 | 13.0 | 4.932 | 82 | 82 | 96 | 10.94 | **YES** |
380
+ | bf16 ceiling (streamed eval) | 16 | 54.4 | 4.552 | 87 | n/a | n/a | n/a | ref |
381
+
382
+ *busy-box, spreads 8–34% — directional until quiet benchmark.sh.
383
+
384
+ Findings of record: (1) the ≥4.5-bpw band sits AT the bf16 ceiling (ppl
385
+ within ~1%, MMLU within noise — a quant scoring 90 vs ceiling 87 proves
386
+ ±3 noise); (2) BOTH Pareto points are ROTATED — rotation at 4-bit is
387
+ competitive exactly when paired with sensitivity allocation (the earlier
388
+ uniform-rotation loss concentrated in the sensitive modules, as Josh
389
+ hypothesized), and mandatory below 4 bpw; (3) OptiQ is dominated on all
390
+ three axes (its extra 0.34 bpw buys nothing and costs ~25% decode);
391
+ (4) GPTQ's measurable 27B contribution is ppl-only — it buys no task
392
+ quality at this scale and (with rotation) costs raw-format robustness;
393
+ (5) 3-bit kernels pay an unpack tax that eats their bandwidth win
394
+ (TQ-mixed slower than 4-bit arms despite −4 GB); (6) cross-engine parity
395
+ CERTIFIED (byte-identical greedy, ours vs stock mlx-lm, on the staged
396
+ flagship). Remaining before publish: promote+package the chosen artifact,
397
+ its serve gauntlet, quiet-box TPS, M4 Pro 24 GB cut (Josh-gated).
398
+
399
+ ## Known engine gaps found in passing (not TQ defects)
400
+
401
+ - `mlx-bun perplexity` cannot score qwen3_5: it routes through
402
+ `trainForward`, whose cache stub lacks the DeltaNet `SSMCache.advance`
403
+ (`qwen3_5.ts:226` throws on BOTH plain and TQ arms identically).
404
+ 27B ppl therefore runs through stock mlx-lm
405
+ (scripts/experiments/tq-ppl.py) — which doubles as the cross-stack
406
+ load check for the release artifact.
407
+ - bf16 (unquantized) qwen3_5 trunks don't load in our engine:
408
+ `QuantizedEmbedding.load`/`QuantizedLinear.load` hard-require `.scales`.
409
+ The small-scale fold proof ran through stock mlx-lm instead.
410
+ - `scripts/eval.ts` capability tasks at 27B swap-thrash a 32 GB box
411
+ (73 GB swapfiles, process 95% paged out) where the mlx-lm scoring path
412
+ is fine — investigate the in-engine eval memory profile.
413
+ - Qwen MTP via the HTTP serve lane 500s with `[slice] Invalid number of
414
+ indices or strides for array with dimension 3` — REPRODUCES WITH STOCK
415
+ ARTIFACTS (plain-4bit trunk + original mlx-community MTP companion,
416
+ `serve --draft-model <companion> --draft-kind mtp`, any chat request),
417
+ so it is a pre-existing serving-path bug, not TQ. The 14g harness path
418
+ (specServeRun via scripts/experiments/qwen38-mtp-ab.ts) is the green
419
+ gate; TQ MTP was validated through that.
420
+
421
+ ## Non-goals
422
+
423
+ Mirrors the PLAN.md phase: no custom weight format / new qmm kernels,
424
+ no activation quant, no runtime weight rotation, no GGUF/AWQ export.
425
+
426
+ ## M4 Pro 24 GB speed row (2026-08-20, mlx-bun, winner artifact)
427
+
428
+ Measured on the second reference machine (M4 Pro, 24 GB, ~273 GB/s) with
429
+ `sysctl iogpu.wired_limit_mb=21504` and the DeltaNet leak fix (37de0d0):
430
+
431
+ | prompt | prefill tok/s | TTFT | decode tok/s | notes |
432
+ |---|---|---|---|---|
433
+ | 1,024 | 127 | 8.1 s | 14.66 (1.1%) | chunk 2048 |
434
+ | 8,192 | 124 | 66 s | 14.13 (1.3%) | chunk 2048 |
435
+ | 32,768 | 114 | 288 s | 12.77 | chunk 1024 (peak 19.3 GB) |
436
+
437
+ - **Compute-bound decode confirmed cross-machine:** 14.7 tok/s here vs
438
+ 11.8 on the M1 Max (400 GB/s) — the machine with 68% of the bandwidth
439
+ is 25% FASTER. Decode is dequant-ALU-bound, not weight-streaming-bound
440
+ (supporting M1 telemetry: GPU 100% @ ~266 GB/s of 400). Kernel headroom
441
+ to the ~24 tok/s bandwidth roofline is a future perf program.
442
+ - **Decode-at-depth is nearly flat** (−13% at 32× context): only 16 of 64
443
+ layers grow KV; DeltaNet state is constant.
444
+ - **Prefill transient scales with chunk × offset** (~2.8 GB at 24k with
445
+ 2048-chunks; measured via MLX_BUN_PREFILL_MEM_LOG): on 24 GB the 32k row
446
+ needs 1024-token chunks (−8% prefill). Engine follow-up: serve should
447
+ scale prefillChunkSize from fit.ts headroom automatically.
448
+ - Prefill absolute rate (~125 tok/s) is the weak axis — suspected
449
+ DeltaNet per-token recurrence during prefill; compare against mlx-lm
450
+ same-box before treating as our bug (oracle-gap rule).
451
+
452
+ ### Compact sibling on the M4 (same protocol, chunk 1024 all rows)
453
+
454
+ | prompt | prefill tok/s | TTFT | decode tok/s (spread) |
455
+ |---|---|---|---|
456
+ | 1,024 | 117 | 8.8 s | **17.14** (0.7%) |
457
+ | 8,192 | 124 | 66 s | 16.05 (2.4%) |
458
+ | 32,768 | 85 | 6.4 min | 13.80 (2.9%) |
459
+
460
+ **The 3-bit speed verdict is GPU-generation-dependent:** on M1 Max the
461
+ 3-bit-heavy artifact decoded SLOWER than the 4/8 winner (10.94 vs 11.80 —
462
+ unpack ALU dominates); on M4 Pro it decodes FASTER (17.14 vs 14.66 —
463
+ newer ALU absorbs the unpack, fewer bytes win). Card guidance: M1-class →
464
+ winner fastest; M4-class → compact is smaller AND faster. Compact 32k
465
+ prefill (85 tok/s) is its weak axis. Peak not instrumented this run;
466
+ estimated ~16 GB at 32k (likely fits the DEFAULT 24 GB wired limit —
467
+ untested).
@@ -226,7 +226,7 @@ fwd `:174–270`, SG bwd `:561–726`, gates `:732`/`:739`/`:1034`/`:1130`; stag
226
226
 
227
227
  **Cross-links:** [[flash-cce-metal-kernel-prototype]] · [[three-level-fidelity-tree-model]]
228
228
  · [[opssdpa-dk-vjp-bug]] · [[e4b-forward-length-sensitivity]] ·
229
- [[verify-benchmarks-against-evaldb-not-docs]] · `docs/investigations/steel-flash-cce-handoff.md`.
229
+ [[verify-benchmarks-against-evaldb-not-docs]] · `docs/archive/investigations/steel-flash-cce-handoff.md`.
230
230
 
231
231
  **Sibling deferred lever** (queued together, post-run): `docs/design/orpo-future-enhancements.md`
232
232
  → "Deferred levers" (expose `--grad-accum`).
@@ -4,10 +4,10 @@ Status: proposed · Owner: web/chat surface · Scope: `src/web/app.html`, `src/p
4
4
 
5
5
  This document merges three independent design visions, ten market-research
6
6
  briefs, and a line-level audit of the current UI and backend into one
7
- execution plan. It supersedes `docs/planning/chat-ui-vision.md` and
8
- `docs/planning/chat-ui-vision-memory-first.md` as the working plan (keep
7
+ execution plan. It supersedes `docs/archive/planning/chat-ui-vision.md` and
8
+ `docs/archive/planning/chat-ui-vision-memory-first.md` as the working plan (keep
9
9
  those two as historical inputs; this is the doc that gets executed against).
10
- It also absorbs and re-prioritizes every item in `docs/planning/web-ui-pass-plan.md`
10
+ It also absorbs and re-prioritizes every item in `docs/archive/planning/web-ui-pass-plan.md`
11
11
  — those bug-fixes are folded into Phase 0/1 below by number.
12
12
 
13
13
  ---
@@ -161,7 +161,7 @@ Ranked by severity, from the three-part current-state audit:
161
161
  2737 lines, no documented keyboard shortcuts beyond Enter/Shift+Enter,
162
162
  no chat search, generic non-personalized hero/empty-state.**
163
163
 
164
- Plus the full tactical list already catalogued in `docs/planning/web-ui-pass-plan.md`
164
+ Plus the full tactical list already catalogued in `docs/archive/planning/web-ui-pass-plan.md`
165
165
  (queue-bar array-truthiness bug, library staleness, `[object Object]` adapter
166
166
  error, dead `status-page.html`, Routes-tab 404 in the compiled binary, stale
167
167
  vision copy, etc.) — folded into Phase 0/1 below by number, not repeated in
@@ -814,7 +814,7 @@ bugs fixed as part of the IA move (§9 Phase 1).
814
814
  ## 9. Phased roadmap
815
815
 
816
816
  Each phase is independently shippable and includes the relevant tactical
817
- fixes from `docs/planning/web-ui-pass-plan.md` by number. Ordered by
817
+ fixes from `docs/archive/planning/web-ui-pass-plan.md` by number. Ordered by
818
818
  effort/reward, starting with free wins, ending with differentiator
819
819
  features. The [beat matrix](web-chat-beat-matrix.md) is the coverage
820
820
  checklist across all phases: at any release point, every matrix row is
@@ -2,7 +2,7 @@
2
2
 
3
3
  Where the MiniCPM5 chunking adapter stands and what raises real segmentation
4
4
  quality. Companion to the chunk-eval metric vs. accuracy finding (score = well-formedness, not gold accuracy) and
5
- [`docs/investigations/chunk-finetune-experiment.md`](../investigations/chunk-finetune-experiment.md).
5
+ [`docs/archive/investigations/chunk-finetune-experiment.md`](../investigations/chunk-finetune-experiment.md).
6
6
 
7
7
  ## Where we are
8
8
 
@@ -250,8 +250,8 @@ diversity; the audit below as methods material).
250
250
 
251
251
  ## 6. Why the old data is not trusted — audit of the prior experiments
252
252
 
253
- Committed artifacts checked: `docs/investigations/curve-runs/*.json`,
254
- `docs/investigations/hlg-runs/*`, harness sources. Severity: **INVALIDATES** /
253
+ Committed artifacts checked: `docs/archive/investigations/curve-runs/*.json`,
254
+ `docs/archive/investigations/hlg-runs/*`, harness sources. Severity: **INVALIDATES** /
255
255
  **WEAKENS** / cosmetic.
256
256
 
257
257
  - **F1 — INVALIDATES (the old distinctness claim).** The curve-temp family
@@ -327,5 +327,5 @@ Committed artifacts checked: `docs/investigations/curve-runs/*.json`,
327
327
  - Witness probe: `scripts/experiments/curve-distinctness.ts`.
328
328
  - Assessment: `reports/curve-designer-paper-assessment-2026-07-01.md`.
329
329
  - Prior investigations (superseded on the points in §6):
330
- `docs/investigations/hlg-sampling-investigation.md`,
331
- `docs/investigations/curve-bisector-routing.md`.
330
+ `docs/archive/investigations/hlg-sampling-investigation.md`,
331
+ `docs/archive/investigations/curve-bisector-routing.md`.
@@ -21,7 +21,7 @@ are treated as the direction of record and untouched.
21
21
  | `docs/design/bucketing-stage.md` | Classify-stage design (2026-06-26) | **No banner.** Core content (embeddings as candidate-narrower) is dead under "no embeddings anywhere"; the binary-question ladder survives inside the nightly BUCKET stage | **Needs a SUPERSEDED banner** (same shape as memory-synthesis's): dead = embedding narrower + silhouette; survives = capacity-by-decomposition, one-binary-question-at-a-time. |
22
22
  | `docs/design/write-pipeline-entity.md` | Entity-keyed routing design (2026-06-26); itself "supersedes bucket-centric routing" | **No banner.** Half-dead: pure entity ROUTE (no bucket layer) is replaced by BUCKET→RESOLVE; the personal-notability checklist is dead. Survives: articles-are-THINGS, name/alias/category lookup, no-embeddings routing | **Needs a PARTIALLY SUPERSEDED banner** mapping survives/dead — otherwise its own "supersedes bucketing" claim inverts the actual chain for a newcomer. |
23
23
  | `docs/design/memory-system.md` | M0 substrate design (vault, read tools, CLI, scheduling, consent) | **Status header is FALSE**: "synthesize is currently a safe no-op stub", "stage modules throw if called" — the pipeline is built and has produced 677+ articles. Directly contradicts `docs/reference/memory.md`. The four-adapter table + "Next implementation steps" describe the abandoned M1 sketch | **Fix the header + scope it down.** Retitle scope to "M0 substrate: vault + read path (landed)"; delete or banner the "Synthesis pipeline design (M1/M2)" and "Next implementation steps" sections, pointing at dreaming-nightly-pipeline. The substrate half (storage layout, tools, skill, scheduling, consent) is still the best writeup of the read side — keep it. |
24
- | `docs/design/memory-inference-path.md` | Inference-path rework: design + measured verification | Accurate, self-bannered (BUILT + VERIFIED; batching measured a loss). It's really an investigation record | Fine as-is. Optional (low priority): move to `docs/investigations/` where measured-experiment records live. |
24
+ | `docs/design/memory-inference-path.md` | Inference-path rework: design + measured verification | Accurate, self-bannered (BUILT + VERIFIED; batching measured a loss). It's really an investigation record | Fine as-is. Optional (low priority): move to `docs/archive/investigations/` where measured-experiment records live. |
25
25
  | `docs/reference/memory.md` | User-facing reference | Mostly current (synthesize description matches as-built stages; status truth fixed 2026-07-01). **But** the "Synthesis roadmap" section still tells the old four-named-LoRA / HF-adapter-pack story (memory-bucket/memory-synthesis/memory-editor LoRAs "distributed from Hugging Face") — not the plan of record (`memory-<stage>` convention, only `memory-chunk` exists, base+policy otherwise) | **Rewrite the roadmap section** to the as-built stage list + the `memory-<stage>` adapter convention; update stage names again when BUCKET/RESOLVE land. |
26
26
  | `STATUS.md` § THE DREAMING | Live state | Current and correct (batch default 1, third-person fix merged, import paused at cursor 900/2096, inference-path landed) | Keep as the ONLY live-state location. |
27
27
 
@@ -0,0 +1,49 @@
1
+ # mlx-bun v0.2.0
2
+
3
+ Version 0.2.0 is the first release with the complete Qwen3.8 serving path:
4
+ text, images, video, thinking controls, tool calls, and native MTP speculation.
5
+ It also ships the serving and memory work completed since v0.0.13.
6
+
7
+ ## Highlights
8
+
9
+ - Qwen3.8 image input now runs through the dedicated vision tower and mRoPE
10
+ path. Video content parts decode through the bundled AVFoundation helper,
11
+ sample frames at 2 fps, and use the gated Qwen video pipeline.
12
+ - Qwen native MTP can mount from a separate companion or an artifact's `mtp/`
13
+ directory. Rejected drafts restore recurrent DeltaNet state correctly.
14
+ - The default continuous scheduler now shares request planning, sampling,
15
+ usage accounting, cache selection, and protocol events with the strict
16
+ serial executor. `--batch 1` remains the explicit serial pin.
17
+ - Memory admission treats `max_tokens` as a ceiling. If the prompt fits, the
18
+ server caps generation to the safe remaining context instead of rejecting a
19
+ broad client default.
20
+ - `convert --rotate-weights` folds supported rotations before quantization.
21
+ The offline pipeline also gained streamed shard handling, 3-bit GPTQ, and
22
+ atomic output publication.
23
+
24
+ ## Reliability and performance fixes
25
+
26
+ - Large Qwen models now enter the same wired-memory scope as mlx-lm during
27
+ serial and continuous execution. This removes the token-zero residency
28
+ stall on machines whose recommended working set grew beyond the old cutoff.
29
+ - DeltaNet prefill and batch-row extraction now copy owned cache state instead
30
+ of pinning whole chunk buffers.
31
+ - SSD prompt-cache snapshots stay dirty until atomic storage completes.
32
+ `POST /admin/cache/flush` and normal SIGINT/SIGTERM shutdown provide an
33
+ explicit durability boundary.
34
+ - Rotating-cache batch joins now dispatch by cache capability and preserve the
35
+ correct rotating signature.
36
+ - Qwen and GLM MTP sampling no longer passes a rank-3 logits tensor into the
37
+ rank-2 sampler.
38
+
39
+ ## Distribution
40
+
41
+ - macOS on Apple Silicon remains the supported platform.
42
+ - Source and npm installs require Bun 1.4.0 or newer.
43
+ - Direct downloads and Homebrew use the signed, notarized self-contained
44
+ archive.
45
+ - npm and `bunx` use native pack v0.3.0, which includes MLX, the bounded expert
46
+ I/O helper, and the AVFoundation frame extractor.
47
+
48
+ Upgrade with `brew upgrade joshuarossi/tap/mlx-bun`, `bun update -g mlx-bun`,
49
+ or rerun the direct installer.