@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,479 @@
1
+ import type { ModelConfig } from "../../artifacts/config";
2
+ import type { Weights } from "../../artifacts/weights";
3
+ import { WeightAudit } from "../../artifacts/weight-audit";
4
+ import { MlxArray } from "@mlx-bun/mlx/array";
5
+ import { Dtype } from "@mlx-bun/mlx/ffi";
6
+ import * as ops from "@mlx-bun/mlx/ops";
7
+ import type { Cache } from "../../contracts/mlx/cache";
8
+ import type { TrellisRepresentations } from "../../kernels/trellis/index";
9
+ import { disposing } from "../../layers/helpers";
10
+ import { QuantizedLinear, QuantizedLinearPlain } from "../../layers/quantized-linear";
11
+ import { TrellisLinear } from "../../layers/trellis-linear";
12
+ import { TrellisReducePrompt, TrellisScatterPrompt, TrellisExpandReducePrompt, TrellisExpandScatterPrompt, type RowProjection } from "../../layers/trellis-prompt";
13
+ import { RMSNorm } from "../../layers/normalization";
14
+ import { compiledSwiglu } from "../../layers/swiglu";
15
+ import { initializeRope, phi3SuRope, UniversalRope } from "../../layers/rope";
16
+ import { loadLayerNorm, loadLinear, loadRmsNorm, type AnyLinear, type AnyNorm } from "../../layers/loading";
17
+ import { softcapAttentionReads } from "../../state/softcap-attention";
18
+ import { cleanupFailure } from "../../runtime/resources";
19
+ import type { ReadPhase } from "../graph";
20
+ import type { AttentionReadStrategy } from "../qwen/blocks";
21
+ import type { UniversalArgs } from "./archs";
22
+
23
+ /** The score-softcapped read as a block's read strategy: decode reads
24
+ * `appendDecode`, a window `appendWindow`; this graph has no committed append
25
+ * (its `appendKnown` is the window read), so a committed span reads as a window. */
26
+ export function softcapRead(softcap: number, window: number | null, arrayMasks: boolean): AttentionReadStrategy {
27
+ const reads = softcapAttentionReads(softcap, window, arrayMasks);
28
+ const byPhase: Readonly<Record<ReadPhase, typeof reads.appendDecode>> = {
29
+ decode: reads.appendDecode, window: reads.appendWindow, committed: reads.appendWindow,
30
+ };
31
+ return Object.freeze({ read: (cache: Cache, phase: ReadPhase, k: MlxArray, v: MlxArray) => byPhase[phase](cache, k, v) });
32
+ }
33
+
34
+ /** Adapter carriers retain the artifact projection payload and dimensions. */
35
+ function adapterTarget(_weights: Weights, _config: ModelConfig, _path: string, linear: AnyLinear): QuantizedLinear | TrellisLinear | null {
36
+ return linear instanceof QuantizedLinear || linear instanceof TrellisLinear ? linear : null;
37
+ }
38
+
39
+ export function stockProjection(base: AnyLinear): RowProjection {
40
+ return base instanceof QuantizedLinear ? new QuantizedLinearPlain(base) : base;
41
+ }
42
+ export function packedProjection(base: TrellisLinear): RowProjection {
43
+ return base.geometry.axis === 1 ? new TrellisReducePrompt(base) : new TrellisScatterPrompt(base);
44
+ }
45
+ export function expandedProjection(base: TrellisLinear): RowProjection {
46
+ return base.geometry.axis === 1 ? new TrellisExpandReducePrompt(base) : new TrellisExpandScatterPrompt(base);
47
+ }
48
+
49
+ // Read exact MLX dtype metadata at load. These lazy probes never evaluate or
50
+ // allocate an expanded weight; owning norms, ropes and payloads are reused.
51
+ export function normType(norm: AnyNorm | null, dtype: Dtype, width: number): Dtype {
52
+ if (!norm) return dtype;
53
+ using x = ops.zeros([1, width], dtype), out = norm.forward(x); return out.dtype;
54
+ }
55
+ function linearType(base: AnyLinear, dtype: Dtype): Dtype {
56
+ if (base instanceof TrellisLinear) return dtype;
57
+ using x = ops.zeros([1, base.inFeatures], dtype), out = stockProjection(base).forward(x); return out.dtype;
58
+ }
59
+ function promotedType(a: Dtype, b: Dtype): Dtype {
60
+ using x = ops.zeros([1], a), y = ops.zeros([1], b), out = ops.add(x,y); return out.dtype;
61
+ }
62
+ export function projectionFacts(layers: readonly UniversalLayer[], input: Dtype, width: number): {types: Map<AnyLinear,Dtype>; output: Dtype} {
63
+ const types = new Map<AnyLinear,Dtype>();
64
+ const linear = (base: AnyLinear, dtype: Dtype) => { types.set(base,dtype); return linearType(base,dtype); };
65
+ let current = input;
66
+ for (const layer of layers) {
67
+ const a = layer.a, attn = layer.attn, mlp = layer.mlp;
68
+ const xn = a.block === "post" ? current : normType(layer.inputNorm,current,width);
69
+ let q: Dtype, k: Dtype, v: Dtype;
70
+ if (attn.qkvProj) q = k = v = linear(attn.qkvProj,xn);
71
+ else { q = linear(attn.qProj!,xn); k = linear(attn.kProj!,xn); v = linear(attn.vProj!,xn); }
72
+ q = normType(attn.qNorm,q,a.qkNorm === "full" ? a.numHeads*a.headDim : a.headDim);
73
+ k = normType(attn.kNorm,k,a.qkNorm === "full" ? a.numKvHeads*a.headDim : a.headDim);
74
+ let attended: Dtype;
75
+ if (attn.softcap !== null) attended = promotedType(promotedType(q,k),v);
76
+ else {
77
+ using qq=ops.zeros([1,a.numHeads,1,a.headDim],q), kk=ops.zeros([1,a.numKvHeads,1,a.headDim],k), vv=ops.zeros([1,a.numKvHeads,1,a.headDim],v);
78
+ using out=ops.sdpa(qq,kk,vv,a.attnScale,"causal"); attended=out.dtype;
79
+ }
80
+ let r = linear(attn.oProj,attended);
81
+ if (a.block === "post" || a.block === "gemma2") r = normType(layer.postAttnNorm,r,width);
82
+ else if (a.block === "glm4") r = normType(layer.extraNorm1,r,width);
83
+ const h = promotedType(current,r);
84
+ const hn = a.block === "post" ? h : normType(a.block === "gemma2" ? layer.extraNorm1 : layer.postAttnNorm,h,width);
85
+ let mid: Dtype;
86
+ if (mlp.gateUp) mid=linear(mlp.gateUp,hn);
87
+ else {
88
+ const gate=linear(mlp.gate!,hn);
89
+ mid=mlp.up ? promotedType(gate,linear(mlp.up,hn)) : gate;
90
+ }
91
+ let out = linear(mlp.down,mid);
92
+ if (a.block === "post" || a.block === "gemma2" || a.block === "glm4") out=normType(layer.extraNorm2,out,width);
93
+ current=promotedType(h,out);
94
+ }
95
+ return {types,output:current};
96
+ }
97
+
98
+ /** Rope for one attention module, per the descriptor (llama's
99
+ * initialize_rope, the plain-nn.RoPE archs, or phi3's Su/linear branch). */
100
+ export function buildRope(a: UniversalArgs): UniversalRope {
101
+ const ropeDims = Math.floor(a.headDim * a.partialRotaryFactor);
102
+ if (a.rope === "phi3") {
103
+ const sc = a.ropeScaling;
104
+ if (sc && ["longrope", "su"].includes(String(sc.type))) {
105
+ return phi3SuRope(
106
+ ropeDims,
107
+ a.ropeTheta,
108
+ a.maxPositionEmbeddings ?? 131072,
109
+ a.originalMaxPositionEmbeddings,
110
+ (sc.long_factor as number[] | number | undefined) ?? 1.0,
111
+ );
112
+ }
113
+ let scale = 1.0;
114
+ if (sc && String(sc.type) === "linear") scale = 1 / (sc.factor as number);
115
+ return new UniversalRope(ropeDims, a.ropeTraditional, a.ropeTheta, scale, null, 1, false);
116
+ }
117
+ if (a.rope === "plain")
118
+ return new UniversalRope(ropeDims, a.ropeTraditional, a.ropeTheta, 1.0, null, 1, false);
119
+ // initialize_rope path (llama, qwen2, qwen3, olmo2, granite, smollm3)
120
+ return initializeRope(a.headDim, a.ropeTheta, a.ropeTraditional, a.ropeScaling, a.maxPositionEmbeddings);
121
+ }
122
+
123
+ export class UniversalAttention {
124
+ readonly qProj: AnyLinear | null;
125
+ readonly kProj: AnyLinear | null;
126
+ readonly vProj: AnyLinear | null;
127
+ readonly qkvProj: AnyLinear | null;
128
+ readonly oProj: AnyLinear;
129
+ readonly qNorm: RMSNorm | null;
130
+ readonly kNorm: RMSNorm | null;
131
+ /** Bound at construction: the score softcap composes the manual attention
132
+ * over dense K/V arrays (any storage, fetched dense) as this block's read;
133
+ * without it, the block reads through the cache's own read, which also
134
+ * attends encoded KV. */
135
+ readonly softcap: number | null;
136
+ /** The projections adapters mount on, read at load. */
137
+ readonly adapters: { readonly q: QuantizedLinear | TrellisLinear | null; readonly k: QuantizedLinear | TrellisLinear | null;
138
+ readonly v: QuantizedLinear | TrellisLinear | null; readonly qkv: QuantizedLinear | TrellisLinear | null; readonly o: QuantizedLinear | TrellisLinear | null };
139
+
140
+ constructor(
141
+ weights: Weights,
142
+ config: ModelConfig,
143
+ prefix: string,
144
+ readonly a: UniversalArgs,
145
+ readonly rope: UniversalRope,
146
+ audit: WeightAudit,
147
+ /** How the block reads its cache, composed by the graph from the descriptor. */
148
+ readonly reads: AttentionReadStrategy,
149
+ representations?: TrellisRepresentations,
150
+ ) {
151
+ this.softcap = a.attnLogitSoftcap;
152
+ const load = (name: string) => loadLinear(weights, `${prefix}.${name}`, config, audit, representations);
153
+ const target = (name: string, linear: AnyLinear | null) =>
154
+ linear && adapterTarget(weights, config, `${prefix}.${name}`, linear);
155
+ if (a.fusedQkv) {
156
+ this.qkvProj = load("qkv_proj");
157
+ this.qProj = this.kProj = this.vProj = null;
158
+ } else {
159
+ this.qProj = load("q_proj");
160
+ this.kProj = load("k_proj");
161
+ this.vProj = load("v_proj");
162
+ this.qkvProj = null;
163
+ }
164
+ this.oProj = load("o_proj");
165
+ this.adapters = Object.freeze({ q: target("q_proj", this.qProj), k: target("k_proj", this.kProj),
166
+ v: target("v_proj", this.vProj), qkv: target("qkv_proj", this.qkvProj), o: target("o_proj", this.oProj) });
167
+ if (a.qkNorm !== "none") {
168
+ // qwen3 ("head"): RMSNorm(head_dim); olmo2 ("full"): RMSNorm(width) —
169
+ // both live at q_norm/k_norm and use rms_norm_eps.
170
+ this.qNorm = loadRmsNorm(weights, `${prefix}.q_norm`, a.normEps, false, audit);
171
+ this.kNorm = loadRmsNorm(weights, `${prefix}.k_norm`, a.normEps, false, audit);
172
+ } else {
173
+ this.qNorm = this.kNorm = null;
174
+ }
175
+ }
176
+
177
+ /** `x` [B, L, hidden] (borrowed) to an owned [B, L, hidden], appending to
178
+ * `cache` and attending through the read `phase` names. */
179
+ forward(x: MlxArray, cache: Cache, phase: ReadPhase): MlxArray {
180
+ const a = this.a;
181
+ const [B, L] = x.shape as [number, number, number];
182
+
183
+ let q: MlxArray, k: MlxArray, v: MlxArray;
184
+ if (this.qkvProj) {
185
+ // phi3: fused projection, split as ACTIVATIONS (mx.split) like mlx-lm.
186
+ const qkv = this.qkvProj.forward(x);
187
+ const queryPos = a.numHeads * a.headDim;
188
+ const parts = ops.split(qkv, [queryPos, queryPos + a.numKvHeads * a.headDim], -1);
189
+ qkv.dispose();
190
+ [q, k, v] = parts as [MlxArray, MlxArray, MlxArray];
191
+ } else {
192
+ q = this.qProj!.forward(x);
193
+ k = this.kProj!.forward(x);
194
+ v = this.vProj!.forward(x);
195
+ }
196
+
197
+ if (a.qkNorm === "full") {
198
+ // olmo2: norm the FLAT projections before any reshape.
199
+ q = disposing(q, this.qNorm!.forward(q));
200
+ k = disposing(k, this.kNorm!.forward(k));
201
+ }
202
+
203
+ q = disposing(q, ops.reshape(q, [B, L, a.numHeads, -1]));
204
+ k = disposing(k, ops.reshape(k, [B, L, a.numKvHeads, -1]));
205
+ v = disposing(v, ops.reshape(v, [B, L, a.numKvHeads, -1]));
206
+
207
+ if (a.qkNorm === "head") {
208
+ // qwen3: per-head norm over head_dim, BEFORE transpose + rope.
209
+ q = disposing(q, this.qNorm!.forward(q));
210
+ k = disposing(k, this.kNorm!.forward(k));
211
+ }
212
+
213
+ q = disposing(q, ops.transposeAxes(q, [0, 2, 1, 3]));
214
+ k = disposing(k, ops.transposeAxes(k, [0, 2, 1, 3]));
215
+ v = disposing(v, ops.transposeAxes(v, [0, 2, 1, 3]));
216
+
217
+ // Batched decode: the scheduler's mask wrapper exposes each row's REAL
218
+ // position as ropeOffsetArr (rows have different prompt lengths under
219
+ // left-padding; the scalar offset would mis-position every padded row by
220
+ // its pad amount — the 2026-07-03 uneven-batch bug). One row: the scalar
221
+ // offset.
222
+ const offArr = (cache as { ropeOffsetArr?: MlxArray }).ropeOffsetArr;
223
+ q = disposing(q, offArr
224
+ ? this.rope.applyDynamic(q, offArr)
225
+ : this.rope.apply(q, cache.offset));
226
+ k = disposing(k, offArr
227
+ ? this.rope.applyDynamic(k, offArr)
228
+ : this.rope.apply(k, cache.offset));
229
+
230
+ // The read holds its mask: a failed release keeps the attention output
231
+ // from leaking, and an attention failure stays the primary error.
232
+ let attn: MlxArray;
233
+ try {
234
+ const read = this.reads.read(cache, phase, k, v);
235
+ try { attn = read.attend(q, a.attnScale); }
236
+ catch (error) { return cleanupFailure(error, () => read.dispose()); }
237
+ try { read.dispose(); }
238
+ catch (error) { return cleanupFailure(error, () => attn.dispose()); }
239
+ } finally { k.dispose(); v.dispose(); q.dispose(); }
240
+
241
+ const attnT = ops.transposeAxes(attn, [0, 2, 1, 3]);
242
+ attn.dispose();
243
+ const merged = ops.reshape(attnT, [B, L, -1]);
244
+ attnT.dispose();
245
+ const out = this.oProj.forward(merged);
246
+ merged.dispose();
247
+ return out;
248
+ }
249
+ }
250
+
251
+ /** swiglu(gate, up) = nn.silu(gate) * up as ONE call — the whole activation,
252
+ * not just silu. Defaults to the `@mx.compile` version (compiledSwiglu) — the
253
+ * same libmlx kernel mlx-lm dispatches (L1-faithful), bit-identical to the old
254
+ * uncompiled composition but one dispatch instead of three. Set to null to force
255
+ * the uncompiled path (the slower same-parity opt-in). */
256
+ export type SwigluFn = (gate: MlxArray, up: MlxArray) => MlxArray;
257
+
258
+ export class UniversalMLP {
259
+ readonly gate: AnyLinear | null;
260
+ readonly up: AnyLinear | null;
261
+ readonly gateUp: AnyLinear | null;
262
+ readonly down: AnyLinear;
263
+ /** Fused swiglu (silu(gate)*up), default = the oracle's `@mx.compile` closure.
264
+ * Only consumed for the swiglu / fused_swiglu kinds; geglu/geglu_approx/gelu_mlp
265
+ * are unaffected (the oracle does NOT @mx.compile those — gemma/gemma2/starcoder2
266
+ * use a plain nn.gelu composition). Set to null for the uncompiled composition. */
267
+ swigluFn: SwigluFn | null = compiledSwiglu;
268
+ /** The projections adapters mount on, read at load. */
269
+ readonly adapters: { readonly gate: QuantizedLinear | TrellisLinear | null; readonly up: QuantizedLinear | TrellisLinear | null;
270
+ readonly gateUp: QuantizedLinear | TrellisLinear | null; readonly down: QuantizedLinear | TrellisLinear | null };
271
+
272
+ constructor(
273
+ weights: Weights,
274
+ config: ModelConfig,
275
+ prefix: string,
276
+ readonly kind: UniversalArgs["mlp"],
277
+ audit: WeightAudit,
278
+ representations?: TrellisRepresentations,
279
+ ) {
280
+ const load = (name: string) => loadLinear(weights, `${prefix}.${name}`, config, audit, representations);
281
+ const target = (name: string, linear: AnyLinear) => adapterTarget(weights, config, `${prefix}.${name}`, linear);
282
+ if (kind === "fused_swiglu") {
283
+ this.gateUp = load("gate_up_proj");
284
+ this.gate = this.up = null;
285
+ this.down = load("down_proj");
286
+ this.adapters = Object.freeze({ gate: null, up: null, gateUp: target("gate_up_proj", this.gateUp), down: target("down_proj", this.down) });
287
+ } else if (kind === "gelu_mlp") {
288
+ // starcoder2: c_fc → gelu(precise) → c_proj
289
+ this.gate = load("c_fc");
290
+ this.up = this.gateUp = null;
291
+ this.down = load("c_proj");
292
+ this.adapters = Object.freeze({ gate: target("c_fc", this.gate), up: null, gateUp: null, down: target("c_proj", this.down) });
293
+ } else {
294
+ this.gate = load("gate_proj");
295
+ this.up = load("up_proj");
296
+ this.gateUp = null;
297
+ this.down = load("down_proj");
298
+ this.adapters = Object.freeze({ gate: target("gate_proj", this.gate), up: target("up_proj", this.up), gateUp: null,
299
+ down: target("down_proj", this.down) });
300
+ }
301
+ }
302
+
303
+ forward(x: MlxArray): MlxArray {
304
+ if (this.kind === "gelu_mlp") {
305
+ const h = this.gate!.forward(x);
306
+ const g = ops.geluPrecise(h);
307
+ h.dispose();
308
+ const out = this.down.forward(g);
309
+ g.dispose();
310
+ return out;
311
+ }
312
+
313
+ let gate: MlxArray;
314
+ let up: MlxArray;
315
+ if (this.kind === "fused_swiglu") {
316
+ const gu = this.gateUp!.forward(x);
317
+ const half = Math.floor(gu.shape[gu.shape.length - 1]! / 2);
318
+ const parts = ops.split(gu, [half], -1); // mx.split(x, 2, axis=-1)
319
+ gu.dispose();
320
+ [gate, up] = parts as [MlxArray, MlxArray];
321
+ } else {
322
+ gate = this.gate!.forward(x);
323
+ up = this.up!.forward(x);
324
+ }
325
+
326
+ // swiglu / fused_swiglu run silu(gate)*up as ONE fused call (mlx-lm's
327
+ // `@mx.compile swiglu`), matching the oracle kernel set exactly. This is the
328
+ // default (swigluFn = compiledSwiglu); null forces the uncompiled composition.
329
+ if (this.swigluFn && (this.kind === "swiglu" || this.kind === "fused_swiglu")) {
330
+ const hidden = this.swigluFn(gate, up);
331
+ gate.dispose();
332
+ up.dispose();
333
+ const out = this.down.forward(hidden);
334
+ hidden.dispose();
335
+ return out;
336
+ }
337
+
338
+ let act: MlxArray;
339
+ if (this.kind === "geglu") {
340
+ act = ops.geluPrecise(gate); // gemma-1: nn.gelu (erf)
341
+ } else if (this.kind === "geglu_approx") {
342
+ act = ops.geluApprox(gate); // gemma2: nn.gelu_approx
343
+ } else {
344
+ // swiglu — the L1-verified uncompiled composition (minicpm5/qwen3):
345
+ const sig = ops.sigmoid(gate);
346
+ act = ops.mul(gate, sig);
347
+ sig.dispose();
348
+ }
349
+ gate.dispose();
350
+ const hidden = ops.mul(act, up);
351
+ act.dispose();
352
+ up.dispose();
353
+ const out = this.down.forward(hidden);
354
+ hidden.dispose();
355
+ return out;
356
+ }
357
+ }
358
+
359
+ export class UniversalLayer {
360
+ readonly attn: UniversalAttention;
361
+ readonly mlp: UniversalMLP;
362
+ /** pre/gemma2/glm4: input_layernorm. post (olmo2): unused (null). */
363
+ readonly inputNorm: AnyNorm | null;
364
+ /** pre: post_attention_layernorm (pre-MLP). post: post_attention (on
365
+ * attn out). gemma2: post_attention (on attn out). glm4:
366
+ * post_attention (pre-MLP). */
367
+ readonly postAttnNorm: AnyNorm;
368
+ /** gemma2: pre_feedforward. glm4: post_self_attn (on attn out). */
369
+ readonly extraNorm1: AnyNorm | null;
370
+ /** gemma2: post_feedforward. glm4: post_mlp. post: post_feedforward. */
371
+ readonly extraNorm2: AnyNorm | null;
372
+
373
+ constructor(
374
+ weights: Weights,
375
+ config: ModelConfig,
376
+ prefix: string,
377
+ readonly a: UniversalArgs,
378
+ rope: UniversalRope,
379
+ audit: WeightAudit,
380
+ reads: AttentionReadStrategy,
381
+ representations?: TrellisRepresentations,
382
+ ) {
383
+ this.attn = new UniversalAttention(weights, config, `${prefix}.self_attn`, a, rope, audit, reads, representations);
384
+ this.mlp = new UniversalMLP(weights, config, `${prefix}.mlp`, a.mlp, audit, representations);
385
+ const norm = (name: string): AnyNorm =>
386
+ a.norm === "layernorm"
387
+ ? loadLayerNorm(weights, `${prefix}.${name}`, a.normEps, audit)
388
+ : loadRmsNorm(weights, `${prefix}.${name}`, a.normEps, a.norm === "rmsnorm_plus_one", audit);
389
+
390
+ this.postAttnNorm = norm("post_attention_layernorm");
391
+ if (a.block === "post") {
392
+ this.inputNorm = null;
393
+ this.extraNorm1 = null;
394
+ this.extraNorm2 = norm("post_feedforward_layernorm");
395
+ } else if (a.block === "gemma2") {
396
+ this.inputNorm = norm("input_layernorm");
397
+ this.extraNorm1 = norm("pre_feedforward_layernorm");
398
+ this.extraNorm2 = norm("post_feedforward_layernorm");
399
+ } else if (a.block === "glm4") {
400
+ this.inputNorm = norm("input_layernorm");
401
+ this.extraNorm1 = norm("post_self_attn_layernorm");
402
+ this.extraNorm2 = norm("post_mlp_layernorm");
403
+ } else {
404
+ this.inputNorm = norm("input_layernorm");
405
+ this.extraNorm1 = null;
406
+ this.extraNorm2 = null;
407
+ }
408
+ }
409
+
410
+ forward(x: MlxArray, cache: Cache, phase: ReadPhase): MlxArray {
411
+ const a = this.a;
412
+ if (a.block === "post") {
413
+ // olmo2: h = x + norm(attn(x)); out = h + norm(mlp(h))
414
+ const r1 = this.attn.forward(x, cache, phase);
415
+ const n1 = disposing(r1, this.postAttnNorm.forward(r1));
416
+ const h = ops.add(x, n1);
417
+ n1.dispose();
418
+ const r2 = this.mlp.forward(h);
419
+ const n2 = disposing(r2, this.extraNorm2!.forward(r2));
420
+ const out = ops.add(h, n2);
421
+ h.dispose();
422
+ n2.dispose();
423
+ return out;
424
+ }
425
+ if (a.block === "gemma2") {
426
+ // h = x + postAttn(attn(inputNorm(x))); out = h + postFfn(mlp(preFfn(h)))
427
+ const xn = this.inputNorm!.forward(x);
428
+ const r1 = this.attn.forward(xn, cache, phase);
429
+ xn.dispose();
430
+ const n1 = disposing(r1, this.postAttnNorm.forward(r1));
431
+ const h = ops.add(x, n1);
432
+ n1.dispose();
433
+ const fn = this.extraNorm1!.forward(h);
434
+ const r2 = this.mlp.forward(fn);
435
+ fn.dispose();
436
+ const n2 = disposing(r2, this.extraNorm2!.forward(r2));
437
+ const out = ops.add(h, n2);
438
+ h.dispose();
439
+ n2.dispose();
440
+ return out;
441
+ }
442
+ if (a.block === "glm4") {
443
+ // x1 = x + postSelfAttn(attn(inputNorm(x)));
444
+ // out = postMlp(mlp(postAttn(x1))) + x1
445
+ const xn = this.inputNorm!.forward(x);
446
+ const r1 = this.attn.forward(xn, cache, phase);
447
+ xn.dispose();
448
+ const n1 = disposing(r1, this.extraNorm1!.forward(r1));
449
+ const x1 = ops.add(x, n1);
450
+ n1.dispose();
451
+ const pn = this.postAttnNorm.forward(x1);
452
+ const r2 = this.mlp.forward(pn);
453
+ pn.dispose();
454
+ const n2 = disposing(r2, this.extraNorm2!.forward(r2));
455
+ const out = ops.add(n2, x1);
456
+ n2.dispose();
457
+ x1.dispose();
458
+ return out;
459
+ }
460
+ // pre (llama family): h = x + r·mult; out = h + r·mult
461
+ const xn = this.inputNorm!.forward(x);
462
+ let r1 = this.attn.forward(xn, cache, phase);
463
+ xn.dispose();
464
+ if (a.residualMultiplier !== null)
465
+ r1 = disposing(r1, ops.mulScalar(r1, a.residualMultiplier));
466
+ const h = ops.add(x, r1);
467
+ r1.dispose();
468
+ const hn = this.postAttnNorm.forward(h);
469
+ let r2 = this.mlp.forward(hn);
470
+ hn.dispose();
471
+ if (a.residualMultiplier !== null)
472
+ r2 = disposing(r2, ops.mulScalar(r2, a.residualMultiplier));
473
+ const out = ops.add(h, r2);
474
+ h.dispose();
475
+ r2.dispose();
476
+ return out;
477
+ }
478
+ }
479
+