@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,389 @@
1
+ // Universal rope factory — faithful port of mlx_lm/models/rope_utils.py
2
+ // (oracle venv, mlx-lm 0.31.3): initialize_rope with the default / linear /
3
+ // llama3 (Llama3RoPE) / yarn (YarnRoPE) / longrope (SuScaledRoPE) /
4
+ // proportional (ProportionalRoPE) variants.
5
+ //
6
+ // Porting discipline (three-level fidelity tree, L1): every frequency
7
+ // table is computed with the SAME mlx float32 ops the oracle uses at
8
+ // module init — not host-side float64 math — so the freqs bytes match the
9
+ // oracle's bit-for-bit. Host math (Math.log/floor/ceil) is used only where
10
+ // the oracle uses python-float math (yarn correction range, mscale, su
11
+ // scale), which is IEEE double on both sides.
12
+ //
13
+ // The existing runtime paths (ops.rope default, gemma4's proportional
14
+ // freqs) are untouched; this factory serves the universal (Tier-0) models.
15
+
16
+ import { MlxArray } from "@mlx-bun/mlx/array";
17
+ import { Dtype } from "@mlx-bun/mlx/ffi";
18
+ import * as ops from "@mlx-bun/mlx/ops";
19
+
20
+ /** Raw HF `rope_scaling` dict (values read exactly like the oracle). */
21
+ export type RopeScalingConfig = Record<string, unknown>;
22
+
23
+ const num = (v: unknown, fallback: number): number =>
24
+ typeof v === "number" ? v : fallback;
25
+
26
+ const requireNum = (sc: RopeScalingConfig, key: string): number => {
27
+ const v = sc[key];
28
+ if (typeof v !== "number") throw new Error(`rope_scaling.${key} missing or not a number`);
29
+ return v;
30
+ };
31
+
32
+ /** One rope instance (shared across layers — identical params ⇒ identical
33
+ * values). `apply` returns a NEW array; the caller owns disposal of both. */
34
+ export class UniversalRope {
35
+ constructor(
36
+ readonly dims: number,
37
+ readonly traditional: boolean,
38
+ /** Base for native fast_rope; null when `freqs` supplies the table. */
39
+ readonly base: number | null,
40
+ /** fast_rope scale (1/factor for "linear", else 1). */
41
+ readonly scale: number,
42
+ /** Precomputed frequency table (llama3/yarn/longrope/proportional). */
43
+ readonly freqs: MlxArray | null,
44
+ /** Pre-rope input scale on x[..., :dims] (yarn mscale / su scale). */
45
+ readonly preScale: number,
46
+ /** Apply preScale even when it is exactly 1.0 (SuScaledRoPE does; Yarn
47
+ * skips when mscale == 1.0). */
48
+ readonly preScaleAlways: boolean,
49
+ ) {}
50
+
51
+ apply(x: MlxArray, offset: number): MlxArray {
52
+ const input = this.#preScaled(x);
53
+ const out = ops.ropeScaled(
54
+ input ?? x, this.dims, this.traditional, this.base, this.scale, offset, this.freqs,
55
+ );
56
+ input?.dispose();
57
+ return out;
58
+ }
59
+
60
+ /** Per-row array-offset variant (batched decode under left-padding: each
61
+ * row's REAL position rides an int32 [B] array — the scalar offset would
62
+ * mis-position every padded row by its pad amount). Same math as
63
+ * `apply`; only the offset spelling differs. */
64
+ applyDynamic(x: MlxArray, offsetArr: MlxArray): MlxArray {
65
+ const input = this.#preScaled(x);
66
+ const out = ops.ropeScaledDynamic(
67
+ input ?? x, this.dims, this.traditional, this.base, this.scale, offsetArr, this.freqs,
68
+ );
69
+ input?.dispose();
70
+ return out;
71
+ }
72
+
73
+ /** x[..., :dims] = preScale * x[..., :dims] (weak-scalar mul); null when
74
+ * no pre-scale applies (caller uses x unchanged). */
75
+ #preScaled(x: MlxArray): MlxArray | null {
76
+ if (!(this.preScaleAlways || this.preScale !== 1.0)) return null;
77
+ const D = x.shape[x.shape.length - 1]!;
78
+ if (this.dims === D) return ops.mulScalar(x, this.preScale);
79
+ const start = x.shape.map(() => 0);
80
+ const stop = [...x.shape];
81
+ stop[stop.length - 1] = this.dims;
82
+ const head = x.slice(start, stop);
83
+ const headScaled = ops.mulScalar(head, this.preScale);
84
+ head.dispose();
85
+ const scaled = ops.sliceUpdate(x, headScaled, start, stop);
86
+ headScaled.dispose();
87
+ return scaled;
88
+ }
89
+
90
+ dispose(): void {
91
+ this.freqs?.dispose();
92
+ }
93
+ }
94
+
95
+ /** SmolLM3 NoPE: identity stand-in for disabled-rope layers. */
96
+ export class NoRope extends UniversalRope {
97
+ constructor() {
98
+ super(0, false, null, 1, null, 1, false);
99
+ }
100
+ override apply(x: MlxArray, _offset: number): MlxArray {
101
+ // Return an owned copy-view so callers can dispose uniformly.
102
+ return x.slice(x.shape.map(() => 0), [...x.shape]);
103
+ }
104
+ override applyDynamic(x: MlxArray, _offsetArr: MlxArray): MlxArray {
105
+ return x.slice(x.shape.map(() => 0), [...x.shape]);
106
+ }
107
+ }
108
+
109
+ /** `base ** (arange(0, dims, 2) / dims)` with the oracle's dtypes:
110
+ * int32 arange for llama3 (no explicit dtype in the source), float32
111
+ * arange for yarn/longrope. Integer÷integer divides to float32 in mlx,
112
+ * so both spellings compute the pow in f32. */
113
+ function baseFreqs(dims: number, base: number, arangeDtype: Dtype): MlxArray {
114
+ const ar = ops.arange(0, dims, 2, arangeDtype);
115
+ const dimsScalar = arangeDtype === Dtype.int32
116
+ ? ops.fromInt32([dims], [])
117
+ : MlxArray.fromFloat32(new Float32Array([dims]), []);
118
+ const exps = ops.div(ar, dimsScalar); // → float32
119
+ ar.dispose();
120
+ dimsScalar.dispose();
121
+ const baseScalar = ops.scalarLike(base, exps);
122
+ const out = ops.pow(baseScalar, exps);
123
+ baseScalar.dispose();
124
+ exps.dispose();
125
+ return out; // float32 [dims/2]
126
+ }
127
+
128
+ /** Llama3RoPE frequency table (rope_utils.py:74-108, verbatim). */
129
+ function llama3Freqs(dims: number, base: number, sc: RopeScalingConfig): MlxArray {
130
+ const factor = requireNum(sc, "factor");
131
+ const lowFreqFactor = num(sc.low_freq_factor, 1.0);
132
+ const highFreqFactor = num(sc.high_freq_factor, 4.0);
133
+ const oldContextLen = num(sc.original_max_position_embeddings, 8192);
134
+
135
+ const lowFreqWavelen = oldContextLen / lowFreqFactor;
136
+ const highFreqWavelen = oldContextLen / highFreqFactor;
137
+
138
+ let freqs = baseFreqs(dims, base, Dtype.int32);
139
+ const wavelens = ops.mulScalar(freqs, 2 * Math.PI);
140
+
141
+ // freqs = where(wavelens > low_freq_wavelen, freqs * factor, freqs)
142
+ const lfw = ops.scalarLike(lowFreqWavelen, wavelens);
143
+ const gtLow = ops.less(lfw, wavelens);
144
+ const freqsTimesFactor = ops.mulScalar(freqs, factor);
145
+ const freqs1 = ops.where(gtLow, freqsTimesFactor, freqs);
146
+ for (const a of [gtLow, freqsTimesFactor, freqs]) a.dispose();
147
+ freqs = freqs1;
148
+
149
+ // is_medium = (wavelens > high_freq_wavelen) & (wavelens < low_freq_wavelen)
150
+ const hfw = ops.scalarLike(highFreqWavelen, wavelens);
151
+ const gtHigh = ops.less(hfw, wavelens);
152
+ const ltLow = ops.less(wavelens, lfw);
153
+ const isMedium = ops.logicalAnd(gtHigh, ltLow);
154
+ for (const a of [hfw, lfw, gtHigh, ltLow]) a.dispose();
155
+
156
+ // smooth_factors = (old_context_len / wavelens - low) / (high - low)
157
+ const oldScalar = ops.scalarLike(oldContextLen, wavelens);
158
+ const oldOverWav = ops.div(oldScalar, wavelens);
159
+ oldScalar.dispose();
160
+ wavelens.dispose();
161
+ const lowScalar = ops.scalarLike(lowFreqFactor, oldOverWav);
162
+ const numArr = ops.sub(oldOverWav, lowScalar);
163
+ oldOverWav.dispose();
164
+ lowScalar.dispose();
165
+ const denScalar = ops.scalarLike(highFreqFactor - lowFreqFactor, numArr);
166
+ const smooth = ops.div(numArr, denScalar);
167
+ numArr.dispose();
168
+ denScalar.dispose();
169
+
170
+ // smooth_freqs = freqs / ((1 - smooth) / factor + smooth)
171
+ const one = ops.scalarLike(1, smooth);
172
+ const oneMinus = ops.sub(one, smooth);
173
+ one.dispose();
174
+ const factorScalar = ops.scalarLike(factor, oneMinus);
175
+ const scaledDown = ops.div(oneMinus, factorScalar);
176
+ oneMinus.dispose();
177
+ factorScalar.dispose();
178
+ const denom = ops.add(scaledDown, smooth);
179
+ scaledDown.dispose();
180
+ smooth.dispose();
181
+ const smoothFreqs = ops.div(freqs, denom);
182
+ denom.dispose();
183
+
184
+ const out = ops.where(isMedium, smoothFreqs, freqs);
185
+ for (const a of [isMedium, smoothFreqs, freqs]) a.dispose();
186
+ return out;
187
+ }
188
+
189
+ /** YarnRoPE (rope_utils.py:128-181, verbatim): returns [freqs, mscale]. */
190
+ function yarnFreqs(
191
+ dims: number,
192
+ base: number,
193
+ scalingFactor: number,
194
+ originalMaxPositionEmbeddings: number,
195
+ betaFast: number,
196
+ betaSlow: number,
197
+ mscale: number,
198
+ mscaleAllDim: number,
199
+ ): [MlxArray, number] {
200
+ const findCorrectionDim = (numRotations: number): number =>
201
+ (dims * Math.log(originalMaxPositionEmbeddings / (numRotations * 2 * Math.PI))) /
202
+ (2 * Math.log(base));
203
+ let low = Math.floor(findCorrectionDim(betaFast));
204
+ let high = Math.ceil(findCorrectionDim(betaSlow));
205
+ low = Math.max(low, 0);
206
+ high = Math.min(high, dims - 1);
207
+ const getMscale = (scale: number, m: number): number =>
208
+ scale <= 1 ? 1.0 : 0.1 * m * Math.log(scale) + 1.0;
209
+ const outMscale =
210
+ getMscale(scalingFactor, mscale) / getMscale(scalingFactor, mscaleAllDim);
211
+
212
+ const freqExtra = baseFreqs(dims, base, Dtype.float32);
213
+ const freqInter = ops.mulScalar(freqExtra, scalingFactor);
214
+
215
+ // freq_mask = 1 - linear_ramp_mask(low, high, dims // 2)
216
+ let maxVal = high;
217
+ if (low === maxVal) maxVal += 0.001; // prevent singularity (oracle comment)
218
+ const arangeHalf = ops.arange(0, Math.floor(dims / 2), 1, Dtype.float32);
219
+ const minScalar = ops.scalarLike(low, arangeHalf);
220
+ const shifted = ops.sub(arangeHalf, minScalar);
221
+ arangeHalf.dispose();
222
+ minScalar.dispose();
223
+ const rangeScalar = ops.scalarLike(maxVal - low, shifted);
224
+ const linear = ops.div(shifted, rangeScalar);
225
+ shifted.dispose();
226
+ rangeScalar.dispose();
227
+ const lo = ops.scalarLike(0, linear);
228
+ const hi = ops.scalarLike(1, linear);
229
+ const ramp = ops.clip(linear, lo, hi);
230
+ for (const a of [linear, lo, hi]) a.dispose();
231
+ const one = ops.scalarLike(1, ramp);
232
+ const freqMask = ops.sub(one, ramp);
233
+ ramp.dispose();
234
+
235
+ // freqs = (inter * extra) / (inter * mask + extra * (1 - mask))
236
+ const numArr = ops.mul(freqInter, freqExtra);
237
+ const interMasked = ops.mul(freqInter, freqMask);
238
+ const oneMinusMask = ops.sub(one, freqMask);
239
+ one.dispose();
240
+ const extraMasked = ops.mul(freqExtra, oneMinusMask);
241
+ oneMinusMask.dispose();
242
+ const den = ops.add(interMasked, extraMasked);
243
+ const freqs = ops.div(numArr, den);
244
+ for (const a of [freqExtra, freqInter, freqMask, numArr, interMasked, extraMasked, den])
245
+ a.dispose();
246
+ return [freqs, outMscale];
247
+ }
248
+
249
+ /** SuScaledRoPE (rope_utils.py:10-71): [freqs, scale]. NOTE the oracle uses
250
+ * long_factor for ALL positions (short_factor is accepted and ignored). */
251
+ function suFreqsAndScale(
252
+ dims: number,
253
+ base: number,
254
+ maxPositionEmbeddings: number,
255
+ originalMaxPositionEmbeddings: number,
256
+ longFactor: number[] | number,
257
+ longMscale?: number,
258
+ ): [MlxArray, number] {
259
+ const freqs0 = baseFreqs(dims, base, Dtype.float32);
260
+ const lf = Array.isArray(longFactor)
261
+ ? MlxArray.fromFloat32(new Float32Array(longFactor), [longFactor.length])
262
+ : MlxArray.fromFloat32(new Float32Array([longFactor]), []);
263
+ const freqs = ops.mul(lf, freqs0);
264
+ lf.dispose();
265
+ freqs0.dispose();
266
+
267
+ const factor = maxPositionEmbeddings / originalMaxPositionEmbeddings;
268
+ const defaultScale =
269
+ factor <= 1.0
270
+ ? 1.0
271
+ : Math.sqrt(1 + Math.log(factor) / Math.log(originalMaxPositionEmbeddings));
272
+ // python: `long_mscale or default` — 0 is falsy there too.
273
+ const scale = longMscale ? longMscale : defaultScale;
274
+ return [freqs, scale];
275
+ }
276
+
277
+ /** ProportionalRoPE (rope_utils.py:199-232): rotate the first rotated_dims,
278
+ * ∞-freq (identity) padding for the rest. */
279
+ function proportionalFreqs(
280
+ dims: number, rotatedDims: number, base: number, factor: number,
281
+ ): MlxArray {
282
+ if (rotatedDims > dims) throw new Error("rotated_dims should be smaller than dims");
283
+ const ar = ops.arange(0, rotatedDims, 2, Dtype.float32);
284
+ const dimsScalar = MlxArray.fromFloat32(new Float32Array([dims]), []);
285
+ const exps = ops.div(ar, dimsScalar);
286
+ ar.dispose();
287
+ dimsScalar.dispose();
288
+ const baseScalar = ops.scalarLike(base, exps);
289
+ const powed = ops.pow(baseScalar, exps);
290
+ baseScalar.dispose();
291
+ exps.dispose();
292
+ const scaled = ops.mulScalar(powed, factor);
293
+ powed.dispose();
294
+ const padLen = Math.floor((dims - rotatedDims) / 2);
295
+ if (padLen === 0) return scaled;
296
+ const pad = MlxArray.fromFloat32(
297
+ new Float32Array(padLen).fill(Number.POSITIVE_INFINITY), [padLen],
298
+ );
299
+ const out = ops.concatAxis([scaled, pad], 0);
300
+ scaled.dispose();
301
+ pad.dispose();
302
+ return out;
303
+ }
304
+
305
+ /** What a scaling type builds its rope from. `scaling` is empty for the plain `default` type. */
306
+ interface RopeInit {
307
+ dims: number;
308
+ base: number;
309
+ traditional: boolean;
310
+ scaling: RopeScalingConfig;
311
+ maxPositionEmbeddings: number | null;
312
+ }
313
+
314
+ const yarnRope = ({ dims, base, traditional, scaling: sc }: RopeInit): UniversalRope => {
315
+ const [freqs, mscale] = yarnFreqs(
316
+ dims,
317
+ base,
318
+ requireNum(sc, "factor"),
319
+ num(sc.original_max_position_embeddings, 4096),
320
+ num(sc.beta_fast, 32),
321
+ num(sc.beta_slow, 1),
322
+ num(sc.mscale, 1),
323
+ num(sc.mscale_all_dim, 0),
324
+ );
325
+ // YarnRoPE scales x only when mscale != 1.0 (preScaleAlways=false).
326
+ return new UniversalRope(dims, traditional, null, 1.0, freqs, mscale, false);
327
+ };
328
+
329
+ /** The `rope_scaling` types initialize_rope understands, keyed by the config's type string (data,
330
+ * not a model family). A new scaling scheme is one entry here. */
331
+ const ropeScalers: Readonly<Record<string, (init: RopeInit) => UniversalRope>> = {
332
+ default: ({ dims, base, traditional }) => new UniversalRope(dims, traditional, base, 1.0, null, 1, false),
333
+ linear: ({ dims, base, traditional, scaling }) =>
334
+ new UniversalRope(dims, traditional, base, 1 / requireNum(scaling, "factor"), null, 1, false),
335
+ llama3: ({ dims, base, traditional, scaling }) =>
336
+ new UniversalRope(dims, traditional, null, 1.0, llama3Freqs(dims, base, scaling), 1, false),
337
+ yarn: yarnRope,
338
+ deepseek_yarn: yarnRope,
339
+ "telechat3-yarn": yarnRope,
340
+ longrope: ({ dims, base, maxPositionEmbeddings, scaling: sc }) => {
341
+ const [freqs, scale] = suFreqsAndScale(
342
+ dims,
343
+ base,
344
+ maxPositionEmbeddings ?? 131072,
345
+ requireNum(sc, "original_max_position_embeddings"),
346
+ (sc.long_factor as number[] | number | undefined) ?? 1.0,
347
+ );
348
+ // SuScaledRoPE hardcodes traditional=False and ALWAYS pre-scales.
349
+ return new UniversalRope(dims, false, null, 1.0, freqs, scale, true);
350
+ },
351
+ proportional: ({ dims, base, traditional, scaling: sc }) => {
352
+ const rotatedDims = Math.floor(dims * num(sc.partial_rotary_factor, 1.0));
353
+ const freqs = proportionalFreqs(dims, rotatedDims, base, num(sc.factor, 1.0));
354
+ return new UniversalRope(dims, traditional, null, 1.0, freqs, 1, false);
355
+ },
356
+ };
357
+
358
+ /** Port of rope_utils.initialize_rope — the shared entry every
359
+ * initialize_rope-style arch (llama, qwen2/3, olmo2, granite, …) uses. */
360
+ export function initializeRope(
361
+ dims: number,
362
+ base: number,
363
+ traditional: boolean,
364
+ scalingConfig: RopeScalingConfig | null,
365
+ maxPositionEmbeddings: number | null,
366
+ ): UniversalRope {
367
+ const ropeType = scalingConfig
368
+ ? String(scalingConfig.type ?? scalingConfig.rope_type ?? "default")
369
+ : "default";
370
+ const scaler = Object.hasOwn(ropeScalers, ropeType) ? ropeScalers[ropeType] : undefined;
371
+ if (!scaler) throw new Error(`Unsupported RoPE type ${ropeType}`);
372
+ return scaler({ dims, base, traditional, scaling: scalingConfig ?? {}, maxPositionEmbeddings });
373
+ }
374
+
375
+ /** SuScaledRoPE constructed the phi3.py way (NOT via initialize_rope):
376
+ * original_max_position_embeddings comes from the TOP-LEVEL config, and
377
+ * rope_dim = head_dim * partial_rotary_factor. */
378
+ export function phi3SuRope(
379
+ ropeDim: number,
380
+ base: number,
381
+ maxPositionEmbeddings: number,
382
+ originalMaxPositionEmbeddings: number,
383
+ longFactor: number[] | number,
384
+ ): UniversalRope {
385
+ const [freqs, scale] = suFreqsAndScale(
386
+ ropeDim, base, maxPositionEmbeddings, originalMaxPositionEmbeddings, longFactor,
387
+ );
388
+ return new UniversalRope(ropeDim, false, null, 1.0, freqs, scale, true);
389
+ }
@@ -0,0 +1,23 @@
1
+ import { MlxArray } from "@mlx-bun/mlx/array";
2
+ import { CompiledFunction } from "@mlx-bun/mlx/compile";
3
+ import * as ops from "@mlx-bun/mlx/ops";
4
+
5
+
6
+ /** Verbatim port of mlx_lm/models/activations.py:
7
+ * `@partial(mx.compile, shapeless=True) def swiglu(gate, x): return nn.silu(gate) * x`
8
+ * mx.compile fuses sigmoid + mul + mul into ONE kernel (mlx-lm's decode
9
+ * `CV2ISigmoid…Multiply`) instead of our three separate dispatches. Traced
10
+ * once, replayed thereafter for decode and prefill. */
11
+ let _swigluClosure: CompiledFunction | null = null;
12
+ export function compiledSwiglu(gate: MlxArray, up: MlxArray): MlxArray {
13
+ if (!_swigluClosure) {
14
+ _swigluClosure = new CompiledFunction((inputs) => {
15
+ const g = inputs[0]!, u = inputs[1]!; // nn.silu(gate) * x
16
+ const sig = ops.sigmoid(g);
17
+ const silu = ops.mul(g, sig); sig.dispose();
18
+ const out = ops.mul(silu, u); silu.dispose();
19
+ return [out];
20
+ });
21
+ }
22
+ return _swigluClosure.apply([gate, up])[0]!;
23
+ }
@@ -0,0 +1,52 @@
1
+ import type { MlxArray } from "@mlx-bun/mlx/array";
2
+ import * as ops from "@mlx-bun/mlx/ops";
3
+ import { downCodebookRow, downK3InterleavedCodebookRow } from "../kernels/trellis/down-codebook";
4
+ import type { TrellisLinear } from "./trellis-linear";
5
+
6
+ // Packed down-projection layers over a Qwen MLP's axis-0 Trellis codes at one
7
+ // row, with the scatter kernels' output bits (trellisScatter; kernels/trellis/index.ts)
8
+ // through a threadgroup codebook. Each layer runs one kernel for one code layout
9
+ // (row-major 2- or 4-bit codes, or the 3-bit block interleave) and checks the
10
+ // projection at construction. forward(x) keeps x's leading dimensions.
11
+
12
+ function project(lin: TrellisLinear, x: MlxArray, kernel: (x2: MlxArray) => MlxArray): MlxArray {
13
+ const g = lin.geometry, lead = x.shape.slice(0, -1);
14
+ using x2 = ops.reshape(x, [lead.reduce((a, b) => a * b, 1), g.inFeatures]);
15
+ using y = kernel(x2);
16
+ return ops.reshape(y, [...lead, g.outFeatures]);
17
+ }
18
+ function rowMajor(name: string, lin: TrellisLinear): void {
19
+ const g = lin.geometry;
20
+ if (g.axis !== 0 || g.blockInterleave || lin.codes.ndim !== 2 || (g.k === 3 && g.T === 256 && g.L <= 12))
21
+ throw new Error(`${name}: needs packed row-major axis-0 codes the balanced kernels do not decode (3-bit codes take the K3i layers)`);
22
+ }
23
+ function k3Interleaved(name: string, lin: TrellisLinear): void {
24
+ const g = lin.geometry;
25
+ if (g.axis !== 0 || g.blockInterleave !== 2 || g.k !== 3 || g.T !== 256 || g.L !== 12)
26
+ throw new Error(`${name}: needs 3-bit block-interleaved axis-0 codes`);
27
+ }
28
+
29
+ /** One activation row; row-major 2- or 4-bit codes at T 256, decoding through a threadgroup codebook with
30
+ * word-aligned lanes (kernels/trellis/down-codebook.ts): trellisScatter's single-row output bit for bit. */
31
+ export class CodebookDownRow {
32
+ constructor(readonly down: TrellisLinear) {
33
+ rowMajor("CodebookDownRow", down);
34
+ const g = down.geometry;
35
+ if ((g.k !== 2 && g.k !== 4) || g.T !== 256 || g.L > 12) throw new Error("CodebookDownRow: needs 2- or 4-bit codes at T 256, L <= 12");
36
+ }
37
+
38
+ forward(x: MlxArray): MlxArray {
39
+ const { codes, scales, geometry } = this.down;
40
+ return this.down.delta.forward(x, project(this.down, x, x2 => downCodebookRow(x2, codes, scales, geometry)));
41
+ }
42
+ }
43
+
44
+ /** One activation row; 3-bit block-interleaved codes, the same way: trellisScatter's single-row output bit for bit. */
45
+ export class CodebookDownK3iRow {
46
+ constructor(readonly down: TrellisLinear) { k3Interleaved("CodebookDownK3iRow", down); }
47
+
48
+ forward(x: MlxArray): MlxArray {
49
+ const { codes, scales, geometry } = this.down;
50
+ return this.down.delta.forward(x, project(this.down, x, x2 => downK3InterleavedCodebookRow(x2, codes, scales, geometry)));
51
+ }
52
+ }
@@ -0,0 +1,42 @@
1
+ import type { MlxArray } from "@mlx-bun/mlx/array";
2
+ import { gateUpCodebookRow } from "../kernels/trellis/gate-up-codebook";
3
+ import type { MixedGateUpTail } from "../kernels/trellis/mixed-gate-up";
4
+ import type { TrellisLinear } from "./trellis-linear";
5
+
6
+ // The fused gate/up/SwiGLU layer over a Qwen MLP's axis-1 Trellis gate and up
7
+ // projections at one row, decoding through a threadgroup codebook with the reduce
8
+ // kernels' output bits (kernels/trellis/gate-up-codebook.ts). It runs one kernel
9
+ // and takes everything that kernel varies on at construction.
10
+
11
+ /** `sameWidth` null: either. */
12
+ function sameAxis1(name: string, gate: TrellisLinear, up: TrellisLinear, sameWidth: boolean | null): void {
13
+ const a = gate.geometry, b = up.geometry;
14
+ if (a.axis !== 1 || b.axis !== 1 || a.rows !== b.rows || a.cols !== b.cols ||
15
+ a.T !== b.T || a.L !== b.L || (sameWidth !== null && (a.k === b.k) !== sameWidth))
16
+ throw new Error(`${name}: gate/up need packed axis-1 codes of one geometry${sameWidth === null ? ""
17
+ : `, ${sameWidth ? "the same" : "different"} widths`}`);
18
+ if (gate.variant !== up.variant) throw new Error(`${name}: gate and up decode with different variants`);
19
+ }
20
+
21
+ /** One activation row; gate and up at the same or different widths, decoding through a threadgroup codebook
22
+ * (kernels/trellis/gate-up-codebook.ts) with fusedGateUpSwiglu's (same widths) and fusedGateUpSwigluMixed's (different
23
+ * widths) output bits. `mixedTail` is the SwiGLU arithmetic where the widths differ (fusedGateUpSwigluMixed's `tail`);
24
+ * same widths take the float32 sigmoid. */
25
+ export class CodebookGateUpRow {
26
+ constructor(readonly gate: TrellisLinear, readonly up: TrellisLinear, readonly mixedTail: MixedGateUpTail) {
27
+ sameAxis1("CodebookGateUpRow", gate, up, null);
28
+ if (gate.geometry.L > 12) throw new Error("CodebookGateUpRow: the codebook holds at most 2^12 states");
29
+ }
30
+
31
+ /** `x` [.., in] (borrowed, one row) to an owned [.., rows]. */
32
+ forward(x: MlxArray): MlxArray { return gateUpCodebookRow(x, this.gate, this.up, this.mixedTail); }
33
+ }
34
+
35
+ /** The mixed-width split activation tail, fixed for written two-argument bindings. */
36
+ export class CodebookSplitGateUpRow {
37
+ constructor(readonly gate:TrellisLinear,readonly up:TrellisLinear) {
38
+ sameAxis1("CodebookSplitGateUpRow",gate,up,null);
39
+ if (gate.geometry.L>12) throw new Error("CodebookSplitGateUpRow: the codebook holds at most 2^12 states");
40
+ }
41
+ forward(x:MlxArray):MlxArray {return gateUpCodebookRow(x,this.gate,this.up,"split");}
42
+ }
@@ -0,0 +1,117 @@
1
+ import type { MlxArray } from "@mlx-bun/mlx/array";
2
+ import * as ops from "@mlx-bun/mlx/ops";
3
+ import type { TrellisGeometry } from "../kernels/trellis/geometry";
4
+ import { downFactoredRow, downFactoredRows } from "../kernels/trellis/down-factored";
5
+ import { downK3InterleavedFactoredRow, downK3InterleavedFactoredRows } from "../kernels/trellis/down-k3-interleaved-factored";
6
+ import { downK3InterleavedMma, downMma } from "../kernels/trellis/down-mma";
7
+ import {
8
+ DOWN_ONE_BLOCK, downK3InterleavedMmaWide, downK3InterleavedMmaWidePass, downMmaWide, downMmaWidePass,
9
+ } from "../kernels/trellis/down-mma-wide";
10
+ import { TrellisLinear } from "./trellis-linear";
11
+
12
+ // Down-projection layers over a Qwen MLP's axis-0 Trellis codes. Each layer
13
+ // runs one kernel for one row form and one code layout (row-major, or the
14
+ // 3-bit block interleave); the owning graph picks the layer for the request's
15
+ // row count and the weights' layout. forward(x) keeps x's leading dimensions.
16
+
17
+ type Kernel = (x2: MlxArray, codes: MlxArray, scales: MlxArray, g: TrellisGeometry) => MlxArray;
18
+
19
+ function project(lin: TrellisLinear, kernel: Kernel, x: MlxArray): MlxArray {
20
+ const g = lin.geometry, lead = x.shape.slice(0, -1);
21
+ using x2 = ops.reshape(x, [lead.reduce((a, b) => a * b, 1), g.inFeatures]);
22
+ using y = kernel(x2, lin.codes, lin.scales, g);
23
+ return lin.delta.forward(x, ops.reshape(y, [...lead, g.outFeatures]));
24
+ }
25
+ // The any-row codebook down kernel in one block of 8 rows per pass, fixed for the 1..8-row layers.
26
+ const oneBlockDown: Kernel = (x2, codes, scales, g) => downMmaWidePass(x2, codes, scales, g, DOWN_ONE_BLOCK);
27
+ const oneBlockDownK3i: Kernel = (x2, codes, scales, g) => downK3InterleavedMmaWidePass(x2, codes, scales, g, DOWN_ONE_BLOCK);
28
+
29
+ function rowMajor(name: string, lin: TrellisLinear): void {
30
+ const g = lin.geometry;
31
+ if (g.axis !== 0 || g.blockInterleave || lin.codes.ndim !== 2) throw new Error(`${name}: needs packed row-major axis-0 codes`);
32
+ }
33
+ function k3Interleaved(name: string, lin: TrellisLinear): void {
34
+ const g = lin.geometry;
35
+ if (g.axis !== 0 || g.blockInterleave !== 2 || g.k !== 3 || g.T !== 256 || g.L !== 12)
36
+ throw new Error(`${name}: needs 3-bit block-interleaved axis-0 codes`);
37
+ }
38
+
39
+ /** One activation row; row-major codes. */
40
+ export class FactoredDownRow {
41
+ constructor(readonly down: TrellisLinear) { rowMajor("FactoredDownRow", down); }
42
+ forward(x: MlxArray): MlxArray { return project(this.down, downFactoredRow, x); }
43
+ }
44
+
45
+ /** 2..4 activation rows; row-major codes. */
46
+ export class FactoredDownRows {
47
+ constructor(readonly down: TrellisLinear) { rowMajor("FactoredDownRows", down); }
48
+ forward(x: MlxArray): MlxArray { return project(this.down, downFactoredRows, x); }
49
+ }
50
+
51
+ /** One activation row; 3-bit block-interleaved codes. */
52
+ export class FactoredDownK3iRow {
53
+ constructor(readonly down: TrellisLinear) { k3Interleaved("FactoredDownK3iRow", down); }
54
+ forward(x: MlxArray): MlxArray { return project(this.down, downK3InterleavedFactoredRow, x); }
55
+ }
56
+
57
+ /** 2..4 activation rows; 3-bit block-interleaved codes. */
58
+ export class FactoredDownK3iRows {
59
+ constructor(readonly down: TrellisLinear) { k3Interleaved("FactoredDownK3iRows", down); }
60
+ forward(x: MlxArray): MlxArray { return project(this.down, downK3InterleavedFactoredRows, x); }
61
+ }
62
+
63
+ /** 1..8 activation rows on the simdgroup matrix unit; row-major codes. */
64
+ export class MmaDown {
65
+ constructor(readonly down: TrellisLinear) {
66
+ rowMajor("MmaDown", down);
67
+ if (down.geometry.T !== 256 || down.geometry.L > 12) throw new Error("MmaDown: needs T 256, L <= 12");
68
+ }
69
+ forward(x: MlxArray): MlxArray { return project(this.down, downMma, x); }
70
+ }
71
+
72
+ /** 1..8 activation rows on the simdgroup matrix unit; 3-bit block-interleaved codes. */
73
+ export class MmaDownK3i {
74
+ constructor(readonly down: TrellisLinear) { k3Interleaved("MmaDownK3i", down); }
75
+ forward(x: MlxArray): MlxArray { return project(this.down, downK3InterleavedMma, x); }
76
+ }
77
+
78
+ /** Any number of activation rows on the simdgroup matrix unit through a threadgroup codebook, each decoded fragment
79
+ * feeding up to three 8-row blocks (MmaDown's bits per block); row-major codes. */
80
+ export class MmaDownWide {
81
+ constructor(readonly down: TrellisLinear) {
82
+ rowMajor("MmaDownWide", down);
83
+ const g = down.geometry;
84
+ if (g.T !== 256 || g.L > 12 || g.rows % 8 !== 0) throw new Error("MmaDownWide: needs T 256, L <= 12, rows % 8");
85
+ }
86
+ forward(x: MlxArray): MlxArray { return project(this.down, downMmaWide, x); }
87
+ }
88
+
89
+ /** Any number of activation rows on the simdgroup matrix unit through a threadgroup codebook (MmaDownK3i's bits per
90
+ * block of 8); 3-bit block-interleaved codes. */
91
+ export class MmaDownWideK3i {
92
+ constructor(readonly down: TrellisLinear) {
93
+ k3Interleaved("MmaDownWideK3i", down);
94
+ if (down.geometry.rows % 8 !== 0) throw new Error("MmaDownWideK3i: needs rows % 8");
95
+ }
96
+ forward(x: MlxArray): MlxArray { return project(this.down, downK3InterleavedMmaWide, x); }
97
+ }
98
+
99
+ /** 1..8 activation rows on the simdgroup matrix unit through a threadgroup codebook, one block of 8 rows per pass (the
100
+ * any-row kernel's one-block pass; MmaDown's bits); row-major codes. */
101
+ export class CodebookMmaDown {
102
+ constructor(readonly down: TrellisLinear) {
103
+ rowMajor("CodebookMmaDown", down);
104
+ const g = down.geometry;
105
+ if (g.T !== 256 || g.L > 12 || g.rows % 8 !== 0) throw new Error("CodebookMmaDown: needs T 256, L <= 12, rows % 8");
106
+ }
107
+ forward(x: MlxArray): MlxArray { return project(this.down, oneBlockDown, x); }
108
+ }
109
+
110
+ /** CodebookMmaDown for 3-bit block-interleaved codes (MmaDownK3i's bits). */
111
+ export class CodebookMmaDownK3i {
112
+ constructor(readonly down: TrellisLinear) {
113
+ k3Interleaved("CodebookMmaDownK3i", down);
114
+ if (down.geometry.rows % 8 !== 0) throw new Error("CodebookMmaDownK3i: needs rows % 8");
115
+ }
116
+ forward(x: MlxArray): MlxArray { return project(this.down, oneBlockDownK3i, x); }
117
+ }