@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,447 @@
1
+ import { ExpertIOSlabStore } from "../../artifacts/experts/io";
2
+ import {
3
+ ExpertResidencyManager,
4
+ summarizeExpertLatencies,
5
+ type ExpertLatencySummary,
6
+ type ExpertResidencyLeaseEntry,
7
+ } from "../../artifacts/experts/residency";
8
+ import { MlxArray, gpuStream } from "@mlx-bun/mlx/array";
9
+ import { Dtype, synchronize } from "@mlx-bun/mlx/ffi";
10
+ import * as ops from "@mlx-bun/mlx/ops";
11
+ import type {
12
+ Glm52ExpertProjectionLayout,
13
+ Glm52ExpertSlotLayout,
14
+ } from "../../artifacts/glm52/expert-layout";
15
+ import type {
16
+ Glm52MoeBatchPlan,
17
+ Glm52MoeExpertJob,
18
+ } from "./moe";
19
+ import { Glm52CanonicalQ4MetalExecutor, Glm52CanonicalQ8MetalExecutor, glm52CanonicalQ4SlotView, glm52CanonicalQ8SlotView } from "../../kernels/glm52/streamed-experts";
20
+ import { glm52CanonicalQ4MetalLayout, glm52CanonicalQ8MetalLayout } from "../../artifacts/glm52/kernel-layout";
21
+
22
+ export interface Glm52ExpertExecutionArgs {
23
+ readonly layer: number;
24
+ readonly input: MlxArray;
25
+ readonly plan: Glm52MoeBatchPlan;
26
+ readonly shared: MlxArray | null;
27
+ }
28
+
29
+ export interface Glm52ExpertExecutionBackend {
30
+ execute(args: Glm52ExpertExecutionArgs): Promise<MlxArray>;
31
+ }
32
+
33
+ export interface Glm52StreamedExpertExecutorOptions {
34
+ readonly manager: ExpertResidencyManager;
35
+ readonly store: ExpertIOSlabStore;
36
+ readonly layout: (layer: number, expertId: number) => Glm52ExpertSlotLayout;
37
+ readonly hiddenSize: number;
38
+ /** Explicit candidate selection; stock remains default until the G1 matrix. */
39
+ readonly decodeKernel?: "stock" | "metal";
40
+ }
41
+
42
+ interface MaterializedJob {
43
+ readonly job: Glm52MoeExpertJob;
44
+ readonly output: MlxArray;
45
+ }
46
+
47
+ function projectionDimensions(
48
+ projection: Glm52ExpertProjectionLayout,
49
+ ): readonly [outputRows: number, inputColumns: number] {
50
+ return [
51
+ projection.tensor.outputRows,
52
+ projection.tensor.inputColumns,
53
+ ];
54
+ }
55
+
56
+ /**
57
+ * Correctness-first stock MLX consumer for a canonical Colibri expert slot.
58
+ * Packed Q4 bytes are already in MLX's little-endian uint32 lane order.
59
+ */
60
+ function slotLinear(
61
+ store: ExpertIOSlabStore,
62
+ lease: ExpertResidencyLeaseEntry,
63
+ layout: Glm52ExpertSlotLayout,
64
+ projection: Glm52ExpertProjectionLayout,
65
+ input: MlxArray,
66
+ ): MlxArray {
67
+ const [outputRows, inputColumns] = projectionDimensions(projection);
68
+ const base = store.pointer(lease.slot, lease.generation);
69
+ if ((base + projection.weightOffset) % layout.alignment !== 0 ||
70
+ (base + projection.scaleOffset) % layout.alignment !== 0) {
71
+ throw new Error(
72
+ `${projection.projection}: streamed MLX pointer is not ` +
73
+ `${layout.alignment}-byte aligned`,
74
+ );
75
+ }
76
+ if (layout.bits === 4) {
77
+ const rowBytes = Math.ceil(inputColumns / 2);
78
+ if (rowBytes % 4 !== 0)
79
+ throw new Error("streamed Q4 projection row must occupy whole uint32 lanes");
80
+ const packed = MlxArray.fromPointer(
81
+ base + projection.weightOffset,
82
+ [outputRows, rowBytes / 4],
83
+ Dtype.uint32,
84
+ );
85
+ const scaleGroups =
86
+ projection.tensor.scales.byteLength / 4 / outputRows;
87
+ if (!Number.isSafeInteger(scaleGroups) || scaleGroups < 1)
88
+ throw new Error("streamed Q4 projection has invalid scale geometry");
89
+ const rawScales = MlxArray.fromPointer(
90
+ base + projection.scaleOffset,
91
+ [outputRows, scaleGroups],
92
+ Dtype.float32,
93
+ );
94
+ let scales = rawScales;
95
+ let groupSize = layout.groupSize ?? inputColumns;
96
+ if (layout.groupSize === null && inputColumns > 32) {
97
+ if (inputColumns % 32 !== 0)
98
+ throw new Error("per-row streamed Q4 requires a 32-divisible input width");
99
+ groupSize = 32;
100
+ const zeros = ops.zeros(
101
+ [outputRows, inputColumns / groupSize],
102
+ Dtype.float32,
103
+ );
104
+ scales = ops.add(rawScales, zeros);
105
+ zeros.dispose();
106
+ }
107
+ const biases = ops.mulScalar(scales, -8);
108
+ const output = ops.quantizedMatmul(
109
+ input,
110
+ packed,
111
+ scales,
112
+ biases,
113
+ { bits: 4, groupSize, mode: "affine" },
114
+ true,
115
+ );
116
+ packed.dispose();
117
+ rawScales.dispose();
118
+ if (scales !== rawScales) scales.dispose();
119
+ biases.dispose();
120
+ return output;
121
+ }
122
+
123
+ // MTP uses signed two's-complement Q8. G4 will replace this materializing
124
+ // reference path with its fixed draft/verify kernel family.
125
+ if (layout.groupSize !== null)
126
+ throw new Error("streamed Q8 grouped scales are unsupported");
127
+ const packed = MlxArray.fromPointer(
128
+ base + projection.weightOffset,
129
+ [outputRows, inputColumns],
130
+ Dtype.int8,
131
+ );
132
+ const rawScales = MlxArray.fromPointer(
133
+ base + projection.scaleOffset,
134
+ [outputRows, 1],
135
+ Dtype.float32,
136
+ );
137
+ const values = packed.astype(Dtype.float32);
138
+ const zeros = ops.zeros([outputRows, inputColumns], Dtype.float32);
139
+ const scales = ops.add(rawScales, zeros);
140
+ const weights = ops.mul(values, scales);
141
+ const transposed = ops.transposeAxes(weights, [1, 0]);
142
+ const output = ops.matmul(input, transposed);
143
+ packed.dispose();
144
+ rawScales.dispose();
145
+ values.dispose();
146
+ zeros.dispose();
147
+ scales.dispose();
148
+ weights.dispose();
149
+ transposed.dispose();
150
+ return output;
151
+ }
152
+
153
+ function slotSwiGlu(
154
+ store: ExpertIOSlabStore,
155
+ lease: ExpertResidencyLeaseEntry,
156
+ layout: Glm52ExpertSlotLayout,
157
+ input: MlxArray,
158
+ ): MlxArray {
159
+ let gate: MlxArray | null = null;
160
+ let up: MlxArray | null = null;
161
+ let activated: MlxArray | null = null;
162
+ let product: MlxArray | null = null;
163
+ try {
164
+ gate = slotLinear(
165
+ store, lease, layout, layout.projections.gate, input,
166
+ );
167
+ up = slotLinear(
168
+ store, lease, layout, layout.projections.up, input,
169
+ );
170
+ activated = ops.silu(gate);
171
+ product = ops.mul(activated, up);
172
+ return slotLinear(
173
+ store, lease, layout, layout.projections.down, product,
174
+ );
175
+ } finally {
176
+ gate?.dispose();
177
+ up?.dispose();
178
+ activated?.dispose();
179
+ product?.dispose();
180
+ }
181
+ }
182
+
183
+ /**
184
+ * Stable batch-union executor. Resident graphs and the shared expert are
185
+ * submitted before miss reads; every wave is materialized and fenced before
186
+ * its scratch slots are promoted/reused.
187
+ */
188
+ export class Glm52StockStreamedExpertExecutor
189
+ implements Glm52ExpertExecutionBackend {
190
+ readonly manager: ExpertResidencyManager;
191
+ readonly store: ExpertIOSlabStore;
192
+ readonly hiddenSize: number;
193
+ #layout: Glm52StreamedExpertExecutorOptions["layout"];
194
+ #metal: Glm52CanonicalQ4MetalExecutor | null;
195
+ #mtpMetal: Glm52CanonicalQ8MetalExecutor | null;
196
+ #fixedKernelFamily = false;
197
+ #forwardMs: number[] = [];
198
+
199
+ constructor(options: Glm52StreamedExpertExecutorOptions) {
200
+ this.manager = options.manager;
201
+ this.store = options.store;
202
+ this.#layout = options.layout;
203
+ this.hiddenSize = options.hiddenSize;
204
+ this.#metal = options.decodeKernel === "metal"
205
+ ? new Glm52CanonicalQ4MetalExecutor()
206
+ : null;
207
+ this.#mtpMetal = options.decodeKernel === "metal"
208
+ ? new Glm52CanonicalQ8MetalExecutor()
209
+ : null;
210
+ }
211
+
212
+ setFixedKernelFamily(enabled: boolean): void {
213
+ this.#fixedKernelFamily = enabled;
214
+ }
215
+
216
+ drainForwardTelemetry(): ExpertLatencySummary {
217
+ const summary = summarizeExpertLatencies(this.#forwardMs);
218
+ this.#forwardMs = [];
219
+ return summary;
220
+ }
221
+
222
+ async execute(args: Glm52ExpertExecutionArgs): Promise<MlxArray> {
223
+ const [batch, tokens, hidden] = args.input.shape;
224
+ if (args.input.shape.length !== 3 || hidden !== this.hiddenSize)
225
+ throw new Error(
226
+ `streamed GLM experts require [B,T,${this.hiddenSize}] input`,
227
+ );
228
+ const rowCount = batch! * tokens!;
229
+ if (args.plan.routes.length !== rowCount)
230
+ throw new Error(
231
+ `streamed GLM plan has ${args.plan.routes.length} rows; input has ${rowCount}`,
232
+ );
233
+ this.manager.recordRoutes(args.layer, args.plan.routes);
234
+
235
+ const forwardStarted = performance.now();
236
+ const flattened = ops.reshape(args.input, [rowCount, this.hiddenSize]);
237
+ const sharedFlat = args.shared
238
+ ? ops.reshape(args.shared, [rowCount, this.hiddenSize])
239
+ : null;
240
+ const materialized = new Map<number, MaterializedJob>();
241
+ let sharedSubmitted = false;
242
+ try {
243
+ for (const wave of args.plan.waves) {
244
+ const jobs = new Map(wave.jobs.map((job) => [job.expertId, job]));
245
+ const waveOutputs: MlxArray[] = [];
246
+ let lease = await this.manager.acquireBlock(
247
+ args.layer,
248
+ wave.jobs.map((job) => job.expertId),
249
+ (resident) => {
250
+ for (const entry of resident) {
251
+ const job = jobs.get(entry.expertId)!;
252
+ const output = this.#executeJob(
253
+ flattened,
254
+ job,
255
+ entry,
256
+ this.#layout(args.layer, entry.expertId),
257
+ );
258
+ materialized.set(entry.expertId, { job, output });
259
+ waveOutputs.push(output);
260
+ }
261
+ const submit = sharedFlat && !sharedSubmitted
262
+ ? [...waveOutputs, sharedFlat]
263
+ : waveOutputs;
264
+ if (submit.length) ops.asyncEvalAll(submit);
265
+ if (sharedFlat && !sharedSubmitted) sharedSubmitted = true;
266
+ },
267
+ );
268
+ let releaseAttempted = false;
269
+ try {
270
+ for (const entry of lease.entries) {
271
+ if (entry.hit) continue;
272
+ const job = jobs.get(entry.expertId)!;
273
+ const output = this.#executeJob(
274
+ flattened,
275
+ job,
276
+ entry,
277
+ this.#layout(args.layer, entry.expertId),
278
+ );
279
+ materialized.set(entry.expertId, { job, output });
280
+ waveOutputs.push(output);
281
+ }
282
+ const fence = sharedFlat && !sharedSubmitted
283
+ ? [...waveOutputs, sharedFlat]
284
+ : waveOutputs;
285
+ if (sharedFlat && !sharedSubmitted) sharedSubmitted = true;
286
+ if (fence.length) ops.evalAll(fence);
287
+ synchronize(gpuStream);
288
+ releaseAttempted = true;
289
+ lease.releaseFenced();
290
+ } catch (error) {
291
+ if (releaseAttempted) throw error;
292
+ const cleanupErrors: unknown[] = [];
293
+ try {
294
+ synchronize(gpuStream);
295
+ } catch (cleanupError) {
296
+ cleanupErrors.push(cleanupError);
297
+ }
298
+ if (cleanupErrors.length === 0) {
299
+ releaseAttempted = true;
300
+ try {
301
+ lease.releaseFenced();
302
+ } catch (cleanupError) {
303
+ cleanupErrors.push(cleanupError);
304
+ }
305
+ }
306
+ if (cleanupErrors.length) {
307
+ throw new AggregateError(
308
+ [error, ...cleanupErrors],
309
+ "streamed expert wave failed and fenced cleanup was incomplete",
310
+ );
311
+ }
312
+ throw error;
313
+ }
314
+ }
315
+ this.manager.correctForPressure();
316
+ return this.#compose(
317
+ args.plan,
318
+ materialized,
319
+ sharedFlat,
320
+ [batch!, tokens!, hidden!],
321
+ );
322
+ } finally {
323
+ flattened.dispose();
324
+ sharedFlat?.dispose();
325
+ for (const value of materialized.values()) value.output.dispose();
326
+ this.#forwardMs.push(performance.now() - forwardStarted);
327
+ }
328
+ }
329
+
330
+ #executeJob(
331
+ flattened: MlxArray,
332
+ job: Glm52MoeExpertJob,
333
+ lease: ExpertResidencyLeaseEntry,
334
+ layout: Glm52ExpertSlotLayout,
335
+ ): MlxArray {
336
+ const indices = MlxArray.fromInt32(job.rows, [job.rows.length]);
337
+ let rows: MlxArray | null = null;
338
+ try {
339
+ rows = ops.takeAxis(flattened, indices, 0);
340
+ if (this.#mtpMetal && layout.bits === 8) {
341
+ const descriptor = glm52CanonicalQ8MetalLayout(layout);
342
+ const slot = glm52CanonicalQ8SlotView(
343
+ this.store.pointer(lease.slot, lease.generation),
344
+ descriptor,
345
+ );
346
+ try {
347
+ return this.#mtpMetal.execute(rows, slot, descriptor);
348
+ } finally {
349
+ slot.dispose();
350
+ }
351
+ }
352
+ if (
353
+ this.#metal &&
354
+ layout.bits === 4 &&
355
+ (rows.shape[0] === 1 || this.#fixedKernelFamily)
356
+ ) {
357
+ const descriptor = glm52CanonicalQ4MetalLayout(layout);
358
+ const slot = glm52CanonicalQ4SlotView(
359
+ this.store.pointer(lease.slot, lease.generation),
360
+ descriptor,
361
+ );
362
+ try {
363
+ return this.#metal.execute(rows, slot, descriptor);
364
+ } finally {
365
+ slot.dispose();
366
+ }
367
+ }
368
+ return slotSwiGlu(this.store, lease, layout, rows);
369
+ } finally {
370
+ indices.dispose();
371
+ rows?.dispose();
372
+ }
373
+ }
374
+
375
+ dispose(): void {
376
+ this.#metal?.dispose();
377
+ this.#metal = null;
378
+ this.#mtpMetal?.dispose();
379
+ this.#mtpMetal = null;
380
+ }
381
+
382
+ #compose(
383
+ plan: Glm52MoeBatchPlan,
384
+ materialized: ReadonlyMap<number, MaterializedJob>,
385
+ shared: MlxArray | null,
386
+ shape: readonly [number, number, number],
387
+ ): MlxArray {
388
+ const [batch, tokens, hidden] = shape;
389
+ const consumers = new Map<string, { value: MlxArray; index: number }>();
390
+ for (const { job, output } of materialized.values()) {
391
+ for (let index = 0; index < job.rows.length; index++)
392
+ consumers.set(`${job.rows[index]}:${job.ranks[index]}`, {
393
+ value: output,
394
+ index,
395
+ });
396
+ }
397
+
398
+ const rows: MlxArray[] = [];
399
+ try {
400
+ for (let row = 0; row < plan.routes.length; row++) {
401
+ const route = plan.routes[row]!;
402
+ let sum: MlxArray | null = null;
403
+ for (let rank = 0; rank < route.indices.length; rank++) {
404
+ const consumer = consumers.get(`${row}:${rank}`);
405
+ if (!consumer)
406
+ throw new Error(`missing streamed output for row ${row} rank ${rank}`);
407
+ const view = consumer.value.slice(
408
+ [consumer.index, 0],
409
+ [consumer.index + 1, hidden],
410
+ );
411
+ const scaled = ops.mulScalar(view, route.executionWeights[rank]!);
412
+ view.dispose();
413
+ if (sum === null) {
414
+ sum = scaled;
415
+ } else {
416
+ const next = ops.add(sum, scaled);
417
+ sum.dispose();
418
+ scaled.dispose();
419
+ sum = next;
420
+ }
421
+ }
422
+ if (shared) {
423
+ const sharedRow = shared.slice([row, 0], [row + 1, hidden]);
424
+ if (sum === null) {
425
+ sum = ops.mulScalar(sharedRow, 1);
426
+ } else {
427
+ const next = ops.add(sum, sharedRow);
428
+ sum.dispose();
429
+ sum = next;
430
+ }
431
+ sharedRow.dispose();
432
+ }
433
+ if (!sum) throw new Error(`streamed GLM row ${row} has no expert output`);
434
+ rows.push(sum);
435
+ }
436
+ const flat = rows.length === 1
437
+ ? rows[0]!
438
+ : ops.concatAxis(rows, 0);
439
+ const output = ops.reshape(flat, [batch, tokens, hidden]);
440
+ flat.dispose();
441
+ return output;
442
+ } finally {
443
+ if (rows.length > 1)
444
+ for (const row of rows) row.dispose();
445
+ }
446
+ }
447
+ }
@@ -0,0 +1,59 @@
1
+ import type { ModelConfig } from "../artifacts/config";
2
+ import type { Cache } from "../contracts/mlx/cache";
3
+ import type { MlxArray } from "@mlx-bun/mlx/array";
4
+ import type { MlxDeclaredGraph, MlxModelMemory, MlxTokenPhases, MlxRowTable, MlxCacheLayer } from "../contracts/mlx/graph";
5
+ import { DEFAULT_MAX_ROWS, PREFILL_CHUNK_TOKENS } from "./composition";
6
+ import type { Composition } from "../contracts/portable/composition";
7
+
8
+ /** What the shared token executors (the batch group, its preparation cohorts,
9
+ * the autoregressive binding) consume from a resident graph, whatever family
10
+ * it is: caches, the named phases (`tokenPhasesOf`), weights for the
11
+ * wired-limit scope, and the ports its declaration promises. A graph outside
12
+ * the model registry satisfies it structurally. */
13
+ export interface MlxTokenGraph extends MlxDeclaredGraph, Partial<MlxTokenPhases>, MlxModelMemory {
14
+ readonly config: ModelConfig;
15
+ /** The served configuration the graph was built for; absent for a graph
16
+ * that composes no KV scheme (its caches are its own). */
17
+ readonly composition?: Composition;
18
+ /** The mounted-adapter selection; absent when the graph mounts none. */
19
+ readonly loraState?: { active: string[] };
20
+ /** One cache per cache layer: the caches the composition's KV scheme names
21
+ * (`composedFullAttentionCache`, `composedSlidingAttentionCache`). */
22
+ readonly cacheLayers?: readonly MlxCacheLayer[];
23
+ makeCache(): Cache[];
24
+ /** The vision prefill phase over a prompt's prepared embeddings (borrowed), for
25
+ * direct generation: image tokens attending each other both ways where
26
+ * `imageMask` marks them, `ids` feeding per-layer inputs; `width` is the actual number
27
+ * of the prompt's rows. */
28
+ prefillEmbeddings?(embeddings: MlxArray, state: Cache[], imageMask: MlxArray | null,
29
+ ids: MlxArray, multimodalMask: MlxArray | null, width: number): MlxArray;
30
+ }
31
+
32
+ /** Exact table extent for an unconfigured scheduler. */
33
+ export const DEFAULT_PHASE_ROWS = DEFAULT_MAX_ROWS * PREFILL_CHUNK_TOKENS;
34
+
35
+ /** Materialize the exact row keys the caller's scheduler can supply. */
36
+ export function rowTable<Operation>(operation: Operation, rows: number = DEFAULT_PHASE_ROWS): MlxRowTable<Operation> {
37
+ return Object.freeze(Object.fromEntries(Array.from({ length: rows }, (_, i) => [i + 1, operation])));
38
+ }
39
+
40
+ /** Generic graphs bind their row-specific operations once, before execution. */
41
+ export function rowTableFrom<Operation>(build: (rows: number) => Operation, rows: number = DEFAULT_PHASE_ROWS): MlxRowTable<Operation> {
42
+ return Object.freeze(Object.fromEntries(Array.from({ length: rows }, (_, i) => [i + 1, build(i + 1)])));
43
+ }
44
+
45
+ /** Maximum token rows the scheduler can present under this configuration. */
46
+ export function phaseRowLimit(composition: Pick<Composition, "maxRows" | "prefillChunkTokens" | "draftDepth">): number {
47
+ const depth = typeof composition.draftDepth === "number" ? composition.draftDepth : composition.draftDepth.max;
48
+ return composition.maxRows * Math.max(composition.prefillChunkTokens, depth + 1);
49
+ }
50
+
51
+ /** The phase a forward runs, named by its caller: one new position per row
52
+ * (`decode`), a causal window of positions (`window`: prefill chunks and tails,
53
+ * speculative verify windows), or a span of already decided positions
54
+ * (`committed`: token fill). The names are the cache's own reads
55
+ * (`AttentionCache.appendDecode`, `appendWindow`,
56
+ * `CommittedAttentionCache.appendCommitted`). */
57
+ export type ReadPhase = "decode" | "window" | "committed";
58
+
59
+ export { rowOperationFor, rowTableWithDefault } from "./row-table";