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
package/README.md CHANGED
@@ -1,616 +1,109 @@
1
1
  # mlx-bun
2
2
 
3
- **One command, chatting in under a minute** — a fully local AI on your
4
- Apple Silicon Mac's GPU, no Python, no API key:
5
-
6
- ```sh
7
- curl -fsSL https://mlx-bun.dev/install.sh | sh
8
- mlx-bun
9
- ```
3
+ A Bun/TypeScript native inference engine and OpenAI-compatible HTTP server
4
+ for MLX on Apple Silicon — no Python, no sidecar process. `mlx-bun serve` is
5
+ a drop-in for `mlx_lm.server` (same port, endpoints, request fields, and
6
+ flags); the correctness contract is logit parity with mlx-lm as the oracle,
7
+ verified bit-exact by the test suite. Ships as one signed, notarized binary,
8
+ plus a library-first TypeScript API for embedding generation directly in
9
+ Bun, Tauri, or Electron apps.
10
10
 
11
11
  Docs: **[mlx-bun.dev](https://mlx-bun.dev)**
12
12
 
13
- Native MLX inference for Bun, and the beginning of a one-command local AI
14
- product for Apple Silicon Macs. `mlx-bun` detects the machine, starts a useful
15
- local assistant, exposes OpenAI/Anthropic-compatible APIs, and gives
16
- TypeScript apps direct access to MLX without Python or a sidecar server.
17
-
18
- Six goals, in one binary:
19
-
20
- 1. **A drop-in replacement for `mlx_lm.server`** — same port, endpoints,
21
- request fields, and flags; stop the Python server, start `mlx-bun serve`,
22
- the same curl works ([site guide](https://mlx-bun.dev/guides/drop-in-mlx-lm/)).
23
- 2. **A TypeScript library** — embed MLX generation in Bun/Tauri/Electron apps,
24
- or ship it as a signed single-binary sidecar
25
- ([library](./docs/reference/library-api.md), [embedding](./docs/reference/embedding.md)).
26
- 3. **Bit-exact, fast, and memory-honest** — logit parity with the Python
27
- reference as the correctness oracle, measured speed wins, and a
28
- deterministic `fit` memory contract ([benchmarks](#benchmarks),
29
- [correctness](#correctness)).
30
- 4. **One command, under a minute** — the appliance path above; the default
31
- experience needs zero configuration ([getting started](#getting-started)).
32
- 5. **A personal memory** — a local, git-tracked wiki your assistant reads and
33
- (via local synthesis) writes ([memory](#personal-memory)).
34
- 6. **An AI lab** — training, speculative decoding, and sampling research kept
35
- next to the runtime that serves them ([the lab](#the-lab)).
36
-
37
- The product bet is that local AI on Mac is a finite optimization problem, not
38
- an infinite configuration maze: Apple ships a known set of chip/RAM/bandwidth
39
- SKUs, the supported model list is curated, and the task mode is explicit. That
40
- means defaults can be chosen from measured device × model × mode profiles
41
- instead of asking every user to become an ML systems engineer.
13
+ ## Scope
42
14
 
43
- Measured head-to-head on an M4 Pro (24 GB), same models, same machine
44
- state: logits **bit-exact** against the Python reference; served over
45
- HTTP the **fastest stack on every model tested** — fastest decode, plus
46
- TTFT **34–85 ms** vs python's 218–326 ms at **~0% server overhead**
47
- (mlx-lm pays −5–6%); server start to ready in **0.17–0.47 s**, 2–5×
48
- faster than the Python servers. Full table: [benchmarks](#benchmarks).
15
+ Apple Silicon only — MLX is a Metal framework, so this runs on macOS on M-series
16
+ chips by design, nothing else. Serving is single-user: one process serves one
17
+ loaded model to one caller at a time (`--isolate --model-pool N` pools
18
+ multiple single-model children behind a router; it isn't a multi-tenant
19
+ scheduler). Model support is a curated, oracle-backed list, not a generic
20
+ "any HF repo" loader — see the roster for what's validated.
49
21
 
50
- ## Getting started
22
+ ## Install
51
23
 
52
- You need an Apple Silicon Mac (MLX is Metal-only, so macOS only by
53
- design). Four ways in.
54
-
55
- ### Direct download (recommended)
56
-
57
- No Homebrew, Bun, or git — just curl the install script. It downloads the
58
- signed, notarized self-contained binary from the latest release and puts
59
- `mlx-bun` on your PATH:
24
+ Four ways in; all need an Apple Silicon Mac running macOS.
60
25
 
61
26
  ```sh
27
+ # Direct download — signed, notarized, no toolchain
62
28
  curl -fsSL https://mlx-bun.dev/install.sh | sh
63
- mlx-bun
64
- ```
65
-
66
- Self-contained (binary + MLX runtime) and notarized, so it runs without a
67
- Gatekeeper prompt. Installs to `~/.mlx-bun` by default — override with
68
- `MLX_BUN_INSTALL_DIR`, or pin a release with `MLX_BUN_VERSION=<tag>`
69
- (see [releases](https://github.com/joshuarossi/mlx-bun/releases)).
70
-
71
- ### Homebrew
72
-
73
- A self-contained, signed + notarized binary — no toolchain to install by
74
- hand:
75
29
 
76
- ```sh
30
+ # Homebrew
77
31
  brew install joshuarossi/tap/mlx-bun
78
- mlx-bun
79
- ```
80
-
81
- That's the whole thing. The bottle already bundles the MLX native
82
- runtime, so the only thing the first run fetches is the model.
83
32
 
84
- ### bunx (no install)
85
-
86
- Already have [Bun](https://bun.sh) ≥ 1.3.14? Run it straight from npm,
87
- nothing to install:
88
-
89
- ```sh
33
+ # bunx — no install, needs Bun >= 1.4.0
90
34
  bunx mlx-bun
91
- ```
92
-
93
- First run fetches the MLX native runtime plus the streamed-expert helper
94
- (~52 MB) and the model into your caches, then serves. (Bun only — `npx
95
- mlx-bun` under Node exits with a
96
- "requires Bun" notice by design.)
97
-
98
- ### From source
99
-
100
- Needs [Bun](https://bun.sh) ≥ 1.3.14 — no Python, no native library to
101
- install by hand:
102
-
103
- ```sh
104
- # 1. Install Bun
105
- curl -fsSL https://bun.sh/install | bash
106
- exec $SHELL -l
107
35
 
108
- # 2. Clone, install, link the CLI
36
+ # From source
109
37
  git clone https://github.com/joshuarossi/mlx-bun.git && cd mlx-bun
110
- bun install
111
- bun run link-cli # adds the `mlx-bun` command — or run `bun src/cli.ts <verb>`
112
-
113
- # 3. Run it — that's the whole thing
114
- mlx-bun
115
- ```
116
-
117
- Bare `mlx-bun` is an alias for `mlx-bun serve`. On its first run, with no
118
- model named, it does everything for you:
119
-
120
- 1. pulls the MLX native runtime plus streamed-expert helper (~52 MB) into
121
- `~/Library/Caches/mlx-bun/`
122
- (skipped on the Homebrew install — the runtime ships in the bottle);
123
- 2. downloads the sub-GB `MiniCPM5-1B` starter and serves it, so you're
124
- chatting in well under a minute;
125
- 3. starts downloading `gemma-4-e4b` (the stronger 4B model) in the
126
- background — it becomes the default on your next `mlx-bun serve`;
127
- 4. opens the chat UI in your browser at
128
- [`http://localhost:8080/#/chat`](http://localhost:8080/#/chat)
129
- (pass `--no-open` to skip).
130
-
131
- Want a specific model instead? Name it — `mlx-bun serve e4b` (substring
132
- match against your downloaded models), grabbing it first with
133
- `mlx-bun get <repo-id>` if you don't have it. See
134
- [Supported models](#supported-models) for the full list and what fits
135
- your machine.
136
-
137
- **Prefer the API?** It's OpenAI-compatible — any OpenAI client works:
138
-
139
- ```sh
140
- curl http://localhost:8080/v1/chat/completions \
141
- -H 'Content-Type: application/json' \
142
- -d '{
143
- "messages": [{"role": "user", "content": "Hello!"}],
144
- "max_tokens": 128, "temperature": 0.7
145
- }'
38
+ bun install && bun run link-cli
146
39
  ```
147
40
 
148
- That's it. The server serves the one model it was started with (the
149
- request's `model` field is ignored and the loaded model id is echoed
150
- back in responses). Run `serve --isolate --model-pool N` instead and
151
- the parent proxy pools per-model engine children, routing each request
152
- by its `model` field and spawning on demand — see
153
- [docs/reference/server-config.md](./docs/reference/server-config.md)
154
- and [docs/design/runtime-isolation.md](./docs/design/runtime-isolation.md).
155
-
156
- Longer walkthrough on the site:
157
- [Installation](https://mlx-bun.dev/getting-started/installation/) and
158
- [Quickstart](https://mlx-bun.dev/getting-started/quickstart/).
159
-
160
- ## What mlx-bun is
161
-
162
- `mlx-bun` has several faces, all sharing one native runtime:
163
-
164
- - **The local AI product** — run `mlx-bun` or `bunx mlx-bun` and get a
165
- working local chat UI plus a local server. The default path should feel like
166
- an appliance: download the starter model, start chatting quickly, then move
167
- to the stronger recommended model as it becomes available.
168
- - **The app developer library** — embed local MLX inference inside Bun,
169
- Tauri, Electron, and other TypeScript applications without running Python in
170
- the background.
171
- - **The background agent runtime** — leave a local OpenAI-compatible endpoint
172
- available for scripts, recurring jobs, app integrations, and per-request
173
- adapter routing.
174
- - **The local memory layer** and **the AI lab** — each gets its own section
175
- below.
176
-
177
- The default experience is intentionally opinionated. Power users can override
178
- models, budgets, KV modes, adapters, and flags; the average user should not
179
- need to know those knobs exist.
180
-
181
- ## Personal memory
182
-
183
- `mlx-bun memory init` creates a git-tracked Markdown wiki at
184
- `~/.mlx-bun/wiki`; `Reference/` is seeded with read-only symlinks to
185
- mlx-bun's own docs, and the built-in pi agents read both quietly through two
186
- separate tool families — `reference_search`/`reference_read` for the seeded
187
- Reference docs, `memory_search`/`memory_section`/`memory_read` for your own
188
- articles — and can open it in Obsidian for you (`mlx-bun memory open
189
- [article]`). Chat-time memory is
190
- read-only; synthesis is the separate writer path: `mlx-bun memory synthesize`
191
- runs the built-in local pipeline (segment → extract → route → create/patch →
192
- reconcile → link → wikify) that turns your conversations into cross-linked
193
- subject articles, using the same local models with a fine-tuned chunking LoRA
194
- adapter.
195
-
196
- It's your data in your format: plain Markdown, git history, editable in any
197
- tool, never leaves the machine. Reference:
198
- [docs/reference/memory.md](./docs/reference/memory.md); synthesis design:
199
- [docs/design/memory-synthesis.md](./docs/design/memory-synthesis.md); on the
200
- site: [Personal memory](https://mlx-bun.dev/guides/memory/).
201
-
202
- ## The lab
203
-
204
- Parity, evals, kernels, training, and sampling research live next to the
205
- runtime that serves them:
206
-
207
- - **LoRA fine-tuning on your Mac** (SFT / DPO / ORPO) — `mlx-bun train
208
- <model> --data <dir>`, with a flash-CCE Metal head, segmented backward, and
209
- prefix-sharing so long-context preference training fits laptop memory;
210
- watch runs live with `mlx-bun train-watch`
211
- ([training](./docs/reference/training.md),
212
- [quickstart](./docs/reference/orpo-quickstart.md)).
213
- - **The curve designer** — HLG tone-curve sampling with an interactive
214
- designer in the server UI at `/curves`
215
- ([design](./docs/design/hlg-sampling.md)).
216
- - **Speculative decoding research (DSpark)** — a KV-injection drafter
217
- ([design](./docs/design/dspark-speculative-decoding.md)).
218
- - The full research trail — including dead ends — is tracked in
219
- [docs/design/](./docs/design/) and
220
- [docs/investigations/](./docs/investigations/).
221
-
222
- On the site: [The lab](https://mlx-bun.dev/about/lab/).
41
+ Every channel builds from the same bundle. Details, signing, and the native
42
+ runtime resolution order: [docs/reference/distribution.md](./docs/reference/distribution.md).
223
43
 
224
- ## Supported models
44
+ ## Quickstart
225
45
 
226
- Scope is deliberate: a few model families held to explicit oracle contracts,
227
- rather than dozens held to none. Currently MiniCPM5, the Gemma-4 OptiQ quants,
228
- the Qwen 3.x family, and the direct-container GLM-5.2 path:
229
-
230
- | Model | Download | Fits on | Vision | Notes |
231
- |---|---|---|---|---|
232
- | [`mlx-community/MiniCPM5-1B-OptiQ-4bit`](https://huggingface.co/mlx-community/MiniCPM5-1B-OptiQ-4bit) | 0.92 GB | 8 GB | — | Sub-GB option for 8 GB machines; bit-exact 100-step oracle parity (bf16 + mixed KV), tool calling + agent loop verified |
233
- | [`mlx-community/Qwen3.5-4B-OptiQ-4bit`](https://huggingface.co/mlx-community/Qwen3.5-4B-OptiQ-4bit) | 3.1 GB | 8 GB | — | bf16-KV bit-exact parity (vs mlx-lm); thinking + tool calling; ~74 tok/s predicted |
234
- | [`mlx-community/gemma-4-e4b-it-OptiQ-4bit`](https://huggingface.co/mlx-community/gemma-4-e4b-it-OptiQ-4bit) | 7.0 GB | 16 GB | ✓ | **Recommended starter** (16 GB+); ~56 tok/s |
235
- | [`mlx-community/gemma-4-12B-it-OptiQ-4bit`](https://huggingface.co/mlx-community/gemma-4-12B-it-OptiQ-4bit) | 8.4 GB | 16 GB | ✓ | Vision + tool calling, both verified end-to-end |
236
- | [`mlx-community/gemma-4-26B-A4B-it-OptiQ-4bit`](https://huggingface.co/mlx-community/gemma-4-26B-A4B-it-OptiQ-4bit) | 18 GB | 24 GB | — | MoE (top-8 of 128 experts); ~54 tok/s |
237
- | [`mlx-community/Qwen3.8-27B-OptiQ-4bit`](https://huggingface.co/mlx-community/Qwen3.8-27B-OptiQ-4bit) | 20.4 GB | 32 GB (24 GB with `--memory-budget`) | text-only for now | Current-gen Qwen; bf16-KV bit-exact parity (vs mlx-lm); thinking with `reasoning_effort` (xhigh/medium/low) + `preserve_thinking` + tool calling; MTP speculation, vision + video in bring-up |
238
- | [`mateogrgic/GLM-5.2-colibri-int4-with-int8-mtp`](https://huggingface.co/mateogrgic/GLM-5.2-colibri-int4-with-int8-mtp) | ~384 GB / 357 GiB | 32 GB + fast disk | — | Direct streamed Colibri container; true top-8, native MTP, bounded 25 GiB process plan; warm single-stream performance is disk-bound and below the aspirational 2 tok/s target |
239
-
240
- Not sure what fits your machine? `bun src/cli.ts fit <model> --ctx 8192`
241
- gives a deterministic answer (see below). Downloading, cache layout, and
242
- reclaiming disk: [docs/reference/models.md](./docs/reference/models.md);
243
- on the site: [Choosing a model](https://mlx-bun.dev/getting-started/models/).
244
-
245
- ### GLM-5.2: 32 GB quickstart
246
-
247
- Choose a volume with at least the artifact remainder plus 1 GiB free before
248
- starting; mlx-bun checks this before the first payload and credits resumable
249
- partials. The validated artifact revision and exact 25 GiB serving command are
250
- documented in the [model-management guide](./docs/reference/models.md#glm-52-on-a-32-gb-mac):
46
+ Bare `mlx-bun` aliases to `mlx-bun serve`; with no model named it downloads a
47
+ sub-GB starter and opens a chat UI. To pick a model explicitly:
251
48
 
252
49
  ```sh
253
- export HF_HUB_CACHE=/Volumes/FastSSD/huggingface/hub # optional large fast volume
254
- mlx-bun get mateogrgic/GLM-5.2-colibri-int4-with-int8-mtp \
255
- --revision 3cc8db99b1b13fc79325d987ba3c1c430766b3b8
256
- mlx-bun scan
257
- mlx-bun serve GLM-5.2-colibri --memory-budget 26.8435456 \
258
- --context-length 4096 --max-tokens 128 --mtp on
50
+ mlx-bun serve e4b --port 8080
259
51
  ```
260
52
 
261
- Rerun `get` after interruption; partial files resume and every completed blob
262
- is checksum-verified. The model remains in the standard Hugging Face cache—no
263
- Python environment and no second converted copy inside this repository.
264
-
265
- ## Why
266
-
267
- MLX is Apple's ML framework: hand-tuned Metal kernels for Apple Silicon,
268
- with official bindings for Python, C++, Swift, and C — but no JavaScript
269
- story. Today, a JS/TS app that wants local MLX inference must shell out to
270
- a Python server (mlx-lm, optiq) and accept that stack's fragility: venv
271
- setup, brittle download tooling, segfaults on exit, monkey-patched HTTP
272
- layers.
273
-
274
- The performance-critical work — every matmul, every attention pass — lives
275
- in MLX's C++/Metal core and is exposed through `mlx-c`. The Python layer on
276
- top is pure orchestration: model loading, tokenization, the sampling loop,
277
- serving. That layer is performance-neutral (the GPU dominates), so it can
278
- be rewritten in any runtime without losing speed — and Bun is the right
279
- one:
280
-
281
- - **`bun:ffi`** — lowest-overhead FFI of any JS runtime; binds `mlx-c`
282
- directly, no node-gyp, no binding compilation.
283
- - **Lazy native weight loading** — mlx's loader materializes tensors on
284
- first use; opening an 8.4 GB model takes milliseconds, and warm
285
- restarts are near-instant on cached pages.
286
- - **`Bun.Image`** — native OS image codecs (HEIC, AVIF, WebP, JPEG, …)
287
- for the vision path, EXIF auto-orientation included.
288
- - **`bun:sqlite`** — built-in storage for the model registry and eval DB.
289
- - **One binary, one toolchain** — runtime, package manager, test runner.
290
-
291
- ## CLI
292
-
293
- Commands are shown as `bun src/cli.ts <verb>` (runs straight from a
294
- clone). Once installed/linked, `mlx-bun <verb>` is the identical command.
295
-
296
53
  ```sh
297
- bun src/cli.ts get mlx-community/gemma-4-12B-it-OptiQ-4bit # resumable, verified download
298
- bun src/cli.ts scan # index your HF cache into the registry
299
- bun src/cli.ts ls # list models (size, params, quant, capabilities)
300
- bun src/cli.ts ls --vision --max-size 10GB
301
- bun src/cli.ts fit gemma --ctx 32768 # memory contract: fits? max context? predicted tok/s
302
- bun src/cli.ts fit gemma --ctx 8192 --skus # ...same, across the Apple Silicon lineup
303
- bun src/cli.ts fit GLM-5.2 # streamed plan: disk vs resident slabs + measured speed
304
- bun src/cli.ts serve gemma --port 8080 # OpenAI-compatible server
305
- bun src/cli.ts serve gemma --memory-budget 18 # ...with admission control (GB)
306
- bun src/cli.ts generate gemma "a haiku about metal shaders" # raw one-shot generation
307
- bun src/cli.ts train e4b --data ./pref-data --method orpo # LoRA fine-tune (SFT/DPO/ORPO)
308
- bun src/cli.ts memory init # git-tracked Markdown wiki at ~/.mlx-bun/wiki
309
- bun src/cli.ts memory synthesize # conversations -> cross-linked wiki articles, all local
310
- bun src/cli.ts pi # built-in agentic coding CLI (pi's TUI, in-process)
311
- bun src/cli.ts evals # recorded benchmark runs
312
- bun src/cli.ts harness pi # connect your own pi install to the local server
313
- ./benchmark.sh # head-to-head matrix vs mlx-lm/optiq (reboot first;
314
- # preflight-gated, resumable, writes benchmarks-h2h-<date>-<host>.md)
54
+ curl http://localhost:8080/v1/chat/completions \
55
+ -H 'Content-Type: application/json' \
56
+ -d '{"messages": [{"role": "user", "content": "Hello!"}], "max_tokens": 128}'
315
57
  ```
316
58
 
317
- Model arguments are substring queries against the registry (`e4b`,
318
- `26B`, `12B-it`); a query matching more than one model errors out
319
- listing the candidates — just make it more specific.
320
-
321
- `fit` is deterministic, not vibes: weights bytes from safetensors
322
- headers, KV bytes/token from the config (sliding-window layers capped,
323
- MoE active-expert bytes for decode), calibrated prefill transient, and
324
- the machine's wired-memory ceiling. Predictions are recorded next to
325
- measured peaks in the eval DB. The direct Colibri GLM-5.2 path uses its exact
326
- streamed plan instead: full artifact-on-disk size is separated from bounded
327
- resident weights, main/MTP expert slabs, KV, and reserves, and measured warm
328
- decode is separated from the direct oracle and the 2 tok/s aspiration.
329
-
330
- Every verb, with flags: [docs/reference/cli.md](./docs/reference/cli.md);
331
- on the site: [CLI reference](https://mlx-bun.dev/reference/cli/).
332
-
333
- ## HTTP API
334
-
335
- `serve` exposes an OpenAI-compatible API. Anything that speaks the
336
- OpenAI protocol can point at it — the OpenAI SDK
337
- (`baseURL: "http://localhost:8080/v1"`, any non-empty `apiKey`), or
338
- agent CLIs like pi/OpenClaw via their provider config.
339
-
340
- - **`POST /v1/chat/completions`** — streaming (SSE) and non-streaming;
341
- `temperature`, `top_p`, `top_k`, `max_tokens`, `seed`,
342
- `repetition_penalty`, `stop` (string or array, matched on decoded
343
- text with streaming hold-back), `reasoning_effort` (thinking on/off for
344
- Qwen3.5/3.8 / MiniCPM5 — `none` disables, any level enables; on Qwen3.8
345
- the level also sets reasoning depth: `low`/`medium`/`xhigh`), a Qwen3.8
346
- `chat_template_kwargs.preserve_thinking` toggle (keep think blocks from
347
- history; default on), and an `hlg` tone-curve sampling override;
348
- omitted sampling fields default to the model's own
349
- `generation_config.json` recipe; usage includes `cached_tokens`.
350
- Full schemas in
351
- [docs/reference/server-api.md](./docs/reference/server-api.md); start
352
- flags and the `--batch N` compatibility matrix in
353
- [docs/reference/server-config.md](./docs/reference/server-config.md).
354
- - **Tool calling** — pass OpenAI `tools`; each family's native format
355
- is parsed into `tool_calls` JSON with `finish_reason: "tool_calls"`
356
- (Gemma 4 `<|tool_call>` sentinel tokens; MiniCPM5 / Qwen3.5
357
- `<function name=…>` XML with schema-aware argument decoding);
358
- `role: "tool"` round-trips, including multi-turn agent loops.
359
- The built-in `web_fetch` tool accepts public HTTP(S) destinations only,
360
- revalidates DNS and every redirect, and streams into a 1 MiB response cap.
361
- - **Structured output** — `response_format` (JSON mode / JSON schema),
362
- plus the vLLM/oMLX aliases `guided_grammar`, `guided_regex`,
363
- `guided_choice`, and `structured_outputs`, enforced by
364
- grammar-constrained decoding (xgrammar) on chat and raw completions,
365
- serial and batched lanes alike; a grammar that fails to compile
366
- degrades to a string-valued constraint-specific prompt injection
367
- (oMLX parity) instead of an error
368
- (`MLX_BUN_GRAMMAR=0` disables mask compilation server-wide and routes
369
- requested constraints through that same warning-bearing degrade path).
370
- - **Vision** — `image_url` content parts (data: URLs or http/s), on
371
- models with the vision sidecar. PNG, JPEG, HEIC, AVIF, WebP, TIFF,
372
- GIF, BMP via native OS codecs. Remote fetches are SSRF-guarded by
373
- default (private/loopback/LAN destinations refused); opt out with
374
- `--allow-private-media` / `MLX_BUN_ALLOW_PRIVATE_MEDIA=1`.
375
- - **Audio input** — `input_audio` content parts (base64 WAV, plus
376
- `audio` / `audio_url` aliases), on models whose sidecar ships the
377
- audio tower (gemma-4 e4b). WAV decoded natively; mp3, m4a, FLAC, ogg,
378
- AIFF via CoreAudio. Up to 30 s per clip; images and audio mix in one
379
- message — a capability neither mlx-lm nor optiq serves. Same SSRF
380
- guard and opt-out as `image_url` applies to `audio_url`.
381
- - **Prompt caching** — a byte-capped LRU KV cache reuses the longest
382
- common token prefix across requests (multi-turn conversations
383
- re-prefill only the new turn) — automatic, no client changes.
384
- Entries are adapter-specific when LoRA adapters are in play.
385
- - **LoRA hot-swap** — mount adapters at runtime (`POST /v1/adapters`)
386
- and discover on-disk ones (`GET /v1/adapters/available`), select per
387
- request with the `adapter` body field (`"id"`, stacked `"a+b"`, or
388
- `"none"`). The base model never reloads; an unselected adapter costs
389
- nothing.
390
- - **Mixed-precision KV** — opt in with `--kv-quant config` when the model
391
- repo ships `kv_config.json` (every Gemma-4 OptiQ repo does): per-layer
392
- KV quantization with bits set per layer for both full-attention and
393
- sliding-window (rotating) layers (Phase 9). It trades decode speed
394
- (measured 5–20% at ≤16k, on mlx-lm's uniform scheme too) for KV bytes
395
- ÷4 on the quantized layers — reach for it when context, not speed, is
396
- the constraint. The default KV cache is bf16 (the mlx-lm-parity L1
397
- route); `--kv-quant 4|8` selects uniform bits instead, and
398
- `--kv-quant turbo[:kXvY]` opts into TurboQuant rotation-based KV
399
- (affine keys + FWHT/Lloyd-Max values, full-attention layers, serial
400
- lane — [design](./docs/design/turboquant-kv.md)). Long prefills
401
- over quantized caches run a fused FlashAttention-2 tiling that never
402
- materializes the full scores matrix (bounded transient;
403
- `MLX_BUN_NO_FUSED_SDPA=1` to disable).
404
- - **Speculative decoding** — `serve --draft-model <path|query>`
405
- (mlx_lm.server parity; `--num-draft-tokens`): the drafter KIND is
406
- auto-detected from the artifact (`--draft-kind` overrides) — a full
407
- smaller same-tokenizer model (mlx-lm parity), a Gemma `-assistant`
408
- KV-borrowing drafter (optiq parity), a DeepSpec/DSpark
409
- hidden-tapping drafter (e.g. DeepSeek's released
410
- `dspark_gemma4_12b_block7`), or **model-free prompt-lookup drafting**
411
- (`--draft-kind ngram`, no draft artifact at all — drafts are copied
412
- from the request's own prompt/generation; free wins on echo-heavy
413
- workloads like extraction and code edits, lossless at any
414
- temperature). The main model verifies every draft —
415
- exact results, faster decode when drafts land; pays on 12B-class
416
- targets, not small fast models. Serial lane only — with `--batch N` a
417
- mounted draft routes every request serial, like mlx_lm.server.
418
- - **Memory admission control** — `--memory-budget <GB>` refuses to load
419
- a model that can't serve within the budget. Generic budgeted serving rejects
420
- requests whose `prompt + max_tokens` exceed the safe context with a 400
421
- (`type: "memory_admission"`) *before* generating. GLM-5.2 has a fixed,
422
- pre-planned context instead: broad client `max_tokens` values are capped to
423
- the remaining context, and only a prompt that leaves no generation slot is
424
- rejected. The GPU
425
- out-of-memory crash it prevents is uncatchable by design — rejection
426
- up front is the only defense. Ceiling visible at `GET /stats`.
427
- - **Anthropic Messages API** (`POST /v1/messages`, on by default) —
428
- point any Anthropic-SDK tool at the server
429
- (`ANTHROPIC_BASE_URL=http://localhost:8080`); Claude Code runs
430
- against it as a fully local backend. Streaming event grammar, native
431
- tool_use/tool_result mapping, image blocks via the vision path.
432
- - **OpenAI Responses API** (`POST /v1/responses`) — the protocol
433
- Codex/Cursor/Continue speak; includes `previous_response_id`
434
- resumption backed by a TTL + byte-capped store (visible in /stats).
435
- - **OpenAI Embeddings API** (`POST /v1/embeddings`) — when the served
436
- model is an embedding model (`mlx-bun serve Qwen3-Embedding-4B-4bit-DWQ`):
437
- last-token pooled, L2-normalized vectors, bit-exact vs mlx-lm. Also a
438
- one-shot CLI: `mlx-bun embed <model> --text "…"`.
439
- - **`GET /v1/models`**, **`GET /stats`** (cache hit rates, bytes,
440
- active KV scheme, response store), **`GET/POST/DELETE /v1/adapters`**,
441
- plus **`GET /library`**, **`GET /fit`**, **`GET /downloads`**, and
442
- **`GET /v1`** (a self-describing index of every endpoint).
443
-
444
- Guide with examples on the site:
445
- [The HTTP API](https://mlx-bun.dev/guides/http-api/); coming from
446
- `mlx_lm.server`:
447
- [Drop-in for mlx-lm](https://mlx-bun.dev/guides/drop-in-mlx-lm/).
448
-
449
- ## Library
450
-
451
- The server is one consumer of a library-first API. Published to npm as
452
- `mlx-bun` — import from the package (`from "mlx-bun"`)
453
- or `./src/index` in a clone; `bunx mlx-bun` runs the CLI without
454
- installing. Full reference:
455
- [docs/reference/library-api.md](./docs/reference/library-api.md). For shipping inside a
456
- Mac app (Tauri/Electron sidecar), `./scripts/build-binary.sh` produces
457
- a relocatable single-binary bundle — recipe incl. signing/notarization
458
- in [docs/reference/embedding.md](./docs/reference/embedding.md).
459
-
460
59
  ```ts
461
- import {
462
- openModel, // artifact-aware, incl. bounded streamed GLM-5.2
463
- loadTokenizer, ChatTemplate, generate,
464
- } from "mlx-bun"; // or "./src/index" in a clone
465
-
466
- const dir = "/path/to/hf/snapshot";
467
- const model = await openModel(dir); // RuntimeModel
468
- const tok = await loadTokenizer(dir);
469
- const template = await ChatTemplate.load(dir);
470
-
471
- const ids = tok.encode(template.render([{ role: "user", content: "Hi!" }]));
472
- const gen = generate(model, ids, {
473
- maxTokens: 256,
474
- temperature: 0.7, topP: 0.95, seed: 42, // reproducible sampling
475
- kvBits: 8, quantizedKvStart: 4096, // optional: quantized KV past 4k
60
+ import OpenAI from "openai";
61
+ const client = new OpenAI({ baseURL: "http://localhost:8080/v1", apiKey: "local" });
62
+ const res = await client.chat.completions.create({
63
+ model: "local",
64
+ messages: [{ role: "user", content: "Hello!" }],
476
65
  });
477
- for await (const t of gen) process.stdout.write(tok.decode([t.token], true));
478
- console.log(gen.stats); // prompt/decode tok/s, cached tokens, ...
479
66
  ```
480
67
 
481
- KV caches can be persisted to disk (page-aligned files that reload as
482
- zero-copy GPU-safe mmaps — see `src/kv-store.ts`) so a standard agent
483
- preamble prefills once, ever.
484
-
485
- On the site: [Using the library](https://mlx-bun.dev/guides/library/) and
486
- [Embedding in a Mac app](https://mlx-bun.dev/guides/embedding/).
487
-
488
- ## Benchmarks
489
-
490
- Head-to-head against the Python stacks (mlx-lm 0.31.3, mlx-optiq 0.2.1),
491
- same machine (M4 Pro 24 GB), same HF snapshots, the 2026-06-14
492
- cleared-machine run, preflight-gated, median-of-N with warmups
493
- discarded. Full curated table (parity / performance / quality) with
494
- per-row provenance: [benchmarks/RESULTS.md](./benchmarks/RESULTS.md).
495
-
496
- **Served (warm)** — how agents actually use a local model.
497
- decode tok/s · TTFT ms · start s:
498
-
499
- | model | mlx-bun | mlx-lm | optiq |
500
- |---|---|---|---|
501
- | MiniCPM5-1B | **252.9** · 34 · 0.17 | — | 223.6 · 64 · 0.84 |
502
- | gemma-4-e4b | **55.7** · 44 · 0.36 | 53.5 · 218 · 0.98 | 53.4 · 221 · 0.78 |
503
- | gemma-4-12B | **25.9** · 85 · 0.38 | — | 25.5 · 326 · 1.24 |
504
- | gemma-4-26B | **54.2** · 45 · 0.47 | 52.3 · 228 · 0.77 | — |
505
-
506
- Across every served model mlx-bun has the fastest decode and the fastest
507
- TTFT/startup (2–5×), at **~0% server tax** vs its own direct engine —
508
- mlx-lm pays −5–6%, optiq −1 to −10%.
509
-
510
- **Direct (engine only).** Decode is at parity-to-slightly-behind mlx-lm
511
- (e4b +1.1%, 12B +0.4%, 26B −1.1%, MiniCPM5 −0.9% — within the per-step
512
- host-overhead residual), and prefill leads on the larger models (12B
513
- 1.2×, 26B 1.1×, MiniCPM5 2.3×; e4b trails at 0.8×). The earlier decode
514
- deficit was root-caused and fixed (2026-06-11) — a prefill→decode
515
- allocator-reclaim stall mlx-lm clears with `mx.clear_cache` and bills to
516
- prompt time; see PLAN.md "Decode gap RESOLVED".
517
-
518
- **Long context (12B).** At 16k and 64k mlx-bun holds decode parity with
519
- mlx-lm on bf16 (16k 23.9 = 23.9; 64k 20.9 = 20.9) while optiq drops to
520
- 21.6 then collapses to 12.3 at 64k; mixed-KV trades ~2 tok/s for ~5 GB
521
- lower peak.
522
-
523
- Two cross-stack served cells are absent: no mlx-lm 12B row, and optiq
524
- produced no output on the 26B (the Metal-OOM class from python's
525
- non-lazy load transient — reproduced in isolation; mlx-bun and mlx-lm
526
- both served it from the same machine state). One further optiq cell
527
- (12B/kv=config) is blocked on an upstream `quantized_matmul` bug. Both
528
- are documented in the results file.
529
-
530
- On the site (with the honest negatives spelled out):
531
- [Benchmarks](https://mlx-bun.dev/about/benchmarks/).
532
-
533
- ## Correctness
534
-
535
- Logit parity with mlx-lm (same weights, Python reference) is the
536
- project's oracle. The test suite holds the forward pass **bit-exact**
537
- against it — including every quantized-KV configuration (kv8, kv4, and
538
- the 26B's mixed per-layer scheme) and the fused quantized-attention
539
- prefill, which is bit-exact against optiq's reference implementation.
540
- Every ported helper follows the reference implementation's exact op
541
- composition, down to constants built at load time (the one latent
542
- divergence ever found — rope frequencies computed host-side instead of
543
- on-device — was root-caused and fixed in Phase 10; see PLAN.md
544
- findings). Golden files are regenerated only by explicit scripts
545
- (`scripts/regen-*.ts`) running the Python oracle.
546
-
547
- ```sh
548
- bun test # fast tier runs everywhere; model-loaded tests run only
549
- # when the reference snapshot is in your HF cache
550
- ```
551
-
552
- On the site: [Correctness](https://mlx-bun.dev/about/correctness/) and
553
- [How it compares](https://mlx-bun.dev/about/comparison/).
554
-
555
- ## Troubleshooting
556
-
557
- - **`dlopen` / `libmlxc.dylib` not found** — the MLX runtime
558
- auto-downloads on first `serve` into `~/Library/Caches/mlx-bun/`; if a
559
- download was interrupted, just rerun `serve` (it resumes). To point at
560
- your own copy instead, set `MLX_BUN_LIBMLXC=/path/to/libmlxc.dylib`.
561
- - **`no models match`** — run `bun src/cli.ts scan` after downloading;
562
- models must be in the standard HF cache (`~/.cache/huggingface/hub`).
563
- - **HF download stalls at 0%** — use `bun src/cli.ts get <org/repo>`
564
- (plain HTTPS, no Xet, resumes where it left off); for the Python CLI,
565
- `HF_HUB_DISABLE_XET=1` before the download command.
566
- - **Slow decode on a model near your RAM ceiling** — close memory-heavy
567
- apps; a model that doesn't fit the wired-memory budget pages weights
568
- every token (check with `fit`).
569
- - **Bun version** — requires ≥ 1.3.14 (`bun upgrade`); pinned for
570
- `Bun.Image` and verified FFI behavior.
571
-
572
- ## Status
573
-
574
- Pre-alpha, moving fast. See [PLAN.md](./PLAN.md) for phases, exit
575
- criteria, measured numbers, and the findings log.
576
-
577
- **Complete** — load path; bit-exact model port (MiniCPM5, Qwen3.5-4B,
578
- Qwen3.8-27B, e4b per-layer-input, 12B dense, 26B MoE); sampling + serving (tools, vision,
579
- prompt cache); registry / fit / KV persistence; quantized +
580
- mixed-precision KV serving (rotating-cache KV-quant, Phase 9) with fused
581
- quantized prefill (Phase 10); LoRA hot-swap with per-request selection;
582
- segmented-backward LoRA training (SFT / DPO / ORPO, with an `[M,vocab]`-free
583
- flash-CCE head + prefix-sharing for long-context preference data — `mlx-bun
584
- train <model> --data <dir>`, see [training guide](docs/reference/training.md));
585
- resumable
586
- verified downloads (`mlx-bun get`); memory admission control; the
587
- head-to-head benchmark harness; the decode-gap root-cause fix
588
- (2026-06-11); Anthropic Messages + Responses API (`/v1/messages` and
589
- `/v1/responses`, Phase 11); SigLIP vision sidecar for e4b
590
- (commit 4625fe5); the embeddable single-binary build (signed +
591
- notarized — Homebrew, direct-download, and npm/bunx).
68
+ Longer walkthroughs on the site:
69
+ [Installation](https://mlx-bun.dev/getting-started/installation/) and
70
+ [Quickstart](https://mlx-bun.dev/getting-started/quickstart/).
592
71
 
593
- **In progress** — `Qwen3.8-27B` full support (Phase 14 retarget): text
594
- parity is bit-exact and thinking controls (`reasoning_effort` depths,
595
- `preserve_thinking`) + tool calling are wired; native MTP speculation
596
- (the Qwen-trained head as a `--draft-model`), vision, and video input
597
- are in bring-up.
72
+ ## Reference docs
73
+
74
+ Each fact about the project has exactly one home:
75
+
76
+ | Topic | Doc |
77
+ |---|---|
78
+ | Current state, what's next | [STATUS.md](./STATUS.md) |
79
+ | Benchmark numbers (parity / performance / quality) | [docs/reference/benchmarks.md](./docs/reference/benchmarks.md) |
80
+ | Supported models roster | [docs/reference/models.md](./docs/reference/models.md) |
81
+ | Server start flags, `MLX_BUN_*` env, defaults | [docs/reference/server-config.md](./docs/reference/server-config.md) |
82
+ | HTTP API routes and request/response schemas | [docs/reference/server-api.md](./docs/reference/server-api.md) |
83
+ | CLI verbs | [docs/reference/cli.md](./docs/reference/cli.md) |
84
+ | TypeScript library API | [docs/reference/library-api.md](./docs/reference/library-api.md) |
85
+ | LoRA fine-tuning (SFT / DPO / ORPO) | [docs/reference/training.md](./docs/reference/training.md) |
86
+ | Build, sign, notarize, publish | [docs/reference/distribution.md](./docs/reference/distribution.md) |
87
+ | Troubleshooting | [docs/reference/troubleshooting.md](./docs/reference/troubleshooting.md) |
88
+ | Personal memory (local wiki) | [docs/reference/memory.md](./docs/reference/memory.md) |
89
+ | Reference environment / oracle setup | [docs/reference/environment.md](./docs/reference/environment.md) |
90
+ | Active engineering design docs | [docs/design/](./docs/README.md) |
91
+ | Contributing / repo rules | [CONTRIBUTING.md](./CONTRIBUTING.md) |
92
+
93
+ Correctness is verified bit-exact against the Python mlx-lm reference as the
94
+ project's oracle: [benchmarks.md § Parity](./docs/reference/benchmarks.md#1-parity-porting-correctness--bit-exact-vs-the-oracle).
598
95
 
599
- **Experimental** — opt-in, default-off, still being hardened: transparent
600
- expert offload for MoE models (`serve --expert-offload`, Phase 20:
601
- page-aligned mmap-backed experts, bit-exact — 26B-A4B 17.1→4.2 GB
602
- resident, decode unregressed); batched serving (`--batch N`, default 8
603
- since 2026-07-05 — a lone request runs the exact serial engine, so the cap
604
- engages only under real concurrency, e.g. coding sub-agents; `--batch 1`
605
- pins strict serial; Phase 18: continuous-batching bf16 decode at mlx-lm B=N parity,
606
- B=2 bit-parity verified for MiniCPM5/12B/e4b/26B; sampler extras,
607
- repetition penalty, and grammar-constrained requests batch; Qwen3.5's
608
- SSM caches batch, as do plain full-attention Tier-0 archs (e.g. Llama) —
609
- gemma2-family / sliding-window universal archs and DiffusionGemma route
610
- serial).
96
+ ## Why
611
97
 
612
- **Open** — e4b's ~5% per-step host-overhead decode residual (Phase 7);
613
- SigLIP vision for 26B.
98
+ MLX is Apple's ML framework — hand-tuned Metal kernels with official
99
+ bindings for Python, C++, Swift, and C, but no JavaScript story. The
100
+ performance-critical work (every matmul, every attention pass) lives in
101
+ MLX's C++/Metal core, exposed through `mlx-c`; the layer on top — model
102
+ loading, tokenization, sampling, serving — is pure orchestration and
103
+ performance-neutral, so it can move to a better runtime without losing
104
+ speed. Bun fits: `bun:ffi` binds `mlx-c` directly with no node-gyp step,
105
+ `Bun.Image` gives native OS image codecs for vision input, and the result
106
+ ships as one binary with no Python venv.
614
107
 
615
108
  ## License
616
109