mlx-bun 0.5.0 → 1.0.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 (640) hide show
  1. package/README.md +1449 -109
  2. package/THIRD_PARTY_NOTICES.md +882 -0
  3. package/bin/mlx-bun.convert.mjs +4 -0
  4. package/bin/mlx-bun.fuse.mjs +4 -0
  5. package/bin/mlx-bun.generate.mjs +4 -0
  6. package/bin/mlx-bun.lora.mjs +4 -0
  7. package/bin/mlx-bun.mjs +13 -21
  8. package/bin/mlx-bun.server.mjs +4 -0
  9. package/bin/mlx-bun.upload.mjs +4 -0
  10. package/dist/web/app.js +9584 -0
  11. package/package.json +50 -53
  12. package/src/cli/ane-install.ts +76 -0
  13. package/src/cli/args.ts +179 -0
  14. package/src/cli/engine-entry.ts +68 -0
  15. package/src/cli/inference.ts +214 -0
  16. package/src/cli/job-entry.ts +97 -0
  17. package/src/cli/library-host.ts +117 -0
  18. package/src/cli/main.ts +57 -0
  19. package/src/cli/memory-engine.ts +163 -0
  20. package/src/cli/memory.ts +36 -0
  21. package/src/cli/mlx-lm-aliases.ts +309 -0
  22. package/src/cli/model-choice.ts +33 -0
  23. package/src/cli/model-selection.ts +84 -0
  24. package/src/cli/module-host.ts +11 -0
  25. package/src/cli/module-verbs.ts +50 -0
  26. package/src/cli/numerical-policy.ts +12 -0
  27. package/src/cli/perplexity.ts +89 -0
  28. package/src/cli/serve-host.ts +423 -0
  29. package/src/cli/serve-isolated.ts +217 -0
  30. package/src/cli/serve-options.ts +106 -0
  31. package/src/cli/serve-state.ts +205 -0
  32. package/src/cli/serve.ts +500 -0
  33. package/src/cli/served-model-host.ts +102 -0
  34. package/src/cli/server-entry.ts +148 -0
  35. package/src/cli/serving-unit.ts +177 -0
  36. package/src/{tui.ts → cli/terminal.ts} +13 -8
  37. package/src/cli/worker-adapters.ts +34 -0
  38. package/src/cli/worker-entry.ts +272 -0
  39. package/src/cli/worker-unit.ts +179 -0
  40. package/src/engine/adapter-operation.ts +26 -0
  41. package/src/engine/cache-services.ts +114 -0
  42. package/src/engine/completion.ts +39 -0
  43. package/src/engine/generation-gateway.ts +358 -0
  44. package/src/engine/index.ts +59 -0
  45. package/src/engine/kv-budget.ts +120 -0
  46. package/src/engine/media-preparation.ts +232 -0
  47. package/src/engine/model-binding.ts +24 -0
  48. package/src/engine/model-host.ts +513 -0
  49. package/src/engine/model-serving.ts +89 -0
  50. package/src/{serve → engine}/preparation.ts +7 -5
  51. package/src/{serve → engine}/session-completion-engine.ts +6 -6
  52. package/src/engine/telemetry.ts +109 -0
  53. package/src/hub/downloads.ts +116 -0
  54. package/src/jobs/db.ts +16 -7
  55. package/src/jobs/events.ts +29 -0
  56. package/src/jobs/executable.ts +5 -0
  57. package/src/jobs/host.ts +51 -0
  58. package/src/jobs/in-process.ts +55 -0
  59. package/src/{contracts/jobs.ts → jobs/protocol.ts} +7 -9
  60. package/src/jobs/runner.ts +150 -231
  61. package/src/jobs/service.ts +75 -0
  62. package/src/jobs/sse.ts +59 -23
  63. package/src/jobs/worker-memory.ts +46 -0
  64. package/src/jobs/worker-process.ts +163 -0
  65. package/src/jobs/worker-supervisor.ts +258 -0
  66. package/src/modules.ts +58 -0
  67. package/src/publishing/catalog-hub.ts +18 -0
  68. package/src/publishing/credentials.ts +31 -0
  69. package/src/publishing/upload.ts +37 -0
  70. package/src/residency/leased-adapters.ts +21 -0
  71. package/src/residency/local-records.ts +16 -0
  72. package/src/residency/model-residency.ts +405 -0
  73. package/src/residency/record-index.ts +28 -0
  74. package/src/residency/resident-estimate.ts +50 -0
  75. package/src/{anthropic.ts → server/anthropic.ts} +3 -81
  76. package/src/server/cache-routes.ts +36 -0
  77. package/src/{serve → server}/chat-request.ts +10 -10
  78. package/src/{serve → server}/chat-stage.ts +14 -14
  79. package/src/{client.ts → server/client.ts} +28 -2
  80. package/src/{serve → server}/completion-executor.ts +33 -41
  81. package/src/server/decision-body.ts +55 -0
  82. package/src/server/decision-routes.ts +134 -0
  83. package/src/server/decision-wire.ts +228 -0
  84. package/src/{serve → server}/discovery-routes.ts +25 -82
  85. package/src/{serve → server}/http.ts +25 -13
  86. package/src/{serve → server}/inference-request.ts +5 -5
  87. package/src/server/job-routes.ts +20 -0
  88. package/src/server/media-prompt.ts +63 -0
  89. package/src/server/memory-completion-client.ts +46 -0
  90. package/src/server/model-routes.ts +192 -0
  91. package/src/{serve → server}/openai-wire.ts +3 -2
  92. package/src/{serve → server}/pipeline.ts +1 -1
  93. package/src/server/prompt-builder.ts +13 -0
  94. package/src/server/prompt-contracts.ts +17 -0
  95. package/src/server/proxy-routes.ts +187 -0
  96. package/src/server/publishing-routes.ts +41 -0
  97. package/src/{serve → server}/request-plan.ts +6 -8
  98. package/src/{serve → server}/request-prep.ts +47 -50
  99. package/src/{serve → server}/responses-client.ts +30 -13
  100. package/src/{responses.ts → server/responses.ts} +12 -93
  101. package/src/server/routes.ts +205 -0
  102. package/src/server/start.ts +72 -0
  103. package/src/server/status-routes.ts +108 -0
  104. package/src/{serve → server}/text-completion-stage.ts +25 -4
  105. package/src/server/text-prompt.ts +12 -0
  106. package/src/{serve → server}/token-streams.ts +36 -38
  107. package/src/server/worker-routes.ts +311 -0
  108. package/src/storage/paths.ts +61 -0
  109. package/src/web/assets.ts +37 -0
  110. package/src/web/{src → browser}/api.ts +5 -23
  111. package/src/web/browser/chat-host.ts +17 -0
  112. package/src/web/browser/installed-panels.ts +6 -0
  113. package/src/web/browser/main.ts +55 -0
  114. package/src/web/browser/markdown.ts +279 -0
  115. package/src/web/browser/memory-panel.ts +9 -0
  116. package/src/web/browser/palette.ts +64 -0
  117. package/src/web/browser/protocol.ts +13 -0
  118. package/src/web/browser/shell.ts +467 -0
  119. package/src/web/{src → browser}/status.ts +32 -36
  120. package/src/web/build.ts +51 -0
  121. package/src/web/public/app.html +1054 -0
  122. package/src/web/{sw.js → public/sw.js} +4 -3
  123. package/src/web/{vendor → public/vendor}/hljs-theme.css +2 -2
  124. package/src/web/{vendor → public/vendor}/hljs.js +2 -2
  125. package/THIRD_PARTY_LICENSES.md +0 -51
  126. package/docs/README.md +0 -107
  127. package/docs/archive/hlg-sampling.md +0 -350
  128. package/docs/archive/investigations/audio-input-plan.md +0 -356
  129. package/docs/archive/investigations/benchmark-ledger-through-v0.4.0.md +0 -3617
  130. package/docs/archive/investigations/chunk-finetune-experiment.md +0 -84
  131. package/docs/archive/investigations/colibri-glm52-port.md +0 -1486
  132. package/docs/archive/investigations/colibri-oracle-pin.md +0 -1284
  133. package/docs/archive/investigations/curve-bisector-routing.md +0 -123
  134. package/docs/archive/investigations/decode-roofline-lookagain.md +0 -348
  135. package/docs/archive/investigations/diffusion-gemma-port.md +0 -602
  136. package/docs/archive/investigations/dspark-handoff.md +0 -224
  137. package/docs/archive/investigations/expert-offload-single-user-moe.md +0 -292
  138. package/docs/archive/investigations/faithful-l1-consolidation.md +0 -310
  139. package/docs/archive/investigations/hlg-sampling-investigation.md +0 -970
  140. package/docs/archive/investigations/indexshare-performance-spike.md +0 -357
  141. package/docs/archive/investigations/kernel-perf-review-2026-07.md +0 -171
  142. package/docs/archive/investigations/lab-build-journal.md +0 -157
  143. package/docs/archive/investigations/minicpm5-decode-megakernel.md +0 -489
  144. package/docs/archive/investigations/openjarvis-fit.md +0 -198
  145. package/docs/archive/investigations/openwiki-evaluation.md +0 -249
  146. package/docs/archive/investigations/optimization_plan.md +0 -346
  147. package/docs/archive/investigations/orpo-base-uf-experiment-and-directions.md +0 -120
  148. package/docs/archive/investigations/orpo-flash-cce-pin-leak.md +0 -167
  149. package/docs/archive/investigations/orpo-uf-testing-handoff.md +0 -126
  150. package/docs/archive/investigations/pareto-specialized-runtime-findings.md +0 -92
  151. package/docs/archive/investigations/pi-builtin-investigation.md +0 -308
  152. package/docs/archive/investigations/pre-colibri-stabilization.md +0 -329
  153. package/docs/archive/investigations/qwen38-27b-campaign-log.md +0 -1092
  154. package/docs/archive/investigations/segmented-backward-handoff.md +0 -148
  155. package/docs/archive/investigations/starter-model-port-handoff.md +0 -342
  156. package/docs/archive/investigations/steel-flash-cce-handoff.md +0 -489
  157. package/docs/archive/investigations/the-dreaming-handoff.md +0 -141
  158. package/docs/archive/investigations/trainer-validation-experiment.md +0 -173
  159. package/docs/archive/planning/chat-ui-vision-memory-first.md +0 -199
  160. package/docs/archive/planning/chat-ui-vision.md +0 -50
  161. package/docs/archive/planning/chunk-task-roadmap.md +0 -77
  162. package/docs/archive/planning/curve-sampler-research-plan.md +0 -331
  163. package/docs/archive/planning/journal.md +0 -316
  164. package/docs/archive/planning/memory-docs-and-dag-plan.md +0 -194
  165. package/docs/archive/planning/pi-integration-review.md +0 -178
  166. package/docs/archive/planning/release-notes-v0.0.10.md +0 -57
  167. package/docs/archive/planning/release-notes-v0.0.11.md +0 -239
  168. package/docs/archive/planning/release-notes-v0.0.12.md +0 -80
  169. package/docs/archive/planning/release-notes-v0.0.13.md +0 -77
  170. package/docs/archive/planning/release-notes-v0.0.9.md +0 -122
  171. package/docs/archive/planning/release-notes-v0.2.0.md +0 -49
  172. package/docs/archive/planning/release-notes-v0.3.0.md +0 -35
  173. package/docs/archive/planning/release-notes-v0.4.0.md +0 -45
  174. package/docs/archive/planning/release-notes-v0.5.0.md +0 -37
  175. package/docs/archive/planning/web-ui-pass-plan.md +0 -213
  176. package/docs/archive/planning/website-readme-pass-plan.md +0 -224
  177. package/docs/design/batching.md +0 -2054
  178. package/docs/design/decode-speed-program.md +0 -2404
  179. package/docs/design/dreaming-nightly-pipeline.md +0 -684
  180. package/docs/design/generic-model-support.md +0 -821
  181. package/docs/design/kv-cache.md +0 -993
  182. package/docs/design/orpo-training.md +0 -680
  183. package/docs/design/speculative-decoding.md +0 -2129
  184. package/docs/design/turboquant.md +0 -2225
  185. package/docs/design/unified-engine-frontier-plan.md +0 -1987
  186. package/docs/design/web-chat-redesign.md +0 -695
  187. package/docs/planning/PRODUCT_ROADMAP.md +0 -593
  188. package/docs/planning/ResearchTopics.md +0 -119
  189. package/docs/planning/public-readiness-handoff.md +0 -244
  190. package/docs/planning/public-readiness.md +0 -149
  191. package/docs/planning/video-series.md +0 -421
  192. package/docs/reference/benchmarks.md +0 -3587
  193. package/docs/reference/cli.md +0 -646
  194. package/docs/reference/distribution.md +0 -380
  195. package/docs/reference/environment.md +0 -494
  196. package/docs/reference/glossary.md +0 -39
  197. package/docs/reference/library-api.md +0 -688
  198. package/docs/reference/memory.md +0 -260
  199. package/docs/reference/models.md +0 -346
  200. package/docs/reference/server-api.md +0 -1945
  201. package/docs/reference/server-config.md +0 -973
  202. package/docs/reference/training.md +0 -462
  203. package/docs/reference/troubleshooting.md +0 -158
  204. package/src/admission-plan.ts +0 -18
  205. package/src/audio/audiotoolbox.ts +0 -112
  206. package/src/audio/conformer.ts +0 -655
  207. package/src/audio/decode.ts +0 -133
  208. package/src/audio/features.ts +0 -202
  209. package/src/audio/mic-capture.ts +0 -98
  210. package/src/audio/silero-vad.ts +0 -379
  211. package/src/audio/transcode.ts +0 -67
  212. package/src/audio/whisper-decode.ts +0 -774
  213. package/src/audio/whisper-fast.ts +0 -732
  214. package/src/audio/whisper-format.ts +0 -73
  215. package/src/audio/whisper-mel.ts +0 -185
  216. package/src/audio/whisper-timing.ts +0 -274
  217. package/src/audio/whisper-tokenizer.ts +0 -239
  218. package/src/audio/whisper-transcribe.ts +0 -410
  219. package/src/backends/mlx/assistant-target.ts +0 -46
  220. package/src/backends/mlx/autoregressive-draft-rows.ts +0 -120
  221. package/src/backends/mlx/autoregressive.ts +0 -129
  222. package/src/backends/mlx/batch-group.ts +0 -1874
  223. package/src/backends/mlx/cache-attachment.ts +0 -67
  224. package/src/backends/mlx/cache-layout.ts +0 -31
  225. package/src/backends/mlx/checkpoint-state.ts +0 -53
  226. package/src/backends/mlx/continuation-persistence.ts +0 -107
  227. package/src/backends/mlx/continuation-request.ts +0 -43
  228. package/src/backends/mlx/continuation.ts +0 -77
  229. package/src/backends/mlx/diffusion.ts +0 -39
  230. package/src/backends/mlx/draft-target.ts +0 -32
  231. package/src/backends/mlx/encoder-cache.ts +0 -25
  232. package/src/backends/mlx/evaluation.ts +0 -105
  233. package/src/backends/mlx/fill-append.ts +0 -58
  234. package/src/backends/mlx/fill-group.ts +0 -497
  235. package/src/backends/mlx/full-kv-row-append.ts +0 -32
  236. package/src/backends/mlx/full-kv-row-donor.ts +0 -54
  237. package/src/backends/mlx/full-transitioning-kv-rows.ts +0 -65
  238. package/src/backends/mlx/gateway-binding.ts +0 -174
  239. package/src/backends/mlx/graph.ts +0 -38
  240. package/src/backends/mlx/kv-codec.ts +0 -9
  241. package/src/backends/mlx/kv-maintenance.ts +0 -161
  242. package/src/backends/mlx/kv-tensor-rows.ts +0 -212
  243. package/src/backends/mlx/memory-client.ts +0 -189
  244. package/src/backends/mlx/methods.ts +0 -90
  245. package/src/backends/mlx/mixed-iteration.ts +0 -62
  246. package/src/backends/mlx/model-prompt.ts +0 -178
  247. package/src/backends/mlx/model-serving.ts +0 -80
  248. package/src/backends/mlx/paged-cache-codec.ts +0 -27
  249. package/src/backends/mlx/prefill-cohort.ts +0 -100
  250. package/src/backends/mlx/prefill-policy.ts +0 -26
  251. package/src/backends/mlx/prefill-rows.ts +0 -244
  252. package/src/backends/mlx/prefill.ts +0 -33
  253. package/src/backends/mlx/projected-context-rows.ts +0 -72
  254. package/src/backends/mlx/prompt-input.ts +0 -29
  255. package/src/backends/mlx/qwen-prompt-input.ts +0 -40
  256. package/src/backends/mlx/request-policy.ts +0 -20
  257. package/src/backends/mlx/request-state-policy.ts +0 -54
  258. package/src/backends/mlx/rollback.ts +0 -92
  259. package/src/backends/mlx/row-sampling.ts +0 -49
  260. package/src/backends/mlx/serial-executor.ts +0 -251
  261. package/src/backends/mlx/speculative-group.ts +0 -438
  262. package/src/backends/mlx/speculative-round.ts +0 -161
  263. package/src/backends/mlx/speculative.ts +0 -131
  264. package/src/backends/mlx/state-rows.ts +0 -104
  265. package/src/backends/mlx/state-views.ts +0 -46
  266. package/src/backends/mlx/target-layout-capability.ts +0 -35
  267. package/src/backends/mlx/text-engine.ts +0 -73
  268. package/src/backends/mlx/transitioning-kv-rows.ts +0 -173
  269. package/src/chat-template.ts +0 -382
  270. package/src/cli.ts +0 -3490
  271. package/src/config.ts +0 -399
  272. package/src/contracts/completion.ts +0 -16
  273. package/src/contracts/execution.ts +0 -70
  274. package/src/contracts/generation.ts +0 -103
  275. package/src/contracts/host.ts +0 -7
  276. package/src/contracts/object-cache.ts +0 -8
  277. package/src/contracts/pi-provider.ts +0 -30
  278. package/src/contracts/pi.ts +0 -261
  279. package/src/contracts/prefix-cache.ts +0 -33
  280. package/src/contracts/resources.ts +0 -25
  281. package/src/contracts/sampling.ts +0 -23
  282. package/src/contracts/scheduling.ts +0 -54
  283. package/src/contracts/tsconfig.json +0 -14
  284. package/src/dataset/generators.ts +0 -1087
  285. package/src/dataset/index.ts +0 -12
  286. package/src/dataset/job.ts +0 -81
  287. package/src/dataset/llm.ts +0 -71
  288. package/src/dataset/registry.ts +0 -528
  289. package/src/diffusion/diffusion-generate.ts +0 -507
  290. package/src/download.ts +0 -505
  291. package/src/embed.ts +0 -77
  292. package/src/engine/admission.ts +0 -59
  293. package/src/engine/cancellation.ts +0 -38
  294. package/src/engine/engine.ts +0 -56
  295. package/src/engine/execution-coordinator.ts +0 -70
  296. package/src/engine/execution-plan.ts +0 -64
  297. package/src/engine/execution-tasks.ts +0 -44
  298. package/src/engine/namespaced-cache.ts +0 -13
  299. package/src/engine/resources.ts +0 -53
  300. package/src/engine/scheduler.ts +0 -92
  301. package/src/engine/session.ts +0 -247
  302. package/src/eval/README.md +0 -130
  303. package/src/eval/ifeval.ts +0 -81
  304. package/src/eval/kl-prompts.ts +0 -29
  305. package/src/eval/kl.ts +0 -590
  306. package/src/eval/perplexity.ts +0 -164
  307. package/src/eval/quality-db.ts +0 -92
  308. package/src/eval/reference-logits.ts +0 -207
  309. package/src/eval/runner.ts +0 -124
  310. package/src/eval/score.ts +0 -49
  311. package/src/eval/tasks/bfcl.ts +0 -535
  312. package/src/eval/tasks/gsm8k.ts +0 -98
  313. package/src/eval/tasks/hashhop.ts +0 -139
  314. package/src/eval/tasks/humaneval.ts +0 -275
  315. package/src/eval/tasks/ifeval.ts +0 -525
  316. package/src/eval/tasks/mmlu.ts +0 -157
  317. package/src/eval/ultrafeedback.ts +0 -60
  318. package/src/evaldb.ts +0 -199
  319. package/src/expert-io.ts +0 -393
  320. package/src/expert-offload-build.ts +0 -77
  321. package/src/expert-offload.ts +0 -76
  322. package/src/expert-residency.ts +0 -1134
  323. package/src/expert-usage.ts +0 -415
  324. package/src/fill/echo-index.ts +0 -188
  325. package/src/fill/fill-session.ts +0 -463
  326. package/src/fill/proposal.ts +0 -68
  327. package/src/fill/schema-rows.ts +0 -506
  328. package/src/fill/tool-boundary.ts +0 -103
  329. package/src/fit.ts +0 -249
  330. package/src/generate.ts +0 -1352
  331. package/src/grammar.ts +0 -604
  332. package/src/harness-pi.ts +0 -184
  333. package/src/hf-push.ts +0 -628
  334. package/src/hub-rest.ts +0 -242
  335. package/src/index.ts +0 -63
  336. package/src/inference/denoising.ts +0 -17
  337. package/src/inference/draft-acceptance.ts +0 -41
  338. package/src/inference/draft-output.ts +0 -49
  339. package/src/inference/graph.ts +0 -33
  340. package/src/inference/prefill.ts +0 -45
  341. package/src/inference/rollback.ts +0 -7
  342. package/src/jobs/index.ts +0 -31
  343. package/src/jobs/job-entry.ts +0 -107
  344. package/src/jobs/task-client.ts +0 -19
  345. package/src/jobs/types.ts +0 -2
  346. package/src/kv-scheme.ts +0 -279
  347. package/src/kv-store.ts +0 -1135
  348. package/src/lab/README.md +0 -22
  349. package/src/lab/curve/curve-designer.html +0 -303
  350. package/src/lab/curve/curve-sampler.ts +0 -122
  351. package/src/lab/expert-trace/expert-trace.ts +0 -69
  352. package/src/lab/paged-kv/paged-attention.ts +0 -117
  353. package/src/lab/paged-kv/paged-kv-rows.ts +0 -111
  354. package/src/lab/paged-kv/paged-kv.ts +0 -336
  355. package/src/library.ts +0 -40
  356. package/src/lora.ts +0 -408
  357. package/src/md-modules.d.ts +0 -54
  358. package/src/media-fetch.ts +0 -442
  359. package/src/memory/article.ts +0 -558
  360. package/src/memory/chunk-validation.ts +0 -150
  361. package/src/memory/chunk.ts +0 -318
  362. package/src/memory/cluster.ts +0 -351
  363. package/src/memory/coverage.ts +0 -134
  364. package/src/memory/crosslink.ts +0 -0
  365. package/src/memory/db.ts +0 -253
  366. package/src/memory/entity.ts +0 -203
  367. package/src/memory/gate.ts +0 -187
  368. package/src/memory/history.ts +0 -152
  369. package/src/memory/ingest.ts +0 -335
  370. package/src/memory/model.ts +0 -183
  371. package/src/memory/normalize.ts +0 -671
  372. package/src/memory/parse.ts +0 -22
  373. package/src/memory/pipeline.ts +0 -275
  374. package/src/memory/prompts.ts +0 -65
  375. package/src/memory/query.ts +0 -334
  376. package/src/memory/reconcile.ts +0 -734
  377. package/src/memory/redirect.ts +0 -108
  378. package/src/memory/reindex.ts +0 -325
  379. package/src/memory/resolve.ts +0 -307
  380. package/src/memory/rest.ts +0 -245
  381. package/src/memory/route.ts +0 -272
  382. package/src/memory/schedule.ts +0 -165
  383. package/src/memory/stages.ts +0 -777
  384. package/src/memory/synthesize.ts +0 -1638
  385. package/src/memory/tools.ts +0 -749
  386. package/src/memory/vault.ts +0 -1194
  387. package/src/memory/wikify.ts +0 -1064
  388. package/src/mlx/array.ts +0 -425
  389. package/src/mlx/autograd.ts +0 -304
  390. package/src/mlx/checkpoint.ts +0 -149
  391. package/src/mlx/compile.ts +0 -168
  392. package/src/mlx/custom-vjp.ts +0 -188
  393. package/src/mlx/ffi.ts +0 -531
  394. package/src/mlx/materialize.ts +0 -23
  395. package/src/mlx/metal-kernel.ts +0 -159
  396. package/src/mlx/normalized-argmax.ts +0 -116
  397. package/src/mlx/ops.ts +0 -1108
  398. package/src/mlx/quantized-rows.ts +0 -36
  399. package/src/mlx/token-bitmask.ts +0 -52
  400. package/src/mlx/turboquant-kv-decode.ts +0 -82
  401. package/src/mlx/turboquant-kv-inverse.ts +0 -122
  402. package/src/mlx/turboquant-ops.ts +0 -861
  403. package/src/mlx/turboquant-tables.ts +0 -237
  404. package/src/mmap.ts +0 -90
  405. package/src/model/artifact-identity.ts +0 -73
  406. package/src/model/batched-kv.ts +0 -235
  407. package/src/model/batched-mask.ts +0 -279
  408. package/src/model/batched-quant.ts +0 -212
  409. package/src/model/batched-quantized-kv.ts +0 -144
  410. package/src/model/batched-rotating-quant.ts +0 -353
  411. package/src/model/batched-rotating-state.ts +0 -149
  412. package/src/model/batched-rotating.ts +0 -338
  413. package/src/model/batched-row-storage.ts +0 -179
  414. package/src/model/batched-ssm.ts +0 -52
  415. package/src/model/batched-turboquant-kv.ts +0 -94
  416. package/src/model/compiled-decode.ts +0 -712
  417. package/src/model/decoded-kv-donor.ts +0 -12
  418. package/src/model/delayed-quantized-kv.ts +0 -72
  419. package/src/model/delayed-rotating-quantized-kv.ts +0 -93
  420. package/src/model/delayed-turboquant-kv.ts +0 -57
  421. package/src/model/diffusion-gemma.ts +0 -1026
  422. package/src/model/factory.ts +0 -215
  423. package/src/model/fingerprint.ts +0 -45
  424. package/src/model/flash-attention.ts +0 -694
  425. package/src/model/full-prefill-padding.ts +0 -56
  426. package/src/model/full-prefill-row.ts +0 -105
  427. package/src/model/gemma4-base.ts +0 -2370
  428. package/src/model/gemma4.ts +0 -1395
  429. package/src/model/generated/gemma4-12b.ts +0 -429
  430. package/src/model/generated/gemma4-26b.ts +0 -448
  431. package/src/model/generated/gemma4-e4b.ts +0 -717
  432. package/src/model/generated/index.ts +0 -18
  433. package/src/model/glm52-atlas.ts +0 -511
  434. package/src/model/glm52-cache.ts +0 -792
  435. package/src/model/glm52-config.ts +0 -262
  436. package/src/model/glm52-container.ts +0 -305
  437. package/src/model/glm52-coupling.ts +0 -388
  438. package/src/model/glm52-dsa.ts +0 -606
  439. package/src/model/glm52-expert-layout.ts +0 -253
  440. package/src/model/glm52-layout.ts +0 -152
  441. package/src/model/glm52-memory.ts +0 -500
  442. package/src/model/glm52-mla.ts +0 -792
  443. package/src/model/glm52-moe.ts +0 -223
  444. package/src/model/glm52-pilot.ts +0 -537
  445. package/src/model/glm52-reference.ts +0 -445
  446. package/src/model/glm52-residency.ts +0 -557
  447. package/src/model/glm52-resident-weights.ts +0 -135
  448. package/src/model/glm52-streamed-experts.ts +0 -453
  449. package/src/model/glm52-streamed-metal.ts +0 -610
  450. package/src/model/glm52-weights.ts +0 -503
  451. package/src/model/glm52.ts +0 -1132
  452. package/src/model/implementation.ts +0 -69
  453. package/src/model/kv-attention-view.ts +0 -70
  454. package/src/model/minicpm5.ts +0 -376
  455. package/src/model/profile.ts +0 -468
  456. package/src/model/quantized-append-attention.ts +0 -31
  457. package/src/model/qwen-append.ts +0 -12
  458. package/src/model/qwen-conv.ts +0 -52
  459. package/src/model/qwen3-delta-state.ts +0 -74
  460. package/src/model/qwen3-delta.ts +0 -451
  461. package/src/model/qwen3-moe.ts +0 -404
  462. package/src/model/qwen3-mrope.ts +0 -250
  463. package/src/model/qwen3.ts +0 -277
  464. package/src/model/qwen3_5-checkpoint.ts +0 -164
  465. package/src/model/qwen3_5.ts +0 -881
  466. package/src/model/rotating-kv-donor.ts +0 -35
  467. package/src/model/rotating-kv-layout.ts +0 -262
  468. package/src/model/rotating-row-transaction.ts +0 -35
  469. package/src/model/speculative-rotating-kv.ts +0 -101
  470. package/src/model/ssm-prefill-padding.ts +0 -39
  471. package/src/model/support.ts +0 -110
  472. package/src/model/token-groups.ts +0 -66
  473. package/src/model/trellis-balanced-scatter.ts +0 -51
  474. package/src/model/trellis-linear.ts +0 -672
  475. package/src/model/trellis-shared-m.ts +0 -151
  476. package/src/model/trellis-shared-scatter.ts +0 -144
  477. package/src/model/trellis-splitk-prefill.ts +0 -158
  478. package/src/model/trellis-tiled-prefill.ts +0 -136
  479. package/src/model/trellis-vector-expand.ts +0 -62
  480. package/src/model/trellis-wide-prefill.ts +0 -94
  481. package/src/model/turboquant-codec.ts +0 -89
  482. package/src/model/universal/archs.ts +0 -332
  483. package/src/model/universal/dense.ts +0 -612
  484. package/src/model/universal/modules.ts +0 -170
  485. package/src/model/universal/rope.ts +0 -381
  486. package/src/model/whisper.ts +0 -435
  487. package/src/native/expert_io.c +0 -523
  488. package/src/native/frame_extract.swift +0 -140
  489. package/src/native/mic_capture.swift +0 -92
  490. package/src/native-pack.ts +0 -163
  491. package/src/pi-provider.ts +0 -53
  492. package/src/pi-session.ts +0 -81
  493. package/src/pi-terminal.ts +0 -274
  494. package/src/pi-web.ts +0 -1940
  495. package/src/preflight.ts +0 -158
  496. package/src/prompt-cache.ts +0 -682
  497. package/src/quantize/allocator.ts +0 -627
  498. package/src/quantize/atomic-output.ts +0 -38
  499. package/src/quantize/calibration.ts +0 -181
  500. package/src/quantize/config-writer.ts +0 -145
  501. package/src/quantize/index.ts +0 -84
  502. package/src/quantize/job.ts +0 -162
  503. package/src/quantize/quantizer.ts +0 -666
  504. package/src/quantize/rotate.ts +0 -603
  505. package/src/quantize/safetensors-writer.ts +0 -249
  506. package/src/quantize/sensitivity.ts +0 -216
  507. package/src/quantize/trellis.ts +0 -586
  508. package/src/quantize/weight-transform.ts +0 -292
  509. package/src/registry.ts +0 -602
  510. package/src/runtime-config.ts +0 -77
  511. package/src/safetensors.ts +0 -165
  512. package/src/sampler.ts +0 -1012
  513. package/src/serve/admin-routes.ts +0 -184
  514. package/src/serve/assets/curve-terrain.html +0 -105
  515. package/src/serve/assets/training-inference-map.html +0 -575
  516. package/src/serve/audio-routes.ts +0 -323
  517. package/src/serve/aux-routes.ts +0 -132
  518. package/src/serve/batch-scheduler.ts +0 -8
  519. package/src/serve/checkpoint-identity.ts +0 -64
  520. package/src/serve/generation-gateway.ts +0 -537
  521. package/src/serve/isolate.ts +0 -609
  522. package/src/serve/kv-budget.ts +0 -14
  523. package/src/serve/lab-routes.ts +0 -341
  524. package/src/serve/lane-registry.ts +0 -45
  525. package/src/serve/model-admin-routes.ts +0 -155
  526. package/src/serve/model-binding.ts +0 -49
  527. package/src/serve/model-host.ts +0 -511
  528. package/src/serve/parent-application.ts +0 -56
  529. package/src/serve/prompt-response-trace.ts +0 -161
  530. package/src/serve/response-lease.ts +0 -24
  531. package/src/serve/session-search.ts +0 -326
  532. package/src/serve/static-routes.ts +0 -101
  533. package/src/serve/transcription-server.ts +0 -64
  534. package/src/serve/transcription-service.ts +0 -502
  535. package/src/server.ts +0 -1282
  536. package/src/spec/assistant-rows.ts +0 -93
  537. package/src/spec/assistant-source.ts +0 -126
  538. package/src/spec/cache-identity.ts +0 -22
  539. package/src/spec/deepspec-rows.ts +0 -29
  540. package/src/spec/deepspec-source.ts +0 -145
  541. package/src/spec/dflash-source.ts +0 -149
  542. package/src/spec/drafter.ts +0 -304
  543. package/src/spec/dspark/ab-stats.ts +0 -136
  544. package/src/spec/dspark/calibration.ts +0 -112
  545. package/src/spec/dspark/data-dflash.ts +0 -156
  546. package/src/spec/dspark/data.ts +0 -201
  547. package/src/spec/dspark/deepspec-module.ts +0 -776
  548. package/src/spec/dspark/generate-dflash.ts +0 -245
  549. package/src/spec/dspark/generate.ts +0 -290
  550. package/src/spec/dspark/loader.ts +0 -23
  551. package/src/spec/dspark/loss.ts +0 -213
  552. package/src/spec/dspark/module-dflash.ts +0 -560
  553. package/src/spec/dspark/module.ts +0 -540
  554. package/src/spec/dspark/quantize-drafter.ts +0 -91
  555. package/src/spec/dspark/sample.ts +0 -112
  556. package/src/spec/generate.ts +0 -276
  557. package/src/spec/glm52-mtp-graph.ts +0 -29
  558. package/src/spec/glm52-mtp-rows.ts +0 -132
  559. package/src/spec/glm52-mtp-source.ts +0 -318
  560. package/src/spec/glm52-mtp-state.ts +0 -33
  561. package/src/spec/ngram-source.ts +0 -226
  562. package/src/spec/projected-draft-rows.ts +0 -73
  563. package/src/spec/qwen-mtp-module.ts +0 -171
  564. package/src/spec/qwen-mtp-rows.ts +0 -230
  565. package/src/spec/qwen-mtp-source.ts +0 -386
  566. package/src/spec/qwen-mtp-state.ts +0 -30
  567. package/src/spec/serve-loop.ts +0 -587
  568. package/src/spec/source.ts +0 -228
  569. package/src/spec/two-model-rows.ts +0 -62
  570. package/src/spec/two-model.ts +0 -113
  571. package/src/ssd-cache.ts +0 -431
  572. package/src/ssd-durability.ts +0 -209
  573. package/src/storage/host-buffer.ts +0 -24
  574. package/src/storage/kv-writer.ts +0 -83
  575. package/src/storage/kv-writer.worker.js +0 -264
  576. package/src/storage/retention-policy.ts +0 -37
  577. package/src/tiered-prompt-cache.ts +0 -45
  578. package/src/tokenizer.ts +0 -335
  579. package/src/tool-approvals.ts +0 -131
  580. package/src/tool-call.ts +0 -695
  581. package/src/train/dataset.ts +0 -484
  582. package/src/train/diffusion-lora.ts +0 -216
  583. package/src/train/export.ts +0 -32
  584. package/src/train/flash-cce.ts +0 -1234
  585. package/src/train/forward.ts +0 -266
  586. package/src/train/fuse.ts +0 -243
  587. package/src/train/index.ts +0 -46
  588. package/src/train/job.ts +0 -205
  589. package/src/train/lora-params.ts +0 -254
  590. package/src/train/loss.ts +0 -1591
  591. package/src/train/merge.ts +0 -195
  592. package/src/train/optimizer.ts +0 -183
  593. package/src/train/prefix-shared.ts +0 -490
  594. package/src/train/rank.ts +0 -137
  595. package/src/train/segmented.ts +0 -1828
  596. package/src/train/steel-qmm-header.ts +0 -1461
  597. package/src/train/trainer.ts +0 -1221
  598. package/src/train/watch.ts +0 -542
  599. package/src/vision/diffusion-vision.ts +0 -620
  600. package/src/vision/embedder.ts +0 -176
  601. package/src/vision/preprocess.ts +0 -247
  602. package/src/vision/prompt.ts +0 -409
  603. package/src/vision/qwen3vl-preprocess.ts +0 -409
  604. package/src/vision/qwen3vl-prompt.ts +0 -233
  605. package/src/vision/qwen3vl-tower.ts +0 -566
  606. package/src/vision/siglip.ts +0 -607
  607. package/src/vision/video-frames.ts +0 -148
  608. package/src/web/app.html +0 -2155
  609. package/src/web/app.js +0 -5863
  610. package/src/web/skills/memory/SKILL.md +0 -120
  611. package/src/web/skills/web-research/SKILL.md +0 -46
  612. package/src/web/skills.ts +0 -97
  613. package/src/web/src/adapters-panel.ts +0 -288
  614. package/src/web/src/assistant.ts +0 -451
  615. package/src/web/src/chat.ts +0 -1060
  616. package/src/web/src/composer.ts +0 -962
  617. package/src/web/src/dataset.ts +0 -132
  618. package/src/web/src/finetune.ts +0 -267
  619. package/src/web/src/hub.ts +0 -428
  620. package/src/web/src/main.ts +0 -98
  621. package/src/web/src/markdown.ts +0 -0
  622. package/src/web/src/memory-panel.ts +0 -572
  623. package/src/web/src/model-picker.ts +0 -159
  624. package/src/web/src/palette.ts +0 -346
  625. package/src/web/src/protocol.ts +0 -26
  626. package/src/web/src/quantize.ts +0 -167
  627. package/src/web/src/rag.ts +0 -274
  628. package/src/web/src/sessions.ts +0 -469
  629. package/src/web/src/shell.ts +0 -804
  630. package/src/web/src/ui-catalog.ts +0 -78
  631. package/src/web/src/voice.ts +0 -141
  632. package/src/web/vendor/README.md +0 -61
  633. package/src/web-assets.ts +0 -47
  634. package/src/web-tools.ts +0 -478
  635. package/src/weights.ts +0 -255
  636. /package/src/{serve → server}/completion-sink.ts +0 -0
  637. /package/src/{serve → server}/generated-token-history.ts +0 -0
  638. /package/src/web/{icon.svg → public/icon.svg} +0 -0
  639. /package/src/web/{manifest.webmanifest → public/manifest.webmanifest} +0 -0
  640. /package/src/web/{vendor → public/vendor}/hljs-LICENSE +0 -0
@@ -1,3587 +0,0 @@
1
- # mlx-bun benchmark results
2
-
3
- Logit comparisons, serving performance, and instructions for reproducing the
4
- measurements. Model support and configuration limits are in the
5
- [model roster](models.md). Historical experiments, failures, and source hashes
6
- remain in the [campaign ledger](../archive/investigations/benchmark-ledger-through-v0.4.0.md).
7
-
8
- To compare saved results locally, run:
9
-
10
- ```sh
11
- bun scripts/bench/report.ts --out reports/comparison.html <result.json>...
12
- ```
13
-
14
- The standalone HTML accepts serving schema-4, native schema-1 and saved Pi
15
- `fresh-pi-kanban-task` results. A task's adjacent `quality.json` supplies its
16
- individual app acceptance checks. The report shows completed output tokens,
17
- task time, weighted post-first-output throughput, summed first-output waits,
18
- cache hits, final persistence status, tool errors and captured settings.
19
- Missing data remains unknown; failed or incomplete tasks have no completed-task
20
- throughput. Quality scores are calculated from the checks, with failures and
21
- blocked checks shown separately. File hashes identify the imported evidence;
22
- the renderer does not rerun app validation. Task rows never supply engine-speed
23
- ratios.
24
-
25
- To add saved model-quality results, export the existing evaluation ledger:
26
-
27
- ```sh
28
- bun scripts/bench/quality-report.ts --db "$HOME/.cache/mlx-bun/evals.sqlite" --out reports/quality.json
29
- bun scripts/bench/report.ts --out reports/comparison.html reports/quality.json <result.json>...
30
- ```
31
-
32
- The exporter reads SQLite without changing it. The portable JSON retains task
33
- accuracy, sample count, KL statistics/reference, safetensors size, captured
34
- configuration, commit, machine record and notes. Plots group accuracy and size
35
- by task and recorded machine; missing size stays unknown. Legacy rows do not
36
- guarantee dataset revision, sample selection or artifact content hashes, so
37
- the report supplies no inferred quality deltas or performance ratios. The M1
38
- ledger's 77 rows are preserved in `reports/prefill-observation/quality-ledger-m1.json`;
39
- the rendered table and plots are in `quality-history.html` beside it.
40
-
41
- The five saved Kanban runs below render together in
42
- `reports/kanban-decode-fixed-prefill-r1/comparison.html`. Browser review confirms
43
- their recorded scores and timings, expandable acceptance/turn records, and
44
- no blocking script errors. Model-free tests cover missing records, failed
45
- execution, contradictory summaries, escaping and CLI import.
46
-
47
- ## 1. Parity (porting correctness) — bit-exact vs the oracle
48
-
49
- These recorded results compare logits under matching model, cache, execution
50
- shape and machine conditions. They establish agreement for the tested inputs,
51
- not identical responses across arbitrary batching shapes or sampling settings.
52
- Oracle fixtures are generated by the pinned Python reference.
53
-
54
- | model | L1: mlx-lm, standard (bf16) KV | L2: mlx-optiq, mixed-precision KV | proof |
55
- |---|---|---|---|
56
- | MiniCPM5-1B | ✓ 100/100 logit vectors | ✓ 100/100 logit vectors | [decode](../../tests/parity/minicpm5-parity.test.ts), [mixed KV](../../tests/parity/minicpm5-kv-parity.test.ts) |
57
- | gemma-4-e4b | ✓ | ✓ | [decode](../../tests/parity/parity.test.ts), [quantized KV](../../tests/parity/kv-quant.test.ts) |
58
- | gemma-4-12B | ✓ | ✓ | [decode](../../tests/parity/parity.test.ts), [quantized KV](../../tests/parity/kv-quant.test.ts) |
59
- | gemma-4-26B | ✓ | ✓ (mixed per-layer scheme) | [MoE decode](../../tests/parity/parity-26b.test.ts), [rotating KV](../../tests/parity/rotating-kvq.test.ts) |
60
-
61
- Fused quantized-attention prefill is separately bit-exact against
62
- optiq's reference ([SDPA test](../../tests/parity/fused-sdpa.test.ts)).
63
-
64
- Reproduce the MiniCPM5 comparison with the [pinned setup and fixture recipe](environment.md#reproduce-the-minicpm5-logit-comparison).
65
-
66
- Recipe acceptance, 2026-09-11, M1 Max 32 GB: a clean source export with
67
- a new Python environment and empty Hugging Face model cache passed all 100
68
- full logit vectors and 100 greedy tokens. Dependency installation took 0.92 s,
69
- oracle setup 5.15 s, and model download plus generation/comparison 46.82 s.
70
- The Python package cache was warm. This single setup check is not a download
71
- time guarantee or a serving-performance measurement. The fixture manifest
72
- records the model, native wheel and oracle provenance.
73
-
74
- ## 2. Performance — like-for-like numbers
75
-
76
- The latest standard comparison is shown first, with machine conditions and
77
- losses retained. These diagnostic results are observations of this workload,
78
- not a universal speed ranking.
79
-
80
- ### Lossless weight interleaving with RAM/SSD caching — M4 Pro 24 GB (2026-09-13)
81
-
82
- R6's remaining cache-enabled acceptance compares the original and two-block
83
- interleaved Qwen3.8-27B k300 packed artifacts. The existing inverse-code proof
84
- establishes identical quantized weights. All twelve standard suites use source
85
- `2c88d72`, Bun 1.4.2, MLX 0.32.2, variant 13, KV4 group 64, folded RTN4 MTP2,
86
- fixed prefill 256 and default shared scheduling. RAM prompt caching is 4 GiB;
87
- the standard script also tests SSD flush and fresh-process restore. No forced
88
- serial arm is used. Async expansion, compiled decode and fill are off.
89
-
90
- Six balanced original/interleaved pairs complete all 228 requests with no
91
- failures. Every request reports the batched lane. All 114 paired request
92
- hashes, response text hashes, complete usage records, counts and finish reasons
93
- match, including the four concurrent streams. Every SSD flush is durable with
94
- no pending, dropped or failed writes, and all twelve restarts reuse 10,398
95
- prompt tokens. The measured context has 10,399 tokens. All suites retain the
96
- same source hash at start and save.
97
-
98
- Each cell below is **original / interleaved**. Short decode produces 192 tokens;
99
- cached context completion produces 64, and aggregate uses four 128-token streams.
100
-
101
- | Pair, original/interleaved suite | Short decode tok/s | Context decode tok/s | Cached completion ms | Aggregate tok/s |
102
- |---|---:|---:|---:|---:|
103
- | 0/1 | 18.824 / 19.125 | 20.767 / 21.283 | 3150.0 / 3068.8 | 16.727 / 16.927 |
104
- | 3/2 | 18.737 / 19.314 | 20.719 / 21.313 | 3152.1 / 3070.7 | 16.817 / 16.930 |
105
- | 4/5 | 18.737 / 19.331 | 20.693 / 21.369 | 3156.2 / 3062.1 | 16.796 / 16.917 |
106
- | 7/6 | 18.728 / 19.141 | 20.745 / 21.265 | 3154.8 / 3068.4 | 16.810 / 16.922 |
107
- | 8/9 | 18.729 / 19.345 | 20.768 / 21.339 | 3147.9 / 3064.6 | 16.843 / 16.915 |
108
- | 11/10 | 18.742 / 19.159 | 20.739 / 21.300 | 3154.5 / 3066.6 | 16.798 / 16.915 |
109
-
110
- Interleaving improves short decode in all six pairs by 1.60–3.29%, and cached
111
- completion time falls 2.58–2.98%. Median paired changes are +2.65% short decode,
112
- +2.73% context decode, −2.69% cached completion time and +0.68% aggregate
113
- throughput. Short complete-request time falls in every pair by 1.32–2.88%.
114
- Cold-context first-output time is essentially flat, decreasing 0.07–0.18%.
115
- Peak RSS changes are mixed, −0.72% to +0.49%; there is no general memory claim.
116
- This closes R6's cache-enabled acceptance for the existing interleaved artifact.
117
- It does not change registry artifacts or qualify other weight bit widths.
118
-
119
- The diagnostic run records 545 activity samples, 539 with active Bun work;
120
- 524 identify an active Bun process as the last GPU submitter. Fifteen active
121
- samples instead identify Codex or Terminal. There are no observer errors.
122
- Last submission does not measure utilization, and this is not a contention-free
123
- claim. CPU activity and retained swap remain recorded with the raw evidence.
124
-
125
- Command profile: `bun scripts/bench-serve.ts all --model-path <artifact>
126
- --label qwen38-k300 --arms mlx-bun --no-serial --draft-model <folded-rtn4>
127
- --num-draft-tokens 2 --kv-quant 4 --prompt-cache 4 --context 16384 --tokens 192
128
- --diagnostic`, with fixed prefill 256 and the environment above.
129
- Raw evidence on both Macs: `reports/prefill-observation/interleave-cache-shared-{0..11}.md.json`,
130
- matching text/log reports, plan, activity and review. The plan records full
131
- artifact paths, ordering and exact commands.
132
-
133
- ### Shared strict tool continuations — M4 Pro 24 GB (2026-09-13)
134
-
135
- The shared strict-fill method reuses prefill, row state, sampling and generated
136
- RAM/SSD caching. Qualified Qwen B1 uses its existing multi-position append;
137
- wider cohorts preserve one-position arithmetic. Fill remains off by default.
138
-
139
- Six bounded HTTP arms use the interleaved Qwen3.8-27B k300 packed artifact,
140
- Bun 1.4.2, MLX 0.32.2, variant 13, KV4 group 64 from start zero, fixed prefill
141
- 256, 1 GiB RAM cache and a fresh 4 GiB SSD directory per arm. No draft is loaded;
142
- compiled decode and async expansion are off. Shared arms omit `--batch` and
143
- use the default cap eight; serial controls explicitly use `--batch 1`.
144
- Each arm includes ten saved tool-turn fixtures, warmup, explicit seed, an
145
- ordinary response with tools available, four concurrent requests and an SSD
146
- restart. Temperature is zero; tools are recorded fixtures and are not executed.
147
-
148
- All 108 responses complete without errors. Every paired input, response text,
149
- tool name/arguments, finish reason, token count and cached-token count matches.
150
- All six SSD flushes are durable with zero missing, dropped or failed snapshots;
151
- each fresh process restores 284 tokens of the 285-token restart request.
152
- All shared responses report `lane: batched`. Shared strict arms each inject
153
- 220 tokens across 13 requests; serial injects 201 across 12 because explicit
154
- serial fill excludes user-fixed seeds.
155
-
156
- | Arm, in execution order | Ten-fixture total ms | Ordinary response ms | Slowest of four concurrent requests ms |
157
- |---|---:|---:|---:|
158
- | Shared, fill off | 38,020.4 | 19,655.7 | 4,065.9 |
159
- | Shared, strict fill | 32,888.2 | 19,685.0 | 3,826.5 |
160
- | Serial, strict fill | 32,847.0 | 19,659.9 | 7,353.8 |
161
- | Serial, strict fill | 32,850.0 | 19,670.4 | 7,375.3 |
162
- | Shared, strict fill | 32,855.4 | 19,666.0 | 4,083.5 |
163
- | Shared, fill off | 38,013.7 | 19,671.4 | 3,986.8 |
164
-
165
- Shared strict fill reduces the sequential fixture total by **13.50% / 13.57%**
166
- against shared fill-off. Its total differs from serial strict fill by
167
- **+0.13% / +0.02%**. Ordinary response time changes +0.15% / −0.03% against
168
- shared fill-off. Concurrent fill-on/off timing is mixed. Shared execution
169
- finishes the four-request set sooner than serial, but the first submitted
170
- request takes 3,468 / 2,379 ms versus 1,520 / 1,522 ms under serial. These are
171
- request durations from concurrently issued calls, not a stationary-load
172
- capacity measurement. The throughput/first-request latency tradeoff remains.
173
-
174
- The run preserves 634 source/config hashes with no start/end changes and 88
175
- activity samples with no observer failures. It is a diagnostic measurement;
176
- CPU, GPU and memory activity are retained. Source is `16c2201` plus the saved
177
- shared-fill diff. A subsequent binding correction uses the same model-declared
178
- format predicate in both execution methods: KV8 retains specialized append,
179
- while k4v3 fills through one-position execution. Both seeded native checks pass;
180
- the measured KV4 selection is unchanged.
181
-
182
- The earlier HTTP attempt accidentally shared one SSD directory across arms.
183
- Its responses remain available, but its timing cannot isolate the fill change.
184
- The corrected run above uses separate directories. Native delayed-conversion
185
- failures also remain recorded: exposing cache-owned append boundaries and
186
- propagating committed attention policy fixes both. Full hidden values, live
187
- cache bytes and continuation logits pass on M4 across bf16/KV4/k8v3 and delayed
188
- formats, including B2 retirement into a specialized B1 append. Equivalent M1
189
- MiniCPM row-state checks pass. Seeded method replay also covers M1 Qwen0.8B and
190
- Gemma4-e4b. This closes the covered shared strict-fill HTTP/cache comparison;
191
- speculative/echo fill, media and broader held-out task combinations remain open.
192
-
193
- Raw evidence on both Macs: `reports/prefill-observation/shared-fill-http.json`,
194
- `shared-fill-http-review.json`, activity/server logs and the exact source bundle.
195
- The `shared-fill-http-initial*` files preserve the invalid-cache experiment.
196
- Native logs use the `shared-fill-append-*`, `shared-fill-burst-*` and
197
- `shared-fill-format-selection-*` prefixes.
198
-
199
- ### Fused TurboQuant default — shared serving (2026-09-13)
200
-
201
- The default candidate changes only packed KV decoding for requests that already
202
- select TurboQuant. The existing accepted kernel, codec bytes and eligibility
203
- rules are unchanged; `MLX_BUN_TURBOQUANT_FUSED_DECODE=0` supplies the control.
204
- The standard script runs off/default/default/off with default shared scheduling,
205
- 192 short output tokens, a 16,384-token context target, four concurrent streams,
206
- 4 GiB RAM cache and SSD restart. Each machine compares its own outputs.
207
-
208
- M1 Max 32 GB uses MiniCPM5-1B OptiQ-4bit with k8v3 and ordinary decode. The
209
- measured context contains 9,062 tokens. All four suites complete without errors;
210
- all 76 requests report the batched lane, and all four SSD flush/restart checks
211
- pass. Source hashes remain fixed. Each paired short/context response and full
212
- usage record is identical. Three of four concurrent responses differ in each
213
- pair while counts and finish reasons match; their throughput is an observed
214
- serving result, not an identical-output speed ratio.
215
-
216
- | M1 MiniCPM metric | Off → default, first pair | Off → default, reverse pair |
217
- |---|---:|---:|
218
- | Short decode (tokens/s) | 62.02 → 91.28 | 58.30 → 79.90 |
219
- | Short complete request (ms) | 3,126.77 → 2,160.84 | 3,327.89 → 2,433.64 |
220
- | Decode at context (tokens/s) | 32.61 → 67.71 | 31.84 → 67.87 |
221
- | Cached 64-token completion (ms) | 1,964.74 → 956.20 | 2,018.15 → 948.01 |
222
- | Cold context first output (ms) | 3,973.51 → 3,838.52 | 3,956.20 → 3,844.87 |
223
- | Four-stream aggregate (tokens/s) | 219.29 → 259.28 | 200.76 → 258.06 |
224
- | Peak sampled RSS (MiB) | 1,459.05 → 1,423.50 | 1,467.69 → 1,463.06 |
225
-
226
- Short complete time falls 26.9–30.9%; cached complete time falls 51.3–53.0%.
227
- The observer records 28 samples with no collection errors; 22 of 27 active-Bun
228
- samples name that process as the last GPU submitter, and five name Terminal.
229
- This is a diagnostic serving comparison, with two balanced pairs rather than
230
- a statistical significance claim. It supports the earlier repeated codec
231
- measurements; it does not change the default cache quantization format.
232
-
233
- Reports: `reports/prefill-observation/tq-default-minicpm-m1-{0..3}.md.json`,
234
- `.../tq-default-minicpm-m1-review.json` and the adjacent activity/plan files.
235
- M4 Pro 24 GB uses the packed interleaved Qwen3.8-27B target, its folded RTN4
236
- companion at MTP3, k8v3 and fixed 256-token prefill chunks. Asynchronous weight
237
- expansion is explicitly off in both arms. All four suites complete with 76
238
- batched requests, no failures, fixed source hashes and durable SSD restart.
239
- Every paired request, including concurrent requests, matches input, response
240
- text, complete usage and finish reason. The measured context has 10,399 tokens.
241
-
242
- | M4 Qwen/MTP3 metric | Off → default, first pair | Off → default, reverse pair |
243
- |---|---:|---:|
244
- | Short decode (tokens/s) | 18.56 → 18.03 | 18.18 → 18.33 |
245
- | Short complete request (ms) | 11,527.54 → 11,867.76 | 11,749.39 → 11,665.97 |
246
- | Decode at context (tokens/s) | 12.67 → 21.58 | 12.66 → 21.53 |
247
- | Cached 64-token completion (ms) | 5,230.11 → 3,053.58 | 5,230.00 → 3,059.66 |
248
- | Cold context first output (ms) | 93,008.61 → 90,598.29 | 93,032.18 → 90,656.40 |
249
- | Four-stream aggregate (tokens/s) | 17.14 → 17.23 | 17.13 → 17.21 |
250
- | Peak sampled RSS (MiB) | 15,086.63 → 15,140.56 | 15,160.28 → 15,103.94 |
251
-
252
- Cached complete time falls 41.5–41.6% and context decode improves about 70% in
253
- both pairs. Short complete time is mixed: +2.95% in the first pair and −0.71%
254
- in the reverse. No broad short-decode or memory saving is claimed. The observer
255
- records 188 samples without errors; 178 of 185 active-Bun samples name a test
256
- process as the last GPU submitter. Other samples name Codex, Terminal or
257
- loginwindow. Retained swap and process activity stay in the diagnostic records.
258
-
259
- These results support selecting the existing fused decoder by default for
260
- TurboQuant, with the short-Qwen tradeoff explicit and `=0` retained. They also
261
- confirm its composition with shared MTP. They do not change quantization or
262
- claim a new Kanban speedup: that accepted task uses affine KV4.
263
- Reports: `reports/prefill-observation/tq-default-shared-{0..3}.md.json`,
264
- `.../tq-default-shared-review.json`, the source patch and activity/plan files.
265
- Both-machine focused checks and existing native gates remain separate from
266
- this serving comparison. The default change passes 2,320 model-free tests
267
- with 14 fixture skips, all three typechecks and hygiene.
268
-
269
- ### Combined TurboQuant/MTP expansion pressure — M4 Pro (2026-09-13)
270
-
271
- The saved seven-request agent-boundary fixture passes on M4 Pro 24 GB with
272
- variant 13, fused TurboQuant k8v3, the packed interleaved Qwen target and folded
273
- RTN4 draft at MTP depth 3. Three fresh shared servers compare synchronous
274
- expansion with 8 GiB and 1 GiB RAM caches, then bounded asynchronous expansion
275
- with a 1 GiB cache. Shared capacity is four; these requests arrive sequentially
276
- and use actual B=1. The separate concurrent-row gates remain the B>1 evidence.
277
-
278
- All 21 responses preserve choices and complete usage records, including draft
279
- acceptance. The final request has 14,467 prompt tokens, reuses 12,955 and emits
280
- 512 tokens. Each server persists 14 SSD entries (5,373,652,992 bytes), including
281
- the final 14,979-token checkpoint, with zero pending, missing, dropped or failed
282
- writes. All servers exit successfully; source, fixture and artifact-config
283
- hashes remain fixed. This run tests persistence but does not trigger an SSD
284
- restore. Existing restart tests supply that separate evidence.
285
-
286
- | Expansion / RAM limit | Final RAM entries / bytes | Async / blocking submissions | Maximum observed active allocation |
287
- |---|---:|---:|---:|
288
- | Synchronous / 8 GiB | 6 / 2,933,437,440 | 0 / 4,224 | 15,974,600,266 B |
289
- | Synchronous / 1 GiB | 1 / 598,766,592 | 0 / 4,224 | 13,872,975,434 B |
290
- | Bounded async / 1 GiB | 1 / 598,766,592 | 4,017 / 207 | 14,736,281,254 B |
291
-
292
- The asynchronous arm exercises both sides of the existing allocation threshold.
293
- Its observer preserves every projection argument, including the contiguous-row
294
- proof used by wide prefill. Five-second process/GPU samples, RSS, vmmap and
295
- system memory records are retained. The last GPU submitter belongs to the test
296
- server in 49/50, 49/50 and 29/49 samples respectively; the remaining samples
297
- name Codex or Terminal. A last-submitter field does not establish sustained
298
- GPU ownership or utilization by that process. The machine starts with 84% free memory
299
- and 3,481 MB retained swap. This is a completed combined-pressure correctness
300
- gate; its sequential arm order does not establish a performance gain.
301
- The bounded expansion flag remains off by default.
302
-
303
- Raw evidence and the checked summary are
304
- `reports/prefill-observation/combined-tq-mtp-pressure{,-review}.json`, with
305
- `pressure-*.server.log`, boundary observations and the captured runner sources
306
- in `completed-acceptance-runner-sources.json`. The three SSD directories remain
307
- on M4 at the paths recorded in each row.
308
-
309
- ### Default batched h2h after token-history reuse — M4 Pro (2026-09-13)
310
-
311
- The final two standard suites use `9411c11`, Bun 1.4.2 and MLX 0.32.2 on the
312
- 24 GB M4 Pro, with the same artifacts, workload and opposite arm orders as the
313
- initial integrated comparison below. Early output stays enabled; no arm forces
314
- serial. All 18 cells and 342 requests complete without phase failures. The 114
315
- default requests report batched execution, and all twelve Bun cells complete
316
- SSD flush/restore. Both source snapshots and recorded diffs remain fixed.
317
-
318
- Each entry is **order A / order B**. These are observed SSE-window and concurrent
319
- completion rates; the response qualifications below apply.
320
-
321
- | Model | Default short tok/s | Reference short tok/s | Default aggregate tok/s | Reference aggregate tok/s |
322
- |---|---:|---:|---:|---:|
323
- | MiniCPM5-1B | 277.56 / 274.51 | 224.54 / 223.13 | 704.24 / 703.01 | 405.49 / 391.53 |
324
- | Gemma4-e4b | 58.26 / 59.06 | 54.17 / 54.14 | 170.41 / 170.03 | 131.45 / 131.21 |
325
- | Gemma4-12B | 26.35 / 26.53 | 25.53 / 25.50 | 74.50 / 74.96 | 65.36 / 65.29 |
326
-
327
- All 30 short and 18 context comparisons preserve input hashes, response text,
328
- usage counts and finish status against both the September 11 run and the
329
- matching pre-fix order. Both Gemmas also preserve the pre-fix concurrent outputs;
330
- MiniCPM concurrent outputs vary. Historical concurrent texts differ on every
331
- model, so those rates do not establish identical-output historical speed ratios.
332
- The stock MiniCPM thinking-boundary difference remains a separate qualification.
333
-
334
- MiniCPM cached 64-token completion improves to 393.10 / 403.64 ms from
335
- 403.93 / 409.10 ms in the initial integrated matrix; TTFT remains 14.92 / 16.62 ms.
336
- This confirms a smaller request-level benefit with default early output than
337
- the dedicated off-control pairs below. Other changes stay visible: e4b cached
338
- completion is 1332.60 / 1350.75 ms and 12B is 2653.13 / 2660.25 ms. Short decode
339
- is effectively close to the initial matrix, with mixed directions by model and
340
- order. This is not evidence of a broad new decode-kernel gain.
341
-
342
- The diagnostic observer records 232 samples without collection errors. During
343
- 222 active-worker samples, an owned inference process is last GPU submitter in
344
- 205; eleven name Codex and six Terminal. Median collection cost is 16 ms,
345
- maximum 53 ms. Last submission does not measure utilization. The retained
346
- activity and machine reports accompany these results; no additional quietness
347
- or statistical significance claim is made.
348
-
349
- Raw plans, both suites, activity and comparisons:
350
- `reports/prefill-observation/standard-history-reuse-*`. The combined offline
351
- serving/task/quality report is `reports/prefill-observation/integrated-comparison.html`.
352
-
353
- ### Initial integrated default batched h2h — M4 Pro (2026-09-13)
354
-
355
- Two complete standard suites use source `565bc13`, Bun 1.4.2 and MLX 0.32.2
356
- on the 24 GB M4 Pro. They retain the September 11 artifacts and complete
357
- `bench-serve-v2` workload: five 192-token short decode samples, a 16,384-token
358
- context target and four concurrent 128-token requests. Order A runs default
359
- Bun, stock reference, then mixed-KV Bun; order B reverses those arms. Neither
360
- forces serial. All 114 default-Bun requests report the batched lane.
361
-
362
- Each table entry shows **order A / order B**. Short decode is the median
363
- visible SSE-window rate; aggregate is completed output tokens divided by
364
- the four-request wall time.
365
-
366
- | Model | Default short tok/s | Reference short tok/s | Default aggregate tok/s | Reference aggregate tok/s |
367
- |---|---:|---:|---:|---:|
368
- | MiniCPM5-1B | 277.73 / 276.32 | 224.79 / 223.01 | 708.87 / 701.73 | 401.82 / 397.40 |
369
- | Gemma4-e4b | 59.39 / 58.64 | 54.06 / 53.99 | 171.35 / 170.60 | 131.69 / 131.62 |
370
- | Gemma4-12B | 26.68 / 26.53 | 25.52 / 25.53 | 75.18 / 74.28 | 65.37 / 65.38 |
371
-
372
- Against the September 11 default rows below, short decode ranges from 1.7%
373
- lower to 0.1% higher across these models. Observed aggregate throughput rises
374
- 0.3–1.3% for MiniCPM, 2.8–3.3% for e4b and 8.2–9.5% for 12B. Those historical
375
- comparisons are observations across sessions. The fresh reference is also
376
- slower than its September 11 result, so the changing reference margin alone
377
- cannot establish an engine improvement.
378
-
379
- Every historical default short/context request matches input hash, output
380
- text, prompt/generated/cached counts and finish status: 30 short and 18
381
- context comparisons across the two runs. Concurrent inputs and counts match,
382
- but several texts differ, including between the two MiniCPM orders. These
383
- aggregate rows are not identical-output speed ratios. Both Gemmas match all
384
- fresh reference short-decode outputs; MiniCPM retains its documented stock
385
- reference thinking-boundary difference. All fresh context texts match;
386
- e4b has one cache-count difference per suite, and concurrent Gemma cache counts
387
- differ between stacks.
388
-
389
- All 18 cells complete without phase failures. The twelve Bun cells flush
390
- durably and restore their SSD prefixes. Source snapshots remain unchanged.
391
- Losses remain visible: MiniCPM context SSE throughput is 159.00–160.15 tok/s
392
- versus 176.56 previously, with cached 64-token completion at 403.93–409.10 ms
393
- versus 384.75 ms. Its first output improves to 14.29–15.51 ms from 28.81 ms.
394
- Gemma e4b cached completion is 1342.87–1345.22 ms versus 1300.40 ms; 12B is
395
- 2657.35–2658.98 ms versus 2606.45 ms. The MiniCPM on/off and source controls
396
- below separate output-window effects from complete-request cost.
397
-
398
- Both suites are diagnostic. Initial free memory is 89% with 3,976 MB of
399
- retained swap. A five-second observer has no collection errors and identifies
400
- an owned inference process as last GPU submitter in 201 of 219 active-worker
401
- samples. Eleven name Codex and seven name Terminal; last submission is not
402
- utilization or proof of exclusive GPU time. The observer takes a median 16 ms
403
- and maximum 52 ms per sample. Preserve these conditions when comparing runs;
404
- two opposite orders do not supply a statistical significance claim.
405
-
406
- Raw suites, activity, frozen command plan and comparisons are
407
- `reports/prefill-observation/standard-integrated-{0,1}.md.json`,
408
- `standard-integrated-activity.jsonl`, `standard-integrated-plan.json` and
409
- `standard-integrated-review.json`. Packed Qwen remains outside this
410
- stock-reference matrix because its artifact has no stock loader.
411
-
412
- #### MiniCPM output timing and source controls
413
-
414
- Four standard MiniCPM suites on the same M4 use early-output order off/on/on/off
415
- at fixed source `565bc13`. Cached 9,062-token prompts generate 64 tokens.
416
- Earlier output reduces median cached TTFT from 25.71–28.14 ms to 14.46–14.76 ms;
417
- complete time remains 406.43–409.63 ms across the four suites. The SSE interval
418
- starts earlier, explaining part of its lower displayed decode rate. Keep the
419
- early-output default. This does not explain the whole historical completion gap.
420
-
421
- A fresh old/current/current/old comparison uses `47620a5` and `565bc13`, with
422
- the current measurement scripts and support helpers on both sources. Early
423
- output is off throughout. Cached completion is 396.20 / 409.04 / 406.45 / 383.96 ms.
424
- The old source therefore reproduces a smaller completion cost under these
425
- conditions. Peak RSS is approximately 1,253–1,275 MB old versus 1,485–1,491 MB
426
- current. That observation alone does not attribute either difference to an
427
- individual cache or decode change.
428
-
429
- Both four-suite controls retain all short/context input hashes, response texts,
430
- counts and finish status. Concurrent texts vary despite matching requests and
431
- counts, including within one source, and do not support identical-output ratios.
432
- Each suite has a fixed source snapshot and no phase failures. The source
433
- control observer names an owned inference worker as last GPU submitter in all
434
- eight active-worker samples. The early-output control has eight owned and one
435
- Terminal sample. These are bounded diagnostic controls, not utilization traces.
436
- Raw plans, requests, source hashes, activity and comparisons are under
437
- `reports/prefill-observation/minicpm-{early,source}-control-*`.
438
-
439
- #### Reuse identical token-history conversions
440
-
441
- The sampler-only old/current/current/old control holds all other source at
442
- `565bc13`: cached completion is 403.80 / 405.04 / 406.35 / 403.97 ms. This small
443
- change does not explain the historical gap. An earlier cache-source screen
444
- at `c953f2f` also reproduces approximately 406–410 ms. Its tracked source matches
445
- that commit, with ten later, unreferenced modules left in the temporary tree;
446
- full source manifests retain that distinction.
447
-
448
- A separate instrumented run measures `GeneratedTokenHistory.remember` taking
449
- 7.45–21.62 ms to decode 9,125 IDs into text. Cache publication can repeat that
450
- same checkpoint. The retained implementation compares IDs against the bounded
451
- provenance entries and refreshes an exact match without another decode or copy.
452
- It still decodes new sequences and replaces provenance when different IDs spell
453
- the same text. It changes no model, sampler or cache-state computation.
454
-
455
- A paired standard-suite screen uses treatment/control/control/treatment, early
456
- output off and otherwise identical `565bc13` source. The cached 64-token
457
- completion medians are **390.69 / 408.83 / 407.37 / 392.76 ms**, improvements of
458
- 4.4% and 3.6% within the adjacent pairs. All 24 short/context comparisons against
459
- the first suite preserve input hashes, response text, usage counts and finish
460
- status. Concurrent outputs remain partly variable. All four suites complete
461
- without failures or changing source snapshots; all eight active-worker samples
462
- name an owned inference worker as last GPU submitter. The observer median is
463
- 20.5 ms with a 50 ms maximum. These diagnostic pairs support the specific reuse
464
- change, not a cross-model or statistical significance claim.
465
-
466
- The provenance/retention tests pass, including exact BPE IDs, same-text/different-ID
467
- replacement and eviction order. All three TypeScript projects pass. Raw
468
- sampler/cache screens, instrumented timings and reuse pairs are under
469
- `reports/prefill-observation/minicpm-{sampler-control,cache-control,history-observation,history-reuse}-*`.
470
- The full default-on standard matrix above completes this specific acceptance step.
471
-
472
- ### Default batched h2h without serial controls — M4 Pro (2026-09-11)
473
-
474
- This comparison uses default batching without a forced-serial arm.
475
- Machine: Apple M4 Pro, 24 GB, source `47620a5`, Bun 1.4.2,
476
- MLX 0.32.2 and pinned mlx-lm 0.31.3. The 12B reference uses OptiQ registration
477
- for its artifact before mlx-lm serving. The command manifest contains no
478
- `--batch` override, and **all 57 requests to the default Bun arm report
479
- `lane=batched`**, including lone requests. Five short-decode samples per model
480
- each generate 192 tokens; the aggregate leg submits four concurrent requests.
481
-
482
- | Model | Default / reference short decode tok/s | Default lead | Default / reference aggregate tok/s | Default lead | Default / reference median request ms |
483
- |---|---:|---:|---:|---:|---:|
484
- | MiniCPM5-1B | 281.08 / 237.28 | +18.5% | 699.58 / 420.52 | +66.4% | 706.67 / 880.25 |
485
- | Gemma4-e4b | 59.37 / 55.89 | +6.2% | 165.95 / 134.58 | +23.3% | 3310.74 / 3659.64 |
486
- | Gemma4-12B | 26.65 / 25.94 | +2.8% | 68.63 / 66.22 | +3.6% | 7428.84 / 7812.49 |
487
-
488
- Default serving wins short decode, total short-request latency and aggregate
489
- throughput for these three models. It does not win every context metric:
490
- e4b context decode is 51.59 versus 52.23 tok/s, and its cold context first
491
- output is 7,880 versus 7,839 ms. MiniCPM context decode is 176.56 versus
492
- 153.33 tok/s; 12B is 25.76 versus 24.93 tok/s. Actual context lengths are
493
- 9,062 MiniCPM tokens and 9,589 Gemma tokens. After restarting, default Bun
494
- restores 9,061/9,588/9,588 tokens from SSD, with first output in approximately
495
- 95/390/1,659 ms; the reference re-prefills with zero restored tokens.
496
-
497
- All nine cells complete without phase failures; the six Bun default/mixed
498
- cells all flush durably and restore their SSD prefixes successfully.
499
- All fifteen short-decode request hashes, token counts and finish statuses
500
- match across stacks. Both Gemmas match all five timed response texts;
501
- MiniCPM retains the separately investigated stock-reference thinking-boundary
502
- output difference. Source hashes stay fixed. This is a single ordered
503
- diagnostic suite: initial free memory is 91%, retained swap 1,916 MB and
504
- `appstoreagent` occupies approximately one CPU core. The mixed-KV arms remain
505
- in the standard suite; they are not the default rows above.
506
-
507
- The 12.14 GiB packed Qwen artifact has no stock-reference loader, so it is
508
- excluded from this same-artifact h2h. Its [KV4/TQ measurements](#released-v040-packed-qwen-with-kv4tq-and-mtp2--m4-pro-2026-09-11) appear below; the larger registry Qwen is not substituted.
509
- Raw command manifest, report and comparison live in
510
- `reports/release-v0.4.0-standard/default-batched-h2h-{manifest.json,m4.md.json,review.json}`.
511
-
512
- ### Whisper speech-to-text head-to-head — M1 Max 32 GB (2026-09-15)
513
-
514
- `bun scripts/bench/whisper.ts --reps 5` (min of 5 warm in-process runs per
515
- cell; every engine decodes the same 16 kHz clips; `mlx-community/
516
- whisper-large-v3-turbo` fp16 for the MLX arms, `ggml-large-v3-turbo.bin`
517
- for whisper.cpp v1.9.3 Metal through sotto's helper at beam 5 / temperature
518
- 0 / its Silero gate). Machine: MacBookPro18,2, M1 Max 32 GB, MLX 0.32.2,
519
- sotto's dev server idle in the background. Transcripts were identical
520
- across arms except whisper.cpp's leading-space and casing conventions.
521
-
522
- | clip (audio) | mlx-bun fast greedy | mlx-bun faithful greedy | mlx-whisper 0.4.3 greedy | mlx-bun fast beam-5 | mlx-bun faithful beam-5 | whisper.cpp beam-5 |
523
- | --- | --- | --- | --- | --- | --- | --- |
524
- | fox (2.7 s) | **323 ms** | 340 | 337 | **366 ms** | 405 | 408 |
525
- | jfk (11.0 s) | **340 ms** (32× rt) | 378 | 371 | **424 ms** (26× rt) | 447 | 499 |
526
- | long (33.0 s, 2 windows) | **759 ms** (44× rt) | 825 | 826 | **1027 ms** (32× rt) | 1091 | 1157 |
527
-
528
- Reading: the faithful (oracle-graph) path already matches mlx-whisper;
529
- the fast path (fused attention, fused cross-K/V, compiled decoder step,
530
- device-side filters, pipelined greedy) is 8 % faster than mlx-whisper on
531
- greedy and 11–15 % faster than whisper.cpp at beam 5. Where the time
532
- goes on the 11 s clip (fast path, warm): mel 1 ms · encoder 285 ms ·
533
- cross-K/V 5 ms · prefill 4 ms · 28 decode steps ≈ 45 ms (1.5 ms/token).
534
- The encoder is bound by its fp16 gemms (~7–8 TFLOPS on this GPU); the
535
- measured dead ends are recorded in generic-model-support.md §6.7.
536
- **Neural Engine (Core ML) encoder, same machine, 2026-09-16:** the encoder
537
- converted with coremltools 9 to an fp16 mlprogram (plain linear/attention
538
- graph, `/tmp/coreml/convert_encoder.py`, 14 s to convert) and timed from
539
- Swift (`MLModel.prediction`, best of 5 warm): `cpuAndNeuralEngine` **940 ms**,
540
- `cpuAndGPU` 288 ms, `all` 288 ms (Core ML picks the GPU). The naive graph
541
- is 3.3× slower on the ANE than on the GPU and its fp16 outputs differ from
542
- the GPU's; whisper.cpp's ANE gains come from an ANE-shaped graph (4-D
543
- 1×1 convs, split softmax) and matter on chips whose GPU is weak relative
544
- to the ANE. Not pursued for the M1 Max; the MLX GPU path already ties Core
545
- ML's GPU path.
546
-
547
- **Silero VAD (Silero v6.2 port, `src/audio/silero-vad.ts`):** 24 ms for
548
- 11 s of audio warm, 433 ms for 180 s (the host-side LSTM recurrence
549
- dominates: 2.4 ms per second of audio); a silent take costs the VAD only.
550
- **AudioToolbox decode:** 11 s mp3 in 3.7 ms warm vs 72 ms through the
551
- `afconvert` subprocess; WAV bit-identical to the PCM parser.
552
- **Streaming sessions:** a 62 s take (three windows) transcribed batch in
553
- 1165 ms; fed in 1 s chunks it finished 327 ms after the last chunk with
554
- identical text (888 ms of window work happened during capture).
555
-
556
- Lab `audio_ctx` (whisper.cpp `-ac`) halves the encoder at 768 positions
557
- but hallucinates repeats on the JFK clip at ≤ 768 and appends "Thank you."
558
- at 1024 — not a default. Page-in after idle unload: 37–45 ms (weights
559
- from the OS file cache), first request then pays the compile traces.
560
-
561
- ## Running the benchmark
562
-
563
- Install the repository dependencies and the matching native runtime. Configure
564
- the pinned Python oracle using [environment.md](environment.md). Model artifacts
565
- must already be downloaded. The benchmark starts temporary servers and writes
566
- Markdown, raw request JSON, and database records.
567
-
568
- ```sh
569
- bun scripts/bench-serve.ts all --models cpm5,e4b,12B --no-serial
570
- ```
571
-
572
- This runs the default scheduler, without adding a serial control. Short decode,
573
- cold and cached first output, context decode, four-request throughput, memory,
574
- and startup are separate measurements. Full options, workload identity,
575
- paired-run ordering, and raw-report fields are described in the
576
- [v0.4.0 benchmark runbook](../archive/investigations/benchmark-ledger-through-v0.4.0.md#running-the-benchmark).
577
-
578
- To reproduce the September 11 diagnostic conditions explicitly:
579
-
580
- ```sh
581
- bun scripts/bench-serve.ts all --models cpm5,e4b,12B --no-serial --diagnostic --allow-cpu-process /usr/libexec/audiomxd
582
- ```
583
-
584
- The diagnostic flag retains observed background activity and memory conditions
585
- in the report. It does not make the machine quiet or turn one ordered suite
586
- into a balanced experiment. For a new controlled comparison, use an idle GPU,
587
- record machine conditions, and alternate repeated arm order with matching
588
- artifacts, prompts, cache policies, and settings.
589
-
590
- TTFT includes the path to first visible output: request processing, any prompt
591
- prefill, cache restore and initial model execution. A warm-cache TTFT difference
592
- is not a direct measurement of server overhead or of model decode speed. The
593
- decode and aggregate columns answer different questions and must stay labeled.
594
- Raw evidence paths in this document are machine-local, not downloadable reports.
595
- The clean-checkout oracle setup is verified above. A downloadable evidence
596
- bundle remains preparation work; do not treat a skipped parity test as
597
- successful reproduction.
598
-
599
- ### Coverage beyond the four-model summary
600
-
601
- The roster's L1 label identifies the intended reference computation. It is
602
- not a claim that every artifact, modality, cache layout, or scheduler shape
603
- has the same completed test coverage. The following table maps each additional
604
- roster row to its gate and explicitly distinguishes unvalidated artifacts.
605
- The presence of a test is not a passing run; fixture-gated skips are not evidence.
606
-
607
- | Roster row | Comparison and scope | Test or evidence |
608
- |---|---|---|
609
- | Other Gemma 4 configurations | Family support; no pinned artifact or completed artifact-specific parity claim | Roster marks these artifact-unvalidated |
610
- | Qwen3.5-4B OptiQ | Exact logits with bf16 KV against mlx-lm; mixed KV against mlx-optiq; artifact/fixture-gated | `tests/parity/qwen-parity.test.ts`, `MLX_BUN_TEST_QWEN35_4B=1` |
611
- | Qwen3.8-27B OptiQ | Exact bf16-KV logits against mlx-lm; mixed KV remains Lab; packed Trellis is a different artifact | `tests/parity/qwen-parity.test.ts`, `MLX_BUN_TEST_QWEN38=1` |
612
- | Qwen3-Embedding-4B DWQ | Exact hidden/pooled vectors against the pinned mlx-lm fixture; embeddings, not a chat-logit claim | `tests/parity/qwen3-embed-parity.test.ts` |
613
- | Qwen3-30B-A3B | Exact bf16-KV logits; artifact/fixture-gated | `tests/parity/qwen3-moe-parity.test.ts`, `MLX_BUN_TEST_QWEN3_MOE=1` |
614
- | Tier-0 generic: llama, smollm3, qwen2, qwen3, gemma, gemma2, phi3, olmo2, glm4, granite, starcoder2 | Manifest-driven exact last-position logits and first 12 greedy tokens for each available artifact; requires explicit opt-in and same-machine fixtures | `tests/support/universal-manifest.ts`, `tests/parity/universal-parity.test.ts`, `MLX_BUN_TEST_UNIVERSAL=1` |
615
- | DiffusionGemma | Separate denoising implementation and mlx-optiq contract; not included in the four-model autoregressive summary | Model roster and diffusion parity suites |
616
- | GLM-5.2 Colibri | Separate Colibri oracle and component/trajectory evidence; not a blanket mlx-lm bit-exact claim | [Recorded GLM results](../archive/investigations/benchmark-ledger-through-v0.4.0.md#glm-52-direct-colibri-oracle-closure--m1-max-32-gb) |
617
-
618
- The reproducibility work in the public-readiness plan must publish a pinned
619
- setup and same-machine fixture-generation recipe, then reconcile each claimed
620
- result with an identifiable artifact and run. The existing four-model table
621
- is a historical result summary, not an exhaustive certification matrix.
622
-
623
- ### Released v0.4.0 packed Qwen with KV4/TQ and MTP2 — M4 Pro (2026-09-11)
624
-
625
- The follow-up uses the intended 12.14 GiB packed Trellis Qwen artifact and
626
- folded RTN4 MTP companion on M4 Pro 24 GB, source `47620a5`, Bun 1.4.2 and
627
- MLX 0.32.2. `bench-serve.ts all` runs default batching then explicit serial
628
- for affine KV4, followed by the same order for TQ K8V3. Both use draft depth
629
- two, RAM cache capacity four, temporary SSD storage, `mtp-serving-block-1`,
630
- five 192-token decode samples and the 16,384-token context target. Actual
631
- context is 10,398 tokens. Async Trellis expansion is off and fused TQ decode
632
- is enabled. Diagnostic mode records retained swap and background CPU activity; this is one ordered settings comparison, not a balanced repeat.
633
-
634
- | Cache / actual execution | Short decode tok/s | Five requests, total ms | Context decode tok/s | Cached TTFT ms | SSD restart TTFT ms | Aggregate ×4 tok/s |
635
- |---|---:|---:|---:|---:|---:|---:|
636
- | KV4 / shared MTP2 | 20.247 | 53,399.63 | 22.233 | 96.71 | 1,916.79 | 17.520 |
637
- | KV4 / serial MTP2 | 19.973 | 54,124.69 | 22.225 | 93.28 | 1,913.19 | 16.133 |
638
- | TQ K8V3 / shared MTP2 | 18.368 | 58,053.53 | 19.285 | 100.36 | 1,967.83 | 16.881 |
639
- | TQ K8V3 / serial ordinary | 11.486 | 89,526.15 | 9.532 | 172.42 | 2,008.05 | 10.418 |
640
-
641
- All four cells finish without phase failures. Every SSD restart restores
642
- 10,397 tokens; each flush is durable with zero pending, dropped or failed
643
- spills. Within each cell, all three context responses match. Source hashes
644
- remain fixed. Shared KV4's peak RSS is 13,570 MiB versus TQ's 13,727 MiB;
645
- these are whole-process measurements, not isolated KV storage sizes.
646
-
647
- TQ's explicit serial command requests MTP2 but executes ordinary decoding:
648
- all five responses report `lane=serial` and no speculation telemetry. Shared
649
- TQ reports `lane=batched` with actual drafted/accepted tokens. The binding
650
- enables `speculativeTurboQuant` only with continuous scheduling. Therefore
651
- the serial TQ row is not a same-method MTP performance control. Both KV4
652
- lanes actually use MTP. This confirms TQ/MTP composition in the shared path;
653
- it does not establish that composition in the retained serial path.
654
-
655
- Against the saved September 9 KV4/MTP2 context profile, shared short decode
656
- changes from 20.133 to 20.247 tok/s, and five complete requests from
657
- 53,548.41 to 53,399.63 ms. All fifteen individually issued requests match in
658
- request hash, text, token counts and finish status; two of four concurrent
659
- texts differ. The current KV4 and TQ shared profiles match all nineteen
660
- request hashes and token/finish counts, but thirteen response texts differ,
661
- including all five short-decode responses. KV4 is faster on this workload;
662
- the difference does not isolate cache-kernel cost from changed continuations
663
- and draft acceptance, and it is not a quality comparison.
664
-
665
- Raw evidence in `reports/release-v0.4.0-standard/`:
666
- `packed-kv4-mtp2-m4.md.json`, `packed-tq-mtp2-m4.md.json` and
667
- `packed-comparison.json`. The historical reference is
668
- `reports/qwen38-closeout/composition-baseline/decode-default-kv4-mtp2-context-1.md.json`.
669
-
670
- ### Released v0.4.0 standard registry comparison — M4 Pro 24 GB (2026-09-11)
671
-
672
- `bun scripts/bench-serve.ts all` completed on an Apple M4 Pro with 24 GB, source `47620a5`, Bun 1.4.2 and MLX 0.32.2. It used the
673
- September 8 registry artifacts and `bench-serve-v2` requests, including five
674
- 192-token decode samples, the 16,384-token context target and four concurrent
675
- requests. Source hashes stayed fixed. Diagnostic execution recorded the following conditions:
676
- initial free memory was 90%, retained swap 1,341 MB, and `appstoreagent` used
677
- approximately one CPU core. These are recorded observations, not a quiet
678
- paired timing acceptance; the previous run used Bun 1.4.0.
679
-
680
- | Model | Previous / v0.4.0 default decode tok/s | Change | Previous / v0.4.0 median request ms | v0.4.0 default / serial aggregate tok/s |
681
- |---|---:|---:|---:|---:|
682
- | MiniCPM5-1B | 278.65 / 280.82 | +0.8% | 709.57 / 705.91 | 702.44 / 244.86 |
683
- | Gemma4-e4b | 57.86 / 59.32 | +2.5% | 3401.92 / 3314.44 | 165.99 / 56.95 |
684
- | Gemma4-12B | 26.14 / 26.63 | +1.9% | 7576.35 / 7436.02 | 68.58 / 25.74 |
685
- | Qwen3.8-27B 4/8-bit | 14.75 / 14.89 | +0.9% | 13813.51 / 13717.30 | 33.74 / 13.64 |
686
-
687
- All twenty default short-decode responses match the previous run in request
688
- hash, text, prompt/generated/cached counts, finish reason and DONE status.
689
- All twenty also match the current serial control. Concurrent responses are
690
- not all identical across runs; aggregate rates are workload observations.
691
- The twelve MiniCPM/Gemma cells complete without phase failures, and every
692
- Bun cache flush/restart succeeds. The seven recorded phase failures belong
693
- to Qwen: both Bun paths recover a 1K-prefill Metal OOM, then fail context;
694
- Python recovers a 1K timeout, fails context and skips concurrency because its
695
- server is dead. Qwen mixed KV is skipped because its registry artifact has no
696
- KV configuration. Existing stock-Python thinking-boundary output differences
697
- remain documented in the [September 8 investigation](../archive/investigations/benchmark-ledger-through-v0.4.0.md#standard-serve-matrix--m4-pro-24-gb-2026-09-08-incomplete-acceptance).
698
-
699
- This registry Qwen contains **15.85 GiB of safetensors**, uses bf16 KV and
700
- has no MTP companion configured. It is not the campaign's **12.14 GiB packed
701
- Trellis** artifact with quantized KV and MTP. Its capacity failures must not
702
- be attributed to that optimized configuration. Raw report and comparison:
703
- `reports/release-v0.4.0-standard/standard-m4.md.json` and
704
- `reports/release-v0.4.0-standard/historical-comparison.json`.
705
-
706
- ### Saved Kanban cache-failure replay — M4 Pro 24 GB (2026-09-12 UTC)
707
-
708
- The fresh `6e918e2` task stopped at its fourth request after 46m 13s and
709
- 42,979 output tokens. Its first tool turn reused only 2,554 tokens and waited
710
- 340.24 s for first output. Generated text and the next rendered prompt matched,
711
- but BPE re-encoding changed token IDs starting at position 16,534. The terminal
712
- 37,556-token recurrent checkpoint consequently failed exact-prefix lookup.
713
-
714
- The follow-up preserves generated token provenance and reclaims optional RAM
715
- snapshots under allocator pressure. Conditions: the same packed 12.14 GiB Qwen
716
- artifact, affine KV4, MTP2, default batch cap eight, 256-token prefill chunks,
717
- 4 GiB RAM-cache cap and SSD persistence, Bun 1.4.2 / MLX 0.32.2. These are
718
- diagnostic saved-request checks, not fresh full-task speed measurements.
719
-
720
- | Check | Merged `6e918e2` | Follow-up |
721
- |---|---|---|
722
- | Reconstruct the 6,215-token CSS response from the saved preceding state | 361.18 s; completes | 364.23 s; identical response and complete usage/speculation record |
723
- | Immediately submit the original fourth request | Metal OOM after 1.31 s | 45,646 tokens reused; first output 1.24 s; 32-token check completes in 3.35 s |
724
- | First tool turn, with only the first response's SSD snapshots available | Original task reused 2,554 tokens, first output 340.24 s | 37,556 tokens reused; first output 4.57 s from a fresh server; 32-token check completes in 6.77 s |
725
-
726
- The reconstructed failure reaches 18.96 GB peak native allocation; the fixed
727
- run's recorded peak before the fourth request is 16.74 GB. A fresh process
728
- restoring only the fourth-request snapshot also succeeds on unchanged main:
729
- the failure depends on retained conversation state, not that prompt alone.
730
- The first-turn fix preserves 14 more input IDs than canonical re-encoding
731
- (37,639 versus 37,625); decoded request text is unchanged. It therefore does
732
- not claim identical continuation logits to the older re-tokenized history.
733
-
734
- The fixed replay persists the latest state but drops one unwritten older
735
- boundary under pressure; shutdown correctly reports incomplete durability for
736
- that boundary. This is best-effort cache eviction, not a request refusal.
737
- M1 Max native HTTP checks retain matching RAM/SSD-restart responses, logprobs
738
- and speculation with thinking off/on. The local suite passes 2,240 tests,
739
- with 14 existing skips. Typechecks and documentation surface checks pass.
740
- Evidence: `reports/kanban-cache-fix/{warm-reconstruct-main,warm-reconstruct-fixed,history-final}/`
741
- and `comparison.json` on the M4; summarized copies and local checks are in
742
- `reports/kanban-cache-fix/` on the M1.
743
-
744
- The subsequent fresh task on `a40588e` completes with unchanged sources,
745
- fresh RAM/SSD/workspace, the settings above and an identical initial request
746
- to the failed run. Its first 35,002-token response and complete usage record
747
- also match. All 30 requests use shared batching with MTP active; all 29
748
- follow-up requests hit the cache. The first tool turn reuses 37,556 tokens
749
- and reaches output in 1.73 s. The fourth request completes normally.
750
-
751
- | Full Kanban task, M4 Pro 24 GB | Wall time | Output tokens | Requests | Sum of request TTFT | App acceptance |
752
- |---|---:|---:|---:|---:|---|
753
- | First preserved run, September 8 | 3h 33m 07.685s | 130,494 | 62 | 56m 39.895s | Pass; 15 recorded checks |
754
- | Previous successful run, September 9 | 1h 24m 45.387s | 68,958 | 15 | 13m 34.988s | 18/18 |
755
- | Fresh cache fix, September 12 UTC | 1h 30m 02.183s | 79,523 | 30 | 3m 18.143s | 16/18; fails quality acceptance |
756
- | Seeded cache-fix repeat, September 12 UTC | 1h 18m 31.250s | 72,289 | 27 | 2m 07.925s | 16/18; same two defects |
757
-
758
- The fresh task takes 6.2% longer than the previous success and generates
759
- 15.3% more output. Its summed TTFT is 75.7% lower. Later responses, tool calls
760
- and app behavior differ, so these are workload observations, not a controlled
761
- engine-only speed ratio. Pi finishes without retries or compaction; it records
762
- two tool errors during its own app checks and no inference failures. Combined
763
- server/Pi peak RSS is 13.09 GB; this is not peak native Metal allocation.
764
-
765
- Independent browser checks preserve all 14 generated files unchanged. Card
766
- and column editing, native drag/reorder, archive/restore, search, selected
767
- AND filters, reload persistence and both themes work. Two defects fail the
768
- same acceptance categories used previously: choosing `All labels` or
769
- `All assignees` produces a nonempty filter value and hides every card;
770
- focused cards cannot open for editing with Enter or Space. No repair prompt
771
- or manual app edit is applied.
772
-
773
- The latest two SSD snapshots persist, through 92,665 tokens, totaling
774
- 3.66 GB. Pressure has evicted 58 older unwritten snapshots; explicit flush
775
- returns 503 with `durable: false` and `missingSnapshots: 58`. Thus generation
776
- and latest-state persistence succeed; older-history retention under pressure
777
- and full app quality acceptance remain open. Results, unchanged app, request
778
- streams, `quality.json`, browser evidence and `comparison.json` are preserved
779
- under `reports/kanban-cache-fixed-fresh/` on both machines; the SSD files remain
780
- on the M4. Earlier runs and their snapshots are preserved.
781
-
782
- The seeded repeat on `0d20953` uses identical engine hashes and settings,
783
- a fresh empty output directory and fresh RAM/SSD caches. The sent initial
784
- request, first 35,002-token response and its full usage record match the prior
785
- fresh run. The first model-visible difference is the live `ls -la` result:
786
- both `.` and `..` timestamps change from `18:55` to `21:08`. The next rendered
787
- input and subsequent output differ. This is not an identical-input replay.
788
-
789
- The repeat takes 12.8% less time and generates 9.1% fewer tokens than the
790
- prior fresh task; engine sources did not change. All 26 follow-ups hit the
791
- cache. Pi records seven tool errors during app checks, no inference failures,
792
- no retries and no compactions. Independent browser checks on the untouched
793
- 14-file app again pass 16/18 categories, with filter reset and keyboard edit
794
- still failing. Three SSD snapshots persist through 81,076 tokens, totaling
795
- 5.33 GB; flush reports 51 missing older snapshots and `durable: false`.
796
- Reports and app: `reports/kanban-cache-fixed-repeat-r1/`; browser acceptance
797
- is in `quality.json`, and input/output comparisons are in
798
- `repeat-comparison.json` and `jsonl-comparison.json`. SSD files remain on M4.
799
-
800
- ### Background SSD persistence diagnostic, M4 Pro
801
-
802
- September 12, 2026; M4 Pro 24 GB, Bun 1.4.2, native pack 0.4.0 / MLX
803
- 0.32.2. Packed Qwen3.8-27B interleave2 with RTN4 MTP, depth 2, affine KV4,
804
- shared batch cap 8 with one actual row, greedy sampling and seed 42. This
805
- isolates storage overlap on the candidate engine; it is not the standard
806
- HTTP benchmark or a fresh Kanban comparison.
807
-
808
- Four AB/BA runs each generate 128 tokens from the same 271-token cached
809
- prefix. A synthetic strided KV payload produces a 536,879,104-byte file.
810
- The deferred arm writes after inference. The background arm queues the same
811
- write after output token 16. Both use the new CPU writer and fsync+rename.
812
-
813
- | Measurement, mean of two runs | Deferred until inference finishes | Background during decode |
814
- | --- | ---: | ---: |
815
- | Post-first-token decode | 25.75 tok/s | 25.74 tok/s |
816
- | Inference plus completed persistence | 5.200 s | 5.128 s |
817
- | Time spent writing | 73.2 ms | 119.6 ms |
818
- | Output tokens emitted when write completes | 128 | 19 |
819
-
820
- All four responses and MTP acceptance sequences are identical. Background
821
- persistence takes longer while competing for memory bandwidth, but completes
822
- while decode advances from token 16 to 19; measured decode throughput is
823
- within 0.04%. This supports overlapping this payload without a meaningful
824
- decode penalty. It does not establish long-context, sustained-write or
825
- end-to-end Kanban gains. Raw results and source hashes:
826
- `reports/ssd-background-persistence/m4-overlap.json`.
827
-
828
- ### Cache expansion C1–C5: storage, restore, retention and paged attention
829
-
830
- September 12, 2026. Baseline `c953f2f` plus the cache expansion on
831
- `fix/ssd-background-persistence`; Bun 1.4.2, native pack 0.4.0 / MLX 0.32.2.
832
- M4 Pro 24 GB is the serving comparison host; M1 Max 32 GB supplies a second
833
- component comparison. These are diagnostic measurements, not a new h2h against
834
- mlx-lm or a new complete Kanban task. Raw reports are in
835
- `reports/cache-expansion/`; `source-manifest.json` identifies the final source.
836
-
837
- **Result:** block sharing saves disk space, segmented packing removes copies,
838
- and asynchronous restore keeps the event loop available. Neither block storage
839
- nor the alternative RAM policy earns default promotion. Direct paged attention
840
- has shape-dependent wins and regressions and remains an optional Lab kernel.
841
- The configuration reference owns the selectable settings and defaults.
842
-
843
- #### Same-request M4 serving comparison
844
-
845
- Packed Qwen3.8-27B interleave2, RTN4 MTP depth 2, affine KV4, seed
846
- `cache-expansion-42`, shared batch cap eight. The standard script runs five
847
- short-decode samples, context, SSD restart and four concurrent requests.
848
- The requested 4,096-token context renders to 2,677 actual tokens; restart
849
- reuses 2,676. No arm forces serial execution.
850
-
851
- | Arm | Median short decode, tok/s | Decode at context, tok/s | SSD restart TTFT, ms | Four-request aggregate, tok/s |
852
- | --- | ---: | ---: | ---: | ---: |
853
- | Whole files, synchronous restore, LRU | 19.58 | 24.07 | 1,893 | 17.05 |
854
- | Shared blocks, async restore, cost-size retention | 19.21 | 23.95 | 2,133 | 17.01 |
855
- | Whole files, async restore, LRU | 19.67 | 24.12 | 2,076 | 17.10 |
856
-
857
- All 19 corresponding requests preserve input hashes, response text hashes,
858
- prompt/output counts and finish reasons. Every phase completes; final flushes
859
- are durable with no pending, dropped or failed snapshots. Decode is essentially
860
- unchanged with async restore alone. The combined candidate is slightly slower;
861
- both async arms have worse single-request restart TTFT. These sequential
862
- matrices establish no broad throughput gain. Reports:
863
- `m4-serving-baseline.json`, `m4-serving-candidate.json`, `m4-serving-async.json`.
864
-
865
- #### C1 and C4: shared blocks and packing
866
-
867
- Four immutable checkpoints grow through one quarter, one half, three quarters
868
- and all of the same eight-head tensor. Fixed bytes/seed; the block boundary
869
- resets per head. The M4 payload ends at 256 MiB; medians of five paired samples
870
- include all four writes. Reads verify the final state with warm filesystem
871
- pages. File sizes count unique committed bytes, not APFS allocated extents.
872
-
873
- | M4 storage arm | Total write, ms | Final verified read, ms | Files retained, MiB | Bytes copied for packing, MiB | Peak packing scratch, MiB |
874
- | --- | ---: | ---: | ---: | ---: | ---: |
875
- | Whole files | 100.60 | 21.26 | 641.91 | 384 | 192 |
876
- | Blocks, whole-tensor packing | 282.08 | 97.47 | 257.92 | 384 | 192 |
877
- | Blocks, segmented packing | 276.33 | 97.66 | 257.92 | 0 | 0 |
878
-
879
- Sharing reduces bytes written and retained by **59.8%**, but segmented block
880
- writes take **2.75×** as long as whole files. SHA-256 content hashing and many
881
- small durable writes cost more than whole-file transport. Against the same
882
- block format, segmentation removes 384 MiB of copying and 192 MiB of scratch;
883
- write time improves about 2%. Zero scratch here applies to contiguous spans
884
- within each head; arbitrary strides use bounded packing, not zero copying.
885
- These are allocation counters, not process RSS measurements.
886
-
887
- On M1, a smaller 64 MiB final tensor gives whole/packed-block/segmented-block
888
- write medians of 66.82/128.86/114.23 ms and verified reads of
889
- 13.85/39.82/39.77 ms. Shared files retain 64.44 MiB versus 160.47 MiB;
890
- segmentation removes 96 MiB of packing copies and 48 MiB of peak scratch.
891
- Do not compare these host timings as identical workloads. Reports:
892
- `m4-components-final.json`, `m1-components-final.json`.
893
-
894
- #### C2: restore while decode continues
895
-
896
- A separate ABBA probe restores an unrelated 512 MiB recurrent checkpoint at
897
- Qwen output token 16. Each arm warms the model, file pages and synchronous
898
- allocator; all arms emit the same 128 greedy token IDs. MTP depth 2, KV4,
899
- seed 42, shared cap eight with one active request.
900
-
901
- | Mean of two arms | Synchronous read | Async read |
902
- | --- | ---: | ---: |
903
- | Pause inside the token callback | 53.15 ms | 0.20 ms |
904
- | Read completion time | 53.13 ms | 126.13 ms |
905
- | Output token when read completes | 16 | 19 |
906
- | Post-first-token decode | 18.69 tok/s | 18.84 tok/s |
907
- | Request plus completed read | 7.203 s | 7.141 s |
908
-
909
- The read itself takes longer while sharing memory bandwidth, but the owner
910
- thread returns immediately and generation advances. The small throughput
911
- difference is not a general speed claim. This measures byte transport overlap,
912
- not all model-layout reconstruction work; plain KV capacity growth still uses
913
- its existing MLX operations after transport. Report:
914
- `m4-restore-overlap-warm.json`. Earlier unwarmed probes are retained as diagnostics
915
- and excluded from this comparison.
916
-
917
- #### C3: retention policy replay
918
-
919
- The policy port compares LRU with GreedyDual-style cost/size/frequency ranking.
920
- SSD is durable in both arms: RAM misses cause restores, not lost prefill.
921
- In a synthetic hot-prefix trace interleaved with one-shot histories, cost-size
922
- eliminates 796 restores incurred by LRU. In sequential bursts it introduces
923
- 300 restores where LRU needs none.
924
-
925
- The saved Kanban repeat contributes its observed next-turn cached-prefix
926
- boundaries. This is metadata replay, not a token-level or physical-memory
927
- simulation: each entry costs prefix length plus 16,384 fixed recurrent-state
928
- units. At a 160,000-unit RAM budget, LRU has 26 hits and zero restores;
929
- cost-size has 15 hits and 11 restores. At 80,000 and 320,000 units, cost-size
930
- also causes more restores. Cold-prefill work is unchanged. LRU remains the
931
- selection for this workload; cost-size is useful for the measured pollution
932
- trace, not a universal improvement. Report: `retention.json`.
933
-
934
- #### C5: direct paged attention
935
-
936
- The kernel compares gathered pages plus stock SDPA with direct block-table
937
- reads. At 16,384 cached tokens, bf16 queries, 16 query heads, four KV heads,
938
- head dimension 128, five paired samples of ten evaluated steps:
939
-
940
- | Stored KV | M4 B1 speed ratio | M4 B4 speed ratio | M1 B1 speed ratio | M1 B4 speed ratio |
941
- | --- | ---: | ---: | ---: | ---: |
942
- | bf16 | 1.10× | 1.76× | 1.15× | 1.67× |
943
- | affine 4-bit | 1.00× | 1.27× | 0.92× | 1.02× |
944
- | affine 8-bit | 1.19× | 1.65× | 1.08× | 1.27× |
945
-
946
- Ratios are gathered time / direct time; below one is a regression. B4 here
947
- means four independent row views, not one fused four-row dispatch. The direct
948
- arm eliminates full gathered K/V tensors and row padding; its partial softmax
949
- buffers still allocate memory. Short shapes can lose badly: M4 bf16 B1 at
950
- 256 cached tokens takes about 0.21 ms gathered versus 0.59 ms direct.
951
- Reports: `m4-paged-final.json`, `m1-paged-final.json`.
952
-
953
- A complete-request M4 Gemma4 e4b comparison uses 4,096 + 17×row prompt tokens,
954
- 64 output tokens per row, greedy sampling, no prefix cache, shared cap eight
955
- and uncompiled decode. ABBA, two samples per arm:
956
-
957
- | KV / active requests | Gathered per-row decode, tok/s | Direct per-row decode, tok/s |
958
- | --- | ---: | ---: |
959
- | bf16 / one | 50.94 | 45.82 |
960
- | bf16 / four | 13.73 | 12.58 |
961
- | affine 4-bit / one | 49.55 | 50.31 |
962
- | affine 4-bit / four | 14.14 | 14.70 |
963
-
964
- Every corresponding generated token agrees. The affine arm gains about 1.5%
965
- and 4.0% decode throughput; bf16 regresses about 10% and 8%. The first gathered
966
- prefill can include cold setup, so small wall-time differences in these raw
967
- reports do not establish end-to-end gains. Reports:
968
- `m4-paged-model-bf16.json`, `m4-paged-model-kv4.json`.
969
-
970
- Storage round trips are byte-exact, including paged affine planes and
971
- MTP/TurboQuant attachments. The direct reduction is **Lab numerical behavior**,
972
- tolerance-tested against the same stored values; matching these greedy outputs
973
- is not proof of L1 logit parity. Native tests cover partial blocks, unequal K/V
974
- dimensions, row retirement and restart. The HTTP cache check preserves responses
975
- through RAM and asynchronous SSD reuse for gathered/direct bf16 and KV4.
976
-
977
- #### Reproduction
978
-
979
- Set `TARGET` to the packed Qwen artifact, `DRAFT` to its RTN4 MTP artifact,
980
- and `GEMMA` to the Gemma4 e4b OptiQ snapshot. Native tests require the matching
981
- native pack and artifacts described in environment.md.
982
-
983
- ```sh
984
- # Repeat with SSD_PREFETCH=1; for the combined arm also select blocks/cost-size.
985
- MLX_BUN_SSD_LAYOUT=whole MLX_BUN_SSD_PREFETCH=0 MLX_BUN_CACHE_RETENTION=lru \
986
- bun scripts/bench-serve.ts all --diagnostic --no-serial --arms mlx-bun \
987
- --model-path "$TARGET" --label Qwen3.8-27B-packed12GB --draft-model "$DRAFT" \
988
- --draft-kind mtp --num-draft-tokens 2 --kv-quant 4 --context 4096 \
989
- --workload-seed cache-expansion-42
990
- bun scripts/bench/cache-tiers.ts --mib 256 --samples 5 --output reports/cache-tiers.json
991
- bun scripts/bench/cache-restore-overlap.ts --model "$TARGET" --draft "$DRAFT" \
992
- --mib 512 --output reports/cache-restore.json
993
- bun scripts/bench/cache-retention.ts \
994
- --kanban reports/kanban-cache-fixed-repeat-r1/result.json --output reports/cache-retention.json
995
- bun scripts/bench/paged-attention.ts --output reports/paged-attention.json
996
- bun scripts/bench/paged-model.ts --model "$GEMMA" --bits 4 --output reports/paged-model.json
997
- MLX_BUN_TEST_PAGED_CACHE=1 bun test tests/parity/paged-cache-http.test.ts
998
- ```
999
-
1000
- ### Session checkpoint index C6
1001
-
1002
- September 12, 2026, on top of cache expansion `7692d5b`; Bun 1.4.2,
1003
- MLX 0.32.2 / native pack 0.4.0. M4 Pro 24 GB supplies native storage and
1004
- HTTP measurements; M1 Max 32 GB supplies the second CPU index comparison.
1005
- Reports and the final accepted source manifest are under `reports/session-cache/`.
1006
-
1007
- The session ID selects the latest compatible immutable checkpoint through a
1008
- second index, with ordinary prefix lookup for missing or edited histories.
1009
- RAM retention prefers session-referenced entries over unrelated entries while
1010
- honoring the same budget. Session metadata does not partition content storage.
1011
-
1012
- | CPU index workload, median of eight paired samples | Prefix scan | Session index |
1013
- | --- | ---: | ---: |
1014
- | M4, all 27 saved Kanban request renderings | 13.04 ms total | 1.57 ms total |
1015
- | M1, 64 nested checkpoints ending at 50,000 tokens | 42.16 ms total | 2.77 ms total |
1016
-
1017
- Each checkpoint is published before its lookup; timings average 20 repeated
1018
- lookups per checkpoint after a warm call. Saved Kanban inputs render to
1019
- 2,554–79,417 tokens. These are real token strings with stub KV state and a
1020
- checkpoint at each rendered prompt minus one token, not a replay of the
1021
- original generated KV or the original task. The index removes candidate
1022
- search, while still comparing the known prefix against the intended input.
1023
- The M4 lookup reduction is 8.3×, but only **11.47 ms across the entire sequence**.
1024
- Files: `m4-kanban-index.json`, `m1-index.json`.
1025
-
1026
- A native storage comparison uses eight agent continuations, a three-checkpoint
1027
- RAM accounting budget and four unrelated durable publications between turns.
1028
- Each checkpoint carries 64 MiB of SSM tensor data plus one scalar. Both arms
1029
- use identical immutable bytes, whole-file SSD transport and warm filesystem
1030
- pages; the cache independently owns publication, eviction and restoration.
1031
- Two samples per arm in ABBA order:
1032
-
1033
- | Native M4 retrieval measurement | Anonymous prefix lookup | Session affinity |
1034
- | --- | ---: | ---: |
1035
- | SSD restores over eight continuations | 8 | 0 |
1036
- | Reload traffic | 512 MiB | 0 |
1037
- | Total retrieval time, mean | 33.57 ms | 0.25 ms |
1038
- | Final accounted RAM residency | 192 MiB | 192 MiB |
1039
-
1040
- The budget counts checkpoint state sizes; immutable source buffers can share
1041
- physical storage, so this is not a process-RSS comparison. Retrieval timing
1042
- includes preparation and cache lookup; writes and byte-identity checks are
1043
- outside that interval. Total publication/workload time varies between arms,
1044
- and this probe establishes avoided restores rather than a decode speedup.
1045
- File: `m4-residency.json`. A separate equal-size metadata pollution trace also
1046
- preserves all 26 agent hits with affinity, versus zero without it.
1047
-
1048
- The M4 HTTP comparison uses packed Qwen3.8-27B interleave2, RTN4 MTP depth 2,
1049
- affine KV4, shared batch cap eight with one request at a time, greedy sampling,
1050
- seed 42 and a 4 GiB RAM cache. The saved Kanban opening request starts a
1051
- **bounded six-turn conversation**, with 64 output tokens per turn. The first
1052
- arm records its subsequent histories; every later arm sends those exact
1053
- inputs. This is not a fresh complete Kanban app task.
1054
-
1055
- | HTTP arm, in execution order | Mean follow-up TTFT, ms | Mean follow-up decode, tok/s | All six requests, s | Prefix searches / session hits |
1056
- | --- | ---: | ---: | ---: | ---: |
1057
- | Session disabled, first control | 738.14 | 22.94 | 41.111 | 6 / 0 |
1058
- | Session enabled | 668.64 | 22.89 | 39.265 | 1 / 5 |
1059
- | Session enabled | 661.61 | 22.89 | 39.238 | 1 / 5 |
1060
- | Session disabled, warm control | 661.48 | 22.90 | 39.243 | 6 / 0 |
1061
-
1062
- All corresponding inputs, output text/reasoning hashes, finish reasons and
1063
- output counts match. Cached-prefix counts match at every turn; all four
1064
- flushes are durable. The first control includes more cold setup. Against the
1065
- warm control, **model throughput and request time are effectively unchanged**.
1066
- The five known continuations do bypass prefix search. Do not attribute the
1067
- first-control timing difference to session affinity or infer a full Kanban
1068
- time reduction. File: `m4-serving.json`.
1069
-
1070
- Native M4 MTP with TurboQuant K8/V3, shared row retirement and RAM/SSD
1071
- continuation pass with session IDs. Paged bf16/KV4 HTTP restart, exact SSD
1072
- index removal, shared-session replacement, edited-history fallback and session
1073
- closure also pass their applicable tests. Equivalent-checkpoint session
1074
- reference replacement and publication for short ordinary session requests were
1075
- corrected after measurement, with a regression test and a native short-session
1076
- HTTP check. The timed workloads use unique prefixes longer than the old
1077
- publication threshold, so those corrections leave their paths unchanged.
1078
- Configuration and API lifecycle are in server-config.md and server-api.md.
1079
-
1080
- ```sh
1081
- bun scripts/bench/session-cache.ts --tokens 50000 --checkpoints 64 --output reports/session-index.json
1082
- bun scripts/bench/session-cache.ts --model "$TARGET" \
1083
- --requests reports/kanban-cache-fixed-repeat-r1 --output reports/kanban-session-index.json
1084
- bun scripts/bench/session-residency.ts --mib 64 --turns 8 --output reports/session-residency.json
1085
- bun scripts/bench/session-serving.ts --model "$TARGET" --draft "$DRAFT" \
1086
- --request reports/kanban-cache-fixed-repeat-r1/request-0.json --output reports/session-serving.json
1087
- ```
1088
-
1089
- ### Full Kanban with session cache and queued persistence
1090
-
1091
- September 12, 2026, M4 Pro 24 GB. Current engine `3ea8079` versus the saved
1092
- `kanban-cache-fixed-repeat-r1` run on `0d20953`. Both use Bun 1.4.2, Pi 0.85.1,
1093
- MLX 0.32.2 / native pack 0.4.0, packed Qwen3.8-27B interleave2, RTN4 MTP depth
1094
- two, affine KV4, default shared batch cap eight, a 4 GiB RAM cache and a
1095
- 64 GiB SSD cache. The original Luke prompt, seed 42, temperature 0.6, xhigh
1096
- thinking, 131072-token context and compaction settings are unchanged.
1097
-
1098
- The current run starts Pi in an empty directory at the path named in the
1099
- pinned system prompt, with fresh application cache, Pi configuration and
1100
- session. Pi's session headers reach the shared cache interface. Source hashes
1101
- remain unchanged throughout. The M4 starts with 87% free memory and 1.31 GiB
1102
- retained swap; this is a recorded machine-state diagnostic, not a quiet h2h.
1103
-
1104
- | Full task measurement | Previous run | Current cache run |
1105
- | --- | ---: | ---: |
1106
- | Pi task wall time | 78m31.250s | 83m57.098s |
1107
- | Generated tokens | 72,289 | 76,031 |
1108
- | Requests | 27 | 25 |
1109
- | Weighted post-first-output throughput | 15.777 tok/s | 15.542 tok/s |
1110
- | Sum of pre-first-output intervals | 127.925 s | 143.024 s |
1111
- | Follow-ups with cached input | 26/26 | 24/24 |
1112
- | Direct session hits / ordinary prefix scans | Not available | 24 / 1 |
1113
- | SSD restores | 0 | 0 |
1114
- | Final flush | HTTP 503, not durable | HTTP 200, durable |
1115
- | Missing snapshots at final flush | 51 | 0 |
1116
- | SSD entries after final flush | 3 | 38 |
1117
- | Peak combined server/Pi RSS | 12.233 GiB | 15.453 GiB |
1118
- | Untouched-app browser acceptance | 16/18 | 16/18 |
1119
- | Pi tool errors / inference failures | 7 / 0 | 2 / 0 |
1120
-
1121
- The current task is 6.9% longer with 5.2% more generated tokens. Weighted
1122
- throughput is 1.5% lower, but subsequent inputs and context lengths differ,
1123
- so this is not an engine-only regression measurement. The initial rendered
1124
- request and complete first response match exactly, including tool arguments
1125
- and all 35,002 output tokens. That response takes 2000.478 s versus 1997.378 s,
1126
- a 0.16% difference. The first changed input includes the new directory's
1127
- actual timestamps; later generated histories diverge. No complete-task speedup
1128
- is established by this comparison.
1129
-
1130
- The durability improvement is observable throughout the task. All 24
1131
- follow-ups select their session checkpoint, 50 successful SSD writes are
1132
- recorded, and final flush has zero pending, dropped, failed or missing
1133
- snapshots. The existing 64 GiB SSD limit evicts older persisted entries,
1134
- leaving 38 entries / 63.133 GiB and a longest durable prefix of 85,699 tokens.
1135
- This establishes persistence within the configured capacity, not unlimited
1136
- retention of every historical checkpoint. No SSD restores were required.
1137
- Combined RSS is higher; it does not measure native peak allocation separately.
1138
-
1139
- Independent browser testing of the untouched app passes the same 16 of 18
1140
- categories. Resetting label/assignee filters hides cards, and Enter/Space does
1141
- not open a focused card for editing. Keyboard creation, mouse editing,
1142
- column operations, card/column drag-and-drop, archive/restore, search,
1143
- localStorage persistence and light/dark persistence pass. The new app is not
1144
- byte-identical to the old one. No repairs or extra prompts were supplied.
1145
-
1146
- Reports, full requests/responses, Pi JSONL, source hashes, comparison and
1147
- browser evidence: `reports/kanban-session-cache-r2/`. The preserved runner
1148
- reproduces the task from the pinned local profile and artifacts; it requires
1149
- a fresh report directory and empty task directory. An earlier attempt at
1150
- `reports/kanban-session-cache-r1/` was stopped because its tool cwd differed
1151
- from the pinned system prompt. Its first tool call targeted a nonexistent
1152
- path. That runner error is preserved and excluded from the task comparison;
1153
- it was not an engine failure.
1154
-
1155
- ### Ordinary KV4 long-context cached repeat on current code
1156
-
1157
- M4 Pro 24 GB, 2026-09-12 UTC, source `38f6af4`, Bun 1.4.2, MLX 0.32.2.
1158
- The standard benchmark repeats the previously failing ordinary packed-Qwen
1159
- workload: the 12.14 GiB interleaved Trellis artifact, affine KV4, no drafter,
1160
- default batch capacity eight, 4 GiB RAM cache, temporary SSD, 256-token prefill
1161
- chunks and seed `mtp-late-context-block-0`. Context target 125,000 produces
1162
- 78,678 actual prompt tokens. Async Trellis expansion is off. This diagnostic
1163
- run starts with 1,603 MiB retained swap and 91% free memory, without GPU competition.
1164
-
1165
- | Measurement | Current result |
1166
- |---|---:|
1167
- | Cold context first output | 881,534.26 ms |
1168
- | Context prefill | 89.251 tok/s |
1169
- | Context decode, median of three | 7.289 tok/s |
1170
- | Cached repeat first output, two repeats | 313.71 / 313.40 ms |
1171
- | SSD restart first output | 2,444.30 ms |
1172
- | Reused tokens, cached repeat and restart | 78,677 |
1173
- | Peak sampled RSS | 14,937 MiB |
1174
- | Failed requests / retries | 0 / 0 |
1175
-
1176
- All three context requests retain the original first-attempt SHA-256
1177
- `53c5eaa0296a1831e871bf2b519215ee830bfa2e27d0af0d96a58b8e1d1d824f`.
1178
- Each generates 64 tokens; all three responses are identical, including the
1179
- cold response from the old successful first attempt. The old second request
1180
- failed with Metal OOM; its subsequent retry changed the prompt hash and token
1181
- count. That retry is not a matched performance control. Current cold prefill
1182
- is effectively unchanged from the original 881,941.45 ms. This closes the
1183
- recorded ordinary cached-repeat failure on current source; it does not claim
1184
- a decode speedup or validate the old 2,048-token chunk at this context.
1185
-
1186
- The final flush is durable: 16 entries, longest durable prefix 78,741 tokens,
1187
- zero pending snapshots/spills and zero dropped/failed spills. The source hash
1188
- `7c469ff1dbe847ca99342ae0d0c70b728ab39e297626a4d3be194cafc3e0bc1f`
1189
- remains unchanged. Raw report: `reports/prefill-observation/late-context-ordinary.md.json`;
1190
- original failure: `reports/qwen38-closeout/composition-baseline/decode-prefill-policy-kv4-plain-late-context-chunk256-0.md.json`.
1191
-
1192
- ### Long-context KV4/MTP2 and TurboQuant/MTP3
1193
-
1194
- M4 Pro 24 GB, 2026-09-12 UTC, fixed source `38f6af4`, same artifact,
1195
- workload and 256-token chunks as the ordinary long-context control above.
1196
- Both speculative arms use the folded RTN4 companion, default batch capacity
1197
- eight, 4 GiB RAM plus temporary SSD, and fused TQ decoding where applicable.
1198
- These are ordered diagnostic settings screens, with 1,603 MiB retained swap;
1199
- they are not balanced source-only speed comparisons.
1200
-
1201
- | Setting | Short decode median tok/s | Decode at 78,678 tok/s | Cold context TTFT ms | Cached repeat TTFT ms | SSD restart TTFT ms | Aggregate ×4 tok/s |
1202
- |---|---:|---:|---:|---:|---:|---:|
1203
- | Ordinary KV4 | 11.536 | 7.289 | 881,534 | 313.40 | 2,444.30 | 27.146 |
1204
- | TQ K8V3 / MTP3 | 18.032 | 10.181 | 884,991 | 513.57 | 2,842.60 | 17.424 |
1205
- | KV4 / MTP2 | 19.559 | 12.756 | 882,927 | 207.76 | 2,538.03 | 16.708 |
1206
-
1207
- All arms complete without failures or retries, and every source hash stays
1208
- fixed during its run. All three context requests in each arm have the exact
1209
- original request hash, produce 64 tokens and retain identical response text
1210
- within that arm. Each speculative restart reuses 78,677 tokens. Its final
1211
- SSD flush has 24 durable entries and zero pending, dropped or failed spills.
1212
- TQ's longest durable prefix is 78,742 and KV4's is 78,741 tokens. Peak sampled
1213
- RSS is 15,125 MiB with TQ and 15,317 MiB with KV4; this is process RSS, not
1214
- isolated codec storage.
1215
-
1216
- Current KV4/MTP2 matches all 19 request hashes and all 15 individually issued
1217
- responses from the previous prefill-policy control, including the long-context
1218
- output. Four concurrent responses change. The current short KV4 samples have
1219
- a 1.16 max/min spread; no precise short-decode speedup follows from this run.
1220
- At long context, KV4/MTP2 remains the faster measured agent configuration;
1221
- ordinary KV4 has the highest aggregate throughput on this short concurrent
1222
- workload. Changing KV format or draft width can change text and acceptance,
1223
- so these rows cannot isolate kernel cost. The companion's `block_size=3`
1224
- already selects MTP2 by default. TQ/MTP3 remains an available setting with
1225
- successful long-context/cache acceptance, not the preferred agent preset.
1226
-
1227
- Raw evidence: `reports/prefill-observation/late-context-{ordinary,tq-mtp3,kv4-mtp2}.md.json`.
1228
-
1229
- ### Automatic prefill sizing at long context
1230
-
1231
- M4 Pro 24 GB, same workload and settings as the KV4/MTP2 row above, on
1232
- `5188f8a` plus the request-policy candidate. The manual
1233
- `MLX_BUN_RD_PREFILL_CHUNK=256` override is removed. The captured backend policy
1234
- selects 2,048 tokens for short requests and 256 at 78,678 tokens, bounding the
1235
- estimated materialized attention workspace to 1 GiB. This changes work size,
1236
- not admission, and explicit settings retain precedence.
1237
-
1238
- All 19 request hashes, response hashes, generated counts and cached counts
1239
- match the fixed-256 control, including all four concurrent responses. There
1240
- are no failures or retries. Long-context decode is 12.696 versus 12.756 tok/s;
1241
- cold context TTFT is 889,846 versus 882,927 ms, cached-repeat TTFT 210.65 versus
1242
- 207.76 ms, and SSD restart 2,554.05 versus 2,538.03 ms. Short cold TTFT decreases
1243
- from 6,470.61 to 5,916.70 ms; this single ordered comparison is an acceptance
1244
- screen, not a balanced speed claim. Aggregate throughput is 16.640 versus
1245
- 16.708 tok/s. The automatic arm's sampled RSS peaks at 15,567 MiB.
1246
-
1247
- The restart reuses 78,677 tokens. Final flush records 24 durable entries,
1248
- longest prefix 78,741, and zero pending, dropped or failed spills. Source hash
1249
- `bee0cb78d2c21e9873145b5caa8286af79959e750b047b9260e3eb7499b7689a`
1250
- is unchanged through the run. The policy is adopted across ordinary,
1251
- shared and speculative request bindings; focused override/ownership checks,
1252
- 2,300 model-free tests and all three typechecks pass. Raw evidence:
1253
- `reports/prefill-observation/late-context-auto-kv4-mtp2.md.json`.
1254
-
1255
- ### Affine KV composition for committed token appends
1256
-
1257
- M4 Pro 24 GB, Bun 1.4.2 / native pack 0.4.0, `d3dffa9` plus the append
1258
- candidate, measured 2026-09-13 UTC. The old KV4 failure is an attention
1259
- arithmetic change: appending four tokens selects a multi-query quantized
1260
- operation rather than the one-token operation used by decode. Both tiled
1261
- and ordinary unfused attention differ in the diagnostic. Preserving each
1262
- query's causal prefix and one-token operation removes every difference,
1263
- while projection work remains shared over the committed span.
1264
-
1265
- The operation test passes 72 combinations on both Macs: B1/B2, one/four
1266
- positions, KV4/KV8, groups 32/64/128 and bf16/fp16/fp32 (216 assertions each).
1267
- Packed and RTN4 Qwen27B pass complete hidden, logit and cache-byte identity
1268
- plus four continuations at prefixes 128 and 1021 with KV4/KV8. The latter
1269
- crosses the 1,023/1,024 attention boundary. The real packed-model KV4 generation
1270
- loop also retains emitted IDs, final live state, subsequent logits and active
1271
- allocation; 12 of its 26 tokens are filled with no verification. A separate
1272
- real-generation case converts KV eight tokens after the prompt, inside the
1273
- committed output span, and retains the same complete state/output checks.
1274
- The cache policy supplies that boundary; the method splits and converts
1275
- before continuing. Log: `affine-fill-delayed-native-m4.log`.
1276
-
1277
- Six alternating HTTP pairs use fresh servers, explicit serial execution,
1278
- KV4, disabled prompt caching, temperature zero, thinking off and a 128-token
1279
- budget. Each server warms the weather request before measuring weather and
1280
- shell-tool fixtures. The packed arm preserves all 24 responses: tool names,
1281
- arguments, text, finish reasons and prompt/completion counts. All twelve
1282
- paired request comparisons improve. Median paired complete-time reductions
1283
- are 16.90% for weather and 16.05% for shell-tool output; median wall times
1284
- are 4,898.64→4,068.83 ms and 5,234.14→4,397.59 ms. Each enabled request fills
1285
- 19 tokens with zero verification. Tools are buffered until a complete call,
1286
- so these are request-time results, not ordinary decode tok/s. The matching
1287
- RTN4 comparison also preserves all 24 responses and improves every pair.
1288
- Its median paired reductions are 3.13% and 2.77%, with median wall times
1289
- 4,030.36→3,901.19 ms and 4,307.17→4,159.80 ms. All enabled RTN4 requests
1290
- also fill 19 tokens without verification. Both arms retain fixed source
1291
- throughout their six blocks.
1292
-
1293
- The append binding declares supported affine formats. Preparation and
1294
- placement pass the candidate to the method without duplicating cache-format
1295
- checks. Fill remains opt-in and serial-only. The TurboQuant extension is measured
1296
- below; quantized verification, shared-group fill and held-out quality remain
1297
- separate cells. The full local
1298
- suite passes 2,303 tests with 14 fixture skips; typechecks and expanded
1299
- operation/ownership checks pass. Diagnostic raw reports:
1300
- `reports/prefill-observation/affine-append-{attention,model,model-rtn4}-m4.json`,
1301
- `affine-fill-native-m4.log`, and `affine-fill-http{-rtn4,}-m4.json` in the same directory.
1302
- The first native timing arms include cold work and are not speed evidence.
1303
-
1304
- ### Affine fill across saved session fixtures
1305
-
1306
- M4 Pro 24 GB, clean `eb510cd`, packed Qwen27B, KV4, explicit serial, no
1307
- prompt cache, temperature zero, thinking off and a 128-token budget. The
1308
- existing `bash-suite`, `read-edit-loop` and `grep-repeat` fixtures supply ten
1309
- assistant turns with their recorded tool results. The replay reconstructs
1310
- tool schemas through the existing fill harness; it executes no tools.
1311
-
1312
- Two opposite arm orders produce 40 successful requests, with all 20 paired
1313
- comparisons retaining identical text, tool names/arguments, finish reasons
1314
- and prompt/completion counts. Six distinct turns use fill in both blocks,
1315
- for 192 injected tokens total and zero verification. Every filled comparison
1316
- is faster. Turns without fill range from 1.5% faster to 0.4% slower. Median
1317
- paired complete-time reduction across all turns is 7.59%; this is a small
1318
- fixed-fixture diagnostic, not a full Kanban or general task-quality result.
1319
- The generated answers need not match the recorded assistant's actions;
1320
- the comparison checks whether enabling fill changes those answers.
1321
-
1322
- Tracked source and the append-kernel hash stay unchanged throughout. Raw
1323
- requests, expected fixture output and both served outputs are retained in
1324
- `reports/prefill-observation/affine-fill-fixtures-m4.json`; derived pairs are
1325
- in `affine-fill-fixtures-review.json`. These results broaden the tool-history
1326
- screen without replacing the held-out real-session quality requirement.
1327
-
1328
- ### TurboQuant committed fill
1329
-
1330
- M4 Pro 24 GB, `eb510cd` plus the format-declaration/maintenance patch, packed
1331
- and RTN4 Qwen27B. The model-owned append binding now declares K8V3 support;
1332
- cache maintenance limits chunks at delayed TurboQuant conversion boundaries.
1333
- This reuses the existing attention path without introducing a new kernel.
1334
-
1335
- The real generation gate preserves emitted IDs, complete final state,
1336
- subsequent logits and active allocation on both artifacts. Packed also passes
1337
- conversion eight tokens after the prompt. Each case emits 26 tokens, fills 12
1338
- and performs no verification. The initial packed allocation assertion failed
1339
- because the test retained temporary codec views; using the cache-state lease
1340
- API fixes the harness. That failed result is retained alongside the passing
1341
- rerun. The model-free suite passes 2,304 tests with 14 fixture skips, and all
1342
- three TypeScript checks pass.
1343
-
1344
- Six alternating HTTP pairs per artifact use the same weather/bash requests
1345
- as the affine comparison: fresh servers, explicit serial, K8V3 fused decode,
1346
- no prompt cache or draft, temperature zero, thinking off and max 128 tokens.
1347
- All 48 responses preserve text, tool calls, finish reasons and token counts.
1348
- Each enabled request fills 19 tokens with zero verification. Every paired
1349
- request improves; source and append-kernel hashes remain fixed throughout.
1350
-
1351
- | Artifact | Fixture | Median wall time off → on | Median paired reduction |
1352
- | --- | --- | ---: | ---: |
1353
- | Packed Qwen27B | Weather | 5,765.87 → 4,392.07 ms | 17.45% |
1354
- | Packed Qwen27B | Bash | 6,462.54 → 4,906.06 ms | 16.21% |
1355
- | RTN4 Qwen27B | Weather | 4,869.22 → 4,756.31 ms | 3.04% |
1356
- | RTN4 Qwen27B | Bash | 5,021.60 → 4,917.02 ms | 3.07% |
1357
-
1358
- These diagnostic tool-request results do not establish ordinary decode TPS
1359
- or a speed advantage over affine KV; the codec comparisons ran at different
1360
- times. Fill remains opt-in and serial-only, and quantized echo verification
1361
- remains inactive. Raw evidence in `reports/prefill-observation/`:
1362
- `tq-fill-native-m4.log` (initial failure), `tq-fill-native-v2-m4.log`,
1363
- `tq-fill-delayed-native-m4.log`, `tq-fill-rtn4-native-m4.log`,
1364
- `tq-fill-http{-rtn4,}-m4.json`, and `tq-fill-http-review.json`.
1365
-
1366
- ### Retained-cache alignment after early first-token return
1367
-
1368
- M4 Pro 24 GB, `756a7df` plus the empty-range fix (the tested prompts do not
1369
- use empty ranges). `first-token-cache.test.ts` passes on both packed and RTN4
1370
- Qwen27B: prompts of 76 and 421 tokens preserve token zero, retained token IDs,
1371
- complete cache state and subsequent full logits/state for suffix lengths
1372
- 1, 2, 4, 5 and 16. Each artifact passes 28 assertions. This closes the M4
1373
- native counterpart to the existing M1 checks for the final caller-owned M=1
1374
- alignment; it is correctness evidence, not a latency measurement.
1375
-
1376
- Logs: `reports/prefill-observation/first-token-cache-{packed,rtn4}-m4.log`.
1377
- The monitored serving comparison below closes the default-selection gate.
1378
-
1379
- ### Earlier first output: monitored serving comparison
1380
-
1381
- M4 Pro 24 GB, Bun 1.4.2, native pack 0.4.0 / MLX 0.32.2, source
1382
- `34e1eb4` held unchanged within every comparison. Packed Qwen27B and the
1383
- RTN4 storage control each run six alternating AB/BA blocks in default continuous
1384
- serving (cap eight, no batch override) and explicit serial (`--batch 1`).
1385
- Only `MLX_BUN_EARLY_FIRST_TOKEN=0/1` changes. Both use affine KV4,
1386
- 1 GiB prompt cache, no draft, temperature zero, 32-token maximum and a distinct
1387
- warmup. Each arm measures a short non-thinking response twice and a reasoning
1388
- response cold/cached. The prompts have 20/421 tokens; outputs have 6/32 tokens.
1389
- The short repeat has no cache hit; the reasoning repeat reuses 420 tokens.
1390
-
1391
- The HTTP reader is `measureChatRequest` from `bench-serve.ts`: first output
1392
- means a content, reasoning or tool delta, not headers or an empty SSE event.
1393
- All 192 requests finish, all 96 pairs preserve complete text, prompt/output/cache
1394
- counts and finish reason, and usage confirms the intended execution lane.
1395
- Every paired request emits its first semantic output earlier with the option.
1396
-
1397
- | Artifact / lane | Short first: paired median saved | Short repeat: saved | Reasoning cold: saved | Reasoning cached: saved | Complete-time paired median changes across the four cells |
1398
- | --- | ---: | ---: | ---: | ---: | ---: |
1399
- | Packed / default continuous | 69.31 ms | 72.79 ms | 73.60 ms | 69.57 ms | −0.04% to +0.63% |
1400
- | Packed / explicit serial | 70.31 ms | 68.54 ms | 85.65 ms | 70.60 ms | +0.01% to +0.42% |
1401
- | RTN4 / default continuous | 55.10 ms | 54.05 ms | 58.84 ms | 50.50 ms | −0.14% to +0.92% |
1402
- | RTN4 / explicit serial | 50.46 ms | 51.95 ms | 50.98 ms | 56.37 ms | −0.14% to +2.20% |
1403
-
1404
- For packed Qwen with default serving, median cached first output falls from
1405
- 164.24 to 94.46 ms. This is an output-latency improvement. Starting the output
1406
- interval earlier changes post-first-output TPS arithmetic; it does not mean
1407
- more model work was completed per second. Complete-request times remain close,
1408
- with the short-response tradeoffs shown above.
1409
-
1410
- Activity was sampled throughout each run, including process CPU/RSS, GPU last
1411
- submitter and VM counters. In measured request windows, the benchmark server
1412
- was the last GPU submitter in 131/132 and 128/129 packed samples. Other samples
1413
- were WindowServer/Codex; the two packed runs recorded no swap-outs in intervals
1414
- whose endpoints both fall inside a request. RTN4 had 99/105 and 92/104 server
1415
- samples, with macOS mediaanalysisd appearing once and ten times respectively,
1416
- and active paging. Those RTN4 complete-time changes are not attributed to the
1417
- code alone; a monitored repeat follows. CPU activity and retained swap are
1418
- recorded context, not automatic rejection criteria. Last-submitter sampling
1419
- cannot account for every GPU command.
1420
-
1421
- The RTN4 repeat keeps the same six-pair protocol and source. All 48 additional
1422
- pairs preserve outputs/counts; 47 emit first output earlier (one cold reasoning
1423
- pair does not). Paired median savings are 50.39/53.21/53.21/52.06 ms for default
1424
- continuous and 53.64/51.95/54.52/53.97 ms for serial, in the table’s column order.
1425
- Complete-time cell medians are +0.14..+0.61% and −0.04..+0.99% respectively.
1426
- The server accounts for 100/104 and 100/105 request-window GPU last-submitter
1427
- samples; the others are desktop applications, with no mediaanalysisd sample.
1428
- Neither repeat records swap-outs inside the paired request-window intervals.
1429
- This supports earlier output as the default, with a small complete-time
1430
- tradeoff rather than a throughput gain. The original overlapped RTN4 results
1431
- remain above. Repeat records use the suffix `-cache1-repeat-m4`; analysis is
1432
- `first-token-http-repeat-review.json`.
1433
-
1434
- Raw results, source manifests, responses, event timings and activity:
1435
- `reports/prefill-observation/first-token-http-{packed,rtn4}-{continuous,serial}-cache1-m4{.json,.activity.json,.log}`;
1436
- paired analysis: `first-token-http-final-review.json`. The earlier aborted
1437
- 0.25 GiB cache screen is retained separately: it failed to retain the reasoning
1438
- prompt, so it supplies no cached-latency evidence. The caller-owned native
1439
- alignment checks above and prior cancellation/overlap/SSD gates remain accepted.
1440
-
1441
-
1442
- ### Fixed arrivals under the batched default
1443
-
1444
- M4 Pro 24 GB, packed Qwen27B, Bun 1.4.2 and MLX 0.32.2. The execution
1445
- source is `383e840` plus the request-wait tracing change subsequently committed
1446
- as `50f9c3d`; each arm retains identical before/after source hashes. Two blocks
1447
- reverse serial/default order. Default serving omits a batch override (cap eight);
1448
- the control uses `--batch 1`. Both use KV4, no draft, no prompt cache,
1449
- automatic prefill sizing and the new early-output default with its flag unset.
1450
- This isolates ordinary scheduling from MTP and cache reuse.
1451
-
1452
- Three waves start six seconds apart, with arrivals spaced 250 ms within a wave.
1453
- Each wave has two, four or eight requests; clients submit on the fixed schedule
1454
- without waiting for earlier completions. Each distinct inventory prompt has
1455
- 90 or 91 tokens and requests 32 thinking tokens at temperature zero. All 168
1456
- requests finish at the full budget, all 84 serial/default response pairs match
1457
- exactly, and usage confirms the intended lane. Recorded client submission
1458
- lateness is retained separately from server queueing. Phase tracing is on,
1459
- without synchronization attribution; server stats and process/GPU/VM activity
1460
- are observed throughout. These are bounded repeated-arrival diagnostics, not
1461
- an uninstrumented steady-state capacity measurement.
1462
-
1463
- | Requests per wave | Serial aggregate tok/s, two orders | Default aggregate tok/s, two orders | Default aggregate gain | Serial p95 first-output latency | Default p95 first-output latency |
1464
- | --- | ---: | ---: | ---: | ---: | ---: |
1465
- | 2 | 7.952 / 7.929 | 10.731 / 10.843 | 34.95% / 36.76% | 8.64 / 8.68 s | 2.56 / 2.56 s |
1466
- | 4 | 7.967 / 7.946 | 12.022 / 12.726 | 50.90% / 60.16% | 30.61 / 30.74 s | 8.20 / 8.54 s |
1467
- | 8 | 7.942 / 7.947 | 13.505 / 13.469 | 70.04% / 69.50% | 75.83 / 75.80 s | 32.57 / 32.73 s |
1468
-
1469
- The default reaches two active rows in the lightest workload and eight in both
1470
- heavier workloads, where waves overlap. At the highest load, median combined
1471
- request-slot/execution-admission wait falls from 39.3–39.5 s to 12.9 s.
1472
- The whole queue clears sooner, but individual requests do not all dominate the
1473
- serial control: in the first highest-load block, the first response completes
1474
- in 19.69 s versus 5.24 s serial, and the longest visible-output gap is 6.50 s
1475
- versus 1.21 s. New prefills interrupt existing streams. These results support
1476
- the batched default’s aggregate benefit while preserving its latency tradeoff.
1477
- They are not a single-request decode-TPS comparison or a completed-task quality
1478
- evaluation; the 32-token responses end during reasoning.
1479
-
1480
- The activity logs include intermittent mediaanalysisd GPU submissions, desktop
1481
- GPU work and VM activity. All samples and both arm orders are retained; no CPU
1482
- percentage or retained-swap threshold excludes an arm. The measured gains are
1483
- consistent across orders, but the exact ratios are not promoted as quiet-box
1484
- capacity claims. An earlier attempt lost GPU telemetry because whole-registry
1485
- plist-to-JSON conversion failed; it is retained separately and does not supply
1486
- this table. The corrected observer extracts the convertible GPU submission
1487
- metadata before any benchmark server starts.
1488
-
1489
- Raw results, per-request server spans, output events and activity:
1490
- `reports/prefill-observation/sustained-serving-packed-observed-m4.json`;
1491
- analysis: `sustained-serving-review.json`. The failed-observer attempt uses
1492
- `sustained-serving-packed-m4` and its note file. Existing cancellation,
1493
- independent recovery and long multi-turn RAM/SSD gates remain accepted.
1494
-
1495
- The load-four follow-up tests two existing scheduling controls in opposite arm
1496
- orders, with 12 requests per arm and the same source/workload. A global
1497
- 32-token prefill chunk preserves all 24 paired responses but increases complete
1498
- workload time by 3.85%/12.57%; first-request completion grows from 16.84/16.55 s
1499
- to 22.58/22.63 s. Worst output gaps shrink from 3.54/3.53 s to 3.08/3.06 s.
1500
- Mixed iteration work with budget 32 and feed-forward packing disabled also
1501
- preserves all 24 pairs, but increases complete time by 39.48%/46.89% and
1502
- first-request completion from 16.83/15.98 s to 21.88/20.89 s. Its worst gaps
1503
- shrink to 2.60/1.94 s from 3.52/3.48 s. Activity and source records are retained;
1504
- these controls do not justify a default change. The existing larger-work-unit
1505
- policy stays selected. Raw records: `sustained-chunk32-packed-m4.json` and
1506
- `sustained-unpacked32-packed-m4.json` under the same report directory.
1507
-
1508
- ### Full Kanban after decode integration
1509
-
1510
- September 13, 2026, M4 Pro 24 GB. The fresh task on `721ac4c` uses the same
1511
- packed Qwen artifact, folded RTN4 MTP depth two, affine KV4, batch cap eight,
1512
- 4 GiB RAM cache, 64 GiB SSD cache, pinned Pi/profile, seed 42 and sampling
1513
- settings as `kanban-session-cache-r2`. Automatic prefill replaces the earlier
1514
- explicit 256-token chunks, and early output uses its new default. The initial
1515
- request is identical. The earlier engine also defaulted to 2,048-token
1516
- chunks when no override was supplied; this comparison removed the task's
1517
- explicit override. Source remains fixed, Pi and server exit successfully,
1518
- and there are no inference failures or retries. Pi records one tool error.
1519
-
1520
- | Measurement | Previous session-cache task | Integrated task |
1521
- |---|---:|---:|
1522
- | Task wall time | 83m57.098s | 82m27.681s |
1523
- | Generated tokens | 76,031 | 77,137 |
1524
- | Requests | 25 | 20 |
1525
- | Weighted post-first-output throughput | 15.542 tok/s | 15.885 tok/s |
1526
- | Sum of pre-first-output intervals | 143.024 s | 73.060 s |
1527
- | Follow-ups with cached input | 24/24 | 19/19 |
1528
- | Durable final SSD flush | Yes | Yes |
1529
- | Missing / failed snapshots at final flush | 0 / 0 | 0 / 0 |
1530
- | SSD entries after final flush | 38 | 40 |
1531
- | Verified app acceptance categories | 16/18 | 10/18 |
1532
-
1533
- The task is 1.8% shorter with 1.5% more output and 2.2% higher measured
1534
- throughput. This is not an engine-only speed ratio: the first reasoning
1535
- response already differs, generating 48,804 tokens instead of 35,002, and
1536
- later tool inputs and output lengths differ. The five-second observer records
1537
- 967 server last-submitter samples out of 984 during the task; the others
1538
- identify desktop processes. All activity records are retained, with no
1539
- observer errors. Retained swap at startup is recorded, not used as a veto.
1540
-
1541
- The untouched app fails six categories and leaves two blocked by missing
1542
- editing controls. Its DOM helper stringifies child arrays, so label and modal
1543
- action buttons appear as object text. This blocks card editing, complete card
1544
- creation and column confirmation actions. A separate wrong callback argument
1545
- throws during column naming. Positive label/assignee filters and persistence
1546
- of edited fields cannot be verified through the broken UI. Card/column
1547
- dragging, Done indicators, card archive/restore, search, theme persistence and
1548
- the other passing checks have browser evidence. Generated source hashes are
1549
- unchanged by validation. This run does not meet the 16/18 quality target.
1550
-
1551
- A four-arm first-request replay on the same source keeps every request field
1552
- fixed except a 64-token output cap. Fixed 256-token chunks reproduce the
1553
- previous task's response prefix; automatic chunks reproduce the integrated
1554
- task's prefix. Early-output on/off preserves the complete response and usage
1555
- within each chunk setting. This isolates the initial divergence to prefill
1556
- chunking, not to the early-output option. It does not establish a general
1557
- quality regression from chunking. The full fixed-256 control on the same
1558
- integrated source is complete. No application repair or additional prompt is
1559
- included.
1560
-
1561
- | Measurement | Previous session-cache task | Integrated, fixed-256 control |
1562
- |---|---:|---:|
1563
- | Task wall time | 83m57.098s | 69m52.768s |
1564
- | Generated tokens | 76,031 | 67,816 |
1565
- | Requests | 25 | 17 |
1566
- | Weighted post-first-output throughput | 15.542 tok/s | 16.491 tok/s |
1567
- | Sum of pre-first-output intervals | 143.024 s | 75.877 s |
1568
- | Follow-ups with cached input | 24/24 | 16/16 |
1569
- | Durable final SSD flush | Yes | Yes |
1570
- | Missing / failed snapshots at final flush | 0 / 0 | 0 / 0 |
1571
- | Verified app acceptance categories | 16/18 | 17/18 |
1572
-
1573
- The control reproduces the complete initial response: 35,002 tokens,
1574
- 128,406 reasoning characters, identical tool arguments and MTP counts:
1575
- 27,506 drafted, 21,249 accepted across 13,753 rounds. First-response wall time
1576
- is 1,967.818 s versus 2,000.478 s previously. This is response identity, not a
1577
- record of every logit vector. The next request differs only in generated tool
1578
- IDs and the actual empty directory's listing timestamps; later outputs diverge.
1579
- The full task is 16.8% shorter with 10.8% fewer tokens and 6.1% higher observed
1580
- throughput. Different subsequent work and context lengths prevent attributing
1581
- that whole-task ratio to the engine alone.
1582
-
1583
- The untouched app meets the requested 16/18 target, passing 17 categories.
1584
- Creating/editing labeled and assigned cards, column operations, native drag
1585
- and reorder, Done indicators, archive/restore, search, persisted fields and
1586
- order, light/dark themes and keyboard create/edit all pass. The remaining
1587
- failure is the earlier filter-reset defect: the all-items options omit an
1588
- empty value, so choosing them filters for their display text and hides every
1589
- card. Reload clears the filters. Keyboard editing improves over the prior
1590
- three 16/18 tasks. All 14 generated files retain their pre-validation hashes;
1591
- no blocking JavaScript error occurs. This is a successful task control, not
1592
- proof of quality consistency across prompts or seeds. Retain fixed-256 chunks
1593
- in this task-comparison profile; this result does not justify replacing the
1594
- general automatic policy based on one changed trajectory.
1595
-
1596
- Pi and server exit successfully with unchanged engine source, zero tool
1597
- errors, retries or compactions. Final persistence retains 34 SSD entries and
1598
- 48,310,636,544 bytes, with longest durable prefix 73,035 and no pending,
1599
- dropped, failed or missing snapshots. The five-second observer records the
1600
- server as last GPU submitter in 823 of 834 task samples; the other samples
1601
- identify Codex and Terminal, with no observer errors.
1602
-
1603
- Raw requests/responses, source hashes, activity, cache flushes, untouched apps
1604
- and browser evidence are under `reports/kanban-decode-integrated-r1/` and
1605
- `reports/kanban-decode-fixed-prefill-r1/`. All 40 SSD snapshots from the first
1606
- run are archived in the M1 report directory; their 67,578,265,600 bytes match
1607
- the pre-transfer file-size manifest. The transfer overlaps the control's
1608
- first response and completes before it ends. This is a quality comparison,
1609
- not a quiet timing pair; both tasks retain the same RAM/SSD capacities.
1610
-
1611
- A bounded passive sample during the fixed-256 first response records median
1612
- GPU activity of 98.28% and nominal thermal status. `mactop`'s byte-bandwidth
1613
- fields are unavailable on this installation. A separate read-only IOReport
1614
- sample captures PMP `DCS BW` rate histograms: the aggregate `AMCC RD+WR`
1615
- weighted labels range from 102.07 to 107.49 GB/s over five samples. These are
1616
- coarse system-wide rate estimates, not accumulated byte counters or per-kernel
1617
- attribution. The GPU-specific histogram saturates its highest 32 GB/s bin in
1618
- 78–81% of samples and cannot supply a usable GPU bandwidth average. ANE
1619
- traffic histograms have no residency in this short window. No GPU calibration
1620
- workload runs. Raw telemetry: `pmp-readonly.jsonl`, `pmp-review.json` and
1621
- `mactop-readonly.json` in the fixed-prefill report directory.
1622
-
1623
- ### Three-query affine attention head grouping
1624
-
1625
- The R13 screen groups two or three query heads only for the quantized key
1626
- multiplication, then restores score shape before masking/softmax. Value
1627
- multiplication retains its original geometry. Native KV4/group64 cases cover
1628
- B1/B2, GQA6/D256, three query tokens, contexts 128/8,192/32,768, bf16/f32 and
1629
- both contiguous and transposed queries. The copied ungrouped control matches
1630
- the production implementation in every case on both Macs.
1631
-
1632
- M1 Max: each grouped candidate changes 16 of 24 complete outputs, all at the
1633
- two longer contexts; the difference is already present in key scores. The M1
1634
- path is not eligible for this exact optimization. M4 Pro: both candidates
1635
- preserve every tested key score and complete attention output (24 cases each).
1636
- Each comparison computes its reference on the same Mac as the candidate.
1637
- No M1 result is compared against an M4 golden or output.
1638
-
1639
- Six alternating three-arm blocks time complete attention construction and GPU
1640
- evaluation, 30 calls per arm, at the two longer contexts in bf16. On M4 Pro,
1641
- grouping three heads reduces median paired attention time by 7.48–11.44%
1642
- across all eight batch/context/layout cells; all six pairs improve in each
1643
- cell. Grouping two heads is inconsistent (−2.46% to +0.62%), so the three-head
1644
- candidate proceeds to the full-model verification below. Ten of eleven observer samples
1645
- identify the benchmark as last GPU submitter; the initial sample identifies
1646
- mediaanalysisd. These operation timings alone do not establish serving speed.
1647
-
1648
- The subsequent M4 Pro 24 GB comparison uses Bun 1.4.2, MLX 0.32.2,
1649
- source `a740464` with only the key-head reshape changed, and the packed
1650
- Qwen3.8-27B artifact. Six alternating baseline/candidate blocks evaluate
1651
- three full L3 forwards and four L1 continuations per cell. Attention history
1652
- is padded to the target length after a real four-token initialization;
1653
- recurrent state retains that initialization. This is a synthetic state and
1654
- timing test, not a long-prompt quality evaluation. All 72 paired measured
1655
- forwards, 96 continuation vectors and retained states match exactly.
1656
-
1657
- | Batch | Attention prefix | Baseline forward ms | Grouped forward ms | Median paired change |
1658
- |---|---:|---:|---:|---:|
1659
- | 1 | 8,192 | 117.50 | 115.61 | −1.28% |
1660
- | 1 | 32,768 | 143.61 | 140.27 | −2.12% |
1661
- | 2 | 8,192 | 361.77 | 359.48 | −0.62% |
1662
- | 2 | 32,768 | 429.62 | 423.21 | −1.67% |
1663
-
1664
- Every native pair improves in each cell. A separate HTTP comparison uses a
1665
- real 9,067-token rendered prompt, KV4, MTP depth two and default batch cap
1666
- eight. Each fresh server warms the prompt, then measures two 64-token greedy
1667
- responses with 9,066 cached tokens. Six alternating blocks preserve all 12
1668
- paired responses, usage records and speculation decisions. Median paired
1669
- complete request time decreases 0.89%, with all pairs improving; median
1670
- decode throughput is 18.11 versus 18.29 tok/s. The shared benchmark request
1671
- measurement captures complete streams. All 83 process/GPU samples inside
1672
- measured requests identify the server as last GPU submitter, with no observer
1673
- errors. This sampled observation cannot exclude activity between samples.
1674
- RAM supplies these hits; write-behind is disabled and there are no SSD restores.
1675
- This is a targeted serving comparison, not a replacement standard h2h matrix.
1676
-
1677
- Three-head selection is automatic only on `applegpu_g16s` for B1/B2,
1678
- 24 query heads/four KV heads, L3/D256, KV4/group64, bf16/f32 and N≥8,192.
1679
- An additional 32 M4 cases at N=65,536/131,072 preserve key and output bytes.
1680
- The permanent strided-KV regression passes on both Macs. The complete local
1681
- model-free suite passes 2,310 tests with 14 fixture skips; typechecks pass.
1682
-
1683
- Raw records: `reports/prefill-observation/head-pair-{m1-control,m1-key-stage,m4-key-stage}.json`,
1684
- `head-pair-perf-m4.json`, `head-pair-perf-m4.activity.json` and
1685
- `head-pair-perf-review.json`, `head-pair-large-m4.json`,
1686
- `head-pair-model-review.json`, `head-pair-http-v2-review.json` and their
1687
- per-arm JSON/activity records. The original M1 screen and the aborted HTTP
1688
- setup with a below-threshold prompt are retained and excluded from timing.
1689
-
1690
- ### M1 wide-prefill qualification
1691
-
1692
- Forcing the existing M3+ trellis wide-prefill kernel on M1 Max changes
1693
- output bytes in 35 of 66 cases against expanded-bf16 native matmul computed
1694
- on that same M1, in the same process and loaded MLX runtime. This operation
1695
- screen does not use M4 outputs or substitute for a full model oracle. The
1696
- screen covers M5–15, two/three/four-bit codes, input width 5,120 and output
1697
- widths 128/17,408. All 33 full-width cases differ; the smaller width also
1698
- differs at three-bit M14/M15. The current kernel is therefore not selected
1699
- on M1. No speed claim is made for the failing candidate. Raw records:
1700
- `reports/prefill-observation/trellis-wide-prem3-m1.json`.
1701
-
1702
- ### Native integer ranges and monitored model comparison
1703
-
1704
- Bun 1.4.2 can construct ordinary nonnegative int32 position ranges through
1705
- native MLX after the existing FFI out-pointer read fix. Direct range checks
1706
- match 39,330,480 values; native conversion differs from JS Int32Array for
1707
- starts outside int32, so the candidate preserves the host implementation for
1708
- general ranges. A narrowed candidate only changes unit-step ranges of at least
1709
- 65,536 elements, plus empty ranges whose host buffer has no FFI pointer.
1710
-
1711
- The final range/mask loop evaluates 128 growing four-query masks per arm,
1712
- with six alternating pairs at each context size. Median paired time reductions
1713
- are 26.94% / 40.19% on M1 Max at 65,536 / 131,072 initial positions, and
1714
- 30.88% / 39.76% on M4 Pro. Median loop times are 45.60→34.00 / 56.97→34.43 ms
1715
- on M1 and 19.67→13.71 / 25.16→15.07 ms on M4. These are operator measurements,
1716
- not decode TPS. Raw results: `native-arange-final2-m1.json` and
1717
- `native-arange-final-m4.json` in the report directory below. A reusable
1718
- power-of-two prefix adds inconsistent benefit on M1 and remains unselected. The first six-pair M4 full-model comparison preserves every hidden,
1719
- logit and cache-state hash but contains large timing outliers. It did not record
1720
- other process/GPU activity throughout each pair; its apparent regression does
1721
- not support a rejection decision. The requested monitored repeat also preserves
1722
- all 54 paired hidden/logit/state results, and the large slowdowns disappear.
1723
- Median paired complete-time changes are -0.10% at one token, -0.14% at four
1724
- and -0.14% at 128. These are effectively flat, not a material model-speed gain.
1725
-
1726
- The model probe uses packed Qwen27B and a synthetic 77,077-token zero-filled
1727
- KV4 attention history, with recurrent state from four real input tokens. It
1728
- warms each query length, then times three complete target forwards at lengths
1729
- 1, 4 and 128; these are decode/verification/prefill shapes, not a real task or
1730
- complete speculative round. Raw initial results and all outliers remain in
1731
- `reports/prefill-observation/native-arange-model-pairs-m4.json` and
1732
- `native-arange-model-review.json`. No serving speed claim or default change is
1733
- based on this screen. The repeat captures 247 process/GPU/VM snapshots with
1734
- forward timestamps. Of 95 snapshots inside timed forwards, 93 name the
1735
- benchmark as the last GPU submitter and two name Terminal. ChatGPT's renderer
1736
- is CPU-active throughout most of the run; Resolve's main process is absent
1737
- while an idle ResolvePython helper remains. Limited
1738
- paging still occurs, and sampled last-submitter data cannot prove exclusive
1739
- GPU execution or establish the cause of the earlier outliers. Complete records
1740
- are `native-arange-model-repeat-m4.json`,
1741
- `native-arange-model-repeat-activity-m4.json`, and
1742
- `native-arange-model-repeat-review.json`.
1743
-
1744
- The standard serving script then runs two opposite arm orders on the same M4,
1745
- with default batching, KV4, MTP2, 1 GiB prompt cache, 64 decode tokens and the
1746
- same frozen workload seed. All 30 paired requests preserve text, token/cache
1747
- counts, finish reasons and complete speculation counters, including concurrent
1748
- requests. Source fingerprints stay fixed inside every arm; there are no phase
1749
- failures. This is a short serving screen, not a new long-Kanban acceptance run.
1750
-
1751
- | Pair order | Median decode baseline → native | Aggregate baseline → native |
1752
- | --- | ---: | ---: |
1753
- | Baseline, native | 19.425 → 19.351 tok/s | 10.483 → 10.464 tok/s |
1754
- | Native, baseline | 19.413 → 19.416 tok/s | 10.550 → 10.552 tok/s |
1755
-
1756
- Cold/cached first-output times are also effectively unchanged. The five decode
1757
- prompts have different draft acceptance; matching each request across arms gives
1758
- median decode-rate changes of +0.115% and +0.122%. Neither this nor the model
1759
- screen establishes a material serving gain. Activity capture retains 412
1760
- process/GPU/VM samples: 378 last-submitter observations name the benchmark or
1761
- its server, with desktop clients in the remainder. Paging and background CPU
1762
- activity remain recorded; these diagnostic results do not establish exclusive
1763
- GPU use or explain the earlier unmonitored outliers.
1764
-
1765
- The small range-construction change is retained for lower measured operator
1766
- cost and removal of large host Int32Array construction, with effectively flat
1767
- measured model/serving performance. General integer conversion and the 8 MiB
1768
- cache bound remain unchanged. The empty-range FFI failure is fixed. The final
1769
- model-free suite passes 2,306 tests with 14 fixture skips; typechecks pass.
1770
- Evidence: `native-arange-serving-{0,1}-{baseline,native}-m4.md.json`,
1771
- `native-arange-serving-activity-m4.json` and `native-arange-serving-review.json`
1772
- in the same report directory.
1773
-
1774
- ### Same-batch affine full-attention oracle
1775
-
1776
- `tests/parity/batched-affine-oracle.test.ts` compares MiniCPM5-1B OptiQ against
1777
- the pinned Python oracle with the same actual tensor batch: B1 and B4, uniform
1778
- KV4/KV8 and alternating KV4/KV8/bf16 layers. Six teacher-forced steps per case
1779
- include B4→B2 retirement and reordering to rows `[3, 1]`. Complete float32
1780
- logit byte hashes match at all 36 steps on both M1 Max and M4 Pro (74 assertions
1781
- per machine). The reference receives only the fixed input plan, never native
1782
- outputs. These equal-length rows close the full-attention unpadded cell;
1783
- the padded extension below uses an explicitly composed reference. Rotating
1784
- mixed-KV remains a separate numerical contract.
1785
- Run with `MLX_BUN_TEST_BATCH_AFFINE_ORACLE=1` and the pinned oracle environment.
1786
- Logs: `reports/prefill-observation/batched-affine-oracle-{m1,m4}.log`.
1787
-
1788
- The unequal-length extension uses prompt lengths `[5, 9, 7, 11]`, then six
1789
- teacher-forced decode steps with B4→B2 reordering/retirement to `[3, 1]`.
1790
- All 24 complete logit-vector hashes match on each machine for bf16, KV4,
1791
- KV8 and alternating KV4/KV8/bf16 layers (50 assertions per machine).
1792
- Enable this case with `MLX_BUN_TEST_BATCH_AFFINE_PADDING=1` alongside the
1793
- oracle opt-in. The existing equal-length mode remains available.
1794
-
1795
- Pinned mlx-lm lacks a padded quantized batch cache. The test composes its
1796
- `QuantizedKVCache` with `BatchKVCache` positions and causal masking. Its
1797
- quantized GQA helper also needs one broadcast axis for a per-row mask:
1798
- `[B,1,L,N]` becomes `[B,1,1,L,N]` against grouped scores. That test-only
1799
- adapter preserves the pinned model and attention arithmetic; it receives no
1800
- Bun cache or output values. This is a composed numerical reference, not a
1801
- stock server capability. The bf16 control uses unmodified `BatchKVCache`.
1802
- No production engine change or performance claim follows from this test.
1803
- Logs: `reports/prefill-observation/padded-affine-m1-final.log` and
1804
- `padded-affine-m4.log`; the initial reference broadcast error is preserved.
1805
-
1806
- ### Same-batch rotating affine oracle
1807
-
1808
- The same oracle test adds Gemma4-e4b's actual 512-token sliding window and
1809
- KV-sharing layers. Equal-length B1/B4 cases prefill 510 tokens before six
1810
- teacher-forced steps, crossing the ring boundary before B4→B2 retirement and
1811
- reordering. Unequal cases start with `[505, 509, 507, 511]` tokens and exercise
1812
- physical padding during the same transition. Each mode covers bf16, uniform
1813
- KV4/KV8 and alternating KV4/KV8/bf16 cache layers.
1814
-
1815
- On both M1 Max and M4 Pro with MLX 0.32.2, all 48 equal-length and 24
1816
- unequal-length complete logit-vector hashes match each machine's own pinned
1817
- reference. The M1 `gemma-4-e4b-it-OptiQ-4bit` snapshot is
1818
- `98d7dc6a93ae05583e8a10018c8099459b58aeeb`; M4 uses
1819
- `fcdb12d740cd813634064567fc7cb51159b34253`. These are separate same-artifact
1820
- comparisons on each host, not a cross-machine byte comparison.
1821
-
1822
- Equal-length rows use OptiQ's existing rotating quantized cache. Unequal rows
1823
- compose that storage with unmodified mlx-lm `BatchRotatingKVCache` for offsets,
1824
- padding and masks. The latter keeps separate bf16 state solely for reference
1825
- bookkeeping; attention consumes only the OptiQ quantized storage. Row filtering
1826
- applies to both. The existing GQA mask broadcast shim remains explicit. This is
1827
- a test-only composed reference, not a stock server claim or a solo-row oracle.
1828
- The bf16 cases use the stock cache directly. No production arithmetic changes.
1829
-
1830
- Set `MLX_BUN_TEST_BATCH_AFFINE_ORACLE=1` and
1831
- `MLX_BUN_TEST_BATCH_AFFINE_ROTATING=1`, with optional
1832
- `MLX_BUN_TEST_BATCH_AFFINE_PADDING=1`; `MLX_BUN_TEST_BATCH_AFFINE_MODEL` selects
1833
- the local artifact path. Logs: `reports/prefill-observation/rotating-affine-oracle-{m1,m4}.log`
1834
- and `padded-rotating-affine-oracle-{m1,m4}.log`.
1835
-
1836
- ### Recurrent prefill attribution
1837
-
1838
- Packed interleaved Qwen3.8-27B, bf16 KV, 2,048-token chunks, Bun 1.4.2 and
1839
- native pack 0.4.0, measured 2026-09-12 UTC. Fixed teacher-forced inputs use
1840
- `100 + (position * 7) % 600`. A temporary observer evaluates each gated-delta
1841
- kernel's inputs, then times kernel construction plus completed output/state
1842
- evaluation. It separately records the producer wait and complete prefill.
1843
- Control and attributed arms have identical complete hidden/state byte hashes
1844
- at every length on each machine. Cross-machine hashes are not an exact oracle.
1845
-
1846
- | Machine | Prompt tokens | Control prefill ms | Attributed prefill ms | Gated-delta total ms | Delta calls |
1847
- |---|---:|---:|---:|---:|---:|
1848
- | M1 Max 32 GB | 1,024 | 7,866.36 | 7,988.69 | 265.16 | 48 |
1849
- | M1 Max 32 GB | 4,096 | 34,738.57 | 45,542.79 | 1,391.01 | 96 |
1850
- | M1 Max 32 GB | 8,192 | 77,849.86 | 109,295.84 | 3,475.44 | 192 |
1851
- | M4 Pro 24 GB | 1,024 | 7,588.05 | 7,680.57 | 208.20 | 48 |
1852
- | M4 Pro 24 GB | 4,096 | 30,385.33 | 30,477.49 | 809.46 | 96 |
1853
- | M4 Pro 24 GB | 8,192 | 61,995.30 | 61,908.50 | 1,610.26 | 192 |
1854
-
1855
- On M4, measured gated-delta work is about 2.6–2.7% of complete prefill.
1856
- That scale does not support treating sequential recurrence as the principal
1857
- prefill bottleneck. M1 attribution perturbs the larger controls substantially;
1858
- its stage times are diagnostic, not clean critical-path shares. Neither this
1859
- synchronous observer nor a parallel recurrence algorithm is retained. A
1860
- chunkwise rewrite changes floating-point ordering and needs its own state and
1861
- quality contract; these measurements close attribution, not that numerical gate.
1862
- Weight expansion, projections and attention remain the larger prefill targets.
1863
-
1864
- Raw reports: `reports/prefill-observation/gdn-prefill-attribution-{m1,m4}.json`.
1865
- The operation probe is removed after recording these results. Existing serial
1866
- recurrence remains the pinned-oracle implementation.
1867
-
1868
- ### Nonblocking prefill completion screen
1869
-
1870
- M1 Max 32 GB, 2026-09-12 UTC, MiniCPM5-1B OptiQ snapshot
1871
- `664aabaed233c653f82716d8dc822234d0091f78`, bf16 KV, Bun 1.4.2 and native pack
1872
- 0.4.0. A temporary candidate replaces synchronous cache evaluation at shared
1873
- prefill maintenance boundaries with `mlx_async_eval`, checking each output's
1874
- native completion event once per millisecond. It retains state views until
1875
- completion and changes neither GPU operations nor the scheduler. The standard
1876
- benchmark uses default batch capacity eight, 192-token decode samples, four
1877
- aggregate requests staggered by 25 ms with context target 2,048, and workload
1878
- `prefill-long-0`. These diagnostic AB/BA pairs record roughly 4 GiB retained
1879
- swap and background host activity; they do not qualify an engine speed claim.
1880
-
1881
- | Pair | B1 decode, control → candidate tok/s | Aggregate, control → candidate tok/s | First aggregate request TTFT, control → candidate ms |
1882
- |---|---:|---:|---:|
1883
- | A/B | 272.154 → 282.112 | 191.540 → 180.567 | 381.49 → 739.48 |
1884
- | B/A | 269.658 → 280.016 | 192.581 → 194.464 | 366.92 → 711.87 |
1885
-
1886
- Every arm completes, keeps a fixed source hash and preserves all 15 request
1887
- hashes and prompt/generated/cached token counts. Each pair preserves 12 of 15
1888
- response texts; three concurrent trajectories change. Single-request outputs
1889
- remain exact. Aggregate throughput is inconsistent, and first-request latency
1890
- nearly doubles in both orders. Earlier host admission changes subsequent
1891
- batch scheduling. The candidate is **not adopted**; the original synchronous
1892
- prefill boundary remains. A local eight-matmul probe confirms that completion
1893
- polling frees the event loop and adds up to about one millisecond to the wait,
1894
- but that mechanism alone does not establish a serving benefit.
1895
-
1896
- Raw reports and the excluded patch: `reports/prefill-observation/async-prefill-{before,after}{,-repeat}.md.json`,
1897
- `async-prefill-candidate.patch`, and `async-eval-probe-m1.json` in that directory.
1898
-
1899
- ### Prefill observation and scheduling screen
1900
-
1901
- M4 Pro 24 GB, 2026-09-12 UTC, Bun 1.4.2, MLX 0.32.2/native pack 0.4.0.
1902
- Merged base `debee3e`; Gemma 4 12B OptiQ snapshot
1903
- `5b1101065d2094c8f12aa87fee80e0afa5b292b7`, ordinary affine KV4, 4 GiB RAM
1904
- cache and fresh temporary SSD. The standard server benchmark uses the default
1905
- batch capacity eight, with no `--batch 1`. Same `prefill-long-0` workload as the
1906
- [previous comparison](#current-serial-versus-shared-execution-staggered-gemma-requests):
1907
- 192-token single-request decode samples, skipped context sweep, four aggregate
1908
- requests staggered by 25 ms, target context 2,048. Actual aggregate prompt/cache
1909
- counts remain 1,289/13, 1,281/12, 1,287/14 and 1,287/12; each emits 128 tokens.
1910
- The prefill chunk size remains 2,048. Retained swap is 1,335.56 MiB and free memory
1911
- 89% before each arm. These are diagnostic runs with an exclusively allocated
1912
- GPU, not quiet performance claims. No server requests fail.
1913
-
1914
- | Arm in run order | B1 decode tok/s | Cached TTFT ms | Aggregate tok/s | Aggregate wall ms | First request TTFT ms | Mean TTFT ms |
1915
- |---|---:|---:|---:|---:|---:|---:|
1916
- | Merged baseline, tracing off | 26.108 | 175.589 | 20.250 | 25,284.02 | 9,010.70 | 15,869.64 |
1917
- | Component tracing | 26.060 | 159.833 | 19.976 | 25,630.88 | 9,076.31 | 16,140.91 |
1918
- | Component plus initial routing trace | 26.042 | 162.788 | 20.186 | 25,364.47 | 9,012.04 | 15,930.04 |
1919
- | Active-before-preparation experiment, traced | 26.376 | 160.632 | 19.620 | 26,096.38 | 4,689.58 | 14,162.81 |
1920
- | Final observer code, tracing off, original scheduler | 26.044 | 160.348 | 20.171 | 25,383.24 | 9,022.22 | 15,944.64 |
1921
-
1922
- All source hashes remain unchanged during each arm. The four observer/control
1923
- arms retain all 15 request bodies, responses and usage records exactly. The
1924
- final tracing-off comparison is −0.245% B1 decode and −0.391% aggregate
1925
- throughput versus the baseline, with +0.128% first-request TTFT. This bounded
1926
- screen finds no large observer-off cost; it is not a statistical proof of zero
1927
- overhead. The initial cached-latency sample is higher than the subsequent arms;
1928
- no cache speedup is attributed to instrumentation.
1929
-
1930
- The component trace identifies the first request's prefill cost: 5.16 ms of
1931
- forward construction/dispatch, 4,386.72 ms waiting for cache evaluation,
1932
- 2.84 ms KV maintenance, 0.85 ms checkpoint capture, and 0.38 ms lookup/restore.
1933
- Forward may include backend evaluation; these labels do not claim kernel-only
1934
- GPU timestamps. The first generated token is available at 4,512.23 ms, but the
1935
- first semantic write is at 9,075.96 ms. Another request's prefill evaluation
1936
- occupies 4,428.30 ms of that gap. Request processing for the later clients also
1937
- starts late because the owner thread is blocked; client submission times and
1938
- server trace origins are both retained.
1939
-
1940
- The routing trace resolves the first-token ambiguity: Gemma emits token 100
1941
- (`<|channel>`) at 4,507.24 ms, token 45,518 (`thought`) at 4,548.56 ms, then token
1942
- 107 (newline) at 9,011.62 ms. The first two are channel metadata; the newline is
1943
- the first reasoning event. The stream parser spends less than 0.05 ms per
1944
- observed initial token. It is not holding already-visible prose for seconds.
1945
-
1946
- The experimental scheduler advances active rows and yields before another
1947
- preparation unit. Against the routing-traced control it reduces first-request
1948
- TTFT by 47.96% and mean TTFT by 11.09%, but loses 2.805% aggregate throughput
1949
- and increases aggregate time 2.886%. All four concurrent texts change as batch
1950
- membership/positions change; single-request texts and request/usage counts
1951
- remain unchanged. One pair does not establish a stable throughput effect or
1952
- same-output quality equivalence. The experiment is **not adopted**. Its patch
1953
- is preserved; final source retains the original scheduler.
1954
-
1955
- The retained change is observability: process-aligned spans, shared-work IDs,
1956
- initial token routing, complete trace retention in standard benchmark reports,
1957
- and the offline `scripts/bench/prefill-trace.ts` summary. M1 Max checks pass:
1958
- 2,262 model-free tests, 14 fixture skips, no failures; all three typechecks pass.
1959
- Upstream algorithm comparison and the next mixed-iteration work are in
1960
- [batching design](../design/batching.md#scheduling-reference-algorithms-and-request-observations).
1961
- This screen does not close long-prefill dominance or mixed execution acceptance.
1962
-
1963
- Reproduce the measurement with the model artifact above:
1964
-
1965
- ```sh
1966
- MLX_BUN_P2R_TRACE=1 bun scripts/bench-serve.ts all \
1967
- --model-path /path/to/gemma-4-12B-it-OptiQ-4bit --arms mlx-bun \
1968
- --kv-quant 4 --prompt-cache 4 --tokens 192 --skip-context \
1969
- --aggregate-context 2048 --aggregate-stagger-ms 25 \
1970
- --workload-seed prefill-long-0 --diagnostic --out reports/prefill.md
1971
- bun scripts/bench/prefill-trace.ts reports/prefill.md.json --out reports/prefill-breakdown.json
1972
- ```
1973
-
1974
- Raw evidence on both Macs: `reports/prefill-observation/`, including the five
1975
- reports, `comparison.json`, component breakdown and `active-first.patch`.
1976
- Per-arm source hashes, exact payloads, output hashes, timings and machine state
1977
- are retained in the JSON reports. Tracing is off by default and traced benchmark
1978
- runs are classified diagnostic automatically.
1979
-
1980
- ### Mixed prefill and decode token work
1981
-
1982
- M4 Pro 24 GB, 2026-09-12 UTC. Same Gemma 4 12B artifact, Bun/native versions,
1983
- KV4, RAM/SSD cache, default batch capacity eight, prompt counts, output budgets
1984
- and `prefill-long-0` requests as the preceding observation screen. New code is
1985
- based on `71f3463`; raw reports record the exact worktree source hashes. These
1986
- are diagnostic HTTP runs. Retained swap remains recorded in each report rather
1987
- than preventing the comparison.
1988
-
1989
- The scheduler reserves running decode tokens before assigning a bounded prompt
1990
- chunk. Gemma packs feed-forward work across those real tokens; attention retains
1991
- each group's original geometry and KV ownership. The unpacked arm keeps the same
1992
- scheduler budget and disables only feed-forward packing. The larger-cohort
1993
- experiment removes the old total-prompt admission limit while retaining the
1994
- iteration token limit. It was reverted after the comparisons below.
1995
-
1996
- | Arm | B1 decode tok/s | Aggregate tok/s | Workload wall ms | First request TTFT ms | Mean TTFT ms | Largest output gap ms |
1997
- |---|---:|---:|---:|---:|---:|---:|
1998
- | Previous observer-off control | 26.044 | 20.171 | 25,383.24 | 9,022.22 | 15,944.64 | 4,598.66 |
1999
- | Packed, 256-token budget, traced | 26.132 | 20.015 | 25,580.35 | 5,465.48 | 13,155.55 | 1,802.16 |
2000
- | Packed, 512-token budget, traced | 26.052 | 20.014 | 25,582.60 | 6,361.77 | 14,252.33 | 3,642.18 |
2001
- | Unpacked, 256-token budget, traced | 26.340 | 19.471 | 26,295.51 | 5,496.34 | 13,517.57 | 1,889.96 |
2002
- | Larger cohort, 256-token budget, traced, reverted | 26.331 | 19.746 | 25,929.76 | 5,487.48 | 15,499.28 | 955.07 |
2003
- | Larger cohort, 1,024-token budget, traced, reverted | 26.050 | 19.851 | 25,792.54 | 8,094.81 | 15,961.84 | 3,718.52 |
2004
- | Final default control, tracing off | 26.023 | 20.045 | 25,542.09 | 9,030.63 | 16,071.34 | 4,668.02 |
2005
- | Final packed 256-token path, tracing off | 26.047 | 19.378 | 26,421.19 | 5,611.73 | 13,621.31 | 1,882.32 |
2006
- | Final unpacked 256-token control, tracing off | 26.070 | 19.566 | 26,168.35 | 5,461.18 | 13,416.80 | 1,884.87 |
2007
-
2008
- The first packed 256-token screen reduces first-request TTFT by 39.42% and
2009
- mean TTFT by 17.49% relative to the previous observer-off control. Aggregate
2010
- throughput is 0.77% lower. Against the same-budget unpacked control, packing
2011
- improves aggregate throughput by 2.80%. These ordered single samples establish
2012
- a latency/throughput tradeoff, not a universal throughput gain. Enlarging the
2013
- cohort reduces the worst streaming gap at budget 256, but delays later first
2014
- outputs and loses aggregate throughput. The retained Lab path uses the existing
2015
- cohort admission policy.
2016
-
2017
- The final tracing-off pair confirms lower latency with a throughput cost:
2018
- first-request TTFT improves 37.86%, mean TTFT improves 15.24%, and the largest
2019
- output gap falls from 4,668 to 1,882 ms. Aggregate throughput falls 3.33%; workload
2020
- wall time grows 879 ms. B1 decode changes +0.095%. Output-gap p95 rises from
2021
- 56.67 to 111.68 ms because more visible output now interleaves with preparation.
2022
- Peak RSS is 9,868.5 versus 10,009.3 MB. This is not a default promotion.
2023
-
2024
- The final same-source unpacked control reaches 19.566 tok/s, ahead of packed
2025
- execution's 19.378 tok/s by 0.97%. This reverses the earlier traced packing
2026
- screen. Packing has no repeatable throughput win in these HTTP measurements;
2027
- the latency improvement is attributable to the mixed iteration scheduling.
2028
- The interface and packed model implementation remain available for further
2029
- kernel work, with the entire mixed path off by default.
2030
-
2031
- All measured request bodies and prompt/cache/output counts match the control;
2032
- no server request fails. The eleven non-aggregate response texts remain exact.
2033
- All four concurrent response texts change. The new packed matmul and scheduling
2034
- geometries do not promise identical sampled output to the old geometry, even
2035
- with a fixed seed. Streaming gaps above are intervals between semantic SSE
2036
- output events, not GPU token timings.
2037
-
2038
- The packed native oracle passes on M4 for Gemma e4b, 12B and 26B, each with
2039
- bf16 and uniform KV4, B1/B2 work, unequal decode/prefill row counts and subsequent
2040
- cache continuation. It compares full hidden arrays against the pinned Python
2041
- operators with matching packed feed-forward geometry. The uniform-KV comparison
2042
- explicitly pins stock quantized SDPA on both sides. Unit tests cover packing,
2043
- work budgets, cancellation, consumer failure, row retirement, grammar readiness,
2044
- and preparation with immediate/delayed affine and TurboQuant state.
2045
-
2046
- Reproduce the native comparison:
2047
-
2048
- ```sh
2049
- MLX_BUN_TEST_MIXED_MODEL=/path/to/gemma-model \
2050
- bun test tests/parity/mixed-token-model.test.ts
2051
- ```
2052
-
2053
- Reproduce the HTTP screen with the command in the preceding section plus `MLX_BUN_MIXED_PREFILL=1` and
2054
- `MLX_BUN_MIXED_TOKEN_BUDGET=256`; `MLX_BUN_MIXED_PACKED_MLP=0` selects the
2055
- unpacked control. Runtime settings and their scope are documented in
2056
- [server-config](server-config.md). Mixed execution remains off by default.
2057
- Qwen/recurrent work and speculative provider work now use the same mixed port;
2058
- the extension and its timing decision follow below.
2059
-
2060
- Raw reports are `reports/prefill-observation/mixed-*.md.json`; the comparison is
2061
- `mixed-comparison.json` and the reverted admission experiment is
2062
- `mixed-cohort.patch`. Per-arm `*-source.patch` files reproduce every changed
2063
- early source file, verified against its recorded SHA-256. All three final arms
2064
- match the retained source snapshot exactly. The standard benchmark retains
2065
- payloads, usage, output, SSE event times, source hashes and machine state.
2066
-
2067
-
2068
- #### Qwen and speculative-method extension
2069
-
2070
- M4 Pro 24 GB, September 12 UTC, Bun 1.4.2, native pack 0.4.0. The source extends
2071
- mixed execution to Qwen's recurrent graph and grouped speculative methods.
2072
- Methods report pending-plus-candidate token demand and capture their own hidden
2073
- layers. Verification preserves its existing matmul geometry; it does not share
2074
- a packed feed-forward matmul with the prefill group. The ordinary Gemma packing
2075
- control remains unchanged.
2076
-
2077
- The pinned mixed oracle passes all 25 hidden-vector cases on the M4 Qwen3.8-27B
2078
- OptiQ artifact and on M1 Gemma e4b, 12B and 26B. Cases include bf16/KV4,
2079
- unequal row counts, four-position geometry-preserving verification, and cache
2080
- continuation. The packed Qwen model passes M4 MTP mixed-work lifecycle and
2081
- generated-cache checks with both uniform KV4 and TurboQuant K8V3. M1 Gemma
2082
- prompt lookup passes the corresponding lifecycle and generated-cache checks.
2083
- The complete model-free suite passes 2,284 tests, with 14 existing fixture
2084
- skips; focused preparation checks pass after the allocator adjustment, and all
2085
- three TypeScript checks pass.
2086
-
2087
- A scheduler fragment now evaluates state at each yield but clears the allocator
2088
- pool at the method's planned maintenance boundary. A fixed Gemma KV4 comparison
2089
- isolates this change to `src/backends/mlx/prefill-rows.ts`; every request,
2090
- response and usage count matches:
2091
-
2092
- | Allocator clearing | B1 tok/s | Aggregate tok/s | Workload wall ms | First TTFT ms | Peak RSS MB |
2093
- |---|---:|---:|---:|---:|---:|
2094
- | Every fragment | 26.059 | 19.317 | 26,504.68 | 5,660.55 | 10,128.8 |
2095
- | Planned maintenance boundary | 26.268 | 19.350 | 26,459.72 | 5,664.07 | 10,015.4 |
2096
-
2097
- Aggregate throughput changes +0.17%, effectively flat. This does not explain or
2098
- resolve the mixed-work throughput regression. It retains allocator reuse within
2099
- a planned chunk without changing precision/checkpoint boundaries or default
2100
- non-mixed chunking. These are single ordered diagnostic samples, not proof of
2101
- a speed win.
2102
-
2103
- The Qwen setting comparison uses the required packed interleave2 artifact and
2104
- the folded rtn4-g64 MTP drafter from the Kanban profile, MTP depth three,
2105
- TurboQuant K8V3, fused KV decode, a 256-token mixed budget, 4 GiB RAM cache plus
2106
- SSD, and the same `prefill-long-0` workload/default batch capacity as above.
2107
- Both arms have identical source snapshot `7c608346…`, request bodies and token
2108
- counts: aggregate prompts 1,424/1,416/1,422/1,422, no prefix hits, and outputs
2109
- 124/128/128/128. The first response reaches EOS. Twelve of fifteen response texts
2110
- are identical; three concurrent trajectories change.
2111
-
2112
- | Mixed work | B1 tok/s | Aggregate tok/s | Workload wall ms | First TTFT ms | Mean TTFT ms | Largest output gap ms |
2113
- |---|---:|---:|---:|---:|---:|---:|
2114
- | Off | 18.718 | 7.580 | 67,020.77 | 11,014.71 | 28,143.25 | 11,543.87 |
2115
- | On | 18.652 | 6.689 | 75,944.04 | 11,256.18 | 33,472.05 | 2,642.70 |
2116
-
2117
- Aggregate throughput falls 11.75%; first and mean TTFT worsen. The largest
2118
- streaming pause shrinks, while output-gap p95 rises from 542.55 to 2,523.69 ms.
2119
- Peak RSS is 15,146.9/15,187.2 MB. This is a latency/throughput tradeoff with no
2120
- basis for enabling mixed work by default. Gemma's earlier first-output gain
2121
- does not generalize to this MTP workload. Single-stream decode remains
2122
- approximately unchanged because a lone request has no mixed prompt work.
2123
-
2124
- An earlier Qwen arm used the original bf16 MTP drafter instead of the folded
2125
- Kanban drafter: B1 7.090 tok/s, aggregate 4.624 tok/s. It is preserved as a
2126
- separate drafter-setting diagnostic, not an on/off source comparison or a
2127
- regression from the established packed-model profile.
2128
-
2129
- Reproduce the method timing with the earlier HTTP command, replacing the target
2130
- with the packed Qwen artifact, replacing `--kv-quant 4` with `--kv-quant turbo`,
2131
- and adding `--draft-model /path/to/folded-rtn4-mtp --draft-kind mtp
2132
- --num-draft-tokens 3`. Toggle only `MLX_BUN_MIXED_PREFILL=0|1`. Native lifecycle:
2133
-
2134
- ```sh
2135
- MLX_BUN_TEST_MIXED_METHOD=1 MLX_BUN_TEST_MTP_TARGET=/path/to/target \
2136
- MLX_BUN_TEST_MTP_DRAFT=/path/to/mtp MLX_BUN_TEST_MTP_TURBO=1 \
2137
- bun test tests/parity/mixed-method.test.ts
2138
- ```
2139
-
2140
- Omit the drafter for prompt lookup, or omit `MLX_BUN_TEST_MTP_TURBO` for KV4.
2141
- Raw evidence: `reports/prefill-observation/mixed-maintenance-{before,after}.*`,
2142
- `mixed-qwen-folded-{off,on}.*`, `mixed-qwen-mtp-off.*`, native `mixed-*-oracle*.log`
2143
- and `mixed-*-kv4.log`/`mixed-*-tq.log`; `mixed-method-comparison.json` contains the
2144
- combined metrics. No application default is promoted by these results.
2145
-
2146
-
2147
- ### Shared grammar proposal screen
2148
-
2149
- 2026-09-12, Bun 1.4.2, MLX 0.32.2, native v0.4.0; source based on
2150
- `5400554`, source-tree digest
2151
- `4b802e730ba7c0a1e96d86993f86aaf25ef5032690ca042c2b02bfe8da7fdd54`.
2152
- These are diagnostic composition measurements from `bench-matrix features`,
2153
- not the standard h2h. Grammar jump remains **off by default**.
2154
-
2155
- Four concurrent compact product-schema requests use shared cap eight,
2156
- temperature zero and grammar candidate depth three. MiniCPM5-1B OptiQ uses
2157
- bf16 KV; packed Qwen3.8-27B uses TurboQuant K8/V3 without a learned drafter,
2158
- with trellis async expansion off and fused TQ decode on. Qwen explicitly
2159
- uses answer mode. Each arm has a fresh process; all rounds, including the
2160
- first, are retained. M1 has two rounds, M4 three. Aggregate throughput below
2161
- is total completion tokens divided by total round wall time, not best-of.
2162
-
2163
- | Machine / model | Ordinary aggregate tok/s | Grammar proposals tok/s | Change | TTFT p50 ordinary → proposals | TTFT p95 ordinary → proposals | Exact response text |
2164
- |---|---:|---:|---:|---:|---:|---:|
2165
- | M1 Max 32 GB / MiniCPM5-1B | 205.35 | 184.45 | −10.18% | 310 → 362 ms | 339 → 476 ms | 7/8 |
2166
- | M4 Pro 24 GB / MiniCPM5-1B | 285.64 | 312.87 | +9.53% | 181 → 198 ms | 330 → 284 ms | 9/12 |
2167
- | M4 Pro 24 GB / packed Qwen3.8-27B | 15.19 | 13.27 | −12.65% | 4720 → 4107 ms | 5603 → 8585 ms | 8/12 |
2168
-
2169
- Every response conforms to the schema. Accepted proposals are 100% in these
2170
- cells; acceptance alone does not establish a speedup. MiniCPM completion
2171
- counts differ by one token per arm; Qwen retains all 408 completion tokens.
2172
- Qwen's best round rises from 15.67 to 15.87 tok/s, while total elapsed time
2173
- increases from 26.87 to 30.76 seconds. That is a throughput loss for the full
2174
- measurement. The mixed results do not support a default change.
2175
-
2176
- An additional M4 MiniCPM direct serial-jump control reaches 403.75 tok/s in
2177
- its best round; shared verified proposals in the same process reach 356.70.
2178
- That control has different algorithm and warmup ordering, so it does not
2179
- establish shared dominance over direct jump. The fresh-process shared-only
2180
- arm above is the ordinary/proposal comparison. An initial Qwen run without
2181
- explicit answer mode fails the answer-content JSON check; it is retained
2182
- as a benchmark-configuration failure and excluded from timing comparisons.
2183
-
2184
- Native checks pass on M1 MiniCPM bf16/affine4 and M4 packed-Qwen/TurboQuant:
2185
- nonmutating proposals, concurrent schemas, B1, early stop, cancellation and
2186
- logprob delivery. Fixed bf16 MiniCPM outputs match ordinary decoding; affine
2187
- KV can change valid tokenization across verification widths. Repeated fixed
2188
- quantized configurations match. Existing same-geometry verifier/KV oracles
2189
- remain the numerical contract. The model-free suite passes 2,286 tests with
2190
- 14 fixture skips; all three TypeScript projects pass.
2191
-
2192
- Reproduce an arm with `MLX_BUN_GRAMMAR_JUMP=0` or `1` and:
2193
-
2194
- ```sh
2195
- bun scripts/bench-matrix.ts features --model "$MODEL" --batch 8 \
2196
- --concurrency 4 --maxtok 192 --repeats 3 --cells batch+grammar \
2197
- --compact-grammar true --kv-quant turbo --out reports/grammar.md
2198
- ```
2199
-
2200
- Omit `--kv-quant turbo` and use `--maxtok 160` for the MiniCPM cells. The
2201
- script pins answer mode, writes all response texts/usage/timings to JSON,
2202
- and saves each completed round before schema validation. Its named serial
2203
- controls now explicitly request cap one, keeping their labels accurate after
2204
- the default changed. Raw evidence and summary:
2205
- `reports/prefill-observation/grammar-*`, including `grammar-comparison.json`.
2206
-
2207
- #### Zero-candidate rollback snapshots
2208
-
2209
- A shared verification step with no proposed tokens consumes only its pending
2210
- input. It now keeps transaction ordering without retaining rollback snapshots.
2211
- No proposed suffix exists to reject. Nonzero rounds and the explicit serial
2212
- transaction retain their existing behavior.
2213
-
2214
- M1 Gemma12 affine4 across the real sliding window and M4 packed-Qwen/TurboQuant
2215
- compare the previous explicit snapshot/commit against the new operation at
2216
- identical B/S. Hidden values, every layer's state and the next continuation
2217
- match exactly. The checks have 7,690 and 6,090 assertions respectively.
2218
- MiniCPM grammar retirement/logprob checks and the model-free suite pass
2219
- (2,287 tests, 14 skips), along with all three typechecks.
2220
-
2221
- M4 grammar throughput initially rises from 13.27 to 14.62 tok/s over all
2222
- three rounds. Repeating the previous snapshot behavior yields 14.39 tok/s,
2223
- with all 12 responses matching the candidate. The last two rounds are only
2224
- 0.14% apart; most of the apparent initial gain is first-round variation.
2225
- No substantial speedup is claimed.
2226
-
2227
- The standard script then compares source-only changes with packed Qwen,
2228
- TurboQuant K8/V3, prompt lookup depth three, a 4 GiB RAM cache plus SSD,
2229
- 192-token decode and staggered long-input concurrency four. Both arms retain
2230
- default capacity eight, use diagnostic mode and skip the separate context sweep.
2231
- Both source snapshots remain unchanged during measurement; the sole numerical
2232
- source change is `src/backends/mlx/rollback.ts` relative to `ae04888`.
2233
-
2234
- | M4 Pro 24 GB metric | Previous snapshots | Zero-candidate snapshots removed |
2235
- |---|---:|---:|
2236
- | Median single-request decode | 11.523 tok/s | 11.484 tok/s |
2237
- | Aggregate throughput | 6.149 tok/s | 6.134 tok/s |
2238
- | Median cold TTFT | 5860 ms | 5934 ms |
2239
- | Warm TTFT / cached tokens | 125.86 ms / 758 | 126.13 ms / 758 |
2240
- | Peak RSS | 15060.5 MB | 15111.5 MB |
2241
-
2242
- All 15 requests, response texts and prompt/generated/cached token counts match;
2243
- there are no failed phases. Throughput is effectively flat (−0.33% decode,
2244
- −0.25% aggregate). This removes unnecessary snapshot work without establishing
2245
- a serving speed or memory reduction. Source snapshots are
2246
- `a2ef51986ac3646ed7d7c2d646960bd93f7bbb2b769b7d41e27f877c152590b1` and
2247
- `70507562e4e043f8e03f83c2d2e0ce3b3021c8a356dd9023f1d8cca50a468af7`.
2248
- Raw reports: `reports/prefill-observation/zero-snapshot-*` and
2249
- `grammar-qwen-snapshot-control.md.json`.
2250
-
2251
- ### Bound kernel configuration
2252
-
2253
- The kernel-policy cleanup uses the same M4 Pro 24 GB standard-script settings
2254
- as the preceding prompt-lookup comparison. TurboQuant caches retain their
2255
- fused-decoder policy through RAM copies, row extraction and delayed conversion;
2256
- model and method code use the captured runtime configuration.
2257
-
2258
- | Metric | Before | Bound policy |
2259
- |---|---:|---:|
2260
- | Median single-request decode | 11.484 tok/s | 11.509 tok/s |
2261
- | Aggregate throughput | 6.134 tok/s | 6.131 tok/s |
2262
- | Median cold TTFT | 5934 ms | 5921 ms |
2263
- | Warm TTFT / cached tokens | 126.13 ms / 758 | 126.12 ms / 758 |
2264
- | Peak RSS | 15111.5 MB | 15097.2 MB |
2265
-
2266
- All 15 request hashes, response texts and prompt/generated/cached token counts
2267
- match, with no failed phases. Performance is effectively unchanged. This is
2268
- configuration isolation with a regression comparison, not a speedup claim.
2269
- Both source snapshots are stable throughout their runs. The baseline snapshot
2270
- is `70507562e4e043f8e03f83c2d2e0ce3b3021c8a356dd9023f1d8cca50a468af7`;
2271
- the candidate is `79006c024cdebb18a60ba3b22b2b96289c975dacc9f0a72b6592c9872da20bd4`
2272
- on `ba78658` plus the configuration patch. Both use diagnostic mode. Raw reports
2273
- are `reports/prefill-observation/zero-snapshot-lookup-after.md.json` and
2274
- `config-policy-lookup.md.json`. Focused policy/codec checks pass on both Macs;
2275
- the local model-free suite has 2,289 passes and 14 fixture skips. All three
2276
- TypeScript projects and documentation gates pass.
2277
-
2278
- ### Fused normalized greedy selection
2279
-
2280
- September 12, 2026. The sampler retains native logsumexp, then selects the
2281
- lowest token ID with the largest dtype-rounded normalized score in two tiled
2282
- Metal reductions. It avoids writing the full normalized vocabulary array.
2283
- Fixed-shape compilation caches the operation by input geometry. The same
2284
- operation serves independent verification and ordinary greedy sampling after
2285
- penalties and grammar masks. Metadata, stochastic and custom samplers keep
2286
- their existing operations.
2287
-
2288
- At B16/V262144, the avoided normalized output is 8 MiB in bf16 or 16 MiB in
2289
- f32; partial score/index storage is 32 KiB. These are operation buffer sizes,
2290
- not a claim about total process memory. Native logsumexp still owns its work.
2291
-
2292
- The operation screen evaluates completed GPU work, with five warmups and 100
2293
- calls per arm in each of four alternating blocks. Median per-call times:
2294
-
2295
- | Machine / dtype | Rows | Native composition | Fused selection |
2296
- |---|---:|---:|---:|
2297
- | M1 Max 32 GB / bf16 | 1 | 528.3 µs | 369.7 µs |
2298
- | M1 Max 32 GB / bf16 | 4 | 578.5 µs | 410.4 µs |
2299
- | M1 Max 32 GB / bf16 | 16 | 621.8 µs | 469.4 µs |
2300
- | M4 Pro 24 GB / bf16 | 1 | 180.9 µs | 144.8 µs |
2301
- | M4 Pro 24 GB / bf16 | 4 | 199.3 µs | 134.0 µs |
2302
- | M4 Pro 24 GB / bf16 | 16 | 217.5 µs | 180.1 µs |
2303
-
2304
- F32 cells also improve, but the first M4 cell drifts across blocks and is not
2305
- used for a headline gain. Compiling the original composition alone is flat on
2306
- the M1 screen and is not adopted. A post-integration M4 probe accidentally
2307
- compared the fused sampler to itself; `sampler-kernel-compiled-m4.json` is
2308
- excluded. The corrected final probes explicitly construct the native reference.
2309
-
2310
- The standard HTTP script runs two pairs in A/B then B/A order. Both retain
2311
- default batch capacity eight, the same `prefill-long-0` requests, 192-token
2312
- single-request samples and four aggregate requests staggered 25 ms apart at
2313
- requested context 2048; the separate context sweep is skipped. All reports
2314
- use diagnostic mode, Bun 1.4.2 and MLX 0.32.2/native pack 0.4.0.
2315
- M1 uses MiniCPM5-1B OptiQ with bf16 KV. M4 uses packed Qwen3.8-27B interleave2,
2316
- folded RTN4 MTP depth three, TurboQuant K8/V3 with fused decoding enabled,
2317
- a 4 GiB RAM cache and temporary SSD storage.
2318
-
2319
- | Machine / model / pair | B1 decode before → after | Aggregate before → after | Exact responses |
2320
- |---|---:|---:|---:|
2321
- | M1 / MiniCPM / A-B | 266.400 → 268.575 tok/s | 185.728 → 191.851 tok/s | 13/15 |
2322
- | M1 / MiniCPM / B-A | 266.238 → 270.443 tok/s | 183.612 → 189.496 tok/s | 15/15 |
2323
- | M4 / Qwen MTP3 / A-B | 18.715 → 18.682 tok/s | 7.688 → 7.601 tok/s | 15/15 |
2324
- | M4 / Qwen MTP3 / B-A | 18.734 → 18.727 tok/s | 7.550 → 7.574 tok/s | 15/15 |
2325
-
2326
- MiniCPM improves about 1.2% in B1 decode and 3.3% in aggregate across the two
2327
- pairs. Two concurrent responses change in its first pair; all single-request
2328
- responses, every request hash and all prompt/generated/cached counts match.
2329
- The reverse pair is exact. Same-input native MiniCPM and packed-Qwen tests
2330
- compare the new and old selection on actual model logits at B1/B4 and match
2331
- every token. Changed concurrent text is not treated as a same-output speed claim.
2332
- Qwen is effectively flat, about −0.1% B1 and −0.4% aggregate across pairs,
2333
- with every response and token count exact. No Qwen serving speedup or process
2334
- memory saving is claimed. This retains a measured sampler improvement and a
2335
- smaller-model serving gain; it changes no sampling distribution or user setting.
2336
-
2337
- Both-machine tests cover fp16/bf16/f32, nonfinite rows, rounding-created ties,
2338
- partial tiles, noncontiguous vocabulary axes, changing row shapes and shapeless
2339
- enclosing graphs. Actual-model selection and grammar/cancellation/logprob checks
2340
- pass on both machines. The full local model-free suite has 2,294 passes and
2341
- 14 fixture skips; all three typechecks pass.
2342
-
2343
- Source is `059de1c` plus the sampler changes. Baseline snapshots include an
2344
- unreferenced prototype module; their active sampler is unchanged. Each report's
2345
- source snapshot is stable during measurement. Raw evidence lives under
2346
- `reports/prefill-observation/`: `sampler-kernel-final-{m1,m4}.json`,
2347
- `sampler-minicpm-before{,-repeat}.md.json`, `sampler-minicpm-after-v2.md.json`,
2348
- `sampler-minicpm-after-repeat.md.json`, and `sampler-mtp-{before,after}{,-repeat}.md.json`.
2349
- The earlier independent-only MiniCPM screen preserves every response but shows
2350
- no aggregate gain; ordinary greedy integration is included in the final pairs.
2351
-
2352
- ## Historical results and section links
2353
-
2354
- Earlier measurements retain their original conditions and conclusions in the
2355
- frozen ledger. These links preserve previous section URLs.
2356
-
2357
- <a id="rotating-target-speculation-through-shared-execution"></a>
2358
- - [Rotating target speculation through shared execution](../archive/investigations/benchmark-ledger-through-v0.4.0.md#rotating-target-speculation-through-shared-execution)
2359
-
2360
- <a id="full-attention-speculation-through-shared-execution"></a>
2361
- - [Full-attention speculation through shared execution](../archive/investigations/benchmark-ledger-through-v0.4.0.md#full-attention-speculation-through-shared-execution)
2362
-
2363
- <a id="standalone-drafting-first-shared-executor-comparison"></a>
2364
- - [Standalone drafting: first shared-executor comparison](../archive/investigations/benchmark-ledger-through-v0.4.0.md#standalone-drafting-first-shared-executor-comparison)
2365
-
2366
- <a id="current-serial-versus-shared-execution-staggered-gemma-requests"></a>
2367
- - [Current serial versus shared execution: staggered Gemma requests](../archive/investigations/benchmark-ledger-through-v0.4.0.md#current-serial-versus-shared-execution-staggered-gemma-requests)
2368
-
2369
- <a id="delayed-full-attention-padding-m4-comparison"></a>
2370
- - [Delayed full-attention padding: M4 comparison](../archive/investigations/benchmark-ledger-through-v0.4.0.md#delayed-full-attention-padding-m4-comparison)
2371
-
2372
- <a id="shared-mtp-prefill-m4-comparison-and-scheduling-attribution"></a>
2373
- - [Shared MTP prefill: M4 comparison and scheduling attribution](../archive/investigations/benchmark-ledger-through-v0.4.0.md#shared-mtp-prefill-m4-comparison-and-scheduling-attribution)
2374
-
2375
- <a id="delayed-affine-row-composition-fixed-settings-m4-regression"></a>
2376
- - [Delayed affine row composition: fixed-settings M4 regression](../archive/investigations/benchmark-ledger-through-v0.4.0.md#delayed-affine-row-composition-fixed-settings-m4-regression)
2377
-
2378
- <a id="captured-attention-views-m4-regression"></a>
2379
- - [Captured attention views: M4 regression](../archive/investigations/benchmark-ledger-through-v0.4.0.md#captured-attention-views-m4-regression)
2380
-
2381
- <a id="delayed-rotating-affine-composition-m4-regression"></a>
2382
- - [Delayed rotating affine composition: M4 regression](../archive/investigations/benchmark-ledger-through-v0.4.0.md#delayed-rotating-affine-composition-m4-regression)
2383
-
2384
- <a id="singleton-admission-attribution-on-m4-pro"></a>
2385
- - [Singleton admission attribution on M4 Pro](../archive/investigations/benchmark-ledger-through-v0.4.0.md#singleton-admission-attribution-on-m4-pro)
2386
-
2387
- <a id="recurrent-row-retention-diagnostic-on-m1-max"></a>
2388
- - [Recurrent row retention diagnostic on M1 Max](../archive/investigations/benchmark-ledger-through-v0.4.0.md#recurrent-row-retention-diagnostic-on-m1-max)
2389
-
2390
- <a id="batched-prefill-cohorts-m4-regression-before-projection-correction"></a>
2391
- - [Batched prefill cohorts: M4 regression before projection correction](../archive/investigations/benchmark-ledger-through-v0.4.0.md#batched-prefill-cohorts-m4-regression-before-projection-correction)
2392
-
2393
- <a id="batched-prefill-cohorts-corrected-m4-comparison"></a>
2394
- - [Batched prefill cohorts: corrected M4 comparison](../archive/investigations/benchmark-ledger-through-v0.4.0.md#batched-prefill-cohorts-corrected-m4-comparison)
2395
-
2396
- <a id="staggered-long-prefill-m4-regression"></a>
2397
- - [Staggered long prefill: M4 regression](../archive/investigations/benchmark-ledger-through-v0.4.0.md#staggered-long-prefill-m4-regression)
2398
-
2399
- <a id="prefill-admission-work-budget-m4-comparison"></a>
2400
- - [Prefill admission work budget: M4 comparison](../archive/investigations/benchmark-ledger-through-v0.4.0.md#prefill-admission-work-budget-m4-comparison)
2401
-
2402
- <a id="prefill-early-release-lifetime-screen-no-measured-win"></a>
2403
- - [Prefill early-release lifetime screen: no measured win](../archive/investigations/benchmark-ledger-through-v0.4.0.md#prefill-early-release-lifetime-screen-no-measured-win)
2404
-
2405
- <a id="mtp-preparation-port-and-compiled-activation-m4-comparison"></a>
2406
- - [MTP preparation port and compiled activation: M4 comparison](../archive/investigations/benchmark-ledger-through-v0.4.0.md#mtp-preparation-port-and-compiled-activation-m4-comparison)
2407
-
2408
- <a id="delayed-rotating-prefill-m4-regression"></a>
2409
- - [Delayed rotating prefill: M4 regression](../archive/investigations/benchmark-ledger-through-v0.4.0.md#delayed-rotating-prefill-m4-regression)
2410
-
2411
- <a id="recurrent-padded-prefill-m4-regression"></a>
2412
- - [Recurrent padded prefill: M4 regression](../archive/investigations/benchmark-ledger-through-v0.4.0.md#recurrent-padded-prefill-m4-regression)
2413
-
2414
- <a id="packed-qwen-serial-closeout-on-m4-pro"></a>
2415
- - [Packed Qwen serial closeout on M4 Pro](../archive/investigations/benchmark-ledger-through-v0.4.0.md#packed-qwen-serial-closeout-on-m4-pro)
2416
-
2417
- <a id="glm-52-direct-colibri-oracle-closure--m1-max-32-gb"></a>
2418
- - [GLM-5.2 direct-Colibri oracle closure — M1 Max 32 GB](../archive/investigations/benchmark-ledger-through-v0.4.0.md#glm-52-direct-colibri-oracle-closure--m1-max-32-gb)
2419
-
2420
- <a id="methodology-change-2026-07-05"></a>
2421
- - [Methodology change (2026-07-05)](../archive/investigations/benchmark-ledger-through-v0.4.0.md#methodology-change-2026-07-05)
2422
-
2423
- <a id="standard-serve-matrix--m4-pro-24-gb-2026-09-08-incomplete-acceptance"></a>
2424
- - [Standard serve matrix — M4 Pro 24 GB (2026-09-08, incomplete acceptance)](../archive/investigations/benchmark-ledger-through-v0.4.0.md#standard-serve-matrix--m4-pro-24-gb-2026-09-08-incomplete-acceptance)
2425
-
2426
- <a id="fresh-kanban-candidate-generation--m4-pro-2026-09-09"></a>
2427
- - [Fresh Kanban candidate generation — M4 Pro (2026-09-09)](../archive/investigations/benchmark-ledger-through-v0.4.0.md#fresh-kanban-candidate-generation--m4-pro-2026-09-09)
2428
-
2429
- <a id="direct-scheduler-b1-versus-serial--both-machines-2026-09-08"></a>
2430
- - [Direct scheduler B=1 versus serial — both machines (2026-09-08)](../archive/investigations/benchmark-ledger-through-v0.4.0.md#direct-scheduler-b1-versus-serial--both-machines-2026-09-08)
2431
-
2432
- <a id="batched-logprob-composition--m4-pro-acceptance-open-2026-09-09"></a>
2433
- - [Batched logprob composition — M4 Pro, acceptance open (2026-09-09)](../archive/investigations/benchmark-ledger-through-v0.4.0.md#batched-logprob-composition--m4-pro-acceptance-open-2026-09-09)
2434
-
2435
- <a id="shared-uniform-kv4-composition--m4-pro-acceptance-open-2026-09-09"></a>
2436
- - [Shared uniform KV4 composition — M4 Pro, acceptance open (2026-09-09)](../archive/investigations/benchmark-ledger-through-v0.4.0.md#shared-uniform-kv4-composition--m4-pro-acceptance-open-2026-09-09)
2437
-
2438
- <a id="immutable-ram-prefix-prototype--m4-pro-2026-09-09"></a>
2439
- - [Immutable RAM prefix prototype — M4 Pro (2026-09-09)](../archive/investigations/benchmark-ledger-through-v0.4.0.md#immutable-ram-prefix-prototype--m4-pro-2026-09-09)
2440
-
2441
- <a id="eventual-ssd-persistence--m4-pro-acceptance-open-2026-09-09"></a>
2442
- - [Eventual SSD persistence — M4 Pro, acceptance open (2026-09-09)](../archive/investigations/benchmark-ledger-through-v0.4.0.md#eventual-ssd-persistence--m4-pro-acceptance-open-2026-09-09)
2443
-
2444
- <a id="idle-persistence-queue-on-bun-142--m4-pro-2026-09-09"></a>
2445
- - [Idle persistence queue on Bun 1.4.2 — M4 Pro (2026-09-09)](../archive/investigations/benchmark-ledger-through-v0.4.0.md#idle-persistence-queue-on-bun-142--m4-pro-2026-09-09)
2446
-
2447
- <a id="first-admission-device-pipeline--m4-pro-2026-09-09"></a>
2448
- - [First-admission device pipeline — M4 Pro (2026-09-09)](../archive/investigations/benchmark-ledger-through-v0.4.0.md#first-admission-device-pipeline--m4-pro-2026-09-09)
2449
-
2450
- <a id="batched-sliding-window-correctness--m1-max-and-m4-pro-2026-09-09"></a>
2451
- - [Batched sliding-window correctness — M1 Max and M4 Pro (2026-09-09)](../archive/investigations/benchmark-ledger-through-v0.4.0.md#batched-sliding-window-correctness--m1-max-and-m4-pro-2026-09-09)
2452
-
2453
- <a id="compatible-adapter-groups--m4-pro-2026-09-09"></a>
2454
- - [Compatible adapter groups — M4 Pro (2026-09-09)](../archive/investigations/benchmark-ledger-through-v0.4.0.md#compatible-adapter-groups--m4-pro-2026-09-09)
2455
-
2456
- <a id="state-only-recurrent-replay-experiment--m4-pro-2026-09-09"></a>
2457
- - [State-only recurrent replay experiment — M4 Pro (2026-09-09)](../archive/investigations/benchmark-ledger-through-v0.4.0.md#state-only-recurrent-replay-experiment--m4-pro-2026-09-09)
2458
-
2459
- <a id="shared-mtp-drafting-candidate--m4-pro-2026-09-09"></a>
2460
- - [Shared MTP drafting candidate — M4 Pro (2026-09-09)](../archive/investigations/benchmark-ledger-through-v0.4.0.md#shared-mtp-drafting-candidate--m4-pro-2026-09-09)
2461
-
2462
- <a id="concurrent-mtp-serving-candidate--m4-pro-2026-09-09"></a>
2463
- - [Concurrent MTP serving candidate — M4 Pro (2026-09-09)](../archive/investigations/benchmark-ledger-through-v0.4.0.md#concurrent-mtp-serving-candidate--m4-pro-2026-09-09)
2464
-
2465
- <a id="integrated-settings-screen-and-context-repeat--m4-pro-2026-09-09"></a>
2466
- - [Integrated settings screen and context repeat — M4 Pro (2026-09-09)](../archive/investigations/benchmark-ledger-through-v0.4.0.md#integrated-settings-screen-and-context-repeat--m4-pro-2026-09-09)
2467
-
2468
- <a id="current-mtp-depth-two-versus-four--m4-pro-2026-09-09"></a>
2469
- - [Current MTP depth two versus four — M4 Pro (2026-09-09)](../archive/investigations/benchmark-ledger-through-v0.4.0.md#current-mtp-depth-two-versus-four--m4-pro-2026-09-09)
2470
-
2471
- <a id="current-standard-serve-matrix--m1-max-32-gb-2026-08-22"></a>
2472
- - [Current standard serve matrix — M1 Max 32 GB (2026-08-22)](../archive/investigations/benchmark-ledger-through-v0.4.0.md#current-standard-serve-matrix--m1-max-32-gb-2026-08-22)
2473
-
2474
- <a id="bun-140-repeat"></a>
2475
- - [Bun 1.4.0 repeat](../archive/investigations/benchmark-ledger-through-v0.4.0.md#bun-140-repeat)
2476
-
2477
- <a id="colibri-g1g3-component-matrix--m1-max-32-gb"></a>
2478
- - [Colibri G1/G3 component matrix — M1 Max 32 GB](../archive/investigations/benchmark-ledger-through-v0.4.0.md#colibri-g1g3-component-matrix--m1-max-32-gb)
2479
-
2480
- <a id="colibri-g4-serial-native-mtp--m1-max-32-gb"></a>
2481
- - [Colibri G4 serial native MTP — M1 Max 32 GB](../archive/investigations/benchmark-ledger-through-v0.4.0.md#colibri-g4-serial-native-mtp--m1-max-32-gb)
2482
-
2483
- <a id="colibri-g5g7-full-model-productization--m1-max-32-gb"></a>
2484
- - [Colibri G5–G7 full-model productization — M1 Max 32 GB](../archive/investigations/benchmark-ledger-through-v0.4.0.md#colibri-g5g7-full-model-productization--m1-max-32-gb)
2485
-
2486
- <a id="resource-contract"></a>
2487
- - [Resource contract](../archive/investigations/benchmark-ledger-through-v0.4.0.md#resource-contract)
2488
-
2489
- <a id="coldwarm-mtp-and-memory"></a>
2490
- - [Cold/warm MTP and memory](../archive/investigations/benchmark-ledger-through-v0.4.0.md#coldwarm-mtp-and-memory)
2491
-
2492
- <a id="expert-delivery-and-policy-decisions"></a>
2493
- - [Expert delivery and policy decisions](../archive/investigations/benchmark-ledger-through-v0.4.0.md#expert-delivery-and-policy-decisions)
2494
-
2495
- <a id="dsa-and-served-api"></a>
2496
- - [DSA and served API](../archive/investigations/benchmark-ledger-through-v0.4.0.md#dsa-and-served-api)
2497
-
2498
- <a id="served-warm--the-path-agents-actually-use"></a>
2499
- - [Served (warm) — the path agents actually use](../archive/investigations/benchmark-ledger-through-v0.4.0.md#served-warm--the-path-agents-actually-use)
2500
-
2501
- <a id="served-h2h-post-consolidation-2026-08-22-e4b-single-pass--directional"></a>
2502
- - [Served h2h post-consolidation (2026-08-22, e4b, single pass — directional)](../archive/investigations/benchmark-ledger-through-v0.4.0.md#served-h2h-post-consolidation-2026-08-22-e4b-single-pass--directional)
2503
-
2504
- <a id="direct-engine-only"></a>
2505
- - [Direct (engine only)](../archive/investigations/benchmark-ledger-through-v0.4.0.md#direct-engine-only)
2506
-
2507
- <a id="logprob-metadata-readback-2026-07-29"></a>
2508
- - [Logprob metadata readback (2026-07-29)](../archive/investigations/benchmark-ledger-through-v0.4.0.md#logprob-metadata-readback-2026-07-29)
2509
-
2510
- <a id="long-context-gemma-4-12b--where-the-gap-opens"></a>
2511
- - [Long context (gemma-4-12B) — where the gap opens](../archive/investigations/benchmark-ledger-through-v0.4.0.md#long-context-gemma-4-12b--where-the-gap-opens)
2512
-
2513
- <a id="attempted-but-failed-2026-06-14"></a>
2514
- - [Attempted but failed (2026-06-14)](../archive/investigations/benchmark-ledger-through-v0.4.0.md#attempted-but-failed-2026-06-14)
2515
-
2516
- <a id="3-quality--for-non-bit-exact-lab-optimizations-only"></a>
2517
- - [3. Quality — for non-bit-exact (Lab) optimizations only](../archive/investigations/benchmark-ledger-through-v0.4.0.md#3-quality--for-non-bit-exact-lab-optimizations-only)
2518
-
2519
- <a id="turboquant-kv-quality-vs-bpw-2026-07-06-m1-max-32-gb-minicpm5-1b"></a>
2520
- - [TurboQuant KV quality-vs-bpw (2026-07-06, M1 Max 32 GB, MiniCPM5-1B)](../archive/investigations/benchmark-ledger-through-v0.4.0.md#turboquant-kv-quality-vs-bpw-2026-07-06-m1-max-32-gb-minicpm5-1b)
2521
-
2522
- <a id="4-composition--feature-default-decisions-measured-per-pair"></a>
2523
- - [4. Composition — feature-default decisions (measured, per pair)](../archive/investigations/benchmark-ledger-through-v0.4.0.md#4-composition--feature-default-decisions-measured-per-pair)
2524
-
2525
- <a id="packed-trellis-with-kv4mtp-and-paired-prefixes-m4-pro-2026-09-08"></a>
2526
- - [Packed Trellis with KV4/MTP and paired prefixes, M4 Pro, 2026-09-08](../archive/investigations/benchmark-ledger-through-v0.4.0.md#packed-trellis-with-kv4mtp-and-paired-prefixes-m4-pro-2026-09-08)
2527
-
2528
- <a id="original-and-optimized-serving-diagnostics-m4-pro-2026-09-07"></a>
2529
- - [Original and optimized serving diagnostics, M4 Pro, 2026-09-07](../archive/investigations/benchmark-ledger-through-v0.4.0.md#original-and-optimized-serving-diagnostics-m4-pro-2026-09-07)
2530
-
2531
- <a id="fresh-pi-kanban-diagnostic-m4-pro-2026-09-07"></a>
2532
- - [Fresh Pi kanban diagnostic, M4 Pro, 2026-09-07](../archive/investigations/benchmark-ledger-through-v0.4.0.md#fresh-pi-kanban-diagnostic-m4-pro-2026-09-07)
2533
-
2534
- <a id="kanban-capacity-diagnosis-m4-pro-2026-09-08"></a>
2535
- - [Kanban capacity diagnosis, M4 Pro, 2026-09-08](../archive/investigations/benchmark-ledger-through-v0.4.0.md#kanban-capacity-diagnosis-m4-pro-2026-09-08)
2536
-
2537
- <a id="fresh-pi-kanban-after-mtp-ownership-fixes-m4-pro-2026-09-08"></a>
2538
- - [Fresh Pi Kanban after MTP ownership fixes, M4 Pro, 2026-09-08](../archive/investigations/benchmark-ledger-through-v0.4.0.md#fresh-pi-kanban-after-mtp-ownership-fixes-m4-pro-2026-09-08)
2539
-
2540
- <a id="sustained-kanban-decode-allocation-diagnosis-m4-pro-2026-09-08"></a>
2541
- - [Sustained Kanban decode allocation diagnosis, M4 Pro, 2026-09-08](../archive/investigations/benchmark-ledger-through-v0.4.0.md#sustained-kanban-decode-allocation-diagnosis-m4-pro-2026-09-08)
2542
-
2543
- <a id="completed-fresh-pi-kanban-with-bounded-range-cache-m4-pro-2026-09-08"></a>
2544
- - [Completed fresh Pi Kanban with bounded range cache, M4 Pro, 2026-09-08](../archive/investigations/benchmark-ledger-through-v0.4.0.md#completed-fresh-pi-kanban-with-bounded-range-cache-m4-pro-2026-09-08)
2545
-
2546
- <a id="speculative-decoding--should-spec-be-on-decision-pending-phase-01-runs"></a>
2547
- - [Speculative decoding — "should spec be on?" (decision pending Phase 0/1 runs)](../archive/investigations/benchmark-ledger-through-v0.4.0.md#speculative-decoding--should-spec-be-on-decision-pending-phase-01-runs)
2548
-
2549
- <a id="turboquant-kv--decided-off-2026-07-06-re-affirmed-post-leak-fix"></a>
2550
- - [TurboQuant KV — decided OFF (2026-07-06, re-affirmed post-leak-fix)](../archive/investigations/benchmark-ledger-through-v0.4.0.md#turboquant-kv--decided-off-2026-07-06-re-affirmed-post-leak-fix)
2551
-
2552
- <a id="shared-gemma-assistant-drafting-m4-pro-24-gb-2026-09-10"></a>
2553
- - [Shared Gemma assistant drafting, M4 Pro 24 GB, 2026-09-10](../archive/investigations/benchmark-ledger-through-v0.4.0.md#shared-gemma-assistant-drafting-m4-pro-24-gb-2026-09-10)
2554
-
2555
- <a id="shared-deepspec-drafting-m4-pro-24-gb-2026-09-10"></a>
2556
- - [Shared DeepSpec drafting, M4 Pro 24 GB, 2026-09-10](../archive/investigations/benchmark-ledger-through-v0.4.0.md#shared-deepspec-drafting-m4-pro-24-gb-2026-09-10)
2557
-
2558
- <a id="shared-projected-context-extraction-m4-pro-24-gb-2026-09-10"></a>
2559
- - [Shared projected-context extraction, M4 Pro 24 GB, 2026-09-10](../archive/investigations/benchmark-ledger-through-v0.4.0.md#shared-projected-context-extraction-m4-pro-24-gb-2026-09-10)
2560
-
2561
- <a id="reused-artifact-identity-m4-pro-24-gb-2026-09-10"></a>
2562
- - [Reused artifact identity, M4 Pro 24 GB, 2026-09-10](../archive/investigations/benchmark-ledger-through-v0.4.0.md#reused-artifact-identity-m4-pro-24-gb-2026-09-10)
2563
-
2564
- <a id="affine-rotating-speculation-m4-pro-24-gb-2026-09-11"></a>
2565
- - [Affine rotating speculation, M4 Pro 24 GB, 2026-09-11](../archive/investigations/benchmark-ledger-through-v0.4.0.md#affine-rotating-speculation-m4-pro-24-gb-2026-09-11)
2566
-
2567
- <a id="turboquant-provider-composition-and-centroid-correction-m4-pro-24-gb-2026-09-11"></a>
2568
- - [TurboQuant provider composition and centroid correction, M4 Pro 24 GB, 2026-09-11](../archive/investigations/benchmark-ledger-through-v0.4.0.md#turboquant-provider-composition-and-centroid-correction-m4-pro-24-gb-2026-09-11)
2569
-
2570
- <a id="gemma4-12b--trained-deepspec"></a>
2571
- - [Gemma4 12B + trained DeepSpec](../archive/investigations/benchmark-ledger-through-v0.4.0.md#gemma4-12b--trained-deepspec)
2572
-
2573
- <a id="gemma4-e4b--assistant"></a>
2574
- - [Gemma4 e4b + assistant](../archive/investigations/benchmark-ledger-through-v0.4.0.md#gemma4-e4b--assistant)
2575
-
2576
- <a id="turboquant-option-capture-attribution-m4-pro-2026-09-11"></a>
2577
- - [TurboQuant option-capture attribution (M4 Pro, 2026-09-11)](../archive/investigations/benchmark-ledger-through-v0.4.0.md#turboquant-option-capture-attribution-m4-pro-2026-09-11)
2578
-
2579
- <a id="delayedper-layer-affine-rotating-speculation-m4-pro-2026-09-11"></a>
2580
- - [Delayed/per-layer affine rotating speculation (M4 Pro, 2026-09-11)](../archive/investigations/benchmark-ledger-through-v0.4.0.md#delayedper-layer-affine-rotating-speculation-m4-pro-2026-09-11)
2581
-
2582
- <a id="paged-storage-in-the-shared-executor-m4-pro-2026-09-11"></a>
2583
- - [Paged storage in the shared executor (M4 Pro, 2026-09-11)](../archive/investigations/benchmark-ledger-through-v0.4.0.md#paged-storage-in-the-shared-executor-m4-pro-2026-09-11)
2584
-
2585
- <a id="adapter-qualified-prompt-lookup-m4-pro-2026-09-11"></a>
2586
- - [Adapter-qualified prompt lookup (M4 Pro, 2026-09-11)](../archive/investigations/benchmark-ledger-through-v0.4.0.md#adapter-qualified-prompt-lookup-m4-pro-2026-09-11)
2587
-
2588
- <a id="ngram-match-length-screen-with-the-upper-adapter-m4-pro-2026-09-11"></a>
2589
- - [Ngram match-length screen with the upper adapter (M4 Pro, 2026-09-11)](../archive/investigations/benchmark-ledger-through-v0.4.0.md#ngram-match-length-screen-with-the-upper-adapter-m4-pro-2026-09-11)
2590
-
2591
- <a id="independent-greedy-sampling-across-verification-positions-m4-pro-2026-09-11"></a>
2592
- - [Independent greedy sampling across verification positions (M4 Pro, 2026-09-11)](../archive/investigations/benchmark-ledger-through-v0.4.0.md#independent-greedy-sampling-across-verification-positions-m4-pro-2026-09-11)
2593
-
2594
- <a id="shared-ordinary-checkpoints-and-queued-persistence-m4-pro-2026-09-11"></a>
2595
- - [Shared ordinary checkpoints and queued persistence (M4 Pro, 2026-09-11)](../archive/investigations/benchmark-ledger-through-v0.4.0.md#shared-ordinary-checkpoints-and-queued-persistence-m4-pro-2026-09-11)
2596
-
2597
- <a id="shared-ordinary-continuation-composition-m4-pro-2026-09-11"></a>
2598
- - [Shared ordinary continuation composition (M4 Pro, 2026-09-11)](../archive/investigations/benchmark-ledger-through-v0.4.0.md#shared-ordinary-continuation-composition-m4-pro-2026-09-11)
2599
-
2600
- ## Native submission thresholds on MLX 0.32.2 (2026-09-13)
2601
-
2602
- The R16 `25/25` candidate changes MLX's native command-buffer submission
2603
- thresholds, independently of request scheduling. The current-version screen
2604
- uses `aaf6082`, Bun 1.4.2 and native pack 0.4.0 / MLX 0.32.2. Every request
2605
- uses default shared serving; no `--batch 1` override. Both threshold variables
2606
- are absent in controls and set to `25` in candidates. Runtime defaults remain
2607
- unchanged. The benchmark now records these native environment overrides in its
2608
- JSON alongside the existing engine settings.
2609
-
2610
- Each model runs four standard suites in default/candidate/candidate/default
2611
- order, with bf16 KV, no draft, 1 GiB RAM cache, SSD restart, 192-token short
2612
- requests and a 4,096-token context target. Actual rendered context is 2,721
2613
- for Llama, 2,307 for MiniCPM and 2,448 for Gemma. Compiled decode and strict
2614
- fill are off; early output remains on. Each percentage below compares adjacent
2615
- opposite arms, preserving both orders. Cached completion includes the whole
2616
- request, averaged over the two warm context requests by the suite review.
2617
-
2618
- | Machine and model | Short decode TPS change, A/B and B/A | Context decode TPS change | Cached completion time change | Four-request throughput change |
2619
- |---|---:|---:|---:|---:|
2620
- | M4 Pro 24 GB, Llama 3.2 1B 4-bit | +8.31% / +1.90% | +14.10% / +10.84% | −11.55% / −10.58% | +3.35% / +3.06% |
2621
- | M4 Pro 24 GB, MiniCPM5 1B | +1.92% / +0.29% | +5.03% / +3.16% | −5.68% / −6.33% | +3.23% / +2.59%, changed text |
2622
- | M4 Pro 24 GB, Gemma 4 e4b | +1.15% / −1.11% | +1.85% / +1.12% | −1.64% / −0.82% | +0.04% / +0.07% |
2623
- | M4 Pro 24 GB, Gemma 4 12B | +0.08% / −0.39% | −0.25% / +0.01% | +0.20% / +0.05% | −0.64% / +0.52% |
2624
- | M1 Max 32 GB, Llama 3.2 3B 4-bit, first screen | −5.32% / −7.36% | −8.01% / −9.04% | +9.02% / +12.48% | −6.90% / −1.88% |
2625
-
2626
- All 380 requests complete, with every SSD restart durable. All 190 paired
2627
- inputs, complete usage objects, output counts and finish reasons match.
2628
- All paired text matches except the eight MiniCPM concurrent responses across
2629
- two pairs. Their throughput is recorded but does not establish an identical-work
2630
- speedup. Full native logits and prefix/live/continuation cache-state hashes
2631
- match all ten cases on M4 Llama 1B and all ten on M1 Llama 3B, at context
2632
- positions 0/127/511/1023/4095 and append lengths 1/4. These native cases use B1;
2633
- they do not establish a B4 numerical contract from HTTP text alone.
2634
-
2635
- A second M1 Llama 3B screen reverses the order to
2636
- candidate/default/default/candidate. All 76 requests and all 38 paired
2637
- responses/usage records match, with four durable SSD restarts. Short decode
2638
- changes −5.22%/−4.46%, context decode −5.55%/−8.62%, cached completion
2639
- +6.15%/+5.72%, and aggregate throughput −2.01%/−1.54%. This reproduces the
2640
- slowdown in the opposite order; activity remains recorded, so the conclusion
2641
- is to retain native defaults on this measured configuration. Raw evidence:
2642
- `llama3-submission-m1-r2-*`.
2643
-
2644
- The M4 Llama control rises from 278.01 to 295.30 short TPS between arms,
2645
- while candidates are 301.11/300.92. Both orders are retained. M1 candidate arms
2646
- coincide with more indexing/browser activity and some desktop GPU submissions;
2647
- the first screen alone cannot isolate its observed slowdown. All screens are
2648
- diagnostic. Activity sampling records last GPU submitters, not exclusive
2649
- ownership or time spent by each process. M4 retained swap stays at 3,279 MB;
2650
- M1 decreases from 3,532 to 3,412 MB. Cold prefill and peak RSS results are mixed.
2651
-
2652
- In upstream MLX 0.32.2, `Device` reads these overrides at construction and
2653
- shares them across command encoders. Its public header exposes a getter, with
2654
- no scoped setter for these fields. Changing an environment variable around a
2655
- model call after initialization cannot implement a model-owned policy.
2656
- This screen therefore does not introduce a per-request setting or a universal
2657
- startup default. See the pinned [device implementation](https://github.com/ml-explore/mlx/blob/v0.32.2/mlx/backend/metal/device.cpp)
2658
- and [device interface](https://github.com/ml-explore/mlx/blob/v0.32.2/mlx/backend/metal/device.h).
2659
-
2660
- The packed Qwen3.8 27B agent profile also completes four ABBA suites:
2661
- interleaved k300 weights, folded RTN4 MTP2, KV4/group64, 4 GiB RAM cache,
2662
- fixed 256-token prefill, Trellis v13 and synchronous expansion. Actual context
2663
- is 10,399 tokens. All 76 responses, 38 paired inputs/text/full usage records
2664
- and four durable SSD restarts match. Short decode changes −2.75%/+0.13%,
2665
- context decode −3.60%/−0.81%, cached completion +4.15%/+1.08%, and aggregate
2666
- throughput +0.44%/−0.80%. The 183 activity samples record Bun as last GPU
2667
- submitter 172 times, Terminal seven times and the desktop Codex process four
2668
- times. This supports retaining the current Qwen setting. Raw evidence:
2669
- `qwen-submission-current-*`.
2670
-
2671
- Across the first screens and both follow-ups, all 532 requests complete;
2672
- all 266 paired inputs and full usage records match, with only the eight
2673
- MiniCPM concurrent text differences described above. This closes the current
2674
- submission-threshold screen with no universal default change. The measured
2675
- M4 Llama profile can use the existing startup overrides when desired:
2676
-
2677
- ```sh
2678
- MLX_MAX_OPS_PER_BUFFER=25 MLX_MAX_MB_PER_BUFFER=25 bun scripts/bench-serve.ts all --model-path /path/to/Llama-3.2-1B-Instruct-4bit --arms mlx-bun --no-serial --kv-quant off --prompt-cache 1 --context 4096 --tokens 192 --diagnostic
2679
- ```
2680
-
2681
- Raw reports, plans, activity samples and pair reviews are under
2682
- `reports/prefill-observation/`: `llama-submission-current-*`,
2683
- `submission-stock-current-*`, `llama3-submission-m1-*` and
2684
- `submission-llama{1-native-m4,3-native-m1}-*`. Native environment capture was
2685
- added after the M4 Llama HTTP screen; that screen's launch plan records the
2686
- same overrides. The standard reports capture unchanged engine source before
2687
- and after each suite. Older MLX 0.31.2 measurements remain separate evidence.
2688
-
2689
- ## Shared Gemma media execution (2026-09-13)
2690
-
2691
- Gemma4 image/audio requests now use prepared embeddings followed by ordinary
2692
- shared decode. Media downloads and container transcoding run outside the native
2693
- execution lease. A held audio download no longer blocks text generation. The
2694
- encoder and full media prefill remain indivisible work at execution boundaries.
2695
-
2696
- **M4 Pro 24 GB, diagnostic, source-controlled ABBA.** Control runtime source
2697
- `48e234c`; candidate `97eb80e`; Bun 1.4.2, native pack 0.4.0 / MLX 0.32.2.
2698
- Both use the existing Gemma4-e4b OptiQ snapshot `fcdb12d…` with its complete
2699
- 912 MiB vision/audio sidecar, bf16 KV, default batch cap eight, no draft,
2700
- compiled decode off and fill off. The ordinary RAM cache remains enabled;
2701
- media bypasses token-only caching and no SSD cache is configured. Each fresh
2702
- process warms audio, image and text once, then repeats six scenarios three
2703
- times. Inputs are the existing speech-fox WAV/transcription request, a solid
2704
- red 64×64 PNG, and a 128-token counting request. These are bounded media
2705
- measurements, separate from the standard text-only h2h script.
2706
-
2707
- Median complete times per scenario, including all requests in a concurrent set:
2708
-
2709
- | Scenario | Control A → shared A, ms | Control B → shared B, ms | Paired change |
2710
- |---|---:|---:|---:|
2711
- | One audio request | 356.49 → 361.08 | 359.01 → 363.55 | +1.29% / +1.26% |
2712
- | One image request | 608.93 → 615.98 | 606.89 → 617.48 | +1.16% / +1.75% |
2713
- | Two audio requests | 717.98 → 574.82 | 720.70 → 580.56 | −19.94% / −19.45% |
2714
- | Four audio requests | 1,433.86 → 963.54 | 1,435.50 → 931.34 | −32.80% / −35.12% |
2715
- | Two image requests | 1,227.89 → 1,196.56 | 1,217.94 → 1,198.98 | −2.55% / −1.56% |
2716
- | Text + audio + image | 3,242.79 → 3,208.42 | 3,251.49 → 3,208.60 | −1.06% / −1.32% |
2717
-
2718
- All 156 measured requests complete. All 78 paired responses and complete usage
2719
- records excluding the intentionally changed `lane` field match. Audio returns
2720
- 11 tokens and images two; the text request returns 128. Controls send media
2721
- through serial execution despite cap eight. Candidates send it through shared
2722
- execution, with actual B2/B4 audio forwards and B2 image forwards observed.
2723
- The very short image outputs do not reach B2 in every repetition.
2724
-
2725
- Aggregate completion improves at a cost to individual latency. With four audio
2726
- requests, the first submitted request completes in 531.08 → 933.57 ms and
2727
- 528.46 → 930.99 ms. Its first visible output changes from 168.36 → 178.23 ms
2728
- and 169.50 → 182.36 ms. Lone-audio first-output medians are 197.90 → 203.11 ms
2729
- and 168.78 → 203.45 ms. Shared media is integrated; these results do not establish
2730
- strict domination of explicit serial execution. The small lone-request cost and
2731
- encoder scheduling remain optimization opportunities.
2732
-
2733
- Activity records contain 57 process/GPU/swap samples. The last GPU submitter is
2734
- Bun in 53 samples; the four initial samples show Terminal or the desktop app.
2735
- Retained swap remains 2,883.81 MiB throughout. Browser and desktop CPU activity
2736
- is retained in the raw records. No competing inference/training process was
2737
- observed. This is monitored diagnostic evidence, not a quiet-machine label.
2738
-
2739
- Both-machine prepared-input tests compare complete same-machine logits, live
2740
- cache state and continuation for image/audio/mixed masks at lengths seven and
2741
- 17, using bf16 and delayed KV4. Queued native preparation preserves every
2742
- captured active B1/B2 logit vector. Both-machine HTTP checks preserve the existing
2743
- audio transcription golden, exercise actual B2 audio decode, transcode AAC,
2744
- handle malformed input, and complete text while an audio download is held open.
2745
- The model-free suite passes 2,353 tests with 14 existing fixture skips; all three
2746
- TypeScript projects and hygiene pass.
2747
-
2748
- Raw source/input/native manifests, stream events, timing samples and activity:
2749
- `reports/prefill-observation/shared-media-{control,candidate}-{a,b}.json` on both
2750
- Macs. Derived comparisons: `shared-media-comparison-review.json`. The initial
2751
- control attempted a text-only local snapshot; its explicit missing-audio-sidecar
2752
- failure remains in `shared-media-control-a-missing-sidecar.*`. The completed
2753
- runner source is retained in `completed-shared-media-tool-sources.json`.
2754
- Qwen's request-specific mRoPE state and video acceptance follow below.
2755
- Encoder-cache measurements remain separate work.
2756
-
2757
-
2758
- ## Shared Qwen image and video execution (2026-09-13)
2759
-
2760
- Qwen image/video decode now carries each request's mRoPE position delta through
2761
- an input-state interface. The current row order and device-resident cache offsets
2762
- determine positions after merging and retirement. The model receives positions
2763
- explicitly; shared execution never changes the legacy serial mRoPE field.
2764
- Image/video preprocessing stays outside the native execution lease. Encoder
2765
- execution and the full media prefill remain atomic.
2766
-
2767
- **M4 Pro 24 GB, diagnostic, source-controlled ABBA.** Control runtime source
2768
- `011a19c`; candidate `a24151b`; Bun 1.4.2, native pack 0.4.0 / MLX 0.32.2.
2769
- Both use the existing interleaved k300 packed Qwen3.8-27B artifact, KV4, batch cap
2770
- eight, no draft, ordinary RAM caching, no SSD, compiled decode off and fill off.
2771
- Each fresh process warms image/video/text once, then repeats six scenarios three
2772
- times. Inputs are solid-color PNGs with different 64/96-pixel grids, a one-second
2773
- red MP4 and a text request. Media generates 64 tokens; text generates 128.
2774
- Temperature is zero, seed 42, thinking disabled. This bounded media comparison
2775
- is separate from the standard text-only h2h script.
2776
-
2777
- Median complete time includes all requests in a concurrent set:
2778
-
2779
- | Scenario | Control A → shared A, ms | Control B → shared B, ms | Paired change |
2780
- |---|---:|---:|---:|
2781
- | One image | 6,302.69 → 6,302.58 | 6,296.41 → 6,304.66 | −0.00% / +0.13% |
2782
- | One video | 6,873.32 → 6,848.58 | 6,846.71 → 6,859.52 | −0.36% / +0.19% |
2783
- | Two images | 12,625.07 → 7,715.17 | 12,558.80 → 7,724.26 | −38.89% / −38.50% |
2784
- | Four images | 25,195.82 → 10,935.59 | 25,140.36 → 11,044.71 | −56.60% / −56.07% |
2785
- | Image + video | 13,189.18 → 8,624.31 | 13,150.96 → 8,637.60 | −34.61% / −34.32% |
2786
- | Text + two images | 24,297.23 → 19,337.81 | 24,267.51 → 19,383.98 | −20.41% / −20.12% |
2787
-
2788
- All 156 measured requests complete. All 78 paired inputs and full usage records
2789
- excluding the intended lane change match. Response text matches in 54/78 pairs:
2790
- all lone-image, lone-video and mixed-text scenarios, plus some concurrent-image
2791
- rows. The other 24 pairs change text when serial media becomes B2/B4 work.
2792
- These differing batch geometries do not establish a same-B numerical failure,
2793
- and this short color fixture does not establish unchanged general media quality.
2794
- The first pair's probe wrapped only `forwardHidden`, missing the new position
2795
- forward. Its recorded zero widths mean unobserved, not B0. The corrected probe
2796
- in the second pair observes B2 for two images/image+video and B4 for four images
2797
- in every repetition. No engine change separates the candidate arms.
2798
-
2799
- The first submitted image in the four-image set completes in
2800
- 6,304.57 → 10,697.33 ms and 6,297.85 → 10,802.06 ms; its first visible output
2801
- changes from 815.21 → 823.53 ms and 809.46 → 843.48 ms. First image+video output
2802
- changes from 812.34 → 899.53 ms and 809.51 → 838.27 ms. Concurrent total time
2803
- improves while the first request can finish later. Explicit serial remains
2804
- available; this is not strict latency domination.
2805
-
2806
- The 476 activity samples identify Bun as last GPU submitter in 470 cases;
2807
- initial desktop processes and two Chrome samples account for the others.
2808
- Retained swap ranges from 3,067.31 to 3,932.88 MiB across the four processes.
2809
- Sampled peak Bun RSS is 12,610–12,633 MiB. Process/activity records are preserved,
2810
- including desktop activity; this comparison is diagnostic, not quiet-qualified.
2811
-
2812
- Numerical acceptance uses the same machine and geometry. Frozen pre-change
2813
- module-global and explicit-position forwards match all 40 complete logit/cache
2814
- snapshots per Mac across eight B1/B2, length-seven/17, bf16/delayed-KV4 cases.
2815
- This is a source comparison, not a new independent Python oracle. Shared
2816
- B1/B2/B4 padded and retiring rows also match an independently constructed CPU
2817
- position grid for bf16, delayed KV4 and delayed K8V3, nine cases per Mac. The M4
2818
- uses the actual packed 27B artifact; the M1 source/group checks use Qwen0.8B.
2819
- Real image HTTP checks on the packed 27B pass on both Macs, including logprobs,
2820
- different image grids, correct red/blue responses, actual B2 and no mutation of
2821
- legacy model position state. Tests: `qwen-media-state.test.ts` and
2822
- `qwen-media-serve.test.ts` under `tests/parity/`.
2823
-
2824
- Raw manifests, complete stream events, timing/activity, source comparisons and
2825
- native/HTTP logs are on both Macs under `reports/prefill-observation/qwen-media-*`.
2826
- The derived review is `qwen-media-comparison-review.json`; completed one-off
2827
- sources are retained in `completed-qwen-media-tool-sources.json`. Encoder feature
2828
- caching, chunked media prefill and broader speculative/media compositions remain
2829
- separate optimization work.
2830
-
2831
-
2832
- ## Qwen encoder reuse through shared RAM and SSD storage (2026-09-13)
2833
-
2834
- The exact-object cache retains Qwen encoder outputs under the existing RAM
2835
- budget and SSD writer. Keys include preprocessed pixel bytes, grids, encoder
2836
- schema and a one-time SHA-256 of the loaded encoder tensors. Requests still
2837
- render their own positions and run media language-model prefill. This does not
2838
- cache preprocessing or enable media KV-prefix reuse.
2839
-
2840
- **M4 Pro 24 GB, diagnostic, source-controlled ABBA.** Runtime control `64e4226`,
2841
- candidate `dbd7bc3`; the same interleaved k300 packed Qwen3.8-27B artifact,
2842
- Bun 1.4.2, native pack 0.4.0 / MLX 0.32.2, KV4, default cap eight, no draft,
2843
- compiled decode off, fill off and temperature zero/seed 42. Both use the normal
2844
- RAM cache; these timing arms do not configure SSD. Each process first warms an
2845
- image, video and text request, preserving those timings separately. It then
2846
- runs six repetitions of each scenario. Images are 512×512 and 768×512 solid-color
2847
- PNGs; video is the earlier one-second 64×64 red clip. Media emits 16 tokens.
2848
-
2849
- | Scenario | Control A → cached A, ms | Control B → cached B, ms | Complete-time change |
2850
- |---|---:|---:|---:|
2851
- | Repeated 512×512 image | 4,070.27 → 3,886.72 | 4,065.97 → 3,881.26 | −4.51% / −4.54% |
2852
- | Repeated small video | 2,676.05 → 2,627.50 | 2,676.22 → 2,627.71 | −1.81% / −1.81% |
2853
- | Two image requests | 8,058.20 → 7,586.82 | 8,052.03 → 7,584.61 | −5.85% / −5.81% |
2854
-
2855
- All 96 measured requests complete; all 48 paired responses and full usage
2856
- records match. Both arms observe actual B2 in every two-image repetition.
2857
- Every paired complete-time cell improves. The first two-image repetition
2858
- includes the initially unseen blue image; its gains are smaller than later
2859
- fully cached repetitions. Three encoder objects retain 7,208,960 additional
2860
- bytes, or 6.875 MiB, in the same cache as the text checkpoint.
2861
-
2862
- Exact weight identity has a first-use cost. The first image after loading the
2863
- model completes in 5,525.19 → 6,132.09 ms and 5,539.03 → 6,107.68 ms.
2864
- The additional 568.65–606.90 ms is recovered after about four subsequent
2865
- repetitions of this image. These two first-use samples are not a tail-latency
2866
- estimate. The cache remains useful for repeated media; a one-shot image pays
2867
- the initial cost. Disabling the RAM cache supplies no object port and avoids
2868
- both hashing and feature retention.
2869
-
2870
- Activity contains 136 process/GPU/swap samples, with Bun the last GPU submitter
2871
- in 130 and desktop/browser processes in six. Retained swap ranges from
2872
- 4,636.12 to 4,668.12 MiB. Sampled peak Bun RSS changes from
2873
- 12,663.06 → 12,696.30 MiB and 12,627.34 → 12,678.23 MiB. These monitored
2874
- conditions remain diagnostic. All raw samples, including first-use costs and
2875
- background activity, are preserved.
2876
-
2877
- The preceding small-media prototype preserves all 132 response/full-usage pairs
2878
- across 264 requests. It reduces complete time by 0.18–2.59% across both arm orders,
2879
- while avoiding 63 of 68 encoder calls per candidate process. It uses six
2880
- repetitions of the earlier 64/96-pixel image and video fixtures. This prototype
2881
- memoizes encoder results in the measurement runner; the table above measures
2882
- the integrated shared-cache implementation with larger images.
2883
-
2884
- Correctness and persistence checks pass on both Macs. The object store shares
2885
- its byte cap with prefix checkpoints, lends independent native views, retains
2886
- unwritten victims until SSD completion, rejects stale restore publication after
2887
- clear, and preserves newer resident publication during a competing restore.
2888
- A real Qwen image request reuses the encoder once with identical output and
2889
- logprobs. A new HTTP server restores it with a 16-byte RAM budget, makes no
2890
- additional tower call, reproduces output/logprobs and flushes durably. The M4
2891
- also passes two separate processes: the writer encodes once, the reader encodes
2892
- zero times, exact encoder-weight fingerprints match, and every response,
2893
- logprob and usage field matches after verified SSD restore. The retained
2894
- small SSD artifact is in the report directory.
2895
-
2896
- The complete model-free run passes 2,358 tests with 14 fixture skips. Subsequent
2897
- weight-identity/disabled-cache changes pass 57 focused tests; types, hygiene and
2898
- CI pass. Native HTTP acceptance passes four cases and 31 assertions per Mac.
2899
- Raw reports: `reports/prefill-observation/qwen-encoder-{control,candidate}-{a,b}.json`,
2900
- `qwen-encoder-integrated-{control,candidate}-{a,b}.json`,
2901
- `qwen-encoder-{prototype,integrated}-review.json`, and `encoder-process-*`.
2902
- Completed runner sources are in `completed-encoder-cache-tool-sources.json`.
2903
- Gemma encoder caching, media KV-prefix reuse and broader media compositions
2904
- remain separate opportunities; these results do not require another unchanged
2905
- text-only Kanban run.
2906
-
2907
-
2908
- ## Gemma encoder reuse through shared RAM and SSD storage (2026-09-13)
2909
-
2910
- Gemma image/audio preparation now retains encoder features through the same
2911
- exact-object cache used by Qwen. Comparison source is `4289bce`; runtime and
2912
- model configuration are unchanged. Each Mac supplies its own baseline.
2913
-
2914
- On M1 Max 32 GB and M4 Pro 24 GB, all six prepared prompts match the original
2915
- in complete embeddings, token IDs, bidirectional mask and multimodal mask.
2916
- The cases are image, audio and mixed input, each repeated with retained features.
2917
- Both Macs pass all nine real-model HTTP checks with 49 assertions, including
2918
- mixed image/audio reuse in RAM and from a new server's verified SSD cache.
2919
- Outputs, all requested logprobs and full usage match; each encoder runs once,
2920
- and neither runs after SSD restore. Existing transcription, actual B2 decode,
2921
- download concurrency, transcode and malformed-request checks also pass.
2922
- This proves retention identity for these fixtures; it does not extend the
2923
- model's separately documented external-oracle tier.
2924
-
2925
- Reports: `reports/prefill-observation/gemma-encoder-{control,candidate}-{m1,m4}.json`
2926
- and `gemma-encoder-http-{m1,m4}.log`.
2927
-
2928
- M4 Pro 24 GB ABBA compares runtime source `4289bce` with `4521024`, using
2929
- Gemma e4b OptiQ snapshot `fcdb12d740cd813634064567fc7cb51159b34253`,
2930
- Bun 1.4.2 / MLX 0.32.2, bf16 KV, default cap eight, no draft, an 8,000,000,000-byte
2931
- RAM cache and no SSD during timing. Compiled decode uses its existing default.
2932
- The runner's `MLX_BUN_COMPILED=0` is an unused environment name, not the
2933
- `MLX_BUN_COMPILED_DECODE` option; both arms use identical runtime settings.
2934
- Inputs are a 64×64 red PNG and the existing speech WAV, with temperature zero
2935
- and seed 42. Six repetitions per scenario follow separately recorded audio,
2936
- image and 128-token text warmups. Audio returns 11 tokens, image two, and the
2937
- single mixed-media request 12, under unchanged 32/16-token budgets.
2938
-
2939
- All 168 paired measured responses retain complete content, reasoning and usage.
2940
- Medians below are request completion times, not isolated decode throughput.
2941
-
2942
- | Workload | Control A → candidate A, ms | Change | Control B → candidate B, ms | Change |
2943
- |---|---:|---:|---:|---:|
2944
- | One audio request | 354.57 → 326.65 | −7.87% | 357.16 → 327.08 | −8.42% |
2945
- | One image request | 611.51 → 413.51 | −32.38% | 625.98 → 414.56 | −33.77% |
2946
- | Two audio requests | 570.41 → 519.37 | −8.95% | 575.19 → 517.19 | −10.08% |
2947
- | Four audio requests | 923.95 → 855.95 | −7.36% | 931.98 → 856.43 | −8.11% |
2948
- | Two image requests | 1196.14 → 833.21 | −30.34% | 1229.68 → 834.23 | −32.16% |
2949
- | Concurrent text, audio and image | 3147.68 → 2927.42 | −7.00% | 3182.60 → 2932.27 | −7.87% |
2950
- | One request containing image and audio | 901.25 → 680.19 | −24.53% | 922.33 → 682.12 | −26.04% |
2951
-
2952
- Audio cohorts observe actual B2/B4 in every repetition. The image pair's overlap
2953
- changes: the control observes B2, while the candidate's first request finishes
2954
- much earlier, at 420.37/423.92 ms versus 1196.12/1229.67 ms. The runner's forward
2955
- probe does not observe compiled B1 calls; zero in that raw field means unobserved.
2956
- This is request-level acceptance, not a fixed-B2 kernel comparison.
2957
-
2958
- First-use audio costs 946.84 → 1222.28 ms and 899.07 → 1227.05 ms; image costs
2959
- 625.77 → 882.39 ms and 627.98 → 871.59 ms. Weight fingerprints and first cache
2960
- publication add 275.44/327.98 ms for audio and 256.62/243.62 ms for images.
2961
- At the repeated B1 savings above, that cost is recovered after roughly 10–11
2962
- additional audio uses or two image uses. The two feature objects add exactly
2963
- 1,996,800 resident bytes, about 1.90 MiB, to the existing shared cache budget.
2964
-
2965
- These are diagnostic measurements. All 94 activity samples retain process,
2966
- GPU-submitter and swap observations; Bun is the last GPU submitter in 87,
2967
- with desktop applications in seven. Retained swap is 3996.12 MiB throughout.
2968
- Sampled peak Bun RSS is 7628.20 → 7558.05 MiB and 7644.98 → 7398.94 MiB.
2969
- Both comparison orders favor reuse despite the recorded background activity.
2970
-
2971
- A separate M4 process reloads the model and restores both features from verified
2972
- SSD storage. Request, encoder fingerprints, output, every requested top-ten
2973
- logprob and full usage match; encoder calls change from one per tower to zero.
2974
- Both processes finish with durable persistence. Both-machine HTTP/native checks,
2975
- all 2,360 model-free tests, typechecks and hygiene pass.
2976
-
2977
- Raw timing: `gemma-encoder-{control,candidate}-{a,b}.json`, reviewed in
2978
- `gemma-encoder-comparison-review.json`. Fresh-process evidence:
2979
- `gemma-encoder-process-{write,read}.json` and `gemma-encoder-process-review.json`.
2980
- Completed runner sources: `completed-gemma-encoder-tool-sources.json`.
2981
- Media KV-prefix reuse remains open.
2982
-
2983
-
2984
- ## Latency-aware MLP allocation screen (2026-09-13)
2985
-
2986
- The existing production `tq-trellis-kernel-bench.ts` measures actual packed
2987
- Qwen3.8-27B matrices at k2/k3/k4, using layers 0/1/56 of the accepted interleaved
2988
- artifact. Gate/up are one fused producer for M≤4; down projection is separate.
2989
- M is the number of rows in an MLP call, not the scheduler's request count.
2990
- Current variant 13 is used on Bun 1.4.2 / MLX 0.32.2, with 20 measured rounds
2991
- and eight queued calls per evaluation. Forward/reverse sweep orders use the
2992
- same matrix hashes. All 228 self-reference reader checks match; these are
2993
- harness checks against the same implementation, not cross-bit or external
2994
- oracle quality claims. No runtime source or artifact changes in this screen.
2995
-
2996
- Complete MLP medians below average the two sweep-order medians. The independent
2997
- fused-gate/up and down timings supply the allocation cost model.
2998
-
2999
- | Machine / M | k2, ms | k3, ms | k4, ms |
3000
- |---|---:|---:|---:|
3001
- | M1 Max 32 GB / 1 | 1.182 | 1.113 | 1.141 |
3002
- | M1 Max / 3 | 1.677 | 1.558 | 1.559 |
3003
- | M1 Max / 4 | 2.034 | 1.974 | 1.938 |
3004
- | M1 Max / 16 | 10.986 | 11.519 | 8.851 |
3005
- | M4 Pro 24 GB / 1 | 0.985 | 0.985 | 0.926 |
3006
- | M4 Pro / 3 | 1.164 | 1.171 | 1.135 |
3007
- | M4 Pro / 4 | 1.294 | 1.284 | 1.245 |
3008
- | M4 Pro / 16 | 5.381 | 5.419 | 5.357 |
3009
-
3010
- Bit count alone does not order execution cost. The k4 M1/M16 complete MLP is
3011
- 23.2% faster than k3 in both sweep orders, while k3 is faster at M1/M1. These
3012
- are role/MLP diagnostics with repeated inputs, not full-model TPS measurements.
3013
- Both Macs record background activity and retained swap: 2712.19 MiB on M1,
3014
- 3980.12 MiB on M4. No quiet classification is claimed. Source/native geometry
3015
- and per-round samples remain in the reports; source commits differ only in
3016
- unrelated Gemma/tests/docs changes, with identical kernel hashes.
3017
-
3018
- A multiple-choice knapsack then minimizes normalized sensitivity loss plus a
3019
- weighted sum of measured producer times. Its 128 decisions tie each layer's
3020
- gate/up and choose down independently. k is 2, 3 or 4, subject to the existing
3021
- 3.00 average MLP-bit budget and 6,423,969,792 packed MLP bytes. Attention, GDN,
3022
- embedding and head remain unchanged. Eight latency weights, zero through eight,
3023
- run against each machine/M profile. At zero latency weight, every profile
3024
- reproduces the existing k300 allocation exactly.
3025
-
3026
- The sensitivity source is the previously saved EXL3 per-tensor table. It ranks
3027
- an external codec's losses; neither its absolute divergence nor candidate loss
3028
- changes establish Trellis quality. The following are proposal estimates only.
3029
-
3030
- | Profile, latency weight | Estimated summed MLP-role time change | External-codec loss proxy change | Changed tensors |
3031
- |---|---:|---:|---:|
3032
- | M1 / M1, weight 1 | −0.52% | +0.26% | 8 |
3033
- | M4 / M1, weight 1 | −0.09% | +0.07% | 4 |
3034
- | M4 / M4, weight 1 | −0.07% | +0.05% | 4 |
3035
- | M1 / M16, weight 2 | −6.20% | +9.01% | 60 |
3036
- | M4 / M1, weight 8 | −1.12% | +4.68% | 52 |
3037
-
3038
- Keep the current artifact. This MLP-only screen finds little estimated decode
3039
- headroom at a fixed size and a larger M1-prefill tradeoff that needs real quality
3040
- evaluation. No candidate has been quantized or promoted. The checked primary
3041
- model directories contain quantized targets/references, but no complete original
3042
- Qwen bf16 weight snapshot. Re-encoding the existing k300 weights cannot restore
3043
- precision for promoted tensors. Teacher-based quantization and frozen
3044
- KL/MMLU/tGSM/rawGSM acceptance remain open, as do non-MLP allocation and the
3045
- other R19 calibration/rounding choices.
3046
-
3047
- Reports: `reports/prefill-observation/r19-cost/` contains all 48 kernel runs,
3048
- `cost-review.json`, all 64 `allocation-proposals.json` cells and archived
3049
- `completed-allocation-source.json`. The existing production script is retained;
3050
- the completed one-off allocator is removed.
3051
-
3052
-
3053
- ## Gemma prepared-media KV reuse (2026-09-13)
3054
-
3055
- The experimental `MLX_BUN_MEDIA_PREFIX_CACHE=1` option combines the producer's
3056
- media/token identity with the ordinary cache namespace. Generated conversation
3057
- state uses the existing RAM residency and SSD persistence interfaces. Repeated
3058
- media encoder caching remains enabled independently in both comparison arms.
3059
-
3060
- Both M1 Max 32 GB and M4 Pro 24 GB pass 23 native prepared-input tests with
3061
- 98 assertions, including complete logits/state and continuation after retained
3062
- image, audio and mixed prefixes. New resumed cases use bf16, delayed affine KV4
3063
- and delayed k8v3. Both Macs also pass 11 real-model HTTP tests with 188 assertions:
3064
- bf16, start-zero KV4/k8v3 and delayed KV4/k8v3 through RAM and verified SSD
3065
- restart, plus mixed/audio identity. Follow-ups reuse generated output tokens;
3066
- different images and changed media sets miss correctly. The fixture's TurboQuant
3067
- configuration quantizes full-attention layers while sliding layers remain bf16.
3068
-
3069
- The first delayed-precision test incorrectly expected a shorter repeated prompt
3070
- to hit after conversion. Inspection records minimum reusable offset 280 on
3071
- trimmable generated entries at offsets 282/301. The shorter request needs offset
3072
- 279, before conversion, so it correctly recomputes; growing conversation turns
3073
- hit. The runtime was unchanged for that finding, and the tests now assert the
3074
- boundary explicitly. The failed assumptions and inspection remain preserved.
3075
-
3076
- Reports: `reports/prefill-observation/media-prefix-native-{m1,m4}.log`,
3077
- `media-prefix-http-{m1,m4}.log`, `media-prefix-trim-inspection.log` and
3078
- `completed-media-prefix-inspection.json`. M4 same-source ABBA on `7ea35fb` uses the existing e4b OptiQ fixture, bf16 KV,
3079
- default cap eight and compiled decode, six repetitions per workload, and the
3080
- same encoded-feature cache in both arms. Only media prefix reuse is toggled.
3081
- No SSD participates in these timings; the separate restart checks cover it.
3082
-
3083
- | Workload | Control A → candidate A, ms | Change | Control B → candidate B, ms | Change |
3084
- |---|---:|---:|---:|---:|
3085
- | One audio request | 327.80 → 230.48 | −29.69% | 328.98 → 230.11 | −30.06% |
3086
- | One image request | 413.04 → 73.55 | −82.19% | 414.24 → 72.74 | −82.44% |
3087
- | Two audio requests | 517.89 → 296.59 | −42.73% | 521.07 → 294.76 | −43.43% |
3088
- | Four audio requests | 858.40 → 407.62 | −52.51% | 862.02 → 405.85 | −52.92% |
3089
- | Two image requests | 834.56 → 148.10 | −82.25% | 834.20 → 146.39 | −82.45% |
3090
- | Concurrent text, audio and image | 2923.02 → 2329.57 | −20.30% | 2934.48 → 2339.33 | −20.28% |
3091
- | One request containing image and audio | 681.82 → 287.71 | −57.80% | 683.60 → 285.89 | −58.18% |
3092
-
3093
- Of 168 paired measured requests, 158 retain identical content/reasoning and
3094
- non-cache token usage. The ten changed mixed-media replies add a terminal
3095
- period after “Red”, increasing completion count from 12 to 13; their transcription
3096
- and color are unchanged. Prompt cached counts intentionally change. Audio
3097
- reuses 82 tokens and image 279. The first mixed-media request is uncached;
3098
- subsequent mixed-media requests reuse its state. This is same-workload request
3099
- acceptance, not identical full-prefill geometry or a bit-identical token stream.
3100
- The native retained-state checks above use matched geometry.
3101
-
3102
- All scenarios improve in both comparison orders. Concurrent occupancy changes
3103
- as preparation gets shorter; the mixed text/audio/image case reaches B3 instead
3104
- of B2. The runner's zero forward-probe field means unobserved compiled B1, not
3105
- zero active rows. These are complete request times, not isolated decode TPS.
3106
-
3107
- First-use audio is 1170.63 → 1296.42 ms and 1319.00 → 1294.70 ms; first-use image
3108
- is 876.81 → 879.04 ms and 878.60 → 907.45 ms. The extra prefix records retain
3109
- 93,757,440 bytes, about 89.41 MiB, in the same cache budget. The 74 activity
3110
- samples name Bun as last GPU submitter in 70 and desktop applications in four;
3111
- retained swap is 3964.12 MiB throughout. Sampled peak Bun RSS is
3112
- 7408.44 → 7114.09 MiB and 7183.34 → 7082.58 MiB. Diagnostic classification remains.
3113
-
3114
- Raw comparisons: `gemma-media-prefix-{control,candidate}-{a,b}.json`, with
3115
- `gemma-media-prefix-review.json`. Together with the Qwen comparison below,
3116
- these results select prepared media-prefix reuse by default. Encoder-only
3117
- comparison remains available with `MLX_BUN_MEDIA_PREFIX_CACHE=0`.
3118
-
3119
-
3120
- ### Qwen prepared-media KV identity and continuation
3121
-
3122
- Qwen uses the same shared prefix-cache port. Its producer identity additionally
3123
- includes prepared image/video hashes, rendered timestamps and mRoPE positions
3124
- through the last media span. Recurrent layers keep their exact-prefix rule.
3125
- The native binding resumes the new request's positioned text forward from the
3126
- retained offset; no global model position state is changed.
3127
-
3128
- Both Macs pass all 12 request-owned media state tests with 78 assertions. New
3129
- cases preserve complete logits, attention/recurrent state, donor immutability
3130
- and continuation after bf16, delayed KV4 and delayed k8v3 prefixes. M1 uses the
3131
- existing Qwen3.5 0.8B fixture and M4 the actual packed 27B artifact; each comparison
3132
- uses its own model and machine. Both Macs then pass five actual packed 27B HTTP
3133
- tests with 57 assertions: image follow-ups through KV4 and k8v3 in RAM and a
3134
- new server's verified SSD cache, different-image isolation, and video-history
3135
- reuse with timestamps/positions. The follow-ups reuse generated output tokens.
3136
-
3137
- Reports: `reports/prefill-observation/qwen-media-prefix-native-{m1,m4}.log` and
3138
- `qwen-media-prefix-http-{m1,m4}.log`.
3139
-
3140
-
3141
- ### Qwen media-session KV reuse on M4 Pro (2026-09-13)
3142
-
3143
- A same-source ABBA comparison on `a382cad` replays a frozen corpus captured on
3144
- the M4 Pro with the packed 27B artifact, KV4, default cap eight and compiled
3145
- decode, no speculation, an 8,000,000,000-byte shared RAM budget and no SSD.
3146
- Both arms reuse encoder features; only `MLX_BUN_MEDIA_PREFIX_CACHE` changes.
3147
- The corpus has image, video and two concurrent image sessions. Each session
3148
- contains an initial response capped at 16 tokens and a one-word follow-up
3149
- capped at eight. Three repetitions per arm give 96 measured requests and
3150
- 48 matched pairs. Corpus/source hashes match and every source diff is empty.
3151
-
3152
- | Workload | Session control A → candidate A, ms | Change | Session control B → candidate B, ms | Change |
3153
- |---|---:|---:|---:|---:|
3154
- | Image conversation | 6988.85 → 4636.54 | -33.66% | 6985.57 → 4633.27 | -33.67% |
3155
- | Video conversation | 4471.45 → 3470.36 | -22.39% | 4484.69 → 3469.52 | -22.64% |
3156
- | Two image conversations | 14638.65 → 9008.47 | -38.46% | 14664.64 → 9025.04 | -38.46% |
3157
-
3158
- All 48 paired responses, reasoning and non-cache token counts are identical.
3159
- Every measured follow-up hits its session cache in each enabled arm, reusing
3160
- 306 image tokens, 122 video tokens or 307/434 tokens for the image pair.
3161
- The initial requests still recompute because Qwen's recurrent state cannot
3162
- rewind the longer completed conversation. Their median completion changes range
3163
- from −0.08% to +0.36% across the pairs.
3164
-
3165
- | Follow-up | Control A → candidate A, ms | Change | Control B → candidate B, ms | Change |
3166
- |---|---:|---:|---:|---:|
3167
- | Image conversation | 3117.09 → 749.70 | -75.95% | 3107.98 → 750.40 | -75.86% |
3168
- | Video conversation | 1847.86 → 833.79 | -54.88% | 1840.45 → 830.34 | -54.88% |
3169
- | Two image conversations | 7049.63 → 1423.41 | -79.81% | 7065.98 → 1425.51 | -79.83% |
3170
-
3171
- The positioned-forward probe observes B2 on initial paired image decode and
3172
- B1 on those short follow-ups in both arms. These are conversation and request
3173
- times, not isolated decode throughput. Prefix records add 1,299,787,776 bytes
3174
- of retained state to the three encoder objects, within the same cache budget.
3175
- First-use red-image warmup is 6075.29 → 6145.35 ms and 6124.64 → 6125.24 ms.
3176
-
3177
- All 104 activity samples are retained: Bun is the last GPU submitter in 100,
3178
- and desktop applications in four. Swap stays at 3956.12 MiB. Sampled peak Bun
3179
- RSS is 12702.22 → 12655.58 MiB and 12686.38 → 12673.36 MiB. These monitored
3180
- comparisons are diagnostic. Both orders support selecting media-prefix reuse
3181
- by default; the explicit encoder-only switch remains available.
3182
-
3183
- Reports: `reports/prefill-observation/qwen-media-prefix-fixture.json`,
3184
- `qwen-media-prefix-session-{control,candidate}-{a,b}.json`,
3185
- `qwen-media-prefix-session-review.json` and
3186
- `completed-qwen-media-prefix-tool-sources.json`.
3187
-
3188
-
3189
- ### Media KV restore in a fresh process
3190
-
3191
- On M1 Max, both actual e4b OptiQ and packed Qwen27B pass a separate-process
3192
- restore comparison. The writer generates an image response, flushes its
3193
- checkpoint to SSD and copies that durable directory before issuing a follow-up
3194
- against warm RAM. A new process loads the copied directory and submits the
3195
- identical follow-up. Complete response choices, top-ten log probabilities and
3196
- full usage match the warm RAM result for each model.
3197
-
3198
- Gemma reuses 294 tokens with bf16 KV; Qwen reuses 45 with KV4. Each new process
3199
- restores two SSD records: the encoder feature and generated conversation state.
3200
- The initial durable directories contain 27,160,576 and 156,312,992 bytes,
3201
- respectively. The recorded read stats precede persistence of the new follow-up;
3202
- they are evidence of restored initial state, not a final follow-up flush.
3203
-
3204
- Source: `a382cad`. Reports and retained SSD directories are under
3205
- `reports/prefill-observation/{gemma,qwen}-media-prefix-process-*`;
3206
- `completed-media-prefix-process-tool-source.json` preserves the retired runner.
3207
-
3208
-
3209
- ### R24 activation quantization and resource bounds (2026-09-13)
3210
-
3211
- This is a feasibility screen, not a new model-quality or serving-speed claim.
3212
- The pinned MLX 0.32.2 oracle runs five alternating paired blocks per cell,
3213
- with three warmups and ten completed evaluations per arm. Synthetic seeded
3214
- bf16 inputs use the Qwen MLP gate/up dimensions, K=5120 and N=17408. Both arms
3215
- share the same pre-quantized weights. The control uses `quantized_matmul`;
3216
- the candidate uses `qqmm`, adding activation quantization. No model is loaded.
3217
- Each comparison is within one machine and format, not against packed Trellis.
3218
-
3219
- | Format | M | M1 control → candidate, ms | Change | M4 control → candidate, ms | Change |
3220
- |---|---:|---:|---:|---:|---:|
3221
- | nvfp4 | 1 | 0.760 → 0.792 | +4.18% | 0.360 → 0.360 | -0.21% |
3222
- | nvfp4 | 4 | 0.814 → 0.829 | +1.75% | 0.402 → 0.396 | -1.62% |
3223
- | nvfp4 | 16 | 1.438 → 1.652 | +14.84% | 1.112 → 1.166 | +4.83% |
3224
- | nvfp4 | 256 | 8.658 → 21.093 | +143.62% | 7.014 → 15.388 | +119.39% |
3225
- | mxfp8 | 1 | 0.502 → 0.512 | +1.89% | 0.510 → 0.509 | -0.22% |
3226
- | mxfp8 | 4 | 0.677 → 0.680 | +0.49% | 0.639 → 0.642 | +0.39% |
3227
- | mxfp8 | 16 | 1.467 → 1.868 | +27.35% | 1.139 → 1.714 | +50.51% |
3228
- | mxfp8 | 256 | 8.866 → 25.453 | +187.08% | 7.160 → 24.139 | +237.16% |
3229
-
3230
- Numbers are medians of block medians. Small-M cells have mixed block-level
3231
- noise; no small speed win is established. Every M=16/256 cell is slower in
3232
- all five pairs on both machines. Relative squared output error versus the
3233
- same quantized weights with bf16 activations is 0.0090–0.0095 for NVFP4 and
3234
- 0.00069–0.00072 for MXFP8. These are synthetic operation errors, not task scores.
3235
- The capability smoke also records that INT8 input to ordinary QMM is cast back
3236
- to the floating scale dtype. A constant NVFP4 example produces 136 where its
3237
- unquantized dot product is 128; MXFP8 produces 128 for that example.
3238
-
3239
- The pinned [Metal implementation](https://github.com/ml-explore/mlx/blob/v0.32.2/mlx/backend/metal/quantized.cpp#L1865)
3240
- quantizes/dequantizes activations before dispatching the weight kernel. Native
3241
- `mlx_qqmm` is exported by the current pack, but it does not provide a packed
3242
- Trellis W3A8 operation. Do not add a serving option for this measured loss.
3243
- Reopen with an operation that consumes compressed activations directly and
3244
- passes a whole-model quality comparison.
3245
-
3246
- These short diagnostic screens have three activity samples per machine. M1
3247
- names Python as last GPU submitter in all three; M4 names Python twice and a
3248
- desktop application once. Swap remains 2656.12 MiB on M1 and 3924.12 MiB on M4.
3249
- Sources are `6fe0a7f` on both machines; each uses its pinned 0.32.2 oracle.
3250
- Reports: `reports/prefill-observation/r24-activation-screen-{m1,m4}.json`,
3251
- `r24-activation-screen-review.json`, `r24-activation-native-capability.json`,
3252
- the adjacent native graph exports and `completed-r24-activation-tool-source.json`.
3253
-
3254
- The separate static resource screen reads the actual packed snapshot's
3255
- configuration and safetensors headers, without allocating model tensors.
3256
- Its 192 MLP matrices contain 17,112,760,320 parameters and occupy
3257
- 6,423,969,792 payload bytes, 49.27% of the 13,038,407,512-byte artifact.
3258
- Those file fractions are not fractions of decode time: the artifact also
3259
- contains media and MTP weights, and R19 shows bit count does not predict latency.
3260
-
3261
- | Candidate resource | Calculated bound and assumptions |
3262
- |---|---|
3263
- | MLP mean three → two bits | Save 2,139,095,040 raw code bytes before changed codebooks/metadata. This is 16.41% of artifact bytes, with unchanged other tensors; no latency or quality prediction. |
3264
- | Sparse MLP correction | A flat uint32 index plus fp16 value costs about 97.92/489.60/979.20 MiB at 0.1%/0.5%/1% density, excluding row pointers/alignment. Overhead is 0.048/0.24/0.48 bits per original MLP weight. |
3265
- | Low-rank MLP replacement | bf16 factors use `2*r*(5120+17408)` bytes per matrix. Rank 128/256/512 across all MLP projections uses 1056/2112/4224 MiB. Rank must be below about 742 to beat raw three-bit matrix bytes. Task quality at those ranks is unmeasured. |
3266
- | One-matrix calibration | One f32 MLP matrix is 340 MiB. Full f32 input covariance is 100 MiB for gate/up and 1156 MiB for down; solver copies, activations and the resident model are additional. Layerwise fitting is a candidate; whole-model residency is unnecessary. |
3267
- | Full 27B training | Approximate bf16 weights alone use 50.29 GiB. At 12 bytes/parameter for weights, gradients and Adam moments, state uses 301.75 GiB; a separate f32 master adds another 100.58 GiB. This full-resident form cannot fit either Mac. Offload is a different, unmeasured training design. |
3268
- | Adapter-only recovery | Existing adapters use f32 parameters. Rank-eight adapters on all MLP matrices would have 34,603,008 parameters and 528 MiB for parameters, gradients and two moments, before activations/base weights. This is a proposed capacity bound: the packed model currently excludes Trellis MLPs from its adapter targets. |
3269
- | B1 activation traffic | One MLP's three bf16 matrix inputs/outputs total 135,168 bytes before fusion/cache effects. Halving that saves at most 67,584 bytes against about 100,270,080 raw three-bit weight bytes, only 0.067%. Larger M is a separate compute/traffic regime. |
3270
-
3271
- Calculations: `reports/prefill-observation/r24-feasibility-bounds.json`.
3272
- They establish neither absence of task-quality loss nor a maximum TPS gain.
3273
-
3274
-
3275
- #### Actual-weight approximation and derivative screens
3276
-
3277
- The packed layer-one gate matrix is expanded through the existing Bun decoder
3278
- to bf16, then converted losslessly to f32 for inspection. Its SHA-256 is
3279
- `90a28e05d53aad2f4e920af988ad0ca2f81c98c38d3dc92fd4f7ee90659267f8`.
3280
- This is the current k3 reconstruction, not unavailable original bf16 weights.
3281
- M1 computes the complete singular spectrum with pinned MLX's CPU SVD.
3282
- The spectrum's squared sum agrees with direct f64 matrix energy within
3283
- 3.8e-8 relative error.
3284
-
3285
- | Rank | bf16 factor bytes | Best unweighted squared reconstruction error |
3286
- |---|---:|---:|
3287
- | 128 | 5,767,168 | 84.59% |
3288
- | 256 | 11,534,336 | 75.95% |
3289
- | 512 | 23,068,672 | 63.11% |
3290
- | 741 | 33,386,496 | 54.19% |
3291
- | 1024 | 46,137,344 | 45.17% |
3292
- | 2048 | 92,274,688 | 23.09% |
3293
- | 4096 | 184,549,376 | 3.42% |
3294
-
3295
- These are ideal unweighted truncation errors before factor quantization.
3296
- A rank that beats raw W3 bytes has large error on this matrix. Do not build a
3297
- whole-model plain-SVD format from this result. Activation-aware factorization,
3298
- other layers and actual task quality remain unmeasured.
3299
-
3300
- A second M1 screen takes 64 uniformly spaced rows of the same matrix, retaining
3301
- all 5120 columns per row, and re-encodes them with the existing unweighted
3302
- L12/k2/T256 tail-biting codec. Sparse corrections select the largest individual
3303
- squared errors. The error bound assumes exact residual recovery while charging
3304
- six bytes per entry; actual fp16 residual rounding, row indexes and sparse
3305
- execution can only add costs/error relative to that bound.
3306
-
3307
- | Corrected density | Effective bits/weight | Remaining squared error relative to current k3 |
3308
- |---|---:|---:|
3309
- | 0% | 2.0031 | 7.3684% |
3310
- | 0.1% | 2.0510 | 7.2675% |
3311
- | 0.5% | 2.2431 | 6.9977% |
3312
- | 1% | 2.4830 | 6.7328% |
3313
- | 2% | 2.9630 | 6.2937% |
3314
-
3315
- The near-three-bit arm leaves substantial additional error for little size
3316
- saving. It is not selected for a model conversion. This small unweighted
3317
- sample does not settle activation-calibrated sparse methods, original-weight
3318
- recovery, other matrices or whole-model quality. No sparse speedup is claimed.
3319
-
3320
- On M4, differentiating the actual packed matrix through its current forward
3321
- fails at M=1/4/16 with the native missing `CustomKernel` VJP error. Differentiating
3322
- the same frozen matrix after bf16 expansion succeeds with a gradient of shape
3323
- `[1,5120]`. This identifies a missing packed backward operation, rather than
3324
- an inability to train any adapter. The packed model also explicitly excludes
3325
- Trellis MLPs from `loraTargets()`. Expanded backwards require the temporary
3326
- memory already included in the resource screen; no training option is added.
3327
-
3328
- Sources remain `6fe0a7f`. Reports: `r24-mlp-layer1-gate.f32.json`,
3329
- `r24-low-rank-spectrum.json`, `r24-mlp-sample.json`,
3330
- `r24-sparse-residual-screen.json`, `r24-packed-gradient-m4.json` and
3331
- `completed-r24-weight-screen-tool-sources.json`, all under
3332
- `reports/prefill-observation/`. The raw matrix, sampled rows, full spectrum,
3333
- failed runner-API attempt and native errors are preserved.
3334
-
3335
- ## Shared echo verification on M4 Pro (2026-09-13)
3336
-
3337
- Shared fill now supplies copied-session proposals to the existing grouped target
3338
- verifier. This is opt-in `MLX_BUN_FILL=echo`, compared with shared `strict` on
3339
- identical source. It is not an MTP or default-serving TPS comparison.
3340
-
3341
- M4 Pro 24 GB, Bun 1.4.2, native pack 0.4.0 / MLX 0.32.2; packed
3342
- `Qwen3.8-27B-q3-trellis-ldlq-k300-packed-interleave2-rd`, KV4/group64,
3343
- fixed 256-token prefill, compiled decode off, no drafter, default batch cap
3344
- eight, 1 GiB RAM cache and 4 GiB SSD budget. Requests use temperature zero,
3345
- seed 42 and thinking disabled. Four fresh CLI servers run strict/echo/echo/strict.
3346
- Each arm contains a first request, three repetitions of four saved tool
3347
- fixtures, a seeded repeat, ordinary prose with tools, four concurrent requests
3348
- and a new-process SSD restart. Tools are not executed. Full requests, SSE,
3349
- source hashes and activity samples are retained.
3350
-
3351
- The repeated comparison contains **80 responses, 38 measured pairs plus two
3352
- first-request pairs**. All 38 measured pairs preserve response text, parsed
3353
- tool arguments, finish reason and complete usage apart from the intended fill
3354
- counters. All first-request pairs also match. Every response uses the batched
3355
- lane. All four final flushes are durable with zero missing, pending, dropped or
3356
- failed writes; the four restarted servers successfully reuse stored state.
3357
-
3358
- Per-fixture medians over three repetitions, in milliseconds:
3359
-
3360
- | Fixture | Strict → echo, AB | Change | Strict → echo, BA | Change |
3361
- |---|---:|---:|---:|---:|
3362
- | Copy sentence | 3051.96 → 2672.91 | −12.42% | 3060.71 → 2690.29 | −12.10% |
3363
- | Copy URL | 4884.43 → 2861.68 | −41.41% | 4879.74 → 2891.76 | −40.74% |
3364
- | First saved suite call | 1583.26 → 1562.26 | −1.33% | 1572.13 → 1612.07 | +2.54% |
3365
- | Following saved suite call | 1909.70 → 1889.51 | −1.06% | 1922.13 → 1882.03 | −2.09% |
3366
-
3367
- The sentence accepts nine echo tokens and the URL accepts thirty, each in one
3368
- verification event with no rejected tokens. The two suite fixtures accept no
3369
- echo tokens. Ordinary prose changes −1.04%/−1.33%. The final completion of the
3370
- four concurrent requests changes 7104.49→5751.98 ms (−19.04%) and
3371
- 6967.29→5505.37 ms (−20.98%); these are request completion measurements, not
3372
- proof of a fixed four-row GPU geometry. First copy requests change
3373
- 7726.29→7149.52 ms and 7481.18→7156.00 ms, including initial setup.
3374
-
3375
- All arms finish with six RAM entries/960,970,752 bytes, ten SSD
3376
- entries/1,611,411,552 bytes and eleven restores. Sampled peak server RSS is
3377
- 13,195.67→13,279.28 MiB and 13,241.59→13,199.47 MiB. The 66 activity samples
3378
- include substantial Codex-renderer CPU activity; one contains a remaining
3379
- headless-browser/test process. Retained swap ranges 3493.00–4576.25 MiB.
3380
- These remain diagnostics with recorded machine activity, not quiet standard
3381
- suite numbers. The repeat supports a targeted copy-span benefit; fill remains
3382
- off by default and general task benefit is unmeasured.
3383
-
3384
- The first identical-source ABBA is preserved separately: all 38 measured
3385
- response/usage pairs also match, but sentence timing changes +22.71%/−20.80%,
3386
- URL −12.98%/−46.70%, and the suite controls swing +51.32%/−13.88% and
3387
- +37.74%/−11.36%. Headless Chromium and Node/Vitest workloads appear in its
3388
- 71 activity samples; swap grows from 4237.44 to 6689.94 MiB and peaks at
3389
- 7653.12 MiB. This prompted the unchanged-source repeat after those workloads
3390
- finished. It supplies correctness evidence, not a speed-selection result.
3391
- Neither run changes production source during execution.
3392
-
3393
- ### Shared echo state and template-boundary acceptance
3394
-
3395
- M1 Qwen0.8B/Gemma-e4b and M4 packed Qwen27B each pass 15 native cases across
3396
- B1/B2/B4, bf16/KV4/k8v3 and delayed quantization. The audit compares samplers on
3397
- the same logits and processor history; it covers rejected and mixed proposals
3398
- and stopping inside a verified span. Published token keys match consumed
3399
- state. B2 SSD reopening preserves all live state and two subsequent logit
3400
- vectors against the retained RAM clone. Gemma sliding-window layers remain
3401
- bf16 in the TurboQuant arm. The original 21-case strict-fill replay also passes
3402
- on M1 without changing its assertions. New model-free verified-output cases
3403
- cover EOS, length limits, consumer stop/failure and cancellation independently
3404
- of sibling rows.
3405
-
3406
- Actual HTTP copy/seeded-concurrency/follow-up/restart tests pass six cases each
3407
- on M1 Qwen0.8B/Gemma-e4b and M4 packed Qwen27B, covering RAM and SSD with all
3408
- three cache formats. They exposed a separate template-boundary miss on
3409
- Qwen0.8B: the initial 305-token prompt shares only 301 tokens with the next
3410
- rendered tool turn, because the template omits its empty thinking primer.
3411
- The previous 304-token recurrent snapshot could not match. Probing text and
3412
- tool replies followed by a new user turn now retains the reusable 301-token
3413
- boundary. Existing KV is never relabeled under different tokens. Packed Qwen's
3414
- fixture already reused its generated history; both behaviors are retained in
3415
- the evidence.
3416
-
3417
- An early wide-verification versus sequential-output comparison produced
3418
- changed sampled tokens. It is preserved as an unmatched numerical-geometry
3419
- experiment; echo does not promise identical samples to one-position decoding.
3420
- All 2,367 model-free tests pass with 14 fixture skips, and typechecks and hygiene
3421
- pass. Reports are under `reports/prefill-observation/`: `shared-echo-*`,
3422
- `completed-echo-cache-inspection.json` and the completed echo tool-source
3423
- archive. Sources are `cb408ec` plus the captured implementation diff; every
3424
- production file hash is stored in each HTTP report.
3425
-
3426
- ### Mixed echo cohorts and independent greedy sampling
3427
-
3428
- A source-controlled M4 Pro ABBA compares `d893afb` with ordinary rows joining
3429
- verified echo spans and the existing independent greedy sampler enabled in
3430
- that method. Both arms use echo and the settings above. Only `fill-group.ts`
3431
- changes between arms; the candidate is restored afterward and the source audit
3432
- finds no unexpected changes. All 80 responses complete, all 38 measured pairs
3433
- and both first-request pairs preserve responses and full usage apart from fill
3434
- counters, and all four SSD flush/restart checks pass with clean server exits.
3435
-
3436
- | Fixture | Control → candidate AB, ms | Change | Control → candidate BA, ms | Change |
3437
- |---|---:|---:|---:|---:|
3438
- | Copy sentence | 2657.24 → 2657.33 | +0.00% | 2659.77 → 2675.60 | +0.60% |
3439
- | Copy URL | 2862.60 → 2878.90 | +0.57% | 2852.66 → 2859.32 | +0.23% |
3440
- | First saved suite call | 1577.26 → 1553.15 | −1.53% | 1575.84 → 1555.43 | −1.30% |
3441
- | Following saved suite call | 1887.28 → 1894.08 | +0.36% | 1895.86 → 1878.38 | −0.92% |
3442
- | Four concurrent requests, last completion | 5619.97 → 5355.71 | −4.70% | 5461.38 → 5391.45 | −1.28% |
3443
-
3444
- Sequential copy performance is effectively unchanged. One concurrent suite
3445
- request completes later in both orders: 3664.40→4262.67 ms and
3446
- 3482.71→4311.00 ms. This is a throughput/latency tradeoff, not domination of
3447
- every row. Ordinary prose changes −0.04%/−0.14%; first-copy setup changes
3448
- −1.31%/−1.07%. The candidate persists eleven entries instead of ten; all final
3449
- flushes report zero missing, pending, dropped or failed writes. Retain mixed
3450
- verification as part of opt-in echo, with no default change or additional
3451
- Kanban speed claim.
3452
-
3453
- The 61 activity samples contain renderer CPU work in 57 top-CPU positions.
3454
- Retained swap ranges 4163.44–4814.25 MiB. Sampled peak server RSS is
3455
- 13,283.00→13,208.25 MiB and 13,288.22→13,241.27 MiB. These are monitored
3456
- serving diagnostics, not quiet standard-suite numbers.
3457
-
3458
- Native sampling/state checks pass all fifteen Qwen cases on both Macs, plus
3459
- five Gemma B2 formats on M1. Mixed cases now require actual verification events.
3460
- A final staggered-proposal check passes KV4 B2 and k8v3 B4 on each machine,
3461
- including SSD state and subsequent logits. It covers a proposal discovered
3462
- while another row publishes pending output; the method retains its remainder
3463
- without exceeding declared scheduler work. Unit coverage also preserves newly
3464
- discovered asserted spans. All 2,369 model-free tests pass with 14 fixture skips;
3465
- typechecks and documentation checks pass. Reports: `shared-echo-mixed-*` and
3466
- `shared-echo-staggered-*` under `reports/prefill-observation/`.
3467
-
3468
- ### Qwen echo with MTP2 — M4 Pro 24 GB
3469
-
3470
- A same-source ABBA compares MTP2 with fill off against MTP2 plus opt-in echo.
3471
- Both use the packed interleaved 27B artifact, folded RTN4 companion, KV4/g64,
3472
- fixed 256-token prefill, shared cap eight, temperature zero and seed 42.
3473
- RAM cache is 1 GiB and each arm starts with a fresh 4 GiB SSD cache. All eighty
3474
- responses complete. The 38 measured pairs and two first-request pairs preserve
3475
- response content and every usage field except the intended fill/speculation
3476
- counters. All four SSD flush/restart checks complete with zero missing, pending,
3477
- dropped or failed snapshots. Source hashes remain unchanged throughout.
3478
-
3479
- | Fixture | Control → echo AB, ms | Change | Control → echo BA, ms | Change |
3480
- |---|---:|---:|---:|---:|
3481
- | Copy sentence | 1766.58 → 1966.74 | +11.33% | 1738.50 → 1969.18 | +13.27% |
3482
- | Copy URL | 2629.95 → 2209.76 | −15.98% | 2546.08 → 2241.72 | −11.95% |
3483
- | First saved suite call | 1312.27 → 1299.75 | −0.95% | 1289.74 → 1321.01 | +2.42% |
3484
- | Following saved suite call | 961.17 → 944.71 | −1.71% | 945.76 → 944.63 | −0.12% |
3485
-
3486
- Echo remains opt-in. A longer copied URL benefits; the short sentence loses.
3487
- The initial implementation verified unproven 32-token proposals and paid for
3488
- immediate rejection. That comparison is retained as a failed candidate. The
3489
- final method first checks ordinary MTP output against the proposed prefix;
3490
- a first-token rejection requires no extra target forward. This avoids the
3491
- large rejected-span cost but does not make every short copy profitable.
3492
- These are serving diagnostics with recorded background activity, not quiet
3493
- standard-suite numbers or a full-task speed claim.
3494
-
3495
- Both Macs pass the companion's external-token operation against the pinned
3496
- same-machine oracle. Shared native tests cover seeded sampling, independent
3497
- rows, partial stops, first-token rejection, KV4/TurboQuant, delayed conversion,
3498
- paired SSD state and subsequent logits. Final M1 KV4 B2 and M4 KV4 B2/B4 and
3499
- TurboQuant B2 checks pass after the prefix policy change. Real HTTP checks
3500
- cover bf16/KV4/TurboQuant and RAM/SSD, including fresh-process restoration.
3501
- All 2,372 model-free tests pass with 14 fixture skips; typechecks and docs pass.
3502
- Reports: `reports/prefill-observation/echo-mtp-*`. Each report captures source
3503
- hashes over `c119661` plus the integration diff. The full Kanban comparison
3504
- retains the prior MTP2/fixed-256 profile and adds echo.
3505
-
3506
- Completed benchmark SSD payloads were deleted during workspace cleanup after
3507
- their measurements and restore checks. Cleanup manifests record each removed
3508
- path and size; transcripts, measurements, source manifests and generated apps
3509
- remain. Historical SSD cache directories require regeneration before reuse.
3510
-
3511
- ### Full Kanban task with echo and MTP2 — M4 Pro 24 GB
3512
-
3513
- The requested fresh task runs on `7966b92` through Pi 0.85.1, Node 23.11.0,
3514
- Bun 1.4.2 and the released native pack. Qwen chooses the tool calls; Pi executes
3515
- them. The task starts in an empty directory with the same original prompt and
3516
- initial request as the accepted fixed-prefill run. Both use the packed 27B
3517
- artifact, folded RTN4 MTP companion, two draft tokens, KV4/g64, fixed 256-token
3518
- prefill, default shared cap eight, seed 42, temperature 0.6, top-p 0.95,
3519
- top-k 20, xhigh thinking, 131,072 context, 4 GiB RAM cache and 64 GiB SSD cache.
3520
- The new run enables echo. Its integrated source also includes the changes since
3521
- `721ac4c`; this is a whole-task observation, not a source-isolated echo A/B.
3522
-
3523
- | Measurement | Previous fixed-prefill task | Echo + MTP2 task |
3524
- |---|---:|---:|
3525
- | Task wall time | 69m52.768s | 82m55.067s |
3526
- | Generated tokens | 67,816 | 76,089 |
3527
- | Requests | 17 | 25 |
3528
- | Observed streaming tokens/sec | 16.4908 | 16.4774 |
3529
- | Sum of first-output waits | 75.877s | 316.757s |
3530
- | First response tokens | 35,002 | 39,039 |
3531
- | Follow-up session cache hits | 16/16 | 24/24 |
3532
- | Inference failures / retries / compactions | 0 / 0 / 0 | 0 / 0 / 0 |
3533
- | Failed model-chosen shell checks | 0 | 7 |
3534
- | Untouched-app browser acceptance | 17/18 | 17/18 |
3535
-
3536
- Streaming rate uses total completion tokens divided by the sum of each
3537
- request's stream wall time minus its first semantic-output wait, as in the
3538
- previous report. First-output waits include more than prefill and must not be
3539
- labeled pure prefill time. Tool arguments can remain buffered while generation
3540
- continues. A one-second process sample during such a pause shows active native
3541
- evaluation; the sample is retained with the activity log.
3542
-
3543
- The observed rate changes −0.08%, effectively flat. The task takes 18.66%
3544
- longer and generates 12.20% more tokens. Responses diverge during the first
3545
- reasoning turn despite identical initial inputs; later requests and work differ.
3546
- This run establishes no task-speed win for echo, which remains opt-in.
3547
-
3548
- Echo records 19,147 matched tokens in 1,151 wide verification events, with
3549
- 27,415 rejected proposed tokens. Matched prefixes include tokens established
3550
- by ordinary MTP sampling; they are not an additive count of avoided decodes.
3551
- The first response alone records 6,047 matches. Learned-draft statistics stay
3552
- separate. Total checkpoint bookkeeping is 1.144 seconds; this is not the full
3553
- cost of verification or companion consumption.
3554
-
3555
- All 24 follow-ups reuse the session cache. Final flush is durable with zero
3556
- missing, pending, dropped or failed snapshots. Fifty writes leave 38 resident
3557
- SSD entries totaling 68,652,904,448 bytes under the explicit 64 GiB budget;
3558
- the longest retained prefix is 82,800 tokens. Older SSD entries are removed
3559
- under that budget. Final RAM residency is one 2,019,268,608-byte entry. Production
3560
- source hashes remain unchanged for the complete task and settings checks pass.
3561
- After the server exits, the runner removes disposable SSD payloads and retains
3562
- a per-file cleanup manifest, cache metadata, full transcripts and the app.
3563
-
3564
- The seven failed shell checks belong to Qwen's generated test script: one
3565
- relative module lookup from `/tmp`, one incorrect description-search assertion,
3566
- two incorrect persisted-shape assertions, one invalid `window.localStorage`
3567
- mock reset, and two missing `window.Kanban.state` mock setups. The description
3568
- query matched both test cards; the script incorrectly expected only one.
3569
- Persisted counts expected two where there were three. The model corrected its
3570
- test script. These command failures are distinct from inference failures.
3571
-
3572
- Independent browser evaluation on M1, after generation ends, passes 17 of the
3573
- same 18 categories and meets the requested 16/18 target. The new app passes
3574
- filter reset, which failed previously. Keyboard-only card editing now fails:
3575
- cards have no keyboard focus target and Enter does not open their editor.
3576
- Keyboard creation and mouse editing work. Native column/card dragging, Done
3577
- indication, full card fields, archive/restore, title/description search,
3578
- combined filters, reload persistence and both themes pass. All ten generated
3579
- source files remain byte-identical throughout evaluation. No repair prompt or
3580
- manual app edit is supplied. Initial favicon 404 only; final browser console
3581
- has no errors. Evaluator locator mistakes are recorded separately.
3582
-
3583
- Reports, full responses, source hashes, quality protocol and screenshots:
3584
- `reports/kanban-echo-mtp-r1/`. Previous report:
3585
- `reports/kanban-decode-fixed-prefill-r1/`. Both task trajectories, including the
3586
- failed checks, remain available. Completed benchmark KV cleanup removes
3587
- 215.31 GiB on M4 and 63.76 GiB on M1; model artifacts, transcripts and apps stay.