@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,415 @@
1
+ import {
2
+ closeSync,
3
+ existsSync,
4
+ fsyncSync,
5
+ openSync,
6
+ readFileSync,
7
+ renameSync,
8
+ rmSync,
9
+ writeSync,
10
+ } from "node:fs";
11
+
12
+ const UINT32_MAX = 0xffff_ffff;
13
+
14
+ export interface ExpertUsageRoute {
15
+ readonly indices: ArrayLike<number>;
16
+ }
17
+
18
+ export interface ExpertUsageLedgerOptions {
19
+ readonly path: string;
20
+ readonly layers: readonly number[];
21
+ readonly expertsPerLayer: number;
22
+ /** A damaged profile is derived state: report it and start fresh. */
23
+ readonly onWarning?: (message: string) => void;
24
+ }
25
+
26
+ export interface ExpertUsageEntry {
27
+ readonly count: number;
28
+ readonly heat: number;
29
+ readonly lastAccess: number;
30
+ }
31
+
32
+ export interface ExpertUsageSnapshot {
33
+ readonly clock: number;
34
+ readonly routeSelections: number;
35
+ readonly totalCount: number;
36
+ readonly nonzeroCounts: number;
37
+ readonly dirty: boolean;
38
+ }
39
+
40
+ export interface ExpertUsageCount {
41
+ readonly layer: number;
42
+ readonly expertId: number;
43
+ readonly count: number;
44
+ }
45
+
46
+ export interface ExpertAutoPinPlan {
47
+ readonly historySelections: number;
48
+ readonly confidence: number;
49
+ readonly requestedBudgetBytes: number;
50
+ readonly usableBudgetBytes: number;
51
+ readonly plannedBytes: number;
52
+ readonly pins: readonly ExpertUsageCount[];
53
+ }
54
+
55
+ export interface ExpertAutoPinInput {
56
+ readonly ledger: ExpertUsageLedger;
57
+ /** Bytes available to the persistent LRU + pin tiers after working banks. */
58
+ readonly residentTierBudgetBytes: number;
59
+ /** One non-evictable LRU slot per managed layer. */
60
+ readonly mandatoryResidentBytes: number;
61
+ readonly slotBytes: (layer: number) => number;
62
+ readonly minHistorySelections?: number;
63
+ readonly fullConfidenceSelections?: number;
64
+ readonly pinShare?: number;
65
+ readonly minPinBudgetBytes?: number;
66
+ }
67
+
68
+ export interface ExpertLfruCandidate {
69
+ readonly layer: number;
70
+ readonly coldSlot: number;
71
+ readonly coldExpertId: number;
72
+ readonly hotExpertId: number;
73
+ readonly coldScore: number;
74
+ readonly hotScore: number;
75
+ readonly gain: number;
76
+ }
77
+
78
+ export function expertLfruScore(
79
+ heat: number,
80
+ lastAccess: number,
81
+ clock: number,
82
+ ): number {
83
+ const age = (clock - lastAccess) >>> 0;
84
+ return heat * 256 + (age < 255 ? 255 - age : 0);
85
+ }
86
+
87
+ export function selectExpertLfruCandidates(
88
+ candidates: readonly ExpertLfruCandidate[],
89
+ limit = 4,
90
+ ): ExpertLfruCandidate[] {
91
+ positiveSafeInteger(limit, "live-repin limit");
92
+ return candidates.slice().sort((left, right) =>
93
+ right.gain - left.gain ||
94
+ left.layer - right.layer ||
95
+ left.hotExpertId - right.hotExpertId)
96
+ .slice(0, limit);
97
+ }
98
+
99
+ function positiveSafeInteger(value: number, name: string): void {
100
+ if (!Number.isSafeInteger(value) || value <= 0)
101
+ throw new RangeError(`${name} must be a positive safe integer`);
102
+ }
103
+
104
+ function incrementUint32(value: number, amount: number): number {
105
+ return Math.min(UINT32_MAX, value + amount);
106
+ }
107
+
108
+ /**
109
+ * Colibri-compatible long-term expert frequency plus session-local heat and
110
+ * recency. The on-disk format is one `layer expert count` row per nonzero
111
+ * counter, matching Colibri's `.coli_usage` reader.
112
+ */
113
+ export class ExpertUsageLedger {
114
+ readonly path: string;
115
+ readonly layers: readonly number[];
116
+ readonly expertsPerLayer: number;
117
+ #counts = new Map<number, Uint32Array>();
118
+ #heat = new Map<number, Uint32Array>();
119
+ #last = new Map<number, Uint32Array>();
120
+ #clock = 0;
121
+ #routeSelections = 0;
122
+ #dirty = false;
123
+
124
+ private constructor(options: ExpertUsageLedgerOptions) {
125
+ if (!options.path) throw new Error("expert usage path must not be empty");
126
+ positiveSafeInteger(options.expertsPerLayer, "expertsPerLayer");
127
+ if (options.expertsPerLayer > UINT32_MAX)
128
+ throw new RangeError("expertsPerLayer exceeds uint32 range");
129
+ const layers = options.layers.slice();
130
+ if (layers.length === 0 || new Set(layers).size !== layers.length)
131
+ throw new Error("expert usage layers must be non-empty and unique");
132
+ for (const layer of layers)
133
+ if (!Number.isSafeInteger(layer) || layer < 0)
134
+ throw new RangeError(`invalid expert usage layer ${layer}`);
135
+ this.path = options.path;
136
+ this.layers = Object.freeze(layers);
137
+ this.expertsPerLayer = options.expertsPerLayer;
138
+ for (const layer of layers) {
139
+ this.#counts.set(layer, new Uint32Array(options.expertsPerLayer));
140
+ this.#heat.set(layer, new Uint32Array(options.expertsPerLayer));
141
+ this.#last.set(layer, new Uint32Array(options.expertsPerLayer));
142
+ }
143
+ }
144
+
145
+ static open(options: ExpertUsageLedgerOptions): ExpertUsageLedger {
146
+ const ledger = new ExpertUsageLedger(options);
147
+ if (!existsSync(options.path)) return ledger;
148
+ try {
149
+ ledger.#load(readFileSync(options.path, "utf8"));
150
+ } catch (error) {
151
+ const detail = error instanceof Error ? error.message : String(error);
152
+ options.onWarning?.(
153
+ `ignoring invalid expert usage profile ${options.path}: ${detail}`,
154
+ );
155
+ ledger.#clearCounts();
156
+ }
157
+ return ledger;
158
+ }
159
+
160
+ /** Count every selected route before the execution plan deduplicates it. */
161
+ recordRoutes(layer: number, routes: readonly ExpertUsageRoute[]): void {
162
+ const counts = this.#counts.get(layer);
163
+ const heat = this.#heat.get(layer);
164
+ const last = this.#last.get(layer);
165
+ if (!counts || !heat || !last)
166
+ throw new RangeError(`layer ${layer} is not tracked by expert usage`);
167
+
168
+ const selected: number[] = [];
169
+ for (let row = 0; row < routes.length; row++) {
170
+ for (let rank = 0; rank < routes[row]!.indices.length; rank++) {
171
+ const expertId = Number(routes[row]!.indices[rank]);
172
+ if (!Number.isSafeInteger(expertId) || expertId < 0 ||
173
+ expertId >= this.expertsPerLayer) {
174
+ throw new RangeError(
175
+ `route ${row} rank ${rank} has invalid expert ${expertId}`,
176
+ );
177
+ }
178
+ selected.push(expertId);
179
+ }
180
+ }
181
+
182
+ for (const expertId of selected) {
183
+ counts[expertId] = incrementUint32(counts[expertId]!, 1);
184
+ heat[expertId] = incrementUint32(heat[expertId]!, 1);
185
+ this.#clock = (this.#clock + 1) >>> 0;
186
+ last[expertId] = this.#clock;
187
+ this.#routeSelections++;
188
+ }
189
+ if (selected.length) this.#dirty = true;
190
+ }
191
+
192
+ entry(layer: number, expertId: number): ExpertUsageEntry {
193
+ this.#validateEntry(layer, expertId);
194
+ return {
195
+ count: this.#counts.get(layer)![expertId]!,
196
+ heat: this.#heat.get(layer)![expertId]!,
197
+ lastAccess: this.#last.get(layer)![expertId]!,
198
+ };
199
+ }
200
+
201
+ snapshot(): ExpertUsageSnapshot {
202
+ let nonzeroCounts = 0;
203
+ let totalCount = 0;
204
+ for (const counts of this.#counts.values())
205
+ for (const count of counts) {
206
+ totalCount += count;
207
+ if (count !== 0) nonzeroCounts++;
208
+ }
209
+ return {
210
+ clock: this.#clock,
211
+ routeSelections: this.#routeSelections,
212
+ totalCount,
213
+ nonzeroCounts,
214
+ dirty: this.#dirty,
215
+ };
216
+ }
217
+
218
+ rankedCounts(): ExpertUsageCount[] {
219
+ const ranked: ExpertUsageCount[] = [];
220
+ for (const layer of this.layers) {
221
+ const counts = this.#counts.get(layer)!;
222
+ for (let expertId = 0; expertId < counts.length; expertId++) {
223
+ const count = counts[expertId]!;
224
+ if (count !== 0) ranked.push({ layer, expertId, count });
225
+ }
226
+ }
227
+ ranked.sort((left, right) =>
228
+ right.count - left.count ||
229
+ left.layer - right.layer ||
230
+ left.expertId - right.expertId);
231
+ return ranked;
232
+ }
233
+
234
+ lfruCandidate(
235
+ layer: number,
236
+ pinnedExpertIds: readonly number[],
237
+ ): ExpertLfruCandidate | null {
238
+ if (pinnedExpertIds.length === 0) return null;
239
+ for (const expertId of pinnedExpertIds) this.#validateEntry(layer, expertId);
240
+ const pinned = new Set(pinnedExpertIds);
241
+ let coldSlot = 0;
242
+ let coldScore = this.#lfruScore(layer, pinnedExpertIds[0]!);
243
+ for (let slot = 1; slot < pinnedExpertIds.length; slot++) {
244
+ const score = this.#lfruScore(layer, pinnedExpertIds[slot]!);
245
+ if (score < coldScore) {
246
+ coldSlot = slot;
247
+ coldScore = score;
248
+ }
249
+ }
250
+ let hotExpertId = -1;
251
+ let hotScore = 0;
252
+ for (let expertId = 0; expertId < this.expertsPerLayer; expertId++) {
253
+ if (pinned.has(expertId)) continue;
254
+ const score = this.#lfruScore(layer, expertId);
255
+ if (hotExpertId < 0 || score > hotScore) {
256
+ hotExpertId = expertId;
257
+ hotScore = score;
258
+ }
259
+ }
260
+ if (hotExpertId < 0 ||
261
+ hotScore <= coldScore + Math.floor(coldScore / 4) + 4 * 256) {
262
+ return null;
263
+ }
264
+ return {
265
+ layer,
266
+ coldSlot,
267
+ coldExpertId: pinnedExpertIds[coldSlot]!,
268
+ hotExpertId,
269
+ coldScore,
270
+ hotScore,
271
+ gain: Math.floor((hotScore - coldScore) / 256),
272
+ };
273
+ }
274
+
275
+ decayHeat(): void {
276
+ for (const heat of this.#heat.values())
277
+ for (let expertId = 0; expertId < heat.length; expertId++)
278
+ heat[expertId] = heat[expertId]! >>> 1;
279
+ }
280
+
281
+ /** Persist the current profile with same-directory temp + atomic rename. */
282
+ flush(): void {
283
+ if (!this.#dirty) return;
284
+ const rows: string[] = [];
285
+ for (const layer of this.layers) {
286
+ const counts = this.#counts.get(layer)!;
287
+ for (let expertId = 0; expertId < counts.length; expertId++) {
288
+ const count = counts[expertId]!;
289
+ if (count !== 0) rows.push(`${layer} ${expertId} ${count}\n`);
290
+ }
291
+ }
292
+ const temp =
293
+ `${this.path}.tmp-${process.pid}-${Math.trunc(Bun.nanoseconds())}`;
294
+ let fd: number | null = null;
295
+ try {
296
+ fd = openSync(temp, "w", 0o600);
297
+ const data = Buffer.from(rows.join(""));
298
+ let written = 0;
299
+ while (written < data.length) {
300
+ written += writeSync(
301
+ fd,
302
+ data,
303
+ written,
304
+ data.length - written,
305
+ written,
306
+ );
307
+ }
308
+ fsyncSync(fd);
309
+ closeSync(fd);
310
+ fd = null;
311
+ renameSync(temp, this.path);
312
+ this.#dirty = false;
313
+ } catch (error) {
314
+ if (fd !== null) closeSync(fd);
315
+ try { rmSync(temp, { force: true }); } catch {}
316
+ throw error;
317
+ }
318
+ }
319
+
320
+ #load(text: string): void {
321
+ for (const [index, raw] of text.split("\n").entries()) {
322
+ const line = raw.trim();
323
+ if (!line) continue;
324
+ const fields = line.split(/\s+/);
325
+ if (fields.length !== 3)
326
+ throw new Error(`line ${index + 1}: expected layer expert count`);
327
+ const [layer, expertId, count] = fields.map(Number);
328
+ if (!Number.isSafeInteger(layer) || !this.#counts.has(layer!))
329
+ throw new Error(`line ${index + 1}: invalid layer ${fields[0]}`);
330
+ if (!Number.isSafeInteger(expertId) || expertId! < 0 ||
331
+ expertId! >= this.expertsPerLayer) {
332
+ throw new Error(`line ${index + 1}: invalid expert ${fields[1]}`);
333
+ }
334
+ if (!Number.isSafeInteger(count) || count! < 0 || count! > UINT32_MAX)
335
+ throw new Error(`line ${index + 1}: invalid count ${fields[2]}`);
336
+ const counts = this.#counts.get(layer!)!;
337
+ counts[expertId!] = incrementUint32(counts[expertId!]!, count!);
338
+ }
339
+ }
340
+
341
+ #clearCounts(): void {
342
+ for (const counts of this.#counts.values()) counts.fill(0);
343
+ }
344
+
345
+ #validateEntry(layer: number, expertId: number): void {
346
+ if (!this.#counts.has(layer))
347
+ throw new RangeError(`layer ${layer} is not tracked by expert usage`);
348
+ if (!Number.isSafeInteger(expertId) || expertId < 0 ||
349
+ expertId >= this.expertsPerLayer) {
350
+ throw new RangeError(`invalid expert ${expertId}`);
351
+ }
352
+ }
353
+
354
+ #lfruScore(layer: number, expertId: number): number {
355
+ const heat = this.#heat.get(layer)![expertId]!;
356
+ const last = this.#last.get(layer)![expertId]!;
357
+ return expertLfruScore(heat, last, this.#clock);
358
+ }
359
+ }
360
+
361
+ /**
362
+ * Faithful, budget-safe form of Colibri's startup AUTOPIN policy. History must
363
+ * reach 5k selections; confidence ramps to one at 200k; pins receive at most
364
+ * half of the resident-tier budget and are not created below a 0.5 GB tier.
365
+ */
366
+ export function planExpertAutoPins(input: ExpertAutoPinInput): ExpertAutoPinPlan {
367
+ const minHistory = input.minHistorySelections ?? 5_000;
368
+ const fullConfidence = input.fullConfidenceSelections ?? 200_000;
369
+ const pinShare = input.pinShare ?? 0.5;
370
+ const minPinBudget = input.minPinBudgetBytes ?? 500_000_000;
371
+ positiveSafeInteger(minHistory, "auto-pin minHistorySelections");
372
+ positiveSafeInteger(fullConfidence, "auto-pin fullConfidenceSelections");
373
+ if (!Number.isFinite(pinShare) || pinShare <= 0 || pinShare > 1)
374
+ throw new RangeError("auto-pin pinShare must be in (0, 1]");
375
+ if (!Number.isSafeInteger(minPinBudget) || minPinBudget < 0)
376
+ throw new RangeError("auto-pin minPinBudgetBytes must be non-negative");
377
+ if (!Number.isSafeInteger(input.residentTierBudgetBytes) ||
378
+ input.residentTierBudgetBytes < 0 ||
379
+ !Number.isSafeInteger(input.mandatoryResidentBytes) ||
380
+ input.mandatoryResidentBytes < 0) {
381
+ throw new RangeError("auto-pin resident budgets must be non-negative safe integers");
382
+ }
383
+
384
+ const historySelections = input.ledger.snapshot().totalCount;
385
+ const confidence = Math.min(historySelections / fullConfidence, 1);
386
+ const requestedBudgetBytes = Math.floor(
387
+ input.residentTierBudgetBytes * pinShare * confidence,
388
+ );
389
+ const usableBudgetBytes = Math.min(
390
+ requestedBudgetBytes,
391
+ Math.max(
392
+ 0,
393
+ input.residentTierBudgetBytes - input.mandatoryResidentBytes,
394
+ ),
395
+ );
396
+ const pins: ExpertUsageCount[] = [];
397
+ let plannedBytes = 0;
398
+ if (historySelections >= minHistory && requestedBudgetBytes >= minPinBudget) {
399
+ for (const candidate of input.ledger.rankedCounts()) {
400
+ const bytes = input.slotBytes(candidate.layer);
401
+ positiveSafeInteger(bytes, `auto-pin slotBytes for layer ${candidate.layer}`);
402
+ if (plannedBytes + bytes > usableBudgetBytes) continue;
403
+ pins.push(candidate);
404
+ plannedBytes += bytes;
405
+ }
406
+ }
407
+ return {
408
+ historySelections,
409
+ confidence,
410
+ requestedBudgetBytes,
411
+ usableBudgetBytes,
412
+ plannedBytes,
413
+ pins: Object.freeze(pins),
414
+ };
415
+ }
@@ -0,0 +1,44 @@
1
+ // Config fingerprint (`02d723a:docs/archive/investigations/optimization_plan.md`
2
+ // Phase C): a stable hash over every config field that changes the decode graph
3
+ // structure, plus the kv_config quant layout. The default graph table keys a
4
+ // written graph's entry on its declared fingerprint and composition, and uses
5
+ // the family's generic graph otherwise. Explicit graph choices bypass the table.
6
+
7
+ import type { ModelConfig } from "./config";
8
+
9
+ export function configFingerprint(config: ModelConfig): string {
10
+ const t = config.text;
11
+ const payload = JSON.stringify({
12
+ layerTypes: t.layerTypes,
13
+ hiddenSize: t.hiddenSize,
14
+ headDim: t.headDim,
15
+ globalHeadDim: t.globalHeadDim,
16
+ numAttentionHeads: t.numAttentionHeads,
17
+ numKeyValueHeads: t.numKeyValueHeads,
18
+ numGlobalKeyValueHeads: t.numGlobalKeyValueHeads,
19
+ attentionKEqV: t.attentionKEqV,
20
+ numKvSharedLayers: t.numKvSharedLayers,
21
+ enableMoeBlock: t.enableMoeBlock,
22
+ numExperts: t.enableMoeBlock ? t.numExperts : 0,
23
+ topKExperts: t.enableMoeBlock ? t.topKExperts : 0,
24
+ hiddenSizePerLayerInput: t.hiddenSizePerLayerInput,
25
+ slidingWindow: t.slidingWindow,
26
+ finalLogitSoftcapping: t.finalLogitSoftcapping,
27
+ kvQuant: config.kvQuant ?? null,
28
+ });
29
+ const h = new Bun.CryptoHasher("sha256");
30
+ h.update(payload);
31
+ return h.digest("hex").slice(0, 16);
32
+ }
33
+
34
+ /** Exact immutable model-component identity, calculated once while its owner
35
+ * holds the native execution lease. Names/shapes/dtypes disambiguate layouts. */
36
+ export function tensorFingerprint(entries: Iterable<readonly [string,
37
+ Pick<import("@mlx-bun/mlx/array").MlxArray, "dtype" | "shape" | "rawBytesView">]>): string {
38
+ const hash = new Bun.CryptoHasher("sha256");
39
+ for (const [name, tensor] of [...entries].sort(([a], [b]) => a.localeCompare(b))) {
40
+ hash.update(JSON.stringify([name, tensor.dtype, tensor.shape]));
41
+ hash.update(tensor.rawBytesView());
42
+ }
43
+ return hash.digest("hex");
44
+ }