@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,79 @@
1
+ import { isUnservableDrafterModelType } from "./drafters";
2
+ import { familyOf, familyOfModelType } from "./families";
3
+ import { loadModelConfig, type ModelConfig } from "../artifacts/config";
4
+ import type { MoeDeclaration } from "./family";
5
+
6
+ /** Registry-level role of a `model_type` before any weights are read: a
7
+ * speech-to-text checkpoint, served by the transcription engine. */
8
+ export function isTranscriptionModelType(modelType: string): boolean {
9
+ return familyOfModelType(modelType)?.transcribes === true;
10
+ }
11
+
12
+ /** Registry-level role of a `model_type` before any weights are read: its
13
+ * graph declares the pooled-embedding path (`embeddingDeclarationFor`). */
14
+ export function isEmbeddingModelType(modelType: string): boolean {
15
+ return familyOfModelType(modelType)?.embedding !== undefined;
16
+ }
17
+
18
+ /** Speculative-decoding drafters (e.g. `gemma4_assistant`) are companion
19
+ * artifacts to a target model — Q-only, centroid-head, no standalone LM
20
+ * head. They are never servable/selectable on their own (the spec path
21
+ * loads them by explicit path), so they must be excluded from model
22
+ * resolution and the supported-model lists. See
23
+ * packages/inference/src/models/gemma4/assistant.ts. */
24
+ export function isDrafterModelType(modelType: string): boolean {
25
+ return isUnservableDrafterModelType(modelType);
26
+ }
27
+
28
+ /** Support tier of a registry record's `model_type` (`02d723a:docs/design/generic-model-support.md`):
29
+ * "targeted" = dedicated forward + L2/L3 paths;
30
+ * "generic" = the Tier-0 universal module (L1 only);
31
+ * null = unsupported. Generic never shadows targeted. The type alone cannot
32
+ * tell a family that shares another's `model_type` (MiniCPM5 is `llama`); read
33
+ * the config for the exact family. */
34
+ export function supportTier(modelType: string): "targeted" | "generic" | null {
35
+ if (isDrafterModelType(modelType)) return null;
36
+ return familyOfModelType(modelType)?.tier ?? null;
37
+ }
38
+
39
+ export function isSupportedModelRecord(modelType: string): boolean {
40
+ return supportTier(modelType) !== null;
41
+ }
42
+
43
+ /** Whether a family serves this config. A malformed config is unsupported, not a crash. */
44
+ export function isSupportedModelConfig(config: ModelConfig): boolean {
45
+ if (isDrafterModelType(config.modelType)) return false;
46
+ try {
47
+ return familyOf(config) !== null;
48
+ } catch {
49
+ return false;
50
+ }
51
+ }
52
+
53
+ /** The experts the config's family routes each token through; null for a dense,
54
+ * unsupported or unreadable model (sizing estimates never throw). */
55
+ export function moeOf(config: ModelConfig): MoeDeclaration | null {
56
+ try { return familyOf(config)?.moe?.(config) ?? null; } catch { return null; }
57
+ }
58
+
59
+ export type SupportTier = "targeted" | "generic";
60
+
61
+ /** The exact tier of a model directory: the family that accepts its config,
62
+ * where the `model_type` alone is ambiguous (MiniCPM5 shares `llama`); the
63
+ * record-level tier when the config names no family or cannot be read.
64
+ * Reads one config, so a registry calls it once per snapshot at index time. */
65
+ export async function supportTierOfModelDir(modelDir: string, modelType: string): Promise<SupportTier | null> {
66
+ if (isDrafterModelType(modelType)) return null;
67
+ try {
68
+ return familyOf(await loadModelConfig(modelDir))?.tier ?? supportTier(modelType);
69
+ } catch {
70
+ return supportTier(modelType);
71
+ }
72
+ }
73
+
74
+ /** The tier a listed record shows: the one its registry classified at index time,
75
+ * else the record-level tier for its `model_type`. */
76
+ export function listedSupportTier(record: { modelType: string; supportTier?: string | null }): SupportTier | null {
77
+ const indexed = record.supportTier;
78
+ return indexed === "targeted" || indexed === "generic" ? indexed : supportTier(record.modelType);
79
+ }
@@ -0,0 +1,365 @@
1
+ // Arch descriptor table for the Tier-0 universal dense module
2
+ // (`02d723a:docs/design/generic-model-support.md` §4.1). One entry per mlx-lm
3
+ // model_type; each parse function is the ~15–25-line transcription of that
4
+ // arch's ModelArgs (defaults included) + structural deltas, read from the
5
+ // RAW config.json exactly like the oracle's dataclass does.
6
+ //
7
+ // Support is this table's keys (+ MODEL_REMAPPING aliases) — an explicit,
8
+ // declared surface. No config sniffing. A model_type absent here is
9
+ // unsupported until a descriptor + green parity manifest entry exist.
10
+
11
+ import type { ModelConfig } from "../../artifacts/config";
12
+ import type { RopeScalingConfig } from "../../layers/rope";
13
+
14
+ /** mlx_lm/utils.py MODEL_REMAPPING, vendored (free aliases). Only entries
15
+ * whose TARGET has a descriptor below actually load; the rest are kept so
16
+ * the reject message can name the real arch. */
17
+ export const MODEL_REMAPPING: Record<string, string> = {
18
+ mistral: "llama",
19
+ llava: "mistral3",
20
+ "phi-msft": "phixtral",
21
+ falcon_mamba: "mamba",
22
+ joyai_llm_flash: "deepseek_v3",
23
+ kimi_k2: "deepseek_v3",
24
+ qwen2_5_vl: "qwen2_vl",
25
+ minimax_m2: "minimax",
26
+ iquestcoder: "llama",
27
+ };
28
+
29
+ export function remapModelType(modelType: string): string {
30
+ return MODEL_REMAPPING[modelType] ?? modelType;
31
+ }
32
+
33
+ /** Normalized args for the universal dense forward — the union of the
34
+ * launch archs' ModelArgs, one value per knob (no optionals left). */
35
+ export interface UniversalArgs {
36
+ modelType: string;
37
+ hiddenSize: number;
38
+ numHiddenLayers: number;
39
+ intermediateSize: number;
40
+ numHeads: number;
41
+ numKvHeads: number;
42
+ headDim: number;
43
+ normEps: number;
44
+ vocabSize: number;
45
+ ropeTheta: number;
46
+ ropeTraditional: boolean;
47
+ ropeScaling: RopeScalingConfig | null;
48
+ maxPositionEmbeddings: number | null;
49
+ /** q/k/v projection bias; o and mlp separately (qwen2: qkv only). */
50
+ qkvBias: boolean;
51
+ oBias: boolean;
52
+ mlpBias: boolean;
53
+ tieWordEmbeddings: boolean;
54
+ /** null ⇒ every layer full attention. */
55
+ layerTypes: string[] | null;
56
+ slidingWindow: number | null;
57
+ // ---- block structure ----
58
+ /** pre = llama (norm → sublayer → residual)
59
+ * post = olmo2 (sublayer → norm → residual)
60
+ * gemma2 = sandwich (input/post-attn + pre/post-ffn norms)
61
+ * glm4 = post-sublayer norms with pre-norms too */
62
+ block: "pre" | "post" | "gemma2" | "glm4";
63
+ norm: "rmsnorm" | "rmsnorm_plus_one" | "layernorm";
64
+ /** qwen3 = per-head RMSNorm over head_dim (before transpose);
65
+ * olmo2 = full-width RMSNorm on the flat projection (before reshape). */
66
+ qkNorm: "none" | "head" | "full";
67
+ mlp: "swiglu" | "geglu" | "geglu_approx" | "fused_swiglu" | "gelu_mlp";
68
+ /** phi3: one fused qkv_proj, split as activations (mx.split — exactly
69
+ * what mlx-lm does; the quantized matrix stays fused). */
70
+ fusedQkv: boolean;
71
+ attnScale: number;
72
+ /** gemma2 attention-score softcap ⇒ manual q·kᵀ→tanh→softmax path. */
73
+ attnLogitSoftcap: number | null;
74
+ finalLogitSoftcap: number | null;
75
+ /** granite: logits / logits_scaling. */
76
+ logitsDivisor: number | null;
77
+ /** gemma: hidden**0.5; granite: embedding_multiplier. */
78
+ embedMultiplier: number | null;
79
+ /** granite residual_multiplier. */
80
+ residualMultiplier: number | null;
81
+ rope: "initialize" | "plain" | "phi3";
82
+ /** rope dims = floor(headDim * partialRotaryFactor) (glm4, phi3). */
83
+ partialRotaryFactor: number;
84
+ /** phi3 SuScaledRoPE original context (TOP-LEVEL config key). */
85
+ originalMaxPositionEmbeddings: number;
86
+ /** smollm3: per-layer 1 = rope, 0 = NoPE. null ⇒ rope everywhere. */
87
+ noRopeLayers: number[] | null;
88
+ /** gemma2: create_attention_mask(..., return_array=True). */
89
+ maskArray: boolean;
90
+ /** sanitize: tensors mlx-lm drops on load (audit allowances). */
91
+ dropWeightPatterns: RegExp[];
92
+ }
93
+
94
+ type Raw = Record<string, any>;
95
+
96
+ const INV_FREQ = /self_attn\.rotary_emb\.inv_freq/;
97
+
98
+ /** Common fields most archs share; per-arch parsers override the deltas. */
99
+ function common(raw: Raw, modelType: string): UniversalArgs {
100
+ const heads = raw.num_attention_heads as number;
101
+ return {
102
+ modelType,
103
+ hiddenSize: raw.hidden_size,
104
+ numHiddenLayers: raw.num_hidden_layers,
105
+ intermediateSize: raw.intermediate_size,
106
+ numHeads: heads,
107
+ numKvHeads: raw.num_key_value_heads ?? heads,
108
+ headDim: Math.floor(raw.hidden_size / heads),
109
+ normEps: raw.rms_norm_eps,
110
+ vocabSize: raw.vocab_size,
111
+ ropeTheta: raw.rope_theta ?? 10000,
112
+ ropeTraditional: raw.rope_traditional ?? false,
113
+ ropeScaling: (raw.rope_scaling as RopeScalingConfig | undefined) ?? null,
114
+ maxPositionEmbeddings: raw.max_position_embeddings ?? null,
115
+ qkvBias: false,
116
+ oBias: false,
117
+ mlpBias: false,
118
+ tieWordEmbeddings: raw.tie_word_embeddings ?? true,
119
+ layerTypes: null,
120
+ slidingWindow: null,
121
+ block: "pre",
122
+ norm: "rmsnorm",
123
+ qkNorm: "none",
124
+ mlp: "swiglu",
125
+ fusedQkv: false,
126
+ attnScale: Math.pow(Math.floor(raw.hidden_size / heads), -0.5),
127
+ attnLogitSoftcap: null,
128
+ finalLogitSoftcap: null,
129
+ logitsDivisor: null,
130
+ embedMultiplier: null,
131
+ residualMultiplier: null,
132
+ rope: "initialize",
133
+ partialRotaryFactor: 1.0,
134
+ originalMaxPositionEmbeddings: 4096,
135
+ noRopeLayers: null,
136
+ maskArray: false,
137
+ dropWeightPatterns: [],
138
+ };
139
+ }
140
+
141
+ function parseLlama(raw: Raw, modelType = "llama"): UniversalArgs {
142
+ const a = common(raw, modelType);
143
+ a.headDim = raw.head_dim ?? a.headDim;
144
+ a.attnScale = Math.pow(a.headDim, -0.5);
145
+ a.qkvBias = raw.attention_bias ?? false;
146
+ a.oBias = raw.attention_bias ?? false; // llama.py wires o_proj bias to the same flag
147
+ a.mlpBias = raw.mlp_bias ?? false;
148
+ a.layerTypes = (raw.layer_types as string[] | undefined) ?? null;
149
+ a.slidingWindow = raw.sliding_window ?? null;
150
+ a.dropWeightPatterns = [INV_FREQ];
151
+ if (a.tieWordEmbeddings) a.dropWeightPatterns.push(/^lm_head\.weight$/);
152
+ return a;
153
+ }
154
+
155
+ export const ARCHS: Record<string, (raw: Raw) => UniversalArgs> = {
156
+ /** llama (+ mistral / iquestcoder via remap): the reference dense block. */
157
+ llama: (raw) => parseLlama(raw),
158
+
159
+ /** smollm3: llama with NoPE layers (every no_rope_layer_interval-th). */
160
+ smollm3: (raw) => {
161
+ const a = parseLlama(raw, "smollm3");
162
+ const interval = raw.no_rope_layer_interval ?? 4;
163
+ const list = raw.no_rope_layers as number[] | undefined;
164
+ if (list && list.length !== a.numHiddenLayers)
165
+ throw new Error("`no_rope_layers` length mismatch");
166
+ a.noRopeLayers = list ??
167
+ Array.from({ length: a.numHiddenLayers }, (_, i) => ((i + 1) % interval !== 0 ? 1 : 0));
168
+ return a;
169
+ },
170
+
171
+ /** qwen2: llama block + hardcoded q/k/v bias (o unbiased), theta 1e6. */
172
+ qwen2: (raw) => {
173
+ const a = common(raw, "qwen2");
174
+ a.ropeTheta = raw.rope_theta ?? 1000000;
175
+ a.maxPositionEmbeddings = raw.max_position_embeddings ?? 32768;
176
+ a.qkvBias = true;
177
+ a.dropWeightPatterns = [INV_FREQ];
178
+ if (a.tieWordEmbeddings) a.dropWeightPatterns.push(/^lm_head\.weight$/);
179
+ return a;
180
+ },
181
+
182
+ /** qwen3: per-head q/k RMSNorm over head_dim BEFORE transpose+rope. */
183
+ qwen3: (raw) => {
184
+ const a = common(raw, "qwen3");
185
+ a.headDim = raw.head_dim; // required in qwen3 ModelArgs
186
+ a.attnScale = Math.pow(a.headDim, -0.5);
187
+ a.qkNorm = "head";
188
+ a.tieWordEmbeddings = raw.tie_word_embeddings ?? false;
189
+ if (a.tieWordEmbeddings) a.dropWeightPatterns = [/^lm_head\.weight$/];
190
+ return a;
191
+ },
192
+
193
+ /** gemma (v1): (1+w) RMSNorm, √hidden embed scale, PRECISE-gelu gated
194
+ * MLP, always-tied head, plain rope (rope_scaling ignored). */
195
+ gemma: (raw) => {
196
+ const a = common(raw, "gemma");
197
+ a.headDim = raw.head_dim; // required
198
+ a.attnScale = Math.pow(a.headDim, -0.5);
199
+ a.norm = "rmsnorm_plus_one";
200
+ a.mlp = "geglu";
201
+ a.embedMultiplier = Math.pow(raw.hidden_size, 0.5);
202
+ a.tieWordEmbeddings = true; // as_linear unconditionally
203
+ a.rope = "plain";
204
+ a.ropeScaling = null;
205
+ return a;
206
+ },
207
+
208
+ /** gemma2: gemma + sandwich norms, attention-score softcap (manual
209
+ * attention), query_pre_attn_scalar scale, final logit softcap,
210
+ * gelu_approx MLP, always-array mask. mlx-lm runs every layer full
211
+ * attention (no sliding window in its gemma2) — we match the oracle. */
212
+ gemma2: (raw) => {
213
+ const a = common(raw, "gemma2");
214
+ a.headDim = raw.head_dim; // required
215
+ a.norm = "rmsnorm_plus_one";
216
+ a.block = "gemma2";
217
+ a.mlp = "geglu_approx";
218
+ a.embedMultiplier = Math.pow(raw.hidden_size, 0.5);
219
+ a.tieWordEmbeddings = true;
220
+ a.rope = "plain";
221
+ a.ropeScaling = null;
222
+ a.attnScale = 1.0 / Math.pow(raw.query_pre_attn_scalar ?? 144.0, 0.5);
223
+ a.attnLogitSoftcap = raw.attn_logit_softcapping ?? 50.0;
224
+ a.finalLogitSoftcap = raw.final_logit_softcapping ?? 30.0;
225
+ a.maskArray = true;
226
+ return a;
227
+ },
228
+
229
+ /** phi3: fused qkv + fused gate_up (split as ACTIVATIONS, like mlx-lm),
230
+ * longrope/su (or linear) rope on partial dims, untied head. */
231
+ phi3: (raw) => {
232
+ const a = common(raw, "phi3");
233
+ a.tieWordEmbeddings = raw.tie_word_embeddings ?? false;
234
+ a.fusedQkv = true;
235
+ a.mlp = "fused_swiglu";
236
+ a.rope = "phi3";
237
+ a.partialRotaryFactor = raw.partial_rotary_factor ?? 1.0;
238
+ a.maxPositionEmbeddings = raw.max_position_embeddings ?? 131072;
239
+ a.originalMaxPositionEmbeddings = raw.original_max_position_embeddings ?? 4096;
240
+ // phi3.py __post_init__: rope_scaling must carry {long_factor, type};
241
+ // only longrope/su/linear supported, anything else → scaling off.
242
+ if (a.ropeScaling) {
243
+ for (const key of ["long_factor", "type"])
244
+ if (!(key in a.ropeScaling))
245
+ throw new Error(`rope_scaling must contain keys {'long_factor', 'type'}`);
246
+ const t = String(a.ropeScaling.type);
247
+ if (!["longrope", "su", "linear"].includes(t)) a.ropeScaling = null;
248
+ }
249
+ return a;
250
+ },
251
+
252
+ /** olmo2: POST-norm block (norm on sublayer output), full-width q/k
253
+ * RMSNorm on the flat projections. */
254
+ olmo2: (raw) => {
255
+ const a = common(raw, "olmo2");
256
+ a.headDim = raw.head_dim ?? a.headDim;
257
+ a.attnScale = Math.pow(a.headDim, -0.5);
258
+ a.block = "post";
259
+ a.qkNorm = "full";
260
+ a.qkvBias = raw.attention_bias ?? false;
261
+ a.oBias = raw.attention_bias ?? false;
262
+ a.mlpBias = raw.mlp_bias ?? false;
263
+ a.dropWeightPatterns = [INV_FREQ];
264
+ return a;
265
+ },
266
+
267
+ /** glm4: pre+post sublayer norms (post_self_attn / post_mlp), fused
268
+ * gate_up MLP, PARTIAL rope with traditional=True default, always a
269
+ * separate lm_head. */
270
+ glm4: (raw) => {
271
+ const a = common(raw, "glm4");
272
+ a.headDim = raw.head_dim ?? a.headDim;
273
+ a.attnScale = Math.pow(a.headDim, -0.5);
274
+ a.block = "glm4";
275
+ a.mlp = "fused_swiglu";
276
+ a.qkvBias = raw.attention_bias;
277
+ a.rope = "plain";
278
+ a.ropeScaling = null;
279
+ a.ropeTraditional = raw.rope_traditional ?? true;
280
+ a.partialRotaryFactor = raw.partial_rotary_factor;
281
+ a.maxPositionEmbeddings = raw.max_position_embeddings ?? 32768;
282
+ a.tieWordEmbeddings = false; // glm4.py constructs lm_head unconditionally
283
+ return a;
284
+ },
285
+
286
+ /** granite: llama block scaled everywhere — attention_multiplier as the
287
+ * SDPA scale, embedding/residual multipliers, logits / logits_scaling. */
288
+ granite: (raw) => {
289
+ const a = common(raw, "granite");
290
+ a.attnScale = raw.attention_multiplier;
291
+ a.embedMultiplier = raw.embedding_multiplier;
292
+ a.residualMultiplier = raw.residual_multiplier;
293
+ a.logitsDivisor = raw.logits_scaling;
294
+ a.qkvBias = raw.attention_bias;
295
+ a.oBias = raw.attention_bias;
296
+ a.mlpBias = raw.mlp_bias;
297
+ a.ropeTraditional = false; // granite.py hardcodes False
298
+ return a;
299
+ },
300
+
301
+ /** starcoder2: LayerNorm (bias affine), bias on ALL projections, plain
302
+ * c_fc→gelu(precise)→c_proj MLP, theta 1e5. */
303
+ starcoder2: (raw) => {
304
+ const a = common(raw, "starcoder2");
305
+ a.normEps = raw.norm_epsilon ?? 1e-5;
306
+ a.vocabSize = raw.vocab_size ?? 49152;
307
+ a.ropeTheta = raw.rope_theta ?? 100000;
308
+ a.norm = "layernorm";
309
+ a.mlp = "gelu_mlp";
310
+ a.qkvBias = true;
311
+ a.oBias = true;
312
+ a.mlpBias = true;
313
+ a.rope = "plain";
314
+ a.ropeScaling = null;
315
+ return a;
316
+ },
317
+ };
318
+
319
+ /** Which cache each attention group reads its mask from, bound once per
320
+ * graph (mlx-lm llama.py): full layers from the first full layer's cache
321
+ * (cache 0 without sliding layers), sliding layers from the first sliding
322
+ * layer's cache with the window. `array`: the graph's manual attention needs
323
+ * an explicit mask (gemma2's return_array), spelled from that group's cache. */
324
+ export interface UniversalMaskRecipe {
325
+ readonly full: number;
326
+ readonly sliding: number | null;
327
+ readonly window: number | null;
328
+ readonly array: boolean;
329
+ readonly slidingLayers: readonly boolean[];
330
+ }
331
+
332
+ export function universalMaskRecipe(a: UniversalArgs): UniversalMaskRecipe {
333
+ const types = a.layerTypes;
334
+ const sliding = types?.includes("sliding_attention") ? types.indexOf("sliding_attention") : -1;
335
+ return Object.freeze({
336
+ full: sliding === -1 ? 0 : Math.max(0, types!.indexOf("full_attention")),
337
+ sliding: sliding === -1 ? null : sliding,
338
+ window: a.slidingWindow,
339
+ array: a.maskArray,
340
+ slidingLayers: Object.freeze(Array.from({ length: a.numHiddenLayers },
341
+ (_, i) => sliding !== -1 && types![i] === "sliding_attention")),
342
+ });
343
+ }
344
+
345
+ /** Each layer's cache, bound once per graph: a rotating window on a sliding
346
+ * layer that has a window, plain KV otherwise. */
347
+ export function universalCacheWindows(a: UniversalArgs): readonly (number | null)[] {
348
+ return Object.freeze(Array.from({ length: a.numHiddenLayers },
349
+ (_, i) => a.layerTypes?.[i] === "sliding_attention" && a.slidingWindow ? a.slidingWindow : null));
350
+ }
351
+
352
+ /** The declared generic support surface (post-remap model_types). */
353
+ export const GENERIC_MODEL_TYPES: ReadonlySet<string> = new Set(Object.keys(ARCHS));
354
+
355
+ /** Descriptor lookup for a loaded config; null ⇒ not generically supported. */
356
+ export function genericArgsFor(config: ModelConfig): UniversalArgs | null {
357
+ const arch = remapModelType(config.modelType);
358
+ const parse = ARCHS[arch];
359
+ if (!parse) return null;
360
+ const raw = (config.raw.text_config ?? config.raw) as Raw;
361
+ const args = parse(raw);
362
+ // keep the ORIGINAL model_type visible in errors/labels
363
+ args.modelType = config.modelType;
364
+ return args;
365
+ }