mlx-bun 0.0.13 → 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 (427) hide show
  1. package/README.md +71 -578
  2. package/bin/mlx-bun.mjs +1 -1
  3. package/docs/README.md +91 -0
  4. package/docs/{design → archive}/hlg-sampling.md +3 -3
  5. package/docs/{design → archive/investigations}/audio-input-plan.md +4 -4
  6. package/docs/{design → archive/investigations}/colibri-glm52-port.md +1 -1
  7. package/docs/{design → archive/investigations}/diffusion-gemma-port.md +3 -3
  8. package/docs/{design → archive/investigations}/faithful-l1-consolidation.md +4 -4
  9. package/docs/{investigations → archive/investigations}/hlg-sampling-investigation.md +1 -1
  10. package/docs/{design → archive/investigations}/minicpm5-decode-megakernel.md +11 -11
  11. package/docs/{design → archive/investigations}/optimization_plan.md +1 -1
  12. package/docs/archive/investigations/pareto-specialized-runtime-findings.md +92 -0
  13. package/docs/{design → archive/investigations}/pre-colibri-stabilization.md +5 -5
  14. package/docs/{design → archive/investigations}/the-dreaming-handoff.md +2 -2
  15. package/docs/{planning → archive/planning}/chat-ui-vision.md +1 -1
  16. package/docs/{planning → archive/planning}/chunk-task-roadmap.md +1 -1
  17. package/docs/{planning → archive/planning}/curve-sampler-research-plan.md +4 -4
  18. package/docs/{planning → archive/planning}/memory-docs-and-dag-plan.md +1 -1
  19. package/docs/{planning → archive/planning}/release-notes-v0.0.9.md +1 -1
  20. package/docs/archive/planning/release-notes-v0.2.0.md +49 -0
  21. package/docs/{planning → archive/planning}/website-readme-pass-plan.md +1 -1
  22. package/docs/design/batching.md +569 -0
  23. package/docs/design/decode-speed-program.md +3178 -169
  24. package/docs/design/dreaming-nightly-pipeline.md +675 -282
  25. package/docs/design/generic-model-support.md +579 -334
  26. package/docs/design/kv-cache.md +680 -0
  27. package/docs/design/orpo-training.md +673 -1239
  28. package/docs/design/speculative-decoding.md +1627 -0
  29. package/docs/design/turboquant.md +2102 -0
  30. package/docs/design/unified-engine-frontier-plan.md +1831 -727
  31. package/docs/design/web-chat-redesign.md +666 -1083
  32. package/docs/planning/PRODUCT_ROADMAP.md +34 -1
  33. package/docs/planning/release-notes-v0.3.0.md +35 -0
  34. package/docs/planning/video-series.md +421 -0
  35. package/docs/reference/benchmarks.md +1162 -0
  36. package/docs/reference/cli.md +395 -149
  37. package/docs/reference/distribution.md +321 -181
  38. package/docs/reference/environment.md +348 -0
  39. package/docs/reference/glossary.md +39 -0
  40. package/docs/reference/library-api.md +580 -142
  41. package/docs/reference/memory.md +227 -64
  42. package/docs/reference/models.md +137 -6
  43. package/docs/reference/server-api.md +938 -422
  44. package/docs/reference/server-config.md +652 -320
  45. package/docs/reference/training.md +393 -254
  46. package/docs/reference/troubleshooting.md +166 -0
  47. package/package.json +10 -5
  48. package/src/admission-plan.ts +18 -0
  49. package/src/anthropic.ts +92 -3
  50. package/src/audio/decode.ts +2 -2
  51. package/src/audio/features.ts +2 -2
  52. package/src/backends/mlx/autoregressive.ts +108 -0
  53. package/src/backends/mlx/batch-group.ts +1646 -0
  54. package/src/backends/mlx/diffusion.ts +39 -0
  55. package/src/backends/mlx/draft-target.ts +47 -0
  56. package/src/backends/mlx/evaluation.ts +105 -0
  57. package/src/backends/mlx/fill-append.ts +45 -0
  58. package/src/backends/mlx/gateway-binding.ts +71 -0
  59. package/src/backends/mlx/graph.ts +38 -0
  60. package/src/backends/mlx/memory-client.ts +189 -0
  61. package/src/backends/mlx/memory-guard.ts +40 -0
  62. package/src/backends/mlx/methods.ts +90 -0
  63. package/src/backends/mlx/model-prompt.ts +164 -0
  64. package/src/backends/mlx/model-serving.ts +79 -0
  65. package/src/backends/mlx/prefill.ts +33 -0
  66. package/src/backends/mlx/request-policy.ts +20 -0
  67. package/src/backends/mlx/rollback.ts +51 -0
  68. package/src/backends/mlx/serial-executor.ts +273 -0
  69. package/src/backends/mlx/speculative.ts +114 -0
  70. package/src/backends/mlx/state-views.ts +26 -0
  71. package/src/backends/mlx/text-engine.ts +73 -0
  72. package/src/cli.ts +189 -61
  73. package/src/client.ts +66 -0
  74. package/src/config.ts +21 -4
  75. package/src/contracts/completion.ts +16 -0
  76. package/src/contracts/execution.ts +49 -0
  77. package/src/contracts/generation.ts +103 -0
  78. package/src/contracts/host.ts +7 -0
  79. package/src/contracts/jobs.ts +66 -0
  80. package/src/contracts/pi-provider.ts +30 -0
  81. package/src/contracts/pi.ts +259 -0
  82. package/src/contracts/resources.ts +18 -0
  83. package/src/contracts/scheduling.ts +27 -0
  84. package/src/contracts/tsconfig.json +14 -0
  85. package/src/diffusion/diffusion-generate.ts +218 -153
  86. package/src/embed.ts +1 -1
  87. package/src/engine/admission.ts +59 -0
  88. package/src/engine/cancellation.ts +38 -0
  89. package/src/engine/engine.ts +56 -0
  90. package/src/engine/execution-coordinator.ts +70 -0
  91. package/src/engine/execution-plan.ts +51 -0
  92. package/src/engine/resources.ts +42 -0
  93. package/src/engine/scheduler.ts +67 -0
  94. package/src/engine/session.ts +247 -0
  95. package/src/eval/README.md +44 -1
  96. package/src/eval/kl.ts +263 -23
  97. package/src/eval/reference-logits.ts +207 -0
  98. package/src/eval/runner.ts +10 -79
  99. package/src/eval/tasks/bfcl.ts +2 -1
  100. package/src/eval/tasks/gsm8k.ts +2 -1
  101. package/src/eval/tasks/hashhop.ts +2 -1
  102. package/src/eval/tasks/humaneval.ts +5 -4
  103. package/src/eval/tasks/ifeval.ts +2 -1
  104. package/src/eval/tasks/mmlu.ts +2 -1
  105. package/src/expert-io.ts +3 -1
  106. package/src/expert-offload.ts +3 -1
  107. package/src/fill/echo-index.ts +188 -0
  108. package/src/fill/fill-session.ts +452 -0
  109. package/src/fill/proposal.ts +68 -0
  110. package/src/fill/schema-rows.ts +506 -0
  111. package/src/fill/tool-boundary.ts +103 -0
  112. package/src/fit.ts +24 -43
  113. package/src/generate.ts +740 -337
  114. package/src/grammar.ts +14 -8
  115. package/src/harness-pi.ts +15 -34
  116. package/src/hub-rest.ts +4 -4
  117. package/src/index.ts +27 -0
  118. package/src/inference/denoising.ts +17 -0
  119. package/src/inference/graph.ts +33 -0
  120. package/src/inference/prefill.ts +39 -0
  121. package/src/inference/rollback.ts +7 -0
  122. package/src/jobs/db.ts +4 -0
  123. package/src/jobs/index.ts +2 -0
  124. package/src/jobs/job-entry.ts +15 -14
  125. package/src/jobs/runner.ts +98 -13
  126. package/src/jobs/task-client.ts +19 -0
  127. package/src/jobs/types.ts +2 -58
  128. package/src/kv-scheme.ts +199 -0
  129. package/src/kv-store.ts +459 -234
  130. package/src/lab/README.md +18 -0
  131. package/src/{assets → lab/curve}/curve-designer.html +2 -2
  132. package/src/{curve-sampler.ts → lab/curve/curve-sampler.ts} +2 -2
  133. package/src/{expert-trace.ts → lab/expert-trace/expert-trace.ts} +7 -5
  134. package/src/{model → lab/paged-kv}/paged-kv.ts +9 -6
  135. package/src/library.ts +40 -0
  136. package/src/lora.ts +18 -0
  137. package/src/media-fetch.ts +20 -4
  138. package/src/memory/article.ts +1 -1
  139. package/src/memory/chunk.ts +1 -1
  140. package/src/memory/model.ts +32 -170
  141. package/src/memory/prompts.ts +1 -1
  142. package/src/memory/rest.ts +1 -1
  143. package/src/memory/schedule.ts +1 -1
  144. package/src/memory/stages.ts +4 -1
  145. package/src/memory/vault.ts +3 -4
  146. package/src/mlx/array.ts +9 -10
  147. package/src/mlx/compile.ts +12 -2
  148. package/src/mlx/ffi.ts +66 -22
  149. package/src/mlx/materialize.ts +23 -0
  150. package/src/mlx/metal-kernel.ts +10 -11
  151. package/src/mlx/ops.ts +64 -19
  152. package/src/mlx/quantized-rows.ts +36 -0
  153. package/src/mlx/token-bitmask.ts +52 -0
  154. package/src/mlx/turboquant-kv-decode.ts +82 -0
  155. package/src/mlx/turboquant-kv-inverse.ts +122 -0
  156. package/src/mlx/turboquant-ops.ts +33 -3
  157. package/src/mlx/turboquant-tables.ts +2 -2
  158. package/src/model/batched-mask.ts +9 -3
  159. package/src/model/batched-quant.ts +2 -2
  160. package/src/model/batched-rotating-quant.ts +45 -99
  161. package/src/model/batched-rotating-state.ts +73 -0
  162. package/src/model/batched-rotating.ts +57 -106
  163. package/src/model/batched-row-storage.ts +127 -0
  164. package/src/model/compiled-decode.ts +4 -3
  165. package/src/model/diffusion-gemma.ts +8 -8
  166. package/src/model/factory.ts +87 -49
  167. package/src/model/fingerprint.ts +1 -1
  168. package/src/model/flash-attention.ts +3 -3
  169. package/src/model/gemma4-base.ts +187 -17
  170. package/src/model/gemma4.ts +6 -6
  171. package/src/model/generated/gemma4-12b.ts +52 -148
  172. package/src/model/generated/gemma4-26b.ts +34 -94
  173. package/src/model/generated/gemma4-e4b.ts +28 -76
  174. package/src/model/glm52-cache.ts +19 -9
  175. package/src/model/glm52-dsa.ts +13 -9
  176. package/src/model/glm52-memory.ts +28 -1
  177. package/src/model/implementation.ts +69 -0
  178. package/src/model/minicpm5.ts +7 -8
  179. package/src/model/profile.ts +443 -0
  180. package/src/model/qwen-append.ts +12 -0
  181. package/src/model/qwen-conv.ts +52 -0
  182. package/src/model/qwen3-delta.ts +98 -2
  183. package/src/model/qwen3-mrope.ts +252 -0
  184. package/src/model/qwen3_5-checkpoint.ts +164 -0
  185. package/src/model/qwen3_5.ts +336 -60
  186. package/src/model/support.ts +1 -1
  187. package/src/model/trellis-balanced-scatter.ts +51 -0
  188. package/src/model/trellis-linear.ts +672 -0
  189. package/src/model/trellis-shared-m.ts +151 -0
  190. package/src/model/trellis-shared-scatter.ts +144 -0
  191. package/src/model/trellis-splitk-prefill.ts +158 -0
  192. package/src/model/trellis-tiled-prefill.ts +136 -0
  193. package/src/model/trellis-vector-expand.ts +62 -0
  194. package/src/model/trellis-wide-prefill.ts +94 -0
  195. package/src/model/universal/dense.ts +1 -1
  196. package/src/model/universal/modules.ts +8 -1
  197. package/src/native/frame_extract.swift +140 -0
  198. package/src/native-pack.ts +15 -7
  199. package/src/pi-provider.ts +6 -64
  200. package/src/pi-web.ts +14 -320
  201. package/src/prompt-cache.ts +97 -54
  202. package/src/quantize/allocator.ts +1 -1
  203. package/src/quantize/atomic-output.ts +38 -0
  204. package/src/quantize/calibration.ts +2 -1
  205. package/src/quantize/config-writer.ts +16 -3
  206. package/src/quantize/index.ts +28 -1
  207. package/src/quantize/job.ts +11 -0
  208. package/src/quantize/quantizer.ts +265 -100
  209. package/src/quantize/rotate.ts +603 -0
  210. package/src/quantize/safetensors-writer.ts +79 -1
  211. package/src/quantize/sensitivity.ts +41 -59
  212. package/src/quantize/trellis.ts +586 -0
  213. package/src/quantize/weight-transform.ts +292 -0
  214. package/src/responses.ts +130 -3
  215. package/src/runtime-config.ts +81 -0
  216. package/src/sampler.ts +276 -4
  217. package/src/serve/admin-routes.ts +184 -0
  218. package/src/serve/aux-routes.ts +132 -0
  219. package/src/serve/batch-scheduler.ts +8 -1558
  220. package/src/serve/chat-request.ts +391 -0
  221. package/src/serve/chat-stage.ts +195 -0
  222. package/src/serve/checkpoint-identity.ts +64 -0
  223. package/src/serve/completion-executor.ts +354 -0
  224. package/src/serve/completion-sink.ts +157 -0
  225. package/src/serve/discovery-routes.ts +204 -0
  226. package/src/serve/generation-gateway.ts +211 -243
  227. package/src/serve/http.ts +159 -0
  228. package/src/serve/inference-request.ts +79 -0
  229. package/src/serve/isolate.ts +297 -105
  230. package/src/serve/kv-budget.ts +14 -0
  231. package/src/serve/lab-routes.ts +341 -0
  232. package/src/serve/lane-registry.ts +2 -1
  233. package/src/serve/model-admin-routes.ts +155 -0
  234. package/src/serve/model-binding.ts +43 -0
  235. package/src/serve/model-host.ts +512 -0
  236. package/src/serve/openai-wire.ts +103 -0
  237. package/src/serve/parent-application.ts +56 -0
  238. package/src/serve/pipeline.ts +33 -0
  239. package/src/serve/preparation.ts +33 -0
  240. package/src/serve/prompt-response-trace.ts +147 -0
  241. package/src/serve/request-plan.ts +162 -0
  242. package/src/serve/request-prep.ts +346 -0
  243. package/src/serve/response-lease.ts +24 -0
  244. package/src/serve/responses-client.ts +69 -0
  245. package/src/serve/session-completion-engine.ts +110 -0
  246. package/src/serve/session-search.ts +1 -1
  247. package/src/serve/static-routes.ts +101 -0
  248. package/src/serve/text-completion-stage.ts +104 -0
  249. package/src/serve/token-streams.ts +519 -0
  250. package/src/server.ts +523 -3551
  251. package/src/spec/assistant-source.ts +10 -44
  252. package/src/spec/deepspec-source.ts +6 -6
  253. package/src/spec/dflash-source.ts +9 -8
  254. package/src/spec/dspark/ab-stats.ts +3 -3
  255. package/src/spec/dspark/calibration.ts +2 -2
  256. package/src/spec/dspark/deepspec-module.ts +2 -2
  257. package/src/spec/dspark/generate-dflash.ts +2 -2
  258. package/src/spec/dspark/generate.ts +2 -2
  259. package/src/spec/dspark/loader.ts +1 -1
  260. package/src/spec/dspark/module-dflash.ts +5 -4
  261. package/src/spec/dspark/module.ts +3 -3
  262. package/src/spec/dspark/quantize-drafter.ts +1 -1
  263. package/src/spec/generate.ts +1 -1
  264. package/src/spec/glm52-mtp-source.ts +9 -1
  265. package/src/spec/ngram-source.ts +1 -1
  266. package/src/spec/prefix-state.ts +45 -0
  267. package/src/spec/qwen-mtp-source.ts +528 -0
  268. package/src/spec/serve-loop.ts +179 -213
  269. package/src/spec/source.ts +42 -10
  270. package/src/spec/two-model.ts +1 -1
  271. package/src/ssd-cache.ts +95 -24
  272. package/src/ssd-durability.ts +207 -0
  273. package/src/tool-call.ts +51 -14
  274. package/src/train/flash-cce.ts +14 -13
  275. package/src/train/forward.ts +38 -1
  276. package/src/train/loss.ts +3 -2
  277. package/src/train/prefix-shared.ts +5 -1
  278. package/src/train/segmented.ts +9 -6
  279. package/src/train/trainer.ts +9 -8
  280. package/src/vision/preprocess.ts +1 -1
  281. package/src/vision/prompt.ts +48 -2
  282. package/src/vision/qwen3vl-preprocess.ts +409 -0
  283. package/src/vision/qwen3vl-prompt.ts +196 -0
  284. package/src/vision/qwen3vl-tower.ts +555 -0
  285. package/src/vision/video-frames.ts +148 -0
  286. package/src/web/app.html +1 -1
  287. package/src/web/app.js +15 -6
  288. package/src/web/src/adapters-panel.ts +3 -3
  289. package/src/web/src/assistant.ts +2 -36
  290. package/src/web/src/chat.ts +16 -9
  291. package/src/web/src/composer.ts +4 -4
  292. package/src/web/src/hub.ts +1 -1
  293. package/src/web/src/markdown.ts +0 -0
  294. package/src/web/src/memory-panel.ts +1 -1
  295. package/src/web/src/model-picker.ts +1 -1
  296. package/src/web/src/palette.ts +1 -1
  297. package/src/web/src/protocol.ts +3 -39
  298. package/src/web/src/sessions.ts +1 -1
  299. package/src/web/src/ui-catalog.ts +4 -18
  300. package/src/web-assets.ts +47 -0
  301. package/src/weights.ts +134 -33
  302. package/docs/archive/mlx-bun-lab-report.html +0 -275
  303. package/docs/archive/wwdc-mlx-bun.html +0 -848
  304. package/docs/design/adapters-end-to-end.md +0 -205
  305. package/docs/design/batching-perf-path.md +0 -255
  306. package/docs/design/batching-v2-plan.md +0 -529
  307. package/docs/design/bucketing-stage.md +0 -197
  308. package/docs/design/compat-cli-surface-design.md +0 -230
  309. package/docs/design/docs-reorg-plan.md +0 -165
  310. package/docs/design/dspark-serving-program.md +0 -371
  311. package/docs/design/dspark-speculative-decoding.md +0 -268
  312. package/docs/design/grammar-spec-batching-integration.md +0 -301
  313. package/docs/design/memory-inference-path.md +0 -422
  314. package/docs/design/memory-synthesis.md +0 -287
  315. package/docs/design/memory-system.md +0 -237
  316. package/docs/design/mlx-lm-tool-parity-plan.md +0 -545
  317. package/docs/design/omlx-adoption-map.md +0 -98
  318. package/docs/design/orpo-dynamic-lambda.md +0 -220
  319. package/docs/design/orpo-future-enhancements.md +0 -340
  320. package/docs/design/paged-kv-cache.md +0 -214
  321. package/docs/design/parallel-slots.md +0 -567
  322. package/docs/design/parity-tier-dag.md +0 -161
  323. package/docs/design/repo-cleanup-plan.md +0 -189
  324. package/docs/design/runtime-isolation.md +0 -263
  325. package/docs/design/segmented-backward-training.md +0 -543
  326. package/docs/design/spec-decode-larger-targets.md +0 -229
  327. package/docs/design/ssd-kv-cold-tier.md +0 -288
  328. package/docs/design/structured-output.md +0 -484
  329. package/docs/design/tauri-desktop-app.md +0 -127
  330. package/docs/design/the-dreaming-master-plan.md +0 -445
  331. package/docs/design/turboquant-kv.md +0 -235
  332. package/docs/design/w4a16-compute-precision-spike.md +0 -232
  333. package/docs/design/web-chat-beat-matrix.md +0 -315
  334. package/docs/design/write-pipeline-entity.md +0 -468
  335. package/docs/investigations/curve-runs/bisector-route.json +0 -98
  336. package/docs/investigations/curve-runs/bisector-trace.json +0 -1393
  337. package/docs/investigations/curve-runs/curve-terrain.json +0 -1179
  338. package/docs/investigations/curve-runs/curve-terrain.svg +0 -42
  339. package/docs/investigations/hlg-ab.html +0 -34
  340. package/docs/investigations/hlg-explorer.html +0 -238
  341. package/docs/investigations/hlg-figs/cliff.svg +0 -1
  342. package/docs/investigations/hlg-figs/cross.svg +0 -1
  343. package/docs/investigations/hlg-figs/edges.svg +0 -1
  344. package/docs/investigations/hlg-figs/k20-grids.svg +0 -1
  345. package/docs/investigations/hlg-figs/k20-peaks.svg +0 -1
  346. package/docs/investigations/hlg-figs/lw-curve.svg +0 -1
  347. package/docs/investigations/hlg-figs/terrain.svg +0 -1
  348. package/docs/investigations/hlg-report.html +0 -262
  349. package/docs/investigations/hlg-runs/hlg-ab.json +0 -149
  350. package/docs/investigations/hlg-runs/hlg-blind-prompts.md +0 -87
  351. package/docs/investigations/hlg-runs/hlg-blind.json +0 -107
  352. package/docs/investigations/hlg-runs/hlg-cliff.json +0 -197
  353. package/docs/investigations/hlg-runs/hlg-cross.json +0 -505
  354. package/docs/investigations/hlg-runs/hlg-edge.json +0 -388
  355. package/docs/investigations/hlg-runs/hlg-eval1.json +0 -25
  356. package/docs/investigations/hlg-runs/hlg-frontier.json +0 -86
  357. package/docs/investigations/hlg-runs/hlg-grid.json +0 -242
  358. package/docs/investigations/hlg-runs/hlg-grid2.json +0 -343
  359. package/docs/investigations/hlg-runs/hlg-lw-coarse.json +0 -110
  360. package/docs/investigations/hlg-runs/hlg-map.json +0 -383
  361. package/docs/investigations/hlg-runs/run0-original.log +0 -159
  362. package/docs/investigations/hlg-runs/runA-recommended.log +0 -131
  363. package/docs/investigations/hlg-runs/runAA-cliff-cpm5.log +0 -26
  364. package/docs/investigations/hlg-runs/runAB-grid2-e4b.log +0 -18
  365. package/docs/investigations/hlg-runs/runAC-peak-e4b-partial.log +0 -25
  366. package/docs/investigations/hlg-runs/runAD-ab-samples.log +0 -8
  367. package/docs/investigations/hlg-runs/runAE-edge-e4b.log +0 -51
  368. package/docs/investigations/hlg-runs/runAF-logit-calibration.log +0 -10
  369. package/docs/investigations/hlg-runs/runAG-eval-config2.log +0 -16
  370. package/docs/investigations/hlg-runs/runB-gain-variants.log +0 -192
  371. package/docs/investigations/hlg-runs/runC-pivots.log +0 -162
  372. package/docs/investigations/hlg-runs/runD-oetf.log +0 -132
  373. package/docs/investigations/hlg-runs/runE-eotf.log +0 -162
  374. package/docs/investigations/hlg-runs/runF-shaper-working.log +0 -86
  375. package/docs/investigations/hlg-runs/runG-shaper-sweep.log +0 -101
  376. package/docs/investigations/hlg-runs/runH-wsweep.log +0 -176
  377. package/docs/investigations/hlg-runs/runI-asweep.log +0 -176
  378. package/docs/investigations/hlg-runs/runJ-knobmap.log +0 -49
  379. package/docs/investigations/hlg-runs/runK-frontier.log +0 -19
  380. package/docs/investigations/hlg-runs/runL-widemap.log +0 -65
  381. package/docs/investigations/hlg-runs/runM-frontier-emb.log +0 -15
  382. package/docs/investigations/hlg-runs/runN-verify.log +0 -116
  383. package/docs/investigations/hlg-runs/runO-frontier-seed5000.log +0 -15
  384. package/docs/investigations/hlg-runs/runP-grid-AxSm.log +0 -15
  385. package/docs/investigations/hlg-runs/runQ-grid-tgW.log +0 -15
  386. package/docs/investigations/hlg-runs/runR-blind-transcript.log +0 -79
  387. package/docs/investigations/hlg-runs/runS-cross-coherence.log +0 -33
  388. package/docs/investigations/hlg-runs/runT-cross-cpm5.log +0 -33
  389. package/docs/investigations/hlg-runs/runU-cross-12b.log +0 -33
  390. package/docs/investigations/hlg-runs/runV-lw-e4b.log +0 -22
  391. package/docs/investigations/hlg-runs/runW-lw-12b.log +0 -22
  392. package/docs/investigations/hlg-runs/runX-lw-cpm5.log +0 -22
  393. package/docs/investigations/hlg-runs/runY-cliff-e4b.log +0 -26
  394. package/docs/investigations/hlg-runs/runZ-cliff-12b.log +0 -26
  395. package/docs/planning/IDEAS.md +0 -69
  396. package/docs/reference/embedding.md +0 -197
  397. package/docs/reference/features-matrix.md +0 -100
  398. package/docs/reference/orpo-quickstart.md +0 -135
  399. package/src/flags.ts +0 -13
  400. /package/docs/{investigations → archive/investigations}/chunk-finetune-experiment.md +0 -0
  401. /package/docs/{investigations → archive/investigations}/colibri-oracle-pin.md +0 -0
  402. /package/docs/{investigations → archive/investigations}/curve-bisector-routing.md +0 -0
  403. /package/docs/{investigations → archive/investigations}/decode-roofline-lookagain.md +0 -0
  404. /package/docs/{investigations → archive/investigations}/dspark-handoff.md +0 -0
  405. /package/docs/{investigations → archive/investigations}/expert-offload-single-user-moe.md +0 -0
  406. /package/docs/{investigations → archive/investigations}/indexshare-performance-spike.md +0 -0
  407. /package/docs/{investigations → archive/investigations}/kernel-perf-review-2026-07.md +0 -0
  408. /package/docs/{investigations → archive/investigations}/lab-build-journal.md +0 -0
  409. /package/docs/{investigations → archive/investigations}/openwiki-evaluation.md +0 -0
  410. /package/docs/{investigations → archive/investigations}/orpo-base-uf-experiment-and-directions.md +0 -0
  411. /package/docs/{investigations → archive/investigations}/orpo-flash-cce-pin-leak.md +0 -0
  412. /package/docs/{investigations → archive/investigations}/orpo-uf-testing-handoff.md +0 -0
  413. /package/docs/{investigations → archive/investigations}/pi-builtin-investigation.md +0 -0
  414. /package/docs/{investigations → archive/investigations}/segmented-backward-handoff.md +0 -0
  415. /package/docs/{investigations → archive/investigations}/starter-model-port-handoff.md +0 -0
  416. /package/docs/{investigations → archive/investigations}/steel-flash-cce-handoff.md +0 -0
  417. /package/docs/{investigations → archive/investigations}/trainer-validation-experiment.md +0 -0
  418. /package/docs/{planning → archive/planning}/chat-ui-vision-memory-first.md +0 -0
  419. /package/docs/{planning → archive/planning}/journal.md +0 -0
  420. /package/docs/{planning → archive/planning}/pi-integration-review.md +0 -0
  421. /package/docs/{planning → archive/planning}/release-notes-v0.0.10.md +0 -0
  422. /package/docs/{planning → archive/planning}/release-notes-v0.0.11.md +0 -0
  423. /package/docs/{planning → archive/planning}/release-notes-v0.0.12.md +0 -0
  424. /package/docs/{planning → archive/planning}/release-notes-v0.0.13.md +0 -0
  425. /package/docs/{planning → archive/planning}/web-ui-pass-plan.md +0 -0
  426. /package/{docs/investigations → src/serve/assets}/curve-terrain.html +0 -0
  427. /package/{docs/dag → src/serve/assets}/training-inference-map.html +0 -0
@@ -1,172 +1,3181 @@
1
- # Decode-speed program — the ranked path to faster tokens
2
-
3
- Status: PLANNED (2026-07-04). The single-stream decode roadmap, written
4
- down after the mode-matrix benchmark (scripts/bench-modes.ts) confirmed
5
- what the roofline work predicted: **the baseline decode path has no waste
6
- left** — e4b/cpm5/12B sit at the memory-bandwidth wall in every tier, so
7
- tier levers can't buy short-context decode speed. Faster means one of
8
- four physical moves. Each lever below has evidence, an expected win, and
9
- a trigger; pick them up in order.
10
-
11
- **LANDED 2026-07-04 (correcting "no waste left" for CPM5):** CPM5 decode
12
- carried one real, non-physics waste — an UNFUSED swiglu (`sigmoid`+`mul`+`mul`
13
- = 3 kernels/layer × 24). Porting mlx-lm's `@partial(mx.compile) swiglu`
14
- (activations.py → `compiledSwiglu` in minicpm5.ts, M=1 decode, kill-switch
15
- `MLX_BUN_COMPILED_SWIGLU=0`) fused it to one `CV2ISigmoid…` kernel and moved
16
- CPM5 **250.5 → 264.4 tok/s (+5.5%), to parity/ahead of mlx-lm (260.3)** —
17
- bit-identical tokens. The win was per-dispatch host+encode tax (48 ops/token),
18
- NOT the ~0.9% elementwise GPU time the Xcode capture showed; that's also why
19
- CompiledDecode was 0% (it replays the same unfused graph). See §4 and
20
- [[cpm5-decode-parity-investigation]]. The bandwidth-wall framing holds for the
21
- *matmul* path; small-elementwise fusion is the exception it missed.
22
-
23
- The physics: decode tok/s ≈ bandwidth ÷ bytes-touched-per-token
24
- (M4 Pro ~273 GB/s). To go faster: read the bytes ONCE for several tokens
25
- (speculation, batching), read FEWER bytes (quantization), SKIP reads
26
- (caching), or shave the non-GPU residue (host overhead). TTFT/throughput
27
- are already leadership territory (caches 16×/8.7× second-turn TTFT,
28
- batching 12× TTFT + 2.1× aggregate under load, 2–5× startup vs the
29
- Python stacks) — this program is about the decode number itself.
30
-
31
- ## The levers, ranked
32
-
33
- ### 1. Speculative decoding — the only wall-breaker [expected 1.1–3×]
34
-
35
- One target forward verifies γ drafts + a bonus: the weight read amortizes
36
- over up-to-γ+1 tokens. The serve loop, verify math (L1: 48/48 vs mlx-lm),
37
- grammar composition, and `usage.speculation` telemetry ALL landed
38
- 2026-07-03; what remains is drafters worth running:
39
-
40
- - **1a. AssistantSource (build next)** — wrap the optiq KV-borrowing
41
- gemma assistant drafter (`src/spec/drafter.ts`, bit-exact vs optiq's
42
- spec_generate) as a `DraftSource` behind the SAME `--draft-model` flag
43
- (parity-plan §7.9 dispatch-by-artifact). Artifacts downloaded for e4b +
44
- 12B. Measured today: **12B γ=1 ≈ 1.09×** with this deliberately heavy
45
- drafter (docs/design/spec-decode-larger-targets.md). L2 oracle exists.
46
- - **1b. Cheaper drafter head** — the 262k tied-embedding argmax every
47
- draft step dominates γ≥2 cost; capping/approximating it extends the win
48
- past γ=1 (same doc, "remaining levers").
49
- - **1d. Grammar-aware speculation (Josh's insight, 2026-07-04)** — the
50
- grammar mask collapses the drafting problem on structured output:
51
- (i) **jump-forward** — when the mask admits exactly ONE token
52
- (structural JSON runs), emit it with NO forward at all and fold it into
53
- the next verify window as a pre-accepted draft (zero-cost tokens,
54
- 20–40% of dense-schema output); (ii) **constrained drafting** — mask
55
- the drafter too (matcher `rollBack` on rejection, the flagged
56
- MLX_BUN_SPEC_GRAMMAR_DRAFT lever): our own matrix measured acceptance
57
- DROP 51%→29% under grammar with a blind drafter — constrained drafting
58
- flips that to ~1.0 on structural spans; (iii) **grammar-pruned draft
59
- TREES** — a DSpark token tree's branching factor collapses under a
60
- tight mask, concentrating the budget on content positions
61
- (XGrammar-2's `traverse_draft_tree`, the U2 trigger in
62
- structured-output.md). Agent output is majority-structural: this turns
63
- speculation near-deterministic exactly where agents spend tokens.
64
- - **1c. DSpark (THE goal drafter)** — DFlash KV-injection, architecture
65
- verified (overfit τ=3.24, paper-range). Blockers are research, not
66
- serve wiring: 27B/12B retarget (regen+train, Josh's shell), data scale
67
- (thousands of on-distribution generations vs 160), draft-loop
68
- tightening. At τ≈3 on the 27B agent workload: **~15 → ~35–45 tok/s**
69
- (docs/investigations/dspark-handoff.md). Slots in as `DflashSource`,
70
- no-oracle/KL-gated (a Lab item).
71
-
72
- ### 2. mlx bump — narrow 26B / spec-decode wins, NOT a general decode lever [main-only, from-source]
73
-
74
- Pinned at mlx 0.31.2 — still the newest *released* mlx (and newest on
75
- PyPI). All the decode-relevant work is UNRELEASED on mlx `main`; there is
76
- no nightly wheel, so a bump means building mlx + mlx-c from source AND
77
- running the oracle (mlx-lm / optiq — no released version targets mlx >
78
- 0.31.2) on an unvalidated combination. That oracle validity is the real
79
- cost, NOT golden regen (regenerating goldens is the verification, not a
80
- gate). Upstream refs below are all in `ml-explore/mlx`, full-URL'd — a bare
81
- `#NNNN` in this repo resolves to our own tracker (a 404), not theirs.
82
-
83
- What `main` actually has (confirmed against the PR pages):
1
+ ---
2
+ status: active
3
+ axis: ON
4
+ canonical-for: decode-speed-levers
5
+ plan-anchor: "Phase 6 — Speed: change what gets computed `[~]`"
6
+ last-verified: 2026-09-07
7
+ ---
8
+
9
+ # Inference performance program
10
+
11
+ This is the canonical performance research plan. The current priority is the
12
+ Qwen3.8-27B program in section 7, covering quants, the complete execution graph,
13
+ custom kernels, deterministic token replay, prefill, decode, and serving.
14
+ Sections 1–6 retain the earlier cross-model research and the
15
+ **port ledger vs oMLX** (§6, folded in from `docs/design/decode-speed-program.md` on
16
+ 2026-08-23). Status and run logs live in PLAN.md (Phase 6 and the serve
17
+ h2h phases); the architecture the levers plug into is
18
+ `unified-engine-frontier-plan.md`; curated numbers are
19
+ `docs/reference/benchmarks.md`. Every lever here has evidence, an expected
20
+ win, and a trigger; pick them up in order. No number below is new — each
21
+ cites where it was measured.
22
+
23
+ ## 1. The physics and the baseline
24
+
25
+ For an efficient bandwidth-bound implementation,
26
+ decode tok/s ≈ bandwidth ÷ bytes-touched-per-token. The earlier mode-matrix benchmark
27
+ (`scripts/bench-matrix.ts modes`) confirmed what the roofline work predicted:
28
+ the then-tested L1 decode paths approached the memory-bandwidth wall
29
+ at short context, so tier levers cannot buy single-stream decode speed
30
+ (PLAN.md "Decision: naked default = --l1": decode parity with mlx-lm on every
31
+ model; no output-changing lever beat it). Faster therefore means one of five
32
+ physical moves:
33
+
34
+ 1. read the weight bytes ONCE for several tokens — speculation, batching;
35
+ 2. read FEWER bytes — quantization quality-per-bit;
36
+ 3. SKIP reads — caching (prefill/TTFT side, already leadership territory);
37
+ 4. shave the non-GPU residue — host overhead, dispatch count, residency.
38
+ 5. execute the math more efficiently when arithmetic, access patterns or
39
+ occupancy keep the implementation below its bandwidth limit.
40
+
41
+ One correction the bandwidth framing missed (2026-07-04, CPM5): small
42
+ ELEMENTWISE ops are dispatch-bound, not bandwidth-bound. An unfused swiglu
43
+ (`sigmoid` + `mul` + `mul`, 3 kernels/layer × 24) cost ~5% of decode; porting
44
+ mlx-lm's `@mx.compile` swiglu (`compiledSwiglu`, now the default in
45
+ `src/model/minicpm5.ts`, `qwen3.ts`, `qwen3_5.ts`, `qwen3-moe.ts`,
46
+ `universal/dense.ts`; `MLX_BUN_COMPILED_SWIGLU=0` kills it) moved CPM5 to
47
+ parity with mlx-lm, bit-identical tokens. The win was per-dispatch host +
48
+ encode tax, which is why CompiledDecode was 0% there (it replays the same
49
+ unfused graph). Packed trellis is a further exception: unpack arithmetic,
50
+ memory access patterns, and occupancy can dominate its matrix products.
51
+ Section 7 measures these limits for each shape and chip instead of assuming
52
+ fewer bits are faster.
53
+
54
+ ## 2. The levers, ranked
55
+
56
+ ### Lever 1 — speculative decoding, subject to a wall-clock win
57
+
58
+ One target forward verifies γ drafts + a bonus token: the weight read
59
+ amortizes over up to γ+1 tokens. The serve loop is the ONE verify/accept
60
+ executor (`src/spec/serve-loop.ts`, faithful to mlx-lm's
61
+ `speculative_generate_step`; grammar composes on the verify walk), reached
62
+ through `serve --draft-model` / `--draft-kind`, with `usage.speculation`
63
+ telemetry. Drafters, as wired in `src/spec/` and `src/cli.ts` on 2026-08-23:
64
+
65
+ | kind | source | status | evidence |
66
+ |---|---|---|---|
67
+ | `two-model` | `two-model.ts` — a full same-tokenizer draft model (mlx_lm.server parity) | landed | 48/48 token-for-token vs mlx-lm's spec path (`docs/design/batching.md` Phase B) |
68
+ | `assistant` | `assistant-source.ts` — optiq's KV-borrowing Gemma "-assistant" drafter | landed (was "build next" in the 2026-07-04 draft of this doc) | bit-exact vs optiq's `spec_generate`; 12B γ=1 ≈ 1.09× (`docs/design/speculative-decoding.md`); e4b a net loss at every γ (PLAN.md Phase 6) |
69
+ | `dspark` / `deepspec` | `dflash-source.ts`, `deepspec-source.ts` — DFlash KV-injection (ours / DeepSeek's released drafters) | landed, wall-clock NEGATIVE so far | 12B + block-7 drafter: τ ≈ 2.8 committed tokens per target forward but ~3.4× slower wall-clock (spec 14.6 vs serial 49.8 agg tok/s, loaded box) — the drafter's own weight reads and host syncs are the tax (`docs/design/speculative-decoding.md`) |
70
+ | `mtp` | `qwen-mtp-source.ts`, `glm52-mtp-source.ts` | Qwen3.8 implemented, opt-in; measured negative on the 27B | `speculative-decoding.md` section 4.4 records the off/on wall-clock comparison; acceptance alone is not a speed result |
71
+ | `ngram` | `ngram-source.ts` — model-free prompt lookup, lossless | landed | no drafter weights; drafts copied from the request's own context (`--ngram-max/--ngram-min`) |
72
+
73
+ What remains is drafters worth running, in this order:
74
+
75
+ - **1a. Reopen native MTP only with a changed cost model.** The native head
76
+ still reads head weights, projects vocabulary logits, and samples drafts.
77
+ The recorded Qwen off/on comparison lost. Test head quantization and small-M
78
+ verify kernels against the same artifact with MTP off; retain off as control.
79
+ - **1b. Cheaper drafter head** — the 262k tied-embedding argmax every draft
80
+ step dominates γ≥2 cost on the Gemma assistant drafter; capping or
81
+ approximating it extends the win past γ=1 (`docs/design/speculative-decoding.md`
82
+ "remaining levers").
83
+ - **1c. DSpark wall-clock flip** — `docs/design/speculative-decoding.md` Phases 0–4
84
+ (drafter weight diet, host-sync reduction in `draftBlock`, tapped verifies
85
+ on the optimized graph). Goal there: spec ≥ 1.3× serial on 12B at the best
86
+ config, clean machine. No-oracle / KL-gated (Lab).
87
+ - **1d. Grammar-aware speculation** — the grammar mask collapses the
88
+ drafting problem on structured output. State in `src/` today:
89
+ (i) **jump-forward** exists as `MLX_BUN_GRAMMAR_JUMP=1`, opt-in, in the
90
+ serial NON-spec loop only (`generate.ts` `shouldUseGrammarJump`; the batch
91
+ lane's `#stepGrammar` doesn't jump; excluded when logprobs are requested).
92
+ It is not yet folded into a spec verify window as a pre-accepted draft.
93
+ (ii) **constrained drafting** is NOT implemented — the drafter runs free and
94
+ the mask rides the verify walk (`serve-loop.ts` header); the
95
+ `MLX_BUN_SPEC_GRAMMAR_DRAFT` lever an older draft of this doc named does not
96
+ exist in `src/`. The measured motivation stands: acceptance dropped 51%→29%
97
+ under grammar with a blind drafter (our own matrix). (iii) grammar-pruned
98
+ draft TREES (XGrammar-2's `traverse_draft_tree`) — idea only.
99
+ - **Per-slot drafting under batching** — the composition-matrix row in the
100
+ architecture doc; a mounted draft routes every request serial today.
101
+
102
+ ### Lever 2 — native MLX updates against the pinned control
103
+
104
+ We are pinned to the oracle stack in PLAN.md "Reference environment" (mlx
105
+ 0.31.2). The July audit below identified upstream changes absent from that
106
+ pin. Recheck current releases and the native libraries actually loaded before
107
+ an upgrade experiment. A new mlx/mlx-c build also needs matching oracles;
108
+ retain the pinned installation and test the new stack in isolation.
109
+ Upstream refs are full URLs on purpose (a bare `#NNNN` here resolves to our
110
+ own tracker).
111
+
112
+ What `main` has (confirmed against the PR pages, 2026-07-04):
84
113
  - [ml-explore/mlx#3485](https://github.com/ml-explore/mlx/pull/3485)
85
- `GatherQMM::output_shapes` — merged 2026-05-29, zero numeric change. THE
86
- prize: resolves the `src/generate.ts` blocker that keeps 26B MoE decode
87
- uncompiled → unblocks CompiledDecode over the MoE (attacks the 26B host
88
- term).
114
+ `GatherQMM::output_shapes` (merged 2026-05-29, zero numeric change) — THE
115
+ prize: `src/model/compiled-decode.ts` still keeps MoE models uncompiled
116
+ because GatherQMM lacks `output_shapes` in the pinned mlx (verified
117
+ 2026-08-23); this unblocks CompiledDecode over the MoE and attacks the
118
+ 26B/30B-A3B host term.
89
119
  - [ml-explore/mlx#3764](https://github.com/ml-explore/mlx/pull/3764)
90
- `qmv_wide` — merged 2026-06-26. Small-M (≈2–8) quant matvec; helps
91
- SPEC-DECODE verify + batching, NOT single-stream M=1 and NOT the gather /
92
- MoE path. Becomes the default for M≈2–8 → re-baseline batched goldens.
93
- This is why the bump pairs with lever 1, not standalone.
94
-
95
- What `main` does NOT have (corrects the prior note):
96
- [ml-explore/mlx#3553](https://github.com/ml-explore/mlx/issues/3553) is an
97
- OPEN issue (the problem report), NOT a merged fix, and `qmv_wide` is not
98
- wired into the gather path. There is NO `gather_qmm` M=1 qmv-class fast
99
- path upstream — the 26B M=1 compute-bound gap (~4 ms/step) is ours to close
100
- (the shelved moe-qmv-kernel; roofline #2). Probable no-op:
120
+ `qmv_wide` (merged 2026-06-26) — small-M (≈2–8) quant matvec: helps the
121
+ spec-decode VERIFY forward and small batches, NOT single-stream M=1 and NOT
122
+ the gather/MoE path. Becomes the default at M≈2–8 → re-baseline batched
123
+ goldens.
124
+
125
+ The older description of
126
+ [ml-explore/mlx#3553](https://github.com/ml-explore/mlx/issues/3553) was wrong:
127
+ it describes a dense small-M QMV discontinuity, not the MoE gather path, and
128
+ is closed as of 2026-09-04. Issue status does not establish which fix is in
129
+ our binary. Inspect the selected dispatch and measure Qwen's actual shapes.
101
130
  [ml-explore/mlx#3120](https://github.com/ml-explore/mlx/pull/3120) (split-K
102
- small-M quant matmul) was in mlx HEAD 2026-03-21, before the 0.31.2 tag —
103
- likely already ours; confirm before counting it.
104
-
105
- Sequence: land this WITH lever 1 (speculation), where #3485 + #3764 both
106
- pay off — not as a standalone "faster decode" move it isn't.
107
-
108
- ### 3. Quantization quality-per-bit — fewer bytes IS more tok/s [expected ~10–15%]
109
-
110
- Decode scales ~linearly with weight bytes. oQ-style sensitivity-driven
111
- quant in `convert` (adoption map #4, eval-gated) and TurboQuant (Phase 13)
112
- are decode-speed programs wearing quality clothes: 4.0 → ~3.5 effective
113
- bpw at equal KL ≈ +10–15% decode with zero kernel work. Gate: perplexity
114
- + 6-task eval vs the existing knapsack at equal bpw.
115
-
116
- ### 4. Host-side residuals [expected 2–8% on affected models]
117
-
118
- - **CPM5 unfused swiglu — LANDED (+5.5% decode, 2026-07-04).** `compiledSwiglu`
119
- (minicpm5.ts) `mx.compile`s `silu(gate)*up` → one kernel at decode (M=1),
120
- cutting 48 dispatches/token. Proof the ~5% residual was dispatch tax, not GPU
121
- time. The exact-copy `FaithfulMiniCPM5` fuses it for ALL shapes like mlx-lm's
122
- non-M-gated `@mx.compile` (autograd-safe, Vjp maxDiff==0), which makes its
123
- per-token kernel SET byte-identical to mlx-lm's (24==24, verified via parseable
124
- **xctrace shader-list diff**); the M=1 gate leaves prefill unfused (extra
125
- `vn_Sigmoid`+`vvn_Multiply`, ~0.7% there). Whether to widen production's gate
126
- was deferred until the FaithfulMiniCPM5 A/B landed a verdict (it did — see the
127
- retired note below). The same
128
- standalone `sigmoid/silu + mul` pattern likely costs ~5% on other models' MLPs
129
- (gemma/qwen) — audit and give each an `mx.compile` helper.
130
- - **e4b ~5% per-step host overhead** (Phase 7 residual; dispatch count) —
131
- now a prime suspect for the SAME unfused-elementwise cause; try the
132
- compiledSwiglu treatment on its MLP.
133
- - **FaithfulMiniCPM5 exact-copy backend — BUILT (2026-07-04; retired
134
- 2026-07-05 — the default IS the faithful path; file deleted along with
135
- `MLX_BUN_CPM5_FAITHFUL`, unified-engine-frontier-plan.md §6).** Was
136
- `src/model/minicpm5-faithful.ts`: an op-for-op copy of mlx-lm's llama.py +
137
- activations.py, swappable against our optimized `MiniCPM5Model` through the
138
- same generate()/eval path. Bit-exact to the golden, dispatched-kernel set
139
- verified identical to mlx-lm's. The A/B reference — prove identical, THEN
140
- compare performance, THEN optimize. Debranching alone buys ~0% (host JS
141
- conditionals hidden by the GPU-bound pipeline); its analysis produced the
142
- matmul-fusion non-lever below.
143
- - **P4 device-side step chaining** — depth-k chained step graphs, one
144
- host sync per k tokens (batching-perf-path P4; the oMLX burst-decode
145
- REFUTATION does not apply — this attacks OUR FFI/readback cost, a
146
- different mechanism).
147
- - ~~**Perf-kernel default flip**~~ — OBSOLETE: the perf kernel was DELETED
148
- 2026-07-05 (regressed e4b 0.62–0.93× in the paired A/B; only win 12B@16k
149
- +6% with a KL WARN — unified-engine-frontier-plan.md §6).
150
-
151
- ### Non-levers (measured, don't re-litigate without new evidence)
152
-
153
- Megakernels at M=1 (bandwidth floor: ceiling ~1.78× CPM5, achieved 0.94×
154
- — multi-token amortization is required, which is levers 1/batching);
155
- oMLX-style burst decode (refuted for Bun); fused-decode activeN (refuted
156
- end-to-end on 12B, reverted); host graph-build overlap (already hidden by
157
- the pipelined loop — spin-injection proof in decode-roofline-lookagain);
158
- **QKV / gate-up matmul fusion at M=1** (CPM5 2026-07-04: q/k/v blocked by
159
- OptiQ mixed precision — v_proj 8-bit vs q/k 4-bit; gate/up fusible in 18/24
160
- layers but the speed-ceiling version is ~2% SLOWER — matmul dispatches are
161
- bandwidth-hidden, and a concatenated `[2I]` qmv is less efficient at M=1
162
- than two `[I]`. Contrast the swiglu win: that fuses ELEMENTWISE ops, which
163
- are dispatch-bound. Don't re-litigate matmul fusion for single-stream).
164
-
165
- ## Sequence
166
-
167
- **1a AssistantSource → 2 mlx bump + re-bench → 3 oQ spike → 1b cheaper
168
- head → 1c DSpark** (as its training milestones land, Josh-gated runs),
169
- with §4 host residuals as filler between blocks. Re-run
170
- `scripts/bench-modes.ts` (e4b + 12B, short/2k/4k) after each lever lands —
171
- it is this program's scoreboard; promote clean-machine rows to
172
- benchmarks/RESULTS.md.
131
+ small-M quant matmul) predates the 0.31.2 tag — probably already ours;
132
+ confirm before counting it.
133
+
134
+ For the dense 27B, prioritize small-M reuse for fill spans and prefill before
135
+ reopening MTP. MoE-specific changes belong to the other models' experiments.
136
+
137
+ ### Lever 3 — quantization quality, bytes and measured latency
138
+
139
+ On bandwidth-bound paths, reducing weight bytes can improve decode. Packed
140
+ formats also change unpack cost and access patterns, so test the latency of
141
+ each recipe. Existing quality-per-bit work includes the sensitivity-driven
142
+ knapsack (`convert --target-bpw`, `src/quantize/sensitivity.ts`, a port of
143
+ optiq's `analyze_sensitivity_exact`), rotation-folded quantization
144
+ (`--rotate-weights`, `docs/design/turboquant.md`), and TurboQuant KV
145
+ (`docs/design/turboquant.md`). The 27B program's measured verdict (STATUS.md /
146
+ PLAN.md "TurboQuant weights"): quality saturates at ≥4.5 bpw on ppl and
147
+ MMLU/GSM8K; recipes matter below 4 bpw, where rotation wins (the 3.86 bpw /
148
+ 13.9 GB Qwen3.8-27B-TQ artifact is the M4 Pro 24 GB fit lever). Decode tok/s
149
+ for those artifacts on a quiet box is still owed (PLAN W7) — do not quote a
150
+ speed number for them until it exists. Gate for any new recipe: perplexity +
151
+ the frozen 6-task eval at equal bpw, eval-DB rows.
152
+
153
+ ### Lever 4 — host-side residuals [expected 2–8% on affected models]
154
+
155
+ - **Compiled elementwise activations — LANDED** (§1). Same standalone
156
+ `sigmoid/silu + mul` pattern audited into every dedicated file; gemma geglu
157
+ is `MLX_BUN_COMPILED_GEGLU` (default on).
158
+ - **Weight residency (wiring) — LANDED 2026-08-23** (PLAN.md "Prefill vs
159
+ mlx-lm — paired re-measurement" and the follow-up; STATUS.md): the
160
+ large-model wiring policy was stale against macOS's reported working set,
161
+ so Qwen3.8-27B ran unwired. Both the serial generator and the continuous
162
+ scheduler now hold the same re-entrant wired scope (`acquireModelWiredLimit`
163
+ in `src/generate.ts`) while they own the GPU; the controlled replay moved
164
+ the final Qwen L=1 forward from about 1.48 s to 55 ms. Numerics unchanged.
165
+ Rule: a decode-class regression on a large model is a residency question
166
+ before it is a kernel question.
167
+ - **e4b ~5% per-step host overhead** (PLAN.md Phase 7 residual; dispatch
168
+ count) — still open; prime suspect is the same unfused-elementwise class.
169
+ Method: xctrace shader-list diff vs mlx-lm (the qwen3.5 kernel-trace parity
170
+ method), then `mx.compile` the site.
171
+ - **P4 device-side step chaining** — depth-k chained step graphs, one host
172
+ sync per k tokens (`docs/design/batching.md` P4). Attacks OUR FFI/readback
173
+ cost — a different mechanism from oMLX's burst decode, whose refutation
174
+ (§6) does not apply.
175
+ - **Padded-B>1 per-step mask rebuild** — by design in the scheduler's padded
176
+ branch; unmeasured at B>1, likely amortized. Measure via a forced-padding
177
+ aggregate A/B before building a step-stable mask cache (PLAN.md 2026-07-06
178
+ audit).
179
+ - **MoE M=1 gather path** — see lever 2; the compute-bound gap on 26B/30B-A3B
180
+ is a kernel item, not a bump item.
181
+
182
+ ### Non-levers (measured; don't re-litigate without new evidence)
183
+
184
+ - **Megakernels at M=1** — bandwidth floor: ceiling ~1.78× on CPM5, achieved
185
+ 0.94× (`docs/design/generic-model-support.md`); multi-token amortization is
186
+ required, which is lever 1 / batching.
187
+ - **oMLX-style burst decode** — refuted for Bun (§6).
188
+ - **Fused-decode / perf kernel / custom fused-gelu** — deleted 2026-07-05
189
+ after losing the paired A/B (architecture doc §11). A future flash-decode
190
+ kernel re-derives from the L1 baseline in the Lab.
191
+ - **QKV / gate-up matmul fusion at M=1** — CPM5 2026-07-04: q/k/v blocked by
192
+ OptiQ mixed precision (v_proj 8-bit vs q/k 4-bit); gate/up fusible in 18/24
193
+ layers but the speed-ceiling version measured ~2% SLOWER — matmul
194
+ dispatches are bandwidth-hidden and a concatenated `[2I]` qmv is less
195
+ efficient at M=1 than two `[I]`. Contrast the swiglu win: elementwise ops
196
+ are dispatch-bound.
197
+ - **Host graph-build overlap** — already hidden by the pipelined loop
198
+ (spin-injection proof in
199
+ `docs/archive/investigations/decode-roofline-lookagain.md`).
200
+ - **Debranching alone** — ~0% (host JS conditionals hidden by the GPU-bound
201
+ pipeline); it stays a hygiene item in the architecture doc, not a speed
202
+ lever.
203
+
204
+ ## 3. Sequence
205
+
206
+ The current Qwen3.8-27B order is section 7.7: trustworthy controls, graph
207
+ capture, packed kernels and deterministic replay, then the remaining measured
208
+ bottlenecks and serving interactions. MTP requires a changed cost model.
209
+ For shared engine changes, also run `scripts/bench-matrix.ts modes` on the
210
+ affected e4b/12B controls. Promote clean-machine rows to
211
+ `docs/reference/benchmarks.md`.
212
+
213
+ ## 4. Related design ownership
214
+
215
+ Section 7 coordinates TTFT, prefill, decode, and throughput. Implementation
216
+ design remains with its topic: prompt cache + SSD tier
217
+ (`docs/design/kv-cache.md`), batching aggregate (`docs/design/batching.md`),
218
+ prefill vs mlx-lm (PLAN.md "Prefill vs mlx-lm — paired re-measurement",
219
+ "Qwen3.8 prefill — measurement + analysis", and the prompt-to-response
220
+ attribution matrix in STATUS.md).
221
+
222
+ ## 5. Measurement discipline
223
+
224
+ - Every claim is a paired A/B on this machine, labeled host/chip/RAM; run
225
+ spread is the quality signal (`bench-h2h` retries unstable cells and
226
+ withholds verdicts). Numbers on a loaded machine are not quotable.
227
+ - Wall-clock only. SSE-burst inflates naive tok/s; oMLX's own logs
228
+ over-report.
229
+ - Verify the served model id (`/v1/models`) before trusting any bench.
230
+ - A perf gap vs mlx-lm/optiq is OUR bug until proven otherwise: copy the
231
+ oracle op-for-op, prove the kernel set identical (xctrace shader-list
232
+ diff, `export_to_dot` op-set diff), then optimize.
233
+
234
+ ## 6. Port ledger vs oMLX
235
+
236
+ oMLX (github.com/jundot/omlx, Apache-2.0) is the systematic port source for
237
+ serving features: read its real implementation (the full source ships in the
238
+ local app bundle under `/Applications/oMLX.app/Contents/Resources/omlx/`),
239
+ port the IDEA into our architecture, keep it only if OUR benchmarks improve.
240
+ Attribution: derived code is noted in `THIRD_PARTY_LICENSES.md` (the
241
+ xgrammar row credits `api/grammar.py`); idea ports get a source comment.
242
+
243
+ ### Where oMLX sits in the tier model
244
+
245
+ It doesn't slot at L1 or L2 — it decomposes. The tiers are numerics
246
+ contracts; oMLX is a Python appliance ON mlx-lm:
247
+
248
+ - its stock forwards are mlx-lm's numerics = our existing L1 oracle (no new
249
+ oracle value);
250
+ - its own numeric inventions (oQ, custom kernels, DFlash, MTP) are
251
+ oracle-less = Lab-class here, and get our Lab gating (KL/eval/envelope +
252
+ kill switch) that they lack upstream;
253
+ - its product surface (SSD cache, EnginePool, menu bar, MCP, grammar) is the
254
+ tier-agnostic serving layer — keyed by the effective scheme, never part of
255
+ the decode-numerics graph.
256
+
257
+ ### Ported, kept (benchmarked wins)
258
+
259
+ | feature | theirs | ours | result |
260
+ |---|---|---|---|
261
+ | Continuous batching | scheduler on mlx-lm `BatchGenerator` | `--batch N` (default 8) → `src/serve/batch-scheduler.ts`, per-row samplers/processors, SSM (Qwen3.5) rows, `--kv-budget` admission, universal (Llama) per-row RoPE | cpm5 aggregate win, e4b/Qwen3.5 within a few %, TTFT 2–3× better (`docs/design/batching.md`); B=1 through the scheduler 0.992–0.996 of serial (PLAN.md) |
262
+ | SSD KV cold tier | `cache/paged_ssd_cache.py` (content-hashed blocks) | `src/ssd-cache.ts` + kv-store v2 (whole-entry spill, zero-copy mmap), inside `PromptCache.take()` | restart TTFT 12.1 s → 0.24 s vs their 1–3 s; 0% decode overhead vs their ~20% (`docs/design/kv-cache.md`) |
263
+ | Structured output | `api/grammar.py` | `@mlc-ai/web-xgrammar` (WASM), full `response_format`/`guided_*` surface, serial AND batched, composes with spec | byte-identical content vs oMLX (`docs/reference/server-api.md`) |
264
+ | Multi-model serving / EnginePool | `engine_pool.py` (LRU + pinning + load/unload) | `--isolate --model-pool N` → `ModelPool` in `src/serve/isolate.ts`: LRU residency over engine children, routing by the request `model` field, spawn-overlap switching, drain → demote-to-SSD → park | switch ~1.5 s, switch-back ~1.2 s with the conversation's KV restored from disk (PLAN.md 2026-07-05, M1 Max, cpm5⇄qwen0.8b) |
265
+ | DFlash serving wiring | `engine/dflash.py` + their published drafts | `DflashSource` / `DeepSpecSource` behind the same `DraftSource` seam as every other drafter (`--draft-kind dspark|deepspec`) | serve-integrated; wall-clock negative on 12B so far (lever 1c) |
266
+
267
+ ### Ported, refuted (do not re-add without new evidence)
268
+
269
+ | feature | why it doesn't transfer |
270
+ |---|---|
271
+ | Adaptive burst decode (`engine_core.py _step_burst`) | Amortizes Python GIL/asyncio ping-pong (~1 ms/token). Bun's `setImmediate` hop costs microseconds; the faithful port REGRESSED cpm5 B=4 aggregate 345→289, batch-lane B=1 149→121, and TTFT ~+100 ms (first-token SSE flush waits out the burst). Reverted with a breadcrumb in `batch-scheduler.ts`. |
272
+
273
+ ### Queue (by leverage; ★ = Josh explicitly wants)
274
+
275
+ 1. **★ Menu bar app** (`apps/omlx-mac/`, native SwiftUI + Sparkle) — product
276
+ layer. Their repo is the structural reference; our signed/notarized single
277
+ binary is the sidecar. Supersedes `docs/design/web-chat-redesign.md`'s Electron
278
+ ambivalence. Not started.
279
+ 2. **oQ-style sensitivity-driven quantization** (`oq.py`,
280
+ `docs/oQ_Quantization.md`) — Lab-class, would land in `convert` beside
281
+ `--target-bpw`: calibration-measured per-layer sensitivity with boosts on
282
+ non-expert tensors only and batched expert GPTQ. Note the distinction: our
283
+ `sensitivity.ts` is a port of optiq's exact-KL sweep, not oMLX's oQ. Gate:
284
+ perplexity + 6-task eval vs the knapsack at equal bpw. The 27B finding that
285
+ quality saturates ≥4.5 bpw narrows where this can pay (sub-4 bpw).
286
+ 3. **Vision feature cache** (`cache/vision_feature_cache.py`) — encoder
287
+ features for repeated-image agent turns; natural second client of the SSD
288
+ substrate (Layer 0 in the architecture doc). Not started.
289
+ 4. **MCP tool execution in serve** (`--mcp-config`, `mcp_routes.py`) — Pi
290
+ already owns tool orchestration for our UIs; scope to bare-API consumers.
291
+ Not started.
292
+ 5. **Prefill progress observability** (`prefill_progress.py`) — /stats + web
293
+ UI surfacing for long prompts. Our `PromptResponseTrace` is a diagnostic,
294
+ not a live progress signal. Not started.
295
+ 6. **Rerank endpoint** (`/v1/rerank`) — needs a reranker model family first.
296
+ 7. **Document ingestion (MarkItDown)** — would go through Pi attachments, not
297
+ the server.
298
+ 8. **Admin one-click benchmark with prefix-cache-hit testing** — fold into
299
+ `scripts/bench-serving-load.ts` as a cache-hit-ratio mode; not present.
300
+
301
+ ### Explicitly not porting
302
+
303
+ - **Audio STT/TTS/STS** — our audio work is the input tower
304
+ (`docs/design/generic-model-support.md`), not their pipeline.
305
+ - **Their SSE burst streaming** — a side effect of the GIL workaround;
306
+ per-token streaming is strictly better UX at zero cost here.
307
+ - **Python-side scheduler details** (GIL executors, collector reaping) —
308
+ runtime-specific.
309
+
310
+ ### Porting discipline
311
+
312
+ 1. Read their real source first (the local app bundle) — the README lies
313
+ less than the code.
314
+ 2. Port the idea into OUR architecture; never transliterate Python.
315
+ 3. Benchmark before/after on THIS machine; keep only wins (burst decode died
316
+ here). Wall-clock metrics only.
317
+ 4. Numeric features get Lab gates + kill switches; serving features get
318
+ effective-scheme keying; nothing touches the L1/L2 contracts.
319
+ 5. Verify the served model id before trusting any bench.
320
+
321
+ ## 7. Qwen3.8-27B research program
322
+
323
+ Josh requested a complete inference optimization campaign on 2026-09-04.
324
+ Optimize useful completed work at a measured quality and memory budget.
325
+ The deliverable is a frontier of configurations for the M4 Pro, with a reason
326
+ to keep or reject every investigated method. A smaller artifact, a faster
327
+ microkernel, and a higher draft acceptance rate are intermediate results.
328
+ Each must survive the full application measurement.
329
+
330
+ Josh narrowed the remaining hardware scope to the M4 Pro on 2026-09-06.
331
+ M1 Max runs are not required for this campaign. Existing M1 Max evidence
332
+ remains historical; the final report format still supports other machines.
333
+
334
+ Single-request performance is a primary acceptance target alongside aggregate
335
+ serving. Use the existing `scripts/bench-serve.ts all` workload, which replaced
336
+ the root `benchmark.sh` in `7d81462`: sustained decode, cold and cached TTFT,
337
+ 1k and long-context prefill, decode at context, restart reuse, sampled RSS and
338
+ load/readiness. Its prefill rate includes the work before the first streamed
339
+ token; keep pure native prefill timing separate. A short-prompt TTFT gain does
340
+ not establish a 1k/long-context gain. Record MLX active/peak allocations
341
+ separately from sampled RSS, which does not account for all GPU memory.
342
+
343
+ Preserve the refactor's request, completion, graph and session contracts.
344
+ Keep numerical dispatch and resource handling in backend/model operations;
345
+ HTTP parsing must not select kernels. Add an abstraction only when a retained
346
+ change needs it. Remove closed experimental helpers after documenting their
347
+ findings, and reject extra production caches or dispatch branches without a
348
+ complete-request benefit.
349
+
350
+ This program includes new weight formats, custom Metal kernels, fusion,
351
+ unrolling, alternate algorithms, and deterministic replay without verification.
352
+ It supersedes the older weights-leg restriction against new qmm kernels for
353
+ this campaign. Numerical changes retain the repository's L1/L2/Lab contracts.
354
+ The weight recipe remains in [turboquant.md](turboquant.md), cache design in
355
+ [kv-cache.md](kv-cache.md), and replay/speculation design in
356
+ [speculative-decoding.md](speculative-decoding.md). PLAN owns open status.
357
+
358
+ ### 7.1 What the initial audit establishes
359
+
360
+ The local artifacts select the dense `qwen3_5` graph: 64 layers, three
361
+ GatedDeltaNet layers followed by one full-attention layer per group of four.
362
+ Hidden width is 5120; MLP width is 17408. There are 192 MLP matrices.
363
+ Full attention has 24 query heads, four KV heads, and head dimension 256.
364
+ GDN has 16 key heads and 48 value heads, both with dimension 128.
365
+ These are config/header observations, not measured shader dispatches.
366
+
367
+ The packed Q3 metadata contains duplicate module aliases. Counting config
368
+ entries reports twice the actual trellis matrix count. The new
369
+ `scripts/bench/model-inventory.ts` counts tensors present in shard headers,
370
+ groups matrices by role, logical shape, bits, group size and coding axis,
371
+ and includes scales/biases in matrix storage. Its matrix bpw denominator is
372
+ explicit; it does not claim whole-model bpw or resident memory. It does not
373
+ read or hash weight payloads. Sidecars and MTP companions require their own
374
+ inventory. Raw inventories and source pins go under `reports/qwen38-rd/`.
375
+
376
+ The source inspection found these starting points:
377
+
378
+ - `TrellisLinear.forward` uses packed matvec for flattened M ≤ 4 and dense
379
+ expansion plus stock matmul above it. Prefill currently evaluates each
380
+ projection, and `Qwen35Model.forwardLayers` evaluates cache outputs per
381
+ layer, to bound live buffers. Removing these barriers without replacing
382
+ their memory bound can recreate the OOM already being fixed.
383
+ - Decode defaults to trellis variant 6. It computes f32 code×scale, whereas
384
+ expansion rounds to bf16. A trace across M=4/5 therefore crosses both a
385
+ performance boundary and a numerical boundary. Variant 4 has deliberately
386
+ wrong numerics and is only a diagnostic cost floor.
387
+ - Trellis dispatch hard-codes 128 threads, four SIMD groups and 128 scatter
388
+ splits. Gate/up fusion requires compatible geometry. These are parameters
389
+ to measure per chip and bit allocation, not universal optima.
390
+ - `GatedDeltaNet.forward` separately dispatches convolution, SiLU, q/k norms,
391
+ q/k scaling, gate computation, recurrence and gated output normalization.
392
+ Its recurrence already keeps state in registers across sequence positions.
393
+ - Full attention separately applies the output sigmoid and multiplication.
394
+ Any fusion must reproduce the existing intermediate rounding to retain L1.
395
+ - The existing `__deltaProf` instrumentation calls `evalAll` between stages.
396
+ It is useful for isolation and changes execution overlap. Its times cannot
397
+ be summed into a claimed production speedup.
398
+ - Strict fill already uses `policy: "assert"`: no verification/readback in
399
+ normal operation. It advances hidden states and all caches for the span,
400
+ skips intermediate vocabulary heads, and discards an in-flight sample.
401
+ The source still pays that discarded sample's scheduled work.
402
+ - MTP is an optional, previously losing 27B arm. See the actual off/on
403
+ experiment in speculative-decoding section 4.4. High acceptance never
404
+ established a Qwen throughput win.
405
+
406
+ The initial CPU inventory covers the locally available 27B artifacts. The
407
+ first benchmark preflight refused the occupied M4. Subsequent native controls
408
+ and candidate timings are diagnostic; the quiet HTTP baseline remains open.
409
+ Environment details,
410
+ including the different installed OptiQ versions, belong in
411
+ [environment.md](../reference/environment.md).
412
+
413
+ #### Refactor review: main at `673b43f` (2026-09-05)
414
+
415
+ The 35 commits after `6d45ca1` merge the interface-based engine refactor.
416
+ Its implementation and acceptance record are in
417
+ [engine architecture §12.13](unified-engine-frontier-plan.md#1213-implementation-status-2026-09-05).
418
+ They change the execution paths to inspect and the way we register candidates;
419
+ they do not establish a new 27B performance baseline. The repeated upstream
420
+ HTTP comparisons used MiniCPM5/Gemma e4b on a loaded M1 Max. The designated
421
+ 27B quants, quiet performance and second-machine acceptance remain open.
422
+ Upstream did not change `qwen3_5.ts`, `trellis-linear.ts` or `qwen3-delta.ts`
423
+ in this merge. Retain the existing quant-quality controls and negative MTP
424
+ result, then remeasure the complete serving path at the new revision.
425
+
426
+ The M4 Pro audit now uses isolated, unmodified `6d45ca1` and `673b43f`
427
+ checkouts. Their MLX binding and Qwen/Trellis numerical source blobs are
428
+ identical. Six fresh-process native AB/BA pairs hold Bun, artifact, variant 6,
429
+ greedy settings and a bounded prefill policy fixed. All warmup and measured
430
+ IDs agree at 6/128/512 prompt tokens, every worker exits cleanly, and both
431
+ source snapshots stay fixed. Native TTFT, complete-request timing and memory
432
+ are approximately flat; this provides no evidence of a native regression on
433
+ those workloads. Six serial HTTP process pairs also preserve every response,
434
+ token count and finish reason, with fixed sources and clean shutdowns. TTFT,
435
+ complete-request time and sampled peak RSS are approximately flat. Telemetry
436
+ confirms the serial executor. Six additional default-scheduler pairs also
437
+ preserve every response, with fixed sources and clean shutdowns. Per-request
438
+ telemetry proves that these requests enter the scheduler. Complete-request
439
+ timing is flat or slightly lower after the refactor, decode timing is flat,
440
+ and sampled peak RSS is close. These controls provide no evidence of a
441
+ refactor slowdown on the measured native or serving workloads. Both historical
442
+ revisions run unmodified; no memory-fix overlay was needed for these bounded
443
+ requests. Prompt/SSD caches are disabled throughout. Cached, sustained-pressure
444
+ and second-machine acceptance remain separate checks.
445
+ Evidence: `refactor-fixed-kernel-audit-plan.json`, `refactor-native-paired.json`
446
+ and `refactor-native-paired-review.json`, plus
447
+ `refactor-http-paired-{serial,default}-review.json`, under `reports/qwen38-rd/`.
448
+
449
+ The refactor is completed infrastructure for this performance campaign.
450
+ Its unrelated interface and product-acceptance work stays in its own program.
451
+ Use the new seams to isolate the expensive computation, then measure whether
452
+ a replacement pays off. The plan changes in five places:
453
+
454
+ - **R0 follows the current execution path.** Freeze the merged source plus local
455
+ diff, then run `tests/parity/qwen-quant-engine.test.ts` separately for each
456
+ exact artifact via `MLX_BUN_QWEN_QUANT_PATH`. Follow with same-artifact
457
+ serial/default/oracle controls. Use the same memory safeguards on any old/new
458
+ revision comparison; the unpatched packed-prefill OOM path is not a viable
459
+ baseline. Historical reports retain their original source identity.
460
+ - **Register kernel candidates through the model implementation registry.**
461
+ `model/implementation.ts` selects the declared graph/loader/loop and refuses
462
+ missing or incompatible implementations. Give a changed graph, layout or
463
+ method an explicit identity and compatible state/codec ABI. Verify the
464
+ selected registration in every benchmark; no silent fallback arm.
465
+ - **Profile the new lifecycle as well as the kernels.** Shared prefill now
466
+ uses `inference/prefill.ts` and `backends/mlx/prefill.ts`; native serial
467
+ ownership lives in `backends/mlx/serial-executor.ts`. Session demand,
468
+ resolved policy, leases, snapshots and readback cleanup are part of the
469
+ measured path. Shared prefill extraction does not implement B-wide prefill.
470
+ - **Preserve bounded memory while tuning.** Local projection/cache evaluation
471
+ barriers remain. The local serial headroom guard now enters through the MLX
472
+ binding after cache acquisition and restores its previous model hook on
473
+ every exit. SSD tensor steps share the gateway lease and pending writes drain
474
+ before serial generation. Test failed demotion, cancelled replay and retained
475
+ checkpoints before changing those boundaries in R2/R16/R17/R22.
476
+ - **Replay and MTP must pass resolved-policy gates.** The new speculative
477
+ bindings and rollback ownership are correctness infrastructure. They are not
478
+ evidence of faster MTP. Confirm strict fill is active under the captured
479
+ execution policy and that checkpoint identity includes that policy before
480
+ timing R15. Keep MTP off in the initial controls.
481
+
482
+ The earlier M4 DeltaNet discrepancy is resolved by an explicit pinned-oracle
483
+ replay on unchanged inputs. Bun and Python match exactly; the old fixture
484
+ differs at one output. The regenerated fixture records provenance and exact
485
+ recurrent-state hashes, with no tolerance change. See
486
+ [environment.md](../reference/environment.md) for the evidence and command.
487
+ The model-free checkpoint passes with the experimental kernels and replayed
488
+ fixture. Quiet application and full-model same-machine oracle acceptance
489
+ remain open.
490
+
491
+ The native control worker now freezes prompt token IDs for both engines and
492
+ records the configured plus tokenizer EOS policy, fresh-cache wall time,
493
+ TTFT, actual outputs and peak memory. Repeated short-prompt controls on the
494
+ flagship, compact and RTN4 affine artifacts reproduce the oracle's greedy
495
+ outputs. Their original timing comparison had unmatched wiring: the Python
496
+ worker omitted mlx-lm's usual wired scope. That worker is corrected and
497
+ matched-wiring timing controls must be repeated. Raw paired reports live in
498
+ `reports/qwen38-rd/native-affine-paired/`; their residual-swap preflight fails,
499
+ so they establish neither a quiet serving baseline nor full logit parity.
500
+ The longer flagship prefill completed its warmup but crashed in the measured
501
+ Bun request. Native exception tracing confirms a Metal OOM, also reproduced
502
+ in the Python worker with its usual wired scope. Clearing the Bun allocator
503
+ cache at request entry does not fix it. Both workers complete repeated
504
+ requests with chunk size 512 and identical observed tokens. Chunking changes
505
+ the numerical graph, so this does not prove identity against chunk size 2048.
506
+ These direct workers bypass serving admission and pressure safeguards; their
507
+ failures do not establish a regression in the repaired serving path. Evidence:
508
+ `reports/qwen38-rd/native-memory-ledger.json` and `native-memory-chunk512-screen/`.
509
+ Remaining quants and packed controls are separate cells. See
510
+ [benchmark tooling](../reference/benchmarks.md) for commands.
511
+
512
+ ### 7.2 Freeze the controls and workload matrix
513
+
514
+ Start with packed Q3, the affine flagship, plain RTN4, compact affine, and
515
+ published OptiQ. Retain the down-input-axis and unrotated artifacts as known
516
+ quality-failure controls. Inventory the fake-quant and carrier artifacts,
517
+ but do not load them on a machine where the full working set cannot fit.
518
+ The bf16 teacher uses the existing streamed KL procedure on these Macs.
519
+ Test every available artifact once; expand expensive sweeps around survivors.
520
+
521
+ | axis | cells and controls |
522
+ |---|---|
523
+ | Stack | Same affine snapshot on mlx-bun serial and pinned mlx-lm first; default scheduler separately. Packed trellis has no stock mlx-lm loader. Its carrier is a different precision and footprint. vLLM-Metal is a same-MLX comparison where the artifact is supported; llama.cpp/GGUF is a separately qualified ecosystem comparison. |
524
+ | Weights | Existing artifacts first; affine 2/3/4/5/6/8-bit with supported group sizes 32/64/128; mixed allocation; rotated/plain RTN and calibrated recipes; trellis k2/k3/k4 mixtures and the Q5 2.75 budget; supported mxfp4/nvfp4; new codes or layouts after microkernel evidence. Do not equate nominal bits with total bytes. |
525
+ | Context | 128, 1k, 4k, 8k, 16k and 32k prompt tokens; 64k and larger only after a measured memory projection. Decode at each depth, without generating an entire long context to establish it. |
526
+ | Prefill | Chunk sizes 128/256/512/1024/2048, plus unsplit only when it fits. Test a partial final chunk, cached suffixes, and the one-token tail convention. |
527
+ | Output | 256 generated tokens for screening, plus a sustained 1024-token cell for finalists. Record actual counts, EOS and finish reasons. Never score early EOS as faster completion of the same task. |
528
+ | B and M | B=1 serial control; scheduler concurrency 1/2/4/8 as memory permits. Kernel M=1/2/3/4/5/8/16/32/128/512, including B×sequence products with the same M but different cache semantics. |
529
+ | KV | bf16, affine KV8/KV4, then TurboQuant k8v3 and measured alternatives. GDN state is a separate allocation. Verify the active codec, bytes and dispatch; RSS is insufficient. |
530
+ | Work | Plain text, long reasoning, code generation/editing, multi-turn tool sessions, structured output, raw completions including the EOS-cliff items. Screen text first; finalists also cover repeated images and short video. |
531
+ | Reuse | Cold process, process-warm with cold prompt, RAM prefix hit, SSD restore, exact resumed generation and edited-prefix miss. Pin cache budget and checkpoint policy. |
532
+ | Replay/spec | Fill off baseline; strict no-verification fill; echo separately; MTP off/on only after head/verify economics. Unsupported combinations get a reason, not a silently inactive arm. |
533
+
534
+ Freeze prompt token IDs, tokenizer/template hashes, thinking mode, tools,
535
+ stop policy, sampler settings, context and output budgets. Use the same
536
+ prompt and initial cache state within each pair. Greedy engine tests and
537
+ representative stochastic serving tests answer different questions.
538
+
539
+ Record source commit plus source diff hash, model revision and shard content
540
+ hashes or existing trusted manifests, quantization map, compiled native library
541
+ and metallib hashes, Python packages, Bun, OS, chip, RAM, wired limit, disk,
542
+ power and thermal state. Hash large payloads outside timed runs. A matching
543
+ config hash does not prove identical weights. Keep pinned-oracle comparisons
544
+ separate from an isolated newer-MLX experiment; never upgrade the oracle in place.
545
+
546
+ ### 7.3 Account for the complete graph
547
+
548
+ Generation and serving each need a measured baseline and acceptance result.
549
+ Native timing covers model computation, generation-loop scheduling and state
550
+ cleanup. HTTP timing additionally covers preparation, admission/queue wait,
551
+ cache lookup/restore, transport and stream completion. Measure cold prompts,
552
+ RAM hits, SSD restores, edited prefixes, concurrent requests, disconnects
553
+ and continued tool sessions. Keep per-request TTFT, stream gaps, complete
554
+ request latency and aggregate throughput; a burst of SSE chunks is not a
555
+ sequence of individually timed model tokens. Attribute the server overhead
556
+ using request traces and matched native work, accounting for cache, batching
557
+ and sampler differences before subtracting timings.
558
+
559
+ Tune operations by their contracts, not by the model name. Each candidate
560
+ records supported shapes, dtypes, strides, quant layout, reduction/rounding
561
+ order, state ownership, hardware and workspace limits. Compare applicable
562
+ algorithms and tune dispatch across those regimes. Retained kernels belong
563
+ in the shared operation layer; model code selects them only when the
564
+ contract holds and retains a tested fallback. Other models using that
565
+ operation need their own call-site and full-model gates. A winner on this
566
+ Qwen/M4 shape is evidence for that cell, not a universal best kernel.
567
+
568
+ Use the knowledge graph to discover definitions, then follow the actual
569
+ implementations and MLX/Metal dispatch. The static index sometimes resolves
570
+ generic `forward`, `state` and `dispose` methods to unrelated classes. It is
571
+ a navigation aid; runtime traces establish the executed graph.
572
+
573
+ | stage | local entry points and work to account for |
574
+ |---|---|
575
+ | Request and admission | `serve/request-prep.ts`, `chat-stage.ts`, `session-completion-engine.ts`, `generation-gateway.ts`, `engine/session.ts` and `execution-coordinator.ts`: tokenization, demand, queue/lease wait, resolved policy, actual lane and admission. |
576
+ | Model and method binding | `model/implementation.ts`, `backends/mlx/model-serving.ts`, `graph.ts`, `autoregressive.ts` and `serial-executor.ts`: exact registration, captured runtime, hidden-state/logit selection, state ownership and native execution. Trace the selected method rather than assuming every registration uses the compatibility binder. |
577
+ | Prefill scheduling | `inference/prefill.ts`, `backends/mlx/prefill.ts` and `batch-group.ts`: shared chunk/tail/snapshot decisions, cache evaluation, maintenance, temporary disposal and scheduler yields. Distinguish shared scheduling from B-wide kernels. |
578
+ | Embedding and output | `qwen3_5.ts`, `gemma4-base.ts`: embedding gather/dequant, final norm, untied vocabulary projection, dtype casts, sample/logits processors and host token readback. Include both embedding and head storage. |
579
+ | Every layer | `Qwen3Layer.forward`: input/post-attention RMSNorm and residual adds. Count each dispatch, view, materialized copy and temporary. |
580
+ | GDN projections | `GatedDeltaNet.forward`: qkv, z, a, b and output projections, including small head projections often missed by MLP-only profiling. |
581
+ | GDN convolution | Prefix concat, depthwise conv, SiLU, tail copy, state lifetime and update; distinguish S=1 from prefill. |
582
+ | GDN recurrence | `qwen3-delta.ts`: q/k normalization/scaling, computeG, sigmoid beta, scan, f32 state reads/writes, gated normalization and speculative prefix replay. |
583
+ | Full attention | q-plus-output-gate projection, k/v projections, q/k norms, reshape/transpose, RoPE/mRoPE, cache update, SDPA dispatch, output gate and o projection. |
584
+ | Quantized attention | `quantized-sdpa.ts` and `turboquant/`: quantize, pack, gather/dequantize, tile attention, rotations and reductions. Trace the selected branch and its masks. |
585
+ | MLP | Affine QMV/QMM; trellis reduce/scatter/expand/fused gate-up; split-K partials, final sum/cast, SwiGLU and down projection for all 192 matrices. |
586
+ | Generation loop | `generate.ts`, `backends/mlx/request-policy.ts`, `engine/resources.ts`, `mlx/ops.ts`, `mlx/ffi.ts`: graph construction, compile caches, async/blocking eval, pending sample and readback ownership, cancellation, disposal and memory cache management. |
587
+ | Reuse and persistence | `prompt-cache.ts`, `kv-store.ts`, `ssd-cache.ts`: hashes, snapshots, state copies, cache-owned views, disk stalls, generation-lock contention and cancellation. |
588
+ | Optional paths | `spec/serve-loop.ts`, `qwen-mtp-source.ts`, `fill/*`, batch scheduler, grammar sampling, vision tower/merger and image feature reuse. Activate and trace each separately. |
589
+
590
+ For each exercised regime export the MLX graph before materialization and
591
+ capture a warmed Metal trace. Use production scheduling for attribution;
592
+ profiled/debug captures are never the reported timing run. MLX documents
593
+ graph capture and source-labelled debug builds in its
594
+ [Metal debugger guide](https://ml-explore.github.io/mlx/build/html/dev/metal_debugger.html).
595
+ The installed mlx-c exports `mlx_export_to_dot(FILE*, mlx_node_namer,
596
+ mlx_vector_array)`; its header and dylib symbol were checked without loading
597
+ MLX. The Bun wrapper still needs that graph-export binding. Metal capture already
598
+ exists as `metalCapture(path, fn)` in `src/mlx/metal-kernel.ts`, bound to
599
+ `mlx_metal_start_capture`/`stop_capture`. Reuse it with
600
+ `MTL_CAPTURE_ENABLED=1`; warm first, then evaluate outputs and cache state
601
+ inside its synchronous callback so the capture contains executed work.
602
+ Use Instruments for host/encode timing and counters alongside the capture.
603
+
604
+ Export each region before its existing evaluation barrier. A graph exported
605
+ only after the full forward can omit already-materialized projections and
606
+ earlier prefill chunks. Join the fragments using named tensor/state edges and
607
+ an explicit barrier ledger; do not remove the memory bounds to obtain a larger
608
+ graph. Compiled/custom operations also require their source-level subgraphs
609
+ and Metal pipelines in the coverage record.
610
+
611
+ Each kernel row records caller, shader/pipeline, shape, strides, dtype,
612
+ quantization, grid/threadgroup, registers/spills where tooling exposes them,
613
+ threadgroup memory, dispatch count, GPU duration, logical read/write bytes,
614
+ intermediate allocations and synchronization edges. Use counters to distinguish
615
+ bandwidth, instruction throughput, latency and occupancy limits. Logical
616
+ bytes divided by time is not a measurement of DRAM traffic.
617
+
618
+ Cover all shader dispatches, graph nodes and explicit host/GPU waits in every
619
+ selected regime. Group identical shapes for tuning, but retain layer counts
620
+ and call-site mapping. Reconcile GPU intervals and host gaps with end-to-end
621
+ wall time; investigate an unexplained remainder above 5%. Overlapping kernel
622
+ times must not be added as though they were serial wall time. Untested branches
623
+ remain marked untested.
624
+
625
+ Microbench both dependent repeated work and independent work with production
626
+ pipeline depth. Warm compilation, evaluate outputs and state, then time batches
627
+ of operations with one final synchronization. Avoid an `eval()` per tiny op
628
+ unless explicitly measuring sync overhead. Check against the real forward:
629
+ constant-input reuse, cached expansions or dead graphs can create false wins.
630
+
631
+ ### 7.4 Experiments, in execution order
632
+
633
+ This is the initial search set. Each row expands into single-variable trials
634
+ with its source reference, gate, raw result and stopping reason in the run
635
+ ledger. A candidate's priority changes when the measured graph changes.
636
+
637
+ | ID | experiment | measure and deciding condition |
638
+ |---|---|---|
639
+ | R0 | Exact artifact and execution controls for performance | Freeze `673b43f` plus the integrated local diff; matched token IDs, active graph/method/quant, raw timings and actual memory. Use relevant numerical and lifetime gates; the wider refactor acceptance program is separate. Resolve the M4 delta golden cell before L1 promotion. |
640
+ | R1 | Packed prefill tile decode plus matmul | Decode a tile into registers/threadgroup storage and consume it with supported Metal matrix operations. Compare with bounded dense expansion. Win must lower TTFT without a larger peak live working set. |
641
+ | R2 | Bounded expansion scheduling | Compare per-projection, per-layer and bounded groups of projections; include cache outputs in dependencies. Test async evaluation and explicit memory budgets. A removed wait is a win only if memory lifetime stays bounded. |
642
+ | R3 | Axis-0 scatter layout and split-K | Sweep splits 16/32/64/128/256, lane/output ownership, row tiling, vector loads and split-reduction fusion. Preserve the rotated coding axis. Include partial-buffer traffic and final reduction. |
643
+ | R4 | Axis-1 reduce and gate/up fusion | Sweep 64/128/256 threads, rows per group, run unrolling, accumulator count and fused/separate gate-up. Inspect spills and occupancy; tune mixed-k eligibility rather than forcing incompatible fusions. |
644
+ | R5 | Decode primitive | Compare precise/refined reciprocal, existing f32 variant, bf16-rounded reference, compressed/half LUT, hybrid lookup/computation and alternate computed codes. Exact rewrites keep identical decoded weights; changed codes need a new artifact and quality gate. |
645
+ | R6 | Offline repacking without re-quantization | Tile/interleave code words and scales to make down-proj reads coalesced; optional expanded state-window indices trade bytes for ALU. Prove all reconstructed weights identical before model measurements. |
646
+ | R7 | Small-M packed kernel | Reuse each decoded weight across 2/3/4/5/8 input vectors. Measure the M=4/5 boundary, fill spans and MTP verifies. Tune crossover by chip, shape, k and dtype, including temporary memory. |
647
+ | R8 | Fused GDN conv/state/SiLU | Specialize the short convolution, update the state tail in the same dispatch, preserve the oracle's intermediate rounding. Compare vLLM-Metal's fused implementation; no blanket claim that it is L1-equivalent. |
648
+ | R9 | GDN norm, gates and recurrence | Fuse q/k scaling into normalization, combine gate math where legal, unroll Dk loops, test layout/TG_DV, register-resident state and output norm/gate fusion. Validate f32 recurrent state, not just next-token logits. |
649
+ | R10 | Parallel/chunkwise GDN prefill | Compare the sequential scan with chunkwise matrix formulations, scan decompositions and recomputation/workspace tradeoffs. Investigate CUDA CuTe/FLA algorithms; re-derive for Metal. Different reduction order is a Lab candidate unless exactness is proven. |
650
+ | R11 | Affine QMV/QMM and native builds | Real Qwen shapes at every available bit/group size; compare current binary, newer MLX and selected backports, plus llama.cpp Metal tiling. Keep L1 against the matching oracle build. |
651
+ | R12 | Norm/residual/activation/projection fusion | Enumerate producer/consumer pairs throughout the graph, including full-attention output gating and compatible QKV or GDN projections. Measure copy cost, register pressure and changed reductions. Older CPM5 fusion losses do not settle Qwen trellis. |
652
+ | R13 | Attention and KV | Stock SDPA dispatch, tiling, grouped-query reuse, fused KV append/quantize, direct attention over compressed KV, mask specialization, RoPE fusion and paged versus contiguous storage. Measure quality, TTFT and decode by depth. |
653
+ | R14 | Vocabulary head and sampler | Last-position-only projection, exact fused matvec/argmax for eligible greedy requests, GPU logits processors, reduced readbacks and structured-output singleton runs. Head elimination must respect logprobs and sampling contracts. |
654
+ | R15 | Deterministic no-verification replay | Follow section 7.5. Improve proven coverage and span execution economics; report wall time and output identity independently. This is a first-class track ahead of speculative drafter training. |
655
+ | R16 | MLX graph and loop | Use model-owned graph/method bindings for compiled regions, stable buffers/shapes, graph replay, cache donation, allocation removal, bounded device-side chaining and host/GPU overlap. Measure session/lease/readback costs without adding per-op evals. Preserve cancellation and ownership gates. |
656
+ | R17 | Hybrid prefix and recurrent state reuse | Exact prefixes, semantic anchors, page/block storage, compact active-state updates and checkpoint cadence. Test mixed prompt edits and cancellation; no KV-only hit that loses the corresponding recurrent state. |
657
+ | R18 | Scheduler | Solo latency, actual B-wide prefill, continuous batching, chunked-prefill/decode interleaving and shape buckets. Report per-request latency and aggregate throughput; one cannot substitute for the other. |
658
+ | R19 | Weight-quality allocation | Measured latency-aware allocation across MLP, attention, GDN, embedding and head; GPTQ/LDLQ calibration and damping; QTIP/YAQA rounding; group size, k, L, block length, rotations and sensitive-layer exceptions. Optimize quality/bytes/time together. |
659
+ | R20 | MTP economics | Off versus gamma 1/2/3/4 with a compatible head; head quantization, bounded adaptive gamma, verification cost, state replay and peak residency. Native MTP's previous loss is the control. Accept-rate improvements alone fail. |
660
+ | R21 | Other exact speculative sources | Prompt lookup, n-grams, suffix reuse and smaller draft models; grammar-aware proposals. Include target verification and rollback cost. This is separate from proven assert replay. |
661
+ | R22 | Residency and shared memory | Weight loading, mmap/page alignment, wired-budget scopes, allocator cache, copy elimination and snapshot ownership. CPU work shares memory bandwidth with the GPU; overlap is measured, not presumed free. |
662
+ | R23 | Media and task completion | Image/video tower, preprocessing, encoder feature cache and merger, plus tool streaming, checkpoint stalls and reconnects. Finalists must improve the actual agent session, not only synthetic decode. |
663
+ | R24 | Larger departures | Learned/codebook quantization, sparse residual/outlier correction, activation quantization, pruning, layer skipping, low-rank approximations, QAT/distillation and alternative drafters. First estimate kernel support, quality, training memory and maximum possible benefit; only feasible candidates advance to bounded experiments. |
664
+
665
+ For every row first derive its maximum possible end-to-end gain from the
666
+ observed critical path. If a part occupies fraction f and could become s
667
+ times faster, the serial approximation is `1 / (1 - f + f/s)`; account for
668
+ overlap separately. A poor bound can close a candidate for this workload,
669
+ provided its inputs and assumptions are recorded. A previous negative result
670
+ on another chip, format or batch shape cannot close the current cell.
671
+
672
+ ### 7.5 Deterministic replay without verification
673
+
674
+ The intended fast path is to emit a known span, run one state-advancing append,
675
+ and resume prediction at its end. Normal serving performs no token verification
676
+ for an asserted span. Correctness audits are separate runs and are not part of
677
+ that timing. The implementation details and contract now live in
678
+ speculative-decoding section 7.4.
679
+
680
+ Inventory candidate spans by tool schema, template, parser state and actual
681
+ token boundaries. Separate a unique continuation under enforced constraints,
682
+ a deterministic application transform, an exact cached continuation under the
683
+ same state/policy, and a merely frequent continuation. Repeated text or a
684
+ temperature-zero model is not by itself proof that a suffix is known.
685
+
686
+ Screen the existing strict rows first. They currently use a suffix match,
687
+ so test triggers inside quoted tool syntax, code blocks, prose and prior roles.
688
+ Exercise shared tool-name prefixes, multiple calls, optional/extra keys,
689
+ `additionalProperties`, escaped values, stop/EOS within spans, whitespace
690
+ merges and non-ASCII tokenization. Template token containment establishes a
691
+ possible serialization; the 27B output gate establishes observed agreement.
692
+ A universally valid claim needs a rule that enforces the unique continuation.
693
+
694
+ The existing strict weights test can now select an exact artifact using
695
+ `MLX_BUN_TEST_FILL_MODEL`. Run it on the flagship and packed Q3, then expand
696
+ to all retained quants and a frozen adversarial/real-session corpus. Compare
697
+ every emitted token, stop decision, KV offset and subsequent teacher-forced
698
+ logits/state. Require nonzero fills. Keep a held-out set of sessions unused
699
+ while designing the rows. A passing small regression test is not a proof for
700
+ all possible prompts.
701
+
702
+ Then optimize the actual mechanism: remove redundant in-flight vocabulary
703
+ work where pipeline ordering allows it, combine adjacent determined spans,
704
+ cache compiled schema plans by exact tokenizer/template/tools identity, and
705
+ choose append chunking from the packed M curve. Strict fill currently excludes
706
+ batch placement, grammar, quantized KV, media, mounted drafts, logprobs and
707
+ fixed seeds through its eligibility checks. Extend one combination at a time
708
+ after proving state and sampler behavior. A mounted draft must not silently
709
+ disable the arm being called a fill benchmark.
710
+
711
+ Per event record available span length, injected length, independent agreement,
712
+ append time, vocabulary projections avoided, wasted scheduled samples and
713
+ resume cost. Per session record task outcome, TTFT, time to first tool call,
714
+ emitted tokens, prediction steps, total GPU work and wall time. Disable
715
+ `MLX_BUN_FILL_TRACE` for timings: its per-position vocabulary head/readback
716
+ reintroduces work that production assert skips. All-assert acceptance counters
717
+ are not a verification success rate.
718
+
719
+ The optimistic saving at fill fraction f is bounded by the work actually
720
+ removed. Even `1/(1-f)` assumes zero append cost and no other bottleneck.
721
+ Filled positions still traverse the state-update graph. An emitted rate above
722
+ a one-token-per-forward estimate shows amortization; it does not show that
723
+ those positions never passed through model layers.
724
+
725
+ ### 7.6 MLX and Metal opportunities, with outside implementations
726
+
727
+ Start with algorithms and data dependencies. CUDA warp widths, tensor-core
728
+ instructions, shared-memory budgets, graph capture and PCIe transfer models
729
+ do not specify a good Metal implementation. Unified memory removes some
730
+ copies, while CPU/GPU contention and page residency can still dominate.
731
+ MLX can defer evaluation, fuse compiled regions, reuse buffers and overlap
732
+ graph construction with GPU work. Explicit evaluation can also be necessary
733
+ to release large live intermediates. Each opportunity needs an ownership and
734
+ memory-lifetime argument alongside its speed result.
735
+
736
+ Read source at pinned revisions and attach the relevant functions to each
737
+ experiment. The initial source snapshot is recorded in
738
+ `reports/qwen38-rd/upstream/sources.json`; downloaded code stays in reports.
739
+ Sources used for the first candidate set:
740
+
741
+ | source | transferable idea and local experiment |
742
+ |---|---|
743
+ | [vLLM-Metal fused conv](https://github.com/vllm-project/vllm-metal/blob/327d7cb7d19f47f3e32ebb1b561b535365e2b34e/vllm_metal/metal/kernels_v2/gdn_conv1d_silu_decode.metal) | Direct state-tail convolution, SiLU and compact state output in one launch, R8. Its f32 accumulation/activation order must be checked against our bf16 intermediate. |
744
+ | [vLLM-Metal lazy GDN](https://github.com/vllm-project/vllm-metal/blob/327d7cb7d19f47f3e32ebb1b561b535365e2b34e/vllm_metal/attention/impls/gdn_lazy.py) | Lazy custom operations, compact active-request states and shape-specific recurrence dispatch, R9/R16/R17. Their prefill kernel still loops across sequence positions; it is not evidence of a parallel-scan win. |
745
+ | [vLLM-Metal tiled attention](https://github.com/vllm-project/vllm-metal/blob/327d7cb7d19f47f3e32ebb1b561b535365e2b34e/vllm_metal/metal/kernels_v2/pagedattention_tiled.metal) | Paged variable-length attention and grouped-query reuse, R13/R18. M5 NAX work is a separate hardware arm, not an M1/M4 capability. |
746
+ | [vLLM Qwen GDN](https://github.com/vllm-project/vllm/blob/6cbb3c154ef1449d2b3c9131a237f36faa695734/vllm/model_executor/layers/mamba/gdn/qwen_gdn_linear_attn.py) | Fused decode and chunkwise prefill are separate regimes. Inspect gates, normalization and state layout, then derive a Metal implementation, R9/R10. |
747
+ | [vLLM hybrid cache design](https://github.com/vllm-project/vllm/blob/6cbb3c154ef1449d2b3c9131a237f36faa695734/docs/design/hybrid_kv_cache_manager.md) | Cache groups, prefix intersections and recurrent-state constraints, R17. Paging the 16 attention layers alone does not solve the 48 GDN layers. |
748
+ | [vLLM graph execution](https://github.com/vllm-project/vllm/blob/6cbb3c154ef1449d2b3c9131a237f36faa695734/docs/design/cuda_graphs.md) | Distinct decode/prefill capture regimes and shape buckets, R16/R18. MLX compilation is not CUDA Graph replay; measure which host/encode work it actually removes. |
749
+ | [llama.cpp Metal GDN](https://github.com/ggml-org/llama.cpp/blob/427291b5b34cd914a31b3fd3b61a68f6184f4b9f/ggml/src/ggml-metal/kernels/gated_delta_net.metal) | Compile-time dimensions, unrolled register state, transposed layout and optional recent-state snapshots, R9/R17/R20. Head mapping and scaling differ across implementations; preserve Qwen's equations. |
750
+ | [MLX qmv_wide](https://github.com/ml-explore/mlx/pull/3764) | Decode a weight group once and reuse across small M, R7/R11/R20. The affine path is hardware-gated upstream; inspect the binary actually loaded. |
751
+ | [MLX compilation](https://ml-explore.github.io/mlx/build/html/usage/compile.html) | Region fusion and caching, with explicit state and shape-dependent branches. Do not make the M=4/5 dispatch shapeless without proving the selected branch, R16. |
752
+ | [XGrammar MLX bitmask](https://github.com/mlc-ai/xgrammar/blob/b5048784c65f70ca20bc5fb640b06c84583b7a92/python/xgrammar/kernels/apply_token_bitmask_mlx.py) | Compiled byte-to-bitmap lookup versus direct Metal bit extraction. Both avoid the current per-token CPU float-mask expansion. Compare host cost, complete sampling time, padded vocab, dtypes and lifetime; preserve additive-mask numerics, R14/R16. |
753
+ | [QTIP](https://arxiv.org/abs/2406.11235), [YAQA](https://github.com/Cornell-RelaxML/yaqa-quantization) | Hardware-friendly computed/lookup code tradeoffs and improved rounding, R5/R19. CUDA speed results are hypotheses on Metal. |
754
+ | [Gated Delta Networks](https://arxiv.org/abs/2412.06464) | Parallel training/chunk formulations of the gated delta rule, R10. Compare the equations and long-run state drift before a Metal implementation. |
755
+ | [T-MAC](https://github.com/microsoft/T-MAC) | Activation lookup tables for mixed-precision CPU matmul, R5/R22/R24. Its bit-plane representation is not the current trellis code, and CPU work competes for shared bandwidth; test format compatibility and total wall time. |
756
+ | [SGLang jump-forward removal](https://github.com/sgl-project/sglang/pull/4032) | The old scheduler's jump-forward path was removed for maintenance in March 2025. Study its grammar/state/tokenization integration for R15/R18; an old feature description or residual API is not a current runnable baseline. |
757
+
758
+ Continue the source search around each measured bottleneck: FlashAttention
759
+ tiling and online softmax, FlashInfer, FLA chunk algorithms, SGLang prefix reuse
760
+ and structured-output jump-forward, MLX-LM/OptiQ/oMLX scheduling, and low-bit
761
+ lookup methods such as T-MAC. Record a specific paper/function, hardware
762
+ assumptions, local counterpart and falsifiable test before a port. CPU SIMD
763
+ and GPU cooperating on shared memory are also candidates where the dependency
764
+ graph permits it. No GPU-wide synchronization or persistent megakernel is
765
+ assumed safe across threadgroups without a documented Metal mechanism.
766
+
767
+ ### 7.7 Gates, scheduling and completion
768
+
769
+ First establish trustworthy controls. Then capture the graph, run R1–R7 and
770
+ R15 on the packed artifact, and R8–R14/R16 on both packed and affine controls.
771
+ Use R17–R23 for full-serving improvements and interactions. Run R19 throughout
772
+ the kernel work so the allocation objective uses measured latency, not bits
773
+ alone. R24 advances only after a feasible memory/quality/cost screen.
774
+
775
+ Use a warmup followed by at least five paired measurement blocks for an
776
+ initial verdict, alternating or randomizing AB/BA within a balanced schedule.
777
+ One model-owning process at a time on these Macs; restart paired server arms
778
+ sequentially when both do not fit. Control cold-cache and warm-cache trials
779
+ explicitly. Preserve all samples and interruptions. Do not keep retrying until
780
+ a favorable result appears. Recheck residency, swap activity and thermal state
781
+ between cells, and repeat finalists in a separate session on the M4 Pro.
782
+
783
+ Estimate paired log-ratio confidence intervals with sessions/prompts as the
784
+ independent units. A default speed win should exceed 3% and have a 95% lower
785
+ bound above no improvement on its declared workload. Smaller repeatable wins
786
+ may justify simple changes, with their uncertainty reported. Use enough
787
+ requests to estimate tail latency; a handful of runs cannot establish p99.
788
+ Test isolated wins together, since fusion, quant allocation, batching and fill
789
+ often interact. Keep the incumbent if the combined arm regresses.
790
+
791
+ L1/L2 changes pass the existing same-state oracle logit gates at matching B
792
+ and machine. Trellis repacks also prove every reconstructed weight identical.
793
+ Changed reductions/precision/algorithms enter Lab with teacher-forced logits
794
+ and recurrent-state checks over chunk boundaries and long continuations.
795
+ Evaluate actual packed serving, not only the carrier. Quantization quality
796
+ uses frozen KL/ppl screens plus MMLU, templated GSM, raw GSM, code/tool tasks
797
+ and the existing six-task suite. Track per-item failures and immediate EOS.
798
+ Use a held-out set for finalists. Define task noninferiority margins before
799
+ the trial and collect enough items to resolve them; n=50/100 is a screen,
800
+ not evidence that a small quality regression is absent.
801
+
802
+ Every candidate gets one outcome: repeatable win, measured loss, inconclusive
803
+ with the next discriminating experiment, proven inapplicable to this hardware,
804
+ or blocked with the missing resource named. Record hypothesis, baseline and
805
+ candidate revisions, changed parameter, expected limiting resource, artifact,
806
+ workload, correctness/quality evidence, performance distribution, memory,
807
+ decision and the condition that would justify reopening it. Save raw samples,
808
+ traces and commands in reports; record measured runs in the eval DB; promote
809
+ only qualified numbers to [benchmarks.md](../reference/benchmarks.md).
810
+
811
+ The campaign is exhausted for a declared machine/workload when every row has
812
+ such evidence, all exercised graph branches are accounted for, finalists pass
813
+ the combined and held-out gates, and a final source review finds no untested
814
+ applicable candidate with meaningful remaining headroom. Blocked or
815
+ unmeasured rows do not count as exhausted. This is a reproducible stopping
816
+ rule for a finite search, not a claim that no future algorithm can be faster.
817
+
818
+ The scope also includes every owned kernel and native operation used by the
819
+ project's other model paths. Maintain an inventory of dispatch sites, generated
820
+ specializations, dtype/shape/layout eligibility, callers, reference behavior,
821
+ available workloads and measurements. Cover attention, projections, recurrent
822
+ layers, embeddings, normalization, activation, sampling, masks, cache codecs,
823
+ media paths and streamed experts, including graph construction and host work.
824
+ Each inventory row needs an explicit result; a Qwen-only trace cannot close
825
+ an operation used elsewhere. Keep unavailable-model or hardware cells visible.
826
+ Run the final comparison on the M4 Pro. Pin source, runtime/library
827
+ versions, artifacts, request settings and
828
+ cache state so kernel gains are not confused with different test conditions.
829
+
830
+ The final task benchmark uses
831
+ [Luke's published kanban prompt](https://github.com/lukesdevlab/youtube/blob/3288d1918fa6140c10f3b2de2d37f9d717a5ab75/prompts/kanban.txt),
832
+ pinned before execution (SHA-256
833
+ `c40b3c8e0e4d37b316179281aafef187839df7bb0e945f5c1d0f6c5b79fbb521`).
834
+ It requests a local vanilla web app with board/card editing, drag-and-drop,
835
+ archive/restore, combined filters, themes and persistence. The upstream prompt
836
+ asks the builder to verify through code review; independent browser evaluation
837
+ happens after the agent finishes. Preserve the exact prompt in each run.
838
+ The upstream repo supplies model settings but does not establish a pinned
839
+ agent harness for this comparison. Record our harness and any differences
840
+ explicitly; this is not a hardware-matched reproduction of a video score.
841
+
842
+ Before running that final task, freeze one agent/tool interface, system prompt,
843
+ dependencies, context/output/turn/time limits and seed list for every arm.
844
+ Use clean isolated workspaces and identical tool access; save the full request,
845
+ response, tool, usage and timing trace. Run the incumbent and final engine
846
+ configurations on the same artifacts, with same-artifact MLX-LM controls where
847
+ supported. Test different quants as separate quality/performance arms. Keep
848
+ MTP, replay and cache policy explicit. Do not repair generated code during
849
+ scoring or use final-task output to tune the candidate being evaluated.
850
+
851
+ | Final task measure | Evidence and interpretation |
852
+ |---|---|
853
+ | Completion | All required behavior works without manual edits; report partial completion and timeouts. |
854
+ | Functional behavior | Exercise edits, card/column movement, safe deletion, restoration, combined filters and reload persistence in a fresh browser profile. |
855
+ | Usability | Record keyboard behavior, empty states, feedback and screenshots in both themes. |
856
+ | Complete task time | Measure from first agent request to its completion, plus evaluation time separately. |
857
+ | Engine contribution | Per-turn queue/TTFT/decode time, prompt/generated/cached tokens, tool round count, retries, errors and compactions. |
858
+ | Resource use | Peak active/RSS/wired memory, swap activity, cache bytes and actual serving lane. |
859
+ | Repeatability | All prespecified runs and seeds, including failures; compare success rate and time conditional on completion. |
860
+
861
+ Source snapshots and the manifest are in
862
+ `reports/qwen38-rd/lukes-kanban/`. The first attempted task is preserved in
863
+ `reports/qwen38-rd/kanban-final/optimized-mtp-invalid-32k-sleep/` and excluded
864
+ from completion-time claims. Its Pi profile incorrectly declared 32,768 tokens,
865
+ causing premature compaction, and macOS sleep interrupted the run. The artifact
866
+ declares 262,144 positions. The corrected profile derives the effective window
867
+ from that metadata and the server's admission limit, recording both separately.
868
+ Use Pi's standard compaction reserve and recent-history settings, hold
869
+ `caffeinate -is`, and record real wall time plus active monotonic time. The
870
+ original profile, traces and partial app remain available.
871
+
872
+ The corrected thinking-off candidate completed generation without compaction,
873
+ but failed static app acceptance: `main.js` redeclared a `let` variable and the
874
+ requested README was absent. No manual edits or repair prompts were supplied.
875
+ The original-source task exhausted two automatic retries during a long tool
876
+ response. That run is excluded from task-time comparison because the recording
877
+ proxy inherited Bun's socket idle timeout. An independent six-minute silent
878
+ stream reproduces the default timeout and completes with `timeout: false`.
879
+ Pi's own HTTP idle setting is now explicit. The runner also reads Pi's terminal
880
+ events, because an exhausted retry can still leave a zero process exit code.
881
+
882
+ Josh corrected the benchmark configuration: the task must use a named profile
883
+ from Luke's `model-configs.ini`, including its sampling, context, thinking and
884
+ effort settings. The agent-selected greedy configurations are invalid for this
885
+ benchmark, including the later thinking-enabled attempt, which was stopped.
886
+ Do not reuse their times as Luke benchmark results. The pinned prompt itself
887
+ matches upstream. The profile audit resolves inherited defaults, records source
888
+ hashes and rejects missing effort or changed sampling values. Context and effort
889
+ differ across Luke's coding profiles. The selected section is
890
+ `qwen3.8-27b-q3_k_xl-coding-128k`: 131072 context, xhigh thinking, temperature
891
+ 0.6, top-p 0.95, top-k 20, min-p 0, presence penalty 0 and inherited seed 42.
892
+ The task uses that exact prompt and request recipe. Its first attempt was
893
+ stopped after a serving bug discarded the preceding thinking on tool turns.
894
+
895
+ The MTP-prefix integration, now included in the PR #47 feature branch, permits Qwen uniform KV4 with start=0
896
+ behind `MLX_BUN_QWEN_SPEC_KV4`. Prefill converts attention caches through
897
+ `maybeQuantizeKv`; rollback binds after conversion, and prefix identity includes
898
+ KV bits, group size and conversion policy. Recurrent state remains full precision.
899
+ A native sampled test restores all sixteen quantized target layers plus draft
900
+ state with identical continuation after forced rejected drafts. The HTTP check
901
+ also preserves repeated output and acceptance decisions, with active speculation
902
+ and cache reuse. The initial native coverage check failed only because its
903
+ repetitive prompt accepted every draft; the forced-rejection check supplies that
904
+ missing coverage. Both records remain in `reports/qwen38-rd/`.
905
+
906
+ This is an explicit MLX adaptation. The target remains Josh's required packed
907
+ 12 GB Trellis artifact. MLX affine KV4 group64 differs from GGUF q4_0; the single
908
+ MTP-layer cache stays bf16. The corrected-history run uses the profile’s 256-token batch
909
+ size for MLX prefill, bounding long-context attention workspace.
910
+ `MLX_BUN_RD_CONTEXT_LIMIT` narrows the isolated server's physical admission
911
+ ceiling to exactly 131072, never enlarges it. Pi uses the same context and
912
+ xhigh effort. Responses run until EOS or remaining context, with no invented
913
+ 16K cap. Task timing includes automatic tool use and retries; app scoring
914
+ follows after inference exits. The completed retry is recorded later in this section.
915
+ Raw evidence and invalid runs remain in `reports/qwen38-rd/kanban-final/`.
916
+
917
+ The paired cache currently captures prompt checkpoints only. Extending it to
918
+ verified generated boundaries is still open: preserve target, draft and pending
919
+ hidden alignment, and require an exact prefix of the next rendered conversation.
920
+ Tool-argument serialization can change tokenization, so a completed-response
921
+ snapshot alone cannot replace the earlier stable-prefix checkpoint. The uniform
922
+ KV4 prefill path also retains native unfused quantized attention, which materializes
923
+ query-by-context scores. Long tool-turn prefill needs its own memory and timing
924
+ acceptance; decode memory alone does not establish that result. Measured task sources stay frozen while these costs are measured.
925
+
926
+ The stopped profile attempt also reproduced a protocol bug. Pi returns prior
927
+ assistant thinking as `reasoning`; Qwen’s template reads `reasoning_content`.
928
+ Despite `preserve_thinking: true`, normalization previously dropped that history
929
+ from the rendered prompt. The fix supplies the canonical alias without mutating
930
+ the input or replacing an explicit canonical string. Unit tests cover tool calls,
931
+ rendering and precedence. The recorded request now retains its complete reasoning.
932
+ The active runner independently renders each prompt and checks its token count
933
+ against engine usage. This failure remains separate from the earlier attempts
934
+ that used incorrect sampling settings.
935
+
936
+ The subsequent long-history HTTP gate passes with the corrected normalizer,
937
+ 256-token prefill, target KV4 and MTP. Cold and restored requests preserve
938
+ output and draft acceptance, including naturally rejected proposals. The
939
+ corrected-history task runs with source hashes frozen and all original settings
940
+ retained. Evidence: `reports/qwen38-rd/luke-history-kv4-preflight.json` and
941
+ `reports/qwen38-rd/kanban-final/luke-q3-128k-xhigh-history-fixed/`.
942
+
943
+ That task ended with only three app files. All prompt counts and MTP/cache
944
+ checks passed, but a valid nested edit array failed in tool parsing. Qwen
945
+ parameters now follow the pinned mlx-lm parser: raw entity text, with one
946
+ framing newline removed at each end. Outer Qwen markup is selected before
947
+ JSON repair can misread a parameter as a tool envelope. Legacy attribute XML
948
+ keeps its existing decoding policy. The actual saved response now produces
949
+ one intact edit call through the real tokenizer and streaming parser.
950
+ Regression tests, strict-fill checks, both workspace typechecks and hygiene
951
+ pass. The raw failed result and untouched app remain preserved; its numbers
952
+ are in benchmarks.md. The fresh run with both fixes is preserved in
953
+ `reports/qwen38-rd/kanban-final/luke-q3-128k-xhigh-tool-values-fixed/`.
954
+
955
+ That run ended in a Metal out-of-memory error during the next long-history
956
+ turn, before Pi finished. Completed requests kept the full rendered history
957
+ and used MTP with cached prefixes. Static checks find no README. The separate
958
+ browser smoke confirms basic creation but finds a blocking card-editor
959
+ ReferenceError in the incomplete app. Its source is unchanged; no repair
960
+ prompts were supplied. Timings, counts and memory measurements live in
961
+ [benchmarks.md](../reference/benchmarks.md#fresh-pi-kanban-diagnostic-m4-pro-2026-09-07).
962
+
963
+ Do not promote the isolated KV4/MTP/prefix composition or claim a successful
964
+ task-time gain. Josh's known workload is roughly 100,000 generated tokens,
965
+ including thinking, plus the initial prompt and subsequent tool history.
966
+ Fixing only the observed failure boundary is insufficient. Start with a
967
+ 110,000-token accumulated-context capacity screen, then check sustained
968
+ generation, tool turns and cache reuse beyond the expected task size, within
969
+ the unchanged published context settings. A short continuation at a large
970
+ synthetic context is a memory screen, not proof of full task completion.
971
+ The unchanged initial capacity screen finished target prefill but failed
972
+ inside the first MTP draft round. Allocation traces and source hashes are
973
+ preserved; numbers live in benchmarks.md. Draft prefill built a deferred KV
974
+ graph across every chunk, and its pending hidden row was a view into the
975
+ complete prompt buffer. The main source and isolated candidate now evaluate only draft KV
976
+ at each existing chunk boundary and materialize the retained final row.
977
+ Unused prefill attention/MLP outputs stay unevaluated. A focused allocation
978
+ test fails before this change and passes afterwards. A separate sampling
979
+ failure test exposed unowned in-flight output and logits; scoped disposal
980
+ now releases them on errors as well. The small full-model comparison retains
981
+ exact output tokens and MTP acceptance traces, including cached replay.
982
+ The final-source native capacity screen completes repeated continuations at
983
+ the larger context, preserves exact cached replay and recovers after an
984
+ injected output-sink failure without additional retained request memory.
985
+ Main-source ownership tests, a real-target short MTP identity gate and both
986
+ workspace typechecks pass. Saved-history HTTP acceptance also passes, including
987
+ the failed request, conversation growth and exact replay at the larger context.
988
+ The guarded fresh Pi retry also failed with Metal out of memory, this time
989
+ during sustained decode rather than the first draft after prefill. Its source
990
+ and profile stayed fixed. The complete first response and its MTP acceptance
991
+ trace match the preceding task; later tool results reflect their actual runs.
992
+ The untouched app supplies its README but fails both the card-editor and
993
+ archive-panel checks. Measurement and quality audits are preserved beside
994
+ the raw result in `kanban-final/luke-q3-128k-xhigh-mtp-memory-fixed/`.
995
+ This failure leaves sustained-generation acceptance open. The passing short
996
+ capacity checks do not establish reliability over the full workload.
997
+
998
+ The sustained allocation trace identifies a separate lifetime problem in
999
+ `mlx/ops.ts`: the range cache retained every distinct large `arange` for the
1000
+ process lifetime. Quantized causal attention requests a new context-length
1001
+ range on each verification round above the cache's minimum length. Disposing
1002
+ the returned mask view did not release the cache's owner. The range cache now
1003
+ limits retained array data to 8 MiB, evicts least recently used owners with
1004
+ explicit disposal, and leaves oversized ranges owned only by their callers.
1005
+ Repeated vocabulary and attention-layer ranges still share storage; outstanding
1006
+ lazy views retain their native references after eviction. The focused allocation
1007
+ regression fails before this change and passes afterwards. The full-model
1008
+ sustained repeat preserves every output token and MTP acceptance decision,
1009
+ with fixed sources and bounded retained allocation after model disposal.
1010
+ Numbers and the single-pair timing limitation are in benchmarks.md.
1011
+
1012
+ After fresh-task acceptance, screen a reusable integer position-range prefix
1013
+ and the native integer `arange` path on Bun 1.4 against this bounded-cache
1014
+ baseline. The current minimum cache length still rebuilds smaller attention
1015
+ ranges across layers. Keep exact range/mask values, outstanding-view ownership
1016
+ and the memory bound as gates; measure complete prefill and verification rounds
1017
+ before retaining an allocation or dispatch optimization.
1018
+
1019
+ The pinned MLX 0.32.2 source also gives a specific native scheduling experiment
1020
+ for the three-query KV4 verification window. Qwen's 24 query heads share four
1021
+ KV heads (GQA6), with D256. `quantizedSdpaUnfused` currently presents the heads
1022
+ as separate broadcast batches. In `mlx/backend/metal/quantized.cpp`, the
1023
+ M4-eligible affine key multiplication selects `qmv_wide`: three vectors per
1024
+ threadgroup, eight reduction lanes, and a separate batch for each query head.
1025
+ Its code already reuses weights across the three query positions.
1026
+
1027
+ Screen pairing two query heads in the key multiplication only. Reshaping the
1028
+ query from `[B,KV,6,3,D]` to `[B,KV,3,6,D]` keeps this dispatch below its matrix
1029
+ threshold and keeps the native vector tile at three. The grid changes from
1030
+ `(1,ceil(N/8),24)` to `(2,ceil(N/8),12)` for B=1, offering a way to change K
1031
+ reuse and scheduling through native MLX operations. Restore the original score
1032
+ shape before masking and softmax. This is an unmeasured hypothesis: actual
1033
+ shader dispatch, layout/materialization and exact output must be checked;
1034
+ source-level broadcast does not establish actual DRAM traffic.
1035
+ If the paired-head screen passes, also screen groups of three heads. Its nine
1036
+ query rows remain below the matrix threshold, but MLX selects five vectors per
1037
+ threadgroup rather than three. That changes the compiled kernel specialization;
1038
+ do not infer numerical identity from the common source body. Measure both real
1039
+ strided queries and contiguous queries: `ensure_row_contiguous_matrix` may add
1040
+ a copy before multiplication, and the complete attention timing must include it.
1041
+ The recorded CLI selects uniform `--kv-quant 4`, which configures the unfused
1042
+ MLX-LM composition through `applyDecodeRoute`; this runtime option is not an
1043
+ inherited environment variable. Preserve that selection in the control. A
1044
+ smaller graph experiment can reuse one materialized causal mask across Qwen's
1045
+ full-attention layers: `forwardLayers` already shares a mask object, but its
1046
+ causal string currently rebuilds the boolean array in each unfused attention
1047
+ call. Keep the bf16 and OptiQ dispatch policies intact and measure the retained
1048
+ mask's lifetime as well as complete-forward timing before retaining that change.
1049
+
1050
+ Do not apply that fold indiscriminately to the value multiplication. Its native
1051
+ matrix threshold is four query rows, so the same reshape would change the
1052
+ algorithm. At long context it uses `qvm_split_k`, with 32 partitions beyond
1053
+ 8192 reduction elements and an explicit reduction of the intermediate results.
1054
+ Preserve that partition and reduction contract in any custom scheduling arm.
1055
+ The relevant implementation is `mlx/backend/metal/kernels/quantized.h` in the
1056
+ pinned source. Run these experiments as separate arms against the frozen successful task's
1057
+ source; require operation, complete-attention, full-model and serving gates.
1058
+
1059
+ The fresh Pi retry with the bounded range cache completes under the same
1060
+ published profile, prompt and settings, with source hashes frozen. Its untouched
1061
+ app passes the required functional browser checks, including card editing,
1062
+ combined filters, archive/restore, column controls, native card/header drags
1063
+ and persistence. The README and modular plain-script entry are present. The
1064
+ passing sustained replay preceded launch; all prior controls and failed tasks
1065
+ remain preserved. No app code was edited and no repair prompts were supplied.
1066
+ Browser checks ran after inference exited. The original intercepted-drag
1067
+ probes and an incomplete mouse-drop probe remain beside the successful native
1068
+ interaction checks, which deliver dragover before releasing the button.
1069
+ Measured completion time, rates and memory are in benchmarks.md.
1070
+
1071
+ The completed run includes Pi context compaction. Its summary request and
1072
+ subsequent work remain inside task elapsed time. Pi serializes the older conversation
1073
+ into a new summary prompt, so those tokens do not share the original chat's
1074
+ exact prefix. Do not substitute the old KV state merely because the transcript
1075
+ describes the same history. The JSON stream uses `compaction_start`; the frozen
1076
+ outcome helper counts only `auto_compaction_start`. Derived lifecycle
1077
+ counts now include both event names; the raw outcome and its saved helper remain
1078
+ unchanged for audit. The shared helper was corrected only after the run ended.
1079
+ Assess whether Pi's compaction reserve can avoid an
1080
+ unnecessary summary while keeping the published context limit and sampling
1081
+ settings. Check which settings the upstream protocol actually pins before
1082
+ changing a client policy, and report that arm explicitly. Include context
1083
+ admission, truncated responses and subsequent task quality in its acceptance.
1084
+ The existing admission limit is not proof that the composed execution fits.
1085
+ Generated
1086
+ history checkpoints remain a separate opportunity to remove repeated prefill;
1087
+ their target, draft and pending-token state must align with the next rendered
1088
+ conversation prefix. For append-only caches with an unchanged codec, also
1089
+ evaluate deferring the attention-KV view capture until request cleanup while
1090
+ capturing the recurrent state and pending hidden row at the checkpoint. Older
1091
+ KV rows remain available in the live cache; retaining a second native owner
1092
+ throughout decoding can force an otherwise avoidable copy. This requires an
1093
+ explicit lifetime contract, prefix availability checks, correct cleanup on
1094
+ cancellation/errors, and accounting for shared backing storage. Sliding-window
1095
+ eviction or requantization of older rows must disqualify that reuse. Generated
1096
+ checkpoints must match actual next-request tokens; tool serialization is not
1097
+ assumed identical. Keep a valid fallback checkpoint within the memory budget.
1098
+ Collect matched successful original/final task-time comparisons. The completed
1099
+ run establishes a usable result on this source, not an optimization percentage.
1100
+ Capacity acceptance does not establish the fastest completion method. Measure
1101
+ draft acceptance and verify-window attention cost at the context depths reached
1102
+ late in the actual task. Compare complete request times when tuning the draft
1103
+ schedule within the published profile; short-context MTP throughput cannot
1104
+ stand in for those measurements.
1105
+ The pinned quantized value-product dispatch makes draft depth three a concrete
1106
+ next screen: its four-position target window reaches the native matrix-kernel
1107
+ threshold, whereas the current three-position window uses split-K vector
1108
+ multiplication at long context. Compare depths one, two and three and an
1109
+ ordinary continuation at matched context, keeping the sampling recipe fixed.
1110
+ This is a source-derived scheduling hypothesis, not a measured speed claim;
1111
+ each window's native arithmetic, rollback, cache reuse and completed response
1112
+ remain correctness and acceptance gates.
1113
+
1114
+ ### 7.8 Execution progress and next measurements
1115
+
1116
+ Use the integrated memory safeguards and relevant numerical controls in
1117
+ section 7.1, then measure the expensive computation. The existing benchmark
1118
+ accepts an exact local artifact and can print its
1119
+ commands without loading a model. The first prepared jobs are the affine
1120
+ flagship on mlx-bun serial versus mlx-lm, followed by packed Q3 on mlx-bun
1121
+ serial. Start at 4k context; widen only after the measured memory row.
1122
+ The commands and preparation mode are documented in
1123
+ [benchmarks.md](../reference/benchmarks.md#running-the-benchmark).
1124
+
1125
+ The harness now keeps all five decode samples, uses reproducible nonces with
1126
+ `--workload-seed`, pins thinking mode across arms, and saves request bodies,
1127
+ counts, finish reasons, errors and wall times in a JSON companion. It rejects
1128
+ missing token usage instead of counting SSE chunks as tokens. Each block
1129
+ still needs an explicit AB/BA order and a distinct output path; one harness
1130
+ pass is a screening block, not the full paired-session confidence interval.
1131
+ Identical decoded text and prompt counts remain a smoke check; engine logit
1132
+ and token-ID gates provide the stronger correctness evidence.
1133
+
1134
+ The matched-prefill MTP control exposed a separate ordinary-generation
1135
+ latency cost: the serial loop constructs the next decode step before yielding
1136
+ token zero. A runtime-only source transform yields the first sampled token
1137
+ before that construction, retaining the later pipeline and excluding fill,
1138
+ grammar and resumed generation. Its initial packed-model pair preserves every
1139
+ token ID, live cache state, cache key, usage count and finish reason at raw
1140
+ prompt lengths 6/128/512. Native first-token latency improves while complete
1141
+ generation time is approximately flat. Six lifecycle tests, the 26 existing
1142
+ fill-loop tests and 15 binding tests pass with the prototype. One binding
1143
+ cancellation expectation needs the new event order: token zero may arrive
1144
+ before cancellation triggered inside the subsequent forward; no token arrives
1145
+ after cancellation. Consumer return at that first yield leaves a correctly
1146
+ described prompt-only cache. Those screens changed only the runtime-loaded module.
1147
+
1148
+ The first serial HTTP pair preserves all seven warm/measured responses but
1149
+ does not reproduce the native TTFT improvement. Client-visible output can lag
1150
+ token zero through detokenizer buffering. A separate sink observer confirms
1151
+ that these raw prompts first generate bare-space token 220, which emits no
1152
+ event, followed by token 17 (`2`), which emits content and yields for network
1153
+ progress. Both arms preserve that sequence; earlier delivery of the hidden
1154
+ space cannot improve client TTFT. Keep this negative result and test chat
1155
+ fixtures before attributing a serving win or integrating the prototype.
1156
+ Both screens keep sources fixed and exit cleanly. Evidence:
1157
+ `first-yield-native-screen{,-review}.json`, `first-yield-http-screen.json`,
1158
+ `first-yield-http-observe.json` and its per-server `*.sink.json` records,
1159
+ `first-yield-smoke-candidate-v2.txt`, `first-yield-existing-loop-tests.txt` and
1160
+ `first-yield-binding-order-tests.txt` in the campaign report directory.
1161
+
1162
+ The subsequent three-fixture chat HTTP screen preserves all seven paired
1163
+ responses and improves first visible output on each measured fixture, with
1164
+ approximately flat complete-request time. Evidence:
1165
+ `first-yield-chat-http-screen{,-review}.json`. A simplified version captures
1166
+ the current sample index before yielding and increments the normal generated
1167
+ count immediately, avoiding a second stats counter. Its control passes eight
1168
+ tests and the candidate passes 49 lifecycle, binding and fill-loop tests,
1169
+ including two- and three-token budgets. The first budget test expected an
1170
+ explicit native `length` reason, but the incumbent leaves budget completion
1171
+ implicit; the corrected assertion preserves that contract. Evidence:
1172
+ `first-yield-v2-{control-tests,tests,tests-corrected}.txt`. The simplified
1173
+ prototype then completes six fresh-process native pairs. All 36 warm/measured
1174
+ token, live-state, cache-key and usage comparisons agree; every measured pair
1175
+ improves first-token latency at all three prompt lengths. Complete generation
1176
+ time is approximately flat. All 12 children exit cleanly with fixed sources
1177
+ and the same remaining active allocation after explicit cleanup. Evidence:
1178
+ `first-yield-native-v2-repeat{,-review}.json`. Six chat server pairs then
1179
+ complete all 84 requests with 42 exact response/count/finish comparisons.
1180
+ Every measured pair improves first visible output, with approximately flat
1181
+ complete-request time. The sampled native audit also preserves token IDs,
1182
+ requested log probabilities and live cache state across two seeds and two
1183
+ prompt lengths, with penalties enabled. Both runs keep sources fixed and
1184
+ exit cleanly. Evidence: `first-yield-chat-http-v2-repeat{,-review}.json` and
1185
+ `first-yield-sampled-native.json`. Other artifacts and cached/pressure
1186
+ acceptance remain, including first-token consumer return and follow-up reuse.
1187
+
1188
+ The serial change is now integrated behind `MLX_BUN_EARLY_FIRST_TOKEN=1`,
1189
+ default off. Its scheduling decision comes from the binding's captured
1190
+ runtime; request and execution interfaces are unchanged. Eight permanent
1191
+ binding tests cover both settings, captured-policy isolation, short budgets,
1192
+ early return, cancellation and initial EOS. The focused tests and enabled-fill
1193
+ regression pass, as do all three typechecks, hygiene and the complete
1194
+ model-free suite: 1,831 pass, 10 skip, zero failures. The first cancellation
1195
+ test incorrectly expected final stats after an exception; the corrected test
1196
+ preserves the existing null-stats contract for aborted runs. Orderly consumer
1197
+ return still reports the emitted token and exact cache key. Real-model and
1198
+ HTTP flag comparisons follow the prototype measurements before this thread
1199
+ can close. Evidence: `first-yield-production-unit{,-v2}.txt`,
1200
+ `first-yield-production-fill-enabled.txt`, `first-yield-production-typecheck.txt`,
1201
+ `first-yield-production-hygiene.txt` and `first-yield-production-model-free.txt`.
1202
+ The integrated packed-model native pair preserves all six warm/measured
1203
+ token/state/key/usage comparisons. Its serial HTTP pair completes 14 responses
1204
+ with all seven paired text/count/finish checks exact. Both reproduce earlier
1205
+ first-token delivery and keep sources fixed with clean child exits. A slow
1206
+ HTTP warmup is retained; these integration screens do not replace the six
1207
+ balanced prototype pairs for timing evidence. Evidence:
1208
+ `first-yield-production-native-r6{,-review}.json` and
1209
+ `first-yield-production-http-r6{,-review}.json`. Closed source-transform and
1210
+ duplicate test helpers are removed; permanent tests and raw reports remain.
1211
+ The first integrated RTN4 native pair also preserves all six token/state/key
1212
+ comparisons. Its apparent large complete-time difference is not accepted as
1213
+ a speed gain: step intervals change substantially within the control process,
1214
+ system swap grows and final preflight records substantial Chrome CPU use.
1215
+ Keep this correctness result and repeat timing before attribution. Evidence:
1216
+ `first-yield-production-native-rtn4{,-review}.json` and per-token arrival times
1217
+ in the same report. No unrelated application was stopped.
1218
+
1219
+ The continuous scheduler has its own first-output boundary: an empty group
1220
+ finishes preparation and emits token zero, then advances decode before its
1221
+ event-loop yield. A separate prototype adds a yield only when preparation
1222
+ leaves exactly one active row and no queued arrivals. It preserves grouped
1223
+ short admissions and stops immediately if the group closes during that await.
1224
+ Nine scheduling tests pass for each control/candidate arm; an actual
1225
+ continuous HTTP screen must verify wire placement and client arrival time.
1226
+ Evidence: `first-prepare-scheduler-{control,candidate}.txt` and the frozen
1227
+ `first-prepare-http-screen-plan.json` in the campaign report directory.
1228
+
1229
+ Six subsequent AB/BA blocks complete on the M4 Pro with 12 clean server exits,
1230
+ 84 responses and 42 exact paired responses, including counts, finish reasons
1231
+ and cache usage. The actual continuous lane and submitted-row increment are
1232
+ checked for every request. Median paired TTFT changes are -7.66% for code,
1233
+ -7.90% for explanation and -5.63% for JSON, about 74–77 ms earlier. Complete
1234
+ request time changes by +0.15%, +0.04% and +0.08%, respectively. One code pair
1235
+ has 2.20% worse TTFT and remains in the report. The machine begins with Chrome
1236
+ CPU activity and existing swap, so these are diagnostic measurements. Chrome
1237
+ is unrelated background load; a Bun HTTP client sends requests directly to
1238
+ the server without the chat UI. Source hashes remain fixed. Evidence is
1239
+ `first-prepare-http-repeat{,-review}.json`; scheduler lifecycle and broader
1240
+ request gates remain before integration.
1241
+
1242
+ The continuous option is now integrated under `MLX_BUN_EARLY_FIRST_TOKEN`,
1243
+ default off. The MLX backend reads its captured runtime and passes a boolean
1244
+ to the generic scheduler. No request or execution-contract field is added.
1245
+ After the early yield, the scheduler restarts its policy loop so new arrivals,
1246
+ cancelled queued work, admission holds and shutdown are observed before the
1247
+ next step. Eight added unit cases cover those transitions, short-admission
1248
+ grouping, an existing active row and cleanup on a failed yield. All 1,839
1249
+ model-free tests, the three typechecks and hygiene pass. Integrated real HTTP,
1250
+ cache, pressure and quiet gates remain. The integrated native option also
1251
+ passes four sampled cases per artifact on packed Q3 and RTN4, preserving all
1252
+ 32 token IDs, requested log probabilities, cache keys, live KV/recurrent state
1253
+ and usage. Each arm returns to the same measured native allocation baseline
1254
+ after disposal. These are correctness checks, not repeated timing claims.
1255
+ Evidence is `first-prepare-production-{unit,model-free,typecheck,hygiene}.txt`
1256
+ and `first-yield-production-sampled-{r6,rtn4}.json`.
1257
+
1258
+ The first integrated continuous HTTP attempt is retained as a setup failure.
1259
+ Its driver set the new option after MLX imports had captured the runtime, so
1260
+ the candidate's execution counter remained zero and rejected the run. The
1261
+ corrected driver sets the flag in the child environment before imports. Both
1262
+ arms then execute the same instrumented production source, with seven early
1263
+ yields in the candidate and zero in the control. All seven paired responses
1264
+ and usage/finish checks pass, with fixed source and clean exits. TTFT improves
1265
+ by 68–90 ms across the three measured fixtures; this one-block integration
1266
+ check does not replace the six prototype timing pairs. Evidence is
1267
+ `first-prepare-production-http-r6-v2{,-review}.json`; the original unsuffixed
1268
+ report preserves the failed path-coverage check.
1269
+
1270
+ Nine packed-Q3 native cache-lifecycle pairs also pass. At prompt lengths
1271
+ 6/128/512, each arm either returns after one token, returns after two, or
1272
+ aborts after one, then reuses its own borrowed cache for a 16-token follow-up.
1273
+ An early first-token return/abort covers the prompt alone; the incumbent has
1274
+ already fed token zero. Clean-return cache keys reflect those exact positions,
1275
+ and an aborted generation retains the existing null-stats contract. A
1276
+ one-token follow-up suffix with ordinary tail splitting gives matched M=1
1277
+ forwards for any missing emitted token. All subsequent tokens, requested log
1278
+ probabilities, final live cache states and cache keys match. Both processes
1279
+ return to 16,390 native active bytes after disposal, without forced GC, and
1280
+ the source stays fixed. This proves the covered native reuse transitions;
1281
+ HTTP cache/SSD pressure and broader suffix shapes remain. Evidence is
1282
+ `first-yield-production-cache-r6.json`. The same nine pairs also pass on RTN4,
1283
+ including every follow-up token, requested log probability, cache key and live
1284
+ state. Both RTN4 arms return to six native active bytes after disposal. Its
1285
+ separate evidence is `first-yield-production-cache-rtn4.json`.
1286
+
1287
+ The broader native suffix screen completes 110 follow-ups across both Qwen
1288
+ quants at suffix lengths 1/2/3/4/5/8/31/127/511/512/513. It does not pass
1289
+ universal identity. After returning at token one, the early arm's prompt-only
1290
+ cache makes the next prefill one token longer. Seven packed and six RTN4
1291
+ cases change log probabilities or live state; two packed cases and one RTN4
1292
+ case also change emitted IDs. Every two-token-return case remains exact.
1293
+ Feeding the missing emitted token separately at M=1 restores exact stopped
1294
+ state and all 22 aligned follow-ups, including requested log probabilities
1295
+ and cache keys. Both arms return to their original active-allocation baselines.
1296
+ This identifies a prefill-shape effect, not a seed mismatch or a corrupted
1297
+ snapshot. Keep the option experimental; reconciling the first-token cache
1298
+ boundary needs an implementation and performance gate before default
1299
+ promotion. Evidence is `first-yield-suffix-qwen{,-review}.json`. The preceding
1300
+ Llama smoke also records a natural 512-token suffix state/logprob difference.
1301
+
1302
+ The integrated option also passes the saved seven-request agent-boundary/SSD
1303
+ gate in serial and actual continuous serving on the M4 Pro 24 GB. The first
1304
+ six one-token budgets retain their original path; each lane's counter proves
1305
+ the new option runs once on the final 512-token request. All 14 paired choices
1306
+ and complete usage records match. The longest prompt has 14,465 tokens and
1307
+ reuses the same 12,953-token prefix in every arm. All four final flushes report
1308
+ 14 durable entries, no pending/missing/failed snapshots, and a longest durable
1309
+ prefix of 14,976 tokens. Sources stay fixed and all servers exit cleanly.
1310
+ These non-streaming responses establish the covered memory/cache lifecycle,
1311
+ not a TTFT result or an agent task success. Broader suffix shapes remain.
1312
+ Evidence is
1313
+ `first-token-production-long-{serial,continuous}{,-review}.json`.
1314
+
1315
+ Actual streaming HTTP cancellation and arrival checks now pass 120 requests
1316
+ across eight Qwen servers, covering packed Q3 and RTN4, serial and continuous
1317
+ serving, and both option settings. Each server aborts twice at headers and
1318
+ twice at first output, then completes an independent recovery request after
1319
+ each abort. The server observes all 32 cancellations and settles before
1320
+ consuming the 512-token budget. Every recovery response, usage record and
1321
+ finish reason matches its reference. Final active MLX allocation equals the
1322
+ loaded-model baseline exactly, with no cache entries or active/pending rows.
1323
+ One-token budgets also remain exact. Both overlapping-arrival fixtures
1324
+ observe two active rows in continuous serving, with actual admission counts;
1325
+ serial serving remains serial. All sources stay fixed and servers exit
1326
+ cleanly. A preceding Llama smoke adds 60 requests and 16 cancellations.
1327
+ These instrumented checks establish lifecycle behavior, not speed. Concurrent
1328
+ trajectories are not compared across differing admission timing and batch
1329
+ shapes. Evidence is `first-token-lifecycle-{llama,qwen}{,-review}.json`.
1330
+
1331
+ The first actual continuous HTTP pair then completes all 14 requests with
1332
+ seven exact response/count/finish comparisons and verified batched placement.
1333
+ First visible output improves on all three measured chat fixtures; complete
1334
+ time varies slightly. Both servers exit cleanly with fixed sources. This
1335
+ remains a prototype pending balanced repeats and broader scheduling gates.
1336
+ Evidence: `first-prepare-http-screen{,-review}.json`.
1337
+
1338
+ The first performance work after the pull uses the packed artifact's actual
1339
+ k2/k3/k4 matrices. The M=1/2/3/4/5/8 screen identifies the gate/up crossover
1340
+ and the down-projection bit-width asymmetry. Shared-M reduce and fused gate/up
1341
+ kernels are retained as experimental variant 7 after exact matrix/MLP checks
1342
+ and six balanced diagnostic A/B blocks. Variant 8 adds a balanced and aligned
1343
+ 3-bit down kernel; it improves the observed M=1/2/4 full-model forwards while
1344
+ preserving logits, live state and subsequent-token checks. A device LUT for the existing f32
1345
+ code values loses on this M4 and is recorded as a negative result. Kernel
1346
+ implementation, commands and evidence live in turboquant.md's packed-kernel section.
1347
+
1348
+ The full packed 27B passes logits, live recurrent/KV state and subsequent-token
1349
+ identity at M=1..5. Six paired native-forward blocks also retain the gain at
1350
+ M=2/4, but they use a short synthetic prefix and project every output position.
1351
+ They are not HTTP decode, verified MTP or strict-fill throughput measurements.
1352
+ The existing exact-artifact graph/session/cache gate passes on the packed
1353
+ model as well. Variant 6 remains the default.
1354
+
1355
+ The packed 27B strict-fill regression passes on variants 6 and 7: nonzero
1356
+ assert injection, no verification events and exactly matching emitted tokens.
1357
+ This is one tool-call fixture, not a held-out determinism or timing result.
1358
+ The last-position-only native append sweep covers M=1/2/3/4/5/8/9/16 with
1359
+ six paired blocks, preserving candidate/current logits and live state in every
1360
+ cell. It retains the small-M gain and confirms the M=4/5 whole-model cost
1361
+ discontinuity. Raw evidence: `reports/qwen38-rd/shared-m-append-lengths.json`.
1362
+
1363
+ Variant 10 now shares scatter decode across small M as well. It passes the
1364
+ same exact full-model gates and improves M=2..4 against variant 8 in six
1365
+ paired native blocks. Variant 9 separately moves expanded-projection
1366
+ evaluation to the existing layer boundary. Its observed outputs agree, but
1367
+ peak memory rises. Extending the packed crossover to M=8 is a distinct Lab
1368
+ candidate with observed output differences. The packed-kernel section in
1369
+ turboquant.md owns these implementations and evidence.
1370
+
1371
+ Integrated variant 11 adds direct tiled gate/up prefill for M=5..32, with
1372
+ the same full-model logit/state gates and paired native improvement against
1373
+ variant 10. The operation has no model-name dependency; its dispatch profile
1374
+ currently covers the measured Qwen MLP geometry. It also improves the strict
1375
+ fill fixture's complete generation time in six paired fill/no-fill blocks,
1376
+ with identical emitted tokens and no verification forwards. This remains
1377
+ fixture evidence, not a universal determinism proof. Evidence:
1378
+ `variant11-full-model-review.json` and
1379
+ `strict-fill-v11-cap32-served-eos.review.json`. Six paired raw-completion
1380
+ HTTP blocks per method improve first-token and complete-request latency,
1381
+ with identical output, through strict serial and continuous B=1 execution.
1382
+ They cover one six-token prompt and eight/64 output tokens; concurrency and
1383
+ broader-workload conclusions remain open. Evidence: `trellis-v11-http.json`
1384
+ and `trellis-v11-http-review.json`.
1385
+
1386
+ Variant 12 adds tiled split-K down projection at M=5..8. The integrated
1387
+ kernel passes exact full-model logits/state/continuation checks and improves
1388
+ six native paired blocks without changing the paths outside that range.
1389
+ Its implementation and sweep evidence live in turboquant.md. Serving and
1390
+ combined-candidate measurements remain separate gates. The combined variant
1391
+ 12 versus original variant 6 now passes six raw-completion HTTP pairs for
1392
+ each serial/default scheduling method, with matching text and actual token
1393
+ counts at eight/64 output tokens. Source hashes stay fixed throughout all
1394
+ 24 bounded server processes. These one-prompt, B=1 diagnostics improve both
1395
+ TTFT and complete-request latency; they do not establish concurrent load or
1396
+ quiet-machine performance. Evidence: `trellis-v12-combined-http.json` and
1397
+ `trellis-v12-combined-http-review.json`. The exact-input native control also
1398
+ improves first-token and complete-request time in six paired blocks per
1399
+ output length, with identical emitted IDs. One candidate worker escaped
1400
+ through Bun with a C++ exception; its traced replay and the complete repeated
1401
+ pair succeed. The original failed block is retained and excluded from timing
1402
+ aggregation. This does not close the runtime reliability issue. Evidence:
1403
+ `trellis-v12-combined-native-review.json`, its original/resumed reports and
1404
+ `trellis-v12-native-failure-replay.json`.
1405
+
1406
+ The packed serving comparison now also covers four simultaneous raw
1407
+ completions. Six fresh-process pairs compare variants 6 and 12, with a warm
1408
+ four-request wave followed by a measured wave. Every arm observes four active
1409
+ batch rows, all responses/counts/finish reasons agree, and the candidate
1410
+ improves complete-wave throughput in every pair. Prompt and SSD caches are
1411
+ disabled; the source snapshot stays fixed and all twelve servers exit cleanly.
1412
+ These diagnostics establish that the shared small-M kernels improve actual
1413
+ concurrent serving, alongside the earlier B=1 results. Mixed lengths, larger
1414
+ concurrency and quiet M4 Pro acceptance remain separate gates.
1415
+ Evidence: `trellis-concurrent-http.json` and
1416
+ `trellis-concurrent-http-review.json`.
1417
+
1418
+ The operation trace led to smaller M=5..8 matrix tiles and deferred evaluation
1419
+ for direct tiles. Dense expansion retains its projection boundary. The
1420
+ integrated kernels pass targeted units and an old-source/new-source comparison
1421
+ at ten append lengths, including logits, live cache bytes and continuation.
1422
+ Six subsequent HTTP process pairs compare the previous and updated variant 12
1423
+ at B=1 and eight concurrent requests. Every wave observes the expected active
1424
+ row count; all paired warmup and measured responses, token counts and finish
1425
+ reasons agree. Eight-request throughput improves consistently; B=1 first-token
1426
+ latency improves, with a much smaller complete-request gain. All twelve servers
1427
+ exit cleanly and the source hashes remain fixed. The initial explicit-seed
1428
+ pilot routed through serial and is excluded from batching evidence. These
1429
+ remain M4 Pro diagnostics, with variant 6 unchanged. Evidence:
1430
+ `trellis-tile-integrated-forward-review.json`, `trellis-tile-http-review.json`
1431
+ and `trellis-tile-seeded-serial-http-review.json` in the campaign directory.
1432
+ Six old/new native process pairs also preserve all 64 emitted IDs and finish
1433
+ reasons in warmup and measurement. First-token latency improves in every pair;
1434
+ the complete native request improves slightly because single-row decode is
1435
+ unchanged. All twelve workers complete with fixed source hashes. Evidence:
1436
+ `trellis-tile-native.json` and `trellis-tile-native-review.json`.
1437
+ The tile and evaluation-boundary experiments are detailed in turboquant.md.
1438
+
1439
+ The existing `bench-serve.ts all` suite also completes two AB/BA process pairs
1440
+ for packed variants 6 and 12 with the serial arm, fixed workload seed and 192
1441
+ decode tokens. Source snapshots match across all four runs. All 38 paired
1442
+ recorded requests and the separate raw/chat parity probes agree; every server
1443
+ exits cleanly, all SSD entries are durable, and no failed samples are dropped.
1444
+ Single-request decode improves consistently at both tested contexts. Cold
1445
+ prefill improves modestly; warm first-token latency varies between pairs and
1446
+ sampled RSS shows no reduction. The requested context target produces 2,679
1447
+ actual prompt tokens. The four-request aggregate leg is serial queue throughput,
1448
+ not batching evidence. This M4 Pro diagnostic does not promote a default or
1449
+ replace quiet-machine acceptance. Evidence:
1450
+ `single-request-suite-packed.json` and `single-request-suite-packed-review.json`,
1451
+ with all four raw suite reports in the campaign directory.
1452
+
1453
+ Variant 13 adds vectorized packed-weight expansion after a larger fused-tile
1454
+ screen failed to beat native matmul. The operation and packing contract are
1455
+ documented in turboquant.md. Focused tests cover every codebook state, circular
1456
+ windows, scale dtypes, strided inputs and fallback. The integrated 12/13
1457
+ comparison preserves logits, live cache bytes and continuation at five append
1458
+ lengths across seven blocks, including six measured AB/BA pairs. Actual kernel
1459
+ calls confirm the eligible prefills improve while M=1/8 retain their existing
1460
+ path. All three typechecks, hygiene and 1,795 model-free tests pass. Evidence:
1461
+ `trellis-vector-integrated-full-model-review.json` and
1462
+ `trellis-vector-integrated-{unit,typecheck,hygiene,model-free}.txt` in the
1463
+ campaign report directory.
1464
+
1465
+ Two subsequent AB/BA pairs through the existing serving suite preserve all 38
1466
+ paired requests, raw/chat parity and SSD restart durability. All four servers
1467
+ exit cleanly with fixed source snapshots and no failures. Cold TTFT at the
1468
+ smaller prefill improves modestly, while decode, long-context TTFT and RSS are
1469
+ approximately flat. Cached TTFT varies substantially, so it is not an accepted
1470
+ kernel gain. An external browser/build/test burst occurs near the first pair's
1471
+ transition and is retained in the observations. This result does not establish
1472
+ a broad serving improvement or promote variant 13. Quiet M4 Pro acceptance
1473
+ remains. Evidence: `vector-expand-suite-packed.json`,
1474
+ `vector-expand-suite-packed-review.json` and
1475
+ `vector-expand-suite-load-observations.json` in the campaign directory.
1476
+
1477
+ Six further serial HTTP AB/BA pairs isolate 6/16/128/512-token prompts with
1478
+ 64 generated tokens and prompt/SSD caching disabled. Each shape receives a
1479
+ separate warmup; all first-shape timings are retained. Every paired response,
1480
+ token count and finish reason matches across all 54 warmup/measured requests,
1481
+ sources remain fixed, and all twelve servers shut down cleanly. TTFT and
1482
+ complete-request time improve in every 16/128-token pair. The six-token
1483
+ control and decode speed are flat; the 512-token and sampled RSS results are
1484
+ less consistent. Six default-scheduler pairs repeat the improvement at
1485
+ 16/128 tokens, with exact responses, fixed sources and clean shutdowns.
1486
+ Per-request telemetry proves scheduler admission. Existing swap usage and
1487
+ background CPU activity keep both M4 Pro series diagnostic; the 512-token
1488
+ effect remains less consistent. Evidence:
1489
+ `trellis-vector-short-http-paired-{serial,default}.json` and the corresponding
1490
+ `-review.json` files in the campaign directory. Quiet, second-machine and
1491
+ pressure acceptance remain before any default promotion.
1492
+
1493
+ The updated affine controls now complete six alternating Bun/MLX-LM process
1494
+ pairs for each flagship, compact and RTN4 artifact. They use the same six raw
1495
+ prompt IDs, 64 output tokens, tokenizer/model EOS handling, production wiring
1496
+ decisions and fresh-cache cleanup. Every pair emits identical IDs. Complete
1497
+ native request time is close, with a small median Bun advantage; MLX-LM has
1498
+ slightly lower first-token latency. These diagnostic controls establish no
1499
+ new kernel win or HTTP conclusion. All 36 workers finish and the source
1500
+ snapshot stays fixed. Evidence: `native-affine-paired.json` and
1501
+ `native-affine-paired-review.json` in the campaign report directory.
1502
+
1503
+ The shared grammar bitmask candidate compares host expansion, direct Metal,
1504
+ compiled Metal and XGrammar's compiled MLX bitmap-table approach. The compiled
1505
+ Metal operation preserves the additive mask's bytes for bf16/f16/f32,
1506
+ strided inputs, missing words, signed zero and nonfinite values. Its owned
1507
+ host snapshot survives matcher mutation before lazy evaluation. Repeated
1508
+ calls release their arrays after stream synchronization. Complete greedy,
1509
+ sampled and logprob-enabled sampling retains identical selected tokens and
1510
+ logprob bytes across changing masks at three vocabulary sizes, and improves
1511
+ eight paired blocks against the actual host loop. An earlier probe used a
1512
+ slower host callback expansion and is excluded from performance evidence.
1513
+ Grammar integration is opt-in pending actual serving measurements. Evidence:
1514
+ `token-mask-probe.json`, `token-bitmask-unit.txt` and
1515
+ `token-bitmask-grammar-metal.txt`, plus `token-mask-sampling.json` and
1516
+ `token-mask-sampling-review.json` in the report directory.
1517
+
1518
+ The first dense attention prototype adapts vLLM-Metal's register-resident
1519
+ online softmax. It reduces temporary memory but loses the timing screen.
1520
+ Instantiating pinned MLX Steel attention at head dimension 256 is faster on
1521
+ some self-attention shapes, while the long-K/short-Q suffix case remains
1522
+ slower. Tiling must follow both lengths and the device's workspace limit.
1523
+ This changes numerics relative to the current unfused bf16 path and stays
1524
+ Lab pending model and task-quality checks. Evidence:
1525
+ `steel-attention-tune-manifest.json` and its per-tile reports. The initial
1526
+ probe's small-head error metrics used physical output order; the corrected
1527
+ contiguous readback agrees with the pinned oracle and CPU reference in
1528
+ `attention-cpu-check.json` and `attention-oracle-check.json`.
1529
+ The full packed-model Steel test is flat at 128/512 prompt tokens; one
1530
+ 512-token cell exceeds its predeclared last-logit KL screen, despite matching
1531
+ the observed argmax. It has no model-level speed or quality acceptance.
1532
+ Moving Q into threadgroup storage and transposing K storage did not rescue
1533
+ the separate register-based prototype's timing. Evidence:
1534
+ `attention-full-model-packed-128-512-review.json` and
1535
+ `dense-attention-memory-tune-review.json`. Larger-context and exact-arithmetic
1536
+ attention candidates remain separate experiments.
1537
+
1538
+ Graph export now records the existing evaluation boundaries for variants
1539
+ 6/8 at M=1/4/5. Small-M forward has one final evaluation boundary. M=5 has
1540
+ 192 projection evaluations, 64 layer evaluations and a final evaluation.
1541
+ The exported graphs identify the exercised operations, including affine
1542
+ projections, packed custom kernels, GDN, convolution, norms, RoPE, attention
1543
+ and casts. Counts are exported operation occurrences, not GPU dispatches.
1544
+ Raw graphs and the manifest are in `reports/qwen38-rd/graph-captures/`.
1545
+
1546
+ An attached Metal System Trace captures the warmed Bun target and its GPU
1547
+ encoder intervals. The installed release MLX labels only command buffers
1548
+ and encoders, so individual-kernel duration attribution remains open. The
1549
+ capture covers part of prefill and decode; it is not a complete TTFT trace.
1550
+ The first launch-based capture contains no target GPU work and is excluded.
1551
+ Evidence: `variant8-attached.trace` and `attached-trace-summary.json` in the
1552
+ same report directory. A pinned MLX source checkout supports inspection of
1553
+ the actual dispatch and an isolated profiling build without changing the
1554
+ oracle or installed runtime.
1555
+
1556
+ The isolated profiling build now records the kernel name, dispatch grid,
1557
+ threadgroup geometry and pipeline limits for each submitted dispatch. A second
1558
+ attached trace adds operation labels to encoder scopes. Those scopes contain
1559
+ multiple operations, including zero-work views, so their GPU duration cannot
1560
+ be attributed to the label's final operation. The selected Xcode counter
1561
+ profile is unsupported on this M4 and exports no shader or counter samples.
1562
+ Use the dispatch inventory to select isolated operation experiments while
1563
+ individual GPU timing remains open. Evidence: `labelled-v8-analysis.json`,
1564
+ `labelled-v8-kernels.txt` and `variant8-labelled.trace` in the report directory.
1565
+
1566
+ A direct device capability query exposes timestamp counters only at compute
1567
+ stage boundaries on this M4 Pro. Dispatch-level sampling is unsupported.
1568
+ The isolated pinned runtime now samples each operation in a separate encoder,
1569
+ reserving two slots in a shared counter buffer and resolving them once per
1570
+ completed command buffer. A per-operation allocation first exhausted Metal's
1571
+ sample-buffer resources; a larger pool exceeded its documented-in-error size
1572
+ limit. Both failed attempts are retained, and the final pool fits that limit.
1573
+ The installed native library and Python oracle are unchanged.
1574
+
1575
+ Calibration compares the release library, the isolated build without
1576
+ segmentation, segmentation alone, and counters. At B=1 and append lengths
1577
+ 1/4/8/128 from a 32-token prefix, every arm preserves logits, live cache bytes
1578
+ and one continuation across one warmup and three measured forwards. The
1579
+ instrumented full-forward overhead is small in this screen. All recorded
1580
+ timestamps are valid, and sampled CPU/GPU clock pairs agree. These are
1581
+ operation-encoder intervals: operations with multiple dispatches stay grouped,
1582
+ intervals can overlap and include waits, and their sum is not GPU wall time
1583
+ or critical-path attribution. The small-M trace directs further work toward
1584
+ packed projections and affine matvecs; the eight-token trace exposes the
1585
+ cost of the tiled prefill path. Evidence: `metal-counter-capabilities.json`,
1586
+ `mlx-counter-source-manifest.json`, `mlx-counter-build.patch`,
1587
+ `metal-counter-pooled-unit.stderr.txt` and
1588
+ `metal-counter-calibration-review.json` in the report directory.
1589
+
1590
+ A separate schedule recorder now preserves MLX's normal encoder and command
1591
+ buffer boundaries. It counts existing dispatches, barriers, fence waits and
1592
+ temporary references, and reads command-buffer GPU start/end times in the
1593
+ completion handler, following [Metal's timing contract](https://developer.apple.com/documentation/metal/mtlcommandbuffer/gpustarttime).
1594
+ It rejects simultaneous operation segmentation. The first smoke test exposes
1595
+ a unit mistake in the recorder: the pinned runtime's `buffer_sizes_` adds
1596
+ `data_size()`, which counts dtype elements. Correct the recorder to report
1597
+ that heuristic as elements and multiply by item size for temporary bytes.
1598
+ The effective M4 Pro submission defaults are 50 dispatches and 50 shifted
1599
+ element-count units. The setting's upstream name remains
1600
+ `MLX_MAX_MB_PER_BUFFER`; it is not a literal byte ceiling. Temporary-reference
1601
+ totals are also not peak resident memory.
1602
+
1603
+ The corrected recorder passes 45 complete generations across Llama 1B and
1604
+ Qwen packed/RTN4, comparing the ordinary library, the isolated library without
1605
+ telemetry and the recorder with native/raw/compiled sampler arms. Every
1606
+ token, live state byte and usage record agrees. Warmed complete timings show
1607
+ no clear systematic instrumentation shift in this screen; repeated overhead
1608
+ calibration remains necessary for quantitative timing attribution. The
1609
+ 64-token packed sampling trace loses four dispatches per token with fusion,
1610
+ but all three sampler arms still submit 3,905 buffers containing dispatches.
1611
+ Many additional buffers contain no kernel dispatches; they may still carry
1612
+ event waits or signals. Audit callers before attempting to remove them.
1613
+ Command-buffer spans include internal waits, so their union is not kernel
1614
+ active time or device utilization. Evidence is `mlx-schedule-source-manifest.json`,
1615
+ `mlx-schedule-smoke-v2.log` and `top-p-schedule-screen{,-review}.json`.
1616
+
1617
+ A separate caller trace attributes 24 zero-dispatch submissions during steady
1618
+ packed greedy decode to the pressure branch in MLX's `eval_impl`, reached
1619
+ through `async_eval`. That branch finalizes open GPU streams before waiting
1620
+ for outstanding work. All three traced generations preserve emitted IDs,
1621
+ live cache bytes and usage against the calibrated recorder. Startup-only
1622
+ stacks had instead reached final evaluation and synchronization, so they
1623
+ could not establish the steady decode cause. The trace adds CPU logging and
1624
+ is not timing evidence. These observations do not establish that an empty
1625
+ dispatch list has no event work. Keep the validated recorder separate from
1626
+ the caller-trace build. Evidence is `empty-submit-r6-steady-trace{,-review}.json`
1627
+ and `mlx-empty-submit-steady-source-manifest.json`.
1628
+
1629
+ The next stock-library screen varies MLX's command-buffer submission limits,
1630
+ bounded breadth-first graph traversal and optional Metal synchronization
1631
+ implementation. Measure complete warmed generation, with matching token IDs,
1632
+ requested log probabilities and live state, before changing native code or
1633
+ retaining a setting. New-shape prefill cells are correctness screens until
1634
+ their shapes are warmed in both arms. Positive cells require balanced native
1635
+ and actual serial/continuous HTTP repeats, plus memory and disposal checks.
1636
+ The frozen screen is `graph-schedule-screen-plan.json`.
1637
+
1638
+ That first screen passes all 120 generations and 27 complete arm comparisons
1639
+ on Llama 1B and Qwen packed/RTN4. No packed-model decode setting has a
1640
+ compelling first-pass gain. The later RTN4 timings overlap with unrelated
1641
+ disburse TypeScript/Vite/Playwright jobs, including higher load and swap use.
1642
+ Exclude RTN4 timing from tuning decisions and repeat it after those workers
1643
+ exit; retain its exactness results. Llama's smaller-buffer observation needs
1644
+ balanced repeats. Evidence is `graph-schedule-screen{,-review}.json` and
1645
+ `graph-schedule-screen-contamination.json`. Retained tuning belongs at the
1646
+ existing model-owned execution seams; these experiments do not establish
1647
+ new global defaults.
1648
+
1649
+ The RTN4 rescreen completes 40 generations with nine exact arm comparisons,
1650
+ including a return to the default settings at the end. The apparent 0.94%
1651
+ greedy gain with traversal width 64 matches the ending default's 0.92% drift;
1652
+ sampled generation is flat in both. Larger submission limits also fail to
1653
+ improve both decode fixtures. No Qwen setting advances from this screen.
1654
+ New-shape prefill timings remain excluded. Evidence is
1655
+ `graph-schedule-rtn4-rescreen-v2{,-review}.json`.
1656
+
1657
+ Llama's six balanced native pairs preserve all 30 paired generations, including
1658
+ requested log probabilities and live state. Reducing both submission limits
1659
+ to 25 lowers complete warmed generation time by 2.44% for greedy and 2.30%
1660
+ for sampled output; all six pairs improve in each cell. TTFT is effectively
1661
+ flat. Peak MLX allocation falls in the measured cells, which is not a claim
1662
+ about physical RAM savings. Six actual HTTP pairs per lane then preserve all
1663
+ 84 paired responses across 168 requests. Complete time improves by
1664
+ 1.86–3.02% in serial and 2.22–3.00% in continuous serving across the three
1665
+ fixtures, with every pair faster. These M4 Pro results remain diagnostic.
1666
+ The controls are `graph-schedule-llama-repeat{,-review}.json` and
1667
+ `graph-schedule-llama-http-repeat{,-review}.json`. MLX caches these settings
1668
+ at device initialization; assigning environment variables from a later
1669
+ model forward would not apply the measured policy. Broader contexts,
1670
+ lifecycle coverage and scoped integration remain.
1671
+
1672
+ A separate native prototype elides `finalize` only when the command buffer
1673
+ has not been touched since the preceding commit. Access to the buffer,
1674
+ encoder creation, output registration and temporary registration all make it
1675
+ ineligible. This preserves event-only and completion-handler work, and leaves
1676
+ explicit synchronization unchanged. The isolated build and its disabled arm
1677
+ each pass 84 stream/lifetime cases against the installed library, spanning
1678
+ three dtypes, two sizes, two memory limits, CPU/GPU and GPU/GPU dependencies,
1679
+ view-only events and disposal before asynchronous completion. All cases
1680
+ return active memory to zero. The subsequent 45 complete generations also
1681
+ preserve IDs, requested log probabilities, live state and usage across the
1682
+ three artifacts and both library controls. Packed generation is effectively
1683
+ flat. Six subsequent RTN4 AB/BA pairs preserve all 30 paired generations but
1684
+ find no reliable gain: complete greedy time changes by -0.069%, sampled by
1685
+ +0.108% and warmed prefill by +0.011%. Peak MLX allocation is flat. Close the
1686
+ prototype without production integration. Evidence
1687
+ is `mlx-untouched-finalize-source-manifest.json` and
1688
+ `untouched-finalize-stream-default{,-review}.json`, plus
1689
+ `untouched-finalize-native{,-review}.json` and
1690
+ `untouched-finalize-rtn4-repeat{,-review}.json`.
1691
+
1692
+ The separate exact traces confirm that the prototype removes the intended
1693
+ submissions. For 64 packed sampled tokens, zero-dispatch buffers fall from
1694
+ 3,311 to 194, while all 116,164 dispatches and 3,905 buffers containing
1695
+ dispatches remain. RTN4's corresponding zero-dispatch count falls from 4,083
1696
+ to two; its 115,947 dispatches remain. The sampled skip counters record
1697
+ 3,113/4,072 omitted calls. Counts need not subtract exactly between runs
1698
+ because pressure callbacks and completion timing vary. This is mechanism
1699
+ evidence, not an end-to-end speed claim. Evidence is
1700
+ `untouched-finalize-trace{,-review}.json`.
1701
+
1702
+ The optional upstream `MLX_METAL_FAST_SYNCH=1` mode stalls in the installed
1703
+ library's large bf16 three-stream case under the probe's small submission
1704
+ limits. A stack sample finds the host in `scheduler::wait_for_one` and a
1705
+ worker in `Fence::wait`. Stop only that probe after more than 100 seconds
1706
+ without progress, retain its partial results, and rerun all default-mode
1707
+ cases successfully. Do not attribute this stock-library failure to the new
1708
+ prototype or treat the unrun experimental-mode arms as passes. Evidence is
1709
+ `untouched-finalize-stream.json`, `untouched-finalize-stream-fast1-interruption.json`
1710
+ and `untouched-finalize-stream-fast1-default.sample.txt`.
1711
+ The initial interruption annotation mislabeled that case as f32; the partial
1712
+ report's dtype 12 identifies bf16. The corrected attribution is recorded in
1713
+ `untouched-finalize-stream-fast1-failure-review.json`.
1714
+
1715
+ The existing GDN stage profiler has also been run at M=1/4/128/512 against
1716
+ unprofiled forwards from the same prefix. Observed logits agree. Its added
1717
+ stage/layer evaluations substantially inflate small-M time, so those stage
1718
+ durations cannot substitute for GPU kernel attribution. Evidence:
1719
+ `reports/qwen38-rd/gdn-stage-probe.json`. A fused convolution/SiLU/copied-tail
1720
+ prototype matches the tested bf16/f32 outputs and live tail at B=1/2. It
1721
+ requires MLX's typed sigmoid expression; a float32 rewrite changes bf16
1722
+ results. The opt-in operation now passes full packed-model logits, live
1723
+ state, continuation and speculative rollback checks. Its initial memory
1724
+ benefit exposed an aliasing baseline: `mlx_copy` retains the source buffer.
1725
+ The default path now uses a shared compact materialization operation backed
1726
+ by stock MLX DynamicSlice, with gradient and compiled-execution gates.
1727
+ Replacing the alias preserves all tested packed-model logits, live state,
1728
+ continuation and rollback bytes. Explicit disposal still owns handle cleanup;
1729
+ the copy change allows the large backing allocation to be released.
1730
+ Against an independently materialized baseline, convolution fusion has
1731
+ approximately flat full-model timing and similar peak memory. It remains an
1732
+ unpromoted R8 experiment. Evidence: `qwen-conv-materialized-packed.json`,
1733
+ `materialize-final-packed-comparison.json`, and `conv-probe-typed-sigmoid.json`.
1734
+ The final stock-copy rerun is a correctness gate; concurrent CPU trace exports
1735
+ exclude its diagnostic timings from performance comparisons.
1736
+
1737
+ GDN specialization now covers threadgroup layouts, fixed sequence lengths,
1738
+ loop unrolling, compiled wrappers and typed sigmoid fusion. Correcting the
1739
+ initial float32 sigmoid rewrite restores exact bf16 recurrence and state.
1740
+ The subsequent shape sweep passes all 114 cells. A compiled fixed-length
1741
+ candidate preserves full-model logits, live state and continuation, but its
1742
+ isolated gains mostly disappear in full forwards. A separate fused recurrence,
1743
+ output RMS normalization and gate kernel passes 60 isolated shape/dtype cells
1744
+ and the small-M full-model checks. Its full-forward improvement is too small
1745
+ to justify integration at this point. Neither candidate changes production
1746
+ dispatch. Evidence: `gdn-specialization-typed.json`,
1747
+ `gdn-static-full-model-review.json`, `gdn-fused-norm-probe.json` and
1748
+ `gdn-fused-norm-full-model-review.json`.
1749
+
1750
+ The affine matvec layout screen preserves pinned MLX's reduction arithmetic
1751
+ while varying output rows per SIMD group and groups per threadgroup. Actual
1752
+ packed-artifact head and GDN projection weights pass exact checks with both
1753
+ direct and compiled wrappers. The best isolated head cells improve only
1754
+ slightly, and the small-M projection results are mixed. There is no accepted
1755
+ whole-model gain. Combined projection dispatch remains a separate candidate.
1756
+ Evidence: `affine-qmv-screen.json` and `affine-qmv-compiled.json`.
1757
+
1758
+ A second affine prototype shares packed weights and quantization metadata
1759
+ across four or eight input rows, preserving MLX's dot-product and SIMD
1760
+ reduction order. The corrected real-matrix screen passes all 50 cases; larger
1761
+ GDN projections improve in isolation, while vocabulary-head gains are smaller.
1762
+ An initial bf16 failure was large, not rounding noise: some shared-row layouts
1763
+ read incorrect scale/bias values. Explicit bf16 bit expansion avoids the
1764
+ observed failure without resident float32 metadata copies. Direct and compiled
1765
+ bf16/f32 debug cells then agree exactly. The underlying compiler cause is not
1766
+ established. Six full-model pairs preserve logits, live cache bytes and
1767
+ continuation on both packed and plain RTN4 artifacts. RTN4 improves consistently
1768
+ at M=4/8 with unchanged peak allocation and flat unused-shape controls. Packed
1769
+ improves little; its unused M=128 control also shifts, so the smaller packed
1770
+ timing difference needs an independent check. Six RTN4 HTTP process pairs
1771
+ then preserve all 108 paired warmup/measured responses, token counts and
1772
+ finish reasons. Every measured eight-request wave reaches eight active rows
1773
+ and improves throughput; the single-request control is approximately flat.
1774
+ All twelve servers exit cleanly with fixed source hashes. Evidence:
1775
+ `affine-shared-m-http-rtn4-review.json`, `affine-shared-m-probe.json`,
1776
+ `affine-shared-m-probe-initial.json` and
1777
+ `affine-shared-m-debug-scale-bits.json`, plus
1778
+ `affine-shared-m-full-model-{packed,rtn4}-review.json`.
1779
+
1780
+ The retained shared operation is `src/mlx/affine-shared-m.ts`, opt-in via
1781
+ `MLX_BUN_AFFINE_SHARED_M=1`. Eligibility follows dtype, quantization, shape
1782
+ and stream rather than a model name. It retains native MLX for unsupported
1783
+ cells and during shapeless compile traces: the native CustomKernel primitive
1784
+ cannot infer output shapes there. The trace context is restored on return or
1785
+ exception. Shape-specific compiled calls remain eligible. Focused tests cover
1786
+ strided activations and metadata, leading dimensions, shape changes and
1787
+ fallbacks. A cleaned-up kernel passes another six RTN4 full-model pairs and
1788
+ retains the gain. Six final production-flag HTTP pairs preserve all 156 paired
1789
+ warmup/measured responses with fixed source hashes and clean server exits.
1790
+ Both four- and eight-request throughput improve in every pair; the
1791
+ single-request control is flat. Dispatch counters confirm M4 and M8 use the
1792
+ shared operation. Broader artifacts and quiet M4 Pro gates remain. Evidence:
1793
+ `affine-shared-m-production-full-model-rtn4-review.json`,
1794
+ `affine-shared-m-shapeless.json`, `affine-shared-m-integrated-unit.txt` and
1795
+ `affine-shared-m-integrated-http-rtn4-review.json`.
1796
+
1797
+ The next row-width screen passes all 112 real RTN4 matrix cases at
1798
+ M=2/3/5/6/7. Six full-model pairs per width also preserve logits, live state
1799
+ and continuation. M2 loses and retains native dispatch. M3 improves slightly;
1800
+ M5/6/7 improve consistently without a material peak-memory increase. The large
1801
+ head needs separate geometry: its M6/7 shared-row cells lose even when smaller
1802
+ projections win. Wider integration therefore keeps those head cells native.
1803
+ Evidence: `affine-shared-m-width-rtn4-review.json` and
1804
+ `affine-shared-m-width-full-model-rtn4-review.json`.
1805
+
1806
+ A broader-format prototype initially fails nine of 216 arithmetic cells,
1807
+ all bf16 M8 layouts with 3- or 5-bit weights. The errors are large and survive
1808
+ float32 output storage. Float32 activations remove the large error but also
1809
+ change the reference's typed arithmetic. Explicit bf16 input expansion plus
1810
+ rounding after each typed addition preserves that arithmetic and passes all
1811
+ 216 dtype/bit/group-size cells. Evidence:
1812
+ `affine-shared-m-all-bits-correctness-review.json`,
1813
+ `affine-shared-m-all-bits-debug.json` and
1814
+ `affine-shared-m-all-bits-explicit-input-correctness-review.json`.
1815
+
1816
+ The compact artifact supplies actual 3-bit head/MLP and 8-bit attention/GDN
1817
+ matrices. All 80 real-matrix cells agree exactly, including compiled calls.
1818
+ Reusing each packed load for two input rows at 3-bit and four at 8-bit wins
1819
+ the retained M4/8 cells. Both compute four output rows per SIMD group, with
1820
+ two SIMD groups per threadgroup. Six full-model pairs
1821
+ with the prototype and another six with the cleaned production operation
1822
+ preserve logits, live cache bytes and continuation; both row counts improve,
1823
+ unused-shape controls stay approximately flat and peak allocation is unchanged.
1824
+ The 3/8-bit implementation now lives in `src/mlx/affine-shared-quant.ts`, under
1825
+ the same opt-in flag and native fallback rules. Other bit widths and group
1826
+ sizes remain research-only. Evidence:
1827
+ `affine-shared-m-all-bits-explicit-compact-review.json`,
1828
+ `affine-shared-m-all-bits-full-model-compact-review.json` and
1829
+ `affine-shared-m-broader-full-model-compact-review.json`.
1830
+
1831
+ The final 4-bit operation includes M3/5/6/7, retaining native M2 and the large
1832
+ head at M5/6/7. Six complete-model pairs per width preserve logits, state and
1833
+ continuation. Six production-flag HTTP pairs at B1/3/5/6/7 preserve all 264
1834
+ paired warmup/measured responses. Each measured wave reaches the requested
1835
+ active width; candidate dispatch is observed and all twelve servers exit
1836
+ cleanly. Concurrent throughput improves in every pair. Single-request decode
1837
+ is approximately flat. All pairs are retained, including noisier final runs:
1838
+ the machine has residual swap, XProtect is active at the initial preflight,
1839
+ and unrelated build/browser activity is observed after the run. This remains
1840
+ a diagnostic result. Wider model coverage remains open.
1841
+ Evidence: `affine-shared-m-broader-full-model-rtn4-review.json` and
1842
+ `shared-affine-frontier-http-rtn4-review.json`. Current focused tests, all
1843
+ three typechecks, hygiene and the complete model-free tier pass; the latter
1844
+ has 1,785 passes, ten skips and no failures. Evidence:
1845
+ `affine-shared-m-broader-{unit,typecheck,hygiene,model-free}.txt`.
1846
+
1847
+ Six final compact production-flag HTTP pairs preserve all 156 paired warmup
1848
+ and measured responses, usage counts and stop reasons. Both B4 and B8 improve
1849
+ in every measured pair; the median B1 control is flat, with individual noisy
1850
+ outliers retained. Actual active widths and both 3/8-bit dispatches are
1851
+ observed, all twelve servers exit cleanly and source hashes remain fixed.
1852
+ Residual swap keeps this diagnostic. Evidence:
1853
+ `shared-affine-frontier-http-compact-review.json`.
1854
+
1855
+ A subsequent host-overhead prototype caches shape-specific compiled calls
1856
+ around these shared-affine kernels. Every weight/scale/bias/activation remains
1857
+ a dynamic input, so one compiled function can serve distinct model layers.
1858
+ Six compact full-model pairs retain exact logits, state and continuation;
1859
+ 24 compiled configurations serve all eligible projections without new traces
1860
+ in measured rows. The eligible M4/8 cells improve modestly. Six subsequent
1861
+ HTTP process pairs preserve all 156 paired warm/measured responses with clean
1862
+ server exits and fixed source hashes. Serving gains shrink to approximately
1863
+ flat at B1/4 and a small B8 difference. This does not justify integrating the
1864
+ extra compiled-function cache at present. Evidence:
1865
+ `affine-compiled-call-cache-full-model-compact-review.json` and
1866
+ `affine-compiled-call-cache-http-compact-review.json`.
1867
+
1868
+ The grammar-mask operation now completes six compact HTTP process pairs at
1869
+ B1/4 with shared-affine enabled in both arms and grammar jumping disabled.
1870
+ All 60 paired warm/measured responses match and satisfy the frozen JSON
1871
+ schema; both arms apply the mask the same number of times. Every concurrent
1872
+ wave reaches four active rows, source hashes remain fixed and all servers
1873
+ exit cleanly. The timing is inconclusive for promotion: residual swap and
1874
+ overlapping unrelated build/browser work are recorded, the B1 median is
1875
+ approximately flat and the B4 median regresses. Preserve all samples and
1876
+ revisit on a controlled session. Host masking remains default. Evidence:
1877
+ `grammar-mask-http-compact-review.json`.
1878
+
1879
+ A fused affine gate/up/SwiGLU prototype shares activation loads and replaces
1880
+ the two projections plus activation dispatch. Its first version preserves
1881
+ both projection outputs but fails the activation check: a float32 sigmoid
1882
+ expression differs from MLX's dtype-specific expression. The corrected
1883
+ kernel passes all 48 real RTN4 small-M cells, including complete MLP output.
1884
+ Only M=1 benefits in that isolated screen. Restricting the full-model prototype
1885
+ to M=1 preserves logits, live state and continuation across six paired blocks,
1886
+ but its full-forward gain is too small to justify integration. Longer-M
1887
+ forwards retain the original path. Evidence: `affine-gateup-debug.json`,
1888
+ `affine-gateup-debug-typed.json`, `affine-gateup-typed.json` and
1889
+ `affine-gateup-full-model-review.json`. The existing packed activation's
1890
+ separate arithmetic contract needs its own audit before reusing that code
1891
+ in an affine operation.
1892
+
1893
+ A residual-add/RMSNorm kernel preserves the native reduction topology and
1894
+ the rounded residual before normalization. All 90 synthetic bf16/f16/f32
1895
+ cases preserve both outputs. Six packed-model pairs at M1/4/8/128 then
1896
+ preserve logits, live cache bytes and continuation, with 64 fused calls per
1897
+ forward. M1 is slightly slower, M4/8 are approximately flat and M128 varies.
1898
+ The complete path does not establish a compelling benefit, so this version
1899
+ is not integrated. Operation samples include wrapper/evaluation costs and are
1900
+ not GPU-only timestamps. Evidence: `residual-rms-screen-scalar-review.json`
1901
+ and `residual-rms-full-model-packed-review.json`. Earlier driver/binding
1902
+ failures occurred before timing and remain separate. Closed helpers are
1903
+ removed after recording the finding.
1904
+
1905
+ The first real HTTP screen uses the compact artifact through bounded CLI
1906
+ servers. It retains request hashes, actual usage, arrival times, cache hits,
1907
+ restart durability, concurrent request completion and failures. Its cold
1908
+ context leg required a Bun restart; the retried nonce changed the prompt, so
1909
+ that context comparison is unmatched. The chat probe also diverged despite
1910
+ equal prompt counts. Frozen chat IDs produce identical direct Bun/Python
1911
+ tokens. A cold HTTP control reproduces the Python difference only in its
1912
+ seedless BatchGenerator path; `seed=0` selects its serial method and matches
1913
+ the direct text. Compare those execution methods separately. The Bun HTTP
1914
+ sample also omits a final space, so it has no byte-identical wire-output claim.
1915
+ The benchmark records failed-attempt
1916
+ stderr and process status, including failures recovered by retry. This screen
1917
+ is diagnostic and establishes no serving win. Evidence and exclusions:
1918
+ `serving-compact-screen-0.review.json` and
1919
+ `serving-primes-native-comparison.json` in the report directory.
1920
+
1921
+ Repeated native-throw traces identify the continuous serving crash as Metal
1922
+ command-buffer out-of-memory. Bun 1.4.2 avoids it in one screen but misses
1923
+ one pending SSD snapshot at its first restart boundary; neither issue is
1924
+ closed. Continuous preparation and decode now share the serial memory
1925
+ guard, entered after cache acquisition under the execution lease. Ownership,
1926
+ refusal and guard restoration tests pass. The same context failure still
1927
+ reproduces: the affine graph's transient allocations occur at evaluation,
1928
+ after the per-layer construction checks. Investigate allocator residency
1929
+ and snapshot retention before declaring this fixed. Evidence:
1930
+ `serving-compact-bun140-throw.review.json`,
1931
+ `serving-compact-bun142-throw.review.json` and
1932
+ `serving-compact-shared-guard.review.json`. Source snapshots now include
1933
+ untracked kernels as well as tracked changes.
1934
+
1935
+ The frozen compact request isolates a cache-consumption cause: after one
1936
+ warm repeat transfers the exact recurrent boundary out of RAM, a third
1937
+ identical prompt loses that prefix and prefills again. Stopping after two
1938
+ requests also reproduces a missing SSD snapshot followed by a false-success
1939
+ flush; restart cannot reuse the longer untrimmable descendant. Persisting the
1940
+ boundary before transfer preserves the third request's prefix. Durability
1941
+ records now remain dirty until actually covered, and already-durable records
1942
+ avoid another clone. Ownership/failure and coordinator regression gates pass.
1943
+ The three-request HTTP replay preserves output and cached tokens through
1944
+ repeat and restart, with no missing flush. The two-request replay also writes
1945
+ the consumed boundary before restart. This requires a synchronous SSD write
1946
+ on the first transfer when that boundary is not already durable. The complete
1947
+ compact serving diagnostic now finishes context repeats, SSD flush/restart
1948
+ and four concurrent streams without a recorded failure. One diagnostic pass
1949
+ does not close long-agent or repeated reliability acceptance. Evidence:
1950
+ `ssd-boundary-before.json`, `ssd-boundary-two-before.json`,
1951
+ `ssd-boundary-after.json`, `ssd-boundary-two-after.json`,
1952
+ `ssd-boundary-tests.txt` and `serving-compact-boundary-fixed.review.json`
1953
+ in the campaign report directory.
1954
+
1955
+ The merged packed path now passes the seven saved Pi tool-result boundaries
1956
+ in separate serial and continuous server processes. Both arms use variant 12
1957
+ and the same frozen requests. Each completes the longest prompt, emits the
1958
+ requested 512 tokens, demotes old cache entries under pressure, and finishes
1959
+ with a durable SSD flush and no pending, missing or failed snapshots. Responses
1960
+ match across the two methods and the source snapshot stays fixed. The system
1961
+ prompt was reconstructed once with the installed Pi package and frozen;
1962
+ historical system-prompt byte identity is not established. This is a bounded
1963
+ memory/integration check, not a long-running agent success claim. No returned
1964
+ tools execute. Evidence: `agent-boundary-fixture.json`,
1965
+ `agent-boundary-current.json` and `agent-boundary-current-review.json`.
1966
+
1967
+ The M4 DeltaNet fixture discrepancy is now traced to the cached reference,
1968
+ not a Bun/oracle disagreement. Both implementations match gate values, output
1969
+ bytes and complete recurrent state on the frozen inputs. The explicit
1970
+ replay changes one older expected output and adds oracle provenance/state
1971
+ hashes. The platform evidence and regeneration procedure live in
1972
+ [environment.md](../reference/environment.md).
1973
+
1974
+ R22 now tests immutable file-backed weights through page-aligned Metal roots
1975
+ and ordinary MLX tensor views. The existing external-buffer entry point is
1976
+ sufficient for element-aligned tensors; each root includes the leading page
1977
+ padding and the tensor view carries the offset. This resembles
1978
+ [llama.cpp's mapped Metal buffer views](https://github.com/ggml-org/llama.cpp/blob/427291b5b34cd914a31b3fd3b61a68f6184f4b9f/ggml/src/ggml-metal/ggml-metal-device.m#L1999),
1979
+ which align the root pointer and split oversized mappings into overlapping
1980
+ views. The prototype uses no new artifact and no new production loader.
1981
+ Small metadata and unsupported element alignment retain native loading.
1982
+ All 32 operation cases match payload bytes and GPU add/matmul results;
1983
+ pointer equality proves that the candidate aliases the file, and file hashes
1984
+ stay unchanged. The Llama 1B artifact is ineligible because its large payloads
1985
+ start at odd byte offsets, so that initial native/native control establishes
1986
+ no candidate performance result.
1987
+
1988
+ The first packed 27B native pair maps 758 tensors, 11,895,111,680 payload
1989
+ bytes, through 11,907,530,752 bytes of page windows. Prefix state, ten
1990
+ full-forward logit/live-state/continuation cases and both generation token
1991
+ sequences match. The subsequent six-pair repeat preserves all 60 full-forward
1992
+ logit/state/continuation cases, every prefix state and all 12 generation
1993
+ comparisons. Sources stay fixed and all 12 child processes exit cleanly.
1994
+ The measured 64-token generation is 0.25% slower by median paired wall-time
1995
+ ratio, with no faster pair; TTFT is approximately flat. M1 is about 0.6%
1996
+ faster, while M4/8/128/512 give no consistent useful improvement. Evidence:
1997
+ `mmap-weights-native-packed-paired{,-review}.json`. Readiness varies strongly
1998
+ with order and file-cache state, so it has no cold-start improvement claim. Process RSS and macOS
1999
+ physical-footprint accounting fall sharply because most private copied weights
2000
+ become file-backed mappings. That does not shrink model bytes or establish a
2001
+ corresponding reduction in total physical RAM: clean file pages and GPU
2002
+ residency require separate accounting. Preserve MLX active/peak bytes, RSS,
2003
+ `vmmap` output and system pressure together. Evidence:
2004
+ `reports/qwen38-rd/mmap-page-window{,-pointer}-screen.json` and
2005
+ `mmap-weights-native-{llama1,packed}-screen.json`.
2006
+
2007
+ The serial HTTP follow-up completes six fresh-server pairs with all 42
2008
+ warm/measured response texts, usage counts and finish reasons exact. Sources
2009
+ remain fixed and all servers exit cleanly. Warm complete-response time is
2010
+ 0.04% to 0.14% slower by median paired ratio; decode is 0.14% to 0.21% slower.
2011
+ Median per-server peak RSS changes from 12,182,749,184 to 482,508,800 bytes.
2012
+ The recorded physical-footprint summaries show the same private/file-backed
2013
+ accounting change, not a smaller tensor working set. Evidence:
2014
+ `mmap-weights-http-serial{,-review}.json`. Default scheduling, system-memory
2015
+ pressure and cold file-cache behavior remain separate gates.
2016
+
2017
+ The initial prototype retains immutable roots and mapping owners for the
2018
+ process, matching the existing external-array lifetime requirement. A retained
2019
+ loader must also prove unload, outstanding GPU-reference ownership, repeated
2020
+ model replacement, pressure behavior and HTTP performance. No default or
2021
+ production lifetime change follows from this screen. A subsequent ownership
2022
+ prototype stores array/root handles with each `Weights` instance and releases
2023
+ them on disposal. Existing shard mappings remain mapped for the process. Three
2024
+ full-artifact cycles each load 2,019 tensors and release all 13,056,265,696
2025
+ active bytes. An outstanding GPU consumer survives weight disposal, produces
2026
+ the exact expected output and releases the remaining 2,048 bytes on disposal;
2027
+ active memory is zero before GC. Evidence:
2028
+ `mmap-weights-ownership-packed{,-mapping}.json`. Three additional cycles
2029
+ retain a single-input lazy negation, dispose the weights before submitting it,
2030
+ and then evaluate it. Outputs remain exact; the pending view retains
2031
+ 39,747,584 bytes until its disposal, after which active memory returns to zero
2032
+ before GC. Evidence: `mmap-weights-single-consumer-lazy{,-mapping}.json`.
2033
+ The whole-tensor follow-up fails output identity on the first cycle after
2034
+ owner disposal, although active memory returns to zero and the source tensor
2035
+ still matches the untouched original artifact. The earlier small view did
2036
+ not qualify for unary buffer donation: MLX also bounds excess backing-buffer
2037
+ bytes. Thus those passing cases did not establish donation safety. Keep this
2038
+ read-only loader out of production; reduce the failure on scratch data and
2039
+ test writable private mappings with native lifetime ownership. Evidence:
2040
+ `mmap-weights-whole-consumer-lazy.json`, its log and
2041
+ `mmap-whole-consumer-source-integrity.json`. Full serving, default-scheduler
2042
+ and pressure gates remain for any corrected loader.
2043
+
2044
+ Scratch files isolate the failure across float32/bfloat16 and aligned/offset
2045
+ views. With a retained root, all read-only cases are exact and output uses a
2046
+ separate buffer. After root release, all four donated read-only cases return
2047
+ the original input bytes instead of the negation. Private writable mappings
2048
+ preserve every output, including donation, and leave each file unchanged.
2049
+ Evidence: `mmap-donation-{ro,cow}-screen.json`. The corrected prototype gives
2050
+ each private page window a native payload destructor that unmaps it on the
2051
+ last MLX buffer release. It uses no JavaScript destructor or new production
2052
+ API. All eight scratch ownership cases preserve output and file bytes, retain
2053
+ the mapping through the live consumer, and release every mapping afterward.
2054
+ Three full-artifact cycles then preserve the whole-tensor lazy negation after
2055
+ weight disposal. Only its 1,654,784-byte mapping survives until the pending
2056
+ consumer is disposed; native mapping counts and MLX active bytes return to
2057
+ zero before GC. Evidence: `mmap-managed-donation-screen.json` and
2058
+ `mmap-weights-managed-whole-consumer-lazy{,-mapping}.json`. A further 64-cycle
2059
+ scratch gate submits chained operations asynchronously and disposes the
2060
+ input handles. Half the cycles check every output value; the others dispose
2061
+ the final output before synchronization. All release every native mapping and
2062
+ return MLX active memory to zero. Evidence: `mmap-managed-submitted.json`.
2063
+ Six subsequent private-mapping native blocks on the M4 Pro 24 GB preserve 60 full-forward
2064
+ logit/state/continuation cases and 12 8/64-token generation comparisons, with
2065
+ fixed sources, clean exits and zero remaining native mapping windows. The
2066
+ 64-token warm generation median paired wall-time change is +0.02%; TTFT is
2067
+ +0.13%. Warm full forwards at M1/4/8/128/512 have no useful consistent speed
2068
+ gain. The opening-plus-first-hidden-forward phase is about 7.38 seconds slower
2069
+ by median paired difference, but that observation materializes different
2070
+ amounts of the model. After the hidden-only forward, native head tensors are
2071
+ still lazy while mapped roots already account for their full extent. The
2072
+ 727,580,672-byte active-allocation difference is exactly the 715,161,600-byte
2073
+ head plus 12,419,072 bytes of page padding, in all six pairs. Large changes in
2074
+ RSS and `vmmap` physical-footprint accounting still do not establish how much
2075
+ system RAM is saved. Child wall time includes `vmmap` inspection and is not a
2076
+ performance metric. Evidence is
2077
+ `mmap-weights-managed-native-repeat{,-review}.json` and
2078
+ `mmap-initial-residency-attribution.json`.
2079
+
2080
+ A separate lazy-view control removes per-tensor evaluation and pointer checks
2081
+ from loading. All 64 unsubmitted consumers and 64 submitted consumers remain
2082
+ valid after releasing their weight owners, then release every mapping and
2083
+ return active allocation to zero without forced GC. Its model screen preserves
2084
+ ten full-forward cases and both generations, but warm 64-token generation is
2085
+ +0.22% slower and the first hidden-forward phase does not improve. This rules
2086
+ out retaining the lazy change on that screen; it does not isolate the cause
2087
+ of the first-use cost. Evidence is
2088
+ `mmap-lazy-view-ownership.json` and
2089
+ `mmap-weights-lazy-managed-native-screen{,-review}.json`. Neither prototype is
2090
+ integrated.
2091
+
2092
+ A subsequent four-arm screen measures opening the model through the first
2093
+ generated token, completing all 64 tokens, then a warm 64-token generation.
2094
+ Native loading, lazy private mappings, mapped pages with an OS read-ahead
2095
+ hint, and mapped pages read once per page preserve all token IDs, live state
2096
+ and usage, then release every mapping. On the M4 Pro 24 GB, native first-token
2097
+ time from opening is 14.09 seconds; lazy mapping is 13.62 seconds, read-ahead
2098
+ 19.97 seconds and explicit reads 30.50 seconds. These timings include the
2099
+ preparation itself. Warm generation is approximately flat. The two CPU
2100
+ preparation methods lose this screen. Lazy mapping's small first-generation
2101
+ gain needs balanced repeats: this is one fixed-order block with unpurged
2102
+ filesystem cache. Neither a cold-storage result nor a physical-memory saving
2103
+ is established. Evidence is `mmap-prefault-native-screen.json`.
2104
+
2105
+ The balanced follow-up rejects that apparent cold-generation gain. All six
2106
+ fresh-process pairs preserve both 64-token generations, live state and usage,
2107
+ with fixed sources, clean exits and all 758 mappings released. First-token
2108
+ time from opening is worse in five pairs: the median paired change is +18.42%
2109
+ or +2.24 seconds. Completing the first generation is +12.93% or +2.29 seconds;
2110
+ warm generation is approximately flat at +0.24%. One large native outlier
2111
+ remains in the report. The filesystem cache is unpurged and the machine is
2112
+ not quiet, so these are diagnostic results. RSS accounting falls sharply for
2113
+ file-backed pages but physical-memory savings are still unproven. Close this
2114
+ loader as a performance candidate on the measured workload; no integration
2115
+ or HTTP speed claim follows. Closed loader, page-preparation and ownership
2116
+ helpers are removed; raw plans and evidence remain in
2117
+ `mmap-cold-native-repeat{,-review}.json`.
2118
+
2119
+ The first full-model pair with native private mappings preserves prefix state,
2120
+ all ten checked logit/live-state/continuation cases and both 8/64-token
2121
+ generation sequences. Sources remain fixed; both children exit cleanly and
2122
+ the mapped child releases all 758 native windows before exit. Its 64-token
2123
+ wall time is approximately flat. This single pair is a correctness screen,
2124
+ not a performance acceptance. Evidence:
2125
+ `mmap-weights-managed-native-screen{,-review}.json`. Repeated native/HTTP,
2126
+ and pressure gates still apply. A subsequent API ownership gate preserves
2127
+ pending-consumer output and rematerialized source bytes after `release`,
2128
+ `releaseShard` and `dispose`. It rejects a late view change and releases the
2129
+ mapping after an intentional tensor-fixup failure. All native mapping counts
2130
+ and MLX active bytes return to zero. Evidence:
2131
+ `mmap-managed-shard-release{,-mapping}.json`.
2132
+
2133
+ Next: finish MTP and strict-fill request measurements after the kernel
2134
+ changes, broaden their correctness and state audits, and obtain individual
2135
+ kernel attribution. Continue shared GDN/convolution/affine/prefill work and
2136
+ the exact-artifact controls across quants. Quiet application A/Bs, pressure
2137
+ replay and quiet M4 Pro gates remain. Recheck process ownership and preflight
2138
+ before each GPU run; diagnostic measurements cannot promote a default.
2139
+
2140
+ The native-owned managed mapping is visible to MLX allocation accounting.
2141
+ Across all ten full-model rows in its paired screen, mapped peak allocation
2142
+ exceeds the incumbent by exactly 12,419,072 bytes, the difference between
2143
+ page-aligned root and payload bytes. The low process RSS is not evidence of
2144
+ an unaccounted model in the async-scheduling threshold. Combining these
2145
+ experiments still needs a separate pressure gate. Evidence:
2146
+ `mmap-managed-active-accounting-review.json`.
2147
+
2148
+ A dedicated KV append dispatch probe covers 18 bf16 cases with four KV heads
2149
+ and dimension 256, at depths 65/256/2049/2048/8193/8192. Every active prefix,
2150
+ new row and retained snapshot remains exact; explicit cleanup returns MLX
2151
+ active allocation to zero. With spare capacity and no retained view, each
2152
+ SliceUpdate dispatches only the new-row copy. Holding an evaluated temporal
2153
+ view adds a full-buffer copy; releasing it restores donation. At a 256-step
2154
+ growth boundary, the pair allocates padding, concatenates old/new storage
2155
+ and appends, totaling eight dispatches regardless of retained views. This
2156
+ rejects the assumption that ordinary cache append always copies the full
2157
+ buffer. The next gate is a real-generation census of retained views and
2158
+ growth; instrumented one-shot timings do not establish a speed win. Evidence:
2159
+ `kv-append-donation-probe{,-review}.json` and its native dispatch log.
2160
+
2161
+ A real native-generation census on the interleaved v13 artifact uses a
2162
+ 2,049-token synthetic prompt and 32 generated tokens. Without a prompt
2163
+ snapshot, all 1,024 observed one-row K/V appends dispatch only the new-row
2164
+ copy. Retaining a real `cloneKvCaches` snapshot produces 32 full-buffer copies,
2165
+ one per K/V buffer, then 992 new-row-only appends. Both runs emit identical
2166
+ IDs with fixed sources. This rejects a repeated whole-cache copy in the
2167
+ tested native path; serving, deeper contexts and other cache types remain
2168
+ separate coverage. The counter build is for attribution, not timing claims.
2169
+ Explicit cleanup leaves 16,390 active bytes, so this is not a zero-allocation
2170
+ claim. Evidence: `kv-append-model-trace-2049{,-review}.json` and its dispatch
2171
+ log under campaign reports.
2172
+
2173
+ The actual HTTP census confirms the same append behavior at a verified
2174
+ 2,049-token text prompt. Serial and continuous servers each complete two
2175
+ 16-token warmups and a 32-token measured response. All three paired outputs,
2176
+ counts and finish reasons match, the continuous lane is verified, and both
2177
+ servers exit cleanly with fixed source. Each measured request has 1,024
2178
+ one-row K/V update encoders, all writing only the new row; neither performs
2179
+ a full-buffer copy for those appends. No matching update records fall outside
2180
+ the request phase markers. This rejects a repeated whole-cache-copy hypothesis
2181
+ for both tested HTTP lanes with prefix caching disabled. Deeper context,
2182
+ retained snapshots, growth boundaries and compressed caches remain separate
2183
+ regimes. The original token-array HTTP fixture was correctly rejected by the
2184
+ endpoint; the corrected text fixture is encoded and hashed by the Bun
2185
+ tokenizer before tracing. Evidence is
2186
+ `kv-append-http-text-census{,-review}.json` and its per-server dispatch logs.
2187
+
2188
+ The native census also passes at an 8,193-token prompt with 32 generated
2189
+ tokens. Ordinary ownership again gives 1,024 new-row-only K/V writes. A held
2190
+ snapshot gives 32 whole-buffer copies followed by 992 new-row-only writes.
2191
+ The two runs emit identical IDs, cover the same 8,224 cached tokens, keep
2192
+ sources fixed and return to 16,390 active bytes after explicit cleanup.
2193
+ Each phase also contains 480 larger prefill updates. These counts classify
2194
+ `SliceUpdate` encoders only; allocation/growth and copy traffic in other
2195
+ operations remain separate measurements. Evidence is
2196
+ `kv-append-native-8193{,-review}.json` and its dispatch log. There is no timing
2197
+ claim or new append kernel from this attribution result.
2198
+
2199
+ ### 7.9 Project kernel coverage
2200
+
2201
+ The initial AST inventory contains 35 custom Metal kernel construction sites
2202
+ and 355 calls into 162 distinct MLX C APIs. The API count includes allocation,
2203
+ configuration and graph operations; it is not a count of native GPU kernels.
2204
+ Runtime specializations still need shape, dtype, layout and stream coverage.
2205
+ The complete construction-site list, source hashes and per-site evidence are
2206
+ `reports/qwen38-rd/project-kernel-inventory.json` and
2207
+ `project-kernel-coverage.json`. Every site remains open for broader coverage.
2208
+ Variant 13 adds the 36th construction site; its source hash and evidence are
2209
+ in `project-kernel-vector-expand-addendum.json` alongside that initial census.
2210
+ Joint TurboQuant K/V decoding adds the 37th. A refreshed construction-site
2211
+ census and its evidence are in `project-kernel-turboquant-addendum.json`.
2212
+ The narrowly selected inverse-rotation kernel adds the 38th; the refreshed AST
2213
+ census is `project-kernel-inverse-addendum.json`.
2214
+ The MLX 0.32.2 Trellis small-prefill port adds the 39th. Its refreshed census
2215
+ and gates are in `project-kernel-wide-addendum.json` and §7.12.
2216
+ Consolidating the runtime removes the two old-core affine construction sites.
2217
+ The current AST census has 37 sites in 15 files; frozen controls retain the
2218
+ retired kernels. Evidence: `project-kernel-consolidated-census.json`.
2219
+
2220
+ | Owned kernel family | Sites | Current evidence and next coverage |
2221
+ |---|---:|---|
2222
+ | Packed grammar mask | 1 | Exact micro and HTTP outputs; serving timing inconclusive under external load. |
2223
+ | Joint TurboQuant K/V decoding and selected inverse rotation | 2 | Experimental opt-in; exact operation/lifetime and R6/RTN4 integrated model gates pass on MLX 0.32.2. Integrated inverse-rotation HTTP passes six pairs per quant with decode gains in every pair; R6 complete time improves and RTN4 complete time is inconclusive. Six deferred-consumer pairs per MiniCPM/Gemma also improve complete requests on consolidated source. Combined/pressure and quiet acceptance remain. Direct packed-key attention is exact but slower. Details live in turboquant.md. |
2224
+ | Flash attention forward, D, dKV and dQ | 4 | D256 alternative screen fails one KL gate; other attention shapes and backward costs remain. |
2225
+ | GLM sparse-attention rank and contract keys | 2 | Both keys now use uint32 with stable score sorting. Operation and complete tiny-model state gates pass; six balanced pairs per shape improve selection latency. Real Colibri serving remains unmeasured. |
2226
+ | GLM q4/q8 streamed expert gate/up and down | 4 | Synthetic resident-slot geometry screen and six balanced repeats preserve intermediate/output bytes and cleanup. BF16 timing is bimodal across identical process configurations; no geometry default retained. Attribute that variation before further timing claims. Real model and I/O overlap remain unmeasured. |
2227
+ | Qwen causal convolution, SiLU and copied tail | 1 | Exact operation/model/state gates; fusion has no compelling full-model speed win. |
2228
+ | Gated recurrent update | 1 | Unrolling, geometry, compilation and normalization fusion screened; full-model gains too small to retain. |
2229
+ | Qwen multimodal rotary embedding | 1 | Direct-stride fusion preserves operation/model state, but the complete-forward gain is too small to retain. Actual image/video HTTP coverage remains. |
2230
+ | Trellis reduce, scatter, expand and gate/up variants | 9 | Shared rows and fusion improve measured cells. Device codebook lookup loses. A scoped threadgroup integer table improves repeated M3/4 scatter, full forwards and MTP HTTP requests with exact outputs; M1 loses and stays procedural. Scheduling and prefill controls remain. Broader bit/axis/shape/model coverage remains. |
2231
+ | Trellis split-K projection and accumulation | 2 | Short-prefill model/serving acceptance; larger shapes and additional artifacts remain. |
2232
+ | Trellis tiled projection | 1 | Short axis-1 tiles accepted diagnostically; larger tiles, context and memory pressure remain. |
2233
+ | Trellis native-wide prefill | 1 | Matches MLX 0.32.2 small-prefill arithmetic on eligible GPUs. Operation, integrated R6 state/generation and six HTTP pairs per lane pass. Short-prefill TTFT improves; broader context and quiet acceptance remain. |
2234
+ | Trellis vectorized expansion | 1 | Exact operation, full-model prefill and HTTP responses. Shorter serial and default-scheduler HTTP prefills improve; existing-suite timing mostly flat. Broader context, pressure and quiet M4 Pro gates remain. |
2235
+ | Cross-entropy forward/backward variants | 7 | All seven routes pass the vocabulary-partition screen, including 54 forced-fallback cases. The isolated fast-dispatch opportunity does not apply to the available models wired into this loss path; broader real-loss profiling remains. |
2236
+
2237
+ The native-operation audit covers quantized/dense/gather matmul, SDPA,
2238
+ normalization, rotary embeddings, elementwise activation, convolution,
2239
+ reductions/sorts, indexing and scatter, quantization/dequantization, Hadamard
2240
+ transforms, sampling, copies and cache growth. Account for compiled graph
2241
+ boundaries, custom VJPs, host readbacks, allocator work and serialization.
2242
+ An operation can remain native after a measured negative result; replacing
2243
+ every kernel is not the exit criterion.
2244
+
2245
+ An explicit codebook lookup does not improve the tested packed decode
2246
+ kernels. The corrected screen preserves all 69 cases per candidate using
2247
+ float32 integer values, int16 integer values or pre-scaled float32 values.
2248
+ It covers reduce, both scatter layouts and fused gate/up across f32, f16 and
2249
+ bf16, including the M4/5 fallback boundary. All four processes return active
2250
+ allocation to zero. At the large Qwen M1 bf16 projections, even the int16
2251
+ table takes 0.802 ms versus 0.331 ms for reduce, 0.747 versus 0.443 ms for
2252
+ scatter, and 1.474 versus 0.615 ms for gate/up. These diagnostic operation
2253
+ losses close the candidate before full-model testing. No lookup cache or
2254
+ kernel is added to production.
2255
+
2256
+ The first prototype changed the shared lookup table and failed dense-fallback
2257
+ identity at M5/8. That fallback uses a precisely divided table, while the
2258
+ packed matvec preserves the procedural decoder's multiply order. The corrected
2259
+ prototype keeps the original expansion table and replaces both macro and
2260
+ inline decode sites. Retain the initial failure and the corrected exact
2261
+ negative result separately. Evidence is `trellis-codebook.json` and
2262
+ `trellis-codebook-scoped{,-review}.json`.
2263
+
2264
+ The distinct threadgroup-table follow-up leaves a narrower M3/4 scatter
2265
+ candidate open. Six full-model and six MTP serving pairs preserve outputs
2266
+ with small gains. Its results, unchanged-prefill controls and scope live in
2267
+ [turboquant.md](turboquant.md). It does not justify a one-token decode change.
2268
+
2269
+ A separate Metal constant-address-space table also loses at M1. Two balanced
2270
+ pairs use the actual R6 packed projections, identical tensor hashes and the
2271
+ same synthetic activation seed. A 4,096-entry int16 table nearly doubles
2272
+ complete MLP latency in both orders on the M4 Pro with MLX 0.32.2. All four
2273
+ workers exit normally and source hashes remain fixed. The benchmark's internal
2274
+ v13-versus-v13 check does not compare output bytes across source arms, so this
2275
+ is a rejected speed screen, not a correctness-qualified implementation. No
2276
+ full-model run or production change follows. An earlier accidentally
2277
+ overlapped pair was terminated and excluded. Evidence:
2278
+ mlx-upgrade-0.32.2/trellis-constant-{screen,review,invalid-attempt}.json.
2279
+
2280
+ The four streamed-expert kernels now have a synthetic resident-slot screen.
2281
+ It covers Q4/Q8, bf16/f32, M1/2/4/8 and H/I=32/32 plus 6144/2048. The larger
2282
+ dimensions come from the documented Colibri slot size and need confirmation
2283
+ against actual artifact metadata. One, two, four and eight SIMD groups per
2284
+ threadgroup preserve every gate/up intermediate and final SwiGLU output byte
2285
+ in 96 candidate comparisons. All four processes return active allocation to
2286
+ zero. This excludes disk I/O and full-model execution.
2287
+
2288
+ Six balanced repeats at the larger dimensions preserve another 288 comparisons
2289
+ across 24 fresh processes, again with zero final active allocation. The large
2290
+ first-screen bf16 gains do not establish a retained geometry. Identical Q4 M2
2291
+ controls vary from about 0.29 to 0.58 ms; Q8 M1 controls vary from about 0.24 to
2292
+ 0.51 ms. Some candidate/control pairs reverse by nearly 2x. Float32 is much
2293
+ steadier and generally flat across geometries. Attribute this bf16 timing
2294
+ variation before further optimization claims. No geometry default changes.
2295
+ These are M4 Pro 24 GB diagnostics. Real Colibri serving remains unavailable;
2296
+ the local GLM-5.3-Flash artifact uses a different architecture. Evidence:
2297
+ `streamed-expert-screen{,-review}.json` and
2298
+ `streamed-expert-repeat{,-review}.json`.
2299
+
2300
+ Four identical four-SIMD-group processes with the normal-scheduling recorder
2301
+ preserve all 64 cell outputs and return active allocation to zero. The bf16
2302
+ timings are stable in this instrumented sample: Q4 M2 is 0.288–0.293 ms and
2303
+ Q8 M1 is 0.240–0.244 ms. GPU command-span union per call is about 0.222 and
2304
+ 0.177 ms respectively, with no measured gaps between command spans. This
2305
+ does not capture the slow regime seen with the normal library, so it cannot
2306
+ explain that variation. The recorder uses a separately built MLX library;
2307
+ its wall timings cannot select the production geometry. Preserve the
2308
+ inconclusive verdict until the real workload or a control captures both
2309
+ regimes. Evidence: `streamed-expert-trace{,-review}.json`.
2310
+
2311
+ Six balanced same-geometry blocks compare the stock library, the separate
2312
+ build with recording disabled, and that build with recording enabled. All
2313
+ 192 candidate comparisons preserve intermediate/output bytes and every
2314
+ process releases its active allocation. The bf16 variation occurs in all
2315
+ three arms. Recorder timestamps now capture both regimes: the Q4 M2 median
2316
+ command span per complete operation ranges from 0.230 to 0.658 ms, and Q8 M1
2317
+ from 0.177 to 0.451 ms. Each measured buffer still has sixteen dispatches for
2318
+ eight complete operations. Some transitions happen within one process. This
2319
+ rules out host overhead alone; command spans include waits and do not isolate
2320
+ the underlying GPU cause. No geometry or library change is retained. Evidence:
2321
+ `streamed-expert-library{,-review}.json` and
2322
+ `streamed-expert-library-span-review.json`.
2323
+
2324
+ The sparse-selection screen reduces the contract-order key from uint64 to
2325
+ uint32: the above-threshold class needs one bit and valid MLX positions fit
2326
+ in the remaining 31 bits. The score-ranking key is initially unchanged.
2327
+ All 75 cases preserve selected positions and threshold bits, covering several
2328
+ context/selection sizes, ties, signed zero and nonfinite values. Finite inputs
2329
+ also match the host contract. Each case releases every active native byte.
2330
+ Six AB/BA blocks at the deployed topK of 2,048 then preserve all 90 paired
2331
+ cases. Median selection latency improves about 2–9%, or 28–39 microseconds,
2332
+ on the M4 Pro 24 GB; every pair improves. This is the complete selection
2333
+ operation, not model-generation or serving throughput. Evidence is
2334
+ `dsa-order-u32-screen.json` and `dsa-order-u32-repeat{,-review}.json`.
2335
+
2336
+ The pinned MLX implementation explains the crossover: uint64 sort keys use
2337
+ smaller blocks, so a 2,048-key sort takes the multi-block path. It also sends
2338
+ GPU `argpartition` through a full merge sort. MLX's documented stable
2339
+ `argsort` permits a second reduction: retain the 32-bit descending IEEE score
2340
+ key and let stability preserve ascending positions for equal score bits.
2341
+ Use `argsort` explicitly for that guarantee. This preserves the existing
2342
+ special-value ranking, without relying on stability from the partition API.
2343
+ Primary sources are [MLX 0.31.2 sorting](https://github.com/ml-explore/mlx/blob/v0.31.2/mlx/backend/metal/sort.cpp)
2344
+ and its [stable-sort contract](https://github.com/ml-explore/mlx/blob/v0.31.2/mlx/ops.h).
2345
+ The combined prototype passes the same 75 cases. Six balanced blocks then
2346
+ preserve all 90 paired cases and improve every pair: median selection latency
2347
+ falls 10.47–15.80% across the tested context/pattern cells. Ordinary score rows
2348
+ save about 48 microseconds at 2,049 positions and 218 microseconds at 262,144.
2349
+ All native active bytes are released. Evidence is
2350
+ `dsa-rank-u32-screen.json` and `dsa-rank-u32-repeat{,-review}.json`.
2351
+
2352
+ The complete deterministic tiny-model comparison also preserves all six
2353
+ teacher-forced/greedy/sampled cases at topK 1 and 2,048: every logit byte,
2354
+ requested log probability, selection, cache state and usage record agrees.
2355
+ Each arm executes 76 sparse selections and returns active memory to zero.
2356
+ Existing model tests cover cache restore, mixed-length batching, streamed
2357
+ execution, MTP and HTTP. A separate execution check confirms the transformed
2358
+ module is used: all 34 tests pass. Evidence is `dsa-model-screen.json` and
2359
+ `dsa-rank-u32-model-tests-v2{.txt,.transform.json}`. Bun's test run did not write
2360
+ the initial process-exit observer file, so the second run asserts coverage
2361
+ inside a test instead. The local artifact scan finds no compatible Colibri
2362
+ configuration; the available GLM-5.3 Flash is `glm5_next`, not this
2363
+ `glm_moe_dsa` path. Real-artifact serving remains open.
2364
+
2365
+ The exact representation change is integrated in the existing DSA module
2366
+ without another flag or interface. A permanent 8,193-position test checks
2367
+ threshold ties on strided float32/float16/bfloat16 inputs. The first test run
2368
+ uses the wrong import location for `Dtype`; after correcting that test import,
2369
+ all 34 focused production tests and the three typechecks pass. Evidence is
2370
+ `dsa-production-unit-v2.txt` and `dsa-production-typecheck-v2.txt`. The complete
2371
+ model-free suite also passes: 1,840 passed, 10 skipped and zero failures, with
2372
+ hygiene passing. Evidence is `dsa-production-model-free.txt` and
2373
+ `dsa-production-hygiene.txt`. This is a measured shared-operation improvement;
2374
+ it is not a Qwen throughput claim.
2375
+
2376
+ The top-p sampling audit finds a removable inverse-permutation construction.
2377
+ Keep the incumbent probability calculation, ascending sort and cumulative
2378
+ sums, then scatter the cutoff mask directly to token positions. A pure MLX
2379
+ mask scatter and a fused Metal output scatter preserve every output byte in
2380
+ 216 cases across four vocabularies, three dtypes, three cutoffs, strided
2381
+ inputs, ties and nonfinite values. The initial run stops at its cleanup
2382
+ assertion on case 109: the current path intentionally caches the large
2383
+ `arange` used for inversion. Fresh-process probes attribute the retained
2384
+ 524,288/999,424 bytes to those index arrays, while both candidates release all
2385
+ active bytes. This is an existing cache, not a disposal failure.
2386
+
2387
+ The corrected screen prewarms that range cache and checks cleanup against
2388
+ its measured baseline. The pure MLX rewrite is mostly flat; the fused kernel
2389
+ has a modest operation-level gain. Compiling all three versions also
2390
+ preserves all 216 cases, with exactly one trace per compiled function and
2391
+ the expected remaining range-cache bytes. Evidence is
2392
+ `top-p-scatter-screen-v2{,-review}.json`,
2393
+ `top-p-scatter-compiled-screen{,-review}.json` and
2394
+ `top-p-lifetime-{source,native,scatter,metal}.json`. The subsequent sampler,
2395
+ model and HTTP gates below determine retention. The production sampler is
2396
+ unchanged.
2397
+
2398
+ The full seeded sampler screen then passes 180 cases across three vocabularies
2399
+ and dtypes, four finite/masked distributions, both seeds and four step indices.
2400
+ Top-p alone and its production combinations with top-k, min-p and XTC preserve
2401
+ all sampled IDs in six implementations. All 54 compiled functions trace once;
2402
+ disposal leaves only the incumbent range cache. The initial attempted B=3
2403
+ case fails in the incumbent: this sampler's contract is one `[1,V]` row, as
2404
+ used by sampled serving. That failed probe is retained. Evidence is
2405
+ `top-p-sampler-screen-v2{,-review}.json`.
2406
+
2407
+ The initial complete-generation screen passes 60 generations on Llama 1B and
2408
+ Qwen packed/RTN4. Emitted IDs, requested log probabilities, live cache bytes
2409
+ and usage agree. The packed quant's complete sampled timings are effectively
2410
+ flat. RTN4's compiled-fusion arm also has a slower untouched greedy control,
2411
+ so its timing needs a repeat before attribution. These are screens, not
2412
+ retention evidence. Evidence is `top-p-native-screen{,-review}.json`.
2413
+
2414
+ The actual HTTP screen passes 126 requests across 18 fresh servers, preserving
2415
+ all 84 paired responses and usage records on serial and continuous execution.
2416
+ A research-only default-seed provider returns 42 in both arms. Requests omit
2417
+ the explicit seed field, which would select serial execution; placement is
2418
+ unchanged and the continuous lane/submitted-row counters are asserted.
2419
+ The apparent packed serial improvement does not survive six balanced pairs:
2420
+ all 30 paired responses remain exact, but complete sampled request time is
2421
+ 0.183% higher at the median and only one pair is faster. The untouched greedy
2422
+ control moves by +0.058%. These M4 Pro diagnostic results do not justify
2423
+ retaining the fusion for Qwen. Evidence is `top-p-http-screen{,-review}.json`
2424
+ and `top-p-http-r6-serial-repeat{,-review}.json`.
2425
+
2426
+ Llama 1B's six balanced pairs per serving lane preserve all 84 paired
2427
+ responses across 168 requests. Top-p-only complete time decreases by 0.399%
2428
+ in serial and 0.380% in continuous serving, with all six pairs faster in each
2429
+ lane. Top-p plus top-k changes by -0.132%/-0.196%; greedy remains effectively
2430
+ flat. This is a small model-specific observation, not broad dispatch
2431
+ eligibility or a Qwen gain. Keep it in the evidence ledger while testing
2432
+ the complete graph's submission limits, traversal and synchronization.
2433
+ No production sampler flag or kernel is added. Evidence is
2434
+ `top-p-http-llama-repeat{,-review}.json`.
2435
+
2436
+ Kernel timing is only a screen. Retention requires complete native generation
2437
+ and actual serial/continuous HTTP comparisons at matched inputs, seeds and
2438
+ compute shapes. Measure TTFT, prefill, decode, complete request time and memory.
2439
+ When a fusion wins in isolation but loses in a request, inspect command-buffer
2440
+ and encoder boundaries, synchronization, buffer lifetimes and overlap with the
2441
+ next decode step. Capture traces separately from uninstrumented timing. A
2442
+ smaller dispatch count does not establish better scheduling or throughput.
2443
+
2444
+ The cross-entropy audit identifies two separate restrictions. The existing
2445
+ hidden-width guard rejects Qwen's 5,120-wide head before kernel dispatch;
2446
+ supporting that width is a separate task. For supported widths, vocabulary
2447
+ partitioning can disable both Steel routes even when the vocabulary is
2448
+ tile-aligned. Using the existing maximum block size of
2449
+ 8,192 as the stride, with the final block capped at the vocabulary length,
2450
+ keeps every tile in bounds. This fixed stride also avoids empty trailing
2451
+ blocks at larger vocabularies. Every forward
2452
+ and backward route must use the same partition, including block-skip metadata;
2453
+ merely weakening the dispatch guard would permit unsafe final-tile loads.
2454
+ The prepared head-only screen compares full-logit values and unfiltered
2455
+ gradients, retains already-aligned controls, and measures actual dispatch and
2456
+ allocation. Both initial arms pass 20 smaller cases and then hit the same
2457
+ existing Qwen width restriction. A supported-width continuation passes all
2458
+ 24 cases for 4/8-bit weights, varied token counts, softcap and boundary targets.
2459
+ Candidate loss and unfiltered gradients remain within the predeclared
2460
+ full-logit-reference tolerances; already-aligned forward controls retain
2461
+ identical bytes. All tracked arrays are released. The changed partition and
2462
+ kernel reduction order are not bit-exact to the old fallback. The isolated
2463
+ timing screen favors the fast route at Llama-sized head geometry, but repeated
2464
+ timing, actual-weight gradients, pruning and complete training/evaluation
2465
+ measurements remain. This establishes no inference gain. Protocol and evidence:
2466
+ `cce-block-alignment-plan.json`, `cce-block-alignment-{control,candidate}-screen.json`
2467
+ and `cce-block-alignment-supported-review.json` under campaign reports.
2468
+
2469
+ The follow-up forces SIMD, scalar and lane forward routes plus SIMD/scalar
2470
+ backward on both partitions. All 54 cases pass the same full-logit and
2471
+ unfiltered-gradient gates, including an unaligned vocabulary that must keep
2472
+ its fallback. Maximum log-probability error is 1.91e-6; maximum gradient
2473
+ relative L2 error is 1.12e-5. Every process returns to zero active bytes, with
2474
+ fixed source. Together with the Steel screen this exercises all seven kernel
2475
+ construction sites. Evidence is `cce-block-alignment-fallbacks{,-review}.json`.
2476
+
2477
+ The production call-site audit closes this candidate without integration on
2478
+ the current available workloads. `headQuant` in the loss path accepts Gemma4
2479
+ and MiniCPM5. The available Gemma heads have vocabulary 262,144 and block stride
2480
+ 8,192; MiniCPM5 has vocabulary 130,560 and stride 8,160. Both already satisfy
2481
+ the Steel alignment guard. The Llama geometries that improved in isolation
2482
+ are not wired into this loss helper. Changing their model support would be
2483
+ separate work, and changing an already-aligned partition would add numerical
2484
+ differences without the proposed dispatch benefit. Reopen if a supported
2485
+ model actually reaches a misaligned block partition. No inference, full-loss
2486
+ or training speedup is claimed; closed one-off helpers are removed after
2487
+ recording the result.
2488
+
2489
+ Local complete snapshots include Gemma e4b/12B/26B, diffusion Gemma, MiniCPM5,
2490
+ Llama 1B/3B, assistant heads and GLM weights. Snapshot/file availability is
2491
+ recorded in `reports/qwen38-rd/project-other-models.json`. Availability is not
2492
+ execution acceptance. The GLM artifact exceeds device memory and requires its
2493
+ streamed path; measure expert-slot kernels separately before full requests.
2494
+
2495
+ A broader 4-bit prototype supports float16 and inner dimensions outside the
2496
+ native fast-matvec regime. It must reproduce native dispatch's eight versus
2497
+ sixteen values per lane, including the matching reduction order; masking the
2498
+ old kernel's final loads alone is insufficient. All 320 synthetic dtype,
2499
+ shape and strided-input checks pass. Six full-model pairs per append length
2500
+ on Gemma 12B/e4b, MiniCPM5 and Llama 1B/3B preserve logits, live cache bytes
2501
+ and continuation, with fixed source hashes. Gemma 12B improves at M4/8;
2502
+ e4b improves at M8 but is approximately flat at M4. MiniCPM and both Llama
2503
+ models regress in eligible cells. This prototype is not integrated: qualify
2504
+ individual matrix shapes and full HTTP requests before widening dispatch.
2505
+ Evidence: `affine-shared-cross-model-exactness.json` and
2506
+ `affine-shared-cross-model-{gemma12,gemmae4b,minicpm5,llama1,llama3}-review.json`
2507
+ under `reports/qwen38-rd/`.
2508
+
2509
+ An actual-weight follow-up covers 44 matrix/append-length cases with exact
2510
+ outputs, six AB/BA pairs, and both repeated dispatch and dispatch after a
2511
+ scratch-memory sweep. Small attention projections generally favor native
2512
+ MLX; large float16 output-head matrices identify a narrower shared-kernel
2513
+ candidate. The initial Gemma 12B cells overlap an external Playwright/Node
2514
+ burst recorded by preflight and vary substantially. Retain that run but repeat
2515
+ those affected cells before deriving eligibility. Operation timing remains
2516
+ distinct from full-model and HTTP acceptance. Evidence:
2517
+ `affine-cross-model-matrix-{inventory,screen,screen-review}.json` under the
2518
+ campaign report directory.
2519
+
2520
+ A separate Gemma 12B repeat, with more dispatches per timing sample, preserves
2521
+ all outputs and yields consistent improvements on its larger projections.
2522
+ The smaller projection remains marginal or slower. The repeat retains its
2523
+ own source hashes and machine observations; it does not replace the noisy
2524
+ run. Evidence: `affine-cross-model-matrix-gemma12-repeat.json`.
2525
+
2526
+ Restricting the float16 candidate to large output heads preserves every
2527
+ 32-step greedy stream, live cache byte and continuation on Llama 1B/3B.
2528
+ Six native pairs at B4/8 show small gains; B1 is flat. Six fresh-process HTTP
2529
+ pairs per model then preserve all 312 paired responses, including usage and
2530
+ finish reasons, with observed B4/8 overlap and clean server exits. The B8
2531
+ serving gain is modest on 1B and below one percent on 3B; single-request
2532
+ timing is flat. B4 is inconclusive. This does not justify widening production
2533
+ dispatch. Both arms disable the existing shared-affine flag, and the candidate
2534
+ pays its eligibility checks. The first two HTTP attempts failed overlap
2535
+ qualification and remain excluded. Evidence:
2536
+ `affine-head-batched-decode-mfirst-{llama1,llama3}-review.json` and
2537
+ `affine-shared-head-http-{llama1,llama3}-overlap-review.json`. These M4 Pro
2538
+ diagnostics do not replace quiet-machine acceptance. Closed head-only helpers
2539
+ are removed; the broader operation's eligibility work remains open.
2540
+
2541
+ A bf16-only selection uses large projections and leaves small matrices on
2542
+ native MLX. The first selection preserves six full-model pairs per length on
2543
+ Gemma 12B/e4b. Expanding the 12B selection to its other positive matrix shapes
2544
+ preserves every checked logit, live cache byte and continuation. Both models
2545
+ improve at M8; 12B also improves at M4. A 32-step fixed-B 12B repeat confirms
2546
+ identity and the batched gain. Single-token controls are approximately flat.
2547
+ The initial raw-completion HTTP comparison fails response identity at B4,
2548
+ with differing admission histories and mostly repeated-character output in
2549
+ both arms. Templated chat produces coherent text but also fails response
2550
+ identity on its third B8 pair. A live diagnostic then compares every selected
2551
+ projection against native MLX on the same inputs. All 36,704 operations are
2552
+ byte-identical, including both M4 and M8, and both servers exit cleanly.
2553
+ Those synchronizations invalidate its timing. A native A/A control with the
2554
+ candidate disabled in both servers reproduces the same wording difference
2555
+ when the second arm staggers arrivals by one millisecond per request. Both
2556
+ servers exit cleanly, with stable sources and zero candidate calls. Thus the
2557
+ response variation also occurs without the candidate; it is not evidence of
2558
+ a candidate-only arithmetic error. Preserve both failed response gates.
2559
+ Subsequent timing pairs retain every difference and require single-request
2560
+ text identity, all usage/finish invariants and the independent same-input
2561
+ numerical gates. Do not claim multi-request response identity when it fails.
2562
+ Evidence:
2563
+ `affine-large-projection-full-model-{gemma12,gemmae4b}-review.json`,
2564
+ `affine-large-projection-v2-full-model-gemma12-review.json`,
2565
+ `affine-large-projection-batched-decode-gemma12-review.json` and
2566
+ `affine-large-projection-http-gemma12.json`,
2567
+ `affine-large-projection-chat-http-gemma12.json` and
2568
+ `affine-large-projection-verify-http-gemma12.json` and
2569
+ `affine-large-projection-chat-http-native-control-gemma12.json`.
2570
+ Six subsequent 12B timing pairs complete with stable sources, clean server
2571
+ exits and all 156 paired responses identical in that run. Both observed B4
2572
+ and B8 improve in every pair; B1 is approximately flat. Earlier response
2573
+ failures remain part of the evidence. See
2574
+ `affine-large-projection-chat-http-qualified-gemma12-review.json`.
2575
+ The next control adds only large 4-bit bf16 projections whose K is divisible
2576
+ by 256 but not 512, with M4/8 and both K and N at least 3072. The existing production
2577
+ shared-affine flag is enabled in both arms, including its 3/8-bit kernels.
2578
+ Six native pairs per append length preserve all logits, live states and
2579
+ continuations. Both M4 and M8 improve in every pair; M1 and M128 controls are
2580
+ approximately flat. The candidate exercises 105 additional projections at
2581
+ M4/8. Evidence: `affine-nonfast-large-full-model-gemma12-review.json`.
2582
+ The existing opt-in 4-bit kernel now selects native eight- or sixteen-value
2583
+ lane arithmetic for those shapes. The flag remains off by default, and the
2584
+ 3/8-bit selection remains restricted to its original shapes. Large nonfast
2585
+ output heads with N≥65536 remain native because no such head has passed the
2586
+ model/serving performance gate. This does not change the measured Gemma
2587
+ projection selection. Focused tests
2588
+ cover strided activations/metadata, compiled replay and native fallback.
2589
+ The integrated version preserves six full-model pairs per append length and
2590
+ improves M4/8. Six further production HTTP pairs improve B4/8 in every pair,
2591
+ with single-request timing approximately flat, fixed sources and clean exits.
2592
+ Two B8 warmup responses exhibit the same wording difference as the prior
2593
+ native A/A control. All usage and finish invariants match; whole-response
2594
+ identity does not hold for that run. Preserve those differences and the
2595
+ independent numerical gates. Evidence:
2596
+ `affine-nonfast-integrated-full-model-gemma12-review.json` and
2597
+ `affine-nonfast-integrated-chat-http-gemma12-review.json`.
2598
+ Live same-input verification then checks all 50,149 selected 4/8-bit operations
2599
+ against native MLX with identical bytes, fixed sources and clean exits. Its
2600
+ synchronizations invalidate timing. Evidence:
2601
+ `affine-nonfast-integrated-verify-http-gemma12-review.json`. Six complete
2602
+ flag-off/flag-on HTTP pairs also improve B4/8 in every measured pair, with
2603
+ approximately flat single-request throughput, fixed sources and clean exits.
2604
+ Two B8 warmup responses differ; preserve those alongside the live numerical
2605
+ gate. All usage and finish invariants match. Evidence:
2606
+ `affine-nonfast-integrated-chat-http-native-gemma12-review.json`. This does not establish a gain
2607
+ for smaller models or justify enabling the flag across model families. Superseded projection and verification
2608
+ helpers are removed after recording their findings; the incumbent comparison
2609
+ helpers are removed after the native-flag control completes.
2610
+
2611
+ One shared candidate is launch-configuration reuse. The current wrapper
2612
+ recreates output/template/grid configuration on every custom-kernel call.
2613
+ [mlx-c v0.6.0's implementation](https://github.com/ml-explore/mlx-c/blob/v0.6.0/mlx/c/fast.cpp)
2614
+ copies that configuration into the apply call. A bounded per-kernel cache can
2615
+ therefore reuse it while keeping tensor inputs dynamic. Qualify changed shapes,
2616
+ template order, initialization, compile traces, eviction and disposal, then
2617
+ measure full models and HTTP. No default change follows from the source audit.
2618
+
2619
+ The first configuration-reuse prototype passes 160 changing shape/dtype
2620
+ checks plus compiled replay, eviction and disposal. Six packed-model pairs
2621
+ at M1/4/8/128 preserve logits, live cache bytes and continuation. Full-model
2622
+ timings are approximately flat, with unchanged peak allocation. Compact
2623
+ Qwen's affine control is also approximately flat. MiniCPM's single-forward
2624
+ samples vary; a 32-step fixed-B repeat preserves every token, live state byte
2625
+ and continuation with small B4/8 gains, but its unused B1 control also moves.
2626
+ The subsequent HTTP run fails response identity in a later B8 wave. Its two
2627
+ arms have different early admission histories. Six A/A pairs and six further
2628
+ pairs with deliberately staggered arrivals do not reproduce the mismatch.
2629
+ That leaves the cause unresolved; admission sensitivity is a hypothesis, not
2630
+ a finding. The changed response occurred in the cache-disabled arm. Close
2631
+ this prototype without integration: Qwen is approximately flat and MiniCPM
2632
+ does not pass the serving gate. The HTTP mismatch remains unresolved in the
2633
+ broader correctness coverage. Evidence:
2634
+ `reports/qwen38-rd/metal-config-cache-exactness.json` and
2635
+ `metal-config-cache-full-model-{packed,compact,minicpm5}-review.json`, plus
2636
+ `metal-config-cache-batched-decode-minicpm5-api-review.json` and
2637
+ `metal-config-cache-http-minicpm5.json`.
2638
+ The control reports are `metal-config-cache-http-minicpm5-control-review.json`
2639
+ and `metal-config-cache-http-minicpm5-admission-control-review.json`; their
2640
+ passing responses do not replace the failed A/B gate.
2641
+ Closed configuration-cache helpers are removed; raw reports remain.
2642
+
2643
+ The multimodal rotary audit identifies repeated angle evaluation across
2644
+ heads/layers and a contiguous-input requirement after Q/K transposes.
2645
+ Separate prototypes test shared float32 angles, direct stride reads, and both
2646
+ together. All 108 operation comparisons preserve bf16/f16/f32 bytes across
2647
+ partial/full rotary dimensions, multiple positions and strided inputs. A
2648
+ 16-layer Q/K schedule includes angle construction and uses distinct inputs
2649
+ per layer. Short-sequence variants lose; direct stride reads improve the
2650
+ prefill operation, while angle reuse alone is weaker. Timing varies within
2651
+ the sweep and the operation is a small part of a complete 27B forward.
2652
+ The full-body gate keeps shorter sequences native and uses fixed 3D
2653
+ positions. All 35 logit/state/continuation cases match, but M128 is slightly
2654
+ slower and M512 is approximately flat. Peak allocation decreases only
2655
+ slightly. Close the prototype without integration; the operation gain does
2656
+ not establish a useful complete-model gain. This gate excludes image encoding
2657
+ and is not a real vision-request benchmark. Text-only generation uses native
2658
+ fast RoPE. Evidence: `mrope-reuse-screen-review.json` and
2659
+ `mrope-stride-full-model-packed-review.json`. Closed helpers are removed; raw
2660
+ reports and source hashes remain.
2661
+
2662
+ The final M4 Pro bundle must record incumbent and candidate source hashes,
2663
+ local diff, Bun/native/oracle versions, model hashes, flags and workload files.
2664
+ Run the existing serving suite and native generation separately on the M4 Pro,
2665
+ with fixed cache conditions and all paired samples retained. Its existing
2666
+ numbers are historical controls until the workload and version metadata match.
2667
+
2668
+ ### 7.10 Final benchmark and HTML comparison report
2669
+
2670
+ After the optimization gates close, build and run a repeatable benchmark for
2671
+ the incumbent, combined finalists and retained quantizations on the M4 Pro.
2672
+ The benchmark must preserve the existing suite's measurements while making
2673
+ native generation, serving, memory and quality comparisons easier to inspect.
2674
+ Its protocol is frozen before final runs; the held-out Kanban task in section
2675
+ 7.7 remains a separate task evaluation and is never an optimization fixture.
2676
+
2677
+ Use Bun/TypeScript for orchestration, measurement, validation, statistics and
2678
+ HTML generation. Python is confined to launching or instrumenting the pinned
2679
+ MLX-LM/OptiQ reference. The mlx-bun arm loads and serves through the existing
2680
+ engine and request interfaces. Browser rendering is outside the timed engine
2681
+ and HTTP cells. Any later chat-UI profiling needs its own browser workload.
2682
+
2683
+ Extend the current native worker, serving measurements, machine preflight,
2684
+ artifact inventory and result persistence. Start from the serving suite's
2685
+ versioned raw JSON and existing report functions; extract shared functions
2686
+ only when both callers need them. Keep execution, comparison and HTML rendering
2687
+ separate. Rendering saved results must require neither model weights nor a
2688
+ running server, GPU, Python or network connection. Raw data remains portable
2689
+ between machines, and the SQLite store is an index rather than the only copy.
2690
+
2691
+ | Measurement group | Required cells and definitions |
2692
+ |---|---|
2693
+ | Single-request generation | Fixed token-ID prompts at the declared context depths, first emitted token, prefill time and processed tokens, sustained decode time, actual generated token count, total generation time and cleanup. Record computation boundaries so prefill throughput excludes unrelated loading or queue time. |
2694
+ | Single-request HTTP | Serial execution and actual continuous execution with one request. Measure request start to headers, first byte, first visible content or tool output, final output and stream completion. Preserve server phase timings where available. SSE chunks are not tokens; client-visible output gaps and native token intervals have separate names. |
2695
+ | Startup and reuse | Fresh-process readiness and first request, warm process with an uncached prompt, RAM prefix hit, SSD restore, exact continuation and edited-prefix miss. Record cache budget, persisted state and actual reused-token counts. A new process does not imply a cold filesystem cache. Page-cache-cold trials require an explicit controlled protocol. |
2696
+ | Sustained serving | Fixed arrival schedules and concurrency levels within each machine's capacity; per-request queue time, TTFT, completion latency, stream stalls, aggregate completed requests and output tokens per second, error rate and throughput meeting declared latency limits. Verify actual lane, admitted rows and batch occupancy; a seed option must not silently route a continuous test through serial execution. Include cancellation, recovery and long multi-turn cache pressure. |
2697
+ | Memory and resource use | Startup, prefill, decode, cache retention and post-disposal observations; peak server-process RSS, native active/peak allocations, allocator cache, KV and recurrent state, SSD cache size, system memory pressure and swap activity. Record sampler frequency and process ownership. Unified-memory and file-mapping accounting can change RSS without saving physical memory. Add energy only if supported measurement is calibrated and its overhead is excluded from ordinary timing. |
2698
+ | Fidelity and quality | Same-input logits and cache/state gates at matched compute shapes, generated IDs where available, output bytes, usage and finish reasons. Different quantizations carry artifact bytes, quality results and task failures alongside performance. Early EOS, reduced thinking or incomplete output cannot count as faster completion of the same work. |
2699
+
2700
+ For supported artifacts, pair each native/HTTP mlx-bun cell with the same
2701
+ artifact on the pinned MLX-LM reference. Pin tokenizer, template, sampler,
2702
+ seed, thinking, tools, budgets, cache state, prefill chunk/tail policy and
2703
+ wiring. Store both requested and effective configuration. Identical seeds
2704
+ alone do not establish equivalent graph shapes or RNG consumption. If a
2705
+ reference lacks a feature or measurement, show an unsupported cell with its
2706
+ reason. Packed trellis has no stock MLX-LM loader; a different affine or GGUF
2707
+ artifact belongs in the quality/size comparison and cannot be its speedup
2708
+ denominator. OptiQ and additional backends are separate supported controls.
2709
+
2710
+ Record immutable machine, session, workload and artifact identifiers; OS,
2711
+ chip, memory, power/thermal conditions, storage, Bun and oracle versions;
2712
+ source commit/diff and native-library hashes; weight content manifests;
2713
+ commands, resolved flags, protocol version, timestamps and preflight results.
2714
+ Resolve accelerator details explicitly: actual draft architecture/artifact,
2715
+ draft weight precision, block size, native MTP, prompt selection and KV format.
2716
+ Requested flags or a model's nominal weight precision do not establish those
2717
+ states. Report native active-memory peaks separately from process RSS.
2718
+ Hash large files before timing. Preserve every attempted request, failure,
2719
+ timeout, interruption and retry, with reasons for exclusions. Diagnostics
2720
+ remain identifiable and cannot become quiet acceptance rows during import.
2721
+
2722
+ Use the internal-SSD active-model policy in environment.md. Artifact transfer
2723
+ and hash verification precede the timed run; record the active volume and
2724
+ storage protocol. For startup, report readiness, first-request latency and
2725
+ their combined elapsed time. Eager weight loading must not appear faster
2726
+ merely because it moves disk work before the readiness signal. Historical
2727
+ external-drive measurements stay separate from internal-drive comparisons.
2728
+
2729
+ A Bun FFI collector prototype reads macOS `proc_pid_rusage` v4 directly for
2730
+ an owned PID. Its layout is checked against the installed SDK; RSS, physical
2731
+ footprint, lifetime peak physical footprint and disk-byte counters keep distinct
2732
+ fields. The PID's start tick guards against reuse, and an exited or unreadable
2733
+ process returns no sample. A 64 MiB allocation calibration matches Bun's RSS
2734
+ and the expected physical-footprint growth; live/exited child reads and disposal
2735
+ also pass. Two 32-sample blocks per arm measure about 0.0013–0.0015 ms per native
2736
+ read versus 1.09–1.14 ms for the current `ps` subprocess. This is collector
2737
+ overhead only, not an inference speedup. Validate real-server accounting and
2738
+ sampling effects before using it in the final benchmark. Evidence:
2739
+ process-memory-sdk-layout.json and process-memory-calibration.json under
2740
+ reports/qwen38-rd. Existing timing reports keep their original collector.
2741
+
2742
+ Apply section 7.7's balanced paired blocks, independent-session repeats and
2743
+ correctness gates. Calculate speed ratios within a machine and compatible
2744
+ protocol/artifact cells. Show raw distributions, sample counts and paired
2745
+ uncertainty; estimate tail percentiles only with adequate request counts.
2746
+ Use a prespecified stopping rule and acceptance thresholds. Keep supported
2747
+ configuration tradeoffs visible instead of averaging different workloads,
2748
+ precision levels or machines into a single score.
2749
+
2750
+ The offline HTML report should provide machine/model/quant/backend/configuration
2751
+ filters, baseline selection among compatible rows, absolute metrics and
2752
+ within-machine deltas, distributions, memory-versus-speed and quality-versus-size
2753
+ plots. Every summary links to raw JSON, provenance and correctness evidence.
2754
+ Failed, skipped, unsupported and unmeasured cells remain visible. Escape saved
2755
+ model output and other external strings; report generation must not execute
2756
+ them. Embed the report's required assets so the exported file works offline.
2757
+
2758
+ Exit requires a model-free replay fixture proving schema validation, unit
2759
+ definitions, pairing, failure handling and renderer escaping; a bounded live
2760
+ smoke through the real measurement paths; then the frozen final matrix on
2761
+ the M4 Pro. Compare the old suite and new suite on shared cells to
2762
+ detect measurement changes before attributing a difference to the engine.
2763
+ Publish qualified numbers only in the canonical benchmark reference, with
2764
+ raw JSON and HTML under `reports/`. Machine access or unsupported cells that
2765
+ remain unavailable must be named explicitly and cannot be counted as done.
2766
+
2767
+ ### 7.11 Mac quant video follow-up
2768
+
2769
+ The September 6 [RepoChad video](https://www.youtube.com/watch?v=dHK90xc9Q64)
2770
+ names additional Mac quantization and serving configurations. Its description
2771
+ contains chapters and hashtags, with no external artifact links. Automatic
2772
+ captions were advertised but could not be retrieved. The investigation used
2773
+ public storyboard frames to identify visible recommendations, then inspected
2774
+ primary model cards and source. It did not recover a transcript. Metadata,
2775
+ frames and pinned sources are retained in
2776
+ `reports/qwen38-rd/video-dHK90xc9Q64/`.
2777
+
2778
+ The concrete new weight candidate is
2779
+ [`manjunathshiva/Qwen3.8-27B-tq3-mini-g64`](https://huggingface.co/manjunathshiva/Qwen3.8-27B-tq3-mini-g64/tree/5542979c87f72acaa9019633649cb6624e32699f).
2780
+ It stores independent eight-centroid indices, ten codes per uint32, with
2781
+ fp16 RMS scales per 64 inputs and online randomized Hadamard rotation.
2782
+ Index storage is 3.2 bits/value before scales and other tensors. This differs
2783
+ from the campaign's Trellis format. The custom wrapper can load it directly;
2784
+ stock MLX-LM and our current loader do not implement this format.
2785
+
2786
+ Its [M1 kernel](https://github.com/manjunathshiva/turboquant-mlx/blob/f4e3d34a831fc1f6acd8e7c29665bad358ce878e/kernels/polar_qmv.py)
2787
+ uses five shared-memory barriers to reduce one SIMD group's partial sums.
2788
+ First compare explicit converged SIMD shuffles with the same 16/8/4/2/1 tree,
2789
+ element order, group scale placement and final cast. Include the wrapper's
2790
+ bf16-to-f32 promotion and complete online rotation cost. The Apache-2.0 source
2791
+ and attribution are pinned. [Conversion seeds rotations per projection path](https://github.com/manjunathshiva/turboquant-mlx/blob/f4e3d34a831fc1f6acd8e7c29665bad358ce878e/quantize_model.py);
2792
+ gate/up sharing requires identical saved sign tensors. Do not reconstruct
2793
+ those signs from a base seed, since conversion also uses Python string hashing.
2794
+ Different small-M and expanded paths have separate rounding/reduction contracts.
2795
+
2796
+ The video's attractive M4 Pro result matches
2797
+ [oMLX record sio0vt3c](https://omlx.ai/benchmarks/performance/sio0vt3c): DFlash2,
2798
+ quantized draft weights and block size five are enabled; native MTP is off.
2799
+ It is not a plain Q4 decode baseline. The
2800
+ [Qwen DFlash2 artifact](https://huggingface.co/z-lab/Qwen3.8-27B-DFlash2/tree/50307d4c4cde6860d4eee73e2547cd786fe8e8a4)
2801
+ is a concrete R21 candidate. Existing Gemma draft support does not establish
2802
+ support for this architecture. Any port needs target-state/rollback identity,
2803
+ draft residency and full-request comparisons with ordinary decode and fixed-two
2804
+ native MTP. Guaranteed structural appends remain a separate operation.
2805
+
2806
+ The pinned oMLX package file actually selects
2807
+ [dflash-mlx c55324c, v0.1.10+omlx.7](https://github.com/jundot/omlx/blob/aa8db73496bd8367989e2862f50b315885b9b91a/pyproject.toml).
2808
+ The older v0.1.10+omlx.4 string is an engine compatibility comment. At that
2809
+ [dependency revision](https://github.com/jundot/dflash-mlx/tree/c55324c86540c369f6818a0f47eae544d405475b),
2810
+ DFlash2 adds dynamic grouped causal convolutions around both attention and
2811
+ MLP, plus a selector that conditions each token on its selected predecessor
2812
+ using top-16 candidates and rank-256 codebooks. Our existing DFlash provider
2813
+ needs this architecture and selector in addition to Qwen target taps; loading
2814
+ the checkpoint into the current provider would not implement DFlash2.
2815
+
2816
+ The fork's flat greedy verify path concatenates proposed and target token IDs
2817
+ for one host read, then checks acceptance and EOS from that result. Hidden
2818
+ feature extraction launches asynchronously outside profiling. This does not
2819
+ mean every mode has one synchronization: repetition penalties need another
2820
+ ID read and stochastic acceptance follows a separate path. Our speculative
2821
+ accept walk reads each sampled target position eagerly, and Qwen MTP reads
2822
+ each draft token before the next draft step. Test grouped reads first for
2823
+ history-independent greedy requests. Preserve the shared sampler's processor,
2824
+ grammar, RNG and history contract; do not bypass it for a blanket fast path.
2825
+ The pinned eleven-file
2826
+ source bundle and hashes are in video-dHK90xc9Q64/dflash-source-manifest.json.
2827
+
2828
+ The grouped-read experiment is closed without a production change. Two Bun
2829
+ prototypes keep the existing independent per-position sampler calls: one
2830
+ concatenates their IDs for one read; the other uses `evalAll` followed by direct
2831
+ integer reads. Each passes 144 operation cases, including ties and nonfinite
2832
+ logits, with unchanged inputs and zero retained allocation after disposal.
2833
+ The operation improves when several positions are consumed, but computing
2834
+ unused positions makes a first-position rejection slower.
2835
+
2836
+ Six balanced three-arm HTTP blocks then preserve all 84 candidate/control
2837
+ response comparisons, usage and acceptance traces across 126 requests. All
2838
+ arms use the same R6 target, saved q4 MTP companion, gamma 2, bf16 KV and greedy
2839
+ seed 42. Ordinary sampling makes 432 eager ID reads per server; either
2840
+ prototype replaces verification reads with 152 grouped windows plus seven
2841
+ ordinary first-token reads. All servers exit cleanly with equal active
2842
+ capacity, and all 547 source hashes remain fixed. Complete-request paired
2843
+ medians for concatenation improve only 0.33%, 0.06% and 0.23% across the code,
2844
+ explanation and JSON fixtures. The `evalAll` alternative improves 0.26% and
2845
+ 0.04% but regresses 0.44% on JSON. Losses remain in both results. These M4 Pro
2846
+ diagnostics establish no broad serving benefit worth another sampler path.
2847
+ Evidence: spec-grouped-greedy-screen.json, spec-grouped-greedy-eval-screen.json
2848
+ and spec-grouped-greedy-three-http{,-review}.json. This tests target verification
2849
+ readback only, not DFlash2's architecture or the separate forced-token method.
2850
+
2851
+ The scalar checkpoint's reported four agent failures on a 16 GB Mac mix missing
2852
+ tool calls, a queue timeout and perseveration ending in OOM. The same weights
2853
+ pass on a larger Mac, with differing wrapper builds unresolved. These reports
2854
+ do not isolate quantization damage. Borrow the long-agent memory/context tests
2855
+ using current artifacts first. Likewise,
2856
+ [SpecPrefill](https://github.com/jundot/omlx/blob/aa8db73496bd8367989e2862f50b315885b9b91a/omlx/patches/specprefill.py)
2857
+ selects a prompt subset with a smaller model. Keeping RoPE positions does not
2858
+ reconstruct skipped GDN recurrence updates. It belongs in an approximate Lab
2859
+ arm with original/selected token counts, retrieval and task-quality gates.
2860
+
2861
+ Priority is the bounded M1 scalar operation screen, current-artifact long-agent
2862
+ memory/context coverage, then Qwen DFlash2 feasibility. Only positive operation
2863
+ economics and quality evidence justify a new full-model loader or artifact.
2864
+ Approximate prompt reduction follows the exact-path work. No external speed
2865
+ or memory figure changes our baseline; remaining runs stay on the M4 Pro.
2866
+
2867
+ The bounded Bun/Metal M1 screen now preserves all 54 fixture cases, including
2868
+ online rotation, dtype promotion and incomplete packed rows. Six fresh-process
2869
+ repeats preserve every fixture/output hash and release all active allocations.
2870
+ For the 5120-to-17408 projection, explicit shuffles reduce complete rotated
2871
+ operation time by a median 2.77–3.84% across the three input dtypes; the reverse
2872
+ projection improves 0.63–1.06%. Every pair improves. Packed-word reuse is slower,
2873
+ forced loop unrolling adds little, and larger threadgroups do not establish an
2874
+ additional large-projection benefit. This is the literal upstream source run
2875
+ through our Bun binding on synthetic matrices, not installed-wrapper parity or
2876
+ a current-engine/full-model improvement. Evidence: `polar-qmv-screen-v2.json`,
2877
+ `polar-qmv-variants.json`, `polar-qmv-geometry.json` and
2878
+ `polar-qmv-repeat{,-review}.json`.
2879
+
2880
+ A separate exact prototype fuses the upstream large-prefill unpack, centroid
2881
+ gather and group-scale multiplication into one fp16 expansion. The original
2882
+ fallback builds uint32 indices, narrows them to uint8, widens them for gather,
2883
+ then multiplies the gathered weights by scales. The screen preserves all 16
2884
+ expanded-weight and complete-operation cases, including small padded rows and
2885
+ zero/subnormal/overflow scale values. Six fresh processes then preserve all 84
2886
+ large-projection comparisons at M257/512, including rotation and native matmul,
2887
+ with identical cross-process hashes and zero final active allocation. Median
2888
+ complete-operation time falls 40.85–57.51%; peak temporary allocation falls
2889
+ 765.00–765.05 MiB. Every pair improves. These are M4 Pro diagnostics on synthetic
2890
+ resident matrices. They do not measure real model quality, RSS or whole-model
2891
+ speed, and they do not replace the separate small-M QMM arithmetic. Evidence:
2892
+ `polar-expand.json` and `polar-expand-repeat{,-review}.json`.
2893
+
2894
+ Our existing `TurboQuantKVCache.#decode` has the same unpack/gather/scale
2895
+ pattern. The byte-packed KV decoder passes operation repeats, long-context
2896
+ Qwen state, RTN4 and deferred D128/D512 consumer gates. It is integrated behind
2897
+ an experimental opt-in, with exact operation/fallback/lifetime checks, six
2898
+ HTTP pairs per R6/RTN4 quant and the first integrated 8K state gate. Allocation
2899
+ diagnostics distinguish live-array ownership from Metal buffer capacity.
2900
+ Six long-context three-arm blocks preserve responses and improve complete time;
2901
+ the narrower inverse-rotation operation is now integrated. Its R6 and RTN4
2902
+ model and repeated HTTP response gates pass on the new core. Decode improves
2903
+ on both; R6 complete time improves while RTN4 complete time remains inconclusive.
2904
+ Six HTTP
2905
+ pairs each on MiniCPM and Gemma deferred consumers pass response identity and
2906
+ improve complete time. Pressure and quiet acceptance remain. Direct packed-key
2907
+ attention preserves the native arithmetic but loses
2908
+ against the integrated decoder in complete codec/attention repeats; that
2909
+ additional speed candidate is closed.
2910
+ Its mechanism and evidence
2911
+ live in turboquant.md, "Packed-value decode fusion investigation". The video's
2912
+ weight format still has no production loader or kernel here.
2913
+
2914
+ ### 7.12 Custom-kernel graph reuse and the MLX runtime update
2915
+
2916
+ The pinned runtime separates three costs. `metal_kernel` constructs a lazy
2917
+ custom primitive on each eager call. Its GPU evaluator uses MLX's ordinary
2918
+ command encoder and cached Metal library/pipeline. `compile` separately caches
2919
+ an optimized graph, then instantiates it with new inputs during native replay.
2920
+ Avoiding JavaScript tracing does not remove all native graph or dispatch work.
2921
+
2922
+ The actual Bun probe confirms shape-specific compilation works with custom
2923
+ kernels: five calls over shapes 8/8/16/16/8 trace twice, invoke the shape/grid
2924
+ callbacks twice and return exact outputs for changing values. Native shapeless
2925
+ addition traces once across those shapes. Both custom shapeless variants fail
2926
+ with `CustomKernel cannot infer output shapes`, even when JS callbacks supply
2927
+ output shapes and the launch grid. All allocations release after disposal.
2928
+ The wrapper comments now describe this accurately: callbacks run during eager
2929
+ construction or tracing, never during native replay. Evidence:
2930
+ custom-kernel-compile-probe.json; the earlier helper error is retained separately.
2931
+
2932
+ This is an upstream limitation, not solely a Bun binding omission. The
2933
+ [CustomKernel declaration at current MLX main](https://github.com/ml-explore/mlx/blob/ce916dbbcaa88e433b6fd1e60a17f766d49c27fe/mlx/fast_primitives.h)
2934
+ still lacks `output_shapes`, and captures a concrete launch grid. A future
2935
+ native operation must infer both result shapes and dispatch from current
2936
+ inputs. Passing an output-shape callback through our existing JS interface
2937
+ cannot supply that native behavior. Prior per-projection shape-specific caching
2938
+ and launch-configuration reuse did not improve complete Qwen requests (§7.8/7.9);
2939
+ those negative results remain. Next candidates must target larger reusable
2940
+ regions or measured native construction costs, with growing-cache, compile,
2941
+ state, cancellation and complete-request gates.
2942
+
2943
+ Josh authorized upgrading to the latest stable MLX. The fresh upstream check
2944
+ finds [MLX v0.32.2](https://github.com/ml-explore/mlx/releases/tag/v0.32.2), released
2945
+ 2026-08-25; Homebrew currently offers 0.32.1. The staged runtime pairs that
2946
+ version with [MLX-C c74db530](https://github.com/ml-explore/mlx-c/tree/c74db5307cc8ce122f48d97ef951b30578674e7f),
2947
+ whose CMake dependency pins 0.32.2. The full source build stopped because this
2948
+ Mac lacks the offline Metal toolchain. The completed build instead links the
2949
+ C wrapper against MLX's verified official 0.32.2 native wheel libraries.
2950
+ Bun loads those native libraries directly. Local build, archive and library
2951
+ hashes are recorded in `reports/qwen38-rd/mlx-upgrade-0.32.2/`.
2952
+
2953
+ The initial cross-version checks used a temporary dual-ABI adapter. The
2954
+ consolidated production binding now directly uses the 0.32.2 C API. Attention
2955
+ supplies `force_fused=false`, cumulative sum supplies an absent optional dtype,
2956
+ and both cumulative operations call the axis-taking symbols. Startup checks
2957
+ the linked core version. The original cross-version suites and the later
2958
+ Trellis-port suites passed on both runtimes; their separate reports remain.
2959
+
2960
+ The frozen shared-affine port was validated against the 0.31.2 core. Identical packed
2961
+ weights, activations and metadata reproduce four exactness differences against
2962
+ 0.32.2 native multi-row matmul. The custom outputs are unchanged across versions
2963
+ and match separate native M1 rows. Upstream `qmv_wide` decodes each group once
2964
+ for several vectors and uses different arithmetic and an eight-lane reduction.
2965
+ Native dispatch on the new core preserves its numerical contract. The final
2966
+ production code removes the old affine kernel and its experimental flag;
2967
+ the frozen source controls retain that implementation for comparisons.
2968
+
2969
+ Six balanced process pairs screen ten affine shapes with twenty alternating
2970
+ operation samples per implementation. New native Q3 gate/up-shaped operations
2971
+ improve over old shared operations in all six blocks; Q4 results are mixed by
2972
+ shape and block, while Q8 loses in every block. These are loaded-machine
2973
+ operation diagnostics, not full-model gains, and refer to affine Q3 rather
2974
+ than Trellis. All input hashes agree and every process releases its arrays.
2975
+ Evidence: affine-{old,new}-screen.json and affine-runtime-repeat{,-review}.json.
2976
+ Same-version RTN4 oracle gates now pass on both cores and on both official
2977
+ 0.32.2 macOS builds. Each comparison covers contexts 0/64/512 and append lengths
2978
+ 1/4/8/128, checking complete logit arrays, every live cache array, and a fixed
2979
+ continuation. All twelve cells are byte-exact against the matching MLX-LM
2980
+ reference. The two new-core builds also agree with each other in those cells.
2981
+ Source hashes stay fixed and every worker exits cleanly. Evidence:
2982
+ runtime-oracle-rtn4.json and runtime-oracle-rtn4-macos14.json.
2983
+ The working tree now selects the verified macOS 14 native-pack candidate
2984
+ 0.4.0 from a local cache. It has not been published. Final-source acceptance
2985
+ passes 16 RTN4 same-version reference cases (including actual 4K/8K prompts),
2986
+ 36 Trellis forward/state/continuation cases and six Trellis generations.
2987
+ The Trellis control is the accepted new-core implementation; this is not a
2988
+ claim of an external packed-Trellis oracle. All three workers exit cleanly,
2989
+ with fixed source, library and reference hashes. Evidence:
2990
+ `final-source-gates.json`. The consolidated model-free suite passes 1,875 tests
2991
+ with ten skips; all three typechecks and hygiene pass. Integrated inverse-KV
2992
+ serving also passes its repeated response and decode gates; its complete-time
2993
+ verdict differs by quant, as recorded in turboquant.md. Broader same-version
2994
+ reference checks and combined/pressure acceptance remain. The old runtime and both source controls remain
2995
+ separate; environment.md records their paths.
2996
+
2997
+ Production targets one pinned runtime. Trellis, rotation and TurboQuant
2998
+ continue through their existing interfaces. The integrated inverse-KV decoder
2999
+ passes its new-core R6 and RTN4 comparisons against the preceding joint decoder.
3000
+ Each checks 12 full forward/state/continuation cases and four greedy/sampled
3001
+ generations at 2K and 8K contexts. Logits, complete cache arrays, token IDs,
3002
+ logprobs and usage are exact. Each pair has equal final active allocation and
3003
+ clean exits. These comparisons isolate the KV change and do not establish
3004
+ every Trellis variant's equivalence. Evidence: r6-kv-inverse-full.json and
3005
+ rtn4-kv-inverse-full.json.
3006
+
3007
+ The separate new-core Trellis v6/v13 model gate catches an M8 append mismatch.
3008
+ M1/3/4/128/512 and all four tested generations remain exact. The first differing
3009
+ cache appears after layer zero. Upstream `gemv_wide` changes the arithmetic of
3010
+ contiguous small-M dense projections on M3 and newer GPUs. The old direct
3011
+ Trellis prefill tile reproduces the preceding SIMD-matrix reduction instead.
3012
+ A deterministic operation reproduction fails at every M5..15 row count and
3013
+ passes again at M16, where native dispatch returns to GEMM. The replacement
3014
+ kernel decodes packed Trellis weights to bf16 within the new eight-iteration,
3015
+ four-value dot-product loop. Sharing each decoded row across all M vectors
3016
+ preserves the native reduction and wins the initial complete-operation screen
3017
+ for every tested 2/3/4-bit cell. A full-model prototype comparison passes all
3018
+ 36 forward/state/continuation cells and four greedy/sampled generations.
3019
+ Those timings are screening evidence, not serving results.
3020
+
3021
+ The integrated implementation keeps geometry and arithmetic in
3022
+ `trellis-wide-prefill.ts`. Qwen supplies an explicit layout proof from its
3023
+ RMSNorm output through the existing MLP and linear calls. Unproven layouts
3024
+ return to native expansion/matmul for the affected sizes. Reading lazy-array
3025
+ strides before evaluation cannot establish this proof, and inserting an eval
3026
+ would change scheduling. Native arithmetic also depends on the GPU generation;
3027
+ the gate reads MLX's architecture identifier once and retains the earlier
3028
+ dispatch on pre-M3 hardware. The operation tests cover every M5..15 size for
3029
+ all three bit widths and a full-size transposed-input fallback. The integrated
3030
+ model comparison passes all 36 forward/state/continuation cases and six
3031
+ greedy/sampled generations, including short prompts. Logits, tokens, logprobs
3032
+ and cache state are exact. Both processes release to the same active-memory
3033
+ baseline. The complete model-free suite passes on both cores, with 1,882 passes
3034
+ and ten skips on the new core, and 1,881 passes and eleven skips on the old
3035
+ core. The additional skipped test needs the new native reduction. All three
3036
+ typechecks and hygiene pass. Preserve the
3037
+ failed model report; no equality check is weakened. Evidence: trellis-runtime-full,
3038
+ trellis-wide-screen, trellis-wide-perf, trellis-wide-full and
3039
+ trellis-wide-integrated-full reports in the upgrade directory.
3040
+
3041
+ Six balanced actual HTTP pairs per serial/continuous lane preserve every
3042
+ response, usage count and finish reason. The raw 9/12-token prompts exercise
3043
+ 8/11-row prefills with normal tail splitting. TTFT improves in every pair;
3044
+ complete-request time improves in all but one measured fixture pair. Decode
3045
+ and peak RSS are effectively unchanged. These are narrow, loaded-M4-Pro
3046
+ diagnostics. The first continuous attempt supplied an explicit seed, which
3047
+ correctly selected serial placement. Its failure remains recorded. The
3048
+ corrected continuous requests use greedy decoding without an explicit seed
3049
+ and assert actual scheduler admission and batched usage. Evidence:
3050
+ trellis-wide-http.json, trellis-wide-continuous.json and
3051
+ trellis-wide-http-review.json. This supports the new small-prefill path;
3052
+ it does not establish a general decode gain from upgrading MLX.
3053
+
3054
+ Two balanced runtime blocks complete all 24 native workers with fixed source
3055
+ and library hashes. Short-prompt decode is effectively unchanged. RTN4's
3056
+ short-prompt first-token time improves slightly in both orders. Long-prefill
3057
+ timings vary substantially by order, so the initial apparent gain is not an
3058
+ accepted upgrade result. Both new-core builds produce identical tokens across
3059
+ all repeats. At the 4,096-token prompt, both quants produce stable but different
3060
+ continuations across core versions. Those differences remain explicit in the
3061
+ report. The additional same-version oracle uses the actual long-prompt IDs,
3062
+ repeated for 8K, with 512-token prefix chunks and the final 511-token tail.
3063
+ Both append lengths, one and eight tokens, pass at both contexts. Full
3064
+ logits, every live cache array and the fixed continuation are byte-exact;
3065
+ both workers exit cleanly with fixed source hashes. Evidence:
3066
+ runtime-oracle-long-macos14.json and
3067
+ native-runtime-screen{,-review}.json. These runs used the loaded M4 Pro and
3068
+ are not canonical benchmark rows.
3069
+
3070
+ A native proxy prototype establishes a narrower graph-reuse option. It holds
3071
+ the original custom operation, delegates evaluation to MLX's existing encoder,
3072
+ and supplies constant output shapes only after checking that every custom
3073
+ input retains its captured shape and dtype. Other graph inputs may change
3074
+ dimensions. The two-output probe returns exact results over five changing
3075
+ input-value/native-shape calls with one JS trace. A changed custom input shape
3076
+ throws before dispatch; returning to the original shape still works. Disposal
3077
+ returns active memory to zero. This does not add general dynamic-shape custom
3078
+ kernels or establish a model speedup. Evidence: fixed-custom-probe.json and the pinned native helper build
3079
+ in the upgrade directory.
3080
+
3081
+ The actual Qwen region probe also needs fixed-input `Slice` support. Its
3082
+ native proxy retains the same strict shape/dtype checks. Default compilation
3083
+ passes all 48 R6 recurrent/full-attention cases with one trace per region, but
3084
+ changes an RTN4 full-attention output while preserving KV state. Disabling
3085
+ fusion everywhere instead changes recurrent state. Keeping normal fusion in
3086
+ recurrent regions and disabling additional fusion in full-attention regions
3087
+ passes all 48 cases on both quants, including growing contexts and continuations.
3088
+ All failed comparisons remain recorded; none becomes a tolerance-based pass. Evidence:
3089
+ qwen-fixed-region-{r6,rtn4}-v{2,3,4}.json in the upgrade directory.
3090
+
3091
+ Composing these regions as 64 cached per-layer graphs passes R6's eight full
3092
+ forward/state cases and six greedy/sampled generations, including logprobs.
3093
+ Every layer traces once and all compiled closures release. Request timing is
3094
+ flat or slightly slower. RTN4 fails the full-model numerical gate despite the
3095
+ regional passes. Its one-token forward changes logits while initially
3096
+ preserving cache arrays; subsequent continuations also change state. RTN4
3097
+ timing shows no gain. This per-layer implementation stays out of production.
3098
+ It establishes a limited graph-reuse mechanism, but changing graph boundaries
3099
+ still requires full-model identity and request-time evidence. Both arms exit
3100
+ normally with equal final active allocation for each model. Evidence:
3101
+ qwen-fixed-layer-r6-full-v2.json and qwen-fixed-layer-rtn4-full.json.
3102
+
3103
+ A whole-model graph experiment preserves the existing inner compiled regions.
3104
+ In the pinned MLX source, `detail::compile`
3105
+ calls the original function when an input is already a tracer. Nested
3106
+ `computeG` therefore expands into the outer trace, and an outer `no_fuse` mode
3107
+ also removes its required inner fusion. Warming the inner cache does not
3108
+ change that branch. A research helper temporarily restores ordinary inner
3109
+ compilation, then restores tracer ownership before the outer graph is built.
3110
+ The changing-input probe passes ten bf16/f32 cases with two traces and
3111
+ unchanged input bytes. Both R6 and RTN4 then pass eight full forward/state
3112
+ cases and six greedy/sampled generations each, including logprobs and
3113
+ continuations. Each whole-model closure runs 394 times with two traces and
3114
+ releases on weight disposal; both controls agree on final active allocation.
3115
+ This resolves the earlier RTN4 composition failure for this implementation.
3116
+ The first native timing screen is slower on both quants. It is not a balanced
3117
+ performance verdict, but supplies no speed candidate. Attribute cache copying
3118
+ and graph bookkeeping before further request-time comparisons. No production
3119
+ tracer manipulation or whole-model compilation change is integrated.
3120
+ Evidence: `compiled-region-probe.json` and
3121
+ `qwen-fixed-hidden-regions-{r6,rtn4}.json` in the upgrade directory.
3122
+
3123
+ A narrower experiment uses ordinary fixed-shape `CompiledFunction` for the
3124
+ sixteen groups of three recurrent layers. Full-attention layers keep their
3125
+ native capacity-backed KV updates. This needs no native proxy or tracer
3126
+ manipulation: hidden inputs and initialized recurrent/conv states have fixed
3127
+ decode shapes. Both R6 and RTN4 pass eight complete forward/state/continuation
3128
+ cases and six greedy/sampled generations, including logprobs. Each group
3129
+ traces once, the sixteen groups execute 6,304 calls, and all closures release
3130
+ with the same final active allocation as the ordinary control. R6's initial
3131
+ comparison uses the external archive; RTN4 uses the byte-verified internal
3132
+ active copy specified in environment.md. The initial fixed-order timing
3133
+ screens supply no request-time gain, but unchanged prefill timings also
3134
+ drift. The follow-up alternates ordinary and compiled generation within one
3135
+ loaded internal-SSD model, with four balanced pairs each at 8- and 128-token
3136
+ prompts. Both quants preserve all forty warm/measured generations, logprobs,
3137
+ live state and steady active ownership. Sixteen closures trace once per model
3138
+ across 10,240 group calls, then close. Median paired complete-time reductions
3139
+ are only 0.062% for R6 and 0.202% for RTN4, with one slower pair on each.
3140
+ This does not justify adding model execution and lifetime machinery; no
3141
+ production integration or HTTP speed claim. Evidence:
3142
+ `qwen-fixed-ssm-groups-r6.json` and
3143
+ `qwen-fixed-ssm-groups-rtn4-internal.json`, plus `qwen-ssm-hot-review.json`
3144
+ and its raw per-quant reports in the upgrade directory.
3145
+
3146
+ The broader matching-core audit catches a separate MiniCPM5 prefill gap.
3147
+ M1/M8 agree, while M128 changes logits and state from layer four onward.
3148
+ Its Llama MLP had limited compiled SwiGLU to decode, whereas MLX-LM compiles
3149
+ the activation at every sequence length. Using the oracle operation for
3150
+ prefill restores all six same-input logit/state/continuation cases in the
3151
+ isolated control. The model-owned implementation now uses that existing
3152
+ compiled helper at every length outside an enclosing compiled trace.
3153
+ The explicit opt-out remains. Integrated MiniCPM5, Llama 1B and Gemma e4b
3154
+ reference checks pass all eighteen cases. The retained opt-in regression
3155
+ `tests/parity/runtime-oracle.test.ts` repeats the full logits, live state and
3156
+ continuations with the matching runtime and sequential subprocesses; all
3157
+ three model tests pass. Training and serving checks remain before this
3158
+ runtime correction closes.
3159
+ Evidence: `runtime-oracle-broader.json` and
3160
+ `runtime-oracle-compiled-prefill.json` in the upgrade directory.
3161
+
3162
+ The intervening release notes are:
3163
+
3164
+ | Release | Changes relevant to this program |
3165
+ |---|---|
3166
+ | [0.32.0](https://github.com/ml-explore/mlx/releases/tag/v0.32.0) | Small-batch quantized matvec, RMSNorm register reuse, custom Metal math modes, compile cleanup and shapeless-reduction fixes. |
3167
+ | [0.32.1](https://github.com/ml-explore/mlx/releases/tag/v0.32.1) | Lower custom-kernel naming overhead, reusable Metal hazard tracking, small-batch dense matvec, shader-cache collision and shapeless-matmul fixes. |
3168
+ | [0.32.2](https://github.com/ml-explore/mlx/releases/tag/v0.32.2) | Optional forced fused attention, GQA8 reuse, sliced-array quantization and compiled-cast fixes; additional NAX paths apply to newer GPU architectures. |
3169
+
3170
+ Useful upstream changes include [removing regex from custom-kernel name
3171
+ construction](https://github.com/ml-explore/mlx/pull/3869), [reusing Metal hazard
3172
+ tracking allocations](https://github.com/ml-explore/mlx/pull/3882), [fixing
3173
+ same-name shader cache collisions](https://github.com/ml-explore/mlx/pull/3833),
3174
+ and [correcting shapeless matmul's dynamic dimensions](https://github.com/ml-explore/mlx/pull/3813).
3175
+ Their reported gains are not our measurements. New [GQA8 attention reuse](https://github.com/ml-explore/mlx/pull/4077)
3176
+ has a narrow D64/128 dispatch; Qwen3.8-27B uses GQA6/D256, so it is an algorithm
3177
+ lead rather than a direct dispatch win here. The [optional fused full-attention
3178
+ path](https://github.com/ml-explore/mlx/pull/4185) explicitly trades throughput
3179
+ for bounded temporary memory. Evaluate that tradeoff on the M4 Pro's actual
3180
+ eligible path. Reference numerical changes must be explained, never hidden by
3181
+ loosening the oracle tolerance.