mlx-bun 0.0.13 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (427) hide show
  1. package/README.md +71 -578
  2. package/bin/mlx-bun.mjs +1 -1
  3. package/docs/README.md +91 -0
  4. package/docs/{design → archive}/hlg-sampling.md +3 -3
  5. package/docs/{design → archive/investigations}/audio-input-plan.md +4 -4
  6. package/docs/{design → archive/investigations}/colibri-glm52-port.md +1 -1
  7. package/docs/{design → archive/investigations}/diffusion-gemma-port.md +3 -3
  8. package/docs/{design → archive/investigations}/faithful-l1-consolidation.md +4 -4
  9. package/docs/{investigations → archive/investigations}/hlg-sampling-investigation.md +1 -1
  10. package/docs/{design → archive/investigations}/minicpm5-decode-megakernel.md +11 -11
  11. package/docs/{design → archive/investigations}/optimization_plan.md +1 -1
  12. package/docs/archive/investigations/pareto-specialized-runtime-findings.md +92 -0
  13. package/docs/{design → archive/investigations}/pre-colibri-stabilization.md +5 -5
  14. package/docs/{design → archive/investigations}/the-dreaming-handoff.md +2 -2
  15. package/docs/{planning → archive/planning}/chat-ui-vision.md +1 -1
  16. package/docs/{planning → archive/planning}/chunk-task-roadmap.md +1 -1
  17. package/docs/{planning → archive/planning}/curve-sampler-research-plan.md +4 -4
  18. package/docs/{planning → archive/planning}/memory-docs-and-dag-plan.md +1 -1
  19. package/docs/{planning → archive/planning}/release-notes-v0.0.9.md +1 -1
  20. package/docs/archive/planning/release-notes-v0.2.0.md +49 -0
  21. package/docs/{planning → archive/planning}/website-readme-pass-plan.md +1 -1
  22. package/docs/design/batching.md +569 -0
  23. package/docs/design/decode-speed-program.md +3178 -169
  24. package/docs/design/dreaming-nightly-pipeline.md +675 -282
  25. package/docs/design/generic-model-support.md +579 -334
  26. package/docs/design/kv-cache.md +680 -0
  27. package/docs/design/orpo-training.md +673 -1239
  28. package/docs/design/speculative-decoding.md +1627 -0
  29. package/docs/design/turboquant.md +2102 -0
  30. package/docs/design/unified-engine-frontier-plan.md +1831 -727
  31. package/docs/design/web-chat-redesign.md +666 -1083
  32. package/docs/planning/PRODUCT_ROADMAP.md +34 -1
  33. package/docs/planning/release-notes-v0.3.0.md +35 -0
  34. package/docs/planning/video-series.md +421 -0
  35. package/docs/reference/benchmarks.md +1162 -0
  36. package/docs/reference/cli.md +395 -149
  37. package/docs/reference/distribution.md +321 -181
  38. package/docs/reference/environment.md +348 -0
  39. package/docs/reference/glossary.md +39 -0
  40. package/docs/reference/library-api.md +580 -142
  41. package/docs/reference/memory.md +227 -64
  42. package/docs/reference/models.md +137 -6
  43. package/docs/reference/server-api.md +938 -422
  44. package/docs/reference/server-config.md +652 -320
  45. package/docs/reference/training.md +393 -254
  46. package/docs/reference/troubleshooting.md +166 -0
  47. package/package.json +10 -5
  48. package/src/admission-plan.ts +18 -0
  49. package/src/anthropic.ts +92 -3
  50. package/src/audio/decode.ts +2 -2
  51. package/src/audio/features.ts +2 -2
  52. package/src/backends/mlx/autoregressive.ts +108 -0
  53. package/src/backends/mlx/batch-group.ts +1646 -0
  54. package/src/backends/mlx/diffusion.ts +39 -0
  55. package/src/backends/mlx/draft-target.ts +47 -0
  56. package/src/backends/mlx/evaluation.ts +105 -0
  57. package/src/backends/mlx/fill-append.ts +45 -0
  58. package/src/backends/mlx/gateway-binding.ts +71 -0
  59. package/src/backends/mlx/graph.ts +38 -0
  60. package/src/backends/mlx/memory-client.ts +189 -0
  61. package/src/backends/mlx/memory-guard.ts +40 -0
  62. package/src/backends/mlx/methods.ts +90 -0
  63. package/src/backends/mlx/model-prompt.ts +164 -0
  64. package/src/backends/mlx/model-serving.ts +79 -0
  65. package/src/backends/mlx/prefill.ts +33 -0
  66. package/src/backends/mlx/request-policy.ts +20 -0
  67. package/src/backends/mlx/rollback.ts +51 -0
  68. package/src/backends/mlx/serial-executor.ts +273 -0
  69. package/src/backends/mlx/speculative.ts +114 -0
  70. package/src/backends/mlx/state-views.ts +26 -0
  71. package/src/backends/mlx/text-engine.ts +73 -0
  72. package/src/cli.ts +189 -61
  73. package/src/client.ts +66 -0
  74. package/src/config.ts +21 -4
  75. package/src/contracts/completion.ts +16 -0
  76. package/src/contracts/execution.ts +49 -0
  77. package/src/contracts/generation.ts +103 -0
  78. package/src/contracts/host.ts +7 -0
  79. package/src/contracts/jobs.ts +66 -0
  80. package/src/contracts/pi-provider.ts +30 -0
  81. package/src/contracts/pi.ts +259 -0
  82. package/src/contracts/resources.ts +18 -0
  83. package/src/contracts/scheduling.ts +27 -0
  84. package/src/contracts/tsconfig.json +14 -0
  85. package/src/diffusion/diffusion-generate.ts +218 -153
  86. package/src/embed.ts +1 -1
  87. package/src/engine/admission.ts +59 -0
  88. package/src/engine/cancellation.ts +38 -0
  89. package/src/engine/engine.ts +56 -0
  90. package/src/engine/execution-coordinator.ts +70 -0
  91. package/src/engine/execution-plan.ts +51 -0
  92. package/src/engine/resources.ts +42 -0
  93. package/src/engine/scheduler.ts +67 -0
  94. package/src/engine/session.ts +247 -0
  95. package/src/eval/README.md +44 -1
  96. package/src/eval/kl.ts +263 -23
  97. package/src/eval/reference-logits.ts +207 -0
  98. package/src/eval/runner.ts +10 -79
  99. package/src/eval/tasks/bfcl.ts +2 -1
  100. package/src/eval/tasks/gsm8k.ts +2 -1
  101. package/src/eval/tasks/hashhop.ts +2 -1
  102. package/src/eval/tasks/humaneval.ts +5 -4
  103. package/src/eval/tasks/ifeval.ts +2 -1
  104. package/src/eval/tasks/mmlu.ts +2 -1
  105. package/src/expert-io.ts +3 -1
  106. package/src/expert-offload.ts +3 -1
  107. package/src/fill/echo-index.ts +188 -0
  108. package/src/fill/fill-session.ts +452 -0
  109. package/src/fill/proposal.ts +68 -0
  110. package/src/fill/schema-rows.ts +506 -0
  111. package/src/fill/tool-boundary.ts +103 -0
  112. package/src/fit.ts +24 -43
  113. package/src/generate.ts +740 -337
  114. package/src/grammar.ts +14 -8
  115. package/src/harness-pi.ts +15 -34
  116. package/src/hub-rest.ts +4 -4
  117. package/src/index.ts +27 -0
  118. package/src/inference/denoising.ts +17 -0
  119. package/src/inference/graph.ts +33 -0
  120. package/src/inference/prefill.ts +39 -0
  121. package/src/inference/rollback.ts +7 -0
  122. package/src/jobs/db.ts +4 -0
  123. package/src/jobs/index.ts +2 -0
  124. package/src/jobs/job-entry.ts +15 -14
  125. package/src/jobs/runner.ts +98 -13
  126. package/src/jobs/task-client.ts +19 -0
  127. package/src/jobs/types.ts +2 -58
  128. package/src/kv-scheme.ts +199 -0
  129. package/src/kv-store.ts +459 -234
  130. package/src/lab/README.md +18 -0
  131. package/src/{assets → lab/curve}/curve-designer.html +2 -2
  132. package/src/{curve-sampler.ts → lab/curve/curve-sampler.ts} +2 -2
  133. package/src/{expert-trace.ts → lab/expert-trace/expert-trace.ts} +7 -5
  134. package/src/{model → lab/paged-kv}/paged-kv.ts +9 -6
  135. package/src/library.ts +40 -0
  136. package/src/lora.ts +18 -0
  137. package/src/media-fetch.ts +20 -4
  138. package/src/memory/article.ts +1 -1
  139. package/src/memory/chunk.ts +1 -1
  140. package/src/memory/model.ts +32 -170
  141. package/src/memory/prompts.ts +1 -1
  142. package/src/memory/rest.ts +1 -1
  143. package/src/memory/schedule.ts +1 -1
  144. package/src/memory/stages.ts +4 -1
  145. package/src/memory/vault.ts +3 -4
  146. package/src/mlx/array.ts +9 -10
  147. package/src/mlx/compile.ts +12 -2
  148. package/src/mlx/ffi.ts +66 -22
  149. package/src/mlx/materialize.ts +23 -0
  150. package/src/mlx/metal-kernel.ts +10 -11
  151. package/src/mlx/ops.ts +64 -19
  152. package/src/mlx/quantized-rows.ts +36 -0
  153. package/src/mlx/token-bitmask.ts +52 -0
  154. package/src/mlx/turboquant-kv-decode.ts +82 -0
  155. package/src/mlx/turboquant-kv-inverse.ts +122 -0
  156. package/src/mlx/turboquant-ops.ts +33 -3
  157. package/src/mlx/turboquant-tables.ts +2 -2
  158. package/src/model/batched-mask.ts +9 -3
  159. package/src/model/batched-quant.ts +2 -2
  160. package/src/model/batched-rotating-quant.ts +45 -99
  161. package/src/model/batched-rotating-state.ts +73 -0
  162. package/src/model/batched-rotating.ts +57 -106
  163. package/src/model/batched-row-storage.ts +127 -0
  164. package/src/model/compiled-decode.ts +4 -3
  165. package/src/model/diffusion-gemma.ts +8 -8
  166. package/src/model/factory.ts +87 -49
  167. package/src/model/fingerprint.ts +1 -1
  168. package/src/model/flash-attention.ts +3 -3
  169. package/src/model/gemma4-base.ts +187 -17
  170. package/src/model/gemma4.ts +6 -6
  171. package/src/model/generated/gemma4-12b.ts +52 -148
  172. package/src/model/generated/gemma4-26b.ts +34 -94
  173. package/src/model/generated/gemma4-e4b.ts +28 -76
  174. package/src/model/glm52-cache.ts +19 -9
  175. package/src/model/glm52-dsa.ts +13 -9
  176. package/src/model/glm52-memory.ts +28 -1
  177. package/src/model/implementation.ts +69 -0
  178. package/src/model/minicpm5.ts +7 -8
  179. package/src/model/profile.ts +443 -0
  180. package/src/model/qwen-append.ts +12 -0
  181. package/src/model/qwen-conv.ts +52 -0
  182. package/src/model/qwen3-delta.ts +98 -2
  183. package/src/model/qwen3-mrope.ts +252 -0
  184. package/src/model/qwen3_5-checkpoint.ts +164 -0
  185. package/src/model/qwen3_5.ts +336 -60
  186. package/src/model/support.ts +1 -1
  187. package/src/model/trellis-balanced-scatter.ts +51 -0
  188. package/src/model/trellis-linear.ts +672 -0
  189. package/src/model/trellis-shared-m.ts +151 -0
  190. package/src/model/trellis-shared-scatter.ts +144 -0
  191. package/src/model/trellis-splitk-prefill.ts +158 -0
  192. package/src/model/trellis-tiled-prefill.ts +136 -0
  193. package/src/model/trellis-vector-expand.ts +62 -0
  194. package/src/model/trellis-wide-prefill.ts +94 -0
  195. package/src/model/universal/dense.ts +1 -1
  196. package/src/model/universal/modules.ts +8 -1
  197. package/src/native/frame_extract.swift +140 -0
  198. package/src/native-pack.ts +15 -7
  199. package/src/pi-provider.ts +6 -64
  200. package/src/pi-web.ts +14 -320
  201. package/src/prompt-cache.ts +97 -54
  202. package/src/quantize/allocator.ts +1 -1
  203. package/src/quantize/atomic-output.ts +38 -0
  204. package/src/quantize/calibration.ts +2 -1
  205. package/src/quantize/config-writer.ts +16 -3
  206. package/src/quantize/index.ts +28 -1
  207. package/src/quantize/job.ts +11 -0
  208. package/src/quantize/quantizer.ts +265 -100
  209. package/src/quantize/rotate.ts +603 -0
  210. package/src/quantize/safetensors-writer.ts +79 -1
  211. package/src/quantize/sensitivity.ts +41 -59
  212. package/src/quantize/trellis.ts +586 -0
  213. package/src/quantize/weight-transform.ts +292 -0
  214. package/src/responses.ts +130 -3
  215. package/src/runtime-config.ts +81 -0
  216. package/src/sampler.ts +276 -4
  217. package/src/serve/admin-routes.ts +184 -0
  218. package/src/serve/aux-routes.ts +132 -0
  219. package/src/serve/batch-scheduler.ts +8 -1558
  220. package/src/serve/chat-request.ts +391 -0
  221. package/src/serve/chat-stage.ts +195 -0
  222. package/src/serve/checkpoint-identity.ts +64 -0
  223. package/src/serve/completion-executor.ts +354 -0
  224. package/src/serve/completion-sink.ts +157 -0
  225. package/src/serve/discovery-routes.ts +204 -0
  226. package/src/serve/generation-gateway.ts +211 -243
  227. package/src/serve/http.ts +159 -0
  228. package/src/serve/inference-request.ts +79 -0
  229. package/src/serve/isolate.ts +297 -105
  230. package/src/serve/kv-budget.ts +14 -0
  231. package/src/serve/lab-routes.ts +341 -0
  232. package/src/serve/lane-registry.ts +2 -1
  233. package/src/serve/model-admin-routes.ts +155 -0
  234. package/src/serve/model-binding.ts +43 -0
  235. package/src/serve/model-host.ts +512 -0
  236. package/src/serve/openai-wire.ts +103 -0
  237. package/src/serve/parent-application.ts +56 -0
  238. package/src/serve/pipeline.ts +33 -0
  239. package/src/serve/preparation.ts +33 -0
  240. package/src/serve/prompt-response-trace.ts +147 -0
  241. package/src/serve/request-plan.ts +162 -0
  242. package/src/serve/request-prep.ts +346 -0
  243. package/src/serve/response-lease.ts +24 -0
  244. package/src/serve/responses-client.ts +69 -0
  245. package/src/serve/session-completion-engine.ts +110 -0
  246. package/src/serve/session-search.ts +1 -1
  247. package/src/serve/static-routes.ts +101 -0
  248. package/src/serve/text-completion-stage.ts +104 -0
  249. package/src/serve/token-streams.ts +519 -0
  250. package/src/server.ts +523 -3551
  251. package/src/spec/assistant-source.ts +10 -44
  252. package/src/spec/deepspec-source.ts +6 -6
  253. package/src/spec/dflash-source.ts +9 -8
  254. package/src/spec/dspark/ab-stats.ts +3 -3
  255. package/src/spec/dspark/calibration.ts +2 -2
  256. package/src/spec/dspark/deepspec-module.ts +2 -2
  257. package/src/spec/dspark/generate-dflash.ts +2 -2
  258. package/src/spec/dspark/generate.ts +2 -2
  259. package/src/spec/dspark/loader.ts +1 -1
  260. package/src/spec/dspark/module-dflash.ts +5 -4
  261. package/src/spec/dspark/module.ts +3 -3
  262. package/src/spec/dspark/quantize-drafter.ts +1 -1
  263. package/src/spec/generate.ts +1 -1
  264. package/src/spec/glm52-mtp-source.ts +9 -1
  265. package/src/spec/ngram-source.ts +1 -1
  266. package/src/spec/prefix-state.ts +45 -0
  267. package/src/spec/qwen-mtp-source.ts +528 -0
  268. package/src/spec/serve-loop.ts +179 -213
  269. package/src/spec/source.ts +42 -10
  270. package/src/spec/two-model.ts +1 -1
  271. package/src/ssd-cache.ts +95 -24
  272. package/src/ssd-durability.ts +207 -0
  273. package/src/tool-call.ts +51 -14
  274. package/src/train/flash-cce.ts +14 -13
  275. package/src/train/forward.ts +38 -1
  276. package/src/train/loss.ts +3 -2
  277. package/src/train/prefix-shared.ts +5 -1
  278. package/src/train/segmented.ts +9 -6
  279. package/src/train/trainer.ts +9 -8
  280. package/src/vision/preprocess.ts +1 -1
  281. package/src/vision/prompt.ts +48 -2
  282. package/src/vision/qwen3vl-preprocess.ts +409 -0
  283. package/src/vision/qwen3vl-prompt.ts +196 -0
  284. package/src/vision/qwen3vl-tower.ts +555 -0
  285. package/src/vision/video-frames.ts +148 -0
  286. package/src/web/app.html +1 -1
  287. package/src/web/app.js +15 -6
  288. package/src/web/src/adapters-panel.ts +3 -3
  289. package/src/web/src/assistant.ts +2 -36
  290. package/src/web/src/chat.ts +16 -9
  291. package/src/web/src/composer.ts +4 -4
  292. package/src/web/src/hub.ts +1 -1
  293. package/src/web/src/markdown.ts +0 -0
  294. package/src/web/src/memory-panel.ts +1 -1
  295. package/src/web/src/model-picker.ts +1 -1
  296. package/src/web/src/palette.ts +1 -1
  297. package/src/web/src/protocol.ts +3 -39
  298. package/src/web/src/sessions.ts +1 -1
  299. package/src/web/src/ui-catalog.ts +4 -18
  300. package/src/web-assets.ts +47 -0
  301. package/src/weights.ts +134 -33
  302. package/docs/archive/mlx-bun-lab-report.html +0 -275
  303. package/docs/archive/wwdc-mlx-bun.html +0 -848
  304. package/docs/design/adapters-end-to-end.md +0 -205
  305. package/docs/design/batching-perf-path.md +0 -255
  306. package/docs/design/batching-v2-plan.md +0 -529
  307. package/docs/design/bucketing-stage.md +0 -197
  308. package/docs/design/compat-cli-surface-design.md +0 -230
  309. package/docs/design/docs-reorg-plan.md +0 -165
  310. package/docs/design/dspark-serving-program.md +0 -371
  311. package/docs/design/dspark-speculative-decoding.md +0 -268
  312. package/docs/design/grammar-spec-batching-integration.md +0 -301
  313. package/docs/design/memory-inference-path.md +0 -422
  314. package/docs/design/memory-synthesis.md +0 -287
  315. package/docs/design/memory-system.md +0 -237
  316. package/docs/design/mlx-lm-tool-parity-plan.md +0 -545
  317. package/docs/design/omlx-adoption-map.md +0 -98
  318. package/docs/design/orpo-dynamic-lambda.md +0 -220
  319. package/docs/design/orpo-future-enhancements.md +0 -340
  320. package/docs/design/paged-kv-cache.md +0 -214
  321. package/docs/design/parallel-slots.md +0 -567
  322. package/docs/design/parity-tier-dag.md +0 -161
  323. package/docs/design/repo-cleanup-plan.md +0 -189
  324. package/docs/design/runtime-isolation.md +0 -263
  325. package/docs/design/segmented-backward-training.md +0 -543
  326. package/docs/design/spec-decode-larger-targets.md +0 -229
  327. package/docs/design/ssd-kv-cold-tier.md +0 -288
  328. package/docs/design/structured-output.md +0 -484
  329. package/docs/design/tauri-desktop-app.md +0 -127
  330. package/docs/design/the-dreaming-master-plan.md +0 -445
  331. package/docs/design/turboquant-kv.md +0 -235
  332. package/docs/design/w4a16-compute-precision-spike.md +0 -232
  333. package/docs/design/web-chat-beat-matrix.md +0 -315
  334. package/docs/design/write-pipeline-entity.md +0 -468
  335. package/docs/investigations/curve-runs/bisector-route.json +0 -98
  336. package/docs/investigations/curve-runs/bisector-trace.json +0 -1393
  337. package/docs/investigations/curve-runs/curve-terrain.json +0 -1179
  338. package/docs/investigations/curve-runs/curve-terrain.svg +0 -42
  339. package/docs/investigations/hlg-ab.html +0 -34
  340. package/docs/investigations/hlg-explorer.html +0 -238
  341. package/docs/investigations/hlg-figs/cliff.svg +0 -1
  342. package/docs/investigations/hlg-figs/cross.svg +0 -1
  343. package/docs/investigations/hlg-figs/edges.svg +0 -1
  344. package/docs/investigations/hlg-figs/k20-grids.svg +0 -1
  345. package/docs/investigations/hlg-figs/k20-peaks.svg +0 -1
  346. package/docs/investigations/hlg-figs/lw-curve.svg +0 -1
  347. package/docs/investigations/hlg-figs/terrain.svg +0 -1
  348. package/docs/investigations/hlg-report.html +0 -262
  349. package/docs/investigations/hlg-runs/hlg-ab.json +0 -149
  350. package/docs/investigations/hlg-runs/hlg-blind-prompts.md +0 -87
  351. package/docs/investigations/hlg-runs/hlg-blind.json +0 -107
  352. package/docs/investigations/hlg-runs/hlg-cliff.json +0 -197
  353. package/docs/investigations/hlg-runs/hlg-cross.json +0 -505
  354. package/docs/investigations/hlg-runs/hlg-edge.json +0 -388
  355. package/docs/investigations/hlg-runs/hlg-eval1.json +0 -25
  356. package/docs/investigations/hlg-runs/hlg-frontier.json +0 -86
  357. package/docs/investigations/hlg-runs/hlg-grid.json +0 -242
  358. package/docs/investigations/hlg-runs/hlg-grid2.json +0 -343
  359. package/docs/investigations/hlg-runs/hlg-lw-coarse.json +0 -110
  360. package/docs/investigations/hlg-runs/hlg-map.json +0 -383
  361. package/docs/investigations/hlg-runs/run0-original.log +0 -159
  362. package/docs/investigations/hlg-runs/runA-recommended.log +0 -131
  363. package/docs/investigations/hlg-runs/runAA-cliff-cpm5.log +0 -26
  364. package/docs/investigations/hlg-runs/runAB-grid2-e4b.log +0 -18
  365. package/docs/investigations/hlg-runs/runAC-peak-e4b-partial.log +0 -25
  366. package/docs/investigations/hlg-runs/runAD-ab-samples.log +0 -8
  367. package/docs/investigations/hlg-runs/runAE-edge-e4b.log +0 -51
  368. package/docs/investigations/hlg-runs/runAF-logit-calibration.log +0 -10
  369. package/docs/investigations/hlg-runs/runAG-eval-config2.log +0 -16
  370. package/docs/investigations/hlg-runs/runB-gain-variants.log +0 -192
  371. package/docs/investigations/hlg-runs/runC-pivots.log +0 -162
  372. package/docs/investigations/hlg-runs/runD-oetf.log +0 -132
  373. package/docs/investigations/hlg-runs/runE-eotf.log +0 -162
  374. package/docs/investigations/hlg-runs/runF-shaper-working.log +0 -86
  375. package/docs/investigations/hlg-runs/runG-shaper-sweep.log +0 -101
  376. package/docs/investigations/hlg-runs/runH-wsweep.log +0 -176
  377. package/docs/investigations/hlg-runs/runI-asweep.log +0 -176
  378. package/docs/investigations/hlg-runs/runJ-knobmap.log +0 -49
  379. package/docs/investigations/hlg-runs/runK-frontier.log +0 -19
  380. package/docs/investigations/hlg-runs/runL-widemap.log +0 -65
  381. package/docs/investigations/hlg-runs/runM-frontier-emb.log +0 -15
  382. package/docs/investigations/hlg-runs/runN-verify.log +0 -116
  383. package/docs/investigations/hlg-runs/runO-frontier-seed5000.log +0 -15
  384. package/docs/investigations/hlg-runs/runP-grid-AxSm.log +0 -15
  385. package/docs/investigations/hlg-runs/runQ-grid-tgW.log +0 -15
  386. package/docs/investigations/hlg-runs/runR-blind-transcript.log +0 -79
  387. package/docs/investigations/hlg-runs/runS-cross-coherence.log +0 -33
  388. package/docs/investigations/hlg-runs/runT-cross-cpm5.log +0 -33
  389. package/docs/investigations/hlg-runs/runU-cross-12b.log +0 -33
  390. package/docs/investigations/hlg-runs/runV-lw-e4b.log +0 -22
  391. package/docs/investigations/hlg-runs/runW-lw-12b.log +0 -22
  392. package/docs/investigations/hlg-runs/runX-lw-cpm5.log +0 -22
  393. package/docs/investigations/hlg-runs/runY-cliff-e4b.log +0 -26
  394. package/docs/investigations/hlg-runs/runZ-cliff-12b.log +0 -26
  395. package/docs/planning/IDEAS.md +0 -69
  396. package/docs/reference/embedding.md +0 -197
  397. package/docs/reference/features-matrix.md +0 -100
  398. package/docs/reference/orpo-quickstart.md +0 -135
  399. package/src/flags.ts +0 -13
  400. /package/docs/{investigations → archive/investigations}/chunk-finetune-experiment.md +0 -0
  401. /package/docs/{investigations → archive/investigations}/colibri-oracle-pin.md +0 -0
  402. /package/docs/{investigations → archive/investigations}/curve-bisector-routing.md +0 -0
  403. /package/docs/{investigations → archive/investigations}/decode-roofline-lookagain.md +0 -0
  404. /package/docs/{investigations → archive/investigations}/dspark-handoff.md +0 -0
  405. /package/docs/{investigations → archive/investigations}/expert-offload-single-user-moe.md +0 -0
  406. /package/docs/{investigations → archive/investigations}/indexshare-performance-spike.md +0 -0
  407. /package/docs/{investigations → archive/investigations}/kernel-perf-review-2026-07.md +0 -0
  408. /package/docs/{investigations → archive/investigations}/lab-build-journal.md +0 -0
  409. /package/docs/{investigations → archive/investigations}/openwiki-evaluation.md +0 -0
  410. /package/docs/{investigations → archive/investigations}/orpo-base-uf-experiment-and-directions.md +0 -0
  411. /package/docs/{investigations → archive/investigations}/orpo-flash-cce-pin-leak.md +0 -0
  412. /package/docs/{investigations → archive/investigations}/orpo-uf-testing-handoff.md +0 -0
  413. /package/docs/{investigations → archive/investigations}/pi-builtin-investigation.md +0 -0
  414. /package/docs/{investigations → archive/investigations}/segmented-backward-handoff.md +0 -0
  415. /package/docs/{investigations → archive/investigations}/starter-model-port-handoff.md +0 -0
  416. /package/docs/{investigations → archive/investigations}/steel-flash-cce-handoff.md +0 -0
  417. /package/docs/{investigations → archive/investigations}/trainer-validation-experiment.md +0 -0
  418. /package/docs/{planning → archive/planning}/chat-ui-vision-memory-first.md +0 -0
  419. /package/docs/{planning → archive/planning}/journal.md +0 -0
  420. /package/docs/{planning → archive/planning}/pi-integration-review.md +0 -0
  421. /package/docs/{planning → archive/planning}/release-notes-v0.0.10.md +0 -0
  422. /package/docs/{planning → archive/planning}/release-notes-v0.0.11.md +0 -0
  423. /package/docs/{planning → archive/planning}/release-notes-v0.0.12.md +0 -0
  424. /package/docs/{planning → archive/planning}/release-notes-v0.0.13.md +0 -0
  425. /package/docs/{planning → archive/planning}/web-ui-pass-plan.md +0 -0
  426. /package/{docs/investigations → src/serve/assets}/curve-terrain.html +0 -0
  427. /package/{docs/dag → src/serve/assets}/training-inference-map.html +0 -0
@@ -4,14 +4,15 @@
4
4
  // fingerprint: c9dd67ed5a525231
5
5
  //
6
6
  // Branch-resolved, unrolled forward pass for this architecture
7
- // (docs/design/optimization_plan.md Phase C). Bit-exactness vs the monolith is the
8
- // generator's gate: tests/generated-parity.test.ts. The cache-signature
7
+ // (docs/archive/investigations/optimization_plan.md Phase C). Bit-exactness vs the monolith is the
8
+ // generator's gate: tests/parity/generated-parity.test.ts. The cache-signature
9
9
  // guard falls back to the monolith for anything this file wasn't
10
10
  // generated for (bf16 compat runs, vision bidir prefill).
11
11
 
12
12
  import { MlxArray } from "../../mlx/array";
13
13
  import * as ops from "../../mlx/ops";
14
14
  import {
15
+ cacheSignature,
15
16
  disposing,
16
17
  fusedSdpaRuntimeOk,
17
18
  KVCache,
@@ -293,101 +294,40 @@ function donorFullQuantG64B4KeqVMoeScal(layer: DecoderLayer, x: MlxArray, mask:
293
294
  }
294
295
 
295
296
  export class GeneratedGemma4 extends Gemma4Model {
296
- /** Per-layer cache classes must match what this file was generated
297
- * for; anything else runs the monolith path. */
297
+ /** Per-layer cache signatures must match what this file was generated for. */
298
298
  #matches(cache: Cache[]): boolean {
299
299
  return (
300
300
  cache.length === 30 &&
301
- cache[0] instanceof RotatingQuantizedKVCache &&
302
- cache[0].bits === 8 &&
303
- cache[0].groupSize === 64 &&
304
- cache[1] instanceof RotatingQuantizedKVCache &&
305
- cache[1].bits === 4 &&
306
- cache[1].groupSize === 64 &&
307
- cache[2] instanceof RotatingQuantizedKVCache &&
308
- cache[2].bits === 4 &&
309
- cache[2].groupSize === 64 &&
310
- cache[3] instanceof RotatingQuantizedKVCache &&
311
- cache[3].bits === 8 &&
312
- cache[3].groupSize === 64 &&
313
- cache[4] instanceof RotatingQuantizedKVCache &&
314
- cache[4].bits === 8 &&
315
- cache[4].groupSize === 64 &&
316
- cache[5] instanceof QuantizedKVCache &&
317
- cache[5].bits === 8 &&
318
- cache[5].groupSize === 64 &&
319
- cache[6] instanceof RotatingQuantizedKVCache &&
320
- cache[6].bits === 4 &&
321
- cache[6].groupSize === 64 &&
322
- cache[7] instanceof RotatingQuantizedKVCache &&
323
- cache[7].bits === 4 &&
324
- cache[7].groupSize === 64 &&
325
- cache[8] instanceof RotatingQuantizedKVCache &&
326
- cache[8].bits === 8 &&
327
- cache[8].groupSize === 64 &&
328
- cache[9] instanceof RotatingQuantizedKVCache &&
329
- cache[9].bits === 8 &&
330
- cache[9].groupSize === 64 &&
331
- cache[10] instanceof RotatingQuantizedKVCache &&
332
- cache[10].bits === 4 &&
333
- cache[10].groupSize === 64 &&
334
- cache[11] instanceof QuantizedKVCache &&
335
- cache[11].bits === 8 &&
336
- cache[11].groupSize === 64 &&
337
- cache[12] instanceof RotatingQuantizedKVCache &&
338
- cache[12].bits === 8 &&
339
- cache[12].groupSize === 64 &&
340
- cache[13] instanceof RotatingQuantizedKVCache &&
341
- cache[13].bits === 4 &&
342
- cache[13].groupSize === 64 &&
343
- cache[14] instanceof RotatingQuantizedKVCache &&
344
- cache[14].bits === 4 &&
345
- cache[14].groupSize === 64 &&
346
- cache[15] instanceof RotatingQuantizedKVCache &&
347
- cache[15].bits === 4 &&
348
- cache[15].groupSize === 64 &&
349
- cache[16] instanceof RotatingQuantizedKVCache &&
350
- cache[16].bits === 4 &&
351
- cache[16].groupSize === 64 &&
352
- cache[17] instanceof QuantizedKVCache &&
353
- cache[17].bits === 4 &&
354
- cache[17].groupSize === 64 &&
355
- cache[18] instanceof RotatingQuantizedKVCache &&
356
- cache[18].bits === 4 &&
357
- cache[18].groupSize === 64 &&
358
- cache[19] instanceof RotatingQuantizedKVCache &&
359
- cache[19].bits === 4 &&
360
- cache[19].groupSize === 64 &&
361
- cache[20] instanceof RotatingQuantizedKVCache &&
362
- cache[20].bits === 4 &&
363
- cache[20].groupSize === 64 &&
364
- cache[21] instanceof RotatingQuantizedKVCache &&
365
- cache[21].bits === 4 &&
366
- cache[21].groupSize === 64 &&
367
- cache[22] instanceof RotatingQuantizedKVCache &&
368
- cache[22].bits === 4 &&
369
- cache[22].groupSize === 64 &&
370
- cache[23] instanceof QuantizedKVCache &&
371
- cache[23].bits === 4 &&
372
- cache[23].groupSize === 64 &&
373
- cache[24] instanceof RotatingQuantizedKVCache &&
374
- cache[24].bits === 4 &&
375
- cache[24].groupSize === 64 &&
376
- cache[25] instanceof RotatingQuantizedKVCache &&
377
- cache[25].bits === 4 &&
378
- cache[25].groupSize === 64 &&
379
- cache[26] instanceof RotatingQuantizedKVCache &&
380
- cache[26].bits === 4 &&
381
- cache[26].groupSize === 64 &&
382
- cache[27] instanceof RotatingQuantizedKVCache &&
383
- cache[27].bits === 4 &&
384
- cache[27].groupSize === 64 &&
385
- cache[28] instanceof RotatingQuantizedKVCache &&
386
- cache[28].bits === 4 &&
387
- cache[28].groupSize === 64 &&
388
- cache[29] instanceof QuantizedKVCache &&
389
- cache[29].bits === 4 &&
390
- cache[29].groupSize === 64
301
+ cacheSignature(cache[0]) === "kv:rotating-quant:8:64" &&
302
+ cacheSignature(cache[1]) === "kv:rotating-quant:4:64" &&
303
+ cacheSignature(cache[2]) === "kv:rotating-quant:4:64" &&
304
+ cacheSignature(cache[3]) === "kv:rotating-quant:8:64" &&
305
+ cacheSignature(cache[4]) === "kv:rotating-quant:8:64" &&
306
+ cacheSignature(cache[5]) === "kv:quant:8:64" &&
307
+ cacheSignature(cache[6]) === "kv:rotating-quant:4:64" &&
308
+ cacheSignature(cache[7]) === "kv:rotating-quant:4:64" &&
309
+ cacheSignature(cache[8]) === "kv:rotating-quant:8:64" &&
310
+ cacheSignature(cache[9]) === "kv:rotating-quant:8:64" &&
311
+ cacheSignature(cache[10]) === "kv:rotating-quant:4:64" &&
312
+ cacheSignature(cache[11]) === "kv:quant:8:64" &&
313
+ cacheSignature(cache[12]) === "kv:rotating-quant:8:64" &&
314
+ cacheSignature(cache[13]) === "kv:rotating-quant:4:64" &&
315
+ cacheSignature(cache[14]) === "kv:rotating-quant:4:64" &&
316
+ cacheSignature(cache[15]) === "kv:rotating-quant:4:64" &&
317
+ cacheSignature(cache[16]) === "kv:rotating-quant:4:64" &&
318
+ cacheSignature(cache[17]) === "kv:quant:4:64" &&
319
+ cacheSignature(cache[18]) === "kv:rotating-quant:4:64" &&
320
+ cacheSignature(cache[19]) === "kv:rotating-quant:4:64" &&
321
+ cacheSignature(cache[20]) === "kv:rotating-quant:4:64" &&
322
+ cacheSignature(cache[21]) === "kv:rotating-quant:4:64" &&
323
+ cacheSignature(cache[22]) === "kv:rotating-quant:4:64" &&
324
+ cacheSignature(cache[23]) === "kv:quant:4:64" &&
325
+ cacheSignature(cache[24]) === "kv:rotating-quant:4:64" &&
326
+ cacheSignature(cache[25]) === "kv:rotating-quant:4:64" &&
327
+ cacheSignature(cache[26]) === "kv:rotating-quant:4:64" &&
328
+ cacheSignature(cache[27]) === "kv:rotating-quant:4:64" &&
329
+ cacheSignature(cache[28]) === "kv:rotating-quant:4:64" &&
330
+ cacheSignature(cache[29]) === "kv:quant:4:64"
391
331
  );
392
332
  }
393
333
 
@@ -4,14 +4,15 @@
4
4
  // fingerprint: 418e9adc386ea67c
5
5
  //
6
6
  // Branch-resolved, unrolled forward pass for this architecture
7
- // (docs/design/optimization_plan.md Phase C). Bit-exactness vs the monolith is the
8
- // generator's gate: tests/generated-parity.test.ts. The cache-signature
7
+ // (docs/archive/investigations/optimization_plan.md Phase C). Bit-exactness vs the monolith is the
8
+ // generator's gate: tests/parity/generated-parity.test.ts. The cache-signature
9
9
  // guard falls back to the monolith for anything this file wasn't
10
10
  // generated for (bf16 compat runs, vision bidir prefill).
11
11
 
12
12
  import { MlxArray } from "../../mlx/array";
13
13
  import * as ops from "../../mlx/ops";
14
14
  import {
15
+ cacheSignature,
15
16
  disposing,
16
17
  fusedSdpaRuntimeOk,
17
18
  KVCache,
@@ -529,83 +530,34 @@ function sharerFullQuantG64B4VPliScal(layer: DecoderLayer, x: MlxArray, mask: Ma
529
530
  }
530
531
 
531
532
  export class GeneratedGemma4 extends Gemma4Model {
532
- /** Per-layer cache classes must match what this file was generated
533
- * for; anything else runs the monolith path. */
533
+ /** Per-layer cache signatures must match what this file was generated for. */
534
534
  #matches(cache: Cache[]): boolean {
535
535
  return (
536
536
  cache.length === 24 &&
537
- cache[0] instanceof RotatingQuantizedKVCache &&
538
- cache[0].bits === 4 &&
539
- cache[0].groupSize === 64 &&
540
- cache[1] instanceof RotatingQuantizedKVCache &&
541
- cache[1].bits === 4 &&
542
- cache[1].groupSize === 64 &&
543
- cache[2] instanceof RotatingQuantizedKVCache &&
544
- cache[2].bits === 4 &&
545
- cache[2].groupSize === 64 &&
546
- cache[3] instanceof RotatingQuantizedKVCache &&
547
- cache[3].bits === 8 &&
548
- cache[3].groupSize === 64 &&
549
- cache[4] instanceof RotatingQuantizedKVCache &&
550
- cache[4].bits === 8 &&
551
- cache[4].groupSize === 64 &&
552
- cache[5] instanceof QuantizedKVCache &&
553
- cache[5].bits === 4 &&
554
- cache[5].groupSize === 64 &&
555
- cache[6] instanceof RotatingQuantizedKVCache &&
556
- cache[6].bits === 4 &&
557
- cache[6].groupSize === 64 &&
558
- cache[7] instanceof RotatingQuantizedKVCache &&
559
- cache[7].bits === 4 &&
560
- cache[7].groupSize === 64 &&
561
- cache[8] instanceof RotatingQuantizedKVCache &&
562
- cache[8].bits === 4 &&
563
- cache[8].groupSize === 64 &&
564
- cache[9] instanceof RotatingQuantizedKVCache &&
565
- cache[9].bits === 8 &&
566
- cache[9].groupSize === 64 &&
567
- cache[10] instanceof RotatingQuantizedKVCache &&
568
- cache[10].bits === 8 &&
569
- cache[10].groupSize === 64 &&
570
- cache[11] instanceof QuantizedKVCache &&
571
- cache[11].bits === 8 &&
572
- cache[11].groupSize === 64 &&
573
- cache[12] instanceof RotatingQuantizedKVCache &&
574
- cache[12].bits === 4 &&
575
- cache[12].groupSize === 64 &&
576
- cache[13] instanceof RotatingQuantizedKVCache &&
577
- cache[13].bits === 4 &&
578
- cache[13].groupSize === 64 &&
579
- cache[14] instanceof RotatingQuantizedKVCache &&
580
- cache[14].bits === 8 &&
581
- cache[14].groupSize === 64 &&
582
- cache[15] instanceof RotatingQuantizedKVCache &&
583
- cache[15].bits === 4 &&
584
- cache[15].groupSize === 64 &&
585
- cache[16] instanceof RotatingQuantizedKVCache &&
586
- cache[16].bits === 4 &&
587
- cache[16].groupSize === 64 &&
588
- cache[17] instanceof QuantizedKVCache &&
589
- cache[17].bits === 4 &&
590
- cache[17].groupSize === 64 &&
591
- cache[18] instanceof RotatingQuantizedKVCache &&
592
- cache[18].bits === 4 &&
593
- cache[18].groupSize === 64 &&
594
- cache[19] instanceof RotatingQuantizedKVCache &&
595
- cache[19].bits === 4 &&
596
- cache[19].groupSize === 64 &&
597
- cache[20] instanceof RotatingQuantizedKVCache &&
598
- cache[20].bits === 4 &&
599
- cache[20].groupSize === 64 &&
600
- cache[21] instanceof RotatingQuantizedKVCache &&
601
- cache[21].bits === 4 &&
602
- cache[21].groupSize === 64 &&
603
- cache[22] instanceof RotatingQuantizedKVCache &&
604
- cache[22].bits === 4 &&
605
- cache[22].groupSize === 64 &&
606
- cache[23] instanceof QuantizedKVCache &&
607
- cache[23].bits === 4 &&
608
- cache[23].groupSize === 64
537
+ cacheSignature(cache[0]) === "kv:rotating-quant:4:64" &&
538
+ cacheSignature(cache[1]) === "kv:rotating-quant:4:64" &&
539
+ cacheSignature(cache[2]) === "kv:rotating-quant:4:64" &&
540
+ cacheSignature(cache[3]) === "kv:rotating-quant:8:64" &&
541
+ cacheSignature(cache[4]) === "kv:rotating-quant:8:64" &&
542
+ cacheSignature(cache[5]) === "kv:quant:4:64" &&
543
+ cacheSignature(cache[6]) === "kv:rotating-quant:4:64" &&
544
+ cacheSignature(cache[7]) === "kv:rotating-quant:4:64" &&
545
+ cacheSignature(cache[8]) === "kv:rotating-quant:4:64" &&
546
+ cacheSignature(cache[9]) === "kv:rotating-quant:8:64" &&
547
+ cacheSignature(cache[10]) === "kv:rotating-quant:8:64" &&
548
+ cacheSignature(cache[11]) === "kv:quant:8:64" &&
549
+ cacheSignature(cache[12]) === "kv:rotating-quant:4:64" &&
550
+ cacheSignature(cache[13]) === "kv:rotating-quant:4:64" &&
551
+ cacheSignature(cache[14]) === "kv:rotating-quant:8:64" &&
552
+ cacheSignature(cache[15]) === "kv:rotating-quant:4:64" &&
553
+ cacheSignature(cache[16]) === "kv:rotating-quant:4:64" &&
554
+ cacheSignature(cache[17]) === "kv:quant:4:64" &&
555
+ cacheSignature(cache[18]) === "kv:rotating-quant:4:64" &&
556
+ cacheSignature(cache[19]) === "kv:rotating-quant:4:64" &&
557
+ cacheSignature(cache[20]) === "kv:rotating-quant:4:64" &&
558
+ cacheSignature(cache[21]) === "kv:rotating-quant:4:64" &&
559
+ cacheSignature(cache[22]) === "kv:rotating-quant:4:64" &&
560
+ cacheSignature(cache[23]) === "kv:quant:4:64"
609
561
  );
610
562
  }
611
563
 
@@ -88,7 +88,7 @@ function trimToTokens(array: MlxArray, tokens: number): MlxArray {
88
88
  const stop = [...array.shape];
89
89
  stop[1] = tokens;
90
90
  const view = array.slice(start, stop);
91
- const exact = ops.contiguous(view);
91
+ const exact = ops.copyOf(view); // TRUE copy: see 2026-08-20 contiguous-view pin class
92
92
  view.dispose();
93
93
  return exact;
94
94
  }
@@ -225,6 +225,15 @@ export class Glm52Cache implements BatchableCache {
225
225
  throw new Error("native MTP cache cannot contain target DSA state");
226
226
  }
227
227
 
228
+ signature(): string {
229
+ if (this.role === "mtp") return "kv:mla:mtp";
230
+ return this.dsa ? "kv:mla:target:dsa" : "kv:mla:target";
231
+ }
232
+
233
+ bytesPerToken(): number {
234
+ return (this.kvLoraRank + this.ropeHeadDim + (this.dsa?.headDim ?? 0)) * 4;
235
+ }
236
+
228
237
  /** Append one equal-width row block without expanding it to per-head K/V. */
229
238
  append(latent: MlxArray, rope: MlxArray, dsa: MlxArray | null = null): void {
230
239
  const latentShape = latent.shape;
@@ -620,15 +629,16 @@ export class Glm52Cache implements BatchableCache {
620
629
  const nextWidth = this.offset - removablePad;
621
630
  const indices = ops.fromInt32([...keep], [keep.length]);
622
631
  const filterFamily = (array: MlxArray): MlxArray => {
623
- const selected = ops.takeAxis(array, indices, 0);
624
- if (removablePad === 0) return selected;
625
- const view = selected.slice(
626
- [0, removablePad, 0],
627
- [keep.length, this.offset, array.shape[2]!],
628
- );
629
- const exact = ops.contiguous(view);
632
+ const trimmed = removablePad === 0
633
+ ? array
634
+ : array.slice(
635
+ [0, removablePad, 0],
636
+ [this.batchSize!, this.offset, array.shape[2]!],
637
+ );
638
+ const selected = ops.takeAxis(trimmed, indices, 0);
639
+ const exact = ops.copyOf(selected); // TRUE copy: see 2026-08-20 contiguous-view pin class
630
640
  selected.dispose();
631
- view.dispose();
641
+ if (trimmed !== array) trimmed.dispose();
632
642
  return exact;
633
643
  };
634
644
 
@@ -291,7 +291,7 @@ function getDsaRankKeyKernel(): MetalKernel {
291
291
  ? ~bits
292
292
  : (bits ^ 0x80000000u);
293
293
  const uint descending = ~ascending;
294
- keys[i] = (ulong(descending) << 32) | ulong(i);
294
+ keys[i] = descending;
295
295
  `,
296
296
  });
297
297
  }
@@ -308,7 +308,8 @@ function getDsaContractOrderKeyKernel(): MetalKernel {
308
308
  const uint i = thread_position_in_grid.x;
309
309
  const uint position = selected_positions[i];
310
310
  const uint threshold_class = selected_scores[i] > threshold ? 0u : 1u;
311
- keys[i] = (ulong(threshold_class) << 32) | ulong(position);
311
+ // MLX axis lengths are signed int32; positions leave the high bit free.
312
+ keys[i] = (threshold_class << 31) | position;
312
313
  `,
313
314
  });
314
315
  }
@@ -318,8 +319,8 @@ function getDsaContractOrderKeyKernel(): MetalKernel {
318
319
  /**
319
320
  * Deterministic on-device equivalent of `selectDsaThresholdTiesF32`.
320
321
  *
321
- * The first uint64 key sorts by score descending and then position ascending,
322
- * making the top-k set deterministic even at the threshold. The second key
322
+ * Stable sorting of the first uint32 key orders scores descending and keeps
323
+ * equal-score positions ascending, including threshold ties. The second key
323
324
  * restores Colibri's observable two-scan order: all scores strictly above the
324
325
  * threshold in position order, followed by threshold ties in position order.
325
326
  * The caller owns the returned arrays and must call `dispose()` once the last
@@ -340,18 +341,21 @@ export function selectGlm52DsaDevice(
340
341
  ? scores
341
342
  : scores.astype(Dtype.float32);
342
343
  const [rankKeys] = getDsaRankKeyKernel().apply([scoresF32], {
343
- outputs: [{ shape: [contextLength], dtype: Dtype.uint64 }],
344
+ outputs: [{ shape: [contextLength], dtype: Dtype.uint32 }],
344
345
  grid: [contextLength, 1, 1],
345
346
  threadGroup: [Math.min(256, contextLength), 1, 1],
346
347
  });
347
- const partition = ops.argpartitionAxis(rankKeys!, topK - 1, 0);
348
- const selectedUnordered = partition.slice([0], [topK]);
348
+ // Stable argsort retains ascending positions for equal score bits, so the
349
+ // ranking key needs no position field. MLX 0.31.2's GPU argpartition also
350
+ // sorts fully, but does not promise this tie order in its public contract.
351
+ const rankedPositions = ops.argsortAxis(rankKeys!, 0);
352
+ const selectedUnordered = rankedPositions.slice([0], [topK]);
349
353
  const selectedScores = ops.takeAlongAxis(scoresF32, selectedUnordered, 0);
350
354
  const threshold = ops.minAxis(selectedScores, 0, false);
351
355
  const [orderKeys] = getDsaContractOrderKeyKernel().apply(
352
356
  [selectedScores, selectedUnordered, threshold],
353
357
  {
354
- outputs: [{ shape: [topK], dtype: Dtype.uint64 }],
358
+ outputs: [{ shape: [topK], dtype: Dtype.uint32 }],
355
359
  grid: [topK, 1, 1],
356
360
  threadGroup: [Math.min(256, topK), 1, 1],
357
361
  },
@@ -360,7 +364,7 @@ export function selectGlm52DsaDevice(
360
364
  const positions = ops.takeAlongAxis(selectedUnordered, order, 0);
361
365
 
362
366
  rankKeys!.dispose();
363
- partition.dispose();
367
+ rankedPositions.dispose();
364
368
  selectedUnordered.dispose();
365
369
  selectedScores.dispose();
366
370
  orderKeys!.dispose();
@@ -4,6 +4,7 @@ import {
4
4
  type Glm52Config,
5
5
  } from "./glm52-config";
6
6
  import { ColibriGlm52Container } from "./glm52-container";
7
+ import type { MemoryPlan } from "../admission-plan";
7
8
 
8
9
  export const GLM52_G5_GIB = 1024 ** 3;
9
10
  export const GLM52_G5_DEFAULT_MACHINE_BYTES = 32 * GLM52_G5_GIB;
@@ -73,8 +74,9 @@ export interface Glm52MemoryLineItems {
73
74
  readonly safetyMarginBytes: number;
74
75
  }
75
76
 
76
- export interface Glm52MemoryPlan {
77
+ export interface Glm52MemoryPlan extends MemoryPlan {
77
78
  readonly schemaVersion: 1;
79
+ readonly strategy: "glm52-colibri";
78
80
  readonly preset: "g5-32gb-quality";
79
81
  readonly machineBytes: number;
80
82
  readonly processLimitBytes: number;
@@ -374,11 +376,14 @@ export function planGlm52Memory(
374
376
 
375
377
  return {
376
378
  schemaVersion: 1,
379
+ strategy: "glm52-colibri",
380
+ fits: true,
377
381
  preset: "g5-32gb-quality",
378
382
  machineBytes,
379
383
  processLimitBytes,
380
384
  osReserveBytes,
381
385
  contextTokens,
386
+ maxSafeContext: contextTokens,
382
387
  maxGenerationTokens,
383
388
  batchSize,
384
389
  enableMtp,
@@ -392,6 +397,28 @@ export function planGlm52Memory(
392
397
  mtpResidentSlots,
393
398
  mtpTotalSlots,
394
399
  lineItems,
400
+ weightsBytes: sum("GLM planned weights", [
401
+ lineItems.residentWeightsBytes,
402
+ lineItems.mainExpertSlabBytes,
403
+ lineItems.mtpExpertSlabBytes,
404
+ ]),
405
+ kvBytes: sum("GLM planned KV", [
406
+ lineItems.targetKvBytes,
407
+ lineItems.mtpKvBytes,
408
+ ]),
409
+ transientBytes: sum("GLM planned transient", [
410
+ lineItems.reconstructedKvTransientBytes,
411
+ lineItems.verifyBatchTransientBytes,
412
+ ]),
413
+ reserveBytes: sum("GLM planned reserves", [
414
+ lineItems.allocatorReserveBytes,
415
+ lineItems.bunNativeReserveBytes,
416
+ lineItems.safetyMarginBytes,
417
+ ]),
418
+ totalBytes: plannedProcessBytes,
419
+ usableBytes: processLimitBytes,
420
+ predictedDecodeTps: null,
421
+ allocatorLimitBytes: lineItems.allocatorReserveBytes,
395
422
  runtimeReserveBytes,
396
423
  plannedProcessBytes,
397
424
  processHeadroomBytes: processLimitBytes - plannedProcessBytes,
@@ -0,0 +1,69 @@
1
+ import type { ModelConfig } from "../config";
2
+ import {
3
+ assertResolvedModelProfile,
4
+ type GenerationLoop,
5
+ type ModelGraph,
6
+ type ModelLoader,
7
+ type ResolvedModelProfile,
8
+ } from "./profile";
9
+
10
+ /** Engine code implements this port. Source and Model remain backend-specific;
11
+ * selection introduces no tensor conversion or dispatch in the token loop.
12
+ * create borrows source; a failed construction must release its own resources. */
13
+ export interface ModelImplementation<Source, Model> {
14
+ readonly id: string;
15
+ readonly graph: ModelGraph;
16
+ readonly loader: ModelLoader;
17
+ readonly loop: GenerationLoop;
18
+ create(source: Source, config: ModelConfig, profile: ResolvedModelProfile): Model;
19
+ }
20
+
21
+ export interface ModelImplementationProvider<Source, Model> {
22
+ /** Validate identity and composition, then return one compatible binding.
23
+ * A declared implementation must never silently fall back to another. */
24
+ select(config: ModelConfig, profile: ResolvedModelProfile): ModelImplementation<Source, Model>;
25
+ }
26
+
27
+ /** Immutable composition, with identity matching delegated to model profiles.
28
+ * Exact declarations are requirements: absent/incompatible code is an error,
29
+ * never an invitation to retry with a different numerical implementation. */
30
+ export class ModelImplementationRegistry<Source, Model> implements ModelImplementationProvider<Source, Model> {
31
+ private readonly entries: ReadonlyMap<string, ModelImplementation<Source, Model>>;
32
+
33
+ constructor(implementations: readonly ModelImplementation<Source, Model>[]) {
34
+ const entries = new Map<string, ModelImplementation<Source, Model>>();
35
+ for (const implementation of implementations) {
36
+ if (!implementation.id.trim()) throw new Error("model implementation id must not be empty");
37
+ if (entries.has(implementation.id))
38
+ throw new Error(`duplicate model implementation ${implementation.id}`);
39
+ entries.set(implementation.id, Object.freeze({
40
+ id: implementation.id,
41
+ graph: implementation.graph,
42
+ loader: implementation.loader,
43
+ loop: implementation.loop,
44
+ create: implementation.create.bind(implementation),
45
+ }));
46
+ }
47
+ this.entries = entries;
48
+ }
49
+
50
+ /** Return a new composition; active models retain their existing binding. */
51
+ with(...implementations: readonly ModelImplementation<Source, Model>[]): ModelImplementationRegistry<Source, Model> {
52
+ return new ModelImplementationRegistry([...this.entries.values(), ...implementations]);
53
+ }
54
+
55
+ select(config: ModelConfig, profile: ResolvedModelProfile): ModelImplementation<Source, Model> {
56
+ assertResolvedModelProfile(config, profile);
57
+ const execution = profile.profile.execution;
58
+ // These default IDs preserve the existing dedicated/generated/family choice.
59
+ const id = execution.implementation ?? (execution.specialization === "generated"
60
+ ? `${execution.graph}-generated` : execution.graph);
61
+ const implementation = this.entries.get(id);
62
+ if (!implementation)
63
+ throw new Error(`model profile ${profile.profile.id} requires unavailable implementation ${id}; refusing to fall back`);
64
+ if (implementation.graph !== execution.graph || implementation.loader !== execution.loader ||
65
+ implementation.loop !== execution.loop)
66
+ throw new Error(`model implementation ${id} is incompatible with profile ${profile.profile.id}; refusing to fall back`);
67
+ return implementation;
68
+ }
69
+ }
@@ -24,12 +24,13 @@ import {
24
24
  type Mask,
25
25
  } from "./gemma4-base";
26
26
  import { CompiledFunction } from "../mlx/compile";
27
+ import { runtimeValue } from "../runtime-config";
27
28
 
28
29
  /** Verbatim port of mlx_lm/models/activations.py:
29
30
  * `@partial(mx.compile, shapeless=True) def swiglu(gate, x): return nn.silu(gate) * x`
30
31
  * mx.compile fuses sigmoid + mul + mul into ONE kernel (mlx-lm's decode
31
32
  * `CV2ISigmoid…Multiply`) instead of our three separate dispatches. Traced
32
- * once, replayed thereafter. Used on the decode (M=1) path only. */
33
+ * once, replayed thereafter for decode and prefill. */
33
34
  let _swigluClosure: CompiledFunction | null = null;
34
35
  export function compiledSwiglu(gate: MlxArray, up: MlxArray): MlxArray {
35
36
  if (!_swigluClosure) {
@@ -199,15 +200,13 @@ export class LlamaMLP {
199
200
 
200
201
  /** MLP: returns mlp(x); the caller adds the residual when given. */
201
202
  forward(x: MlxArray, residual?: MlxArray): MlxArray {
202
- const H = x.shape[x.shape.length - 1]!;
203
- const M = x.shape.reduce((a, b) => a * b, 1) / H;
204
203
  const gate = this.gate.forward(x);
205
204
  const up = this.up.forward(x);
206
- // Decode (M=1): fuse silu·up into one kernel (mlx_lm activations.py swiglu).
207
- // Plain sigmoid+mul+mul otherwise (M>1 prefill/training, or inside a compile
208
- // trace) — identical math either way. MLX_BUN_COMPILED_SWIGLU=0 disables.
205
+ // Match mlx_lm activations.py at every sequence length. Separate kernels
206
+ // differ numerically on MLX 0.32.2 at larger prefill shapes. An enclosing
207
+ // compiled trace owns fusion itself; the explicit opt-out stays available.
209
208
  let hidden: MlxArray;
210
- if (M === 1 && !isCompiledTrace() && process.env.MLX_BUN_COMPILED_SWIGLU !== "0") {
209
+ if (!isCompiledTrace() && runtimeValue("MLX_BUN_COMPILED_SWIGLU") !== "0") {
211
210
  hidden = compiledSwiglu(gate, up);
212
211
  gate.dispose();
213
212
  up.dispose();
@@ -320,7 +319,7 @@ export class MiniCPM5Model {
320
319
  * NEVER disposed — the caller owns it (for segmented backward `h` is a leaf
321
320
  * whose lifetime is managed by the autograd closure); intra-range
322
321
  * intermediates ARE disposed. Building block for `forwardLayers` and the
323
- * segmented-backward training path (docs/design/segmented-backward-training.md).
322
+ * segmented-backward training path (docs/design/orpo-training.md).
324
323
  * MiniCPM5 is plain full-attention with no KV-sharing, so each layer reads
325
324
  * its own stateless `cache[i]` and a single causal mask. */
326
325
  runLayerRange(h: MlxArray, aIdx: number, bIdx: number, cache: Cache[]): MlxArray {