@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.
- package/LICENSE +21 -0
- package/README.md +1475 -2
- package/THIRD_PARTY_NOTICES.md +3404 -0
- package/dist/native/libmlx_bun_ane.dylib +0 -0
- package/dist/native/libmlx_bun_expert_io.dylib +0 -0
- package/dist/native/mlx-bun-frame-extract +0 -0
- package/examples/fit-model.ts +25 -0
- package/examples/qwen3-forward.ts +42 -0
- package/examples/qwen3-generate.ts +28 -0
- package/examples/trellis-expand.ts +23 -0
- package/package.json +129 -4
- package/src/adapters/available.ts +110 -0
- package/src/adapters/index.ts +3 -0
- package/src/adapters/manager.ts +316 -0
- package/src/artifacts/auxiliary-files.ts +45 -0
- package/src/artifacts/config-dialects.ts +94 -0
- package/src/artifacts/config.ts +341 -0
- package/src/artifacts/draft-vocabulary.ts +30 -0
- package/src/artifacts/expert-offload-build.ts +75 -0
- package/src/artifacts/expert-offload.ts +89 -0
- package/src/artifacts/experts/index.ts +3 -0
- package/src/artifacts/experts/io.ts +386 -0
- package/src/artifacts/experts/residency.ts +1134 -0
- package/src/artifacts/experts/usage.ts +415 -0
- package/src/artifacts/fingerprint.ts +44 -0
- package/src/artifacts/glm52/container.ts +305 -0
- package/src/artifacts/glm52/expert-layout.ts +249 -0
- package/src/artifacts/glm52/index.ts +7 -0
- package/src/artifacts/glm52/kernel-layout.ts +124 -0
- package/src/artifacts/glm52/layout.ts +152 -0
- package/src/artifacts/glm52/memory.ts +500 -0
- package/src/artifacts/glm52/resident-weights.ts +135 -0
- package/src/artifacts/glm52/weights.ts +503 -0
- package/src/artifacts/glm52-config.ts +262 -0
- package/src/artifacts/identity.ts +94 -0
- package/src/artifacts/index.ts +15 -0
- package/src/artifacts/mmap.ts +90 -0
- package/src/artifacts/safetensors-writer.ts +249 -0
- package/src/artifacts/safetensors.ts +164 -0
- package/src/artifacts/turboquant-fold.ts +42 -0
- package/src/artifacts/weight-audit.ts +43 -0
- package/src/artifacts/weights.ts +255 -0
- package/src/contracts/index.ts +2 -0
- package/src/contracts/mlx/attention.ts +8 -0
- package/src/contracts/mlx/cache.ts +510 -0
- package/src/contracts/mlx/checkpoint.ts +10 -0
- package/src/contracts/mlx/draft-checkpoint.ts +14 -0
- package/src/contracts/mlx/draft-projection.ts +27 -0
- package/src/contracts/mlx/draft-target.ts +84 -0
- package/src/contracts/mlx/drafter.ts +176 -0
- package/src/contracts/mlx/forward-work.ts +23 -0
- package/src/contracts/mlx/glm52-weights.ts +25 -0
- package/src/contracts/mlx/graph.ts +309 -0
- package/src/contracts/mlx/head.ts +6 -0
- package/src/contracts/mlx/index.ts +15 -0
- package/src/contracts/mlx/kv-codec.ts +9 -0
- package/src/contracts/mlx/media.ts +113 -0
- package/src/contracts/mlx/positions.ts +16 -0
- package/src/contracts/mlx/row-table.ts +2 -0
- package/src/contracts/mlx/trainable.ts +103 -0
- package/src/contracts/mlx/whisper.ts +96 -0
- package/src/contracts/portable/composition.ts +106 -0
- package/src/contracts/portable/denoising.ts +17 -0
- package/src/contracts/portable/execution.ts +79 -0
- package/src/contracts/portable/generation.ts +103 -0
- package/src/contracts/portable/graph.ts +80 -0
- package/src/contracts/portable/index.ts +15 -0
- package/src/contracts/portable/memory-plan.ts +26 -0
- package/src/contracts/portable/object-cache.ts +8 -0
- package/src/contracts/portable/prefill.ts +63 -0
- package/src/contracts/portable/prefix-cache.ts +33 -0
- package/src/contracts/portable/prompt.ts +2 -0
- package/src/contracts/portable/resources.ts +25 -0
- package/src/contracts/portable/rollback.ts +7 -0
- package/src/contracts/portable/sampling.ts +44 -0
- package/src/contracts/portable/scheduling.ts +54 -0
- package/src/contracts/portable/token-delivery.ts +4 -0
- package/src/contracts/portable/tsconfig.json +14 -0
- package/src/embeddings/index.ts +1 -0
- package/src/embeddings/text.ts +85 -0
- package/src/execution/admission.ts +59 -0
- package/src/execution/batch-group.ts +1240 -0
- package/src/execution/batch-types.ts +225 -0
- package/src/execution/cancellation.ts +38 -0
- package/src/execution/continuation-request.ts +45 -0
- package/src/execution/continuation-types.ts +10 -0
- package/src/execution/coordinator.ts +70 -0
- package/src/execution/denoising-group.ts +180 -0
- package/src/execution/engine.ts +56 -0
- package/src/execution/fill-group.ts +505 -0
- package/src/execution/fit.ts +184 -0
- package/src/execution/gateway-binding.ts +178 -0
- package/src/execution/grammar-group.ts +224 -0
- package/src/execution/index.ts +18 -0
- package/src/execution/methods.ts +75 -0
- package/src/execution/mixed-iteration.ts +96 -0
- package/src/execution/plan.ts +65 -0
- package/src/execution/prefill-cohort.ts +100 -0
- package/src/execution/prefill-rows.ts +263 -0
- package/src/execution/request-policy.ts +19 -0
- package/src/execution/row-sampling.ts +49 -0
- package/src/execution/scheduler.ts +92 -0
- package/src/execution/session.ts +247 -0
- package/src/execution/speculative-group.ts +797 -0
- package/src/execution/tasks.ts +44 -0
- package/src/generation/autoregressive.ts +840 -0
- package/src/generation/bindings/autoregressive.ts +104 -0
- package/src/generation/bindings/denoising.ts +60 -0
- package/src/generation/bindings/prefill-policy.ts +36 -0
- package/src/generation/checkpoint-identity.ts +60 -0
- package/src/generation/denoising.ts +85 -0
- package/src/generation/diffusion.ts +583 -0
- package/src/generation/fill/echo-index.ts +188 -0
- package/src/generation/fill/index.ts +3 -0
- package/src/generation/fill/proposal.ts +69 -0
- package/src/generation/fill/schema-rows.ts +506 -0
- package/src/generation/fill/session.ts +464 -0
- package/src/generation/fill/tool-boundary.ts +103 -0
- package/src/generation/fill-append.ts +58 -0
- package/src/generation/generate.ts +44 -0
- package/src/generation/grammar-step.ts +39 -0
- package/src/generation/index.ts +14 -0
- package/src/generation/phase-dispatch.ts +115 -0
- package/src/generation/prefill.ts +33 -0
- package/src/generation/result.ts +49 -0
- package/src/generation/scopes.ts +157 -0
- package/src/generation/speculative/acceptance.ts +41 -0
- package/src/generation/speculative/adaptive-draft-gate.ts +166 -0
- package/src/generation/speculative/bindings/assistant-rows.ts +102 -0
- package/src/generation/speculative/bindings/autoregressive-rows.ts +124 -0
- package/src/generation/speculative/bindings/binding.ts +106 -0
- package/src/generation/speculative/bindings/deepspec-rows.ts +33 -0
- package/src/generation/speculative/bindings/draft-target.ts +10 -0
- package/src/generation/speculative/bindings/glm52-mtp-rows.ts +128 -0
- package/src/generation/speculative/bindings/projected-context-rows.ts +78 -0
- package/src/generation/speculative/bindings/projected-draft-rows.ts +95 -0
- package/src/generation/speculative/bindings/qwen-mtp-rows.ts +336 -0
- package/src/generation/speculative/bindings/two-model-rows.ts +63 -0
- package/src/generation/speculative/cache-identity.ts +16 -0
- package/src/generation/speculative/draft-kind.ts +149 -0
- package/src/generation/speculative/draft-policy.ts +41 -0
- package/src/generation/speculative/draft-registry.ts +118 -0
- package/src/generation/speculative/draft-vocab.ts +110 -0
- package/src/generation/speculative/index.ts +17 -0
- package/src/generation/speculative/output.ts +49 -0
- package/src/generation/speculative/round.ts +307 -0
- package/src/generation/speculative/source.ts +144 -0
- package/src/generation/speculative/sources/assistant-source.ts +64 -0
- package/src/generation/speculative/sources/deepspec-source.ts +70 -0
- package/src/generation/speculative/sources/dflash-source.ts +84 -0
- package/src/generation/speculative/sources/dflash2-source.ts +86 -0
- package/src/generation/speculative/sources/glm52-mtp-source.ts +66 -0
- package/src/generation/speculative/sources/ngram-source.ts +165 -0
- package/src/generation/speculative/sources/qwen-mtp-source.ts +154 -0
- package/src/generation/speculative/sources/two-model.ts +75 -0
- package/src/generation/types.ts +194 -0
- package/src/index.ts +20 -0
- package/src/input/audio/audiotoolbox.ts +112 -0
- package/src/input/audio/decode.ts +133 -0
- package/src/input/audio/features.ts +202 -0
- package/src/input/audio/index.ts +6 -0
- package/src/input/audio/transcode.ts +67 -0
- package/src/input/audio/whisper-mel.ts +185 -0
- package/src/input/audio/whisper-tokenizer.ts +238 -0
- package/src/input/chat-template.ts +389 -0
- package/src/input/index.ts +6 -0
- package/src/input/media-fetch.ts +439 -0
- package/src/input/packed-mixed.ts +43 -0
- package/src/input/special-tokens.ts +75 -0
- package/src/input/token-groups.ts +49 -0
- package/src/input/tokenizer.ts +336 -0
- package/src/input/tool-call.ts +689 -0
- package/src/input/vision/index.ts +3 -0
- package/src/input/vision/preprocess.ts +247 -0
- package/src/input/vision/prompt.ts +398 -0
- package/src/input/vision/qwen3vl-preprocess.ts +409 -0
- package/src/input/vision/qwen3vl-prompt.ts +237 -0
- package/src/input/vision/video-frames.ts +100 -0
- package/src/kernels/ane/fill.ts +101 -0
- package/src/kernels/ane/linear.ts +416 -0
- package/src/kernels/attention/flash.ts +694 -0
- package/src/kernels/attention/kvq4-decode.ts +155 -0
- package/src/kernels/attention/masks.ts +40 -0
- package/src/kernels/attention/multi-query.ts +193 -0
- package/src/kernels/attention/paged.ts +130 -0
- package/src/kernels/delta/gated.ts +306 -0
- package/src/kernels/delta/index.ts +3 -0
- package/src/kernels/delta/silu-rms-heads.ts +69 -0
- package/src/kernels/delta/state.ts +74 -0
- package/src/kernels/gated-rms-norm.ts +64 -0
- package/src/kernels/glm52/layout.ts +37 -0
- package/src/kernels/glm52/streamed-experts.ts +360 -0
- package/src/kernels/logits.ts +38 -0
- package/src/kernels/quantization/affine-row.ts +154 -0
- package/src/kernels/quantization/affine-rows.ts +36 -0
- package/src/kernels/quantization/affine-split-mma.ts +144 -0
- package/src/kernels/quantization/affine3-mma.ts +117 -0
- package/src/kernels/quantization/affine3-rows.ts +103 -0
- package/src/kernels/quantization/affine4-mma.ts +113 -0
- package/src/kernels/quantization/affine4-rows.ts +102 -0
- package/src/kernels/residual-rms-norm.ts +65 -0
- package/src/kernels/sampling/index.ts +2 -0
- package/src/kernels/sampling/normalized-argmax.ts +116 -0
- package/src/kernels/sampling/token-bitmask.ts +52 -0
- package/src/kernels/softcap.ts +35 -0
- package/src/kernels/trellis/codebook.ts +123 -0
- package/src/kernels/trellis/down-codebook.ts +184 -0
- package/src/kernels/trellis/down-factored.ts +180 -0
- package/src/kernels/trellis/down-k3-interleaved-factored.ts +146 -0
- package/src/kernels/trellis/down-mma-wide.ts +195 -0
- package/src/kernels/trellis/down-mma.ts +145 -0
- package/src/kernels/trellis/expand.ts +42 -0
- package/src/kernels/trellis/gate-up-codebook-mma.ts +141 -0
- package/src/kernels/trellis/gate-up-codebook.ts +137 -0
- package/src/kernels/trellis/gate-up-factored.ts +197 -0
- package/src/kernels/trellis/gate-up-mma-wide.ts +147 -0
- package/src/kernels/trellis/gate-up-mma.ts +148 -0
- package/src/kernels/trellis/gate-up.ts +248 -0
- package/src/kernels/trellis/geometry.ts +22 -0
- package/src/kernels/trellis/index.ts +103 -0
- package/src/kernels/trellis/launch.ts +12 -0
- package/src/kernels/trellis/mixed-gate-up-factored.ts +119 -0
- package/src/kernels/trellis/mixed-gate-up.ts +146 -0
- package/src/kernels/trellis/qualified.ts +34 -0
- package/src/kernels/trellis/reduce.ts +150 -0
- package/src/kernels/trellis/scatter.ts +407 -0
- package/src/kernels/trellis/splitk-prefill.ts +152 -0
- package/src/kernels/trellis/tiled-prefill.ts +131 -0
- package/src/kernels/trellis/vector-expand.ts +58 -0
- package/src/kernels/trellis/wide-prefill.ts +89 -0
- package/src/kernels/turboquant/decode.ts +82 -0
- package/src/kernels/turboquant/index.ts +5 -0
- package/src/kernels/turboquant/inverse.ts +122 -0
- package/src/kernels/turboquant/ops.ts +860 -0
- package/src/kernels/turboquant/signs.ts +130 -0
- package/src/kernels/turboquant/tables.ts +124 -0
- package/src/layers/affine-verify-linear.ts +75 -0
- package/src/layers/ane-prefill-split.ts +283 -0
- package/src/layers/compiled-normalization.ts +41 -0
- package/src/layers/delta-heads.ts +23 -0
- package/src/layers/dense-embedding.ts +29 -0
- package/src/layers/dense-linear.ts +32 -0
- package/src/layers/dequantized-linear.ts +72 -0
- package/src/layers/folded-attention.ts +42 -0
- package/src/layers/geglu.ts +130 -0
- package/src/layers/helpers.ts +7 -0
- package/src/layers/index.ts +36 -0
- package/src/layers/kv4-decode-attention.ts +15 -0
- package/src/layers/layer-norm.ts +24 -0
- package/src/layers/loading.ts +92 -0
- package/src/layers/lora.ts +150 -0
- package/src/layers/normalization.ts +9 -0
- package/src/layers/prefix-layout.ts +33 -0
- package/src/layers/quantized-append-attention.ts +32 -0
- package/src/layers/quantized-attention.ts +353 -0
- package/src/layers/quantized-embedding.ts +39 -0
- package/src/layers/quantized-linear.ts +137 -0
- package/src/layers/quantized-switch-linear.ts +37 -0
- package/src/layers/qwen-append.ts +12 -0
- package/src/layers/qwen-mrope.ts +238 -0
- package/src/layers/rope-2d.ts +110 -0
- package/src/layers/rope.ts +389 -0
- package/src/layers/swiglu.ts +23 -0
- package/src/layers/trellis-codebook-down.ts +52 -0
- package/src/layers/trellis-codebook-gate-up.ts +42 -0
- package/src/layers/trellis-down.ts +117 -0
- package/src/layers/trellis-gate-up.ts +71 -0
- package/src/layers/trellis-linear.ts +211 -0
- package/src/layers/trellis-prompt.ts +102 -0
- package/src/layers/trellis-reduce-gate-up.ts +73 -0
- package/src/layers/trellis-scatter-down.ts +98 -0
- package/src/models/ane-install.ts +74 -0
- package/src/models/audio/conformer.ts +656 -0
- package/src/models/cache-composition.ts +44 -0
- package/src/models/capabilities.ts +89 -0
- package/src/models/chat-template.ts +10 -0
- package/src/models/composition.ts +107 -0
- package/src/models/diffusion-gemma/experts.ts +59 -0
- package/src/models/diffusion-gemma/family.ts +21 -0
- package/src/models/diffusion-gemma/model.ts +900 -0
- package/src/models/diffusion-gemma/vision.ts +549 -0
- package/src/models/drafter-loaders.ts +49 -0
- package/src/models/drafters.ts +39 -0
- package/src/models/factory.ts +351 -0
- package/src/models/families.ts +70 -0
- package/src/models/family.ts +125 -0
- package/src/models/gemma4/assistant-target.ts +46 -0
- package/src/models/gemma4/assistant.ts +327 -0
- package/src/models/gemma4/blocks.ts +755 -0
- package/src/models/gemma4/compiled-decode.ts +452 -0
- package/src/models/gemma4/family.ts +39 -0
- package/src/models/gemma4/gemma4-12b.ts +677 -0
- package/src/models/gemma4/gemma4-26b.ts +544 -0
- package/src/models/gemma4/gemma4-e4b.ts +599 -0
- package/src/models/gemma4/graphs.ts +147 -0
- package/src/models/gemma4/media.ts +88 -0
- package/src/models/gemma4/model.ts +860 -0
- package/src/models/gemma4/serving-blocks.ts +72 -0
- package/src/models/gemma4/trainable.ts +186 -0
- package/src/models/gemma4/written-blocks.ts +232 -0
- package/src/models/gemma4/written-forward.ts +159 -0
- package/src/models/gemma4/written-input.ts +29 -0
- package/src/models/glm52/atlas.ts +507 -0
- package/src/models/glm52/coupling.ts +388 -0
- package/src/models/glm52/dsa.ts +601 -0
- package/src/models/glm52/family.ts +20 -0
- package/src/models/glm52/mla.ts +812 -0
- package/src/models/glm52/model.ts +1127 -0
- package/src/models/glm52/moe.ts +223 -0
- package/src/models/glm52/mtp.ts +60 -0
- package/src/models/glm52/pilot.ts +537 -0
- package/src/models/glm52/reference.ts +445 -0
- package/src/models/glm52/residency.ts +557 -0
- package/src/models/glm52/streamed-experts.ts +447 -0
- package/src/models/graph.ts +59 -0
- package/src/models/implementation.ts +230 -0
- package/src/models/index.ts +15 -0
- package/src/models/media-input.ts +15 -0
- package/src/models/memory-plan.ts +39 -0
- package/src/models/minicpm5/family.ts +29 -0
- package/src/models/minicpm5/model.ts +394 -0
- package/src/models/minicpm5/trainable.ts +90 -0
- package/src/models/profile.ts +337 -0
- package/src/models/qwen/blocks.ts +658 -0
- package/src/models/qwen/checkpoint.ts +190 -0
- package/src/models/qwen/families.ts +57 -0
- package/src/models/qwen/media-input.ts +161 -0
- package/src/models/qwen/mtp.ts +101 -0
- package/src/models/qwen/qwen3-moe.ts +355 -0
- package/src/models/qwen/qwen3.ts +323 -0
- package/src/models/qwen/qwen38-27b-trellis-m1max.ts +1532 -0
- package/src/models/qwen/qwen38-27b-trellis-m4pro.ts +1092 -0
- package/src/models/qwen/qwen3_5.ts +433 -0
- package/src/models/qwen/written-layers.ts +285 -0
- package/src/models/row-table.ts +1 -0
- package/src/models/runtime.ts +73 -0
- package/src/models/speculative/deepspec-artifact.ts +10 -0
- package/src/models/speculative/deepspec.ts +744 -0
- package/src/models/speculative/dflash.ts +553 -0
- package/src/models/speculative/dflash2-artifact.ts +9 -0
- package/src/models/speculative/dflash2-operations.ts +1 -0
- package/src/models/speculative/dflash2.ts +576 -0
- package/src/models/speculative/loader.ts +29 -0
- package/src/models/support.ts +79 -0
- package/src/models/universal/archs.ts +365 -0
- package/src/models/universal/blocks.ts +479 -0
- package/src/models/universal/dense.ts +255 -0
- package/src/models/universal/family.ts +17 -0
- package/src/models/vision/qwen3vl.ts +566 -0
- package/src/models/vision/siglip.ts +520 -0
- package/src/models/vision/unified.ts +176 -0
- package/src/models/whisper/family.ts +19 -0
- package/src/models/whisper/fast.ts +734 -0
- package/src/models/whisper/model.ts +430 -0
- package/src/runtime/compiled-trace.ts +16 -0
- package/src/runtime/config.ts +77 -0
- package/src/runtime/expert-trace.ts +71 -0
- package/src/runtime/graph-forward.ts +65 -0
- package/src/runtime/integers.ts +6 -0
- package/src/runtime/native.ts +16 -0
- package/src/runtime/resources.ts +53 -0
- package/src/runtime/row-operations.ts +42 -0
- package/src/runtime/trace.ts +161 -0
- package/src/sampling/curve.ts +122 -0
- package/src/sampling/draft.ts +55 -0
- package/src/sampling/extras.ts +45 -0
- package/src/sampling/filters.ts +134 -0
- package/src/sampling/grammar.ts +630 -0
- package/src/sampling/hlg.ts +290 -0
- package/src/sampling/index.ts +9 -0
- package/src/sampling/processors.ts +142 -0
- package/src/sampling/sampler.ts +120 -0
- package/src/sampling/step.ts +343 -0
- package/src/sampling/types.ts +161 -0
- package/src/sampling/window-filters.ts +46 -0
- package/src/scoring/decisions.ts +96 -0
- package/src/scoring/full-sequence.ts +103 -0
- package/src/scoring/index.ts +9 -0
- package/src/scoring/kl.ts +29 -0
- package/src/scoring/perplexity.ts +165 -0
- package/src/scoring/response-logps.ts +65 -0
- package/src/state/affine-attention.ts +180 -0
- package/src/state/attachment.ts +68 -0
- package/src/state/attention-read.ts +215 -0
- package/src/state/batched-kv.ts +294 -0
- package/src/state/batched-mask.ts +445 -0
- package/src/state/batched-quant.ts +389 -0
- package/src/state/batched-quantized-kv.ts +209 -0
- package/src/state/batched-rotating-quant.ts +457 -0
- package/src/state/batched-rotating-state.ts +149 -0
- package/src/state/batched-rotating.ts +430 -0
- package/src/state/batched-row-storage.ts +179 -0
- package/src/state/batched-ssm.ts +54 -0
- package/src/state/batched-turboquant-kv.ts +144 -0
- package/src/state/bf16-first-kv.ts +663 -0
- package/src/state/cache-service.ts +592 -0
- package/src/state/capabilities.ts +65 -0
- package/src/state/checkpoint.ts +46 -0
- package/src/state/continuation-persistence.ts +126 -0
- package/src/state/decode-step-inputs.ts +31 -0
- package/src/state/decoded-kv-donor.ts +12 -0
- package/src/state/delayed-quantized-kv.ts +141 -0
- package/src/state/delayed-rotating-quantized-kv.ts +178 -0
- package/src/state/delayed-turboquant-kv.ts +123 -0
- package/src/state/durability.ts +214 -0
- package/src/state/encoder-cache.ts +26 -0
- package/src/state/full-kv-row-append.ts +33 -0
- package/src/state/full-kv-row-donor.ts +54 -0
- package/src/state/full-prefill-padding.ts +56 -0
- package/src/state/full-prefill-row.ts +112 -0
- package/src/state/full-transitioning-kv-rows.ts +70 -0
- package/src/state/glm52-cache.ts +783 -0
- package/src/state/grouped-heads-kv4-cache.ts +26 -0
- package/src/state/index.ts +38 -0
- package/src/state/kv-attention-view.ts +77 -0
- package/src/state/kv-budget.ts +14 -0
- package/src/state/kv-scheme.ts +315 -0
- package/src/state/kv-storage.ts +57 -0
- package/src/state/kv-tensor-rows.ts +212 -0
- package/src/state/kv.ts +324 -0
- package/src/state/kv4-head256-cache.ts +46 -0
- package/src/state/latent-legos.ts +895 -0
- package/src/state/layout.ts +277 -0
- package/src/state/leases.ts +26 -0
- package/src/state/paged/cache.ts +689 -0
- package/src/state/paged/codec.ts +36 -0
- package/src/state/paged/rows.ts +223 -0
- package/src/state/persistence-types.ts +173 -0
- package/src/state/persistence-worker.ts +83 -0
- package/src/state/persistence.ts +1036 -0
- package/src/state/persistence.worker.d.ts +3 -0
- package/src/state/persistence.worker.js +264 -0
- package/src/state/prefix-cache.ts +685 -0
- package/src/state/quantized-kv.ts +369 -0
- package/src/state/quantized-tensor.ts +26 -0
- package/src/state/request-policy.ts +48 -0
- package/src/state/retention-policy.ts +37 -0
- package/src/state/rollback.ts +131 -0
- package/src/state/rotating-kv-donor.ts +35 -0
- package/src/state/rotating-kv-layout.ts +341 -0
- package/src/state/rotating-kv.ts +529 -0
- package/src/state/rotating-quantized-kv.ts +616 -0
- package/src/state/rotating-row-transaction.ts +35 -0
- package/src/state/rows.ts +104 -0
- package/src/state/softcap-attention.ts +118 -0
- package/src/state/speculative/glm52-mtp-state.ts +38 -0
- package/src/state/speculative/qwen-mtp-state.ts +34 -0
- package/src/state/speculative-rotating-kv.ts +113 -0
- package/src/state/ssd-cache.ts +434 -0
- package/src/state/ssm-prefill-padding.ts +39 -0
- package/src/state/ssm.ts +422 -0
- package/src/state/target-layout.ts +7 -0
- package/src/state/tiered-prefix-cache.ts +45 -0
- package/src/state/training-cache.ts +300 -0
- package/src/state/transitioning-kv-rows.ts +267 -0
- package/src/state/turboquant-attention.ts +97 -0
- package/src/state/turboquant-codec.ts +90 -0
- package/src/state/turboquant-kv.ts +442 -0
- package/src/state/views.ts +26 -0
- package/src/transcription/index.ts +3 -0
- package/src/transcription/silero-vad.ts +379 -0
- package/src/transcription/whisper/decode.ts +773 -0
- package/src/transcription/whisper/format.ts +74 -0
- package/src/transcription/whisper/index.ts +4 -0
- package/src/transcription/whisper/timing.ts +274 -0
- package/src/transcription/whisper/transcribe.ts +394 -0
- 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
|
+
|