mlx-bun 0.2.0 → 0.3.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 (364) hide show
  1. package/README.md +71 -588
  2. package/docs/README.md +91 -0
  3. package/docs/{design → archive/investigations}/audio-input-plan.md +4 -4
  4. package/docs/{design → archive/investigations}/diffusion-gemma-port.md +3 -3
  5. package/docs/{design → archive/investigations}/faithful-l1-consolidation.md +4 -4
  6. package/docs/{design → archive/investigations}/minicpm5-decode-megakernel.md +11 -11
  7. package/docs/{design → archive/investigations}/optimization_plan.md +1 -1
  8. package/docs/{design → archive/investigations}/pre-colibri-stabilization.md +5 -5
  9. package/docs/{design → archive/investigations}/the-dreaming-handoff.md +2 -2
  10. package/docs/design/batching.md +569 -0
  11. package/docs/design/decode-speed-program.md +3178 -169
  12. package/docs/design/dreaming-nightly-pipeline.md +675 -282
  13. package/docs/design/generic-model-support.md +579 -334
  14. package/docs/design/kv-cache.md +680 -0
  15. package/docs/design/orpo-training.md +673 -1239
  16. package/docs/design/speculative-decoding.md +1627 -0
  17. package/docs/design/turboquant.md +2102 -0
  18. package/docs/design/unified-engine-frontier-plan.md +1831 -727
  19. package/docs/design/web-chat-redesign.md +666 -1083
  20. package/docs/planning/PRODUCT_ROADMAP.md +34 -1
  21. package/docs/planning/release-notes-v0.3.0.md +35 -0
  22. package/docs/planning/video-series.md +2 -2
  23. package/docs/reference/benchmarks.md +1162 -0
  24. package/docs/reference/cli.md +394 -159
  25. package/docs/reference/distribution.md +321 -182
  26. package/docs/reference/environment.md +348 -0
  27. package/docs/reference/glossary.md +39 -0
  28. package/docs/reference/library-api.md +566 -168
  29. package/docs/reference/memory.md +227 -64
  30. package/docs/reference/models.md +104 -6
  31. package/docs/reference/server-api.md +886 -425
  32. package/docs/reference/server-config.md +638 -330
  33. package/docs/reference/training.md +393 -254
  34. package/docs/reference/troubleshooting.md +166 -0
  35. package/package.json +9 -4
  36. package/src/audio/decode.ts +2 -2
  37. package/src/audio/features.ts +2 -2
  38. package/src/backends/mlx/autoregressive.ts +108 -0
  39. package/src/backends/mlx/batch-group.ts +1646 -0
  40. package/src/backends/mlx/diffusion.ts +39 -0
  41. package/src/backends/mlx/draft-target.ts +47 -0
  42. package/src/backends/mlx/evaluation.ts +105 -0
  43. package/src/backends/mlx/fill-append.ts +45 -0
  44. package/src/backends/mlx/gateway-binding.ts +71 -0
  45. package/src/backends/mlx/graph.ts +38 -0
  46. package/src/backends/mlx/memory-client.ts +189 -0
  47. package/src/backends/mlx/memory-guard.ts +40 -0
  48. package/src/backends/mlx/methods.ts +90 -0
  49. package/src/backends/mlx/model-prompt.ts +164 -0
  50. package/src/backends/mlx/model-serving.ts +79 -0
  51. package/src/backends/mlx/prefill.ts +33 -0
  52. package/src/backends/mlx/request-policy.ts +20 -0
  53. package/src/backends/mlx/rollback.ts +51 -0
  54. package/src/backends/mlx/serial-executor.ts +273 -0
  55. package/src/backends/mlx/speculative.ts +114 -0
  56. package/src/backends/mlx/state-views.ts +26 -0
  57. package/src/backends/mlx/text-engine.ts +73 -0
  58. package/src/cli.ts +58 -25
  59. package/src/client.ts +66 -0
  60. package/src/config.ts +21 -4
  61. package/src/contracts/completion.ts +16 -0
  62. package/src/contracts/execution.ts +49 -0
  63. package/src/contracts/generation.ts +103 -0
  64. package/src/contracts/host.ts +7 -0
  65. package/src/contracts/jobs.ts +66 -0
  66. package/src/contracts/pi-provider.ts +30 -0
  67. package/src/contracts/pi.ts +259 -0
  68. package/src/contracts/resources.ts +18 -0
  69. package/src/contracts/scheduling.ts +27 -0
  70. package/src/contracts/tsconfig.json +14 -0
  71. package/src/diffusion/diffusion-generate.ts +218 -153
  72. package/src/embed.ts +1 -1
  73. package/src/engine/admission.ts +59 -0
  74. package/src/engine/cancellation.ts +38 -0
  75. package/src/engine/engine.ts +56 -0
  76. package/src/engine/execution-coordinator.ts +70 -0
  77. package/src/engine/execution-plan.ts +51 -0
  78. package/src/engine/resources.ts +42 -0
  79. package/src/engine/scheduler.ts +67 -0
  80. package/src/engine/session.ts +247 -0
  81. package/src/eval/README.md +44 -1
  82. package/src/eval/kl.ts +236 -3
  83. package/src/eval/reference-logits.ts +207 -0
  84. package/src/eval/runner.ts +8 -96
  85. package/src/fill/echo-index.ts +188 -0
  86. package/src/fill/fill-session.ts +452 -0
  87. package/src/fill/proposal.ts +68 -0
  88. package/src/fill/schema-rows.ts +506 -0
  89. package/src/fill/tool-boundary.ts +103 -0
  90. package/src/fit.ts +1 -1
  91. package/src/generate.ts +656 -268
  92. package/src/grammar.ts +12 -7
  93. package/src/harness-pi.ts +14 -33
  94. package/src/hub-rest.ts +4 -4
  95. package/src/index.ts +7 -0
  96. package/src/inference/denoising.ts +17 -0
  97. package/src/inference/graph.ts +33 -0
  98. package/src/inference/prefill.ts +39 -0
  99. package/src/inference/rollback.ts +7 -0
  100. package/src/jobs/db.ts +4 -0
  101. package/src/jobs/index.ts +2 -0
  102. package/src/jobs/job-entry.ts +12 -12
  103. package/src/jobs/runner.ts +98 -13
  104. package/src/jobs/task-client.ts +19 -0
  105. package/src/jobs/types.ts +2 -58
  106. package/src/kv-store.ts +109 -49
  107. package/src/lab/README.md +18 -0
  108. package/src/{assets → lab/curve}/curve-designer.html +2 -2
  109. package/src/{curve-sampler.ts → lab/curve/curve-sampler.ts} +2 -2
  110. package/src/{expert-trace.ts → lab/expert-trace/expert-trace.ts} +5 -5
  111. package/src/{model → lab/paged-kv}/paged-kv.ts +9 -6
  112. package/src/library.ts +40 -0
  113. package/src/lora.ts +18 -0
  114. package/src/media-fetch.ts +1 -1
  115. package/src/memory/article.ts +1 -1
  116. package/src/memory/chunk.ts +1 -1
  117. package/src/memory/model.ts +30 -169
  118. package/src/memory/prompts.ts +1 -1
  119. package/src/memory/rest.ts +1 -1
  120. package/src/memory/schedule.ts +1 -1
  121. package/src/memory/stages.ts +4 -1
  122. package/src/memory/vault.ts +1 -3
  123. package/src/mlx/array.ts +9 -10
  124. package/src/mlx/compile.ts +12 -2
  125. package/src/mlx/ffi.ts +58 -11
  126. package/src/mlx/materialize.ts +23 -0
  127. package/src/mlx/metal-kernel.ts +10 -11
  128. package/src/mlx/ops.ts +33 -13
  129. package/src/mlx/quantized-rows.ts +36 -0
  130. package/src/mlx/token-bitmask.ts +52 -0
  131. package/src/mlx/turboquant-kv-decode.ts +82 -0
  132. package/src/mlx/turboquant-kv-inverse.ts +122 -0
  133. package/src/mlx/turboquant-ops.ts +33 -3
  134. package/src/mlx/turboquant-tables.ts +2 -2
  135. package/src/model/batched-mask.ts +8 -2
  136. package/src/model/batched-quant.ts +1 -1
  137. package/src/model/batched-rotating-quant.ts +2 -2
  138. package/src/model/batched-rotating.ts +1 -1
  139. package/src/model/compiled-decode.ts +1 -1
  140. package/src/model/diffusion-gemma.ts +8 -8
  141. package/src/model/factory.ts +76 -33
  142. package/src/model/fingerprint.ts +1 -1
  143. package/src/model/flash-attention.ts +3 -3
  144. package/src/model/gemma4-base.ts +26 -9
  145. package/src/model/gemma4.ts +6 -6
  146. package/src/model/generated/gemma4-12b.ts +2 -2
  147. package/src/model/generated/gemma4-26b.ts +2 -2
  148. package/src/model/generated/gemma4-e4b.ts +2 -2
  149. package/src/model/glm52-dsa.ts +13 -9
  150. package/src/model/glm52-memory.ts +1 -1
  151. package/src/model/implementation.ts +69 -0
  152. package/src/model/minicpm5.ts +6 -8
  153. package/src/model/profile.ts +12 -2
  154. package/src/model/qwen-append.ts +12 -0
  155. package/src/model/qwen-conv.ts +52 -0
  156. package/src/model/qwen3_5-checkpoint.ts +164 -0
  157. package/src/model/qwen3_5.ts +140 -56
  158. package/src/model/support.ts +1 -1
  159. package/src/model/trellis-balanced-scatter.ts +51 -0
  160. package/src/model/trellis-linear.ts +672 -0
  161. package/src/model/trellis-shared-m.ts +151 -0
  162. package/src/model/trellis-shared-scatter.ts +144 -0
  163. package/src/model/trellis-splitk-prefill.ts +158 -0
  164. package/src/model/trellis-tiled-prefill.ts +136 -0
  165. package/src/model/trellis-vector-expand.ts +62 -0
  166. package/src/model/trellis-wide-prefill.ts +94 -0
  167. package/src/model/universal/dense.ts +1 -1
  168. package/src/model/universal/modules.ts +8 -1
  169. package/src/native-pack.ts +6 -5
  170. package/src/pi-provider.ts +6 -64
  171. package/src/pi-web.ts +8 -315
  172. package/src/prompt-cache.ts +96 -53
  173. package/src/quantize/allocator.ts +1 -1
  174. package/src/quantize/config-writer.ts +10 -3
  175. package/src/quantize/rotate.ts +4 -4
  176. package/src/quantize/trellis.ts +586 -0
  177. package/src/responses.ts +28 -1
  178. package/src/runtime-config.ts +18 -4
  179. package/src/sampler.ts +4 -4
  180. package/src/serve/batch-scheduler.ts +8 -1671
  181. package/src/serve/chat-request.ts +391 -0
  182. package/src/serve/chat-stage.ts +195 -0
  183. package/src/serve/checkpoint-identity.ts +64 -0
  184. package/src/serve/completion-executor.ts +15 -7
  185. package/src/serve/discovery-routes.ts +12 -13
  186. package/src/serve/generation-gateway.ts +154 -193
  187. package/src/serve/http.ts +159 -0
  188. package/src/serve/inference-request.ts +79 -0
  189. package/src/serve/isolate.ts +297 -105
  190. package/src/serve/lab-routes.ts +3 -0
  191. package/src/serve/lane-registry.ts +2 -1
  192. package/src/serve/model-admin-routes.ts +7 -5
  193. package/src/serve/model-binding.ts +43 -0
  194. package/src/serve/model-host.ts +512 -0
  195. package/src/serve/openai-wire.ts +103 -0
  196. package/src/serve/parent-application.ts +56 -0
  197. package/src/serve/pipeline.ts +33 -0
  198. package/src/serve/preparation.ts +33 -0
  199. package/src/serve/request-plan.ts +19 -15
  200. package/src/serve/request-prep.ts +346 -0
  201. package/src/serve/response-lease.ts +24 -0
  202. package/src/serve/responses-client.ts +69 -0
  203. package/src/serve/session-completion-engine.ts +110 -0
  204. package/src/serve/session-search.ts +1 -1
  205. package/src/serve/static-routes.ts +5 -5
  206. package/src/serve/text-completion-stage.ts +104 -0
  207. package/src/serve/token-streams.ts +519 -0
  208. package/src/server.ts +317 -2649
  209. package/src/spec/assistant-source.ts +10 -44
  210. package/src/spec/deepspec-source.ts +6 -6
  211. package/src/spec/dflash-source.ts +8 -8
  212. package/src/spec/dspark/ab-stats.ts +3 -3
  213. package/src/spec/dspark/calibration.ts +2 -2
  214. package/src/spec/dspark/deepspec-module.ts +2 -2
  215. package/src/spec/dspark/generate-dflash.ts +2 -2
  216. package/src/spec/dspark/generate.ts +2 -2
  217. package/src/spec/dspark/loader.ts +1 -1
  218. package/src/spec/dspark/module-dflash.ts +4 -3
  219. package/src/spec/dspark/module.ts +3 -3
  220. package/src/spec/dspark/quantize-drafter.ts +1 -1
  221. package/src/spec/generate.ts +1 -1
  222. package/src/spec/glm52-mtp-source.ts +1 -1
  223. package/src/spec/ngram-source.ts +1 -1
  224. package/src/spec/prefix-state.ts +45 -0
  225. package/src/spec/qwen-mtp-source.ts +166 -69
  226. package/src/spec/serve-loop.ts +154 -156
  227. package/src/spec/source.ts +42 -10
  228. package/src/spec/two-model.ts +1 -1
  229. package/src/ssd-cache.ts +80 -12
  230. package/src/ssd-durability.ts +25 -13
  231. package/src/tool-call.ts +51 -14
  232. package/src/train/flash-cce.ts +2 -2
  233. package/src/train/forward.ts +6 -0
  234. package/src/train/loss.ts +1 -1
  235. package/src/train/prefix-shared.ts +5 -1
  236. package/src/train/segmented.ts +5 -3
  237. package/src/train/trainer.ts +6 -6
  238. package/src/vision/prompt.ts +1 -1
  239. package/src/vision/qwen3vl-tower.ts +52 -10
  240. package/src/web/app.html +1 -1
  241. package/src/web/app.js +5 -3
  242. package/src/web/src/adapters-panel.ts +3 -3
  243. package/src/web/src/assistant.ts +2 -36
  244. package/src/web/src/chat.ts +4 -4
  245. package/src/web/src/composer.ts +4 -4
  246. package/src/web/src/hub.ts +1 -1
  247. package/src/web/src/markdown.ts +0 -0
  248. package/src/web/src/memory-panel.ts +1 -1
  249. package/src/web/src/model-picker.ts +1 -1
  250. package/src/web/src/palette.ts +1 -1
  251. package/src/web/src/protocol.ts +3 -39
  252. package/src/web/src/sessions.ts +1 -1
  253. package/src/web/src/ui-catalog.ts +4 -18
  254. package/src/web-assets.ts +47 -0
  255. package/src/weights.ts +55 -9
  256. package/docs/archive/investigations/curve-runs/bisector-route.json +0 -98
  257. package/docs/archive/investigations/curve-runs/bisector-trace.json +0 -1393
  258. package/docs/archive/investigations/curve-runs/curve-terrain.json +0 -1179
  259. package/docs/archive/investigations/curve-runs/curve-terrain.svg +0 -42
  260. package/docs/archive/investigations/hlg-ab.html +0 -34
  261. package/docs/archive/investigations/hlg-explorer.html +0 -238
  262. package/docs/archive/investigations/hlg-figs/cliff.svg +0 -1
  263. package/docs/archive/investigations/hlg-figs/cross.svg +0 -1
  264. package/docs/archive/investigations/hlg-figs/edges.svg +0 -1
  265. package/docs/archive/investigations/hlg-figs/k20-grids.svg +0 -1
  266. package/docs/archive/investigations/hlg-figs/k20-peaks.svg +0 -1
  267. package/docs/archive/investigations/hlg-figs/lw-curve.svg +0 -1
  268. package/docs/archive/investigations/hlg-figs/terrain.svg +0 -1
  269. package/docs/archive/investigations/hlg-report.html +0 -262
  270. package/docs/archive/investigations/hlg-runs/hlg-ab.json +0 -149
  271. package/docs/archive/investigations/hlg-runs/hlg-blind-prompts.md +0 -87
  272. package/docs/archive/investigations/hlg-runs/hlg-blind.json +0 -107
  273. package/docs/archive/investigations/hlg-runs/hlg-cliff.json +0 -197
  274. package/docs/archive/investigations/hlg-runs/hlg-cross.json +0 -505
  275. package/docs/archive/investigations/hlg-runs/hlg-edge.json +0 -388
  276. package/docs/archive/investigations/hlg-runs/hlg-eval1.json +0 -25
  277. package/docs/archive/investigations/hlg-runs/hlg-frontier.json +0 -86
  278. package/docs/archive/investigations/hlg-runs/hlg-grid.json +0 -242
  279. package/docs/archive/investigations/hlg-runs/hlg-grid2.json +0 -343
  280. package/docs/archive/investigations/hlg-runs/hlg-lw-coarse.json +0 -110
  281. package/docs/archive/investigations/hlg-runs/hlg-map.json +0 -383
  282. package/docs/archive/investigations/hlg-runs/run0-original.log +0 -159
  283. package/docs/archive/investigations/hlg-runs/runA-recommended.log +0 -131
  284. package/docs/archive/investigations/hlg-runs/runAA-cliff-cpm5.log +0 -26
  285. package/docs/archive/investigations/hlg-runs/runAB-grid2-e4b.log +0 -18
  286. package/docs/archive/investigations/hlg-runs/runAC-peak-e4b-partial.log +0 -25
  287. package/docs/archive/investigations/hlg-runs/runAD-ab-samples.log +0 -8
  288. package/docs/archive/investigations/hlg-runs/runAE-edge-e4b.log +0 -51
  289. package/docs/archive/investigations/hlg-runs/runAF-logit-calibration.log +0 -10
  290. package/docs/archive/investigations/hlg-runs/runAG-eval-config2.log +0 -16
  291. package/docs/archive/investigations/hlg-runs/runB-gain-variants.log +0 -192
  292. package/docs/archive/investigations/hlg-runs/runC-pivots.log +0 -162
  293. package/docs/archive/investigations/hlg-runs/runD-oetf.log +0 -132
  294. package/docs/archive/investigations/hlg-runs/runE-eotf.log +0 -162
  295. package/docs/archive/investigations/hlg-runs/runF-shaper-working.log +0 -86
  296. package/docs/archive/investigations/hlg-runs/runG-shaper-sweep.log +0 -101
  297. package/docs/archive/investigations/hlg-runs/runH-wsweep.log +0 -176
  298. package/docs/archive/investigations/hlg-runs/runI-asweep.log +0 -176
  299. package/docs/archive/investigations/hlg-runs/runJ-knobmap.log +0 -49
  300. package/docs/archive/investigations/hlg-runs/runK-frontier.log +0 -19
  301. package/docs/archive/investigations/hlg-runs/runL-widemap.log +0 -65
  302. package/docs/archive/investigations/hlg-runs/runM-frontier-emb.log +0 -15
  303. package/docs/archive/investigations/hlg-runs/runN-verify.log +0 -116
  304. package/docs/archive/investigations/hlg-runs/runO-frontier-seed5000.log +0 -15
  305. package/docs/archive/investigations/hlg-runs/runP-grid-AxSm.log +0 -15
  306. package/docs/archive/investigations/hlg-runs/runQ-grid-tgW.log +0 -15
  307. package/docs/archive/investigations/hlg-runs/runR-blind-transcript.log +0 -79
  308. package/docs/archive/investigations/hlg-runs/runS-cross-coherence.log +0 -33
  309. package/docs/archive/investigations/hlg-runs/runT-cross-cpm5.log +0 -33
  310. package/docs/archive/investigations/hlg-runs/runU-cross-12b.log +0 -33
  311. package/docs/archive/investigations/hlg-runs/runV-lw-e4b.log +0 -22
  312. package/docs/archive/investigations/hlg-runs/runW-lw-12b.log +0 -22
  313. package/docs/archive/investigations/hlg-runs/runX-lw-cpm5.log +0 -22
  314. package/docs/archive/investigations/hlg-runs/runY-cliff-e4b.log +0 -26
  315. package/docs/archive/investigations/hlg-runs/runZ-cliff-12b.log +0 -26
  316. package/docs/archive/mlx-bun-lab-report.html +0 -275
  317. package/docs/archive/wwdc-mlx-bun.html +0 -848
  318. package/docs/design/adapters-end-to-end.md +0 -205
  319. package/docs/design/batching-perf-path.md +0 -255
  320. package/docs/design/batching-v2-plan.md +0 -529
  321. package/docs/design/bucketing-stage.md +0 -197
  322. package/docs/design/compat-cli-surface-design.md +0 -230
  323. package/docs/design/docs-reorg-plan.md +0 -165
  324. package/docs/design/dspark-serving-program.md +0 -371
  325. package/docs/design/dspark-speculative-decoding.md +0 -318
  326. package/docs/design/grammar-spec-batching-integration.md +0 -301
  327. package/docs/design/memory-inference-path.md +0 -422
  328. package/docs/design/memory-synthesis.md +0 -287
  329. package/docs/design/memory-system.md +0 -237
  330. package/docs/design/mlx-lm-serving-execution-seam.md +0 -81
  331. package/docs/design/mlx-lm-tool-parity-plan.md +0 -545
  332. package/docs/design/omlx-adoption-map.md +0 -98
  333. package/docs/design/orpo-dynamic-lambda.md +0 -220
  334. package/docs/design/orpo-future-enhancements.md +0 -340
  335. package/docs/design/paged-kv-cache.md +0 -214
  336. package/docs/design/parallel-slots.md +0 -567
  337. package/docs/design/parity-tier-dag.md +0 -161
  338. package/docs/design/repo-cleanup-plan.md +0 -231
  339. package/docs/design/runtime-isolation.md +0 -263
  340. package/docs/design/segmented-backward-training.md +0 -543
  341. package/docs/design/spec-decode-larger-targets.md +0 -229
  342. package/docs/design/ssd-kv-cold-tier.md +0 -415
  343. package/docs/design/structured-output.md +0 -484
  344. package/docs/design/tauri-desktop-app.md +0 -127
  345. package/docs/design/the-dreaming-master-plan.md +0 -445
  346. package/docs/design/turboquant-kv.md +0 -235
  347. package/docs/design/turboquant-weights.md +0 -467
  348. package/docs/design/w4a16-compute-precision-spike.md +0 -232
  349. package/docs/design/web-chat-beat-matrix.md +0 -315
  350. package/docs/design/write-pipeline-entity.md +0 -468
  351. package/docs/planning/IDEAS.md +0 -69
  352. package/docs/reference/embedding.md +0 -197
  353. package/docs/reference/features-matrix.md +0 -101
  354. package/docs/reference/orpo-quickstart.md +0 -135
  355. package/src/flags.ts +0 -11
  356. /package/docs/{design → archive/investigations}/colibri-glm52-port.md +0 -0
  357. /package/docs/{planning → archive/planning}/chunk-task-roadmap.md +0 -0
  358. /package/docs/{planning → archive/planning}/curve-sampler-research-plan.md +0 -0
  359. /package/docs/{planning → archive/planning}/memory-docs-and-dag-plan.md +0 -0
  360. /package/docs/{planning → archive/planning}/pi-integration-review.md +0 -0
  361. /package/docs/{planning → archive/planning}/release-notes-v0.2.0.md +0 -0
  362. /package/src/{memory-plan.ts → admission-plan.ts} +0 -0
  363. /package/{docs/archive/investigations → src/serve/assets}/curve-terrain.html +0 -0
  364. /package/{docs/dag → src/serve/assets}/training-inference-map.html +0 -0
@@ -1,467 +0,0 @@
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).