@mlx-bun/inference 0.0.0-stage → 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 (467) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +1475 -2
  3. package/THIRD_PARTY_NOTICES.md +3404 -0
  4. package/dist/native/libmlx_bun_ane.dylib +0 -0
  5. package/dist/native/libmlx_bun_expert_io.dylib +0 -0
  6. package/dist/native/mlx-bun-frame-extract +0 -0
  7. package/examples/fit-model.ts +25 -0
  8. package/examples/qwen3-forward.ts +42 -0
  9. package/examples/qwen3-generate.ts +28 -0
  10. package/examples/trellis-expand.ts +23 -0
  11. package/package.json +129 -4
  12. package/src/adapters/available.ts +110 -0
  13. package/src/adapters/index.ts +3 -0
  14. package/src/adapters/manager.ts +316 -0
  15. package/src/artifacts/auxiliary-files.ts +45 -0
  16. package/src/artifacts/config-dialects.ts +94 -0
  17. package/src/artifacts/config.ts +341 -0
  18. package/src/artifacts/draft-vocabulary.ts +30 -0
  19. package/src/artifacts/expert-offload-build.ts +75 -0
  20. package/src/artifacts/expert-offload.ts +89 -0
  21. package/src/artifacts/experts/index.ts +3 -0
  22. package/src/artifacts/experts/io.ts +386 -0
  23. package/src/artifacts/experts/residency.ts +1134 -0
  24. package/src/artifacts/experts/usage.ts +415 -0
  25. package/src/artifacts/fingerprint.ts +44 -0
  26. package/src/artifacts/glm52/container.ts +305 -0
  27. package/src/artifacts/glm52/expert-layout.ts +249 -0
  28. package/src/artifacts/glm52/index.ts +7 -0
  29. package/src/artifacts/glm52/kernel-layout.ts +124 -0
  30. package/src/artifacts/glm52/layout.ts +152 -0
  31. package/src/artifacts/glm52/memory.ts +500 -0
  32. package/src/artifacts/glm52/resident-weights.ts +135 -0
  33. package/src/artifacts/glm52/weights.ts +503 -0
  34. package/src/artifacts/glm52-config.ts +262 -0
  35. package/src/artifacts/identity.ts +94 -0
  36. package/src/artifacts/index.ts +15 -0
  37. package/src/artifacts/mmap.ts +90 -0
  38. package/src/artifacts/safetensors-writer.ts +249 -0
  39. package/src/artifacts/safetensors.ts +164 -0
  40. package/src/artifacts/turboquant-fold.ts +42 -0
  41. package/src/artifacts/weight-audit.ts +43 -0
  42. package/src/artifacts/weights.ts +255 -0
  43. package/src/contracts/index.ts +2 -0
  44. package/src/contracts/mlx/attention.ts +8 -0
  45. package/src/contracts/mlx/cache.ts +510 -0
  46. package/src/contracts/mlx/checkpoint.ts +10 -0
  47. package/src/contracts/mlx/draft-checkpoint.ts +14 -0
  48. package/src/contracts/mlx/draft-projection.ts +27 -0
  49. package/src/contracts/mlx/draft-target.ts +84 -0
  50. package/src/contracts/mlx/drafter.ts +176 -0
  51. package/src/contracts/mlx/forward-work.ts +23 -0
  52. package/src/contracts/mlx/glm52-weights.ts +25 -0
  53. package/src/contracts/mlx/graph.ts +309 -0
  54. package/src/contracts/mlx/head.ts +6 -0
  55. package/src/contracts/mlx/index.ts +15 -0
  56. package/src/contracts/mlx/kv-codec.ts +9 -0
  57. package/src/contracts/mlx/media.ts +113 -0
  58. package/src/contracts/mlx/positions.ts +16 -0
  59. package/src/contracts/mlx/row-table.ts +2 -0
  60. package/src/contracts/mlx/trainable.ts +103 -0
  61. package/src/contracts/mlx/whisper.ts +96 -0
  62. package/src/contracts/portable/composition.ts +106 -0
  63. package/src/contracts/portable/denoising.ts +17 -0
  64. package/src/contracts/portable/execution.ts +79 -0
  65. package/src/contracts/portable/generation.ts +103 -0
  66. package/src/contracts/portable/graph.ts +80 -0
  67. package/src/contracts/portable/index.ts +15 -0
  68. package/src/contracts/portable/memory-plan.ts +26 -0
  69. package/src/contracts/portable/object-cache.ts +8 -0
  70. package/src/contracts/portable/prefill.ts +63 -0
  71. package/src/contracts/portable/prefix-cache.ts +33 -0
  72. package/src/contracts/portable/prompt.ts +2 -0
  73. package/src/contracts/portable/resources.ts +25 -0
  74. package/src/contracts/portable/rollback.ts +7 -0
  75. package/src/contracts/portable/sampling.ts +44 -0
  76. package/src/contracts/portable/scheduling.ts +54 -0
  77. package/src/contracts/portable/token-delivery.ts +4 -0
  78. package/src/contracts/portable/tsconfig.json +14 -0
  79. package/src/embeddings/index.ts +1 -0
  80. package/src/embeddings/text.ts +85 -0
  81. package/src/execution/admission.ts +59 -0
  82. package/src/execution/batch-group.ts +1240 -0
  83. package/src/execution/batch-types.ts +225 -0
  84. package/src/execution/cancellation.ts +38 -0
  85. package/src/execution/continuation-request.ts +45 -0
  86. package/src/execution/continuation-types.ts +10 -0
  87. package/src/execution/coordinator.ts +70 -0
  88. package/src/execution/denoising-group.ts +180 -0
  89. package/src/execution/engine.ts +56 -0
  90. package/src/execution/fill-group.ts +505 -0
  91. package/src/execution/fit.ts +184 -0
  92. package/src/execution/gateway-binding.ts +178 -0
  93. package/src/execution/grammar-group.ts +224 -0
  94. package/src/execution/index.ts +18 -0
  95. package/src/execution/methods.ts +75 -0
  96. package/src/execution/mixed-iteration.ts +96 -0
  97. package/src/execution/plan.ts +65 -0
  98. package/src/execution/prefill-cohort.ts +100 -0
  99. package/src/execution/prefill-rows.ts +263 -0
  100. package/src/execution/request-policy.ts +19 -0
  101. package/src/execution/row-sampling.ts +49 -0
  102. package/src/execution/scheduler.ts +92 -0
  103. package/src/execution/session.ts +247 -0
  104. package/src/execution/speculative-group.ts +797 -0
  105. package/src/execution/tasks.ts +44 -0
  106. package/src/generation/autoregressive.ts +840 -0
  107. package/src/generation/bindings/autoregressive.ts +104 -0
  108. package/src/generation/bindings/denoising.ts +60 -0
  109. package/src/generation/bindings/prefill-policy.ts +36 -0
  110. package/src/generation/checkpoint-identity.ts +60 -0
  111. package/src/generation/denoising.ts +85 -0
  112. package/src/generation/diffusion.ts +583 -0
  113. package/src/generation/fill/echo-index.ts +188 -0
  114. package/src/generation/fill/index.ts +3 -0
  115. package/src/generation/fill/proposal.ts +69 -0
  116. package/src/generation/fill/schema-rows.ts +506 -0
  117. package/src/generation/fill/session.ts +464 -0
  118. package/src/generation/fill/tool-boundary.ts +103 -0
  119. package/src/generation/fill-append.ts +58 -0
  120. package/src/generation/generate.ts +44 -0
  121. package/src/generation/grammar-step.ts +39 -0
  122. package/src/generation/index.ts +14 -0
  123. package/src/generation/phase-dispatch.ts +115 -0
  124. package/src/generation/prefill.ts +33 -0
  125. package/src/generation/result.ts +49 -0
  126. package/src/generation/scopes.ts +157 -0
  127. package/src/generation/speculative/acceptance.ts +41 -0
  128. package/src/generation/speculative/adaptive-draft-gate.ts +166 -0
  129. package/src/generation/speculative/bindings/assistant-rows.ts +102 -0
  130. package/src/generation/speculative/bindings/autoregressive-rows.ts +124 -0
  131. package/src/generation/speculative/bindings/binding.ts +106 -0
  132. package/src/generation/speculative/bindings/deepspec-rows.ts +33 -0
  133. package/src/generation/speculative/bindings/draft-target.ts +10 -0
  134. package/src/generation/speculative/bindings/glm52-mtp-rows.ts +128 -0
  135. package/src/generation/speculative/bindings/projected-context-rows.ts +78 -0
  136. package/src/generation/speculative/bindings/projected-draft-rows.ts +95 -0
  137. package/src/generation/speculative/bindings/qwen-mtp-rows.ts +336 -0
  138. package/src/generation/speculative/bindings/two-model-rows.ts +63 -0
  139. package/src/generation/speculative/cache-identity.ts +16 -0
  140. package/src/generation/speculative/draft-kind.ts +149 -0
  141. package/src/generation/speculative/draft-policy.ts +41 -0
  142. package/src/generation/speculative/draft-registry.ts +118 -0
  143. package/src/generation/speculative/draft-vocab.ts +110 -0
  144. package/src/generation/speculative/index.ts +17 -0
  145. package/src/generation/speculative/output.ts +49 -0
  146. package/src/generation/speculative/round.ts +307 -0
  147. package/src/generation/speculative/source.ts +144 -0
  148. package/src/generation/speculative/sources/assistant-source.ts +64 -0
  149. package/src/generation/speculative/sources/deepspec-source.ts +70 -0
  150. package/src/generation/speculative/sources/dflash-source.ts +84 -0
  151. package/src/generation/speculative/sources/dflash2-source.ts +86 -0
  152. package/src/generation/speculative/sources/glm52-mtp-source.ts +66 -0
  153. package/src/generation/speculative/sources/ngram-source.ts +165 -0
  154. package/src/generation/speculative/sources/qwen-mtp-source.ts +154 -0
  155. package/src/generation/speculative/sources/two-model.ts +75 -0
  156. package/src/generation/types.ts +194 -0
  157. package/src/index.ts +20 -0
  158. package/src/input/audio/audiotoolbox.ts +112 -0
  159. package/src/input/audio/decode.ts +133 -0
  160. package/src/input/audio/features.ts +202 -0
  161. package/src/input/audio/index.ts +6 -0
  162. package/src/input/audio/transcode.ts +67 -0
  163. package/src/input/audio/whisper-mel.ts +185 -0
  164. package/src/input/audio/whisper-tokenizer.ts +238 -0
  165. package/src/input/chat-template.ts +389 -0
  166. package/src/input/index.ts +6 -0
  167. package/src/input/media-fetch.ts +439 -0
  168. package/src/input/packed-mixed.ts +43 -0
  169. package/src/input/special-tokens.ts +75 -0
  170. package/src/input/token-groups.ts +49 -0
  171. package/src/input/tokenizer.ts +336 -0
  172. package/src/input/tool-call.ts +689 -0
  173. package/src/input/vision/index.ts +3 -0
  174. package/src/input/vision/preprocess.ts +247 -0
  175. package/src/input/vision/prompt.ts +398 -0
  176. package/src/input/vision/qwen3vl-preprocess.ts +409 -0
  177. package/src/input/vision/qwen3vl-prompt.ts +237 -0
  178. package/src/input/vision/video-frames.ts +100 -0
  179. package/src/kernels/ane/fill.ts +101 -0
  180. package/src/kernels/ane/linear.ts +416 -0
  181. package/src/kernels/attention/flash.ts +694 -0
  182. package/src/kernels/attention/kvq4-decode.ts +155 -0
  183. package/src/kernels/attention/masks.ts +40 -0
  184. package/src/kernels/attention/multi-query.ts +193 -0
  185. package/src/kernels/attention/paged.ts +130 -0
  186. package/src/kernels/delta/gated.ts +306 -0
  187. package/src/kernels/delta/index.ts +3 -0
  188. package/src/kernels/delta/silu-rms-heads.ts +69 -0
  189. package/src/kernels/delta/state.ts +74 -0
  190. package/src/kernels/gated-rms-norm.ts +64 -0
  191. package/src/kernels/glm52/layout.ts +37 -0
  192. package/src/kernels/glm52/streamed-experts.ts +360 -0
  193. package/src/kernels/logits.ts +38 -0
  194. package/src/kernels/quantization/affine-row.ts +154 -0
  195. package/src/kernels/quantization/affine-rows.ts +36 -0
  196. package/src/kernels/quantization/affine-split-mma.ts +144 -0
  197. package/src/kernels/quantization/affine3-mma.ts +117 -0
  198. package/src/kernels/quantization/affine3-rows.ts +103 -0
  199. package/src/kernels/quantization/affine4-mma.ts +113 -0
  200. package/src/kernels/quantization/affine4-rows.ts +102 -0
  201. package/src/kernels/residual-rms-norm.ts +65 -0
  202. package/src/kernels/sampling/index.ts +2 -0
  203. package/src/kernels/sampling/normalized-argmax.ts +116 -0
  204. package/src/kernels/sampling/token-bitmask.ts +52 -0
  205. package/src/kernels/softcap.ts +35 -0
  206. package/src/kernels/trellis/codebook.ts +123 -0
  207. package/src/kernels/trellis/down-codebook.ts +184 -0
  208. package/src/kernels/trellis/down-factored.ts +180 -0
  209. package/src/kernels/trellis/down-k3-interleaved-factored.ts +146 -0
  210. package/src/kernels/trellis/down-mma-wide.ts +195 -0
  211. package/src/kernels/trellis/down-mma.ts +145 -0
  212. package/src/kernels/trellis/expand.ts +42 -0
  213. package/src/kernels/trellis/gate-up-codebook-mma.ts +141 -0
  214. package/src/kernels/trellis/gate-up-codebook.ts +137 -0
  215. package/src/kernels/trellis/gate-up-factored.ts +197 -0
  216. package/src/kernels/trellis/gate-up-mma-wide.ts +147 -0
  217. package/src/kernels/trellis/gate-up-mma.ts +148 -0
  218. package/src/kernels/trellis/gate-up.ts +248 -0
  219. package/src/kernels/trellis/geometry.ts +22 -0
  220. package/src/kernels/trellis/index.ts +103 -0
  221. package/src/kernels/trellis/launch.ts +12 -0
  222. package/src/kernels/trellis/mixed-gate-up-factored.ts +119 -0
  223. package/src/kernels/trellis/mixed-gate-up.ts +146 -0
  224. package/src/kernels/trellis/qualified.ts +34 -0
  225. package/src/kernels/trellis/reduce.ts +150 -0
  226. package/src/kernels/trellis/scatter.ts +407 -0
  227. package/src/kernels/trellis/splitk-prefill.ts +152 -0
  228. package/src/kernels/trellis/tiled-prefill.ts +131 -0
  229. package/src/kernels/trellis/vector-expand.ts +58 -0
  230. package/src/kernels/trellis/wide-prefill.ts +89 -0
  231. package/src/kernels/turboquant/decode.ts +82 -0
  232. package/src/kernels/turboquant/index.ts +5 -0
  233. package/src/kernels/turboquant/inverse.ts +122 -0
  234. package/src/kernels/turboquant/ops.ts +860 -0
  235. package/src/kernels/turboquant/signs.ts +130 -0
  236. package/src/kernels/turboquant/tables.ts +124 -0
  237. package/src/layers/affine-verify-linear.ts +75 -0
  238. package/src/layers/ane-prefill-split.ts +283 -0
  239. package/src/layers/compiled-normalization.ts +41 -0
  240. package/src/layers/delta-heads.ts +23 -0
  241. package/src/layers/dense-embedding.ts +29 -0
  242. package/src/layers/dense-linear.ts +32 -0
  243. package/src/layers/dequantized-linear.ts +72 -0
  244. package/src/layers/folded-attention.ts +42 -0
  245. package/src/layers/geglu.ts +130 -0
  246. package/src/layers/helpers.ts +7 -0
  247. package/src/layers/index.ts +36 -0
  248. package/src/layers/kv4-decode-attention.ts +15 -0
  249. package/src/layers/layer-norm.ts +24 -0
  250. package/src/layers/loading.ts +92 -0
  251. package/src/layers/lora.ts +150 -0
  252. package/src/layers/normalization.ts +9 -0
  253. package/src/layers/prefix-layout.ts +33 -0
  254. package/src/layers/quantized-append-attention.ts +32 -0
  255. package/src/layers/quantized-attention.ts +353 -0
  256. package/src/layers/quantized-embedding.ts +39 -0
  257. package/src/layers/quantized-linear.ts +137 -0
  258. package/src/layers/quantized-switch-linear.ts +37 -0
  259. package/src/layers/qwen-append.ts +12 -0
  260. package/src/layers/qwen-mrope.ts +238 -0
  261. package/src/layers/rope-2d.ts +110 -0
  262. package/src/layers/rope.ts +389 -0
  263. package/src/layers/swiglu.ts +23 -0
  264. package/src/layers/trellis-codebook-down.ts +52 -0
  265. package/src/layers/trellis-codebook-gate-up.ts +42 -0
  266. package/src/layers/trellis-down.ts +117 -0
  267. package/src/layers/trellis-gate-up.ts +71 -0
  268. package/src/layers/trellis-linear.ts +211 -0
  269. package/src/layers/trellis-prompt.ts +102 -0
  270. package/src/layers/trellis-reduce-gate-up.ts +73 -0
  271. package/src/layers/trellis-scatter-down.ts +98 -0
  272. package/src/models/ane-install.ts +74 -0
  273. package/src/models/audio/conformer.ts +656 -0
  274. package/src/models/cache-composition.ts +44 -0
  275. package/src/models/capabilities.ts +89 -0
  276. package/src/models/chat-template.ts +10 -0
  277. package/src/models/composition.ts +107 -0
  278. package/src/models/diffusion-gemma/experts.ts +59 -0
  279. package/src/models/diffusion-gemma/family.ts +21 -0
  280. package/src/models/diffusion-gemma/model.ts +900 -0
  281. package/src/models/diffusion-gemma/vision.ts +549 -0
  282. package/src/models/drafter-loaders.ts +49 -0
  283. package/src/models/drafters.ts +39 -0
  284. package/src/models/factory.ts +351 -0
  285. package/src/models/families.ts +70 -0
  286. package/src/models/family.ts +125 -0
  287. package/src/models/gemma4/assistant-target.ts +46 -0
  288. package/src/models/gemma4/assistant.ts +327 -0
  289. package/src/models/gemma4/blocks.ts +755 -0
  290. package/src/models/gemma4/compiled-decode.ts +452 -0
  291. package/src/models/gemma4/family.ts +39 -0
  292. package/src/models/gemma4/gemma4-12b.ts +677 -0
  293. package/src/models/gemma4/gemma4-26b.ts +544 -0
  294. package/src/models/gemma4/gemma4-e4b.ts +599 -0
  295. package/src/models/gemma4/graphs.ts +147 -0
  296. package/src/models/gemma4/media.ts +88 -0
  297. package/src/models/gemma4/model.ts +860 -0
  298. package/src/models/gemma4/serving-blocks.ts +72 -0
  299. package/src/models/gemma4/trainable.ts +186 -0
  300. package/src/models/gemma4/written-blocks.ts +232 -0
  301. package/src/models/gemma4/written-forward.ts +159 -0
  302. package/src/models/gemma4/written-input.ts +29 -0
  303. package/src/models/glm52/atlas.ts +507 -0
  304. package/src/models/glm52/coupling.ts +388 -0
  305. package/src/models/glm52/dsa.ts +601 -0
  306. package/src/models/glm52/family.ts +20 -0
  307. package/src/models/glm52/mla.ts +812 -0
  308. package/src/models/glm52/model.ts +1127 -0
  309. package/src/models/glm52/moe.ts +223 -0
  310. package/src/models/glm52/mtp.ts +60 -0
  311. package/src/models/glm52/pilot.ts +537 -0
  312. package/src/models/glm52/reference.ts +445 -0
  313. package/src/models/glm52/residency.ts +557 -0
  314. package/src/models/glm52/streamed-experts.ts +447 -0
  315. package/src/models/graph.ts +59 -0
  316. package/src/models/implementation.ts +230 -0
  317. package/src/models/index.ts +15 -0
  318. package/src/models/media-input.ts +15 -0
  319. package/src/models/memory-plan.ts +39 -0
  320. package/src/models/minicpm5/family.ts +29 -0
  321. package/src/models/minicpm5/model.ts +394 -0
  322. package/src/models/minicpm5/trainable.ts +90 -0
  323. package/src/models/profile.ts +337 -0
  324. package/src/models/qwen/blocks.ts +658 -0
  325. package/src/models/qwen/checkpoint.ts +190 -0
  326. package/src/models/qwen/families.ts +57 -0
  327. package/src/models/qwen/media-input.ts +161 -0
  328. package/src/models/qwen/mtp.ts +101 -0
  329. package/src/models/qwen/qwen3-moe.ts +355 -0
  330. package/src/models/qwen/qwen3.ts +323 -0
  331. package/src/models/qwen/qwen38-27b-trellis-m1max.ts +1532 -0
  332. package/src/models/qwen/qwen38-27b-trellis-m4pro.ts +1092 -0
  333. package/src/models/qwen/qwen3_5.ts +433 -0
  334. package/src/models/qwen/written-layers.ts +285 -0
  335. package/src/models/row-table.ts +1 -0
  336. package/src/models/runtime.ts +73 -0
  337. package/src/models/speculative/deepspec-artifact.ts +10 -0
  338. package/src/models/speculative/deepspec.ts +744 -0
  339. package/src/models/speculative/dflash.ts +553 -0
  340. package/src/models/speculative/dflash2-artifact.ts +9 -0
  341. package/src/models/speculative/dflash2-operations.ts +1 -0
  342. package/src/models/speculative/dflash2.ts +576 -0
  343. package/src/models/speculative/loader.ts +29 -0
  344. package/src/models/support.ts +79 -0
  345. package/src/models/universal/archs.ts +365 -0
  346. package/src/models/universal/blocks.ts +479 -0
  347. package/src/models/universal/dense.ts +255 -0
  348. package/src/models/universal/family.ts +17 -0
  349. package/src/models/vision/qwen3vl.ts +566 -0
  350. package/src/models/vision/siglip.ts +520 -0
  351. package/src/models/vision/unified.ts +176 -0
  352. package/src/models/whisper/family.ts +19 -0
  353. package/src/models/whisper/fast.ts +734 -0
  354. package/src/models/whisper/model.ts +430 -0
  355. package/src/runtime/compiled-trace.ts +16 -0
  356. package/src/runtime/config.ts +77 -0
  357. package/src/runtime/expert-trace.ts +71 -0
  358. package/src/runtime/graph-forward.ts +65 -0
  359. package/src/runtime/integers.ts +6 -0
  360. package/src/runtime/native.ts +16 -0
  361. package/src/runtime/resources.ts +53 -0
  362. package/src/runtime/row-operations.ts +42 -0
  363. package/src/runtime/trace.ts +161 -0
  364. package/src/sampling/curve.ts +122 -0
  365. package/src/sampling/draft.ts +55 -0
  366. package/src/sampling/extras.ts +45 -0
  367. package/src/sampling/filters.ts +134 -0
  368. package/src/sampling/grammar.ts +630 -0
  369. package/src/sampling/hlg.ts +290 -0
  370. package/src/sampling/index.ts +9 -0
  371. package/src/sampling/processors.ts +142 -0
  372. package/src/sampling/sampler.ts +120 -0
  373. package/src/sampling/step.ts +343 -0
  374. package/src/sampling/types.ts +161 -0
  375. package/src/sampling/window-filters.ts +46 -0
  376. package/src/scoring/decisions.ts +96 -0
  377. package/src/scoring/full-sequence.ts +103 -0
  378. package/src/scoring/index.ts +9 -0
  379. package/src/scoring/kl.ts +29 -0
  380. package/src/scoring/perplexity.ts +165 -0
  381. package/src/scoring/response-logps.ts +65 -0
  382. package/src/state/affine-attention.ts +180 -0
  383. package/src/state/attachment.ts +68 -0
  384. package/src/state/attention-read.ts +215 -0
  385. package/src/state/batched-kv.ts +294 -0
  386. package/src/state/batched-mask.ts +445 -0
  387. package/src/state/batched-quant.ts +389 -0
  388. package/src/state/batched-quantized-kv.ts +209 -0
  389. package/src/state/batched-rotating-quant.ts +457 -0
  390. package/src/state/batched-rotating-state.ts +149 -0
  391. package/src/state/batched-rotating.ts +430 -0
  392. package/src/state/batched-row-storage.ts +179 -0
  393. package/src/state/batched-ssm.ts +54 -0
  394. package/src/state/batched-turboquant-kv.ts +144 -0
  395. package/src/state/bf16-first-kv.ts +663 -0
  396. package/src/state/cache-service.ts +592 -0
  397. package/src/state/capabilities.ts +65 -0
  398. package/src/state/checkpoint.ts +46 -0
  399. package/src/state/continuation-persistence.ts +126 -0
  400. package/src/state/decode-step-inputs.ts +31 -0
  401. package/src/state/decoded-kv-donor.ts +12 -0
  402. package/src/state/delayed-quantized-kv.ts +141 -0
  403. package/src/state/delayed-rotating-quantized-kv.ts +178 -0
  404. package/src/state/delayed-turboquant-kv.ts +123 -0
  405. package/src/state/durability.ts +214 -0
  406. package/src/state/encoder-cache.ts +26 -0
  407. package/src/state/full-kv-row-append.ts +33 -0
  408. package/src/state/full-kv-row-donor.ts +54 -0
  409. package/src/state/full-prefill-padding.ts +56 -0
  410. package/src/state/full-prefill-row.ts +112 -0
  411. package/src/state/full-transitioning-kv-rows.ts +70 -0
  412. package/src/state/glm52-cache.ts +783 -0
  413. package/src/state/grouped-heads-kv4-cache.ts +26 -0
  414. package/src/state/index.ts +38 -0
  415. package/src/state/kv-attention-view.ts +77 -0
  416. package/src/state/kv-budget.ts +14 -0
  417. package/src/state/kv-scheme.ts +315 -0
  418. package/src/state/kv-storage.ts +57 -0
  419. package/src/state/kv-tensor-rows.ts +212 -0
  420. package/src/state/kv.ts +324 -0
  421. package/src/state/kv4-head256-cache.ts +46 -0
  422. package/src/state/latent-legos.ts +895 -0
  423. package/src/state/layout.ts +277 -0
  424. package/src/state/leases.ts +26 -0
  425. package/src/state/paged/cache.ts +689 -0
  426. package/src/state/paged/codec.ts +36 -0
  427. package/src/state/paged/rows.ts +223 -0
  428. package/src/state/persistence-types.ts +173 -0
  429. package/src/state/persistence-worker.ts +83 -0
  430. package/src/state/persistence.ts +1036 -0
  431. package/src/state/persistence.worker.d.ts +3 -0
  432. package/src/state/persistence.worker.js +264 -0
  433. package/src/state/prefix-cache.ts +685 -0
  434. package/src/state/quantized-kv.ts +369 -0
  435. package/src/state/quantized-tensor.ts +26 -0
  436. package/src/state/request-policy.ts +48 -0
  437. package/src/state/retention-policy.ts +37 -0
  438. package/src/state/rollback.ts +131 -0
  439. package/src/state/rotating-kv-donor.ts +35 -0
  440. package/src/state/rotating-kv-layout.ts +341 -0
  441. package/src/state/rotating-kv.ts +529 -0
  442. package/src/state/rotating-quantized-kv.ts +616 -0
  443. package/src/state/rotating-row-transaction.ts +35 -0
  444. package/src/state/rows.ts +104 -0
  445. package/src/state/softcap-attention.ts +118 -0
  446. package/src/state/speculative/glm52-mtp-state.ts +38 -0
  447. package/src/state/speculative/qwen-mtp-state.ts +34 -0
  448. package/src/state/speculative-rotating-kv.ts +113 -0
  449. package/src/state/ssd-cache.ts +434 -0
  450. package/src/state/ssm-prefill-padding.ts +39 -0
  451. package/src/state/ssm.ts +422 -0
  452. package/src/state/target-layout.ts +7 -0
  453. package/src/state/tiered-prefix-cache.ts +45 -0
  454. package/src/state/training-cache.ts +300 -0
  455. package/src/state/transitioning-kv-rows.ts +267 -0
  456. package/src/state/turboquant-attention.ts +97 -0
  457. package/src/state/turboquant-codec.ts +90 -0
  458. package/src/state/turboquant-kv.ts +442 -0
  459. package/src/state/views.ts +26 -0
  460. package/src/transcription/index.ts +3 -0
  461. package/src/transcription/silero-vad.ts +379 -0
  462. package/src/transcription/whisper/decode.ts +773 -0
  463. package/src/transcription/whisper/format.ts +74 -0
  464. package/src/transcription/whisper/index.ts +4 -0
  465. package/src/transcription/whisper/timing.ts +274 -0
  466. package/src/transcription/whisper/transcribe.ts +394 -0
  467. package/src/transcription/whisper/types.ts +22 -0
@@ -0,0 +1,148 @@
1
+ import { MlxArray } from "@mlx-bun/mlx/array";
2
+ import * as ops from "@mlx-bun/mlx/ops";
3
+ import { MetalKernel } from "@mlx-bun/mlx/metal-kernel";
4
+ import type { TrellisWeights } from "./geometry";
5
+ import { HEADER } from "./codebook";
6
+
7
+ // Verify-width fused gate/up/SwiGLU on the simdgroup matrix unit: one
8
+ // simdgroup owns an 8-output-row tile for up to 8 activation rows. The K index
9
+ // inside each 8x8 step is permuted so that A column i at step s is position
10
+ // base + 32·i + s: every lane decodes two contiguous 32-position runs per
11
+ // projection from K+1 words (the matvec's word window, unrolled) straight into
12
+ // its A fragment and reads its two activation rows contiguously, so per-weight
13
+ // decode work matches the one-row matvec. Raw code values y accumulate in f32;
14
+ // scale·(1/147.8) applies once per output. Gate and up may differ in bit width.
15
+ // Not bit-identical to the per-lane matvec reduction (different summation
16
+ // order); gate it by KL. Fragment coordinates follow MLX steel's Metal layout.
17
+ const SG_TG = 4, MT = 1;
18
+
19
+ const RUN3_HEADER = String.raw`
20
+ template <int K, int BT_>
21
+ inline void load_run(const device uint32_t* rowCodes, uint run, thread uint* w) {
22
+ const uint wpb = (uint)(BT_ * K / 32);
23
+ const uint runsPerBlock = (uint)BT_ / 32u;
24
+ const uint blk = run / runsPerBlock;
25
+ const uint t0 = (run - blk * runsPerBlock) * 32u;
26
+ const device uint32_t* bw = rowCodes + blk * wpb;
27
+ const uint w0 = ((uint)BT_ - 32u - t0) * (uint)K / 32u;
28
+ #pragma clang loop unroll(full)
29
+ for (uint i = 0; i <= (uint)K; ++i) {
30
+ const uint wi = w0 + i;
31
+ w[i] = bw[wi >= wpb ? wi - wpb : wi];
32
+ }
33
+ }
34
+ template <int K, int L_>
35
+ inline uint run_state(thread const uint* w, uint j) {
36
+ const uint b = (31u - j) * (uint)K;
37
+ const uint wi = b >> 5;
38
+ const uint off = b & 31u;
39
+ uint win = w[wi] >> off;
40
+ if (off + (uint)L_ > 32u) win |= w[wi + 1] << (32u - off);
41
+ return win & ((1u << (uint)L_) - 1u);
42
+ }
43
+ `;
44
+ const SOURCE_V3 = String.raw`
45
+ const uint lane = thread_index_in_simdgroup;
46
+ const uint sg = simdgroup_index_in_threadgroup;
47
+ const uint n0 = (threadgroup_position_in_grid.y * (uint)SG_TG + sg) * 8u;
48
+ if (n0 >= (uint)R) return;
49
+ const uint fm = ((lane / 4u) & 4u) + ((lane / 2u) % 4u);
50
+ const uint fn = ((lane / 4u) & 2u) * 2u + (lane % 2u) * 2u;
51
+ const uint row = n0 + fm;
52
+ const device uint32_t* gRow = gcodes + (ulong)row * (ulong)((C / BT) * (BT * KG / 32));
53
+ const device uint32_t* uRow = ucodes + (ulong)row * (ulong)((C / BT) * (BT * KU / 32));
54
+ // MT activation blocks of 8 rows; grid z walks chunks of 8·MT rows.
55
+ const uint mBase = threadgroup_position_in_grid.z * 8u * (uint)MT;
56
+ bool m0[MT], m1[MT];
57
+ const device T* x0[MT];
58
+ const device T* x1[MT];
59
+ #pragma clang loop unroll(full)
60
+ for (uint bk = 0; bk < (uint)MT; ++bk) {
61
+ const uint r0 = mBase + 8u * bk + fn;
62
+ m0[bk] = r0 < (uint)M; m1[bk] = r0 + 1u < (uint)M;
63
+ x0[bk] = x + (ulong)(m0[bk] ? r0 : 0u) * (ulong)C + fm * 32u;
64
+ x1[bk] = x + (ulong)(m1[bk] ? r0 + 1u : 0u) * (ulong)C + fm * 32u;
65
+ }
66
+ metal::simdgroup_float8x8 accG[MT], accU[MT];
67
+ #pragma clang loop unroll(full)
68
+ for (uint bk = 0; bk < (uint)MT; ++bk) {
69
+ accG[bk] = metal::make_filled_simdgroup_matrix<float, 8, 8>(0.0f);
70
+ accU[bk] = metal::make_filled_simdgroup_matrix<float, 8, 8>(0.0f);
71
+ }
72
+ for (uint base = 0; base < (uint)C; base += 256u) {
73
+ const uint runA = base / 32u + fn;
74
+ uint ga[KG + 1], gb[KG + 1], ua[KU + 1], ub[KU + 1];
75
+ load_run<KG, BT>(gRow, runA, ga);
76
+ load_run<KG, BT>(gRow, runA + 1u, gb);
77
+ load_run<KU, BT>(uRow, runA, ua);
78
+ load_run<KU, BT>(uRow, runA + 1u, ub);
79
+ #pragma clang loop unroll(full)
80
+ for (uint s4 = 0; s4 < 8u; ++s4) {
81
+ float4 va[MT], vb[MT];
82
+ #pragma clang loop unroll(full)
83
+ for (uint bk = 0; bk < (uint)MT; ++bk) {
84
+ va[bk] = m0[bk] ? float4(((const device metal::vec<T, 4>*)(x0[bk] + base))[s4]) : float4(0.0f);
85
+ vb[bk] = m1[bk] ? float4(((const device metal::vec<T, 4>*)(x1[bk] + base))[s4]) : float4(0.0f);
86
+ }
87
+ #pragma clang loop unroll(full)
88
+ for (uint q = 0; q < 4u; ++q) {
89
+ const uint j = s4 * 4u + q;
90
+ metal::simdgroup_float8x8 aG, aU;
91
+ aG.thread_elements()[0] = trellis_y_f32((run_state<KG, L>(ga, j)));
92
+ aG.thread_elements()[1] = trellis_y_f32((run_state<KG, L>(gb, j)));
93
+ aU.thread_elements()[0] = trellis_y_f32((run_state<KU, L>(ua, j)));
94
+ aU.thread_elements()[1] = trellis_y_f32((run_state<KU, L>(ub, j)));
95
+ #pragma clang loop unroll(full)
96
+ for (uint bk = 0; bk < (uint)MT; ++bk) {
97
+ metal::simdgroup_float8x8 b;
98
+ b.thread_elements()[0] = va[bk][q];
99
+ b.thread_elements()[1] = vb[bk][q];
100
+ metal::simdgroup_multiply_accumulate(accG[bk], aG, b, accG[bk]);
101
+ metal::simdgroup_multiply_accumulate(accU[bk], aU, b, accU[bk]);
102
+ }
103
+ }
104
+ }
105
+ }
106
+ const float gs = float(gscales[row]) * TRELLIS_RCP;
107
+ const float us = float(uscales[row]) * TRELLIS_RCP;
108
+ #pragma clang loop unroll(full)
109
+ for (uint bk = 0; bk < (uint)MT; ++bk)
110
+ #pragma clang loop unroll(full)
111
+ for (uint j = 0; j < 2u; ++j) {
112
+ const uint m = mBase + 8u * bk + fn + j;
113
+ if (m >= (uint)M) continue;
114
+ const T gateT = T(accG[bk].thread_elements()[j] * gs);
115
+ const T upT = T(accU[bk].thread_elements()[j] * us);
116
+ const T sigmoidT = T(1.0f / (1.0f + metal::precise::exp(-float(gateT))));
117
+ const T siluT = T(float(gateT) * float(sigmoidT));
118
+ mid[(ulong)m * (ulong)R + row] = T(float(siluT) * float(upT));
119
+ }
120
+ `;
121
+
122
+ let kernel: MetalKernel | undefined;
123
+
124
+ /** silu(gate(x))·up(x) for 1..8 activation rows. Gate and up share their
125
+ * axis-1 geometry (rows a multiple of 8, columns of 256); their bit widths may
126
+ * differ. Borrows x and the weights; returns owned lazy output with x's
127
+ * leading dimensions. */
128
+ export function gateUpMma(x: MlxArray, gate: TrellisWeights, up: TrellisWeights): MlxArray {
129
+ const g = gate.geometry, u = up.geometry;
130
+ const lead = x.shape.slice(0, -1), M = lead.reduce((a, b) => a * b, 1);
131
+ if (M < 1 || M > 8) throw new Error(`gateUpMma: M=${M} outside 1..8`);
132
+ if (g.axis !== 1 || u.axis !== 1 || g.rows !== u.rows || g.cols !== u.cols || g.T !== u.T || g.L !== u.L ||
133
+ g.rows % 8 !== 0 || g.cols % 256 !== 0 || g.T % 32 !== 0)
134
+ throw new Error("gateUpMma: unsupported gate/up geometry");
135
+ kernel ??= new MetalKernel({ name: "mlx_bun_trellis_gateup_mma", inputNames: ["x", "gcodes", "gscales", "ucodes", "uscales"],
136
+ outputNames: ["mid"], source: SOURCE_V3, header: HEADER + RUN3_HEADER, ensureRowContiguous: true });
137
+ const x2 = ops.reshape(x, [M, g.inFeatures]);
138
+ const [mid] = kernel.apply([x2, gate.codes, gate.scales, up.codes, up.scales], {
139
+ outputs: [{ shape: [M, g.rows], dtype: x.dtype }],
140
+ grid: [32 * SG_TG, Math.ceil(g.rows / 8 / SG_TG), 1], threadGroup: [32 * SG_TG, 1, 1],
141
+ templateDtypes: { T: x.dtype },
142
+ templateInts: { M, R: g.rows, C: g.cols, BT: g.T, KG: g.k, KU: u.k, L: g.L, SG_TG, MT },
143
+ });
144
+ x2.dispose();
145
+ const out = ops.reshape(mid!, [...lead, g.rows]);
146
+ mid!.dispose();
147
+ return out;
148
+ }
@@ -0,0 +1,248 @@
1
+ import { MlxArray } from "@mlx-bun/mlx/array";
2
+ import * as ops from "@mlx-bun/mlx/ops";
3
+ import { MetalKernel } from "@mlx-bun/mlx/metal-kernel";
4
+ import { Dtype } from "@mlx-bun/mlx/ffi";
5
+ import type { TrellisGeometry, TrellisWeights } from "./geometry";
6
+ import { HEADER, lutFor, decoderVariant } from "./codebook";
7
+ import { TRELLIS_THREADS, TRELLIS_SG_PER_TG, TRELLIS_CODEBOOK_THREADS, TRELLIS_CODEBOOK_SG_PER_TG } from "./launch";
8
+ import { qualifiedRepresentations } from "./qualified";
9
+
10
+ import { TRELLIS_MATVEC_MAX_M as MATVEC_MAX_M } from "./reduce";
11
+
12
+ const GATEUP_SOURCE = String.raw`
13
+ threadgroup float lutTG[4096];
14
+ if ((VARIANT) == 2 || CODEBOOK) {
15
+ for (uint i = thread_position_in_threadgroup.x; i < 4096u; i += (uint)THREADS)
16
+ lutTG[i] = CODEBOOK ? trellis_unrefined_y(trellis_y(i)) : lut[i];
17
+ threadgroup_barrier(metal::mem_flags::mem_threadgroup);
18
+ }
19
+ const uint lane = thread_index_in_simdgroup;
20
+ const uint sg = simdgroup_index_in_threadgroup;
21
+ const uint row = thread_position_in_grid.y * (uint)ROWS_TG + sg;
22
+ const uint sample = thread_position_in_grid.z;
23
+ if (row >= (uint)R || sample >= (uint)M) return;
24
+ const uint wpb = (uint)(BT * K / 32);
25
+ const uint runsPerBlock = (uint)BT / 32u;
26
+ const uint nRuns = (uint)C / 32u;
27
+ const ulong rowWords = (ulong)((C / BT) * wpb);
28
+ const device uint32_t* gRow = gcodes + (ulong)row * rowWords;
29
+ const device uint32_t* uRow = ucodes + (ulong)row * rowWords;
30
+ const device T* xs = x + (ulong)sample * (ulong)C;
31
+ const float gScale = float(gscales[row]);
32
+ const float uScale = float(uscales[row]);
33
+ float gAcc = 0.0f, gAcc2 = 0.0f;
34
+ float uAcc = 0.0f, uAcc2 = 0.0f;
35
+ for (uint run = lane; run < nRuns; run += 32u) {
36
+ const uint blk = run / runsPerBlock;
37
+ const uint t0 = (run - blk * runsPerBlock) * 32u;
38
+ const device uint32_t* gw = gRow + blk * wpb;
39
+ const device uint32_t* uw = uRow + blk * wpb;
40
+ const uint w0 = ((uint)BT - 32u - t0) * (uint)K / 32u;
41
+ uint g[K + 1];
42
+ uint u[K + 1];
43
+ #pragma clang loop unroll(full)
44
+ for (uint i = 0; i <= (uint)K; ++i) {
45
+ const uint wi = w0 + i;
46
+ const uint idx = wi >= wpb ? wi - wpb : wi;
47
+ g[i] = gw[idx];
48
+ u[i] = uw[idx];
49
+ }
50
+ const uint c0 = blk * (uint)BT + t0;
51
+ const device metal::vec<T, 4>* x4 = (const device metal::vec<T, 4>*)(xs + c0);
52
+ #pragma clang loop unroll(full)
53
+ for (uint j4 = 0; j4 < 8u; ++j4) {
54
+ const float4 xv4 = float4(x4[j4]);
55
+ #pragma clang loop unroll(full)
56
+ for (uint q = 0; q < 4u; ++q) {
57
+ const uint j = j4 * 4u + q;
58
+ const uint b = (31u - j) * (uint)K;
59
+ const uint wi = b >> 5;
60
+ const uint off = b & 31u;
61
+ uint gwin = g[wi] >> off;
62
+ uint uwin = u[wi] >> off;
63
+ if (off + (uint)L > 32u) { gwin |= g[wi + 1] << (32u - off); uwin |= u[wi + 1] << (32u - off); }
64
+ gwin &= (1u << (uint)L) - 1u;
65
+ uwin &= (1u << (uint)L) - 1u;
66
+ const float xv = xv4[q];
67
+ const float gv = TRELLIS_ROUND((CODEBOOK ? lutTG[gwin] : TRELLIS_DECODE(gwin, lutTG, lut)) * gScale);
68
+ const float uv = TRELLIS_ROUND((CODEBOOK ? lutTG[uwin] : TRELLIS_DECODE(uwin, lutTG, lut)) * uScale);
69
+ if (q & 1u) { gAcc2 = metal::fma(gv, xv, gAcc2); uAcc2 = metal::fma(uv, xv, uAcc2); }
70
+ else { gAcc = metal::fma(gv, xv, gAcc); uAcc = metal::fma(uv, xv, uAcc); }
71
+ }
72
+ }
73
+ }
74
+ const float gate = metal::simd_sum(gAcc + gAcc2);
75
+ const float up = metal::simd_sum(uAcc + uAcc2);
76
+ if (lane == 0u) {
77
+ const T gateT = T(gate);
78
+ const T upT = T(up);
79
+ const T sigmoidT = T(1.0f / (1.0f + metal::precise::exp(-float(gateT))));
80
+ const T siluT = T(float(gateT) * float(sigmoidT));
81
+ mid[(ulong)sample * (ulong)R + row] = T(float(siluT) * float(upT));
82
+ }
83
+ `;
84
+
85
+ const GATEUP_SHARED_M_SOURCE = String.raw`
86
+ threadgroup float lutTG[4096];
87
+ if ((VARIANT) == 2) {
88
+ for (uint i = thread_position_in_threadgroup.x; i < 4096u; i += ${TRELLIS_THREADS}u) lutTG[i] = lut[i];
89
+ threadgroup_barrier(metal::mem_flags::mem_threadgroup);
90
+ }
91
+ const uint lane = thread_index_in_simdgroup;
92
+ const uint sg = simdgroup_index_in_threadgroup;
93
+ const uint row = thread_position_in_grid.y * (uint)ROWS_TG + sg;
94
+ const uint sample = 0u;
95
+ if (row >= (uint)R || sample >= (uint)M) return;
96
+ const uint wpb = (uint)(BT * K / 32);
97
+ const uint runsPerBlock = (uint)BT / 32u;
98
+ const uint nRuns = (uint)C / 32u;
99
+ const ulong rowWords = (ulong)((C / BT) * wpb);
100
+ const device uint32_t* gRow = gcodes + (ulong)row * rowWords;
101
+ const device uint32_t* uRow = ucodes + (ulong)row * rowWords;
102
+ const float gScale = float(gscales[row]);
103
+ const float uScale = float(uscales[row]);
104
+ float gAcc[M], gAcc2[M], uAcc[M], uAcc2[M];
105
+ #pragma clang loop unroll(full)
106
+ for (uint m = 0; m < (uint)M; ++m) {
107
+ gAcc[m] = 0.0f; gAcc2[m] = 0.0f; uAcc[m] = 0.0f; uAcc2[m] = 0.0f;
108
+ }
109
+ for (uint run = lane; run < nRuns; run += 32u) {
110
+ const uint blk = run / runsPerBlock;
111
+ const uint t0 = (run - blk * runsPerBlock) * 32u;
112
+ const device uint32_t* gw = gRow + blk * wpb;
113
+ const device uint32_t* uw = uRow + blk * wpb;
114
+ const uint w0 = ((uint)BT - 32u - t0) * (uint)K / 32u;
115
+ uint g[K + 1];
116
+ uint u[K + 1];
117
+ #pragma clang loop unroll(full)
118
+ for (uint i = 0; i <= (uint)K; ++i) {
119
+ const uint wi = w0 + i;
120
+ const uint idx = wi >= wpb ? wi - wpb : wi;
121
+ g[i] = gw[idx];
122
+ u[i] = uw[idx];
123
+ }
124
+ const uint c0 = blk * (uint)BT + t0;
125
+ #pragma clang loop unroll(full)
126
+ for (uint j4 = 0; j4 < 8u; ++j4) {
127
+ float4 xv4[M];
128
+ #pragma clang loop unroll(full)
129
+ for (uint m = 0; m < (uint)M; ++m)
130
+ xv4[m] = float4(((const device metal::vec<T, 4>*)(x + (ulong)m * (ulong)C + c0))[j4]);
131
+ #pragma clang loop unroll(full)
132
+ for (uint q = 0; q < 4u; ++q) {
133
+ const uint j = j4 * 4u + q;
134
+ const uint b = (31u - j) * (uint)K;
135
+ const uint wi = b >> 5;
136
+ const uint off = b & 31u;
137
+ uint gwin = g[wi] >> off;
138
+ uint uwin = u[wi] >> off;
139
+ if (off + (uint)L > 32u) { gwin |= g[wi + 1] << (32u - off); uwin |= u[wi + 1] << (32u - off); }
140
+ gwin &= (1u << (uint)L) - 1u;
141
+ uwin &= (1u << (uint)L) - 1u;
142
+ const float gv = TRELLIS_ROUND(TRELLIS_DECODE(gwin, lutTG, lut) * gScale);
143
+ const float uv = TRELLIS_ROUND(TRELLIS_DECODE(uwin, lutTG, lut) * uScale);
144
+ #pragma clang loop unroll(full)
145
+ for (uint m = 0; m < (uint)M; ++m) {
146
+ const float xv = xv4[m][q];
147
+ if (q & 1u) { gAcc2[m] = metal::fma(gv, xv, gAcc2[m]); uAcc2[m] = metal::fma(uv, xv, uAcc2[m]); }
148
+ else { gAcc[m] = metal::fma(gv, xv, gAcc[m]); uAcc[m] = metal::fma(uv, xv, uAcc[m]); }
149
+ }
150
+ }
151
+ }
152
+ }
153
+ #pragma clang loop unroll(full)
154
+ for (uint m = 0; m < (uint)M; ++m) {
155
+ const float gate = metal::simd_sum(gAcc[m] + gAcc2[m]);
156
+ const float up = metal::simd_sum(uAcc[m] + uAcc2[m]);
157
+ if (lane == 0u) {
158
+ const T gateT = T(gate);
159
+ const T upT = T(up);
160
+ const T sigmoidT = T(1.0f / (1.0f + metal::precise::exp(-float(gateT))));
161
+ const T siluT = T(float(gateT) * float(sigmoidT));
162
+ mid[(ulong)m * (ulong)R + row] = T(float(siluT) * float(upT));
163
+ }
164
+ }
165
+ `;
166
+
167
+ let base: MetalKernel | undefined, shared: MetalKernel | undefined;
168
+ function gateUpKernel(): MetalKernel {
169
+ return base ??= new MetalKernel({ name: "mlx_bun_trellis_gateup_swiglu",
170
+ inputNames: ["x", "gcodes", "gscales", "ucodes", "uscales", "lut"], outputNames: ["mid"],
171
+ source: GATEUP_SOURCE, header: HEADER, ensureRowContiguous: true });
172
+ }
173
+ function sharedGateUpKernel(): MetalKernel {
174
+ return shared ??= new MetalKernel({ name: "mlx_bun_trellis_gateup_shared_m",
175
+ inputNames: ["x", "gcodes", "gscales", "ucodes", "uscales", "lut"], outputNames: ["mid"],
176
+ source: GATEUP_SHARED_M_SOURCE, header: HEADER, ensureRowContiguous: true });
177
+ }
178
+
179
+ /** The measured artifact geometry, row count, dtype and numerical variant of the codebook decode. */
180
+ function codebookShape(g: TrellisGeometry, m: number, dtype: Dtype, selected: number): boolean {
181
+ return selected === 13 && m === 1 && dtype === Dtype.bfloat16 &&
182
+ g.axis === 1 && g.T === 256 && g.L === 12 && [2, 3, 4].includes(g.k) &&
183
+ g.inFeatures === 5120 && g.outFeatures === 17408 && g.cols === 5120 && g.rows === 17408 && !g.blockInterleave;
184
+ }
185
+
186
+ /** Qualification is deliberately limited to the measured artifact geometry and
187
+ * GPU family. Other shapes, row counts, dtypes and numerical variants retain
188
+ * inline decode. The table uses variant 6 arithmetic, not the host's rounded LUT. */
189
+ export function gateUpCodebookEligible(g: TrellisGeometry, m: number, dtype: Dtype, selected: number,
190
+ architecture: string): boolean {
191
+ return qualifiedRepresentations(architecture).gateUpCodebook && codebookShape(g, m, dtype, selected);
192
+ }
193
+
194
+ /** Variants 7..13 share each decoded weight across rows (`GATEUP_SHARED_M_SOURCE`). */
195
+ const sharesRows = (selected: number) => selected >= 7 && selected <= 13;
196
+
197
+ /** silu(gate(x))·up(x) for exactly one activation row, gate and up at the same
198
+ * width: the per-row kernel. `codebook` applies at the measured shape; layers
199
+ * pass the choice they resolved at construction (`qualifiedRepresentations`).
200
+ * Borrows x and the weights; returns owned lazy output with x's leading dimensions. */
201
+ export function gateUpReduceRow(x: MlxArray, gate: TrellisWeights, up: TrellisWeights, selected: number,
202
+ codebook: boolean): MlxArray {
203
+ if (x.size !== x.shape.at(-1)) throw new Error("gateUpReduceRow: expects one activation row");
204
+ return launch(gateUpKernel(), x, gate, up, selected, codebook, 1, false);
205
+ }
206
+
207
+ /** silu(gate(x))·up(x) for 2..4 activation rows sharing each decoded weight
208
+ * (variants 7..13), gate and up at the same width. Borrows x and the weights;
209
+ * returns owned lazy output with x's leading dimensions. */
210
+ export function gateUpReduceRows(x: MlxArray, gate: TrellisWeights, up: TrellisWeights, selected: number): MlxArray {
211
+ const M = x.size / x.shape.at(-1)!;
212
+ if (M < 2 || M > MATVEC_MAX_M) throw new Error(`gateUpReduceRows: M=${M} outside 2..${MATVEC_MAX_M}`);
213
+ if (!sharesRows(selected)) throw new Error(`gateUpReduceRows: variant ${selected} does not share rows (7..13 do)`);
214
+ return launch(sharedGateUpKernel(), x, gate, up, selected, false, M, true);
215
+ }
216
+
217
+ /** Borrow matching axis-1 gate/up weights with the same bit width; M must be 1..4.
218
+ * Return owned lazy SwiGLU output, retaining the input's leading dimensions.
219
+ * `codebook` applies at the measured shape: layers pass the choice they resolved
220
+ * at construction (`qualifiedRepresentations`), benches and tests the one they compare. */
221
+ export function fusedGateUpSwiglu(x: MlxArray, gate: TrellisWeights, up: TrellisWeights, selected: number,
222
+ codebook: boolean): MlxArray {
223
+ const M = x.shape.slice(0, -1).reduce((a, b) => a * b, 1);
224
+ if (M > MATVEC_MAX_M) throw new Error(`fusedGateUpSwiglu: M=${M} > ${MATVEC_MAX_M}`);
225
+ const shared = sharesRows(selected) && M > 1;
226
+ return launch(shared ? sharedGateUpKernel() : gateUpKernel(), x, gate, up, selected, codebook, M, shared);
227
+ }
228
+
229
+ function launch(kernel: MetalKernel, x: MlxArray, gate: TrellisWeights, up: TrellisWeights, selected: number,
230
+ codebook: boolean, M: number, shared: boolean): MlxArray {
231
+ const g = gate.geometry;
232
+ const lead = x.shape.slice(0, -1);
233
+ const useCodebook = codebook && codebookShape(g, M, x.dtype, selected);
234
+ const threads = useCodebook ? TRELLIS_CODEBOOK_THREADS : TRELLIS_THREADS;
235
+ const rowsPerGroup = useCodebook ? TRELLIS_CODEBOOK_SG_PER_TG : TRELLIS_SG_PER_TG;
236
+ const x2 = ops.reshape(x, [M, g.inFeatures]);
237
+ const [mid] = kernel.apply([x2, gate.codes, gate.scales, up.codes, up.scales, lutFor(g.L)], {
238
+ outputs: [{ shape: [M, g.rows], dtype: x.dtype }],
239
+ grid: [threads, Math.ceil(g.rows / rowsPerGroup), shared ? 1 : M],
240
+ threadGroup: [threads, 1, 1],
241
+ templateDtypes: { T: x.dtype },
242
+ templateInts: { M, R: g.rows, C: g.cols, BT: g.T, K: g.k, L: g.L, ROWS_TG: rowsPerGroup, VARIANT: decoderVariant(selected), THREADS: threads, CODEBOOK: Number(useCodebook) },
243
+ });
244
+ x2.dispose();
245
+ const out = ops.reshape(mid!, [...lead, g.rows]);
246
+ mid!.dispose();
247
+ return out;
248
+ }
@@ -0,0 +1,22 @@
1
+ import type { MlxArray } from "@mlx-bun/mlx/array";
2
+
3
+ export interface TrellisGeometry {
4
+ k: number;
5
+ L: number;
6
+ T: number;
7
+ axis: 0 | 1;
8
+ /** Stored-matrix rows / coded columns. */
9
+ rows: number;
10
+ cols: number;
11
+ inFeatures: number;
12
+ outFeatures: number;
13
+ /** Two coded blocks interleaved across rows; absent for row-major codes. */
14
+ blockInterleave?: 2;
15
+ }
16
+
17
+ /** Borrowed packed weights and their caller-supplied geometry. */
18
+ export interface TrellisWeights {
19
+ codes: MlxArray;
20
+ scales: MlxArray;
21
+ geometry: TrellisGeometry;
22
+ }
@@ -0,0 +1,103 @@
1
+ // Packed Trellis projection kernels (QTIP 1MAD code) and the decode-variant
2
+ // semantics their callers pass (layers/trellis-linear.ts passes 13).
3
+ //
4
+ // Format: `.weight` = uint32 bitstream, `.scales` = fp16 [rows], config entry
5
+ // `{mode:"trellis", bits:k, group_size:T, trellis:{L, code:"1mad", axis}}`.
6
+ // axis=1 (gate/up) is coded along the INPUT dim, stored [out, in*k/32]; axis=0
7
+ // (down) is coded along the OUTPUT dim, stored [in, out*k/32] (the stored matrix
8
+ // is W^T, coded along its last axis). The k3/axis0 layout [cols/512, rows, 48]
9
+ // interleaves two coded blocks across rows (`blockInterleave`); the tensor
10
+ // shape identifies it and no second code copy is kept.
11
+ //
12
+ // One decode primitive: state_t is the L-bit window at bit offset (T-1-t)*k of
13
+ // the block (wrapping), so any weight decodes in O(1) with the 1MAD code
14
+ // computed inline (codebook.ts HEADER), no LUT and no threadgroup memory.
15
+ // - reduce (M <= 4, axis=1): one SIMD group per output row; each lane owns
16
+ // runs of 32 consecutive positions held in K+1 registers (every
17
+ // window shift a compile-time constant); simd_sum.
18
+ // - scatter (M <= 4, axis=0): lane-per-WORD of a block, running sums per
19
+ // position in the word, split-K over input rows (partials folded
20
+ // by one mlx sum). One kernel each: scatterRow / balancedScatterRow
21
+ // (one row; balanced = 3-bit codes at T 256) and scatterRows /
22
+ // balancedScatterRows (2..4 rows sharing each decoded weight);
23
+ // trellisScatter chooses among them by row count and geometry.
24
+ // - expand (M > 4 fallback): decode the whole tensor to bf16, then a stock
25
+ // matmul; the transient is one tensor.
26
+ // - gate-up / mixed-gate-up: fused gate+up+SwiGLU for M <= 4 rows
27
+ // (gateUpReduceRow one row, gateUpReduceRows 2..4 shared rows;
28
+ // fusedGateUpSwiglu chooses between them by row count). The mixed
29
+ // kernel serves layers whose gate and up bit widths differ (one
30
+ // word layout and bit offset each); TAIL "split" reproduces MLX's
31
+ // compiled swiglu over two bf16 projections bit for bit (no output
32
+ // changes vs the two-kernel path), "fused" the float32 sigmoid of
33
+ // the same-width kernel.
34
+ //
35
+ // Decode VARIANT, an explicit argument of each kernel. TrellisLinear passes
36
+ // 13; benches and tests pass the others to compare them. 0-6 select the decode
37
+ // arithmetic (see HEADER in codebook.ts): 0-3 reconstruct bf16(lut[state]*scale);
38
+ // 6 is f32 code*scale in the packed kernels (expansion still stores bf16).
39
+ // Variants 7-13 keep variant 6's decoded values (`decoderVariant`) and add
40
+ // kernel selection, each including the ones below it:
41
+ // 7 weight decoding shared across M=2..4 in reduce and gate-up
42
+ // 8 balanced 3-bit scatter (k=3, T=256, L<=12)
43
+ // 9 same kernels as 8; it once also deferred prefill projection evaluation
44
+ // to the Qwen layer barrier, which no longer exists
45
+ // 10 shared-M scatter across M=2..4
46
+ // 11 tiled axis-1 prefill at M=5..32 on the measured MLP shape; wide prefill
47
+ // when the input is proven row-contiguous
48
+ // 12 tiled axis-0 prefill at M=5..8 with MLX's split-K reduction
49
+ // 13 shared packed-word loads in the remaining bf16 expansion (vector
50
+ // expand), and the shared scatter codebook for M=3..4 bf16 on the
51
+ // interleaved k3 layout
52
+ //
53
+ // Threadgroup-codebook one-row kernels (every code value of the 2^L states
54
+ // generated once per threadgroup), the variant-13 output of the kernels above
55
+ // bit for bit:
56
+ // - gate-up-codebook: gate/up/SwiGLU, the same or different widths
57
+ // - down-codebook: lanes owning word-aligned runs of positions (every window
58
+ // shift a constant), row-major 2/4-bit and 3-bit block-interleaved codes
59
+ //
60
+ // Factored-scale kernels: weights contribute their code value y and the scale
61
+ // (with 1/147.8) applies once per output (gate/up) or per input row (down);
62
+ // one kernel per row form and code layout:
63
+ // - gate-up-factored: same-width gate/up, one row / 2..4 shared rows
64
+ // - mixed-gate-up-factored: different-width gate/up, 1..4 rows
65
+ // - down-factored: row-major axis-0 codes, one row / 2..4 rows
66
+ // - down-k3-interleaved-factored: 3-bit block-interleaved axis-0 codes
67
+ // - gate-up-mma / down-mma: 1..8 rows on the simdgroup matrix unit
68
+ // - gate-up-mma-wide / down-mma-wide: the same fragments for any number of
69
+ // rows, each decoded fragment feeding the MMAs of several 8-row blocks,
70
+ // each code value read from a threadgroup codebook; down-mma-wide in
71
+ // passes the rows plan or the caller fixes (one block for 1..8 rows)
72
+ // - gate-up-codebook-mma: gate-up-mma's fragments and bits for 1..8 rows,
73
+ // each code value read from a threadgroup codebook (the M1 Max form)
74
+ //
75
+ // ExpandedTrellisLinear (layers/trellis-linear.ts) decodes a trellis tensor at
76
+ // construction into 8-bit g64 affine (the eval-carrier numerics, about -45 dB)
77
+ // and serves it through the stock QuantizedLinear, for a machine where the
78
+ // kernels lose.
79
+ export type { TrellisGeometry, TrellisWeights } from "./geometry";
80
+ export { vectorTrellisExpand, vectorTrellisExpandEligible } from "./vector-expand";
81
+ export { expandTrellis } from "./expand";
82
+ export { trellisReduce, TRELLIS_MATVEC_MAX_M } from "./reduce";
83
+ export { trellisScatter, scatterRow, scatterRows, balancedScatterRow, balancedScatterRows } from "./scatter";
84
+ export { qualifiedRepresentations, type ScatterRepresentation, type TrellisRepresentations } from "./qualified";
85
+ export { fusedGateUpSwiglu, gateUpReduceRow, gateUpReduceRows } from "./gate-up";
86
+ export { gateUpCodebookRow } from "./gate-up-codebook";
87
+ export { downCodebookRow, downK3InterleavedCodebookRow } from "./down-codebook";
88
+ export { fusedGateUpSwigluMixed, type MixedGateUpTail } from "./mixed-gate-up";
89
+ export { tiledTrellisPrefill, tiledTrellisPrefillEligible } from "./tiled-prefill";
90
+ export { splitKTrellisPrefill, splitKTrellisPrefillEligible } from "./splitk-prefill";
91
+ export { wideTrellisPrefill, wideTrellisPrefillEligible, nativeTrellisWidePrefill } from "./wide-prefill";
92
+ export { lut1mad, wordsPerBlock } from "./codebook";
93
+ export { gateUpFactoredRow, gateUpFactoredRows } from "./gate-up-factored";
94
+ export { mixedGateUpFactoredRows } from "./mixed-gate-up-factored";
95
+ export { downFactoredRow, downFactoredRows } from "./down-factored";
96
+ export { downK3InterleavedFactoredRow, downK3InterleavedFactoredRows } from "./down-k3-interleaved-factored";
97
+ export { gateUpMma } from "./gate-up-mma";
98
+ export { downMma, downK3InterleavedMma } from "./down-mma";
99
+ export { gateUpMmaWide } from "./gate-up-mma-wide";
100
+ export {
101
+ downMmaWide, downK3InterleavedMmaWide, downMmaWidePass, downK3InterleavedMmaWidePass, DOWN_ONE_BLOCK, type DownPass,
102
+ } from "./down-mma-wide";
103
+ export { gateUpCodebookMma } from "./gate-up-codebook-mma";
@@ -0,0 +1,12 @@
1
+ /** Default Trellis matvec launch: four SIMD groups of 32 lanes per threadgroup,
2
+ * one output row per SIMD group. Qualified codebook decode uses wider groups. */
3
+ export const TRELLIS_THREADS = 128;
4
+ export const TRELLIS_SG_PER_TG = 4;
5
+ /** Amortize the 16 KiB codebook over sixteen rows in the qualified M1 decode. */
6
+ export const TRELLIS_CODEBOOK_THREADS = 512;
7
+ export const TRELLIS_CODEBOOK_SG_PER_TG = 16;
8
+ /** The one-row gate/up codebook kernel: one threadgroup per M1 Max core, each table serving 32 rows at a time. */
9
+ export const TRELLIS_CODEBOOK_ROW_THREADS = 1024;
10
+ export const TRELLIS_CODEBOOK_ROW_SG_PER_TG = 32;
11
+ /** The one-row down codebook kernel: eight SIMD groups per threadgroup (each split's lanes own 16 positions). */
12
+ export const TRELLIS_CODEBOOK_DOWN_THREADS = 256;
@@ -0,0 +1,119 @@
1
+ import { MlxArray } from "@mlx-bun/mlx/array";
2
+ import * as ops from "@mlx-bun/mlx/ops";
3
+ import { MetalKernel } from "@mlx-bun/mlx/metal-kernel";
4
+ import type { TrellisWeights } from "./geometry";
5
+ import { HEADER } from "./codebook";
6
+ import { TRELLIS_THREADS, TRELLIS_SG_PER_TG } from "./launch";
7
+
8
+ // Fused gate/up/SwiGLU for layers whose gate and up were coded at different
9
+ // bit widths (KG, KU), 1..4 activation rows sharing each decoded weight. Row
10
+ // scales are factored out of the reduction as in gate-up-factored.ts. The
11
+ // SwiGLU tail is MLX's compiled swiglu over bf16 gate and up (sigmoid via
12
+ // exp(|g|) in T), the arithmetic of two separate projections plus swiglu.
13
+ const SOURCE = String.raw`
14
+ const uint lane = thread_index_in_simdgroup;
15
+ const uint sg = simdgroup_index_in_threadgroup;
16
+ const uint row = thread_position_in_grid.y * (uint)ROWS_TG + sg;
17
+ if (row >= (uint)R) return;
18
+ const uint gWpb = (uint)(BT * KG / 32);
19
+ const uint uWpb = (uint)(BT * KU / 32);
20
+ const uint runsPerBlock = (uint)BT / 32u;
21
+ const uint nRuns = (uint)C / 32u;
22
+ const device uint32_t* gRow = gcodes + (ulong)row * (ulong)((C / BT) * gWpb);
23
+ const device uint32_t* uRow = ucodes + (ulong)row * (ulong)((C / BT) * uWpb);
24
+ const float gScale = float(gscales[row]);
25
+ const float uScale = float(uscales[row]);
26
+ float gAcc[M], uAcc[M];
27
+ #pragma clang loop unroll(full)
28
+ for (uint m = 0; m < (uint)M; ++m) { gAcc[m] = 0.0f; uAcc[m] = 0.0f; }
29
+ for (uint run = lane; run < nRuns; run += 32u) {
30
+ const uint blk = run / runsPerBlock;
31
+ const uint t0 = (run - blk * runsPerBlock) * 32u;
32
+ const device uint32_t* gw = gRow + blk * gWpb;
33
+ const device uint32_t* uw = uRow + blk * uWpb;
34
+ const uint gW0 = ((uint)BT - 32u - t0) * (uint)KG / 32u;
35
+ const uint uW0 = ((uint)BT - 32u - t0) * (uint)KU / 32u;
36
+ uint g[KG + 1];
37
+ uint u[KU + 1];
38
+ #pragma clang loop unroll(full)
39
+ for (uint i = 0; i <= (uint)KG; ++i) {
40
+ const uint wi = gW0 + i;
41
+ g[i] = gw[wi >= gWpb ? wi - gWpb : wi];
42
+ }
43
+ #pragma clang loop unroll(full)
44
+ for (uint i = 0; i <= (uint)KU; ++i) {
45
+ const uint wi = uW0 + i;
46
+ u[i] = uw[wi >= uWpb ? wi - uWpb : wi];
47
+ }
48
+ const uint c0 = blk * (uint)BT + t0;
49
+ #pragma clang loop unroll(full)
50
+ for (uint j4 = 0; j4 < 8u; ++j4) {
51
+ float4 xv4[M];
52
+ #pragma clang loop unroll(full)
53
+ for (uint m = 0; m < (uint)M; ++m)
54
+ xv4[m] = float4(((const device metal::vec<T, 4>*)(x + (ulong)m * (ulong)C + c0))[j4]);
55
+ #pragma clang loop unroll(full)
56
+ for (uint q = 0; q < 4u; ++q) {
57
+ const uint j = j4 * 4u + q;
58
+ const uint gb = (31u - j) * (uint)KG;
59
+ const uint ub = (31u - j) * (uint)KU;
60
+ const uint gwi = gb >> 5, goff = gb & 31u;
61
+ const uint uwi = ub >> 5, uoff = ub & 31u;
62
+ uint gwin = g[gwi] >> goff;
63
+ uint uwin = u[uwi] >> uoff;
64
+ if (goff + (uint)L > 32u) gwin |= g[gwi + 1] << (32u - goff);
65
+ if (uoff + (uint)L > 32u) uwin |= u[uwi + 1] << (32u - uoff);
66
+ gwin &= (1u << (uint)L) - 1u;
67
+ uwin &= (1u << (uint)L) - 1u;
68
+ const float gv = trellis_y_f32(gwin);
69
+ const float uv = trellis_y_f32(uwin);
70
+ #pragma clang loop unroll(full)
71
+ for (uint m = 0; m < (uint)M; ++m) {
72
+ const float xv = xv4[m][q];
73
+ gAcc[m] = metal::fma(gv, xv, gAcc[m]); uAcc[m] = metal::fma(uv, xv, uAcc[m]);
74
+ }
75
+ }
76
+ }
77
+ }
78
+ #pragma clang loop unroll(full)
79
+ for (uint m = 0; m < (uint)M; ++m) {
80
+ const float gate = metal::simd_sum(gAcc[m]) * (gScale * TRELLIS_RCP);
81
+ const float up = metal::simd_sum(uAcc[m]) * (uScale * TRELLIS_RCP);
82
+ if (lane == 0u) {
83
+ const T gateT = T(gate);
84
+ const T upT = T(up);
85
+ const T sigY = 1 / (1 + metal::exp(metal::abs(gateT)));
86
+ const T sigmoidT = (gateT < 0) ? sigY : 1 - sigY;
87
+ const T siluT = gateT * sigmoidT;
88
+ mid[(ulong)m * (ulong)R + row] = siluT * upT;
89
+ }
90
+ }
91
+ `;
92
+
93
+ let kernel: MetalKernel | undefined;
94
+
95
+ /** silu(gate(x))·up(x) for 1..4 activation rows when gate and up share their
96
+ * axis-1 geometry but not their bit width. Borrows x and the weights; returns
97
+ * owned lazy output with x's leading dimensions. */
98
+ export function mixedGateUpFactoredRows(x: MlxArray, gate: TrellisWeights, up: TrellisWeights): MlxArray {
99
+ const g = gate.geometry, u = up.geometry;
100
+ if (g.axis !== 1 || u.axis !== 1 || g.k === u.k || g.rows !== u.rows || g.cols !== u.cols || g.T !== u.T || g.L !== u.L)
101
+ throw new Error("mixedGateUpFactoredRows: gate and up need the same axis-1 geometry at different widths");
102
+ const lead = x.shape.slice(0, -1);
103
+ const M = lead.reduce((a, b) => a * b, 1);
104
+ if (M < 1 || M > 4) throw new Error(`mixedGateUpFactoredRows: M=${M} outside 1..4`);
105
+ kernel ??= new MetalKernel({ name: "mlx_bun_trellis_gateup_mixed_factored", inputNames: ["x", "gcodes", "gscales", "ucodes", "uscales"],
106
+ outputNames: ["mid"], source: SOURCE, header: HEADER, ensureRowContiguous: true });
107
+ const x2 = ops.reshape(x, [M, g.inFeatures]);
108
+ const [mid] = kernel.apply([x2, gate.codes, gate.scales, up.codes, up.scales], {
109
+ outputs: [{ shape: [M, g.rows], dtype: x.dtype }],
110
+ grid: [TRELLIS_THREADS, Math.ceil(g.rows / TRELLIS_SG_PER_TG), 1],
111
+ threadGroup: [TRELLIS_THREADS, 1, 1],
112
+ templateDtypes: { T: x.dtype },
113
+ templateInts: { M, R: g.rows, C: g.cols, BT: g.T, KG: g.k, KU: u.k, L: g.L, ROWS_TG: TRELLIS_SG_PER_TG },
114
+ });
115
+ x2.dispose();
116
+ const out = ops.reshape(mid!, [...lead, g.rows]);
117
+ mid!.dispose();
118
+ return out;
119
+ }