mlx-bun 0.4.0 → 1.0.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 (601) hide show
  1. package/README.md +1453 -88
  2. package/THIRD_PARTY_NOTICES.md +882 -0
  3. package/bin/mlx-bun.convert.mjs +4 -0
  4. package/bin/mlx-bun.fuse.mjs +4 -0
  5. package/bin/mlx-bun.generate.mjs +4 -0
  6. package/bin/mlx-bun.lora.mjs +4 -0
  7. package/bin/mlx-bun.mjs +13 -21
  8. package/bin/mlx-bun.server.mjs +4 -0
  9. package/bin/mlx-bun.upload.mjs +4 -0
  10. package/dist/web/app.js +9584 -0
  11. package/package.json +50 -53
  12. package/src/cli/ane-install.ts +76 -0
  13. package/src/cli/args.ts +179 -0
  14. package/src/cli/engine-entry.ts +68 -0
  15. package/src/cli/inference.ts +214 -0
  16. package/src/cli/job-entry.ts +97 -0
  17. package/src/cli/library-host.ts +117 -0
  18. package/src/cli/main.ts +57 -0
  19. package/src/cli/memory-engine.ts +163 -0
  20. package/src/cli/memory.ts +36 -0
  21. package/src/cli/mlx-lm-aliases.ts +309 -0
  22. package/src/cli/model-choice.ts +33 -0
  23. package/src/cli/model-selection.ts +84 -0
  24. package/src/cli/module-host.ts +11 -0
  25. package/src/cli/module-verbs.ts +50 -0
  26. package/src/cli/numerical-policy.ts +12 -0
  27. package/src/cli/perplexity.ts +89 -0
  28. package/src/cli/serve-host.ts +423 -0
  29. package/src/cli/serve-isolated.ts +217 -0
  30. package/src/cli/serve-options.ts +106 -0
  31. package/src/cli/serve-state.ts +205 -0
  32. package/src/cli/serve.ts +500 -0
  33. package/src/cli/served-model-host.ts +102 -0
  34. package/src/cli/server-entry.ts +148 -0
  35. package/src/cli/serving-unit.ts +177 -0
  36. package/src/{tui.ts → cli/terminal.ts} +13 -8
  37. package/src/cli/worker-adapters.ts +34 -0
  38. package/src/cli/worker-entry.ts +272 -0
  39. package/src/cli/worker-unit.ts +179 -0
  40. package/src/engine/adapter-operation.ts +26 -0
  41. package/src/engine/cache-services.ts +114 -0
  42. package/src/engine/completion.ts +39 -0
  43. package/src/engine/generation-gateway.ts +358 -0
  44. package/src/engine/index.ts +59 -0
  45. package/src/engine/kv-budget.ts +120 -0
  46. package/src/engine/media-preparation.ts +232 -0
  47. package/src/engine/model-binding.ts +24 -0
  48. package/src/engine/model-host.ts +513 -0
  49. package/src/engine/model-serving.ts +89 -0
  50. package/src/{serve → engine}/preparation.ts +10 -8
  51. package/src/{serve → engine}/session-completion-engine.ts +6 -6
  52. package/src/engine/telemetry.ts +109 -0
  53. package/src/hub/downloads.ts +116 -0
  54. package/src/jobs/db.ts +16 -7
  55. package/src/jobs/events.ts +29 -0
  56. package/src/jobs/executable.ts +5 -0
  57. package/src/jobs/host.ts +51 -0
  58. package/src/jobs/in-process.ts +55 -0
  59. package/src/{contracts/jobs.ts → jobs/protocol.ts} +7 -9
  60. package/src/jobs/runner.ts +150 -231
  61. package/src/jobs/service.ts +75 -0
  62. package/src/jobs/sse.ts +59 -23
  63. package/src/jobs/worker-memory.ts +46 -0
  64. package/src/jobs/worker-process.ts +163 -0
  65. package/src/jobs/worker-supervisor.ts +258 -0
  66. package/src/modules.ts +58 -0
  67. package/src/publishing/catalog-hub.ts +18 -0
  68. package/src/publishing/credentials.ts +31 -0
  69. package/src/publishing/upload.ts +37 -0
  70. package/src/residency/leased-adapters.ts +21 -0
  71. package/src/residency/local-records.ts +16 -0
  72. package/src/residency/model-residency.ts +405 -0
  73. package/src/residency/record-index.ts +28 -0
  74. package/src/residency/resident-estimate.ts +50 -0
  75. package/src/{anthropic.ts → server/anthropic.ts} +3 -81
  76. package/src/server/cache-routes.ts +36 -0
  77. package/src/{serve → server}/chat-request.ts +12 -10
  78. package/src/{serve → server}/chat-stage.ts +27 -22
  79. package/src/{client.ts → server/client.ts} +28 -2
  80. package/src/{serve → server}/completion-executor.ts +42 -42
  81. package/src/server/decision-body.ts +55 -0
  82. package/src/server/decision-routes.ts +134 -0
  83. package/src/server/decision-wire.ts +228 -0
  84. package/src/{serve → server}/discovery-routes.ts +42 -83
  85. package/src/server/generated-token-history.ts +57 -0
  86. package/src/{serve → server}/http.ts +25 -13
  87. package/src/{serve → server}/inference-request.ts +5 -5
  88. package/src/server/job-routes.ts +20 -0
  89. package/src/server/media-prompt.ts +63 -0
  90. package/src/server/memory-completion-client.ts +46 -0
  91. package/src/server/model-routes.ts +192 -0
  92. package/src/{serve → server}/openai-wire.ts +3 -2
  93. package/src/{serve → server}/pipeline.ts +1 -1
  94. package/src/server/prompt-builder.ts +13 -0
  95. package/src/server/prompt-contracts.ts +17 -0
  96. package/src/server/proxy-routes.ts +187 -0
  97. package/src/server/publishing-routes.ts +41 -0
  98. package/src/{serve → server}/request-plan.ts +8 -8
  99. package/src/{serve → server}/request-prep.ts +82 -68
  100. package/src/{serve → server}/responses-client.ts +30 -13
  101. package/src/{responses.ts → server/responses.ts} +12 -93
  102. package/src/server/routes.ts +205 -0
  103. package/src/server/start.ts +72 -0
  104. package/src/server/status-routes.ts +108 -0
  105. package/src/{serve → server}/text-completion-stage.ts +25 -4
  106. package/src/server/text-prompt.ts +12 -0
  107. package/src/{serve → server}/token-streams.ts +36 -38
  108. package/src/server/worker-routes.ts +311 -0
  109. package/src/storage/paths.ts +61 -0
  110. package/src/web/assets.ts +37 -0
  111. package/src/web/{src → browser}/api.ts +5 -23
  112. package/src/web/browser/chat-host.ts +17 -0
  113. package/src/web/browser/installed-panels.ts +6 -0
  114. package/src/web/browser/main.ts +55 -0
  115. package/src/web/browser/markdown.ts +279 -0
  116. package/src/web/browser/memory-panel.ts +9 -0
  117. package/src/web/browser/palette.ts +64 -0
  118. package/src/web/browser/protocol.ts +13 -0
  119. package/src/web/browser/shell.ts +467 -0
  120. package/src/web/{src → browser}/status.ts +32 -36
  121. package/src/web/build.ts +51 -0
  122. package/src/web/public/app.html +1054 -0
  123. package/src/web/{sw.js → public/sw.js} +4 -3
  124. package/src/web/{vendor → public/vendor}/hljs-theme.css +2 -2
  125. package/src/web/{vendor → public/vendor}/hljs.js +2 -2
  126. package/THIRD_PARTY_LICENSES.md +0 -51
  127. package/docs/README.md +0 -94
  128. package/docs/archive/hlg-sampling.md +0 -350
  129. package/docs/archive/investigations/audio-input-plan.md +0 -356
  130. package/docs/archive/investigations/chunk-finetune-experiment.md +0 -84
  131. package/docs/archive/investigations/colibri-glm52-port.md +0 -1486
  132. package/docs/archive/investigations/colibri-oracle-pin.md +0 -1284
  133. package/docs/archive/investigations/curve-bisector-routing.md +0 -123
  134. package/docs/archive/investigations/decode-roofline-lookagain.md +0 -348
  135. package/docs/archive/investigations/diffusion-gemma-port.md +0 -602
  136. package/docs/archive/investigations/dspark-handoff.md +0 -224
  137. package/docs/archive/investigations/expert-offload-single-user-moe.md +0 -292
  138. package/docs/archive/investigations/faithful-l1-consolidation.md +0 -310
  139. package/docs/archive/investigations/hlg-sampling-investigation.md +0 -970
  140. package/docs/archive/investigations/indexshare-performance-spike.md +0 -357
  141. package/docs/archive/investigations/kernel-perf-review-2026-07.md +0 -171
  142. package/docs/archive/investigations/lab-build-journal.md +0 -157
  143. package/docs/archive/investigations/minicpm5-decode-megakernel.md +0 -489
  144. package/docs/archive/investigations/openjarvis-fit.md +0 -198
  145. package/docs/archive/investigations/openwiki-evaluation.md +0 -249
  146. package/docs/archive/investigations/optimization_plan.md +0 -346
  147. package/docs/archive/investigations/orpo-base-uf-experiment-and-directions.md +0 -120
  148. package/docs/archive/investigations/orpo-flash-cce-pin-leak.md +0 -167
  149. package/docs/archive/investigations/orpo-uf-testing-handoff.md +0 -126
  150. package/docs/archive/investigations/pareto-specialized-runtime-findings.md +0 -92
  151. package/docs/archive/investigations/pi-builtin-investigation.md +0 -308
  152. package/docs/archive/investigations/pre-colibri-stabilization.md +0 -329
  153. package/docs/archive/investigations/qwen38-27b-campaign-log.md +0 -1092
  154. package/docs/archive/investigations/segmented-backward-handoff.md +0 -148
  155. package/docs/archive/investigations/starter-model-port-handoff.md +0 -342
  156. package/docs/archive/investigations/steel-flash-cce-handoff.md +0 -489
  157. package/docs/archive/investigations/the-dreaming-handoff.md +0 -141
  158. package/docs/archive/investigations/trainer-validation-experiment.md +0 -173
  159. package/docs/archive/planning/chat-ui-vision-memory-first.md +0 -199
  160. package/docs/archive/planning/chat-ui-vision.md +0 -50
  161. package/docs/archive/planning/chunk-task-roadmap.md +0 -77
  162. package/docs/archive/planning/curve-sampler-research-plan.md +0 -331
  163. package/docs/archive/planning/journal.md +0 -316
  164. package/docs/archive/planning/memory-docs-and-dag-plan.md +0 -194
  165. package/docs/archive/planning/pi-integration-review.md +0 -178
  166. package/docs/archive/planning/release-notes-v0.0.10.md +0 -57
  167. package/docs/archive/planning/release-notes-v0.0.11.md +0 -239
  168. package/docs/archive/planning/release-notes-v0.0.12.md +0 -80
  169. package/docs/archive/planning/release-notes-v0.0.13.md +0 -77
  170. package/docs/archive/planning/release-notes-v0.0.9.md +0 -122
  171. package/docs/archive/planning/release-notes-v0.2.0.md +0 -49
  172. package/docs/archive/planning/release-notes-v0.3.0.md +0 -35
  173. package/docs/archive/planning/web-ui-pass-plan.md +0 -213
  174. package/docs/archive/planning/website-readme-pass-plan.md +0 -224
  175. package/docs/design/batching.md +0 -1841
  176. package/docs/design/decode-speed-program.md +0 -2349
  177. package/docs/design/dreaming-nightly-pipeline.md +0 -684
  178. package/docs/design/generic-model-support.md +0 -705
  179. package/docs/design/kv-cache.md +0 -824
  180. package/docs/design/orpo-training.md +0 -680
  181. package/docs/design/speculative-decoding.md +0 -1990
  182. package/docs/design/turboquant.md +0 -2212
  183. package/docs/design/unified-engine-frontier-plan.md +0 -1880
  184. package/docs/design/web-chat-redesign.md +0 -695
  185. package/docs/planning/PRODUCT_ROADMAP.md +0 -594
  186. package/docs/planning/ResearchTopics.md +0 -119
  187. package/docs/planning/release-notes-v0.4.0.md +0 -45
  188. package/docs/planning/video-series.md +0 -421
  189. package/docs/reference/benchmarks.md +0 -3613
  190. package/docs/reference/cli.md +0 -585
  191. package/docs/reference/distribution.md +0 -355
  192. package/docs/reference/environment.md +0 -398
  193. package/docs/reference/glossary.md +0 -39
  194. package/docs/reference/library-api.md +0 -674
  195. package/docs/reference/memory.md +0 -260
  196. package/docs/reference/models.md +0 -334
  197. package/docs/reference/server-api.md +0 -1775
  198. package/docs/reference/server-config.md +0 -846
  199. package/docs/reference/training.md +0 -462
  200. package/docs/reference/troubleshooting.md +0 -158
  201. package/src/admission-plan.ts +0 -18
  202. package/src/audio/conformer.ts +0 -647
  203. package/src/audio/decode.ts +0 -133
  204. package/src/audio/features.ts +0 -202
  205. package/src/audio/transcode.ts +0 -67
  206. package/src/backends/mlx/assistant-target.ts +0 -46
  207. package/src/backends/mlx/autoregressive-draft-rows.ts +0 -120
  208. package/src/backends/mlx/autoregressive.ts +0 -108
  209. package/src/backends/mlx/batch-group.ts +0 -1790
  210. package/src/backends/mlx/cache-attachment.ts +0 -67
  211. package/src/backends/mlx/cache-layout.ts +0 -31
  212. package/src/backends/mlx/checkpoint-state.ts +0 -53
  213. package/src/backends/mlx/continuation-persistence.ts +0 -106
  214. package/src/backends/mlx/continuation-request.ts +0 -43
  215. package/src/backends/mlx/continuation.ts +0 -77
  216. package/src/backends/mlx/diffusion.ts +0 -39
  217. package/src/backends/mlx/draft-target.ts +0 -32
  218. package/src/backends/mlx/evaluation.ts +0 -105
  219. package/src/backends/mlx/fill-append.ts +0 -45
  220. package/src/backends/mlx/full-kv-row-append.ts +0 -32
  221. package/src/backends/mlx/full-kv-row-donor.ts +0 -54
  222. package/src/backends/mlx/full-transitioning-kv-rows.ts +0 -65
  223. package/src/backends/mlx/gateway-binding.ts +0 -130
  224. package/src/backends/mlx/graph.ts +0 -38
  225. package/src/backends/mlx/kv-codec.ts +0 -9
  226. package/src/backends/mlx/kv-maintenance.ts +0 -133
  227. package/src/backends/mlx/kv-tensor-rows.ts +0 -212
  228. package/src/backends/mlx/memory-client.ts +0 -189
  229. package/src/backends/mlx/methods.ts +0 -90
  230. package/src/backends/mlx/model-prompt.ts +0 -164
  231. package/src/backends/mlx/model-serving.ts +0 -79
  232. package/src/backends/mlx/prefill-cohort.ts +0 -89
  233. package/src/backends/mlx/prefill-rows.ts +0 -200
  234. package/src/backends/mlx/prefill.ts +0 -33
  235. package/src/backends/mlx/projected-context-rows.ts +0 -72
  236. package/src/backends/mlx/request-policy.ts +0 -20
  237. package/src/backends/mlx/request-state-policy.ts +0 -41
  238. package/src/backends/mlx/rollback.ts +0 -89
  239. package/src/backends/mlx/row-sampling.ts +0 -49
  240. package/src/backends/mlx/serial-executor.ts +0 -242
  241. package/src/backends/mlx/speculative-group.ts +0 -359
  242. package/src/backends/mlx/speculative-round.ts +0 -161
  243. package/src/backends/mlx/speculative.ts +0 -114
  244. package/src/backends/mlx/state-rows.ts +0 -104
  245. package/src/backends/mlx/state-views.ts +0 -46
  246. package/src/backends/mlx/target-layout-capability.ts +0 -35
  247. package/src/backends/mlx/text-engine.ts +0 -73
  248. package/src/backends/mlx/transitioning-kv-rows.ts +0 -165
  249. package/src/chat-template.ts +0 -382
  250. package/src/cli.ts +0 -3168
  251. package/src/config.ts +0 -399
  252. package/src/contracts/completion.ts +0 -16
  253. package/src/contracts/execution.ts +0 -60
  254. package/src/contracts/generation.ts +0 -103
  255. package/src/contracts/host.ts +0 -7
  256. package/src/contracts/pi-provider.ts +0 -30
  257. package/src/contracts/pi.ts +0 -259
  258. package/src/contracts/prefix-cache.ts +0 -23
  259. package/src/contracts/resources.ts +0 -25
  260. package/src/contracts/sampling.ts +0 -23
  261. package/src/contracts/scheduling.ts +0 -45
  262. package/src/contracts/tsconfig.json +0 -14
  263. package/src/dataset/generators.ts +0 -1087
  264. package/src/dataset/index.ts +0 -12
  265. package/src/dataset/job.ts +0 -81
  266. package/src/dataset/llm.ts +0 -71
  267. package/src/dataset/registry.ts +0 -528
  268. package/src/diffusion/diffusion-generate.ts +0 -507
  269. package/src/download.ts +0 -505
  270. package/src/embed.ts +0 -77
  271. package/src/engine/admission.ts +0 -59
  272. package/src/engine/cancellation.ts +0 -38
  273. package/src/engine/engine.ts +0 -56
  274. package/src/engine/execution-coordinator.ts +0 -70
  275. package/src/engine/execution-plan.ts +0 -53
  276. package/src/engine/resources.ts +0 -53
  277. package/src/engine/scheduler.ts +0 -72
  278. package/src/engine/session.ts +0 -247
  279. package/src/eval/README.md +0 -130
  280. package/src/eval/ifeval.ts +0 -81
  281. package/src/eval/kl-prompts.ts +0 -29
  282. package/src/eval/kl.ts +0 -590
  283. package/src/eval/perplexity.ts +0 -164
  284. package/src/eval/quality-db.ts +0 -92
  285. package/src/eval/reference-logits.ts +0 -207
  286. package/src/eval/runner.ts +0 -124
  287. package/src/eval/score.ts +0 -49
  288. package/src/eval/tasks/bfcl.ts +0 -535
  289. package/src/eval/tasks/gsm8k.ts +0 -98
  290. package/src/eval/tasks/hashhop.ts +0 -139
  291. package/src/eval/tasks/humaneval.ts +0 -275
  292. package/src/eval/tasks/ifeval.ts +0 -525
  293. package/src/eval/tasks/mmlu.ts +0 -157
  294. package/src/eval/ultrafeedback.ts +0 -60
  295. package/src/evaldb.ts +0 -199
  296. package/src/expert-io.ts +0 -393
  297. package/src/expert-offload-build.ts +0 -77
  298. package/src/expert-offload.ts +0 -76
  299. package/src/expert-residency.ts +0 -1134
  300. package/src/expert-usage.ts +0 -415
  301. package/src/fill/echo-index.ts +0 -188
  302. package/src/fill/fill-session.ts +0 -452
  303. package/src/fill/proposal.ts +0 -68
  304. package/src/fill/schema-rows.ts +0 -506
  305. package/src/fill/tool-boundary.ts +0 -103
  306. package/src/fit.ts +0 -249
  307. package/src/generate.ts +0 -1346
  308. package/src/grammar.ts +0 -591
  309. package/src/harness-pi.ts +0 -184
  310. package/src/hf-push.ts +0 -628
  311. package/src/hub-rest.ts +0 -242
  312. package/src/index.ts +0 -63
  313. package/src/inference/denoising.ts +0 -17
  314. package/src/inference/draft-acceptance.ts +0 -41
  315. package/src/inference/draft-output.ts +0 -49
  316. package/src/inference/graph.ts +0 -33
  317. package/src/inference/prefill.ts +0 -39
  318. package/src/inference/rollback.ts +0 -7
  319. package/src/jobs/index.ts +0 -31
  320. package/src/jobs/job-entry.ts +0 -107
  321. package/src/jobs/task-client.ts +0 -19
  322. package/src/jobs/types.ts +0 -2
  323. package/src/kv-scheme.ts +0 -257
  324. package/src/kv-store.ts +0 -1099
  325. package/src/lab/README.md +0 -18
  326. package/src/lab/curve/curve-designer.html +0 -303
  327. package/src/lab/curve/curve-sampler.ts +0 -122
  328. package/src/lab/expert-trace/expert-trace.ts +0 -69
  329. package/src/lab/paged-kv/paged-kv-rows.ts +0 -83
  330. package/src/lab/paged-kv/paged-kv.ts +0 -270
  331. package/src/library.ts +0 -40
  332. package/src/lora.ts +0 -408
  333. package/src/md-modules.d.ts +0 -49
  334. package/src/media-fetch.ts +0 -442
  335. package/src/memory/article.ts +0 -558
  336. package/src/memory/chunk-validation.ts +0 -150
  337. package/src/memory/chunk.ts +0 -318
  338. package/src/memory/cluster.ts +0 -351
  339. package/src/memory/coverage.ts +0 -134
  340. package/src/memory/crosslink.ts +0 -0
  341. package/src/memory/db.ts +0 -253
  342. package/src/memory/entity.ts +0 -203
  343. package/src/memory/gate.ts +0 -187
  344. package/src/memory/history.ts +0 -152
  345. package/src/memory/ingest.ts +0 -335
  346. package/src/memory/model.ts +0 -183
  347. package/src/memory/normalize.ts +0 -671
  348. package/src/memory/parse.ts +0 -22
  349. package/src/memory/pipeline.ts +0 -275
  350. package/src/memory/prompts.ts +0 -65
  351. package/src/memory/query.ts +0 -334
  352. package/src/memory/reconcile.ts +0 -734
  353. package/src/memory/redirect.ts +0 -108
  354. package/src/memory/reindex.ts +0 -325
  355. package/src/memory/resolve.ts +0 -307
  356. package/src/memory/rest.ts +0 -245
  357. package/src/memory/route.ts +0 -272
  358. package/src/memory/schedule.ts +0 -165
  359. package/src/memory/stages.ts +0 -777
  360. package/src/memory/synthesize.ts +0 -1638
  361. package/src/memory/tools.ts +0 -749
  362. package/src/memory/vault.ts +0 -1194
  363. package/src/memory/wikify.ts +0 -1064
  364. package/src/mlx/array.ts +0 -388
  365. package/src/mlx/autograd.ts +0 -304
  366. package/src/mlx/checkpoint.ts +0 -149
  367. package/src/mlx/compile.ts +0 -168
  368. package/src/mlx/custom-vjp.ts +0 -188
  369. package/src/mlx/ffi.ts +0 -512
  370. package/src/mlx/materialize.ts +0 -23
  371. package/src/mlx/metal-kernel.ts +0 -159
  372. package/src/mlx/ops.ts +0 -1021
  373. package/src/mlx/quantized-rows.ts +0 -36
  374. package/src/mlx/token-bitmask.ts +0 -52
  375. package/src/mlx/turboquant-kv-decode.ts +0 -82
  376. package/src/mlx/turboquant-kv-inverse.ts +0 -122
  377. package/src/mlx/turboquant-ops.ts +0 -861
  378. package/src/mlx/turboquant-tables.ts +0 -237
  379. package/src/mmap.ts +0 -90
  380. package/src/model/artifact-identity.ts +0 -73
  381. package/src/model/batched-kv.ts +0 -235
  382. package/src/model/batched-mask.ts +0 -279
  383. package/src/model/batched-quant.ts +0 -212
  384. package/src/model/batched-quantized-kv.ts +0 -144
  385. package/src/model/batched-rotating-quant.ts +0 -353
  386. package/src/model/batched-rotating-state.ts +0 -149
  387. package/src/model/batched-rotating.ts +0 -338
  388. package/src/model/batched-row-storage.ts +0 -179
  389. package/src/model/batched-ssm.ts +0 -52
  390. package/src/model/batched-turboquant-kv.ts +0 -93
  391. package/src/model/compiled-decode.ts +0 -712
  392. package/src/model/decoded-kv-donor.ts +0 -12
  393. package/src/model/delayed-quantized-kv.ts +0 -72
  394. package/src/model/delayed-rotating-quantized-kv.ts +0 -93
  395. package/src/model/delayed-turboquant-kv.ts +0 -55
  396. package/src/model/diffusion-gemma.ts +0 -1026
  397. package/src/model/factory.ts +0 -189
  398. package/src/model/fingerprint.ts +0 -33
  399. package/src/model/flash-attention.ts +0 -694
  400. package/src/model/full-prefill-padding.ts +0 -56
  401. package/src/model/full-prefill-row.ts +0 -105
  402. package/src/model/gemma4-base.ts +0 -2351
  403. package/src/model/gemma4.ts +0 -1315
  404. package/src/model/generated/gemma4-12b.ts +0 -429
  405. package/src/model/generated/gemma4-26b.ts +0 -448
  406. package/src/model/generated/gemma4-e4b.ts +0 -717
  407. package/src/model/generated/index.ts +0 -18
  408. package/src/model/glm52-atlas.ts +0 -511
  409. package/src/model/glm52-cache.ts +0 -792
  410. package/src/model/glm52-config.ts +0 -262
  411. package/src/model/glm52-container.ts +0 -305
  412. package/src/model/glm52-coupling.ts +0 -388
  413. package/src/model/glm52-dsa.ts +0 -606
  414. package/src/model/glm52-expert-layout.ts +0 -253
  415. package/src/model/glm52-layout.ts +0 -152
  416. package/src/model/glm52-memory.ts +0 -500
  417. package/src/model/glm52-mla.ts +0 -792
  418. package/src/model/glm52-moe.ts +0 -223
  419. package/src/model/glm52-pilot.ts +0 -537
  420. package/src/model/glm52-reference.ts +0 -445
  421. package/src/model/glm52-residency.ts +0 -557
  422. package/src/model/glm52-resident-weights.ts +0 -135
  423. package/src/model/glm52-streamed-experts.ts +0 -453
  424. package/src/model/glm52-streamed-metal.ts +0 -610
  425. package/src/model/glm52-weights.ts +0 -503
  426. package/src/model/glm52.ts +0 -1132
  427. package/src/model/implementation.ts +0 -69
  428. package/src/model/kv-attention-view.ts +0 -67
  429. package/src/model/minicpm5.ts +0 -376
  430. package/src/model/profile.ts +0 -443
  431. package/src/model/qwen-append.ts +0 -12
  432. package/src/model/qwen-conv.ts +0 -52
  433. package/src/model/qwen3-delta-state.ts +0 -74
  434. package/src/model/qwen3-delta.ts +0 -451
  435. package/src/model/qwen3-moe.ts +0 -404
  436. package/src/model/qwen3-mrope.ts +0 -252
  437. package/src/model/qwen3.ts +0 -277
  438. package/src/model/qwen3_5-checkpoint.ts +0 -164
  439. package/src/model/qwen3_5.ts +0 -819
  440. package/src/model/rotating-kv-donor.ts +0 -35
  441. package/src/model/rotating-kv-layout.ts +0 -262
  442. package/src/model/rotating-row-transaction.ts +0 -35
  443. package/src/model/speculative-rotating-kv.ts +0 -101
  444. package/src/model/ssm-prefill-padding.ts +0 -39
  445. package/src/model/support.ts +0 -102
  446. package/src/model/trellis-balanced-scatter.ts +0 -51
  447. package/src/model/trellis-linear.ts +0 -672
  448. package/src/model/trellis-shared-m.ts +0 -151
  449. package/src/model/trellis-shared-scatter.ts +0 -144
  450. package/src/model/trellis-splitk-prefill.ts +0 -158
  451. package/src/model/trellis-tiled-prefill.ts +0 -136
  452. package/src/model/trellis-vector-expand.ts +0 -62
  453. package/src/model/trellis-wide-prefill.ts +0 -94
  454. package/src/model/turboquant-codec.ts +0 -83
  455. package/src/model/universal/archs.ts +0 -332
  456. package/src/model/universal/dense.ts +0 -612
  457. package/src/model/universal/modules.ts +0 -170
  458. package/src/model/universal/rope.ts +0 -381
  459. package/src/native/expert_io.c +0 -523
  460. package/src/native/frame_extract.swift +0 -140
  461. package/src/native-pack.ts +0 -162
  462. package/src/pi-provider.ts +0 -53
  463. package/src/pi-session.ts +0 -81
  464. package/src/pi-terminal.ts +0 -274
  465. package/src/pi-web.ts +0 -1932
  466. package/src/preflight.ts +0 -158
  467. package/src/prompt-cache.ts +0 -460
  468. package/src/quantize/allocator.ts +0 -627
  469. package/src/quantize/atomic-output.ts +0 -38
  470. package/src/quantize/calibration.ts +0 -181
  471. package/src/quantize/config-writer.ts +0 -145
  472. package/src/quantize/index.ts +0 -84
  473. package/src/quantize/job.ts +0 -162
  474. package/src/quantize/quantizer.ts +0 -666
  475. package/src/quantize/rotate.ts +0 -603
  476. package/src/quantize/safetensors-writer.ts +0 -249
  477. package/src/quantize/sensitivity.ts +0 -216
  478. package/src/quantize/trellis.ts +0 -586
  479. package/src/quantize/weight-transform.ts +0 -292
  480. package/src/registry.ts +0 -602
  481. package/src/runtime-config.ts +0 -81
  482. package/src/safetensors.ts +0 -158
  483. package/src/sampler.ts +0 -1011
  484. package/src/serve/admin-routes.ts +0 -184
  485. package/src/serve/assets/curve-terrain.html +0 -105
  486. package/src/serve/assets/training-inference-map.html +0 -575
  487. package/src/serve/aux-routes.ts +0 -132
  488. package/src/serve/batch-scheduler.ts +0 -8
  489. package/src/serve/checkpoint-identity.ts +0 -64
  490. package/src/serve/generation-gateway.ts +0 -496
  491. package/src/serve/isolate.ts +0 -609
  492. package/src/serve/kv-budget.ts +0 -14
  493. package/src/serve/lab-routes.ts +0 -341
  494. package/src/serve/lane-registry.ts +0 -45
  495. package/src/serve/model-admin-routes.ts +0 -155
  496. package/src/serve/model-binding.ts +0 -43
  497. package/src/serve/model-host.ts +0 -511
  498. package/src/serve/parent-application.ts +0 -56
  499. package/src/serve/prompt-response-trace.ts +0 -147
  500. package/src/serve/response-lease.ts +0 -24
  501. package/src/serve/session-search.ts +0 -326
  502. package/src/serve/static-routes.ts +0 -101
  503. package/src/server.ts +0 -1314
  504. package/src/spec/assistant-rows.ts +0 -92
  505. package/src/spec/assistant-source.ts +0 -126
  506. package/src/spec/cache-identity.ts +0 -22
  507. package/src/spec/deepspec-rows.ts +0 -29
  508. package/src/spec/deepspec-source.ts +0 -145
  509. package/src/spec/dflash-source.ts +0 -149
  510. package/src/spec/drafter.ts +0 -304
  511. package/src/spec/dspark/ab-stats.ts +0 -136
  512. package/src/spec/dspark/calibration.ts +0 -112
  513. package/src/spec/dspark/data-dflash.ts +0 -156
  514. package/src/spec/dspark/data.ts +0 -201
  515. package/src/spec/dspark/deepspec-module.ts +0 -776
  516. package/src/spec/dspark/generate-dflash.ts +0 -245
  517. package/src/spec/dspark/generate.ts +0 -290
  518. package/src/spec/dspark/loader.ts +0 -23
  519. package/src/spec/dspark/loss.ts +0 -213
  520. package/src/spec/dspark/module-dflash.ts +0 -560
  521. package/src/spec/dspark/module.ts +0 -540
  522. package/src/spec/dspark/quantize-drafter.ts +0 -91
  523. package/src/spec/dspark/sample.ts +0 -112
  524. package/src/spec/generate.ts +0 -276
  525. package/src/spec/glm52-mtp-graph.ts +0 -29
  526. package/src/spec/glm52-mtp-rows.ts +0 -132
  527. package/src/spec/glm52-mtp-source.ts +0 -317
  528. package/src/spec/glm52-mtp-state.ts +0 -33
  529. package/src/spec/ngram-source.ts +0 -204
  530. package/src/spec/projected-draft-rows.ts +0 -73
  531. package/src/spec/qwen-mtp-module.ts +0 -171
  532. package/src/spec/qwen-mtp-rows.ts +0 -219
  533. package/src/spec/qwen-mtp-source.ts +0 -383
  534. package/src/spec/qwen-mtp-state.ts +0 -30
  535. package/src/spec/serve-loop.ts +0 -585
  536. package/src/spec/source.ts +0 -215
  537. package/src/spec/two-model-rows.ts +0 -61
  538. package/src/spec/two-model.ts +0 -113
  539. package/src/ssd-cache.ts +0 -372
  540. package/src/ssd-durability.ts +0 -211
  541. package/src/tokenizer.ts +0 -335
  542. package/src/tool-approvals.ts +0 -131
  543. package/src/tool-call.ts +0 -695
  544. package/src/train/dataset.ts +0 -484
  545. package/src/train/diffusion-lora.ts +0 -216
  546. package/src/train/export.ts +0 -32
  547. package/src/train/flash-cce.ts +0 -1234
  548. package/src/train/forward.ts +0 -266
  549. package/src/train/fuse.ts +0 -243
  550. package/src/train/index.ts +0 -46
  551. package/src/train/job.ts +0 -205
  552. package/src/train/lora-params.ts +0 -254
  553. package/src/train/loss.ts +0 -1591
  554. package/src/train/merge.ts +0 -195
  555. package/src/train/optimizer.ts +0 -183
  556. package/src/train/prefix-shared.ts +0 -490
  557. package/src/train/rank.ts +0 -137
  558. package/src/train/segmented.ts +0 -1828
  559. package/src/train/steel-qmm-header.ts +0 -1461
  560. package/src/train/trainer.ts +0 -1221
  561. package/src/train/watch.ts +0 -542
  562. package/src/vision/diffusion-vision.ts +0 -620
  563. package/src/vision/embedder.ts +0 -168
  564. package/src/vision/preprocess.ts +0 -247
  565. package/src/vision/prompt.ts +0 -373
  566. package/src/vision/qwen3vl-preprocess.ts +0 -409
  567. package/src/vision/qwen3vl-prompt.ts +0 -196
  568. package/src/vision/qwen3vl-tower.ts +0 -555
  569. package/src/vision/siglip.ts +0 -599
  570. package/src/vision/video-frames.ts +0 -148
  571. package/src/web/app.html +0 -2143
  572. package/src/web/app.js +0 -5703
  573. package/src/web/skills/memory/SKILL.md +0 -120
  574. package/src/web/skills/web-research/SKILL.md +0 -46
  575. package/src/web/skills.ts +0 -97
  576. package/src/web/src/adapters-panel.ts +0 -288
  577. package/src/web/src/assistant.ts +0 -451
  578. package/src/web/src/chat.ts +0 -1057
  579. package/src/web/src/composer.ts +0 -959
  580. package/src/web/src/dataset.ts +0 -132
  581. package/src/web/src/finetune.ts +0 -267
  582. package/src/web/src/hub.ts +0 -428
  583. package/src/web/src/main.ts +0 -98
  584. package/src/web/src/markdown.ts +0 -0
  585. package/src/web/src/memory-panel.ts +0 -572
  586. package/src/web/src/model-picker.ts +0 -159
  587. package/src/web/src/palette.ts +0 -346
  588. package/src/web/src/protocol.ts +0 -26
  589. package/src/web/src/quantize.ts +0 -167
  590. package/src/web/src/rag.ts +0 -274
  591. package/src/web/src/sessions.ts +0 -469
  592. package/src/web/src/shell.ts +0 -804
  593. package/src/web/src/ui-catalog.ts +0 -78
  594. package/src/web/vendor/README.md +0 -61
  595. package/src/web-assets.ts +0 -47
  596. package/src/web-tools.ts +0 -478
  597. package/src/weights.ts +0 -255
  598. /package/src/{serve → server}/completion-sink.ts +0 -0
  599. /package/src/web/{icon.svg → public/icon.svg} +0 -0
  600. /package/src/web/{manifest.webmanifest → public/manifest.webmanifest} +0 -0
  601. /package/src/web/{vendor → public/vendor}/hljs-LICENSE +0 -0
@@ -1,705 +0,0 @@
1
- ---
2
- status: active
3
- axis: ON
4
- canonical-for: model-support
5
- plan-anchor: "Serving architecture consolidation `[~]` (opened 2026-08-21)"
6
- last-verified: 2026-08-23
7
- ---
8
-
9
- # Model support — run anything mlx-lm runs, and the ports we target
10
-
11
- **This is the one design doc for model support.** New model ports become
12
- SECTIONS under §6 (Ports) of this file, not new files in `docs/design/`.
13
- Per-port phase logs, gate results, and dates belong in PLAN.md (anchors are
14
- named per section); this doc keeps the design and the oracle each port is
15
- held to.
16
-
17
- Direction (Josh): *"we should be able to run any model that mlx-lm can run.
18
- Run any model generically; for the specific models we target, optimize them
19
- further — push the quality/performance border outwards. Like the gemma
20
- generator methodology."*
21
-
22
- Two tiers, one contract:
23
-
24
- - **Tier-0 GENERIC** — one config-driven "universal" module per architecture
25
- *family*. Runs any covered checkpoint at **L1 parity** (bit-exact vs mlx-lm
26
- on this machine's GPU). Monolith path only, without compiled decode.
27
- Standard attention now uses the shared plain/affine KV port; the softcap
28
- branch retains plain KV. Qualified full-attention targets compose delayed
29
- affine conversion with standalone and lookup drafting through the same
30
- cache transaction interface; rotating layouts use that interface for
31
- per-layer conversion and assistant donors. Built: `src/model/universal/` (dense
32
- llama-family). Design only: UniversalMoE.
33
- - **Tier-1 TARGETED** — a model *graduates*: dedicated or generated forward,
34
- L2 (mlx-optiq) composition where an optiq artifact exists, Lab experiments
35
- where warranted, benchmark entries. The ports in §6.
36
-
37
- **L1 = mlx-lm bit-exact is the gate for ANY new model**, generic or targeted.
38
- Where no mlx-lm arm exists (audio, vision towers, DiffusionGemma, GLM-5.2's
39
- Colibri container) the oracle is whoever ships the capability — optiq's
40
- internal machinery, mlx-vlm, or the pinned Colibri engine — and the profile
41
- declares that fidelity honestly (§3). A model the generic tier cannot hold to
42
- L1 parity is not "supported with caveats"; it is unsupported until fixed.
43
-
44
- ---
45
-
46
- ## 1. The mlx-lm zoo, inventoried (mlx-lm 0.31.3, the oracle venv)
47
-
48
- 108 model files in `site-packages/mlx_lm/models/` after excluding
49
- infrastructure (`base`, `cache`, `rope_utils`, `activations`,
50
- `switch_layers`, `ssm`, `gated_delta`, `mla`, `bitlinear_layers`,
51
- `pipeline`). `utils.py MODEL_REMAPPING` adds free aliases (`mistral→llama`,
52
- `kimi_k2→deepseek_v3`, `qwen2_5_vl→qwen2_vl`, `falcon_mamba→mamba`, …).
53
-
54
- | Bucket | ~Files | Shape | Unlocked by |
55
- |---|---|---|---|
56
- | A. dense llama-family | ~36 | embed → N × (norm → GQA attn(+rope) → residual → norm → MLP → residual) → norm → head; every file a permutation of a dozen knobs | **UniversalDense** (built) |
57
- | B. MoE llama-family | ~17 | same block, MLP → router + SwitchGLU (+ shared expert) | **UniversalMoE** (design) |
58
- | F. vision/text wrappers | ~10 | mlx-lm runs only the text stack; ~50–120 lines of config unwrapping + prefix stripping | thin shims over A/B |
59
- | C. MLA lineage | ~11 | DeepSeek latent attention, usually + MoE + yarn | one MLA module, demand-driven (most exceed local RAM at 4-bit) |
60
- | D. SSM / hybrid / linear-attention | ~17 | individually shaped (mamba, jamba, lfm2, qwen3_next, rwkv7, qwen3_5 …) | individual ports, the qwen3_5 pattern |
61
- | E. legacy / exotic | ~13 | gpt2, openelm, phi3small, dbrx, bitnet … | individual ports, likely never |
62
-
63
- Two generic modules + the wrapper shims cover roughly 60% of the zoo by
64
- file count and the large majority of what actually gets downloaded (Llama
65
- 3.x, Mistral/Ministral, Qwen 2.5/3 dense+MoE, Gemma 1–3, Phi-3/4, SmolLM3,
66
- OLMo-2/3, GLM-4, Granite, Mixtral, OLMoE are all in A/B/F).
67
-
68
- ---
69
-
70
- ## 2. Building blocks (what every tier is made of)
71
-
72
- - **Config parsing** — `src/config.ts loadModelConfig` produces a normalized
73
- `TextConfig` (layerTypes/slidingWindow, headDim fallback, tie, softcap,
74
- partialRotaryFactor, `ropeParameters`, per-layer quant map via `quantFor`,
75
- kv_config, sidecar detection). Per-arch quirks for the generic tier live in
76
- the descriptor table (§4.1), not in this if-chain.
77
- - **Primitives** — `src/model/gemma4-base.ts`: `QuantizedLinear` (+LoRA
78
- residual), `QuantizedEmbedding` (+tied `asLinear`), `RMSNorm`,
79
- `QuantizedSwitchLinear` (MoE experts), `KVCache`/`RotatingKVCache` (+
80
- quantized and TurboQuant variants), mask machinery, `logitSoftcap`,
81
- `disposing`. `src/model/universal/modules.ts` adds the dense
82
- (unquantized) `nn.Linear`/`nn.Embedding` ports and the load-time
83
- `WeightAudit`.
84
- - **Generator** — `scripts/gen-model.ts` emits unrolled, branch-resolved
85
- `forwardLayers` overrides of `Gemma4Model` into `src/model/generated/`
86
- (e4b, 12B, 26B), dispatched by config fingerprint, gated bit-exact vs the
87
- monolith by `tests/generated-parity.test.ts`.
88
- - **Parity harness** — `scripts/regen.ts <job>` (jobs: `parity`,
89
- `parity-26b`, `kvq`, `rotating-kvq`, `mixed-kv`, `lora`, `fused-sdpa`,
90
- `universal`, `qwen-parity`, `minicpm5`, `minicpm5-kv`, `turboquant`,
91
- `audio-fixtures`) drives the oracle venv
92
- (`/Users/joshrossi/Code/mlx-lm/.venv/bin/python`) to emit
93
- `<prefix>-parity.json` (explicit prompt ids + greedy ids) plus per-step raw
94
- logit `.bin`s; `tests/*-parity.test.ts` replay the ids (no cross-stack
95
- tokenizer dependency) and compare bit-exact on the same GPU. Manifests are
96
- tracked; `.bin` blobs are machine-specific and untracked
97
- (goldens/README.md).
98
- - **Tokenizer** — `src/tokenizer.ts` (`@huggingface/tokenizers`, pure JS)
99
- reads stock `tokenizer.json` + `tokenizer_config.json`. Known landmine:
100
- BOS conventions (the double-BOS bug). Chat-template rendering rides Pi;
101
- `/v1` is the boundary.
102
-
103
- ---
104
-
105
- ## 3. Model profiles — capability declaration (`src/model/profile.ts`)
106
-
107
- Model loading resolves ONE immutable profile before weights are opened.
108
- A profile declares **construction only**: request-level methods (MTP, KV
109
- schemes, adapters, grammar, sampling) are resolved elsewhere and cannot be
110
- rewritten by profile selection.
111
-
112
- ```ts
113
- interface ModelProfile {
114
- id: string;
115
- artifactFingerprint?: string; // exact external identity (hf:<repo>@<rev>); family profiles omit
116
- configFingerprint?: string; // structural guard for an exact artifact declaration
117
- fidelity: FidelityTarget; // {l1, mlx-lm, bit-exact} | {l2, mlx-optiq, bit-exact} | {l3, null, measured}
118
- requiredCapabilities: EngineCapability[];
119
- execution: { loader: "safetensors" | "colibri";
120
- graph: "gemma4" | "minicpm5" | "qwen3.5" | "qwen3" | "qwen3-moe"
121
- | "diffusion-gemma" | "glm5.2" | "universal-dense";
122
- loop: "autoregressive" | "diffusion";
123
- specialization: "artifact" | "dedicated" | "generated" | "generic" };
124
- }
125
- ```
126
-
127
- Engine capabilities (`ENGINE_CAPABILITIES`): `autoregressive`,
128
- `colibri-container`, `diffusion`, `diffusion-gemma-graph`, `gemma4-graph`,
129
- `generated-graph`, `glm5.2-graph`, `minicpm5-graph`, `mixed-precision-kv`,
130
- `native-mtp`, `qwen3-graph`, `qwen3-moe-graph`, `qwen3.5-graph`,
131
- `recurrent-state`, `safetensors`, `streamed-experts`,
132
- `universal-dense-graph`, `vision-sidecar`.
133
-
134
- Resolution (`resolveModelProfile`):
135
-
136
- 1. **Exact artifact profiles outrank family profiles.** The external
137
- fingerprint is derived only from an immutable HF snapshot path
138
- (`models--<org>--<repo>/snapshots/<40–64 hex>`); relocation keeps the
139
- identity, mutable aliases and arbitrary local dirs return null. A matched
140
- exact profile whose config fingerprint or graph acceptance mismatches
141
- REFUSES — it never falls back. Built-in exact declarations today:
142
- `qwen3.8-27b-optiq-4bit` (L1) and `glm5.2-colibri-int4-int8-mtp` (L3).
143
- 2. **Family profile** by config predicate (`src/model/support.ts`), in this
144
- order: `glm_moe_dsa` → `diffusion_gemma` → MiniCPM5 (exact-shape `llama`
145
- predicate) → `qwen3_5`/`qwen3_5_text` (dense hybrid only; the MoE variant
146
- is excluded) → `qwen3_moe` → `qwen3` → `gemma4*` (generated class if
147
- `GENERATED.has(fingerprint)`, else monolith) → universal-dense if
148
- `genericArgsFor(config)` resolves → throw naming the targeted list and
149
- the generic descriptor keys.
150
- 3. `validateProfile` enforces the fidelity/oracle pairing, loader↔graph
151
- (`glm5.2` ⇒ colibri), loop↔graph (`diffusion-gemma` ⇒ diffusion), and that
152
- every capability the execution composition implies is declared. Missing
153
- engine capabilities refuse; nothing downgrades.
154
-
155
- **Factory** (`src/model/factory.ts`): `openModel(dir)` resolves the profile,
156
- routes `loader: "colibri"` through `openGlm52RuntimeModel` (header-only
157
- memory plan first, then `Glm52Model.openStreamed`; the Colibri snapshot has no
158
- `model.safetensors.index.json` so it bypasses `Weights.open`), and otherwise
159
- `createModel(weights, config, profile)` switches on `execution.graph`.
160
- `RuntimeModel` = `Gemma4Model | MiniCPM5Model | Qwen35Model | Qwen3Model |
161
- Qwen3MoeModel | DiffusionGemmaModel | Glm52Model | UniversalDenseModel`.
162
-
163
- **Support tiers in UX** (`supportTier(modelType, repoId)` →
164
- `"targeted" | "generic" | null`): consumed by `mlx-bun ls`
165
- (src/cli.ts), `src/hub-rest.ts`, and the serve discovery routes. Drafters
166
- (`*_assistant`) are never selectable on their own. Note the MiniCPM5
167
- *record*-level check keys on the repo id containing
168
- `minicpm5-1b-optiq-4bit`; the config-level check is the exact-shape predicate.
169
-
170
- Reference mirror of this section: docs/reference/models.md "Declared model
171
- profiles" (keep in sync).
172
-
173
- ---
174
-
175
- ## 4. Tier-0 design
176
-
177
- ### 4.1 `UniversalDense` (`src/model/universal/`)
178
-
179
- One module (`dense.ts`), shaped like `qwen3.ts`, with every arch delta
180
- selected by a `UniversalArgs` descriptor. `archs.ts` holds an explicit
181
- table keyed by `model_type` (mlx-lm's `MODEL_REMAPPING` vendored in) — no
182
- config sniffing to *identify* an arch; fingerprints remain a generated-
183
- dispatch guard only. Descriptors in the table today (11):
184
- **llama, smollm3, qwen2, qwen3, gemma, gemma2, phi3, olmo2, glm4, granite,
185
- starcoder2**. `GENERIC_MODEL_TYPES` = the table's keys.
186
-
187
- Key choices:
188
-
189
- - **Transcribe mlx-lm op-for-op** inside each descriptor branch (q/k-norm
190
- before vs after reshape, rope order, scale points, softcap, mask kinds).
191
- The descriptor selects branches; it never approximates.
192
- - **Rope factory** (`rope.ts`) — faithful port of `rope_utils.initialize_rope`:
193
- default / linear / llama3 / yarn / longrope (SuScaledRoPE) / proportional.
194
- Frequency tables are computed with the same mlx float32 ops the oracle uses
195
- at module init so the bytes match; host double math only where the oracle
196
- uses python floats. Gated by `tests/universal-rope.test.ts` against
197
- machine-keyed oracle fixtures (`tests/fixtures/universal-rope/`).
198
- - **Dense checkpoints** (`modules.ts`) — verbatim `mlx.nn.Linear`
199
- (`addmm(bias, x, W.T)` / `x @ W.T`) and `nn.Embedding`; quantized paths
200
- delegate to gemma4-base. Additive bias is a first-class field (qwen2 qkv,
201
- starcoder2 all-bias).
202
- - **Weight audit at load** — `WeightAudit.finish` diffs consumed tensors
203
- against the shard index minus the arch's sanitize-drop rules; unconsumed
204
- or missing tensors are a LOAD ERROR naming them, never a silently-wrong
205
- model.
206
- - **KV cache** — `KVCache`/`RotatingKVCache` unchanged; `layer_types` /
207
- `sliding_window` already normalized. Standard attention consumes the shared
208
- cache-attention interface; qualified Llama uniform KV4/KV8 serving and
209
- generated-cache coverage are described in batching.md.
210
- - **RuntimeModel surface** — the minimal contract `Qwen3Model` implements
211
- (config, weightsBytes, loraState, makeCache, forwardHidden,
212
- logitsFromHidden, forward, generate, loraTargets) so serving/eval/LoRA
213
- hot-swap work day one. `forwardEmbeddings` is a stub (vision is per-arch).
214
-
215
- ### 4.2 The parity gate for a new generic arch
216
-
217
- `tests/universal-manifest.ts` — one entry per launch arch pointing at the
218
- SMALLEST mlx-community 4-bit checkpoint of that arch, skip-if-absent, with
219
- `expectClass: "universal" | "dedicated"` (the `qwen3` entry expects
220
- `Qwen3Model` — generic never shadows targeted, the gate still runs the
221
- oracle bar). Flow: user downloads → `bun scripts/regen.ts universal [<prefix>|all]`
222
- → `MLX_BUN_TEST_UNIVERSAL=1 bun test tests/universal-parity.test.ts`.
223
- Asserts: fingerprint-free construction, weight audit clean, greedy
224
- trajectory match, per-step logits bit-exact.
225
-
226
- **Definition of supported-generic = manifest entry green on the current
227
- machine.** Adding a descriptor without its manifest goldens is the one
228
- anti-pattern this design forbids.
229
-
230
- ### 4.3 `UniversalMoE` (design only)
231
-
232
- Same block with the MLP swapped for router + `QuantizedSwitchLinear`
233
- (already serving 26B-A4B and Qwen3-MoE). Deltas to parameterize: top-k,
234
- `norm_topk_probs`, routing score fn (softmax/sigmoid), routing scale,
235
- shared-expert branch (+ optional shared-expert gate — qwen2_moe),
236
- first-k-dense-replace (deepseek/glm4_moe layouts), grouped routing
237
- (deepseek_v3-style, defer). gpt_oss (attention sinks) and llama4 (chunked
238
- attention) are not claimed by the generic MoE. RAM honesty belongs in the
239
- `ls`/fit output (weightsBytes vs RAM), not in marketing.
240
-
241
- ### 4.4 Graduation to Tier-1
242
-
243
- Criteria (all three): (a) L1 generic parity green and stable across real
244
- use; (b) it is a daily driver / benchmark / product target; (c) a measured
245
- perf or memory gap vs a dedicated path worth the maintenance (number in
246
- docs/reference/benchmarks.md).
247
-
248
- Process, in order, stop at any step: (1) L2 — optiq goldens
249
- (`mixed-kv` pattern) if an optiq artifact/kv_config exists; (2) dedicated
250
- or generated forward — extend `gen-model.ts` if gemma4-base-shaped,
251
- otherwise a hand port (`qwen3_5.ts` pattern; hand ports are proven and
252
- cheap); (3) perf levers behind their existing flags (compiled decode,
253
- kv-quant, fused sdpa) — output-changing experiments are Lab items
254
- (unified-engine-frontier-plan.md §6); (4) benchmark + docs entries, tier
255
- label flips to `targeted`. Graduation never deletes the generic path — it
256
- stays the permanent correctness fallback, as the monolith does for generated
257
- gemma classes.
258
-
259
- ### 4.5 Remaining phases
260
-
261
- | Phase | Scope | State |
262
- |---|---|---|
263
- | 1 | UniversalDense + descriptor table + rope factory + bias + manifest harness | built |
264
- | 1.5 | dense (bf16/fp16) checkpoints, no `.scales` | built (`modules.ts`) |
265
- | 2 | UniversalMoE: mixtral, qwen2_moe, olmoe, glm4_moe, dots1, granitemoe, ernie4_5_moe, phimoe (qwen3_moe is already a dedicated port) | design |
266
- | 3 | demand-driven one-offs (SSM/hybrid: lfm2, qwen3_next, mamba2, nemotron_h; MLA if a runnable target appears) — each a real port with its own goldens and cache types | design |
267
- | 4 | `mlx-bun port <hf-repo>`: download smallest snapshot → descriptor coverage check (config keys + weight-audit dry run) → auto-regen goldens vs the oracle venv → run the gate → print verdict + manifest entry. Optionally generalize `gen-model.ts` to emit from UniversalDense | design (no CLI command exists) |
268
-
269
- ---
270
-
271
- ## 5. Multimodal seams shared by the ports
272
-
273
- Every tower (vision or audio) returns language-space soft tokens
274
- `[1, soft, textHidden]` pre-divided by `embed_scale` (the language model
275
- re-multiplies), splices into the prompt through
276
- `src/vision/prompt.ts buildMultimodalPrompt` (images + audio in document
277
- order; `buildVisionPrompt` is a byte-identical wrapper), and enters the model
278
- through `forwardEmbeddings` (merged embeddings; per-layer-input models take
279
- a `multimodal` zeroing mask decoupled from the `bidir` attention overlay).
280
- Media requests route to the **serial lane**, skip the prompt cache and spec
281
- decode, and capability flags (`visionCapable`, `audioCapable` in
282
- `src/registry.ts`) check TENSORS, not just config. Non-WAV audio transcodes
283
- via macOS `afconvert`; video decodes via the AVFoundation sidecar
284
- `mlx-bun-frame-extract` — zero vendored codecs.
285
-
286
- ---
287
-
288
- ## 6. Ports
289
-
290
- One subsection per family. Each states the graph, its oracle, and the
291
- design-relevant facts; phase logs live in PLAN.md at the named anchor.
292
-
293
- ### 6.1 Gemma-4 (e4b / 12B / 26B-A4B) — `src/model/gemma4.ts`, `gemma4-base.ts`, `generated/`
294
-
295
- - **Graph**: line-for-line port of mlx-lm `gemma4_text.py` covering 12B
296
- (dense), e4b (per-layer-input embeddings + KV-shared layers), 26B-A4B
297
- (MoE: router + gather_qmm experts). SDPA scale 1.0 (q/k normalized);
298
- full-attention layers use global_head_dim 512, one global KV head,
299
- `attention_k_eq_v`; ProportionalRoPE rotates only
300
- `partial_rotary_factor` dims; python-float scalars promote weakly; mlx
301
- helper implementations replicated exactly (`x**3` is `mx.power`).
302
- Sliding layers use a plain cache + window masks (numerically identical to
303
- mlx-lm's RotatingKVCache).
304
- - **Specialization**: `scripts/gen-model.ts` → `generated/gemma4-{e4b,12b,26b}.ts`,
305
- fingerprint-dispatched, bit-exact vs the monolith
306
- (`tests/generated-parity.test.ts`).
307
- - **Oracle**: L1 mlx-lm (`goldens/parity.json` on the 12B snapshot,
308
- `tests/parity.test.ts`; 26B `tests/parity-26b.test.ts`); L2 mlx-optiq for
309
- the mixed-KV composition (26B `logits-26b-kvmix.bin`, `mixed-kv` job).
310
- Profile: `gemma4-generated` / `gemma4-dedicated`, L1.
311
- - **Vision**: two towers behind one merge contract — `src/vision/siglip.ts`
312
- (full SigLIP encoder shipped by e2b/e4b/26B/31B; port of optiq's vendored
313
- mlx-vlm gemma4 encoder from the bf16 `optiq_vision.safetensors` sidecar)
314
- and `src/vision/embedder.ts` (12B `gemma4_unified` encoder-free patch
315
- embedder). Oracle = optiq internals (`goldens/e4b-vision.json`,
316
- `tests/e4b-vision.test.ts`, `tests/vision.test.ts`): spliced ids and
317
- soft-token count EXACT, greedy PREFIX match; full bit-exact greedy is not
318
- asserted because the 16-layer bf16 encoder composition drifts sub-bf16 and
319
- the scale-1.0 softmax amplifies it (siglip.ts header).
320
- - **Audio**: §6.6.
321
- - PLAN anchors: Phase 12 (SigLIP), Phase 2 findings (parity notes).
322
-
323
- ### 6.2 MiniCPM5-1B — `src/model/minicpm5.ts`
324
-
325
- - **Graph**: `model_type: llama` (plain Llama block — no MiniCPM residual
326
- scaling), 24 layers, hidden 1536, 16/2 heads @128, vocab 130560, untied,
327
- `rope_theta` from `ropeParameters.full_attention`. Port target mlx-lm
328
- `models/llama.py`; the expert swiglu is mx.compile-compiled like the
329
- oracle's `activations.py` (`compiledSwiglu`, kill-switch
330
- `MLX_BUN_COMPILED_SWIGLU=0`) — the one fusion that matched the oracle's
331
- kernel set and brought CPM5 decode to parity with mlx-lm
332
- (decode-speed-program.md).
333
- - **Dispatch**: the exact-shape `isMiniCPM5Config` predicate keeps it on
334
- the dedicated class ahead of the generic `llama` descriptor.
335
- - **Oracle**: L1 mlx-lm (`goldens/minicpm5-parity.json`,
336
- `tests/minicpm5-parity.test.ts`); L2 mlx-optiq for per-layer quantized KV
337
- (`goldens/minicpm5-kv-parity.json`, `tests/minicpm5-kv-parity.test.ts`,
338
- bit-exact via `QuantizedKVCache` + `quantizedSdpaUnfused`). Also the
339
- TurboQuant KV testbed (`TurboQuantKVCache`). Profile
340
- `minicpm5-dedicated`, L1 (the L2 composition is a request-level KV scheme,
341
- not a profile property).
342
- - Training reference model for segmented backward and ORPO
343
- (docs/design/orpo-training.md, orpo-training.md).
344
-
345
- #### 6.2.1 MiniCPM5-2B investigation
346
-
347
- Metadata and template inspection completed 2026-09-10. No weights were
348
- downloaded and no GPU inference was run. This checkpoint is a candidate,
349
- not an artifact with established parity or local performance results.
350
-
351
- Start with the official [OpenBMB MLX artifact](https://huggingface.co/openbmb/MiniCPM5-2B-MLX),
352
- revision `3d00c3da500debfe345e60e25a87ed2669f5b1ee`. Its config uses standard
353
- Llama blocks, 42 layers, hidden size 2048, intermediate size 6144, 16 query
354
- and 2 KV heads of dimension 128, untied embeddings, vocab 130560 and
355
- RoPE theta 5000000. Quantization is affine 4-bit with group size 64.
356
- Preserve both EOS IDs, `1` and `130073`, and the separate
357
- `chat_template.jinja`. The release is text-only and Apache-2.0.
358
-
359
- Current integration findings:
360
-
361
- - `isMiniCPM5Config` in `src/model/support.ts` matches the older 24-layer,
362
- hidden-1536 artifact. The 2B config fails that predicate and qualifies for
363
- generic Llama through `genericArgsFor`; `familyProfile` therefore selects
364
- the universal graph. Do not widen the predicate before auditing dedicated
365
- execution, training and cache assumptions against this shape.
366
- - A CPU-only smoke using the pinned config and template passed
367
- `loadModelConfig`, `genericArgsFor`, `ChatTemplate.load` and rendering a
368
- user → assistant tool call → tool result → user conversation. Explicit
369
- thinking true/false both render correctly; the XML function call survives.
370
- This checks rendering, not generated tool-call parsing or tokenizer parity.
371
- - `resolveEnableThinking` applies the MiniCPM no-thinking default through
372
- the same exact-shape predicate. It does not apply to 2B. With no explicit
373
- option, this artifact's prompt ends at the assistant header; true appends
374
- an open think tag, false appends a closed empty think block. Set this
375
- explicitly in comparisons. Template support for disabling thinking does
376
- not establish no-thinking quality.
377
-
378
- Evaluation sequence:
379
-
380
- 1. Pin an 8-bit or BF16 control alongside the official 4-bit candidate.
381
- Establish tokenizer/prompt identity and same-machine logits against the
382
- pinned mlx-lm oracle, then test multi-turn tool calls, reasoning splits,
383
- EOS, cache reuse and batched continuation. Keep quantization quality
384
- comparisons separate from same-artifact runtime parity.
385
- 2. Compare with MiniCPM5-1B and Gemma e4b on held-out Dreaming segmentation,
386
- extraction and source-grounded synthesis, plus bounded repository/tool
387
- tasks. Score boundary/label accuracy and completed tasks, not just valid
388
- JSON or XML. Use explicit thinking modes and equal token/time budgets.
389
- 3. Record first-answer latency, complete task time, output/reasoning tokens,
390
- repetition and truncation rates, memory and context scaling. Local
391
- measurements belong only in `docs/reference/benchmarks.md`, with a named
392
- quiet machine and the required serving benchmark procedure.
393
- 4. Investigate the [released DSpark draft](https://huggingface.co/openbmb/MiniCPM5-2B-DSpark)
394
- after ordinary inference passes. Its config declares `Qwen3DSparkModel`,
395
- five draft layers, block size seven, and target taps `[1,10,20,30,39]`.
396
- Existing Gemma DSpark support does not establish compatibility. Audit
397
- the draft's architecture, target taps, weights and verifier before a
398
- paired task-time comparison.
399
-
400
- Evidence to use when designing the quality checks:
401
- [OpenBMB's model card](https://huggingface.co/openbmb/MiniCPM5-2B) distinguishes
402
- internally reproduced scores from Artificial Analysis results. The
403
- [independent September 7 evaluation](https://artificialanalysis.ai/articles/openbmb-releases-minicpm5-2b)
404
- supports strong capability for its size but reports substantial reasoning
405
- token use and weak absolute terminal-task success. These evaluations do not
406
- validate MLX 4-bit quality. [Upstream issue 374](https://github.com/OpenBMB/MiniCPM/issues/374)
407
- reports repetition sensitivity in GGUF coding runs. That is an unreproduced
408
- cross-runtime hypothesis for our sweep, not evidence of the same MLX failure
409
- or a reason to change repetition defaults.
410
-
411
- ### 6.3 Qwen3 / Qwen3-MoE / Qwen3.5-family (3.6, 3.8) — `qwen3.ts`, `qwen3-moe.ts`, `qwen3_5.ts`
412
-
413
- - **Qwen3** (`model_type: qwen3`): dense GQA with per-head q/k RMSNorm
414
- before RoPE, theta 1e6, tied embeddings. Primary use is the
415
- text-embedding backbone (`embedPooled`: last-token hidden, L2-normalized).
416
- Oracle L1 mlx-lm (`tests/qwen3-embed-parity.test.ts`). Shadows the
417
- generic `qwen3` descriptor.
418
- - **Qwen3-MoE** (`qwen3_moe`): straight op-for-op transcription of
419
- mlx-lm `qwen3_moe.py` + `switch_layers.py` — gate Linear → precise
420
- softmax over all experts → argpartition top-k → renormalize → SwitchGLU
421
- with compiled swiglu; `decoder_sparse_step` / `mlp_only_layers` dense
422
- layers handled. Oracle L1 mlx-lm on the 30B-A3B
423
- (`tests/qwen3-moe-parity.test.ts`; the cached checkpoint has no
424
- kv_config, so no L2 bar).
425
- - **Qwen3.5 hybrid** (`qwen3_5` / `qwen3_5_text`; the `qwen3_5_moe` variant
426
- is excluded by `isQwen35Config`): 64 layers, every
427
- `full_attention_interval`-th (4) a gated softmax-attention layer (q-gate
428
- split, per-head q/k norm, partial RoPE 0.25 @ base 1e7, GQA 24/4 @256,
429
- `o_proj(out·σ(gate))`), the rest **gated DeltaNet** linear attention
430
- (`in_proj_qkv/z/b/a`, depthwise causal conv1d k=4, `A_log`/`dt_bias`
431
- float, `RMSNormGated`). The recurrence is the reference's custom Metal
432
- kernel `gated_delta_step` ported VERBATIM (`src/model/qwen3-delta.ts`) —
433
- bit-exact parity requires it; the ops fallback reduces in a different
434
- order. `SSMCache` (conv + recurrent state) implements `Cache` and the
435
- spec-round contract (`specRoundBegin/Commit/Rollback`: free snapshot,
436
- replay of the kept window on partial reject — bit-exact by construction
437
- because the kernel's per-thread loop is serial). Weights under
438
- `language_model.`; `output_gate_type` other than `"swish"`/absent throws.
439
- **Qwen3.8-27B is byte-for-byte the 3.6-27B text geometry** — zero new
440
- graph work; the exact profile `qwen3.8-27b-optiq-4bit` pins the validated
441
- revision.
442
- - **Oracles**: L1 mlx-lm `qwen3_5.py` with bf16 KV
443
- (`goldens/qwen38-parity.json`, `tests/qwen-parity.test.ts`; earlier 4B/3.6
444
- goldens via `regen.ts qwen-parity`); L2 mlx-optiq mixed-KV on the 3.5/3.6
445
- OptiQ artifacts (`install_mixed_kv` per-layer bits keyed by cache index ≡
446
- our `maybeQuantizeKv`). Qwen3.8's OptiQ repo ships no mixed-KV config →
447
- no L2 bar; mixed-KV serving there is Lab-tier.
448
- - **Vision + video** (`src/vision/qwen3vl-{preprocess,tower,prompt}.ts`,
449
- `video-frames.ts`, `src/model/qwen3-mrope.ts`): mlx-vlm `qwen3_vl`
450
- vision tower at the qwen3_5 configuration (depth 27, hidden 1152, heads
451
- 16 @72, patch 16, temporal 2, merge 2, deepstack empty) from the bf16
452
- sidecar `optiq/optiq_vision.safetensors`; PIL-exact fixed-point bicubic
453
- smart_resize; conv3d patch embed (new `mlx_conv3d` binding);
454
- `ensure_fused_sdpa`'s 72→80 head-dim pad replicated; **interleaved
455
- mRoPE** via the reference's verbatim Metal apply kernel with
456
- `get_rope_index` positions + delta exact, installed per request on the
457
- serial lane (text-only keeps the untouched fast-rope path — equal
458
- position streams degenerate mRoPE to plain RoPE). Video: AVFoundation
459
- sidecar samples at 2 fps (max 768 frames), temporal-pair patchify, gridT>1
460
- tower, transformers' `<t seconds>` per-frame-group prompt format with a
461
- python-`%.1f` port. Oracle = **mlx-vlm 0.6.14 pinned to mlx 0.31.2**
462
- (independent of mlx-lm, so no composite bit-match target exists): tower
463
- bit-exact at small grids, calibrated envelope at 2304 patches; e2e greedy
464
- token-exact on 2/3 image fixtures, step-0 argmax exact on all
465
- (`tests/qwen38-vision*.test.ts`).
466
- - **Native MTP** (`src/spec/qwen-mtp-source.ts`, `--draft-kind mtp`): the
467
- separately published `Qwen3.8-27B-MTP-*` head (`fc` over
468
- concat(rms(embed(next)), rms(target_hidden)) → one full-attention layer
469
- with its own KVCache → target lm_head, block_size 3, DeepSeek-V3 shape)
470
- reads the target's PRE-final-norm hidden via `captureLayer`. Gate:
471
- greedy speculation token-identical to non-spec greedy
472
- (`tests/qwen38-mtp.test.ts`). Durable negative perf verdict on the quiet
473
- M1 Max (MTP-on slower than off at γ=2 despite 61% acceptance) — stays
474
- opt-in. Drafter logits verified against the mlx-vlm reference fed the
475
- oracle's captured hidden grid.
476
- - Training: `loraTargets()` wired; the DeltaNet kernel is inference-only —
477
- training needs mlx-lm's pure-mlx `gated_delta_ops` scan under training
478
- (open).
479
- - PLAN anchors: Phase 14 (bring-up, 14g MTP, 14v vision, 14w video, 14y
480
- YaRN open, 14z TurboQuant weights).
481
-
482
- ### 6.4 GLM-5.2 (`glm_moe_dsa`) — the Colibri hierarchy, `src/model/glm52*.ts`
483
-
484
- Summary of docs/archive/investigations/colibri-glm52-port.md (frozen);
485
- full phase record G0–G8 in git (`git show 3199c75:PLAN-archive.md`,
486
- Phase 21, closed 2026-08-17). GLM-5.3+ would extend THIS section.
487
-
488
- - **Decision**: a native `Glm52Model` over the PUBLIC Colibri container in
489
- place (no second copy, no Colibri child process, no `--backend`); the
490
- pinned Colibri build (`JustVugg/colibri` @ `44e489b`) is an external
491
- executable oracle for formats, logits/tokens, routing traces, memory and
492
- speed. Its policy code is studied and reproduced, not shipped.
493
- - **Model**: 78 main layers (3 dense FFN + 75 sparse MoE, 256 routed
494
- experts, top-8) + an MTP row with its own 256 experts (19,456 expert
495
- instances). The dense spine (embeddings, lm-head, attention, norms, first
496
- dense FFNs, routers, shared experts) stays resident at int4 (~9.9 GB); the
497
- ~370 GB routed-expert pool stays on disk.
498
- - **Graph** (`glm52.ts`, `glm52-mla.ts`, `glm52-dsa.ts`, `glm52-moe.ts`):
499
- MLA — q-a → norm → q-b; kv-a → latent norm; **compressed cache** of the
500
- 512-wide latent + 64 RoPE values per token (`MLACache`, ~57× smaller than
501
- reconstructed K/V at this geometry), weight-absorption decode,
502
- reconstructed-prefill fallback, partial interleaved RoPE. **DSA indexer**
503
- — q/k/projection/norm, per-layer full/shared schedule, exact dense
504
- fallback when the selected set covers the prefix (`DSAIndexCache` only on
505
- layers that own it). MoE — sigmoid scores + correction bias for
506
- selection, un-biased gate weights, true top-8, routed scale, shared expert
507
- in parallel. Colibri arithmetic (offset-binary int4, per-row int8 scale
508
- applied once, RMSNorm with multiplicative weight and double-accumulated
509
- reduction) is mirrored in `glm52-reference.ts`. G2 favors an auditable
510
- dequantize→f32 path; the Metal streamed kernel (`glm52-streamed-metal.ts`)
511
- replaces the expert resolver without changing the graph.
512
- - **Expert residency / streaming** (`glm52-residency.ts`,
513
- `glm52-streamed-experts.ts`, `glm52-expert-layout.ts`, `glm52-pilot.ts`,
514
- `glm52-coupling.ts`, `glm52-atlas.ts`): per-layer bounded LRU slots
515
- derived from the whole-process memory equation, pinned hot-store seeded
516
- from persistent usage, LFRU repinning with hysteresis, batch-union of
517
- unique (layer, expert) across rows so each expert is read once per
518
- layer/step, `pread` worker pool with slot generations and completion
519
- fences (no reuse while a lazy MLX command can retain the buffer), PILOT
520
- (next-layer router on the current state) and COUPLE (cross-layer route
521
- pairs) prefetch, RSS feedback shrinking only the evictable tier. Unified
522
- memory removes a copy, not the 370 GB: the meaningful states are disk /
523
- resident / pinned / loading / in-flight / evictable.
524
- - **Fixed-context admission** (`glm52-memory.ts`, `factory.ts
525
- openGlm52RuntimeModel`): a header-only resource plan runs BEFORE any
526
- resident tensor or expert slab is opened — process limit (default 25 GiB
527
- preset or physical RAM, whichever is smaller), fixed context
528
- (default 4096 tokens, 128 generation), allocator/Bun/safety reserves — and
529
- refuses an impossible placement; the opened runtime's planned bytes must
530
- equal the preflight equation or load fails. Serving clamps `max_tokens`
531
- to the room under the fixed context (STATUS: "GLM fixed-context admission
532
- correction", generalized to every model in v0.2.0).
533
- - **Native MTP** (`src/spec/glm52-mtp-source.ts`): the checkpoint's int8 MTP
534
- row as an in-process draft source sharing the target; serial only —
535
- batched rows decode single tokens (Colibri keeps MTP out of its mux path
536
- too). Batched caches land via `makeEmptyBatch/mergeRows/extractRow/
537
- filterRows/projectedBytes` on right-justified latent/RoPE/DSA tensors —
538
- no full K/V at merge, admission, extraction or cancellation.
539
- - **Oracle / fidelity**: profile `glm5.2-colibri` / exact
540
- `glm5.2-colibri-int4-int8-mtp`, **L3 (measured)** — Colibri is neither
541
- mlx-lm nor mlx-optiq, so the tier system cannot call it bit-exact even
542
- though the G2 gate is a teacher-forced trajectory from the pinned engine
543
- on a tiny converted artifact (`tests/glm52-teacher-forcing.test.ts`,
544
- `fixtures/colibri-glm52/`). Curated numbers live in code as operator
545
- guidance (`GLM52_G5_MEASURED_WARM_DECODE_TPS`,
546
- `GLM52_G5_DIRECT_ORACLE_WARM_DECODE_TPS`, M1 Max 32 GB, MTP on) and in
547
- docs/reference/models.md "GLM-5.2 on a 32 GB Mac". The 24 GB M4 Pro is
548
- below the one-slot-per-layer floor and out of scope.
549
- - **Not claimed**: embeddings, image/audio input, LoRA, training, adapters
550
- — advertised false, never faked (archive N8).
551
- - PLAN anchor: Phase 21 (closed 2026-08-17); probes, gate tests, and
552
- lab spikes for the port surface retired afterwards (commit fbafe44).
553
-
554
- ### 6.5 DiffusionGemma-26B-A4B — `src/model/diffusion-gemma.ts`, `src/diffusion/`, `src/vision/diffusion-vision.ts`
555
-
556
- Summary of docs/design/generic-model-support.md (the D0 reference dossier
557
- there stays the porting contract; do not extend it).
558
-
559
- - **What it is**: the first non-autoregressive model — an encoder prefill
560
- over the prompt builds a KV cache, then a decoder pass over a fixed
561
- 256-token canvas (initialized to uniform-random ids, NOT a mask token) is
562
- denoised over up to 48 steps. 30 layers, hidden 2816, 16 heads; each
563
- layer runs a parallel dense MLP + 128-expert top-8 MoE summed through 7
564
- RMSNorms and a `layer_scalar`; attention scale 1.0, no attention softcap
565
- (final-logit softcap 30 in fp32), QK/V-norm post-proj/pre-RoPE, full
566
- layers (5,11,17,23,29) reuse k as v at hd 512 / kv 2 with partial rotary
567
- 0.25; tied 4-bit head via `QuantizedEmbedding.asLinear`; a
568
- `SelfConditioning` MLP feeds soft embeddings from the previous step.
569
- Bidirectional decoder masks (`_make_decoder_masks`) are the crux.
570
- - **Engine** (`diffusion-generate.ts`): linear temperature schedule
571
- (`t_min 0.4 → t_max 0.8`, DIVIDES logits), both samplers
572
- (confidence-threshold = optiq public default, entropy-bound = engine
573
- default), self-conditioning feedback, stability/EOS, block loop. RNG
574
- parity via bound `mlx_random_randint`/`mlx_random_seed` threading the
575
- global key in the reference's draw order. Parity traps recorded in the
576
- source doc: division not reciprocal-multiply; independent history copies;
577
- the as-loaded oracle has `generation_config = None` (stable-stop OFF,
578
- eos {1, 106}).
579
- - **Vision**: a DEDICATED tower (`diffusion-vision.ts`), not the e4b SigLIP
580
- — inline-quantized `input_proj` truncates `2*(x-0.5)` patches to integers
581
- (a trained-in quirk), head_dim 72 padded to 80 like the reference, plain
582
- bf16 `down_proj`.
583
- - **Oracle**: **mlx-optiq IS the oracle** (stock mlx-lm cannot load it);
584
- the mixed-precision quant is the native weight format, so matching optiq
585
- = L2 = the floor. Profile `diffusion-gemma-dedicated`, L2. Gates:
586
- single forward bit-exact (`tests/diffusion-parity.test.ts`), generation
587
- token-for-token for both samplers (`diffusion-gen-parity`), image
588
- token-for-token (`diffusion-vision`), serving (`diffusion-serving`), LoRA
589
- with the denoising objective (`diffusion-lora`,
590
- `src/train/diffusion-lora.ts`; MoE backward by stop-gradient on router
591
- indices). All `MLX_BUN_TEST_DIFFUSION=1`.
592
- - **Entry points — honest state**: `src/generate.ts` routes by
593
- `instanceof DiffusionGemmaModel` to `generateDiffusionInner`, and
594
- `src/server.ts` has a diffusion vision lane; **`src/cli.ts` contains no
595
- diffusion reference** (`grep -c diffusion src/cli.ts` = 0). There is no
596
- diffusion-specific CLI surface; the model is reachable only through the
597
- generic `serve` / `generate` path by profile + instanceof dispatch, and
598
- streaming yields tokens after the engine completes. D4 (performance,
599
- measured) is open.
600
-
601
- ### 6.6 Audio input (gemma-4 audio tower) — `src/audio/`
602
-
603
- Summary of docs/design/generic-model-support.md. Scope: audio-in, text-out
604
- through the chat API; TTS/STT endpoints, streaming audio, >30 s, batched
605
- audio prefill, and 26B-A4B/DiffusionGemma audio (no `audio_config`) are
606
- non-goals.
607
-
608
- - **Oracle**: mlx-lm strips `audio_tower`/`embed_audio` at load and rejects
609
- non-text content; optiq's internal gemma4 machinery is complete but its
610
- serve frontend never exposes audio → the oracle is the optiq internal
611
- model driven directly (`scripts/oracle/gen-e4b-audio-golden.py`,
612
- `goldens/e4b-audio.json`). The e4b OptiQ-4bit sidecar already holds all
613
- 752 audio tensors (bf16, incl. clipped-linear min/max stats) plus
614
- `audio_config` and token ids (`boa 256000`, `audio 258881`,
615
- `eoa 258883`) — no download.
616
- - **Pipeline**: `decode.ts` (RIFF/WAVE PCM16/24/32/f32, mean mixdown, linear
617
- resample to 16 kHz, PCM16/32768 like the oracle; >30 s truncates at
618
- 480 000 samples BEFORE features, the oracle extractor's default) →
619
- `transcode.ts` (`afconvert` for non-WAV, content-sniffed) →
620
- `features.ts` (USM log-mel, frame 320 / hop 160 / rfft 512 in f64, 128 HTK
621
- bins, `log(x+1e-3)`, the oracle's exact f32 Hann values baked in because
622
- numpy's vectorized f32 cos differs by 1 ulp and log-amplifies) →
623
- `conformer.ts` (SSCP two Conv2d stride-2 stages (128, 32) → Linear 1024 →
624
- 12 Conformer blocks with chunked local attention (chunk 12, left 13,
625
- softcap 50), depthwise Conv1d k=5, clipped linears → output_proj 1536 →
626
- `embed_audio` RMSNormNoScale → Linear → /embed_scale). **Dtype contract
627
- differs from siglip**: the oracle feeds f32 mel into bf16 weights and mlx
628
- promotes, so activations stay f32 end-to-end — do not cast to weight
629
- dtype. Clipped-linear stats are load-bearing (off diverges 90%).
630
- - **LM semantics (resolved against the oracle)**: audio tokens are strictly
631
- CAUSAL; any audio in the prompt disables the vision bidir overlay
632
- entirely; per-layer-input zeroing uses the union multimodal mask; USM
633
- parameters are fixed constructor defaults (no per-bin normalization);
634
- `<|audio|>` → `boa + audio×n + eoa` with `n = min(ceil(ms/40), 750)` is
635
- splice-side. The merge divides by embed_scale AFTER the bf16 cast (weak
636
- scalar) — `features(preDivide=false)` + astype + div mirrors it.
637
- - **Serve**: OpenAI `input_audio` plus optiq `audio`/`audio_url` parts;
638
- lazy `getAudioTower` from the same sidecar, zero new flags; a request
639
- with audio on a towerless model is an explicit 400; Anthropic
640
- `/v1/messages` rejects audio blocks with a pointer to the OpenAI
641
- endpoint; `audio` capability flag on `/v1/models`, `/library`, and the pi
642
- `ready` frame (requires `audio_config` AND tower tensors — the 12B stub
643
- sidecar reads false).
644
- - **Gates**: T0 mel model-free (`tests/audio-features.test.ts`, 1e-5),
645
- T1 tower rel-RMSE (`e4b-audio-tower`, bit-exact result), T2 e2e greedy +
646
- decoded text EXACT for both fixtures (`e4b-audio`), T3 HTTP
647
- (`e4b-audio-serve`, `MLX_BUN_TEST_AUDIO_SERVE=1`).
648
- - **Open (A5)**: bench cells (tower ms, TTFT delta, RSS delta) into
649
- docs/reference/benchmarks.md; 12B audio cell needs a sidecar rebuild via
650
- optiq `build_vision_sidecar` (local 12B sidecar holds 1 audio tensor);
651
- features-matrix note audio×batching = serial.
652
- - PLAN anchor: "Phase: audio input — gemma-4 audio tower, e4b first".
653
-
654
- ---
655
-
656
- ## 7. Top design decisions
657
-
658
- 1. **Explicit descriptor table keyed by model_type (+ vendored
659
- MODEL_REMAPPING), not config sniffing** — support is a declared,
660
- testable surface; fingerprints remain a generated-dispatch guard only.
661
- 2. **One profile per load, resolved before weights open** — exact artifact
662
- > family > generic; mismatches refuse, never downgrade; profiles declare
663
- construction only.
664
- 3. **L1 bit-exact is the gate for generic too** — manifest-driven golden
665
- harness (explicit ids, raw per-step logits, same GPU).
666
- 4. **Weight audit at load** — unconsumed/missing tensors are a load error.
667
- 5. **Generic never shadows targeted; graduation never deletes generic.**
668
- 6. **The oracle for any capability is whoever ships it** — mlx-lm (L1),
669
- mlx-optiq (L2), mlx-vlm / optiq internals / Colibri where those are the
670
- only implementations — and the profile's fidelity label says which.
671
- 7. **Honest tiering in UX** — `mlx-bun ls`, hub REST, and discovery routes
672
- show `targeted` vs `generic`; media capability flags check tensors.
673
- 8. **New ports are sections of this doc**, with their durable phase record
674
- in PLAN.md.
675
-
676
- ## History
677
-
678
- - 2026-06-24 — MiniCPM5 decode megakernel shelved (persistent single-dispatch
679
- decode kernel, ~0.94× baseline at best; L2 ceiling 93/100 from quant
680
- discontinuity amplifying 1-ULP GEMV drift). Premise removed by the
681
- bandwidth-wall finding (decode-speed-program.md: the baseline decode path
682
- sits at the memory-bandwidth wall; the real CPM5 waste was the unfused
683
- swiglu, fixed by `compiledSwiglu`). Code shelved to scripts/experiments
684
- 2026-07-01 and deleted with that directory 2026-08-23 (git history); no
685
- megakernel code remains in `src/`. The doc
686
- `docs/design/generic-model-support.md` is superseded by this line.
687
- - 2026-06-24 — DiffusionGemma D0–D3 + D5 landed (bit-exact forward,
688
- token-for-token generation, image, LoRA); D4 open.
689
- - 2026-06-15 → 2026-08-18 — Qwen3.5-family: 3.6 text parity both bars;
690
- 3.8 retarget (identical geometry), native MTP, vision, video landed.
691
- - 2026-07-01 — Generic Phase 1 + 1.5 built (commit 9bd9f1b):
692
- UniversalDense, 11 descriptors, rope factory, dense checkpoints, weight
693
- audit, manifest harness.
694
- - 2026-07-07 — Audio A0–A4 landed (e4b, oracle-exact); A5 open.
695
- - 2026-08-17 — GLM-5.2 Colibri port closed (Phase 21); surface retired,
696
- design archived.
697
- - 2026-08-21 — Model profiles (`src/model/profile.ts`) introduced; exact
698
- artifact declarations for Qwen3.8 OptiQ and GLM-5.2 Colibri.
699
- - 2026-08-23 — This doc consolidated: audio-input-plan,
700
- diffusion-gemma-port, minicpm5-decode-megakernel, and the Colibri archive
701
- summarized here; ports become sections.
702
-
703
-
704
- Non-Qwen grouped TurboQuant drafting, including assistant donor attention, uses
705
- the shared cache interfaces. See [composition coverage](batching.md#turboquant-donor-attention-and-grouped-draft-composition).