@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,113 @@
1
+ import type { MlxArray } from '@mlx-bun/mlx/array';
2
+ import type { Cache } from './cache';
3
+
4
+ /** Prepared embeddings for vision/audio prompts. Qualified models consume
5
+ * this through the media prompt input the graph binds (`bindMediaInput`).
6
+ * Token-only prefix caching remains disabled for media. */
7
+ export type Vision = {
8
+ /** Producer identity includes all media and preceding rendered tokens. */
9
+ prefixIdentity?: string;
10
+ embeddings: MlxArray;
11
+ /** bool [L] image-token mask for the bidirectional attention overlay.
12
+ * Absent when the prompt carries ANY audio — audio(-containing) prompts
13
+ * run fully causal (`02d723a:docs/design/generic-model-support.md` §6.6). */
14
+ imageMask?: MlxArray;
15
+ /** bool [L] union multimodal soft-token mask (image | audio) for
16
+ * per-layer-input id zeroing. Absent on the legacy vision-only shape,
17
+ * where zeroing falls back to imageMask. */
18
+ multimodalMask?: MlxArray;
19
+ /** Qwen3.5/3.8 vision: the request's mRoPE positions + decode delta,
20
+ * owned by the media prompt input the graph binds. */
21
+ mrope?: import("./positions").MropeRequestState;
22
+ };
23
+
24
+ /** Returns unscaled text embeddings; the caller owns the returned tensor. */
25
+ export interface TextEmbeddingModel {
26
+ readonly embed: { encode(ids: MlxArray): MlxArray };
27
+ }
28
+ export interface AudioEncoder {
29
+ readonly cacheIdentity?: string;
30
+ readonly embedScale: number;
31
+ features(mel: Float32Array, frames: number, preDivide?: boolean): MlxArray;
32
+ }
33
+
34
+ /** Prepared native input with an indivisible prefill. The preparation owner
35
+ * retains its tensors; the graph's binding returns an owned final hidden row.
36
+ * Decode, sampling and row retirement use the ordinary execution group. */
37
+ export interface MlxPromptInput {
38
+ /** The vision prefill phase: one sequence's prompt from position `start`,
39
+ * the prepared embeddings at 0 and its token ids after a reused prefix, at
40
+ * the request's positions. `phase` and `width` are the scheduler's: the
41
+ * planner's name for the piece (one position after a reused prefix appends
42
+ * as a decode, more as a tail) and the class of its rows. Returns the hidden
43
+ * of the prompt's last position. */
44
+ prefill(ids: MlxArray, caches: Cache[], start: number, phase: "tail" | "decode", width: number): MlxArray;
45
+ readonly decodeState?: MlxDecodeState;
46
+ }
47
+
48
+ /** Additional graph-owned decode state. Equal keys declare compatible row
49
+ * state; the backend supplies the current row order after joins/retirement. */
50
+ export interface MlxDecodeState {
51
+ readonly key: string;
52
+ /** One new token per row at the positions each row's state names; `width`
53
+ * is the class of the rows, named by the scheduler. */
54
+ decode(ids: MlxArray, caches: Cache[], rows: readonly MlxDecodeState[], width: number): MlxArray;
55
+ }
56
+
57
+ /** Common contract for image encoders: preprocess image bytes into an
58
+ * encoder-specific representation, then turn it into language-space soft
59
+ * tokens [1, softTokens, hidden] (pre-divided by embed_scale). Encoders own
60
+ * their preprocessing. */
61
+ export interface VisionEncoder<P extends { softTokens: number } = { softTokens: number }> {
62
+ readonly cacheIdentity?: string;
63
+ preprocess(bytes: Uint8Array): Promise<P>;
64
+ features(pre: P): MlxArray;
65
+ dispose?(): void;
66
+ }
67
+
68
+ /** Raw image pixels that a denoising method takes as its own prefill input. */
69
+ export interface PixelInput {
70
+ /** Pixels are owned by the caller once returned. */
71
+ preprocess(bytes: Uint8Array): Promise<{ pixels: MlxArray; softTokens: number }>;
72
+ /** Insert `softTokens` image placeholders (one image) into rendered prompt ids. */
73
+ spliceTokens(rawIds: number[], softTokens: number, tokenIds: { image: number; boi: number; eoi: number }): number[];
74
+ }
75
+
76
+ /** Lazy image/audio encoders loaded from a checkpoint's sidecars; null where
77
+ * the checkpoint ships none. Loading is deferred until a request needs it. */
78
+ export interface MediaEncoders {
79
+ vision: (() => VisionEncoder) | null;
80
+ audio: (() => AudioEncoder & { dispose?(): void }) | null;
81
+ }
82
+
83
+ /** Facts about a checkpoint's files that only the caller's storage can answer. */
84
+ export interface MediaSidecarProbes {
85
+ /** Whether the sidecar at `path` ships the audio encoder's tensors (header-only read). */
86
+ shipsAudioTower(path: string): boolean;
87
+ }
88
+
89
+
90
+ /** Fixed embedding prefill over prepared image/audio embeddings. */
91
+ export type MlxEmbeddingsForward = (embeddings: MlxArray, state: Cache[], imageMask: MlxArray | null,
92
+ ids: MlxArray, multimodalMask: MlxArray | null) => MlxArray;
93
+ export interface MlxEmbeddingsRange {
94
+ readonly from: number;
95
+ readonly to: number;
96
+ readonly operation: MlxEmbeddingsForward;
97
+ }
98
+
99
+ /** Fixed token forward at request-owned rotary positions. */
100
+ export type MlxPositionedForward = (ids: MlxArray, state: Cache[], positions: MlxArray) => MlxArray;
101
+ export interface MlxPositionedRange {
102
+ readonly from: number;
103
+ readonly to: number;
104
+ readonly operation: MlxPositionedForward;
105
+ }
106
+
107
+ /** Fixed embedding prefill at request-owned rotary positions. */
108
+ export type MlxPositionedEmbeddingsForward = (embeddings: MlxArray, state: Cache[], positions: MlxArray) => MlxArray;
109
+ export interface MlxPositionedEmbeddingsRange {
110
+ readonly from: number;
111
+ readonly to: number;
112
+ readonly operation: MlxPositionedEmbeddingsForward;
113
+ }
@@ -0,0 +1,16 @@
1
+ import type { MlxArray } from "@mlx-bun/mlx/array";
2
+
3
+ export interface MropeRequestState {
4
+ /** Full-grid positions for the prompt, one Int32Array per t/h/w stream. */
5
+ positions: [Int32Array, Int32Array, Int32Array];
6
+ /** (max position + 1) - promptLength; decode positions = offset + delta. */
7
+ delta: number;
8
+ }
9
+
10
+ export interface MropeForwardState {
11
+ /** Effective positions [3, B, L] int32 for the current forward window. */
12
+ posIds: MlxArray;
13
+ /** Borrowed model-owned f32 inv_freq (mropeInvFreq) — not disposed here. */
14
+ invFreq: MlxArray;
15
+ rotaryDims: number;
16
+ }
@@ -0,0 +1,2 @@
1
+ /** Authored exact positive row entries and, only when explicitly written, a default operation. */
2
+ export type MlxRowTable<Operation> = Readonly<Partial<Record<number, Operation>> & { readonly default?: Operation }>;
@@ -0,0 +1,103 @@
1
+ import type { MlxArray } from "@mlx-bun/mlx/array";
2
+ import type * as ops from "@mlx-bun/mlx/ops";
3
+ import type { SharedKv } from "./cache";
4
+
5
+ /** The quantized LM head and final-logit softcap the fused linear-CE heads
6
+ * read. The head is not a LoRA target, so the base weights are authoritative. */
7
+ export interface HeadQuant {
8
+ w: MlxArray; scales: MlxArray; biases: MlxArray | null;
9
+ spec: ops.QuantSpec; softcap: number | null;
10
+ }
11
+
12
+ /** Layout of a prefix-shared concat [prompt(P); chosen(Rc); rejected(Rr)]. */
13
+ export interface PrefixLayout { P: number; Rc: number; Rr: number }
14
+
15
+ /** A LoRA leaf pair as the trainer holds it (`LoraWeights`). */
16
+ export interface LoraLeaves { a: MlxArray; b: MlxArray; scale: number; rank: number }
17
+
18
+ /** One sequence streamed through the layer stack in segments. Borrows the ids
19
+ * it began with; owns its caches, masks and per-layer inputs until `dispose`. */
20
+ export interface SegmentedPass {
21
+ /** The input embeddings [1, T, hidden] (the first segment boundary). The
22
+ * caller owns and disposes it. */
23
+ readonly input: MlxArray;
24
+ /** Layers `[lo, hi)` over `h`, returning the residual stream after layer
25
+ * hi-1 (no final norm) and the fetched K/V of the reused donors in the range.
26
+ * `h` is never disposed; `donorKvIn` holds earlier segments' donor K/V
27
+ * (caller-owned). The caller owns and disposes what comes back. */
28
+ runRange(h: MlxArray, lo: number, hi: number, donorKvIn: Map<number, SharedKv>):
29
+ { h: MlxArray; donorKvOut: Map<number, SharedKv> };
30
+ /** Release the pass's caches and masks. */
31
+ dispose(): void;
32
+ }
33
+
34
+ /** Backward that streams a sequence layer-segment by layer-segment. The driver
35
+ * owns the autograd (per-segment vjps over detached boundaries); the graph
36
+ * owns how a range of its layers runs and what crosses segment boundaries. */
37
+ export interface SegmentedTraining {
38
+ readonly layerCount: number;
39
+ /** K/V a layer reuses from an earlier layer of the same forward.
40
+ * `donorOf[i]` is the layer whose fetched K/V layer `i` consumes, or null
41
+ * when `i` attends its own; `reusedDonors` are the layers others consume,
42
+ * whose K/V must cross segment boundaries. Both are empty/null for a graph
43
+ * without KV sharing. */
44
+ readonly sharedKv: { readonly reusedDonors: ReadonlySet<number>; readonly donorOf: readonly (number | null)[] };
45
+ /** The final norm applied to the last boundary before the LM head. */
46
+ finalNorm(h: MlxArray): MlxArray;
47
+ /** Begin one pass over `ids` [1, T]. With a `prefix` layout the pass ropes and
48
+ * masks the prefix-shared concat (only for a graph that also declares
49
+ * `prefixShared`); the pass's caches own the layout (`TrainingAttentionCache.ropePositions`). */
50
+ begin(ids: MlxArray, prefix?: PrefixLayout): SegmentedPass;
51
+ }
52
+
53
+ /** One forward over a prefix-shared concat instead of two [prompt; response]
54
+ * forwards: block-sparse mask plus block-wise rope, bit-exact with the pair. */
55
+ export interface PrefixSharedTraining {
56
+ /** Post-final-norm hidden [1, T, hidden] of the concat `ids` under `layout`.
57
+ * Borrows `ids`; the caller owns the result. */
58
+ prefixSharedHidden(ids: MlxArray, layout: PrefixLayout): MlxArray;
59
+ }
60
+
61
+ /** A gradient-checkpointed run of one training loop. */
62
+ export interface GradCheckpointRun {
63
+ /** Free the checkpoints the last backward held (after its grads are eval'd). */
64
+ releaseStep(): void;
65
+ /** Forward-only evaluation: switch checkpointing off / back on. */
66
+ suspend(): void;
67
+ resume(): void;
68
+ /** Switch checkpointing off and free everything it holds. */
69
+ end(): void;
70
+ }
71
+
72
+ /** Recompute layer activations in the backward pass (numerically identical to
73
+ * off: a memory-for-compute trade). */
74
+ export interface GradCheckpointTraining {
75
+ /** Enable for the adapter's targets; `splitMlp` also checkpoints each layer's
76
+ * attention and MLP sub-blocks separately. */
77
+ enable(targets: readonly { modulePath: string; lw: LoraLeaves }[], splitMlp: boolean): GradCheckpointRun;
78
+ }
79
+
80
+ /** Whether the hand-rolled flash kernel may serve the training attention
81
+ * (`MLX_BUN_TRAIN_ATTN=flash`). A refusal states why. */
82
+ export type FlashTrainingAttention = { readonly supported: true } | { readonly supported: false; readonly reason: string };
83
+
84
+ /** The denoising objective of a `method: "denoising"` graph. */
85
+ export interface DenoisingTraining {
86
+ readonly vocabSize: number;
87
+ /** LoRA module path of each decoder layer (`<path>.self_attn.q_proj`, ...). */
88
+ readonly layerModulePaths: readonly string[];
89
+ /** Logits [1, L, vocab] (float32) of denoising `canvas` [1, L] given the prompt. */
90
+ canvasLogits(promptIds: number[], canvas: MlxArray): MlxArray;
91
+ }
92
+
93
+ /** What the trainer consumes from a graph. A graph declares only the parts it
94
+ * implements; the trainer names the missing declaration when it needs one. */
95
+ export interface TrainableGraph {
96
+ /** The quantized LM head for fused/flash linear-CE heads. */
97
+ lmHead?(): HeadQuant;
98
+ readonly flashAttention?: FlashTrainingAttention;
99
+ readonly segmented?: SegmentedTraining;
100
+ readonly prefixShared?: PrefixSharedTraining;
101
+ readonly gradCheckpoint?: GradCheckpointTraining;
102
+ readonly denoising?: DenoisingTraining;
103
+ }
@@ -0,0 +1,96 @@
1
+ import type { MlxArray } from "@mlx-bun/mlx/array";
2
+ import type { Dtype } from "@mlx-bun/mlx/ffi";
3
+
4
+ /** Encoder/decoder geometry a speech graph reads from its checkpoint. */
5
+ export interface WhisperDims {
6
+ nMels: number;
7
+ nAudioCtx: number;
8
+ nAudioState: number;
9
+ nAudioHead: number;
10
+ nAudioLayer: number;
11
+ nVocab: number;
12
+ nTextCtx: number;
13
+ nTextState: number;
14
+ nTextHead: number;
15
+ nTextLayer: number;
16
+ }
17
+
18
+ /** Decoder state one decode owns (self-attention K/V and the cross K/V from the encoder output).
19
+ * The graph that made it is the only one that reads it; the transcription loop only advances,
20
+ * reorders and releases it. */
21
+ export interface WhisperDecoderCache {
22
+ /** Tokens already in the self-attention cache. */
23
+ readonly offset: number;
24
+ /** Beam reorder: keep rows `indices` (take along the batch axis). */
25
+ rearrange(indices: number[]): void;
26
+ dispose(): void;
27
+ }
28
+
29
+ /** The optimized path's cache: its self-attention K/V arrays per layer, so a pipelined loop can
30
+ * schedule their evaluation with the step outputs. */
31
+ export interface WhisperFastCache extends WhisperDecoderCache {
32
+ readonly k: readonly MlxArray[];
33
+ readonly v: readonly MlxArray[];
34
+ }
35
+
36
+ /** Token filters the optimized decode steps apply on device. */
37
+ export interface FastFilterConfig {
38
+ nVocab: number;
39
+ eot: number;
40
+ timestampBegin: number;
41
+ noTimestamps: number;
42
+ /** Ids masked at every step (non-speech + task/special tokens). */
43
+ suppressIds: number[];
44
+ /** Ids masked at the first sampled position (blank + eot), or null. */
45
+ blankIds: number[] | null;
46
+ useTimestampRules: boolean;
47
+ maxInitialTimestampIndex: number | null;
48
+ }
49
+
50
+ /** The optimized execution path of a speech graph (temperature-0 decoding, beam search). Every step
51
+ * returns owned arrays. */
52
+ export interface WhisperFastPath {
53
+ makeCache(): WhisperFastCache;
54
+ /** `audioCtx` (Lab): encode only the first 2·audioCtx mel frames. */
55
+ encode(mel: MlxArray, audioCtx?: number | null): MlxArray;
56
+ /** Project the encoder output into every decoder layer's cross K/V. */
57
+ crossKv(features: MlxArray, cache: WhisperFastCache): void;
58
+ /** Multi-token prefill: fills the self-KV cache, returns logits [B, T, V]. */
59
+ prefill(tokens: MlxArray, cache: WhisperFastCache): MlxArray;
60
+ /** Pipelined greedy step over token and timestamp-state arrays. */
61
+ greedyStep(
62
+ st: { tok: MlxArray; lastTok: MlxArray; penultTok: MlxArray; lastTs: MlxArray },
63
+ cache: WhisperFastCache, cfg: FastFilterConfig,
64
+ ): { pre: MlxArray; next: MlxArray; lp: MlxArray; lastTs: MlxArray };
65
+ beamStep(
66
+ tokens: number[], cache: WhisperFastCache, cfg: FastFilterConfig, k: number,
67
+ state: { lastTok: number[]; penultTok: number[]; lastTs: number[] },
68
+ ): { pre: MlxArray; idx: MlxArray; vals: MlxArray };
69
+ /** One compiled decode step: pre-filter and filtered last-position logits [B, V] f32. */
70
+ step(
71
+ tokens: number[], cache: WhisperFastCache, cfg: FastFilterConfig,
72
+ state: { lastTok: number[]; penultTok: number[]; lastTs: number[]; atBegin: boolean },
73
+ ): { pre: MlxArray; filtered: MlxArray };
74
+ }
75
+
76
+ /** What the transcription engine needs of a speech-recognition graph: the faithful encoder/decoder,
77
+ * the optimized path, and the checkpoint facts window decoding and word timing read. The engine
78
+ * never names the class that implements it. */
79
+ export interface WhisperGraph {
80
+ readonly dims: WhisperDims;
81
+ /** The checkpoint's weight dtype (mel windows are cast to it). */
82
+ readonly dtype: Dtype;
83
+ readonly isMultilingual: boolean;
84
+ /** Cross-attention heads (layer, head) used for word timestamps. */
85
+ readonly alignmentHeads: [number, number][];
86
+ readonly fast: WhisperFastPath;
87
+ makeCache(): WhisperDecoderCache;
88
+ /** mel [B, 3000, n_mels] (weight dtype) → [B, 1500, D]. */
89
+ encode(mel: MlxArray): MlxArray;
90
+ /** tokens [B, T] int32 + audio features → logits [B, T, n_vocab] and, on request, the per-layer
91
+ * raw cross-attention qk. Advances `cache`. */
92
+ decode(
93
+ tokens: MlxArray, audioFeatures: MlxArray, cache: WhisperDecoderCache,
94
+ opts?: { wantCrossQk?: boolean },
95
+ ): { logits: MlxArray; crossQk: (MlxArray | null)[] };
96
+ }
@@ -0,0 +1,106 @@
1
+ /** The read kernels of a composition's affine-quantized caches. `tiled-causal`
2
+ * is OptiQ's rule: a window through the N-tiled fused port while the cache's own
3
+ * mask is plain causal (where the port takes the configuration), every other
4
+ * read through the unfused port. `unfused` is mlx-lm's port for every read.
5
+ * `--fused-sdpa on` composes the first and `off` the second; unset, a per-layer
6
+ * scheme (`--kv-quant config`) composes `tiled-causal` and a uniform one
7
+ * `unfused`, which keeps each scheme's oracle parity. */
8
+ export type AffineKernelChoice = "tiled-causal" | "unfused";
9
+
10
+ /** How a composition's attention caches store keys and values. A quantized
11
+ * scheme carries `quantizedKvStart` only when it is nonzero: storage stays
12
+ * bf16 until a sequence holds that many tokens, then converts in place. */
13
+ export type KvStorageScheme =
14
+ | { readonly kind: "bf16" }
15
+ /** Every attention layer, affine-quantized with one bit width and group size. */
16
+ | { readonly kind: "affine"; readonly bits: number; readonly groupSize: number; readonly quantizedKvStart?: number;
17
+ readonly kernels: AffineKernelChoice }
18
+ /** The layers listed (cache index), each with its own bit width and group size; the others stay bf16. */
19
+ | { readonly kind: "affine-layers"; readonly layers: readonly AffineKvLayer[]; readonly quantizedKvStart?: number;
20
+ readonly kernels: AffineKernelChoice }
21
+ /** Full-attention layers TurboQuant-encoded; sliding-window layers stay bf16. */
22
+ | { readonly kind: "turbo"; readonly kBits: number; readonly vBits: number; readonly quantizedKvStart?: number };
23
+
24
+ /** Full-attention keys and values held in pages (`--paged-kv`). */
25
+ export interface PagedKvComposition {
26
+ /** Positions per page. */
27
+ readonly blockSize: number;
28
+ /** The pages' read of at most eight queries without an array mask (decode,
29
+ * and prefill and verification windows that short): the direct Metal kernel
30
+ * over the blocks (Lab numerics) where true, otherwise the gathered blocks
31
+ * through the fused SDPA (the numerical control). Pages the kernel does not
32
+ * read (TurboQuant, affine widths that straddle a 32-bit word) read gathered.
33
+ * Pages the kernel reads have no compiled decode form (the kernel's
34
+ * partitions follow the context length): their composition resolves
35
+ * `compiledDecode` off. */
36
+ readonly direct: boolean;
37
+ }
38
+
39
+ export interface AffineKvLayer {
40
+ readonly layer: number;
41
+ readonly bits: number;
42
+ readonly groupSize: number;
43
+ }
44
+
45
+ /** The bf16 KV scheme: what a graph whose composition names no scheme stores. */
46
+ export const BF16_KV: KvStorageScheme = Object.freeze({ kind: "bf16" });
47
+
48
+ /** Drafted tokens per verify round: a fixed count (0 when the composition has
49
+ * no drafter), or adaptive, where the scheduler picks each round's count up to
50
+ * `max`. */
51
+ export type DraftDepth = number | { readonly adaptive: true; readonly max: number };
52
+
53
+ /** The facts that fix one served configuration, resolved once by the
54
+ * application before the loader builds the graph and consumed as data. Every
55
+ * field holds a resolved value; nothing here is "unset" or "auto". */
56
+ export interface Composition {
57
+ /** The GPU's architecture identifier as MLX reports it (for example `applegpu_g16s`). */
58
+ readonly device: string;
59
+ /** The storage and reads of every attention cache the graph's `makeCache` composes. */
60
+ readonly kv: KvStorageScheme;
61
+ /** Full-attention keys and values held in pages of `blockSize` positions
62
+ * (`--paged-kv`), or null. Every request's state takes the paged lego in place
63
+ * of the plain full-attention storage the graph composes; its pages store
64
+ * what `kv` names. */
65
+ readonly pagedKv: PagedKvComposition | null;
66
+ readonly draftDepth: DraftDepth;
67
+ /** The prefill chunk size, in prompt tokens, the composition is built for.
68
+ * The prefill planner may hand the graph fewer rows than this as a prompt's
69
+ * tail. Its per-prompt halving for a graph with a bounded prefill workspace
70
+ * is the planner's business and does not change what the composition built. */
71
+ readonly prefillChunkTokens: number;
72
+ /** The most rows one forward carries (`--batch`, mlx-lm's `--batch-size`). */
73
+ readonly maxRows: number;
74
+ /** A decode step whose live rows are all plain greedy samples them with one
75
+ * argmax over the batch instead of one sampler call per row (default on): the
76
+ * same per-row arithmetic in one graph. Off, every row samples alone. */
77
+ readonly vectorGreedySampling: boolean;
78
+ /** One forward carries a decode group and a prefill group where the graph
79
+ * declares mixed rows (default off). */
80
+ readonly mixedPrefill: boolean;
81
+ /** Prompt tokens one mixed forward carries beside its decode rows (default 256). */
82
+ readonly mixedTokenBudget: number;
83
+ /** A prompt's last token prefills alone, as the first one-position step
84
+ * (mlx-lm's convention, default on); off, the final chunk prefills whole and
85
+ * token zero samples from it. */
86
+ readonly prefillTailSplit: boolean;
87
+ /** Grammar-forced continuations enter the KV without one forward per token
88
+ * (jump-forward decoding, default off). */
89
+ readonly grammarJump: boolean;
90
+ /** Every speculative row drafts by argmax instead of the request sampler's
91
+ * coupled draw (default off). The draft moves acceptance and draft cost, not
92
+ * the output distribution (see `generation/speculative/draft-policy`). */
93
+ readonly greedyDraft: boolean;
94
+ }
95
+
96
+ /** The value of each composition fact a caller leaves unstated: what
97
+ * `resolveComposition` resolves, and what a graph built without a record runs. */
98
+ export const COMPOSITION_DEFAULTS = Object.freeze({
99
+ pagedKv: null,
100
+ vectorGreedySampling: true,
101
+ mixedPrefill: false,
102
+ mixedTokenBudget: 256,
103
+ prefillTailSplit: true,
104
+ grammarJump: false,
105
+ greedyDraft: false,
106
+ } satisfies Partial<Composition>);
@@ -0,0 +1,17 @@
1
+ import type { GraphDescriptor } from "./graph";
2
+
3
+ /** Denoising has canvas state and feedback, independent of AR token caches.
4
+ * Returned tensors/state are owned by the run. Inputs remain borrowed. A
5
+ * fused method may bypass this graph and implement InferenceMethod directly. */
6
+ export interface DenoisingGraph<Tensor, State> {
7
+ readonly descriptor: GraphDescriptor;
8
+ readonly vocabSize: number;
9
+ readonly canvasLength: number;
10
+ readonly embedScale: number;
11
+ prefill(promptIds: number[], vision?: Tensor): State;
12
+ extendPrefill(tokens: Tensor, state: State): void;
13
+ decoderLogits(canvas: Tensor, state: State, feedback: Tensor | null): Tensor;
14
+ dequantEmbedWeight(): Tensor;
15
+ softEmbeddings(logits: Tensor, weight: Tensor): Tensor;
16
+ closeState(state: State): void;
17
+ }
@@ -0,0 +1,79 @@
1
+ /** Request facts only. Native resources remain with the preparation owner. */
2
+ export interface ExecutionRequirements {
3
+ /** Prepared autoregressive media (embeddings for a media input binding).
4
+ * Denoising image pixels are that method's own prefill input, not media. */
5
+ readonly hasVision: boolean;
6
+ readonly hasPreparedPrefixIdentity?: boolean;
7
+ readonly hasAdapters: boolean;
8
+ readonly hasRepetitionPenalty: boolean;
9
+ readonly userSeed: boolean;
10
+ readonly hasLogitsExtras: boolean;
11
+ readonly hasGrammar: boolean;
12
+ readonly wantsLogprobs: boolean;
13
+ readonly hasDraft: boolean;
14
+ }
15
+
16
+ export interface ExecutionCapabilities {
17
+ readonly method: "autoregressive" | "denoising";
18
+ /** Executor coordination, not a model capability: the shared group drives
19
+ * each row's own grammar state (wait for its mask, advance it with the
20
+ * emitted token, stop the row when it terminates). The shared sampler masks
21
+ * any model's logits; grammar jump and speculation are qualified separately. */
22
+ readonly grammarBatch: boolean;
23
+ /** Prepared media can enter the ordinary shared execution group. */
24
+ readonly mediaBatch?: boolean;
25
+ readonly mediaPrefixCache?: boolean;
26
+ readonly checkpoints: boolean;
27
+ /** Bound ordinary driver can restore/capture this request configuration. */
28
+ readonly sharedCheckpoints?: boolean;
29
+ readonly speculativeLogprobs?: boolean;
30
+ /** The grouped provider supports the target's mounted adapter context. */
31
+ readonly sharedSpeculativeAdapters?: boolean;
32
+ /** Methods supplied by the model's shared execution binding. */
33
+ readonly groupedMethods?: readonly string[];
34
+ /** A shared method accepts request-owned grammar continuation proposals. */
35
+ readonly sharedGrammarProposals?: boolean;
36
+ /** An AR method appends grammar-accepted spans without speculative verification. */
37
+ readonly sharedGrammarJump?: boolean;
38
+ /** A grouped method can consume this request's strict known continuations. */
39
+ readonly sharedFill?: boolean;
40
+ /** A mounted provider can consume verified external continuations. */
41
+ readonly sharedSpeculativeEcho?: boolean;
42
+ /** The graph owns a compiled decode step. */
43
+ readonly compiledDecode?: boolean;
44
+ }
45
+
46
+ export interface ExecutionFeatures {
47
+ readonly fill: boolean;
48
+ readonly compiledDecode?: boolean;
49
+ readonly grammarJump?: boolean;
50
+ }
51
+
52
+ /** Why a request is refused or not served as asked. Refusals
53
+ * (`mechanism: "unsupported"`) name the capability the executor or graph lacks;
54
+ * the rest name a requested feature the request's other choices make incompatible. */
55
+ export type ExecutionReason =
56
+ | "media-batch-unsupported" | "grammar-batch-unsupported"
57
+ | "method-batch-unsupported"
58
+ | "draft-method-unsupported" | "logprobs-method-unsupported" | "repetition-penalty-method-unsupported"
59
+ | "logits-extras-method-unsupported" | "fill-method-unsupported"
60
+ | "draft-incompatible-with-request"
61
+ | "fill-incompatible-with-request" | "compiled-decode-unavailable-for-request"
62
+ | "grammar-jump-incompatible-with-request";
63
+
64
+ /** Selected once; consumers execute/report these values without reselecting. */
65
+ export interface ResolvedExecution {
66
+ /** Implementation-owned method ID. The built-in planner retains its known
67
+ * methods; another model may register a different set without editing this contract. */
68
+ readonly method: string;
69
+ /** `unsupported`: no shared executor serves this request; `reasons` names why. */
70
+ readonly mechanism: "continuous" | "unsupported";
71
+ readonly promptCache: boolean;
72
+ readonly checkpoint: boolean;
73
+ readonly fill: boolean;
74
+ /** Permission to attempt the bound compiled step, never a promise that
75
+ * every dynamic row/state shape supports replay. */
76
+ readonly compiledDecode: boolean;
77
+ readonly grammarJump: boolean;
78
+ readonly reasons: readonly ExecutionReason[];
79
+ }
@@ -0,0 +1,103 @@
1
+ /** Portable execution contracts. No transport, model, tensor, or runtime imports. */
2
+ export type CancelReason = "requested" | "consumer_closed" | "consumer_idle" | "engine_closed";
3
+
4
+ export interface Cancellation {
5
+ readonly reason: CancelReason | undefined;
6
+ /** Invoked immediately when already cancelled. Returns an idempotent unsubscribe. */
7
+ subscribe(listener: (reason: CancelReason) => void): () => void;
8
+ }
9
+
10
+ export interface TokenLogprobs {
11
+ /** Selected-token logprob, before sampler truncation. */
12
+ logprob?: number;
13
+ /** Top-k pairs, sorted by descending logprob. */
14
+ top?: { id: number; logprob: number }[];
15
+ }
16
+
17
+ export type GenerationEvent =
18
+ | { readonly type: "committed"; readonly sequence: number;
19
+ readonly tokenIds: readonly number[]; readonly logprobs?: readonly (TokenLogprobs | undefined)[] }
20
+ | { readonly type: "progress"; readonly completed: number; readonly total?: number };
21
+
22
+ /** Methods publish in order and await each publication before publishing again.
23
+ * Only committed tokens cross this boundary. Tentative canvases/drafts stay private. */
24
+ export interface GenerationOutput {
25
+ /** False requests a normal stop. The method must stop publishing and settle
26
+ * its metrics after releasing its private execution state. */
27
+ commit(tokenIds: readonly number[], logprobs?: readonly (TokenLogprobs | undefined)[]): Promise<void | false>;
28
+ progress(completed: number, total?: number): Promise<void>;
29
+ }
30
+
31
+ export interface MethodResult<Metrics> {
32
+ readonly finishReason: "stop" | "length";
33
+ readonly metrics: Metrics;
34
+ }
35
+
36
+ /** One attempt's private state, including any pending device work.
37
+ * close must await safe resource release, including on execute failure. */
38
+ export interface MethodRun<Metrics> {
39
+ execute(output: GenerationOutput, cancellation: Cancellation): Promise<MethodResult<Metrics>>;
40
+ close(): Promise<void>;
41
+ }
42
+
43
+ export interface InferenceMethod<Metrics> {
44
+ readonly id: string;
45
+ /** A rejected creation must release its own partial allocations. */
46
+ createRun(cancellation: Cancellation): Promise<MethodRun<Metrics>>;
47
+ }
48
+
49
+ export interface ExecutionPlan<Metrics> {
50
+ readonly id: string;
51
+ readonly outputTokenLimit: number;
52
+ readonly method: InferenceMethod<Metrics>;
53
+ }
54
+
55
+ export interface ExecutionPlanner<Request, Metrics> {
56
+ /** Planning selects a bound implementation; it does not allocate device state. */
57
+ plan(request: Request, cancellation: Cancellation): Promise<ExecutionPlan<Metrics>>;
58
+ }
59
+
60
+ export type GenerationOutcome<Metrics> =
61
+ | { readonly status: "completed"; readonly committedTokens: number;
62
+ readonly output?: Uint32Array; readonly result: MethodResult<Metrics> }
63
+ | { readonly status: "cancelled"; readonly committedTokens: number;
64
+ readonly output?: Uint32Array; readonly reason: CancelReason }
65
+ | { readonly status: "failed"; readonly committedTokens: number;
66
+ readonly output?: Uint32Array; readonly error: { readonly code: string; readonly message: string;
67
+ readonly cleanupError?: string } };
68
+
69
+ export type SessionState = "created" | "preparing" | "running" | "settling" | "terminal";
70
+
71
+ export type RunControl = {
72
+ /** collect returns token IDs; per-token logprobs require stream consumption. */
73
+ readonly output: "stream" | "collect";
74
+ readonly cancellation?: Cancellation;
75
+ } | {
76
+ /** Direct delivery for consumers that already own bounded output storage.
77
+ * The callback is awaited before execution continues; false is a normal
78
+ * token stop. Borrowed arrays are valid until the callback settles. */
79
+ readonly output: "callback";
80
+ readonly onTokens: GenerationOutput["commit"];
81
+ readonly cancellation?: Cancellation;
82
+ };
83
+
84
+ export interface GenerationSession<Metrics> {
85
+ readonly id: string;
86
+ readonly state: SessionState;
87
+ /** Single consumer. Stream mode starts on first next(); collect mode has no events. */
88
+ readonly events: AsyncIterable<GenerationEvent>;
89
+ /** Always resolves with one terminal outcome, after native resources are released. */
90
+ readonly result: Promise<GenerationOutcome<Metrics>>;
91
+ cancel(reason?: CancelReason): Promise<void>;
92
+ close(): Promise<void>;
93
+ }
94
+
95
+ export interface InferenceEngine<Request, Metrics> {
96
+ open(request: Request, control: RunControl): Promise<GenerationSession<Metrics>>;
97
+ close(): Promise<void>;
98
+ }
99
+
100
+ /** Injected host timer. The portable engine has no DOM/Node/Bun dependency. */
101
+ export interface Timer {
102
+ after(milliseconds: number, callback: () => void): () => void;
103
+ }