mlx-bun 0.3.0 → 0.5.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 (231) hide show
  1. package/README.md +57 -32
  2. package/docs/README.md +58 -42
  3. package/docs/archive/investigations/benchmark-ledger-through-v0.4.0.md +3617 -0
  4. package/docs/archive/investigations/openjarvis-fit.md +198 -0
  5. package/docs/archive/investigations/qwen38-27b-campaign-log.md +1092 -0
  6. package/docs/archive/planning/release-notes-v0.4.0.md +45 -0
  7. package/docs/archive/planning/release-notes-v0.5.0.md +37 -0
  8. package/docs/design/batching.md +1535 -50
  9. package/docs/design/decode-speed-program.md +394 -1171
  10. package/docs/design/generic-model-support.md +195 -3
  11. package/docs/design/kv-cache.md +538 -225
  12. package/docs/design/speculative-decoding.md +552 -50
  13. package/docs/design/turboquant.md +140 -17
  14. package/docs/design/unified-engine-frontier-plan.md +259 -150
  15. package/docs/planning/PRODUCT_ROADMAP.md +21 -6
  16. package/docs/planning/public-readiness-handoff.md +244 -0
  17. package/docs/planning/public-readiness.md +149 -0
  18. package/docs/reference/benchmarks.md +3537 -1112
  19. package/docs/reference/cli.md +102 -2
  20. package/docs/reference/distribution.md +45 -13
  21. package/docs/reference/environment.md +159 -13
  22. package/docs/reference/library-api.md +18 -4
  23. package/docs/reference/memory.md +1 -1
  24. package/docs/reference/models.md +28 -7
  25. package/docs/reference/server-api.md +257 -33
  26. package/docs/reference/server-config.md +372 -151
  27. package/docs/reference/troubleshooting.md +13 -21
  28. package/package.json +2 -2
  29. package/src/audio/audiotoolbox.ts +112 -0
  30. package/src/audio/conformer.ts +8 -0
  31. package/src/audio/mic-capture.ts +98 -0
  32. package/src/audio/silero-vad.ts +379 -0
  33. package/src/audio/whisper-decode.ts +774 -0
  34. package/src/audio/whisper-fast.ts +732 -0
  35. package/src/audio/whisper-format.ts +73 -0
  36. package/src/audio/whisper-mel.ts +185 -0
  37. package/src/audio/whisper-timing.ts +274 -0
  38. package/src/audio/whisper-tokenizer.ts +239 -0
  39. package/src/audio/whisper-transcribe.ts +410 -0
  40. package/src/backends/mlx/assistant-target.ts +46 -0
  41. package/src/backends/mlx/autoregressive-draft-rows.ts +120 -0
  42. package/src/backends/mlx/autoregressive.ts +22 -1
  43. package/src/backends/mlx/batch-group.ts +464 -236
  44. package/src/backends/mlx/cache-attachment.ts +67 -0
  45. package/src/backends/mlx/cache-layout.ts +31 -0
  46. package/src/backends/mlx/checkpoint-state.ts +53 -0
  47. package/src/backends/mlx/continuation-persistence.ts +107 -0
  48. package/src/backends/mlx/continuation-request.ts +43 -0
  49. package/src/backends/mlx/continuation.ts +77 -0
  50. package/src/backends/mlx/draft-target.ts +7 -22
  51. package/src/backends/mlx/encoder-cache.ts +25 -0
  52. package/src/backends/mlx/fill-append.ts +21 -8
  53. package/src/backends/mlx/fill-group.ts +497 -0
  54. package/src/backends/mlx/full-kv-row-append.ts +32 -0
  55. package/src/backends/mlx/full-kv-row-donor.ts +54 -0
  56. package/src/backends/mlx/full-transitioning-kv-rows.ts +65 -0
  57. package/src/backends/mlx/gateway-binding.ts +122 -19
  58. package/src/backends/mlx/kv-codec.ts +9 -0
  59. package/src/backends/mlx/kv-maintenance.ts +161 -0
  60. package/src/backends/mlx/kv-tensor-rows.ts +212 -0
  61. package/src/backends/mlx/mixed-iteration.ts +62 -0
  62. package/src/backends/mlx/model-prompt.ts +46 -32
  63. package/src/backends/mlx/model-serving.ts +5 -4
  64. package/src/backends/mlx/paged-cache-codec.ts +27 -0
  65. package/src/backends/mlx/prefill-cohort.ts +100 -0
  66. package/src/backends/mlx/prefill-policy.ts +26 -0
  67. package/src/backends/mlx/prefill-rows.ts +244 -0
  68. package/src/backends/mlx/prefill.ts +1 -1
  69. package/src/backends/mlx/projected-context-rows.ts +72 -0
  70. package/src/backends/mlx/prompt-input.ts +29 -0
  71. package/src/backends/mlx/qwen-prompt-input.ts +40 -0
  72. package/src/backends/mlx/request-state-policy.ts +54 -0
  73. package/src/backends/mlx/rollback.ts +45 -4
  74. package/src/backends/mlx/row-sampling.ts +49 -0
  75. package/src/backends/mlx/serial-executor.ts +51 -73
  76. package/src/backends/mlx/speculative-group.ts +438 -0
  77. package/src/backends/mlx/speculative-round.ts +161 -0
  78. package/src/backends/mlx/speculative.ts +24 -7
  79. package/src/backends/mlx/state-rows.ts +104 -0
  80. package/src/backends/mlx/state-views.ts +21 -1
  81. package/src/backends/mlx/target-layout-capability.ts +35 -0
  82. package/src/backends/mlx/transitioning-kv-rows.ts +173 -0
  83. package/src/cli.ts +333 -36
  84. package/src/contracts/execution.ts +21 -0
  85. package/src/contracts/object-cache.ts +8 -0
  86. package/src/contracts/pi-provider.ts +1 -1
  87. package/src/contracts/pi.ts +3 -1
  88. package/src/contracts/prefix-cache.ts +33 -0
  89. package/src/contracts/resources.ts +7 -0
  90. package/src/contracts/sampling.ts +23 -0
  91. package/src/contracts/scheduling.ts +27 -0
  92. package/src/engine/execution-plan.ts +38 -25
  93. package/src/engine/execution-tasks.ts +44 -0
  94. package/src/engine/namespaced-cache.ts +13 -0
  95. package/src/engine/resources.ts +12 -1
  96. package/src/engine/scheduler.ts +32 -7
  97. package/src/fill/fill-session.ts +14 -3
  98. package/src/fit.ts +29 -15
  99. package/src/generate.ts +105 -195
  100. package/src/grammar.ts +13 -0
  101. package/src/inference/draft-acceptance.ts +41 -0
  102. package/src/inference/draft-output.ts +49 -0
  103. package/src/inference/prefill.ts +6 -0
  104. package/src/inference/rollback.ts +2 -2
  105. package/src/kv-scheme.ts +92 -12
  106. package/src/kv-store.ts +183 -93
  107. package/src/lab/README.md +5 -1
  108. package/src/lab/paged-kv/paged-attention.ts +117 -0
  109. package/src/lab/paged-kv/paged-kv-rows.ts +111 -0
  110. package/src/lab/paged-kv/paged-kv.ts +126 -46
  111. package/src/md-modules.d.ts +5 -0
  112. package/src/mlx/array.ts +39 -1
  113. package/src/mlx/ffi.ts +19 -0
  114. package/src/mlx/normalized-argmax.ts +116 -0
  115. package/src/mlx/ops.ts +97 -10
  116. package/src/model/artifact-identity.ts +73 -0
  117. package/src/model/batched-kv.ts +235 -0
  118. package/src/model/batched-mask.ts +12 -4
  119. package/src/model/batched-quant.ts +8 -2
  120. package/src/model/batched-quantized-kv.ts +144 -0
  121. package/src/model/batched-rotating-quant.ts +76 -15
  122. package/src/model/batched-rotating-state.ts +76 -0
  123. package/src/model/batched-rotating.ts +64 -22
  124. package/src/model/batched-row-storage.ts +52 -0
  125. package/src/model/batched-ssm.ts +52 -0
  126. package/src/model/batched-turboquant-kv.ts +94 -0
  127. package/src/model/compiled-decode.ts +7 -1
  128. package/src/model/decoded-kv-donor.ts +12 -0
  129. package/src/model/delayed-quantized-kv.ts +72 -0
  130. package/src/model/delayed-rotating-quantized-kv.ts +93 -0
  131. package/src/model/delayed-turboquant-kv.ts +57 -0
  132. package/src/model/factory.ts +26 -0
  133. package/src/model/fingerprint.ts +12 -0
  134. package/src/model/full-prefill-padding.ts +56 -0
  135. package/src/model/full-prefill-row.ts +105 -0
  136. package/src/model/gemma4-base.ts +183 -82
  137. package/src/model/gemma4.ts +116 -28
  138. package/src/model/generated/gemma4-12b.ts +4 -1
  139. package/src/model/generated/gemma4-26b.ts +4 -1
  140. package/src/model/generated/gemma4-e4b.ts +4 -1
  141. package/src/model/glm52-cache.ts +80 -4
  142. package/src/model/glm52-mla.ts +12 -6
  143. package/src/model/glm52.ts +19 -40
  144. package/src/model/kv-attention-view.ts +70 -0
  145. package/src/model/minicpm5.ts +11 -7
  146. package/src/model/profile.ts +29 -4
  147. package/src/model/quantized-append-attention.ts +31 -0
  148. package/src/model/qwen3-delta-state.ts +74 -0
  149. package/src/model/qwen3-delta.ts +59 -36
  150. package/src/model/qwen3-mrope.ts +7 -9
  151. package/src/model/qwen3_5.ts +177 -75
  152. package/src/model/rotating-kv-donor.ts +35 -0
  153. package/src/model/rotating-kv-layout.ts +262 -0
  154. package/src/model/rotating-row-transaction.ts +35 -0
  155. package/src/model/speculative-rotating-kv.ts +101 -0
  156. package/src/model/ssm-prefill-padding.ts +39 -0
  157. package/src/model/support.ts +8 -0
  158. package/src/model/token-groups.ts +66 -0
  159. package/src/model/trellis-linear.ts +4 -4
  160. package/src/model/turboquant-codec.ts +89 -0
  161. package/src/model/universal/dense.ts +14 -13
  162. package/src/model/whisper.ts +435 -0
  163. package/src/native/mic_capture.swift +92 -0
  164. package/src/native-pack.ts +6 -5
  165. package/src/pi-web.ts +9 -1
  166. package/src/preflight.ts +31 -15
  167. package/src/prompt-cache.ts +306 -86
  168. package/src/runtime-config.ts +1 -5
  169. package/src/safetensors.ts +9 -2
  170. package/src/sampler.ts +37 -25
  171. package/src/serve/audio-routes.ts +323 -0
  172. package/src/serve/chat-request.ts +2 -0
  173. package/src/serve/chat-stage.ts +19 -14
  174. package/src/serve/completion-executor.ts +9 -1
  175. package/src/serve/discovery-routes.ts +17 -1
  176. package/src/serve/generated-token-history.ts +57 -0
  177. package/src/serve/generation-gateway.ts +88 -38
  178. package/src/serve/model-binding.ts +7 -1
  179. package/src/serve/model-host.ts +3 -4
  180. package/src/serve/preparation.ts +3 -3
  181. package/src/serve/prompt-response-trace.ts +14 -0
  182. package/src/serve/request-plan.ts +6 -3
  183. package/src/serve/request-prep.ts +40 -25
  184. package/src/serve/text-completion-stage.ts +2 -2
  185. package/src/serve/transcription-server.ts +64 -0
  186. package/src/serve/transcription-service.ts +502 -0
  187. package/src/server.ts +185 -261
  188. package/src/spec/assistant-rows.ts +93 -0
  189. package/src/spec/assistant-source.ts +28 -18
  190. package/src/spec/cache-identity.ts +22 -0
  191. package/src/spec/deepspec-rows.ts +29 -0
  192. package/src/spec/deepspec-source.ts +12 -10
  193. package/src/spec/dflash-source.ts +28 -4
  194. package/src/spec/drafter.ts +153 -142
  195. package/src/spec/dspark/deepspec-module.ts +95 -120
  196. package/src/spec/dspark/module-dflash.ts +126 -170
  197. package/src/spec/glm52-mtp-graph.ts +29 -0
  198. package/src/spec/glm52-mtp-rows.ts +132 -0
  199. package/src/spec/glm52-mtp-source.ts +54 -136
  200. package/src/spec/glm52-mtp-state.ts +33 -0
  201. package/src/spec/ngram-source.ts +115 -21
  202. package/src/spec/projected-draft-rows.ts +73 -0
  203. package/src/spec/qwen-mtp-module.ts +171 -0
  204. package/src/spec/qwen-mtp-rows.ts +230 -0
  205. package/src/spec/qwen-mtp-source.ts +84 -226
  206. package/src/spec/qwen-mtp-state.ts +30 -0
  207. package/src/spec/serve-loop.ts +73 -69
  208. package/src/spec/source.ts +93 -15
  209. package/src/spec/two-model-rows.ts +62 -0
  210. package/src/spec/two-model.ts +45 -103
  211. package/src/ssd-cache.ts +107 -36
  212. package/src/ssd-durability.ts +29 -27
  213. package/src/storage/host-buffer.ts +24 -0
  214. package/src/storage/kv-writer.ts +83 -0
  215. package/src/storage/kv-writer.worker.js +264 -0
  216. package/src/storage/retention-policy.ts +37 -0
  217. package/src/tiered-prompt-cache.ts +45 -0
  218. package/src/vision/embedder.ts +8 -0
  219. package/src/vision/prompt.ts +101 -65
  220. package/src/vision/qwen3vl-prompt.ts +101 -64
  221. package/src/vision/qwen3vl-tower.ts +11 -0
  222. package/src/vision/siglip.ts +8 -0
  223. package/src/web/app.html +12 -0
  224. package/src/web/app.js +217 -57
  225. package/src/web/src/chat.ts +4 -1
  226. package/src/web/src/composer.ts +3 -0
  227. package/src/web/src/voice.ts +141 -0
  228. package/src/web/sw.js +1 -1
  229. package/src/backends/mlx/memory-guard.ts +0 -40
  230. package/src/spec/prefix-state.ts +0 -45
  231. /package/docs/{planning → archive/planning}/release-notes-v0.3.0.md +0 -0
@@ -139,15 +139,16 @@ Code map:
139
139
  single conversion chokepoint (serve serial lane + generate + eval all flow
140
140
  through it); `TurboQuantKVCache.fromKVCache`; `RotatingKVCache` layers stay
141
141
  bf16 with a one-time warning; keeps the `quantizedKvStart` semantics.
142
- - `src/server.ts` — startup refusals: `--batch N` + turbo (serial-only);
143
- head_dim not in `TURBOQUANT_HEAD_DIMS` (fail-fast at `createServer`, not on
144
- first append — 2026-07-07 review); `--draft-model` + any quantized KV warns
145
- and those requests decode serially WITHOUT speculation (spec-eligibility
146
- gate excludes `turboQuant`; the spec loop builds fresh bf16 caches and would
147
- otherwise silently drop the scheme). `turboQuant` and `kvQuant` are
148
- mutually exclusive (turbo wins with a warning).
149
- - `src/serve/generation-gateway.ts` — explicit solo-only refusal in
150
- placement (belt + braces on top of the instanceof exclusion).
142
+ - `src/backends/mlx/kv-codec.ts` and `src/model/turboquant-codec.ts` separate
143
+ encoding and existing fused kernel selection from storage membership.
144
+ - `KvTensorRows` owns arbitrary encoded planes; `BatchedTurboQuantKVCache`
145
+ binds the five TQ planes to shared positions and a rotated-value attention
146
+ port. Gemma owns pre-write row positions across cache appends and releases
147
+ shared positions with the shared attention state.
148
+ - `src/backends/mlx/cache-layout.ts` supplies ordinary and target-transaction
149
+ layouts. The gateway binds start-zero TQ and grouped Qwen MTP capabilities;
150
+ the scheduler only chooses work. Server head-dimension validation remains.
151
+ `turboQuant` and `kvQuant` are mutually exclusive.
151
152
  - `src/kv-store.ts` — `CacheKind "turboquant"`; header carries kBits/vBits
152
153
  + head_dim; snapshot/restore/clone branches.
153
154
  - `src/model/fingerprint.ts` — NOT touched, by symmetry: uniform
@@ -356,7 +357,7 @@ Gemma-4-e4b's D512 deferred consumer also passes: 20 forward/state cases, four
356
357
  generations and 1,220 matching cache reads, one specialization and 1,057,864
357
358
  final active bytes per arm. Evidence: tq-kv-gemma-e4b-full{,-review}.json.
358
359
 
359
- The joint decoder is now integrated as an experimental opt-in. The environment
360
+ The joint decoder was initially integrated as an experimental opt-in. The environment
360
361
  setting and supported inputs are documented in server-config.md. A shared
361
362
  `src/mlx/turboquant-kv-decode.ts` owns only the packed Metal operation; the existing
362
363
  codec owns inverse rotation and the cache captures operation selection once.
@@ -516,8 +517,8 @@ longer prompt. Sampled RSS establishes no reduction. The server-exit observer
516
517
  still sees resident model arrays, so its active capacity is not a disposal-to-
517
518
  zero test. Native operation and full-model ownership gates remain separate.
518
519
  These are M4 Pro 24 GB diagnostics with k8v3, greedy seed 42 and 128 generated
519
- tokens. TurboQuant KV requires serial placement in the existing execution
520
- planner. Evidence: mlx-upgrade-0.32.2/deferred-kv-http{,-review}.json. This closes
520
+ tokens. Those measurements used serial placement; shared integration is covered below.
521
+ Evidence: mlx-upgrade-0.32.2/deferred-kv-http{,-review}.json. This closes
521
522
  the deferred-model serving comparison; broader pressure and quiet gates remain.
522
523
 
523
524
  Direct packed-key attention is closed as an additional speed candidate. A
@@ -580,18 +581,78 @@ upstream/mlx-0.31.2; the closed research helpers are removed.
580
581
  4. Whole-repo `tsc --noEmit` = 0; fast suite green; turbo requests route
581
582
  serial with a clear reason.
582
583
 
584
+ The Phase 18 composition is integrated in the unreleased working tree;
585
+ `~/.cache/mlx-bun/turboquant-composition-validation` remains a frozen comparison.
586
+ It extracts the existing
587
+ encode/decode operations behind a KV codec interface and applies that codec to
588
+ one owner of five tensor fields with shared row positions. Merge, retirement,
589
+ rollback and extraction operate on encoded bytes. A rotated-value attention
590
+ port lets Gemma and MiniCPM consumers retain the existing deferred inverse
591
+ rotation with either storage layout.
592
+
593
+ On M1 Max and M4 Pro, the focused codec/kernel/row checks pass 29 tests and
594
+ 2,828 assertions. A native Qwen target test passes 2,824 assertions on each
595
+ machine, comparing retained state and subsequent full logits at the same B=2
596
+ shape across unequal accepted prefixes. Existing fused kernel selection is
597
+ preserved. The subsequent MLX cache-layout binding now serves ordinary and
598
+ Qwen MTP groups through those same encoded rows. Scheduling retains its
599
+ method lifecycle; sampling and fused codec selection are unchanged. The
600
+ method key and paired-prefix namespace include the TurboQuant scheme.
601
+ Temporary extracted-state views use the existing lease interface.
602
+
603
+ Fused K8/V3 serving passes on both Macs: MTP2 and MTP4 each prove true B4,
604
+ seeded logprobs, mixed grammar, joins and retirement; ordinary tests prove
605
+ B1/B2/B3 and immutable RAM donor reuse. Paired RAM and SSD restart tests
606
+ preserve target/draft/hidden state and continuations. Full suites pass
607
+ 2,078 tests on M1 and 2,082 on M4, with typechecks clear. MTP3 also passes
608
+ the M1 native/HTTP gate. On M1, all 21 saved-boundary requests match across
609
+ 8 GiB synchronous, 1 GiB synchronous and 1 GiB asynchronous RAM-cache arms,
610
+ including full usage and acceptance. Each arm durably flushes all seven
611
+ snapshots with no missing, pending, dropped or failed writes. The constrained
612
+ arms cause six eviction spills; the async observer confirms 3,264 submissions.
613
+ These sequential shared-server pressure checks cause substantial swapping;
614
+ B4 correctness is a separate native gate, and no speed or memory-reduction
615
+ claim follows. The subsequent M4 combined pressure gate also passes with both asynchronous and blocking submissions exercised; full usage, responses and final persistence match. Current measurements and provenance live in benchmarks.md. This closes the named pressure gate; performance and default selection remain separate.
616
+ Shared TurboQuant integration ships in v0.4.0; v0.3.0 retained the earlier
617
+ placement limits.
618
+ Evidence: `reports/qwen38-closeout/composition-baseline/turboquant-composition-manifest.json`.
619
+ Integration evidence: `reports/qwen38-closeout/composition-baseline/turboquant-serving/`.
620
+ Broader family checks pass MiniCPM seeded/logprob serving but reproduce a
621
+ Gemma e4b/12B failure: attention borrows the row-offset array across a cache
622
+ append that releases it. The adopted ownership fix passes seeded/logprob and
623
+ prefix checks on both Gemma families, MiniCPM/Qwen prefix controls, and the
624
+ complete suites on both Macs. M4 acceptance also passes fused and unfused
625
+ Gemma seeded sampling, affine KV4 controls and Qwen MTP3 B4 serving.
626
+ MiniCPM prefix checks allow the existing policy to supersede trimmable donors
627
+ while proving byte identity and continuation through retirement.
628
+
629
+ ### Fused codec default selection
630
+
631
+ The unreleased decoder selects packed K/V fusion by default when a caller
632
+ chooses TurboQuant. `turboQuantFusedDecode` resolves the runtime policy once;
633
+ ordinary storage, shared rows and delayed conversion capture the same value.
634
+ Copies and restored rows retain the codec selection through their existing
635
+ interfaces. `MLX_BUN_TURBOQUANT_FUSED_DECODE=0` selects the original operations.
636
+ The numerical kernels and eligibility rules are unchanged from the accepted
637
+ opt-in. TurboQuant quantization itself remains an explicit cache-format choice.
638
+ The current shared-serving comparison and combined pressure measurements are
639
+ recorded in benchmarks.md; the earlier six-pair timing and native/state gates
640
+ above remain the evidence for the fused implementation.
641
+
583
642
  ## KV-leg limits and non-goals (recorded so they don't creep)
584
643
 
585
644
  - Full-attention layers only; rotating/sliding-window layers stay bf16 (warn
586
645
  once, never throw). Head dims outside {64,128,256,512} refused at server
587
646
  start.
588
- - Solo-only: no batched TurboQuant (novel Cache class); paged-KV combos are
589
- refused explicitly.
647
+ - Shared ordinary execution supports row-local delayed TurboQuant; Qwen MTP
648
+ requires start zero. Delayed affine conversion and paged-KV combinations
649
+ remain unsupported.
590
650
  - No fused quantized-SDPA Metal kernel (remaining fetch cost is
591
651
  unpack+gather); no QJL residual stage; no entropy coding (the paper
592
652
  declined it too).
593
- - Speculative lane is bf16-KV-only: turbo + `--draft-model` keeps the KV
594
- scheme and decodes serially without speculation.
653
+ - Strict legacy serial speculation and draft providers without grouped TQ
654
+ support retain their existing exclusions. A shared server with one active
655
+ row is the TQ/MTP B1 path.
595
656
  - No speed claims: v1 dequant-on-fetch is expected slower per step at long
596
657
  context; this ships as a memory/context feature like uniform KV. Admission
597
658
  still bills turbo as bf16 (server-config.md says so).
@@ -902,7 +963,7 @@ since e·Hinv[k,k] = w−q) and `err[..., k:k+1]` indexes a group-local buffer
902
963
  with the GLOBAL k (mlx out-of-range slice assignment silently no-ops →
903
964
  cross-group propagation lost after block 0). Fixing only err
904
965
  DOUBLE-compensates [j, k+j) and REGRESSES below RTN (measured: 7.22/7.50);
905
- fixing both = paper GPTQ. Worth an upstream report. Fork:
966
+ fixing both = paper GPTQ. [mlx-lm #1878](https://github.com/ml-explore/mlx-lm/issues/1878) contains the CPU-only reproduction, observed results against mlx-lm 0.31.3 and upstream `e5962529`, and proposed two-line correction; [mlx-lm PR #1880](https://github.com/ml-explore/mlx-lm/pull/1880) carries the fix plus `tests/test_gptq.py` (column-by-column reference, four groups fail on `main`, single-group control passes on both). Fork:
906
967
  `scripts/turboquant/tq-gptq.py` (also restricts GPTQ+fallback to language
907
968
  modules — vision H is a zero scalar and stays bf16).
908
969
 
@@ -2100,3 +2161,65 @@ any use of the larger crossover or equivalent small-chunk span splitting.
2100
2161
  - 2026-09-02 — Q3 full recipe (rot + LDLQ + k-map 3.00) PASSED: KL 0.1553 at
2101
2162
  3.55 bpw, MMLU 88 / tGSM 48 / rawGSM 44; eval-carrier repack tool; LDLQ
2102
2163
  loop-shadow bug fixed.
2164
+
2165
+ ## Delayed row conversion and reusable precision boundaries
2166
+
2167
+ `DelayedTurboQuantKVCache` implements the existing batchable cache and
2168
+ rotated-value attention ports. It keeps serial row caches during a mixed
2169
+ plain/TQ phase and invokes the existing maintenance operation before each
2170
+ row's next append. `KvTensorRows` supplies positions and masks without
2171
+ dummy tensor planes. Once every row converts, `BatchedTurboQuantKVCache`
2172
+ owns the encoded rows. The scheduler invokes a generic preparation hook;
2173
+ it does not implement threshold, codec or inverse-rotation logic.
2174
+
2175
+ The rotated-value port can capture an output transform for its fetched
2176
+ state. Plain value rows pass through unchanged, and TQ rows receive the
2177
+ existing inverse rotation. Gemma carries that transform through its donor
2178
+ KV consumers. Model projections and attention remain at B=N. Start-zero
2179
+ layouts and kernel selection retain their existing paths.
2180
+
2181
+ A cache's `minimumReusableOffset` records an irreversible precision
2182
+ boundary. Delayed maintenance sets it to the actual conversion offset,
2183
+ which can exceed the configured threshold when a prefill chunk crosses it.
2184
+ Clone, row extraction and SSD metadata retain the bound. RAM/SSD selection
2185
+ and ancestor supersession check it independently of physical trimmability.
2186
+ Earlier plain donors remain reusable after a converted descendant appears.
2187
+ Old TQ SSD headers lacking the bound conservatively use their stored offset.
2188
+
2189
+ Focused tests cover exact mixed-row bytes and output transforms through
2190
+ reordering, retirement and re-admission, plus RAM/SSD ancestor retention,
2191
+ restart, continuation and old-header compatibility. Native seeded/logprob
2192
+ and prefix gates accept positive thresholds via their test environment
2193
+ switches. Shared Qwen MTP also uses the delayed layout. Its transaction
2194
+ begins conversion from committed history before verification. A verify block
2195
+ may cross the configured threshold; resolution converts at the retained
2196
+ offset after rollback and before checkpoint publication, so rejected tokens
2197
+ never set the precision boundary.
2198
+ The draft provider retains its existing paired checkpoint format.
2199
+
2200
+ Mixed rollback and final packed promotion preserve each row's physical left
2201
+ padding. Re-aligning it based on another row's accepted count changes SDPA
2202
+ reduction positions even when all live cache bytes match. Same-batch native
2203
+ controls check every target layer and subsequent hidden rows after unequal
2204
+ acceptance. Affine delayed speculation and the legacy serial TQ speculative
2205
+ path remain excluded. This implementation changes no defaults.
2206
+
2207
+ ### Wider split-K verification screen
2208
+
2209
+ The current packed down-projection operation covers five through eight input
2210
+ vectors. An isolated candidate extended that operation through 32 vectors,
2211
+ using 8-, 16- or 32-row tiles while retaining the native split partition and
2212
+ accumulation order. Scheduler and speculation policy were unchanged.
2213
+
2214
+ Actual 2-, 3- and 4-bit artifact projections pass exact expanded-weight
2215
+ controls at every new width and three input seeds on both Macs. Full Qwen
2216
+ logits, recurrent/KV state and continuation match the unchanged eligibility
2217
+ control at B1/B2/B4/B8 on both Macs. Call-count assertions prove the wider
2218
+ kernels ran. Updated unit coverage includes wider partition tails and
2219
+ noncontiguous inputs; both complete suites and typechecks pass.
2220
+
2221
+ The alternating M4 prompt-lookup comparison preserves all requests but loses
2222
+ concurrent throughput. This wider eligibility is not adopted. Future work
2223
+ needs serving dispatch/cost attribution before additional tile tuning.
2224
+ Measurements: benchmarks.md. Evidence and source manifest:
2225
+ `reports/qwen38-closeout/composition-baseline/trellis-batch-width/`.