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
@@ -0,0 +1,252 @@
1
+ // Qwen3.5/3.8 multimodal RoPE (mRoPE) — the language-side position machinery
2
+ // for vision requests (PLAN 14v), port of mlx-vlm's qwen3_5 language rope:
3
+ // MRoPERotaryEmbedding (style "interleaved", mrope_section [11,11,10]) +
4
+ // get_rope_index + the rope_deltas decode continuation.
5
+ //
6
+ // TEXT-ONLY EQUIVALENCE: with all three position streams equal, interleaved
7
+ // selection collapses to plain partial RoPE — which is why the text path's
8
+ // ops.rope stays bit-exact untouched. This module only activates for
9
+ // requests whose prompt contains vision spans; while active, EVERY
10
+ // full-attention rope in the request (prefill AND decode) goes through the
11
+ // manual interleaved path, mirroring the reference (which never uses the
12
+ // fused fast-rope kernel when position_ids are supplied).
13
+ //
14
+ // Position semantics (get_rope_index, B=1 serial): text tokens advance all
15
+ // three streams together; an image span of grid (t, h/merge, w/merge) gets
16
+ // t/h/w grid positions offset by the current base; text after an image
17
+ // resumes at max+1. delta = (max position + 1) - sequence length; decode
18
+ // positions are offset + delta on all three streams.
19
+
20
+ import { MlxArray } from "../mlx/array";
21
+ import { Dtype } from "../mlx/ffi";
22
+ import * as ops from "../mlx/ops";
23
+ import { MetalKernel } from "../mlx/metal-kernel";
24
+
25
+ export interface MropeRequestState {
26
+ /** Full-grid positions for the prompt, one Int32Array per t/h/w stream. */
27
+ positions: [Int32Array, Int32Array, Int32Array];
28
+ /** (max position + 1) - promptLength; decode positions = offset + delta. */
29
+ delta: number;
30
+ }
31
+
32
+ export interface MropeForwardState {
33
+ /** Effective positions [3, 1, L] int32 for the CURRENT forward window. */
34
+ posIds: MlxArray;
35
+ /** Borrowed model-owned f32 inv_freq (mropeInvFreq) — not disposed here. */
36
+ invFreq: MlxArray;
37
+ rotaryDims: number;
38
+ }
39
+
40
+ /** Active per-forward mRoPE cos/sin, read by Qwen3Attention.forward. Null on
41
+ * the text-only path (serial lane only — vision requests never batch). */
42
+ export let activeMrope: MropeForwardState | null = null;
43
+ export function setActiveMrope(s: MropeForwardState | null): void {
44
+ activeMrope = s;
45
+ }
46
+
47
+ const MROPE_SECTION = [11, 11, 10] as const;
48
+
49
+ /** Interleaved frequency→stream selector (rope_utils
50
+ * _interleaved_position_selector): default t(0); indices 1,4,7,… take
51
+ * h(1) while < section[1]*3; indices 2,5,8,… take w(2) while < section[2]*3. */
52
+ export function interleavedSelector(freqDim: number): Int32Array {
53
+ const sel = new Int32Array(freqDim);
54
+ for (let dim = 1; dim <= 2; dim++) {
55
+ const offset = dim; // h starts at 1, w at 2
56
+ for (let i = offset; i < Math.min(MROPE_SECTION[dim]! * 3, freqDim); i += 3)
57
+ sel[i] = dim;
58
+ }
59
+ return sel;
60
+ }
61
+
62
+ /** inv_freq for the language rope — computed on-device exactly like
63
+ * compute_inv_freq (Metal powf is not correctly rounded; a JS emulation
64
+ * drifts by 1 ulp on some entries). Returned as a live f32 device array
65
+ * (the apply kernel reads it directly). */
66
+ export function mropeInvFreq(rotaryDims: number, base: number): MlxArray {
67
+ const ar = ops.arange(0, rotaryDims, 2, Dtype.float32);
68
+ const ex = ops.mulScalar(ar, 1 / rotaryDims);
69
+ ar.dispose();
70
+ const theta = MlxArray.fromFloat32(Float32Array.from([base]), [1]);
71
+ const p = ops.pow(theta, ex);
72
+ theta.dispose();
73
+ ex.dispose();
74
+ const one = MlxArray.fromFloat32(Float32Array.from([1]), [1]);
75
+ const invA = ops.div(one, p);
76
+ one.dispose();
77
+ p.dispose();
78
+ return invA;
79
+ }
80
+
81
+ /** Effective positions [3,1,L] int32 for window [offset, offset+L) —
82
+ * prompt-grid positions while inside the prompt, offset+delta beyond it
83
+ * (the reference's rope_deltas continuation). */
84
+ export function buildMropePositions(
85
+ state: MropeRequestState, offset: number, L: number,
86
+ invFreq: MlxArray, rotaryDims: number,
87
+ ): MropeForwardState {
88
+ const P = state.positions;
89
+ const promptLen = P[0].length;
90
+ const joint = new Int32Array(3 * L);
91
+ for (let axis = 0; axis < 3; axis++) {
92
+ for (let l = 0; l < L; l++) {
93
+ const idx = offset + l;
94
+ joint[axis * L + l] = idx < promptLen ? P[axis]![idx]! : idx + state.delta;
95
+ }
96
+ }
97
+ return { posIds: MlxArray.fromInt32(joint, [3, 1, L]), invFreq, rotaryDims };
98
+ }
99
+
100
+ // The reference language-side apply is a CUSTOM METAL KERNEL (rope_utils
101
+ // _mrope_apply_kernel, pairing "half_split", position_ndim 3): per rotated
102
+ // pair it computes angle = pos * inv_freq in f32, cos/sin in-kernel, and
103
+ // writes x*c − x_pair*s / x_pair*c + x*s with ONE rounding to the tensor
104
+ // dtype. A bf16 cos/sin manual path is ~0.4% off per rotation and moved
105
+ // step-0 logits by ~1.0 — this verbatim port is the oracle's arithmetic.
106
+ const kernelCache = new Map<number, MetalKernel>();
107
+ function mropeKernel(rotaryDims: number): MetalKernel {
108
+ let k = kernelCache.get(rotaryDims);
109
+ if (k) return k;
110
+ const half = rotaryDims / 2;
111
+ const source = `
112
+ uint elem = thread_position_in_grid.x;
113
+
114
+ const int half_dim = ${half};
115
+ const int q_bsz = x_shape[0];
116
+ const int q_heads = x_shape[1];
117
+ const int q_len = x_shape[2];
118
+ const int q_dim = x_shape[3];
119
+ const int slots = half_dim + q_dim - ${rotaryDims};
120
+ const int work_size = q_bsz * q_heads * q_len * slots;
121
+
122
+ if (elem >= uint(work_size)) {
123
+ return;
124
+ }
125
+
126
+ int local = int(elem);
127
+ int slot = local % slots;
128
+ int tmp = local / slots;
129
+ int t = tmp % q_len;
130
+ tmp = tmp / q_len;
131
+ int h = tmp % q_heads;
132
+ int b = tmp / q_heads;
133
+ int base = ((b * q_heads + h) * q_len + t) * q_dim;
134
+
135
+ if (slot >= half_dim) {
136
+ int pass_d = ${rotaryDims} + slot - half_dim;
137
+ int pass_idx = base + pass_d;
138
+ x_out[pass_idx] = x[pass_idx];
139
+ return;
140
+ }
141
+
142
+ int freq_idx = slot;
143
+ int d = freq_idx;
144
+ int pair_d = d + half_dim;
145
+ int axis = int(position_selector[freq_idx]);
146
+ float pos = static_cast<float>(position_ids[(axis * q_bsz + b) * q_len + t]);
147
+ float angle = pos * static_cast<float>(inv_freq[freq_idx]);
148
+ float c = metal::cos(angle);
149
+ float s = metal::sin(angle);
150
+
151
+ int idx = base + d;
152
+ float xv = static_cast<float>(x[idx]);
153
+ float xp = static_cast<float>(x[base + pair_d]);
154
+ x_out[idx] = static_cast<T>(xv * c - xp * s);
155
+ x_out[base + pair_d] = static_cast<T>(xp * c + xv * s);
156
+ `;
157
+ k = new MetalKernel({
158
+ name: `mrope_apply_half_split_${rotaryDims}_3d`,
159
+ inputNames: ["x", "position_ids", "inv_freq", "position_selector"],
160
+ outputNames: ["x_out"],
161
+ source,
162
+ ensureRowContiguous: true,
163
+ });
164
+ kernelCache.set(rotaryDims, k);
165
+ return k;
166
+ }
167
+
168
+ const selectorCache = new Map<number, MlxArray>();
169
+ function selectorArr(half: number): MlxArray {
170
+ let s = selectorCache.get(half);
171
+ if (!s) {
172
+ s = MlxArray.fromInt32(interleavedSelector(half), [half]);
173
+ selectorCache.set(half, s);
174
+ }
175
+ return s;
176
+ }
177
+
178
+ /** Apply interleaved mRoPE to one [B, heads, L, headDim] tensor via the
179
+ * reference's exact Metal kernel. `invFreq` is the f32 device array from
180
+ * mropeInvFreq. */
181
+ export function applyInterleavedRope(
182
+ x: MlxArray, fwd: MropeForwardState,
183
+ ): MlxArray {
184
+ const rotaryDims = fwd.rotaryDims;
185
+ const [B, H, L, D] = x.shape as [number, number, number, number];
186
+ const half = rotaryDims / 2;
187
+ const slots = half + D - rotaryDims;
188
+ const work = B * H * L * slots;
189
+ const [out] = mropeKernel(rotaryDims).apply(
190
+ [x, fwd.posIds, fwd.invFreq, selectorArr(half)],
191
+ {
192
+ outputs: [{ shape: [B, H, L, D], dtype: x.dtype }],
193
+ grid: [work, 1, 1],
194
+ threadGroup: [256, 1, 1],
195
+ templateDtypes: { T: x.dtype },
196
+ },
197
+ );
198
+ return out!;
199
+ }
200
+
201
+ /** get_rope_index port (B=1, no attention mask): positions per stream + the
202
+ * decode delta for a prompt with vision spans. `grids` are the per-image
203
+ * (t, h, w) grids in PATCH units and must appear in prompt order. */
204
+ export function qwenRopeIndex(
205
+ ids: readonly number[],
206
+ grids: readonly [number, number, number][],
207
+ mergeSize: number,
208
+ imageTokenId: number,
209
+ videoTokenId: number,
210
+ ): MropeRequestState {
211
+ const L = ids.length;
212
+ const P: [Int32Array, Int32Array, Int32Array] =
213
+ [new Int32Array(L), new Int32Array(L), new Int32Array(L)];
214
+ let write = 0; // next output index (== st in the reference walk)
215
+ let base = 0; // st_idx: next position after everything placed so far
216
+ let gi = 0;
217
+ let i = 0;
218
+ while (i < L) {
219
+ const tok = ids[i]!;
220
+ if ((tok === imageTokenId || tok === videoTokenId) && gi < grids.length) {
221
+ const [t, h, w] = grids[gi]!;
222
+ gi++;
223
+ const gh = Math.trunc(h / mergeSize);
224
+ const gw = Math.trunc(w / mergeSize);
225
+ const span = t * gh * gw;
226
+ for (let k = 0; k < span; k++) {
227
+ const tt = Math.trunc(k / (gh * gw));
228
+ const rem = k % (gh * gw);
229
+ const hh = Math.trunc(rem / gw);
230
+ const ww = rem % gw;
231
+ P[0][write + k] = base + tt;
232
+ P[1][write + k] = base + hh;
233
+ P[2][write + k] = base + ww;
234
+ }
235
+ // Reference: next base = max position in the span + 1 = base +
236
+ // max(t, gh, gw) … computed as llm_pos_ids.max()+1.
237
+ base = base + Math.max(t, gh, gw);
238
+ write += span;
239
+ i += span;
240
+ } else {
241
+ P[0][write] = base;
242
+ P[1][write] = base;
243
+ P[2][write] = base;
244
+ base++;
245
+ write++;
246
+ i++;
247
+ }
248
+ }
249
+ if (write !== L)
250
+ throw new Error(`qwenRopeIndex covered ${write} of ${L} tokens (grids misaligned?)`);
251
+ return { positions: P, delta: base - L };
252
+ }
@@ -0,0 +1,164 @@
1
+ // Qwen3.5 checkpoint-generation normalization — the load-seam port of
2
+ // mlx_lm.models.qwen3_5's `Model.sanitize` + `TextModel.sanitize`.
3
+ //
4
+ // Two checkpoint generations ship the same graph under different conventions:
5
+ //
6
+ // pre-5.8 (mlx-lm-converted) 5.8-family (transformers 5.8.0 export)
7
+ // ────────────────────────── ───────────────────────────────────────
8
+ // language_model.model.* model.language_model.*
9
+ // language_model.lm_head.* lm_head.* (top level)
10
+ // vision_tower.* model.visual.*
11
+ // (no mtp tensors in-repo) mtp.* (in-repo)
12
+ // conv1d.weight [C, K, 1] conv1d.weight [C, 1, K] (HF layout)
13
+ // RMSNorm gains stored as γ RMSNorm gains stored as γ−1
14
+ //
15
+ // Our graph speaks the FIRST column (`PREFIX = "language_model"` in
16
+ // qwen3_5.ts) — which is exactly mlx-lm's post-sanitize name space — so this
17
+ // module maps the artifact onto it instead of teaching every consumer two
18
+ // namings. The rules below are a line-for-line copy of the oracle; see
19
+ // mlx_lm/models/qwen3_5.py `Model.sanitize` (naming/drop) and
20
+ // `TextModel.sanitize` (γ shift, conv layout).
21
+ //
22
+ // The γ shift is the dangerous one: a spurious +1.0 silently corrupts an old
23
+ // artifact. The oracle's discriminator is NOT the naming — it is
24
+ // should_shift = any("mtp." in k) or any conv1d.weight with shape[-1] != 1
25
+ // evaluated over the whole (post-rename, pre-drop) weight map. Reproduced
26
+ // verbatim. Measured on the two artifacts in play (2026-09-01, M1 Max):
27
+ // • ~/.cache/…/models--mjriii--Qwen3.8-27B/snapshots/staged — no mtp.*,
28
+ // conv1d [10240,4,1] → no shift; layer-0 input_layernorm ≡ 1.0.
29
+ // • /Volumes/MLX-Models/models/mjriii/Qwen3.8-27B-{tqalloc-norot,rtn4-g64}
30
+ // — 31 mtp.* tensors, conv1d [10240,1,4] → shift; layer-0
31
+ // input_layernorm mean −0.0334 (= γ−1), byte-identical to the raw
32
+ // Qwen/Qwen3.8-27B 5.8 checkpoint (the quantizer copies norms verbatim).
33
+
34
+ import type { MlxArray } from "../mlx/array";
35
+ import * as ops from "../mlx/ops";
36
+ import type { Weights, WeightsView } from "../weights";
37
+
38
+ /** Header-level facts about one stored tensor (no bytes are read). */
39
+ export interface CheckpointTensor {
40
+ readonly name: string;
41
+ readonly shape: readonly number[];
42
+ }
43
+
44
+ export interface Qwen35Sanitized {
45
+ /** canonical (graph) name → the name the artifact actually stores. */
46
+ readonly names: Map<string, string>;
47
+ /** Canonical names stored as γ−1: a +1.0 is due at load. */
48
+ readonly normShift: Set<string>;
49
+ /** Canonical names in HF conv layout: a moveaxis(2, 1) is due at load. */
50
+ readonly convMoveaxis: Set<string>;
51
+ /** True when the artifact already IS our canonical layout — no view needed
52
+ * and the pre-existing load path runs untouched. */
53
+ readonly identity: boolean;
54
+ }
55
+
56
+ /** mlx-lm `TextModel.sanitize` norm_keys, verbatim and in order. */
57
+ const NORM_KEYS = [
58
+ ".input_layernorm.weight",
59
+ ".post_attention_layernorm.weight",
60
+ "model.norm.weight",
61
+ ".q_norm.weight",
62
+ ".k_norm.weight",
63
+ ] as const;
64
+
65
+ /** mlx-lm `Model.sanitize`: drop vision, fold every naming onto
66
+ * `language_model.…`. Returns null for a dropped tensor. */
67
+ function canonicalName(key: string): string | null {
68
+ if (key.startsWith("vision_tower") || key.startsWith("model.visual")) return null;
69
+ if (key.startsWith("model.language_model"))
70
+ return "language_model.model" + key.slice("model.language_model".length);
71
+ if (key.startsWith("language_model.")) return key;
72
+ return "language_model." + key;
73
+ }
74
+
75
+ /**
76
+ * Port of mlx_lm.models.qwen3_5 `Model.sanitize` ∘ `TextModel.sanitize`,
77
+ * name/shape half. Pure: takes header facts, returns the load plan.
78
+ */
79
+ export function sanitizeQwen35Checkpoint(
80
+ tensors: Iterable<CheckpointTensor>,
81
+ ): Qwen35Sanitized {
82
+ // Pass 1 — rename (vision dropped), exactly as Model.sanitize.
83
+ const renamed: { canonical: string; source: string; shape: readonly number[] }[] = [];
84
+ let sawForeignName = false;
85
+ for (const t of tensors) {
86
+ const canonical = canonicalName(t.name);
87
+ if (canonical === null) {
88
+ sawForeignName ||= t.name.startsWith("model.visual");
89
+ continue;
90
+ }
91
+ if (canonical !== t.name) sawForeignName = true;
92
+ renamed.push({ canonical, source: t.name, shape: t.shape });
93
+ }
94
+
95
+ // Pass 2 — TextModel.sanitize's two flags, over the renamed map BEFORE the
96
+ // mtp drop (the oracle computes them first, then filters).
97
+ const hasMtpWeights = renamed.some((t) => t.canonical.includes("mtp."));
98
+ const hasUnsanitizedConv1d = renamed.some(
99
+ (t) => t.canonical.includes("conv1d.weight") && t.shape[t.shape.length - 1] !== 1,
100
+ );
101
+ const shouldShiftNormWeights = hasMtpWeights || hasUnsanitizedConv1d;
102
+
103
+ const names = new Map<string, string>();
104
+ const normShift = new Set<string>();
105
+ const convMoveaxis = new Set<string>();
106
+ for (const t of renamed) {
107
+ if (t.canonical.includes("mtp.")) continue; // oracle drops these outright
108
+ names.set(t.canonical, t.source);
109
+ if (t.canonical.includes("conv1d.weight") && t.shape[t.shape.length - 1] !== 1)
110
+ convMoveaxis.add(t.canonical);
111
+ if (
112
+ shouldShiftNormWeights &&
113
+ NORM_KEYS.some((sfx) => t.canonical.endsWith(sfx)) &&
114
+ t.shape.length === 1
115
+ )
116
+ normShift.add(t.canonical);
117
+ }
118
+
119
+ return {
120
+ names,
121
+ normShift,
122
+ convMoveaxis,
123
+ identity: !sawForeignName && !hasMtpWeights && !shouldShiftNormWeights &&
124
+ convMoveaxis.size === 0,
125
+ };
126
+ }
127
+
128
+ /**
129
+ * The {@link WeightsView} for a qwen3.5 artifact, or null when the artifact is
130
+ * already canonical (then nothing is installed and the load path is bit-for-bit
131
+ * what it was before this seam existed).
132
+ */
133
+ export function qwen35WeightsView(weights: Weights): WeightsView | null {
134
+ const plan = sanitizeQwen35Checkpoint(
135
+ weights.tensorNames.map((name) => ({ name, shape: weights.info(name).shape })),
136
+ );
137
+ if (plan.identity) return null;
138
+ return {
139
+ names: plan.names,
140
+ fixup(canonical: string, arr: MlxArray): MlxArray | null {
141
+ // Oracle order: moveaxis first, then the γ shift (disjoint sets — a
142
+ // conv1d weight is 3-D and never a norm gain).
143
+ if (plan.convMoveaxis.has(canonical)) {
144
+ // `v.moveaxis(2, 1)` on [C, 1, K] → [C, K, 1]. Materialized: the
145
+ // conv1d kernel consumes it every forward, and the transposed view
146
+ // would otherwise pin the source shard buffer.
147
+ const moved = ops.transposeAxes(arr, [0, 2, 1]);
148
+ const out = ops.contiguous(moved);
149
+ moved.dispose();
150
+ return out;
151
+ }
152
+ if (plan.normShift.has(canonical)) {
153
+ // `v + 1.0` — a weak python scalar, so the add happens at the gain's
154
+ // own dtype (bf16 here); scalarLike builds the constant host-side at
155
+ // that dtype for the same single-kernel add the reference dispatches.
156
+ const one = ops.scalarLike(1, arr);
157
+ const out = ops.add(arr, one);
158
+ one.dispose();
159
+ return out;
160
+ }
161
+ return null;
162
+ },
163
+ };
164
+ }