mlx-bun 0.2.0 → 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 (364) hide show
  1. package/README.md +71 -588
  2. package/docs/README.md +91 -0
  3. package/docs/{design → archive/investigations}/audio-input-plan.md +4 -4
  4. package/docs/{design → archive/investigations}/diffusion-gemma-port.md +3 -3
  5. package/docs/{design → archive/investigations}/faithful-l1-consolidation.md +4 -4
  6. package/docs/{design → archive/investigations}/minicpm5-decode-megakernel.md +11 -11
  7. package/docs/{design → archive/investigations}/optimization_plan.md +1 -1
  8. package/docs/{design → archive/investigations}/pre-colibri-stabilization.md +5 -5
  9. package/docs/{design → archive/investigations}/the-dreaming-handoff.md +2 -2
  10. package/docs/design/batching.md +569 -0
  11. package/docs/design/decode-speed-program.md +3178 -169
  12. package/docs/design/dreaming-nightly-pipeline.md +675 -282
  13. package/docs/design/generic-model-support.md +579 -334
  14. package/docs/design/kv-cache.md +680 -0
  15. package/docs/design/orpo-training.md +673 -1239
  16. package/docs/design/speculative-decoding.md +1627 -0
  17. package/docs/design/turboquant.md +2102 -0
  18. package/docs/design/unified-engine-frontier-plan.md +1831 -727
  19. package/docs/design/web-chat-redesign.md +666 -1083
  20. package/docs/planning/PRODUCT_ROADMAP.md +34 -1
  21. package/docs/planning/release-notes-v0.3.0.md +35 -0
  22. package/docs/planning/video-series.md +2 -2
  23. package/docs/reference/benchmarks.md +1162 -0
  24. package/docs/reference/cli.md +394 -159
  25. package/docs/reference/distribution.md +321 -182
  26. package/docs/reference/environment.md +348 -0
  27. package/docs/reference/glossary.md +39 -0
  28. package/docs/reference/library-api.md +566 -168
  29. package/docs/reference/memory.md +227 -64
  30. package/docs/reference/models.md +104 -6
  31. package/docs/reference/server-api.md +886 -425
  32. package/docs/reference/server-config.md +638 -330
  33. package/docs/reference/training.md +393 -254
  34. package/docs/reference/troubleshooting.md +166 -0
  35. package/package.json +9 -4
  36. package/src/audio/decode.ts +2 -2
  37. package/src/audio/features.ts +2 -2
  38. package/src/backends/mlx/autoregressive.ts +108 -0
  39. package/src/backends/mlx/batch-group.ts +1646 -0
  40. package/src/backends/mlx/diffusion.ts +39 -0
  41. package/src/backends/mlx/draft-target.ts +47 -0
  42. package/src/backends/mlx/evaluation.ts +105 -0
  43. package/src/backends/mlx/fill-append.ts +45 -0
  44. package/src/backends/mlx/gateway-binding.ts +71 -0
  45. package/src/backends/mlx/graph.ts +38 -0
  46. package/src/backends/mlx/memory-client.ts +189 -0
  47. package/src/backends/mlx/memory-guard.ts +40 -0
  48. package/src/backends/mlx/methods.ts +90 -0
  49. package/src/backends/mlx/model-prompt.ts +164 -0
  50. package/src/backends/mlx/model-serving.ts +79 -0
  51. package/src/backends/mlx/prefill.ts +33 -0
  52. package/src/backends/mlx/request-policy.ts +20 -0
  53. package/src/backends/mlx/rollback.ts +51 -0
  54. package/src/backends/mlx/serial-executor.ts +273 -0
  55. package/src/backends/mlx/speculative.ts +114 -0
  56. package/src/backends/mlx/state-views.ts +26 -0
  57. package/src/backends/mlx/text-engine.ts +73 -0
  58. package/src/cli.ts +58 -25
  59. package/src/client.ts +66 -0
  60. package/src/config.ts +21 -4
  61. package/src/contracts/completion.ts +16 -0
  62. package/src/contracts/execution.ts +49 -0
  63. package/src/contracts/generation.ts +103 -0
  64. package/src/contracts/host.ts +7 -0
  65. package/src/contracts/jobs.ts +66 -0
  66. package/src/contracts/pi-provider.ts +30 -0
  67. package/src/contracts/pi.ts +259 -0
  68. package/src/contracts/resources.ts +18 -0
  69. package/src/contracts/scheduling.ts +27 -0
  70. package/src/contracts/tsconfig.json +14 -0
  71. package/src/diffusion/diffusion-generate.ts +218 -153
  72. package/src/embed.ts +1 -1
  73. package/src/engine/admission.ts +59 -0
  74. package/src/engine/cancellation.ts +38 -0
  75. package/src/engine/engine.ts +56 -0
  76. package/src/engine/execution-coordinator.ts +70 -0
  77. package/src/engine/execution-plan.ts +51 -0
  78. package/src/engine/resources.ts +42 -0
  79. package/src/engine/scheduler.ts +67 -0
  80. package/src/engine/session.ts +247 -0
  81. package/src/eval/README.md +44 -1
  82. package/src/eval/kl.ts +236 -3
  83. package/src/eval/reference-logits.ts +207 -0
  84. package/src/eval/runner.ts +8 -96
  85. package/src/fill/echo-index.ts +188 -0
  86. package/src/fill/fill-session.ts +452 -0
  87. package/src/fill/proposal.ts +68 -0
  88. package/src/fill/schema-rows.ts +506 -0
  89. package/src/fill/tool-boundary.ts +103 -0
  90. package/src/fit.ts +1 -1
  91. package/src/generate.ts +656 -268
  92. package/src/grammar.ts +12 -7
  93. package/src/harness-pi.ts +14 -33
  94. package/src/hub-rest.ts +4 -4
  95. package/src/index.ts +7 -0
  96. package/src/inference/denoising.ts +17 -0
  97. package/src/inference/graph.ts +33 -0
  98. package/src/inference/prefill.ts +39 -0
  99. package/src/inference/rollback.ts +7 -0
  100. package/src/jobs/db.ts +4 -0
  101. package/src/jobs/index.ts +2 -0
  102. package/src/jobs/job-entry.ts +12 -12
  103. package/src/jobs/runner.ts +98 -13
  104. package/src/jobs/task-client.ts +19 -0
  105. package/src/jobs/types.ts +2 -58
  106. package/src/kv-store.ts +109 -49
  107. package/src/lab/README.md +18 -0
  108. package/src/{assets → lab/curve}/curve-designer.html +2 -2
  109. package/src/{curve-sampler.ts → lab/curve/curve-sampler.ts} +2 -2
  110. package/src/{expert-trace.ts → lab/expert-trace/expert-trace.ts} +5 -5
  111. package/src/{model → lab/paged-kv}/paged-kv.ts +9 -6
  112. package/src/library.ts +40 -0
  113. package/src/lora.ts +18 -0
  114. package/src/media-fetch.ts +1 -1
  115. package/src/memory/article.ts +1 -1
  116. package/src/memory/chunk.ts +1 -1
  117. package/src/memory/model.ts +30 -169
  118. package/src/memory/prompts.ts +1 -1
  119. package/src/memory/rest.ts +1 -1
  120. package/src/memory/schedule.ts +1 -1
  121. package/src/memory/stages.ts +4 -1
  122. package/src/memory/vault.ts +1 -3
  123. package/src/mlx/array.ts +9 -10
  124. package/src/mlx/compile.ts +12 -2
  125. package/src/mlx/ffi.ts +58 -11
  126. package/src/mlx/materialize.ts +23 -0
  127. package/src/mlx/metal-kernel.ts +10 -11
  128. package/src/mlx/ops.ts +33 -13
  129. package/src/mlx/quantized-rows.ts +36 -0
  130. package/src/mlx/token-bitmask.ts +52 -0
  131. package/src/mlx/turboquant-kv-decode.ts +82 -0
  132. package/src/mlx/turboquant-kv-inverse.ts +122 -0
  133. package/src/mlx/turboquant-ops.ts +33 -3
  134. package/src/mlx/turboquant-tables.ts +2 -2
  135. package/src/model/batched-mask.ts +8 -2
  136. package/src/model/batched-quant.ts +1 -1
  137. package/src/model/batched-rotating-quant.ts +2 -2
  138. package/src/model/batched-rotating.ts +1 -1
  139. package/src/model/compiled-decode.ts +1 -1
  140. package/src/model/diffusion-gemma.ts +8 -8
  141. package/src/model/factory.ts +76 -33
  142. package/src/model/fingerprint.ts +1 -1
  143. package/src/model/flash-attention.ts +3 -3
  144. package/src/model/gemma4-base.ts +26 -9
  145. package/src/model/gemma4.ts +6 -6
  146. package/src/model/generated/gemma4-12b.ts +2 -2
  147. package/src/model/generated/gemma4-26b.ts +2 -2
  148. package/src/model/generated/gemma4-e4b.ts +2 -2
  149. package/src/model/glm52-dsa.ts +13 -9
  150. package/src/model/glm52-memory.ts +1 -1
  151. package/src/model/implementation.ts +69 -0
  152. package/src/model/minicpm5.ts +6 -8
  153. package/src/model/profile.ts +12 -2
  154. package/src/model/qwen-append.ts +12 -0
  155. package/src/model/qwen-conv.ts +52 -0
  156. package/src/model/qwen3_5-checkpoint.ts +164 -0
  157. package/src/model/qwen3_5.ts +140 -56
  158. package/src/model/support.ts +1 -1
  159. package/src/model/trellis-balanced-scatter.ts +51 -0
  160. package/src/model/trellis-linear.ts +672 -0
  161. package/src/model/trellis-shared-m.ts +151 -0
  162. package/src/model/trellis-shared-scatter.ts +144 -0
  163. package/src/model/trellis-splitk-prefill.ts +158 -0
  164. package/src/model/trellis-tiled-prefill.ts +136 -0
  165. package/src/model/trellis-vector-expand.ts +62 -0
  166. package/src/model/trellis-wide-prefill.ts +94 -0
  167. package/src/model/universal/dense.ts +1 -1
  168. package/src/model/universal/modules.ts +8 -1
  169. package/src/native-pack.ts +6 -5
  170. package/src/pi-provider.ts +6 -64
  171. package/src/pi-web.ts +8 -315
  172. package/src/prompt-cache.ts +96 -53
  173. package/src/quantize/allocator.ts +1 -1
  174. package/src/quantize/config-writer.ts +10 -3
  175. package/src/quantize/rotate.ts +4 -4
  176. package/src/quantize/trellis.ts +586 -0
  177. package/src/responses.ts +28 -1
  178. package/src/runtime-config.ts +18 -4
  179. package/src/sampler.ts +4 -4
  180. package/src/serve/batch-scheduler.ts +8 -1671
  181. package/src/serve/chat-request.ts +391 -0
  182. package/src/serve/chat-stage.ts +195 -0
  183. package/src/serve/checkpoint-identity.ts +64 -0
  184. package/src/serve/completion-executor.ts +15 -7
  185. package/src/serve/discovery-routes.ts +12 -13
  186. package/src/serve/generation-gateway.ts +154 -193
  187. package/src/serve/http.ts +159 -0
  188. package/src/serve/inference-request.ts +79 -0
  189. package/src/serve/isolate.ts +297 -105
  190. package/src/serve/lab-routes.ts +3 -0
  191. package/src/serve/lane-registry.ts +2 -1
  192. package/src/serve/model-admin-routes.ts +7 -5
  193. package/src/serve/model-binding.ts +43 -0
  194. package/src/serve/model-host.ts +512 -0
  195. package/src/serve/openai-wire.ts +103 -0
  196. package/src/serve/parent-application.ts +56 -0
  197. package/src/serve/pipeline.ts +33 -0
  198. package/src/serve/preparation.ts +33 -0
  199. package/src/serve/request-plan.ts +19 -15
  200. package/src/serve/request-prep.ts +346 -0
  201. package/src/serve/response-lease.ts +24 -0
  202. package/src/serve/responses-client.ts +69 -0
  203. package/src/serve/session-completion-engine.ts +110 -0
  204. package/src/serve/session-search.ts +1 -1
  205. package/src/serve/static-routes.ts +5 -5
  206. package/src/serve/text-completion-stage.ts +104 -0
  207. package/src/serve/token-streams.ts +519 -0
  208. package/src/server.ts +317 -2649
  209. package/src/spec/assistant-source.ts +10 -44
  210. package/src/spec/deepspec-source.ts +6 -6
  211. package/src/spec/dflash-source.ts +8 -8
  212. package/src/spec/dspark/ab-stats.ts +3 -3
  213. package/src/spec/dspark/calibration.ts +2 -2
  214. package/src/spec/dspark/deepspec-module.ts +2 -2
  215. package/src/spec/dspark/generate-dflash.ts +2 -2
  216. package/src/spec/dspark/generate.ts +2 -2
  217. package/src/spec/dspark/loader.ts +1 -1
  218. package/src/spec/dspark/module-dflash.ts +4 -3
  219. package/src/spec/dspark/module.ts +3 -3
  220. package/src/spec/dspark/quantize-drafter.ts +1 -1
  221. package/src/spec/generate.ts +1 -1
  222. package/src/spec/glm52-mtp-source.ts +1 -1
  223. package/src/spec/ngram-source.ts +1 -1
  224. package/src/spec/prefix-state.ts +45 -0
  225. package/src/spec/qwen-mtp-source.ts +166 -69
  226. package/src/spec/serve-loop.ts +154 -156
  227. package/src/spec/source.ts +42 -10
  228. package/src/spec/two-model.ts +1 -1
  229. package/src/ssd-cache.ts +80 -12
  230. package/src/ssd-durability.ts +25 -13
  231. package/src/tool-call.ts +51 -14
  232. package/src/train/flash-cce.ts +2 -2
  233. package/src/train/forward.ts +6 -0
  234. package/src/train/loss.ts +1 -1
  235. package/src/train/prefix-shared.ts +5 -1
  236. package/src/train/segmented.ts +5 -3
  237. package/src/train/trainer.ts +6 -6
  238. package/src/vision/prompt.ts +1 -1
  239. package/src/vision/qwen3vl-tower.ts +52 -10
  240. package/src/web/app.html +1 -1
  241. package/src/web/app.js +5 -3
  242. package/src/web/src/adapters-panel.ts +3 -3
  243. package/src/web/src/assistant.ts +2 -36
  244. package/src/web/src/chat.ts +4 -4
  245. package/src/web/src/composer.ts +4 -4
  246. package/src/web/src/hub.ts +1 -1
  247. package/src/web/src/markdown.ts +0 -0
  248. package/src/web/src/memory-panel.ts +1 -1
  249. package/src/web/src/model-picker.ts +1 -1
  250. package/src/web/src/palette.ts +1 -1
  251. package/src/web/src/protocol.ts +3 -39
  252. package/src/web/src/sessions.ts +1 -1
  253. package/src/web/src/ui-catalog.ts +4 -18
  254. package/src/web-assets.ts +47 -0
  255. package/src/weights.ts +55 -9
  256. package/docs/archive/investigations/curve-runs/bisector-route.json +0 -98
  257. package/docs/archive/investigations/curve-runs/bisector-trace.json +0 -1393
  258. package/docs/archive/investigations/curve-runs/curve-terrain.json +0 -1179
  259. package/docs/archive/investigations/curve-runs/curve-terrain.svg +0 -42
  260. package/docs/archive/investigations/hlg-ab.html +0 -34
  261. package/docs/archive/investigations/hlg-explorer.html +0 -238
  262. package/docs/archive/investigations/hlg-figs/cliff.svg +0 -1
  263. package/docs/archive/investigations/hlg-figs/cross.svg +0 -1
  264. package/docs/archive/investigations/hlg-figs/edges.svg +0 -1
  265. package/docs/archive/investigations/hlg-figs/k20-grids.svg +0 -1
  266. package/docs/archive/investigations/hlg-figs/k20-peaks.svg +0 -1
  267. package/docs/archive/investigations/hlg-figs/lw-curve.svg +0 -1
  268. package/docs/archive/investigations/hlg-figs/terrain.svg +0 -1
  269. package/docs/archive/investigations/hlg-report.html +0 -262
  270. package/docs/archive/investigations/hlg-runs/hlg-ab.json +0 -149
  271. package/docs/archive/investigations/hlg-runs/hlg-blind-prompts.md +0 -87
  272. package/docs/archive/investigations/hlg-runs/hlg-blind.json +0 -107
  273. package/docs/archive/investigations/hlg-runs/hlg-cliff.json +0 -197
  274. package/docs/archive/investigations/hlg-runs/hlg-cross.json +0 -505
  275. package/docs/archive/investigations/hlg-runs/hlg-edge.json +0 -388
  276. package/docs/archive/investigations/hlg-runs/hlg-eval1.json +0 -25
  277. package/docs/archive/investigations/hlg-runs/hlg-frontier.json +0 -86
  278. package/docs/archive/investigations/hlg-runs/hlg-grid.json +0 -242
  279. package/docs/archive/investigations/hlg-runs/hlg-grid2.json +0 -343
  280. package/docs/archive/investigations/hlg-runs/hlg-lw-coarse.json +0 -110
  281. package/docs/archive/investigations/hlg-runs/hlg-map.json +0 -383
  282. package/docs/archive/investigations/hlg-runs/run0-original.log +0 -159
  283. package/docs/archive/investigations/hlg-runs/runA-recommended.log +0 -131
  284. package/docs/archive/investigations/hlg-runs/runAA-cliff-cpm5.log +0 -26
  285. package/docs/archive/investigations/hlg-runs/runAB-grid2-e4b.log +0 -18
  286. package/docs/archive/investigations/hlg-runs/runAC-peak-e4b-partial.log +0 -25
  287. package/docs/archive/investigations/hlg-runs/runAD-ab-samples.log +0 -8
  288. package/docs/archive/investigations/hlg-runs/runAE-edge-e4b.log +0 -51
  289. package/docs/archive/investigations/hlg-runs/runAF-logit-calibration.log +0 -10
  290. package/docs/archive/investigations/hlg-runs/runAG-eval-config2.log +0 -16
  291. package/docs/archive/investigations/hlg-runs/runB-gain-variants.log +0 -192
  292. package/docs/archive/investigations/hlg-runs/runC-pivots.log +0 -162
  293. package/docs/archive/investigations/hlg-runs/runD-oetf.log +0 -132
  294. package/docs/archive/investigations/hlg-runs/runE-eotf.log +0 -162
  295. package/docs/archive/investigations/hlg-runs/runF-shaper-working.log +0 -86
  296. package/docs/archive/investigations/hlg-runs/runG-shaper-sweep.log +0 -101
  297. package/docs/archive/investigations/hlg-runs/runH-wsweep.log +0 -176
  298. package/docs/archive/investigations/hlg-runs/runI-asweep.log +0 -176
  299. package/docs/archive/investigations/hlg-runs/runJ-knobmap.log +0 -49
  300. package/docs/archive/investigations/hlg-runs/runK-frontier.log +0 -19
  301. package/docs/archive/investigations/hlg-runs/runL-widemap.log +0 -65
  302. package/docs/archive/investigations/hlg-runs/runM-frontier-emb.log +0 -15
  303. package/docs/archive/investigations/hlg-runs/runN-verify.log +0 -116
  304. package/docs/archive/investigations/hlg-runs/runO-frontier-seed5000.log +0 -15
  305. package/docs/archive/investigations/hlg-runs/runP-grid-AxSm.log +0 -15
  306. package/docs/archive/investigations/hlg-runs/runQ-grid-tgW.log +0 -15
  307. package/docs/archive/investigations/hlg-runs/runR-blind-transcript.log +0 -79
  308. package/docs/archive/investigations/hlg-runs/runS-cross-coherence.log +0 -33
  309. package/docs/archive/investigations/hlg-runs/runT-cross-cpm5.log +0 -33
  310. package/docs/archive/investigations/hlg-runs/runU-cross-12b.log +0 -33
  311. package/docs/archive/investigations/hlg-runs/runV-lw-e4b.log +0 -22
  312. package/docs/archive/investigations/hlg-runs/runW-lw-12b.log +0 -22
  313. package/docs/archive/investigations/hlg-runs/runX-lw-cpm5.log +0 -22
  314. package/docs/archive/investigations/hlg-runs/runY-cliff-e4b.log +0 -26
  315. package/docs/archive/investigations/hlg-runs/runZ-cliff-12b.log +0 -26
  316. package/docs/archive/mlx-bun-lab-report.html +0 -275
  317. package/docs/archive/wwdc-mlx-bun.html +0 -848
  318. package/docs/design/adapters-end-to-end.md +0 -205
  319. package/docs/design/batching-perf-path.md +0 -255
  320. package/docs/design/batching-v2-plan.md +0 -529
  321. package/docs/design/bucketing-stage.md +0 -197
  322. package/docs/design/compat-cli-surface-design.md +0 -230
  323. package/docs/design/docs-reorg-plan.md +0 -165
  324. package/docs/design/dspark-serving-program.md +0 -371
  325. package/docs/design/dspark-speculative-decoding.md +0 -318
  326. package/docs/design/grammar-spec-batching-integration.md +0 -301
  327. package/docs/design/memory-inference-path.md +0 -422
  328. package/docs/design/memory-synthesis.md +0 -287
  329. package/docs/design/memory-system.md +0 -237
  330. package/docs/design/mlx-lm-serving-execution-seam.md +0 -81
  331. package/docs/design/mlx-lm-tool-parity-plan.md +0 -545
  332. package/docs/design/omlx-adoption-map.md +0 -98
  333. package/docs/design/orpo-dynamic-lambda.md +0 -220
  334. package/docs/design/orpo-future-enhancements.md +0 -340
  335. package/docs/design/paged-kv-cache.md +0 -214
  336. package/docs/design/parallel-slots.md +0 -567
  337. package/docs/design/parity-tier-dag.md +0 -161
  338. package/docs/design/repo-cleanup-plan.md +0 -231
  339. package/docs/design/runtime-isolation.md +0 -263
  340. package/docs/design/segmented-backward-training.md +0 -543
  341. package/docs/design/spec-decode-larger-targets.md +0 -229
  342. package/docs/design/ssd-kv-cold-tier.md +0 -415
  343. package/docs/design/structured-output.md +0 -484
  344. package/docs/design/tauri-desktop-app.md +0 -127
  345. package/docs/design/the-dreaming-master-plan.md +0 -445
  346. package/docs/design/turboquant-kv.md +0 -235
  347. package/docs/design/turboquant-weights.md +0 -467
  348. package/docs/design/w4a16-compute-precision-spike.md +0 -232
  349. package/docs/design/web-chat-beat-matrix.md +0 -315
  350. package/docs/design/write-pipeline-entity.md +0 -468
  351. package/docs/planning/IDEAS.md +0 -69
  352. package/docs/reference/embedding.md +0 -197
  353. package/docs/reference/features-matrix.md +0 -101
  354. package/docs/reference/orpo-quickstart.md +0 -135
  355. package/src/flags.ts +0 -11
  356. /package/docs/{design → archive/investigations}/colibri-glm52-port.md +0 -0
  357. /package/docs/{planning → archive/planning}/chunk-task-roadmap.md +0 -0
  358. /package/docs/{planning → archive/planning}/curve-sampler-research-plan.md +0 -0
  359. /package/docs/{planning → archive/planning}/memory-docs-and-dag-plan.md +0 -0
  360. /package/docs/{planning → archive/planning}/pi-integration-review.md +0 -0
  361. /package/docs/{planning → archive/planning}/release-notes-v0.2.0.md +0 -0
  362. /package/src/{memory-plan.ts → admission-plan.ts} +0 -0
  363. /package/{docs/archive/investigations → src/serve/assets}/curve-terrain.html +0 -0
  364. /package/{docs/dag → src/serve/assets}/training-inference-map.html +0 -0
@@ -1,197 +0,0 @@
1
- # Embedding mlx-bun (single-binary sidecar)
2
-
3
- > **Not text embeddings.** This page is about *embedding the mlx-bun binary*
4
- > inside an app. For text-vector embeddings (Qwen3-Embedding, `mlx-bun embed`,
5
- > `POST /v1/embeddings`), see [server-api.md](./server-api.md#post-v1embeddings-openai-embeddings-api)
6
- > and [library-api.md](./library-api.md#text-embeddings).
7
-
8
- Ship local inference inside a Mac app (Tauri, Electron, or anything
9
- that can spawn a process) with zero user-visible dependencies: one
10
- executable + four native libraries, dropped into your app's resources.
11
-
12
- ## Build the bundle
13
-
14
- ```sh
15
- ./scripts/build-binary.sh dist
16
- ```
17
-
18
- Produces a relocatable directory:
19
-
20
- | file | what | size (arm64) |
21
- |---|---|---|
22
- | `mlx-bun` | the CLI/server, compiled with `bun build --compile` | ~70-75 MB |
23
- | `libmlxc.dylib` | mlx-c, rewritten to load `@loader_path/libmlx.dylib` | ~0.7 MB |
24
- | `libmlx.dylib` | mlx core (+`@loader_path` rpath added for libjaccl) | ~15 MB |
25
- | `libjaccl.dylib` | mlx's distributed-comm dependency | ~0.6 MB |
26
- | `libmlx_bun_expert_io.dylib` | bounded streamed-expert I/O used by direct Colibri GLM-5.2 | ~0.03 MB |
27
- | `mlx.metallib` | Metal kernels — libmlx loads it from its own directory | ~150 MB |
28
- | `photon_rs_bg.wasm` | pi image codec — only the web chat's `read`-on-image path; resolved next to the executable | ~1.8 MB |
29
-
30
- `build-binary.sh` also sidecars a second set of assets for the embedded
31
- pi **terminal** (`mlx-bun pi`, `src/pi-terminal.ts` → `InteractiveMode`),
32
- none of which the headless web chat touches:
33
-
34
- | file | what |
35
- |---|---|
36
- | `theme/*.json` | TUI color themes (built-in dark/light fallback exists in code; shipped so custom theme reads and the schema resolve) |
37
- | `assets/*.png` | TUI startup art |
38
- | `export-html/template.html`, `export-html/vendor/*.js` | the `/export` command's HTML template + vendor JS |
39
- | `package.json`, `CHANGELOG.md` | version banner + startup changelog |
40
- | `native/darwin/prebuilds/<arch>/darwin-modifiers.node` | pi-tui's native modifier-key detection (degrades gracefully if absent) |
41
-
42
- Library resolution order (src/mlx/ffi.ts): `MLX_BUN_LIBMLXC` env var →
43
- `libmlxc.dylib` next to the executable → the downloaded native-pack
44
- cache (`~/Library/Caches/mlx-bun/native-v<ver>-<arch>/`, populated on
45
- first run when no sidecar or homebrew install is found) → homebrew
46
- (`/opt/homebrew/lib`, `/usr/local/lib`). The whole directory can be
47
- renamed/moved; nothing references absolute paths after the build
48
- script's `install_name_tool` fixups. The expert helper independently resolves
49
- `MLX_BUN_EXPERT_IO_DYLIB`, then the executable directory, then the same
50
- native-pack cache.
51
-
52
- ## Embedded pi web chat (`/ws/chat`)
53
-
54
- The compiled binary includes the full embedded pi AgentSession
55
- (`src/pi-web.ts`, dep `@earendil-works/pi-coding-agent`) that drives the
56
- browser chat. The web chat runs pi **headless** — no TUI — so it needs
57
- far less than pi's own `bun build --compile` ships.
58
-
59
- **Bundled automatically.** All of pi's JavaScript (the SDK,
60
- `createAgentSession`, the seven tools, the `openai-completions` provider,
61
- the resource loader) is pulled into the executable by `bun build
62
- --compile`. Nothing extra to do for the JS.
63
-
64
- **Sidecar'd by `build-binary.sh`.** The only runtime asset pi resolves
65
- *by path* on the headless web-chat path is `photon_rs_bg.wasm` (pi's
66
- image codec). pi resolves it relative to `process.execPath`, so the build
67
- script copies it next to `mlx-bun`. It is reached only when the `read`
68
- tool is asked to read an image file, and pi degrades gracefully when it's
69
- absent (the tool returns a text "[Image omitted]" note instead of
70
- crashing), so it is best-effort, not load-bearing.
71
-
72
- > Known limitation: `@silvia-odwyer/photon-node`'s wasm-bindgen glue
73
- > currently fails to decode under Bun (both `bun` and `bun build
74
- > --compile`) with *"Unreachable code should not be executed"* — a Bun
75
- > wasm-bindgen gap, not an asset-placement issue (the bytes are valid and
76
- > found). Net effect today: web-chat image *reads* aren't resized inline.
77
- > The web chat itself is unaffected (its provider is text-only), and the
78
- > wasm is shipped so it will work once Bun's support lands.
79
-
80
- ## Embedded pi terminal (`mlx-bun pi`)
81
-
82
- The compiled binary also embeds pi's full interactive TUI
83
- (`src/pi-terminal.ts` → `InteractiveMode`), reachable via `mlx-bun pi`.
84
- Unlike the headless web chat, the terminal *does* resolve theme JSON,
85
- startup art, the `/export` template, the version banner, and the
86
- pi-tui native modifier-key helper by path — the second table above is
87
- sidecar'd for exactly this mode. `src/pi-web.ts`'s session (the web
88
- chat) still builds with `noThemes`/`noSkills`/`noExtensions`/
89
- `noPromptTemplates`/`noContextFiles`, so none of that table is reached
90
- from `/ws/chat` — only `mlx-bun pi` uses it.
91
-
92
- **Omitted** (upstream pi ships these beside its own binary; neither
93
- mlx-bun mode reaches them):
94
-
95
- | omitted asset | what it's for |
96
- |---|---|
97
- | `docs/`, `examples/`, `README.md` | upstream's own help/doc browsing, not exposed by either mlx-bun entry point |
98
-
99
- `createAgentSession`'s import graph (`core/sdk.js`) pulls in no loaders
100
- for these; both `src/pi-web.ts` and `src/pi-terminal.ts` build sessions
101
- that never reference them.
102
-
103
- **Verifying it.** `build-binary.sh` runs `scripts/verify-binary-pi.ts` as
104
- a sibling compiled binary inside the bundle (so `process.execPath` points
105
- at the bundle dir, matching what the real binary sees). It builds the
106
- exact headless session `src/pi-web.ts` builds — same provider/registry/
107
- resource-loader config — against an unreachable provider, far enough to
108
- prove the bundled SDK + assets resolve without a missing-asset crash. It
109
- needs **no model and no server**; a provider/model error is the success
110
- signal. The one thing this can't cover offline is a live token-streaming
111
- turn over `/ws/chat` — that still requires `mlx-bun serve` running a real
112
- model (run it yourself; the smoke covers everything up to the model call).
113
-
114
- ## Sidecar pattern
115
-
116
- Spawn the server on app start, point your in-app client at it:
117
-
118
- ```ts
119
- // Electron main / Tauri sidecar config
120
- const child = spawn(resourcePath("mlx-bun"), [
121
- "serve", "gemma-4-12B", "--port", "8080", "--memory-budget", "12",
122
- ]);
123
- // readiness: poll GET /v1/models (start→ready is ~0.4 s warm)
124
- ```
125
-
126
- - One generation runs at a time (single queue, one GPU) — serialize or
127
- queue client-side too if you show progress.
128
- - `--memory-budget <GB>` is the OOM defense: requests that can't finish
129
- within the budget are rejected with HTTP 400 (`memory_admission`)
130
- *before* generating. The Metal OOM it prevents is uncatchable.
131
- - Protocols: OpenAI chat completions, Anthropic `/v1/messages`, OpenAI
132
- Responses (`previous_response_id` works) — see
133
- [server-api.md](./server-api.md). Use whichever your client SDK
134
- already speaks.
135
- - Kill the child freely (SIGKILL is fine): restart→ready is ~0.4 s and
136
- prompt-cache misses are the only loss.
137
-
138
- ## First-run weights
139
-
140
- The binary includes the resumable verified downloader:
141
-
142
- ```sh
143
- mlx-bun get mlx-community/gemma-4-12B-it-OptiQ-4bit # → standard HF cache
144
- mlx-bun scan # index it
145
- mlx-bun serve gemma-4-12B --port 8080
146
- ```
147
-
148
- Downloads resume across interruption, every blob is checksum-verified
149
- (sha256/sha1), and the cache layout is exactly huggingface_hub's — a
150
- user's existing HF cache is picked up as-is. For a custom weights
151
- location inside your app's container, set `HF_HOME` in the child's
152
- environment.
153
-
154
- ## Signing & notarization
155
-
156
- The build script ad-hoc signs the dylibs (required on arm64 after
157
- `install_name_tool`). For distribution, re-sign everything with your
158
- Developer ID and notarize:
159
-
160
- ```sh
161
- IDENTITY="Developer ID Application: Your Name (TEAMID)"
162
-
163
- # 1. entitlements — Bun executables REQUIRE allow-jit under the
164
- # hardened runtime (JavaScriptCore JIT); without it the binary is
165
- # killed on launch.
166
- cat > entitlements.plist <<'EOF'
167
- <?xml version="1.0" encoding="UTF-8"?>
168
- <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
169
- "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
170
- <plist version="1.0"><dict>
171
- <key>com.apple.security.cs.allow-jit</key><true/>
172
- <key>com.apple.security.cs.allow-unsigned-executable-memory</key><true/>
173
- </dict></plist>
174
- EOF
175
-
176
- # 2. sign (dylibs first, then the executable with entitlements)
177
- codesign -f --options runtime -s "$IDENTITY" \
178
- dist/libjaccl.dylib dist/libmlx.dylib dist/libmlxc.dylib
179
- codesign -f --options runtime --entitlements entitlements.plist \
180
- -s "$IDENTITY" dist/mlx-bun
181
-
182
- # 3. notarize (zip the bundle dir; metallib needs no signature)
183
- ditto -c -k --keepParent dist mlx-bun.zip
184
- xcrun notarytool submit mlx-bun.zip --keychain-profile "AC_PROFILE" --wait
185
- ```
186
-
187
- Inside an `.app`, put the bundle under
188
- `Contents/Resources/` (Electron: `extraResources`; Tauri:
189
- `bundle.resources` + `externalBin` for the executable) and let the
190
- app's normal signing pass cover it — the same entitlements apply to
191
- the sidecar binary.
192
-
193
- ## Library API
194
-
195
- The server is one consumer of the library — embed generation directly
196
- in a Bun process instead of spawning, via `loadContext`/`generate`:
197
- see [library-api.md](./library-api.md).
@@ -1,101 +0,0 @@
1
- # Features matrix — everything mlx-bun serves, in one table
2
-
3
- The complete option inventory: every serving feature, its default, which
4
- execution lane it runs on, which fidelity tier verifies it, and its knob.
5
- This is the *what-exists* view; per-flag detail lives in
6
- [server-config.md](server-config.md), wire formats in
7
- [server-api.md](server-api.md), CLI verbs in [cli.md](cli.md).
8
-
9
- **Lanes:** `serial` = the default single-queue path; `batch` = the
10
- `--batch N` continuous-batching engine (bf16 compat mode, mlx-lm B=N
11
- parity). **Tiers:** L1 = bit-exact vs mlx-lm · L2 = bit-exact vs mlx-optiq
12
- · Lab = no external oracle; KL/eval-gated experiments (see
13
- [server-config.md → Fidelity tiers](server-config.md#fidelity-tiers-and-the-decode-route---l1----l2)).
14
-
15
- ## Serving & performance
16
-
17
- | Feature | Default | Lane | Tier | Knob |
18
- | --- | --- | --- | --- | --- |
19
- | OpenAI chat completions (`/v1/chat/completions`, SSE) | on | both | — | — |
20
- | Raw text completions (`/v1/completions`) | on | both | — | — |
21
- | Anthropic Messages (`/v1/messages`) | on | both | — | — |
22
- | OpenAI Responses shim (`/v1/responses`) | on | both | — | — |
23
- | Continuous batching (mlx-lm parity at the same B) | **on** — cap 8 (default flipped 2026-07-05; a lone admitted request uses the gated B=1 fast path and concurrent requests can form B=N; `--batch 1` pins the strict serial executor) | batch | L1 | `--batch <n>` |
24
- | Prompt cache (prefix KV reuse) | on, 8 GB | both | — | `--prompt-cache <GB>` (0 = off) |
25
- | **SSD KV cold tier** (cache survives eviction + restarts; v3 includes GLM compressed MLA/DSA state without full-K/V reconstruction) | off | both | — | `--ssd-cache <dir>` (+ `-max`, `-verify`, `-demote-idle <sec>` — default 300s once `--ssd-cache` is on, `0` disables) |
26
- | **Runtime isolation** (engine runs as a crash-isolated CHILD process behind a reverse-proxy parent; UI stays instant under GPU load and survives engine crashes — [runtime-isolation.md](../design/runtime-isolation.md)) | off | both | — | `--isolate` |
27
- | **Model pool** (with `--isolate`: LRU-capped RESIDENT model engines; over the cap the least-recently-used engine demotes its cache to the SSD tier and exits, respawning on the next request) | 1 resident engine | both | — | `--model-pool <n>` (requires `--isolate`) |
28
- | Mixed-precision KV (`kv_config.json`, optiq's scheme) | **off** — opt-in (default flipped to bf16 2026-07-05; quantized KV trades 5–20% decode for memory headroom) | serial + **batch** (per-layer configs batch on every shipped model — full-attention layers Phase 3.1, rotating layers milestone 2; uniform bits stay serial) | L2 | `--kv-quant config\|off\|4\|8`, `--l2` |
29
- | **TurboQuant KV** (rotation-based: affine keys + FWHT/Lloyd-Max values) | off — opt-in ([turboquant-kv.md](../design/turboquant-kv.md); v1 dequantize-on-fetch, full-attention layers only, no speed claim) | serial only (solo-only, unconditionally) | Lab (codec is oracle-backed vs vllm-metal; the cache class is unvalidated) | `--kv-quant turbo[:k<bits>v<bits>]` (default `k8v3`) |
30
- | Compiled decode (bit-exact graph replay) | on, every tier | serial | L1/L2 | `--compiled-decode on\|off` |
31
- | Compiled activations (faithful geglu/swiglu — mlx-lm's `@mx.compile`) | **on**, every tier | both | L1 | `--compiled-activations on\|off` |
32
- | Fused SDPA (optiq-exact quantized-KV attention) | follows `--kv-quant`: on for `config`, off for uniform/bf16 | serial | L2 | `--fused-sdpa on\|off` |
33
- | **Paged KV** (vLLM-style block pool: host-side block table + gather before the stock SDPA, no fused kernel in v1 — [paged-kv-cache.md](../design/paged-kv-cache.md)) | off | serial (pins `--batch 1` unless `--batch` given) | gated bit-exact vs the plain `KVCache` (`tests/paged-kv-parity.test.ts`) | `--paged-kv`, `--paged-kv-block-size <n>` (default 256) — v1 scope Gemma4-family bf16; refuses `--batch N>1`, `--kv-quant`, `--draft-model` |
34
- | **Speculative decoding** (auto-detected drafter: two-model = mlx-lm parity/L1, Gemma `-assistant` = optiq/L2, DSpark local = Lab, DeepSpec released = DeepSpec-reference oracle) | off | serial (forces all-serial) | per-drafter oracle | `--draft-model <path\|query>`, `--draft-kind`, `--num-draft-tokens` |
35
- | **GLM-5.2 checkpoint-native MTP** (bounded auxiliary expert tier, exact verify) | **on** for GLM-5.2 | serial (`usage.lane: serial+spec`) | Colibri/oracle trajectory + synthetic HTTP gate | `--mtp on\|off` (`off` enables ordinary GLM batching) |
36
- | Speculative decoding, **model-free prompt lookup** (drafts copied from the request's own context; port of prompt-lookup decoding / vLLM `ngram`; zero weights) | off | serial (forces all-serial) | lossless by verify (gated vs non-spec greedy, tests/spec-ngram.test.ts) | `--draft-kind ngram` (no `--draft-model`), `--ngram-max`, `--ngram-min`, `--num-draft-tokens` (default 10) |
37
- | Memory admission (refuse what can't fit; never GPU-OOM) | on (RAM × 0.75) | both | — | `--memory-budget <GB>` |
38
- | Aggregate KV admission for batch rows (queue, don't OOM) | off | batch | — | `--kv-budget <GB>` |
39
- | Expert offload (MoE cold experts on mmap) | off | serial | Lab | `--expert-offload` |
40
- | Extend-join (O(1) batch admission) | on | batch | L1 (own oracle) | `MLX_BUN_BATCH_EXTEND=0` |
41
- | Vectorized greedy batch sampling | on | batch | bit-equal A/B | `MLX_BUN_BATCH_VEC_SAMPLE=0` |
42
-
43
- ## Request features
44
-
45
- | Feature | Default | Lane | Tier | Knob |
46
- | --- | --- | --- | --- | --- |
47
- | **Structured output** (`response_format` json_object/json_schema) | on | both | L2 (oMLX) | request field; `MLX_BUN_GRAMMAR=0` kills |
48
- | Structured output **jump-forward** (grammar-forced spans emitted without per-token forwards; SGLang technique via xgrammar) | **off** | serial only | Lab (string-lossless + validity gates, tests/grammar-jump.test.ts; token stream may differ — no oracle) | `MLX_BUN_GRAMMAR_JUMP=1` |
49
- | `guided_grammar` (EBNF) / `guided_regex`¹ / `guided_choice` / `structured_outputs` | on | both | L2 | request fields |
50
- | Structured output × speculative decoding | on (when both active) | serial | Lab (validity+equivalence) | — |
51
- | Quantized KV × speculative decoding (any axis: uniform / config / turbo) | KV scheme wins — drafted requests decode serially WITHOUT speculation (spec lane is bf16-KV-only in v1; startup warning) | serial | — | omit `--kv-quant` to speculate |
52
- | Tool calling (Gemma sentinel / CPM+Qwen XML / GLM `arg_key`+`arg_value`) + `role:"tool"` loops | on | both | — | request `tools` |
53
- | Vision (`image_url` parts; PNG/JPEG/HEIC/AVIF/WebP/TIFF/GIF/BMP) | on (models with a tower); remote fetches refuse private/loopback/link-local hosts by default (SSRF guard) | serial | L1/L2 | `--allow-private-media` / `MLX_BUN_ALLOW_PRIVATE_MEDIA=1` re-permits LAN hosts |
54
- | **Video input** (`video_url`/`video` parts; mp4/mov H.264/HEVC/ProRes/… via the AVFoundation sidecar `mlx-bun-frame-extract`; 2 fps sampling, ≤768 frames, 256 MB body cap; never combines with audio) | on (Qwen3.5-family models); same SSRF guard | serial | mlx-vlm oracle (frames pipeline bit-exact; tests/qwen38-vision.test.ts) | `--allow-private-media` for LAN hosts |
55
- | **Audio input** (`input_audio`/`audio`/`audio_url` parts; WAV native, mp3/m4a/flac/ogg/aiff via CoreAudio; ≤30 s / 750 tokens per clip; mixes with images) | on (models with `audio_config` + sidecar tower: e4b); remote fetches refuse private/loopback/link-local hosts by default (SSRF guard) | serial³ | L2 (greedy stream EXACT vs the optiq internal model) | `--allow-private-media` / `MLX_BUN_ALLOW_PRIVATE_MEDIA=1` re-permits LAN hosts |
56
- | LoRA adapters (mount at start / hot-swap at runtime) | off | serial | — | `--adapter <dir>`, `POST /v1/adapters` |
57
- | Sampling: temperature / top-p / top-k / min-p / XTC / logit_bias / presence+frequency+repetition penalties | per-request | both | L1 (mlx-lm-faithful) | request fields / server defaults |
58
- | `logprobs` / `top_logprobs` (mlx-lm semantics) | off | serial | L1 | request fields |
59
- | Fixed `seed` reproducibility | off | serial (routes solo) | — | request field |
60
- | Thinking-mode control (hybrid-reasoning models) | model default | both | — | `--thinking`, `chat_template_kwargs` |
61
- | Stop sequences / streaming / usage accounting | on | both | — | request fields |
62
- | HLG tone-curve sampling | off | serial | Lab | `--hlg-sampling on` |
63
- | Spec-decode telemetry (`usage.speculation`) | on with a draft | serial | — | — |
64
- | Per-turn lane telemetry (`usage.lane`: serial / serial+spec / batched) | on | both | — | — |
65
-
66
- ## Model coverage (per-model validated cells — no generic path is trusted untested)
67
-
68
- | Family | Serial | Batch | Notes |
69
- | --- | --- | --- | --- |
70
- | MiniCPM5 (cpm5) | ✅ L1/L2 | ✅ | the starter model |
71
- | Gemma 4 (1B/e4b/12B/26B, + vision e4b/12B, + audio e4b) | ✅ L1/L2 | ✅ | sliding+full interleaved; MoE 26B |
72
- | Qwen3.5 (gated-DeltaNet hybrid) | ✅ L1/L2 | ✅ (SSM path) | `MLX_BUN_BATCH_SSM=0` reverts |
73
- | Qwen3.8-27B (same qwen3_5 graph) | ✅ L1 (no L2 oracle) | ✅ (SSM path) | thinking depths + preserve_thinking; native MTP head mounts via `--draft-model` (DeltaNet spec rollback = snapshot/replay, lossless-gated; quiet-box A/B: 0.82× — correct but slower, opt-in); **vision (images) AND video SERVE** — bf16 tower sidecar + mRoPE + embed splice, oracle = mlx-vlm on pinned mlx (preprocessor/tower/positions bit-exact, e2e token-exact on 2/3 fixtures, serve smokes green; tests/qwen38-vision.test.ts); video files decode via the shipped AVFoundation sidecar (`mlx-bun-frame-extract`, src/native/frame_extract.swift — 2 fps, ≤768 frames, temporal pairs, per-frame-group attention) |
74
- | GLM-5.2 / Colibri (pre-release port gate) | ✅ chat/text, Messages, Responses, SSE, tools, grammar, logprobs, library/CLI | ✅ compressed MLA/DSA scheduler | native MTP defaults to serial+spec; `--mtp off` enables ordinary batching; artifact-aware CLI/API/status `fit` and live main/MTP expert-tier telemetry; embeddings, vision/audio, adapters, and training are explicitly unsupported; per-row batched MTP is post-release |
75
- | DiffusionGemma-26B (non-autoregressive) | ✅ (own engine) | — serial always | first bit-exact non-AR port |
76
- | Tier-0 universal (llama/qwen2/qwen3/olmo2/…, 11 archs) | ✅ L1 | ✅ plain full-attention archs² | gemma2-family/sliding universal → serial |
77
-
78
- ## Beyond serving (the same binary)
79
-
80
- Training (`mlx-bun train`: ORPO/DPO/SFT, flash-CCE, segmented backward) ·
81
- quantization (`convert`, `fuse`, `--target-bpw`) · embeddings · local
82
- memory/wiki (`mlx-bun memory`) · pi agent integration (`mlx-bun pi`) ·
83
- model registry + `fit` planner + `gc` · HF `upload` · web chat Model Hub
84
- (`/api/hub/local` + `/search` + `/download`, per-row `/fit` verdict;
85
- `/api/hub/serve` is `restart_required`-only today — no in-process model-swap
86
- seam reaches `/ws/chat`, see [server-api.md](server-api.md#model-hub-apihub))
87
- · **PWA installability** (manifest + shell-only service worker —
88
- installable, instant static-shell paint; explicitly not offline chat, see
89
- [server-api.md](server-api.md#web-app-static-routes--pwa-installability)).
90
- See [cli.md](cli.md) and the per-topic reference docs.
91
-
92
- ---
93
- ¹ `guided_regex` accepts the regex∩EBNF subset today (no `\d`/anchors — those degrade to prompt injection); real regex support is tracked.
94
- ² Gated token-exact vs mlx-lm B=2 (static + dynamic join/leave) on Llama-3.2-3B.
95
- ³ Audio is a capability neither ancestor SERVES: mlx-lm strips the audio tower at load and 400s non-text parts; optiq ships the full machinery but never wires it into its serve frontend — mlx-bun exposes it. Serial lane by design (embeddings prefill; batched audio has no oracle → novel-territory gates would apply), prompt cache skipped.
96
-
97
- Composition rules and exclusions (what combines with what):
98
- [server-config.md → Compatibility matrix](server-config.md#compatibility-matrix).
99
- Performance per mode: `scripts/bench-modes.ts` (TTFT / prefill / decode /
100
- peak-memory across every cell above); feature-composition perf:
101
- `scripts/bench-feature-matrix.ts`.
@@ -1,135 +0,0 @@
1
- # ORPO training quickstart — the full stack, preconfigured
2
-
3
- One launcher runs the complete new system — **flash-CCE Metal head** (steel fwd+bwd,
4
- `[M,V]`-free) + **segmented backward** (gradient-checkpointed layer activations) +
5
- **prefix-sharing** (one forward over `[prompt; chosen; rejected]`) + LoRA. Each feature
6
- **falls back and logs** if a precondition isn't met (e.g. a row whose chosen/rejected
7
- prompts aren't identical → two-forward for that row).
8
-
9
- ## Command — `mlx-bun train` (recommended)
10
-
11
- ```bash
12
- mlx-bun train <model> --data <dir>
13
- ```
14
- - `<model>` is a query or snapshot path (e.g. `e4b`, `MiniCPM5`); omit it to auto-pick.
15
- - `--data <dir>` is a directory with `train.jsonl` (+ optional `valid.jsonl`); rows are
16
- `{"prompt": "...", "chosen": "...", "rejected": "..."}`.
17
- - The full stack (flash head + prefix-share + segmented) is on by default. No env-flag
18
- setup is needed for any model (the old Gemma training-flag requirement is gone —
19
- the no-vjp kernels were deleted 2026-07-05).
20
- - It prints a plan box (dataset counts, format, the resolved knobs), streams per-step loss
21
- + peak memory, and saves a **mountable** adapter (`mlx-bun serve <model> --adapter <dir>`).
22
- - `--dry-run` inspects the dataset and prints the plan without training. `mlx-bun help train`
23
- lists every flag.
24
-
25
- ```bash
26
- # e4b ORPO on your preference data, checkpointing every 200 steps; run it detached
27
- nohup mlx-bun train e4b --data ./prefs --iters 1000 --save-every 200 > train.log 2>&1 &
28
- # resume from a checkpoint (warm-start the LoRA weights)
29
- mlx-bun train e4b --data ./prefs --resume ~/.cache/mlx-bun/mlx-bun-finetunes/orpo-e4b/checkpoints/step-00200
30
- ```
31
-
32
- | flag | default | meaning |
33
- |---|---|---|
34
- | `--method` | `orpo` | `sft` · `dpo` · `orpo` |
35
- | `--iters` | 100 | iterations |
36
- | `--lr` | orpo 1e-5 · dpo 5e-5 · sft 2e-4 | learning rate (cosine + short warmup) |
37
- | `--rank` / `--scale` | orpo 16 / 2.0 | LoRA rank (by_bits scaled) / scale |
38
- | `--seq` | e4b 8192 · cpm 4096 | max sequence length |
39
- | `--lambda` | 0.1 | ORPO odds-ratio weight |
40
- | `--sft-scope` | `full` | ORPO chosen-NLL scope (`sft_scope`): `full` = paper/TRL-faithful prompt+response CE · `response` = response-only, bit-exact to pre-2026-07 runs |
41
- | `--grad-accum` | 1 | gradient accumulation steps (effective batch = batch × grad-accum at batch-size-1 memory) |
42
- | `--grad-clip` | 1.0 | gradient-norm clip (0 = off) |
43
- | `--seed` | 0 | data-shuffle / init seed |
44
- | `--val-size` | 256 | max validation examples per eval |
45
- | `--seg` | 2 | layers/segment (segmented backward); `--no-segment` to disable |
46
- | `--save-every` | off | mountable checkpoint every N steps |
47
- | `--resume <dir>` | — | warm-start LoRA weights from a checkpoint/adapter |
48
- | `--no-flash` / `--no-prefix` | (on) | drop the flash Metal head / prefix-sharing |
49
- | `--adapter <dir>` | `~/.cache/mlx-bun/mlx-bun-finetunes/<method>-<model>` | output dir |
50
-
51
- > **Long runs:** launch detached from your own shell (`nohup … &`). Foreground is fine for
52
- > short runs; the command blocks and streams until done.
53
-
54
- ## The launcher (env-var alternative)
55
-
56
- `scripts/train-orpo.ts` is the same stack driven by env vars — handy for scripting:
57
-
58
- ```bash
59
- MODEL=/path/to/snapshot DATA=/path/to/datadir bun scripts/train-orpo.ts
60
- ```
61
- - `DATA` is a directory with `train.jsonl` (+ optional `valid.jsonl`).
62
-
63
- ### Preconfigured defaults (override via env)
64
- | env | default | meaning |
65
- |---|---|---|
66
- | `SEQ` | e4b 8192 · cpm 4096 | max sequence length |
67
- | `SEG` | 2 | segment size (layers/segment); the validated e4b@8192 sweet spot |
68
- | `ITERS` | 100 | iterations |
69
- | `LR` | 1e-5 | learning rate (cosine + short warmup) |
70
- | `RANK` / `SCALE` | 16 / 2.0 | LoRA rank (by_bits scaled) / scale |
71
- | `LAMBDA` | 0.1 | ORPO odds-ratio weight |
72
- | `SFT_SCOPE` | `full` | chosen-NLL scope: `full` (paper/TRL-faithful, prompt+response) · `response` (pre-2026-07 response-only, reproduces old runs) |
73
- | `FLASH=0` | (on) | use the MLX fused head instead of the flash Metal head |
74
- | `PREFIX=0` | (on) | disable prefix-sharing (plain two-forward) |
75
- | `SEGOFF=1` | (off) | disable the segmented backward (more memory) |
76
- | `ADAPTER` | `~/.cache/mlx-bun/mlx-bun-finetunes/orpo-<model>` | output dir (the finetunes cache, not the repo) |
77
-
78
- Example — e4b overnight at 8192:
79
- ```bash
80
- MODEL=~/.cache/huggingface/hub/models--mlx-community--gemma-4-e4b-it-OptiQ-4bit/snapshots/<snap> \
81
- DATA=./data/mydpo ITERS=200 bun scripts/train-orpo.ts
82
- ```
83
-
84
- ## What to expect — performance (measured, M1 Max 32 GB)
85
-
86
- ### e4b (Gemma4, H=2560, V=262144) — full stack
87
- | seq | config | peak GB | s/step |
88
- |---|---|---|---|
89
- | 8192 | flash + segmented(2) + **prefix-share** (prompt-dominant data) | **13.3** | **~70** |
90
- | 8192 | flash + segmented(2), no prefix | 16.1 | ~175 |
91
- | 4096 | flash + segmented(2), no prefix | 11.7 | ~81 |
92
- | 2048 | flash + segmented(2), no prefix | 10.2 | ~40 |
93
- | 1024 | flash + segmented(2), no prefix | 8.7 | ~21 |
94
-
95
- - **Fits comfortably in 32 GB at 8192** (the historical "e4b OOMs ≥2048" ceiling is gone).
96
- - **Prefix-sharing is a real win when the prompt dominates** — at 8192 with a long shared
97
- prompt it cut memory 16→13 GB *and* step time 175→70 s (prompt encoded once, not twice).
98
- On response-dominant data the saving shrinks toward zero (and it falls back per-row when
99
- prompts differ); it never hurts correctness.
100
- - Memory is **linear in sequence length** (~+1.5 GB / 1024 tokens) — segmenting + flash
101
- attention keep it linear, not quadratic. The head itself is **flat 0.93 GB** regardless
102
- of vocab/seq.
103
- - An ~8 h run at 8192 ≈ 100–400 steps depending on the prompt/response split.
104
-
105
- ### MiniCPM5 (1B, H=1536, V=130560) — full stack
106
- - Fits easily (~1–2 GB at short seq). ~0.4–1 s/step at seq 256; scales with seq.
107
- - Everything composes (flash / segmented / prefix-share, in any combination).
108
-
109
- ### The flash-CCE head in isolation (the piece that made large-vocab affordable)
110
- - Forward 180 ms, backward **754 ms** (e4b) / 224 ms (cpm) — exact (dh 0.40% / 0.28%
111
- bf16-class), `[M,V]`-free, peak **0.93 GB flat at M=8192**. The backward is **5× the old
112
- hand-rolled kernel** (3687 ms) via the verbatim MLX steel GEMM + fused dequant.
113
-
114
- ## Fallback behavior (logged)
115
- - **Prefix-share, per row**: if `chosen`/`rejected` prompts aren't byte-identical →
116
- two-forward for that row. The first occurrence logs `prefix-share: row prompt mismatch
117
- → two-forward fallback`; the saving is lost only on mismatched rows.
118
- - **`FLASH=0`** → the MLX fused linear-CE head (`quantizedMatmul` both ways; exact,
119
- `[chunk,V]` transient) instead of the Metal kernel.
120
- - **`SEGOFF=1`** → all layer activations resident (only viable at short seq on e4b).
121
- - Models other than MiniCPM5 / Gemma4 with `orpoPrefixShared` error out (not silently).
122
-
123
- ## Optional / experimental
124
- - The Apple-CCE backward skips (`MLX_BUN_CCE_BWD_BLOCK_EPS=1e-5`, the lossless vocab-block
125
- skip; `MLX_BUN_CCE_BWD_FILTER_EPS=1e-5`, the coeff filter) are **off by default** — on
126
- the now-fast steel kernel they give little and the coeff filter costs gradient accuracy.
127
- The block skip *can* help on long genuinely-peaked real text; A/B it on your data and
128
- watch that the loss doesn't move.
129
-
130
- ## Caveats (honest)
131
- - The e4b numbers above are from **short probe runs** (2–3 steps); they confirm the
132
- pipeline runs, fits memory, and produces finite/decreasing loss — **not** training
133
- quality (that's your data + hyperparameters).
134
- - e4b gradients are **bf16-class** (~1–3% vs an exact reference) — expected for the fused
135
- bf16 path; MiniCPM5 is tighter (forward bit-exact, grads ~1%).
package/src/flags.ts DELETED
@@ -1,11 +0,0 @@
1
- import { runtimeFlag, type RuntimeKey } from "./runtime-config";
2
-
3
- // Generic on/off resolver for per-fork decode flags. Process environment is
4
- // captured once by runtime-config; CLI tier aliases install an explicit
5
- // immutable override before model modules are loaded.
6
-
7
- /** Resolve an on/off env flag. An explicit "1"/"0" always wins; otherwise the
8
- * flag takes `defaultOn`. */
9
- export function flagOn(name: RuntimeKey, defaultOn: boolean): boolean {
10
- return runtimeFlag(name, defaultOn);
11
- }
File without changes