@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,41 @@
|
|
|
1
|
+
import type { MlxArray } from "@mlx-bun/mlx/array";
|
|
2
|
+
import { CompiledFunction } from "@mlx-bun/mlx/compile";
|
|
3
|
+
import { residualRmsNorm } from "../kernels/residual-rms-norm";
|
|
4
|
+
import { gatedRmsNorm } from "../kernels/gated-rms-norm";
|
|
5
|
+
|
|
6
|
+
// Shared traces take weights as inputs: they retain no model weights or cache
|
|
7
|
+
// state. Shape-aware compilation retraces the custom grid when dimensions change.
|
|
8
|
+
const residualFunctions = new Map<number, CompiledFunction>();
|
|
9
|
+
const gatedFunctions = new Map<number, CompiledFunction>();
|
|
10
|
+
|
|
11
|
+
/** Residual addition and weighted normalization, preserving both rounding steps. */
|
|
12
|
+
export class CompiledResidualRMSNorm {
|
|
13
|
+
readonly #operation: CompiledFunction;
|
|
14
|
+
constructor(readonly weight: MlxArray, readonly eps: number) {
|
|
15
|
+
let operation = residualFunctions.get(eps);
|
|
16
|
+
if (!operation) {
|
|
17
|
+
operation = new CompiledFunction(inputs => residualRmsNorm(inputs[0]!, inputs[1]!, inputs[2]!, eps), false);
|
|
18
|
+
residualFunctions.set(eps, operation);
|
|
19
|
+
}
|
|
20
|
+
this.#operation = operation;
|
|
21
|
+
}
|
|
22
|
+
forward(x: MlxArray, update: MlxArray): [MlxArray, MlxArray] {
|
|
23
|
+
return this.#operation.apply([x, update, this.weight]) as [MlxArray, MlxArray];
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/** Weighted normalization followed by Qwen's float32 SiLU gate. */
|
|
28
|
+
export class CompiledGatedRMSNorm {
|
|
29
|
+
readonly #operation: CompiledFunction;
|
|
30
|
+
constructor(readonly weight: MlxArray, readonly eps: number) {
|
|
31
|
+
let operation = gatedFunctions.get(eps);
|
|
32
|
+
if (!operation) {
|
|
33
|
+
operation = new CompiledFunction(inputs => [gatedRmsNorm(inputs[0]!, inputs[1]!, inputs[2]!, eps)], false);
|
|
34
|
+
gatedFunctions.set(eps, operation);
|
|
35
|
+
}
|
|
36
|
+
this.#operation = operation;
|
|
37
|
+
}
|
|
38
|
+
forward(x: MlxArray, gate: MlxArray): MlxArray {
|
|
39
|
+
return this.#operation.apply([x, gate, this.weight])[0]!;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { MlxArray } from "@mlx-bun/mlx/array";
|
|
2
|
+
import { CompiledFunction } from "@mlx-bun/mlx/compile";
|
|
3
|
+
import { siluRmsHeads } from "../kernels/delta/silu-rms-heads";
|
|
4
|
+
|
|
5
|
+
const functions = new Map<string, CompiledFunction>();
|
|
6
|
+
|
|
7
|
+
/** Shape-aware replay of the fused activation and Q/K RMS norms.
|
|
8
|
+
* Shared traces take both scale vectors as inputs and retain no layer weights. */
|
|
9
|
+
export class CompiledSiluRMSHeads {
|
|
10
|
+
readonly #operation: CompiledFunction;
|
|
11
|
+
constructor(readonly keyHeads: number, readonly valueHeads: number, readonly valueWidth: number) {
|
|
12
|
+
const key = `${keyHeads}:${valueHeads}:${valueWidth}`;
|
|
13
|
+
let operation = functions.get(key);
|
|
14
|
+
if (!operation) {
|
|
15
|
+
operation = new CompiledFunction(inputs => siluRmsHeads(inputs[0]!, inputs[1]!, inputs[2]!, keyHeads, valueHeads, valueWidth), false);
|
|
16
|
+
functions.set(key, operation);
|
|
17
|
+
}
|
|
18
|
+
this.#operation = operation;
|
|
19
|
+
}
|
|
20
|
+
forward(x: MlxArray, qScale: MlxArray, kScale: MlxArray): [MlxArray, MlxArray, MlxArray] {
|
|
21
|
+
return this.#operation.apply([x, qScale, kScale]) as [MlxArray, MlxArray, MlxArray];
|
|
22
|
+
}
|
|
23
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
// Universal-tier primitives: dense (unquantized) linear/embedding modules
|
|
2
|
+
// (mlx nn.Linear / nn.Embedding semantics), quantized-or-dense
|
|
3
|
+
// loader helpers, norm loaders, and the load-time weight audit.
|
|
4
|
+
//
|
|
5
|
+
// The quantized paths delegate to the proven QuantizedLinear/QuantizedEmbedding
|
|
6
|
+
// primitives (packages/inference/src/layers/); the
|
|
7
|
+
// dense paths are verbatim ports of mlx.nn.Linear (`mx.addmm(bias, x, W.T)`
|
|
8
|
+
// / `x @ W.T`) and mlx.nn.Embedding (`weight[ids]`, `x @ weight.T`).
|
|
9
|
+
|
|
10
|
+
import { MlxArray } from "@mlx-bun/mlx/array";
|
|
11
|
+
import * as ops from "@mlx-bun/mlx/ops";
|
|
12
|
+
|
|
13
|
+
/** Plain unquantized embedding — mlx nn.Embedding (+ as_linear tied head). */
|
|
14
|
+
export class DenseEmbedding {
|
|
15
|
+
readonly wT: MlxArray;
|
|
16
|
+
|
|
17
|
+
constructor(readonly w: MlxArray) {
|
|
18
|
+
this.wT = ops.transposeAxes(w, [1, 0]);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
encode(ids: MlxArray): MlxArray {
|
|
22
|
+
return ops.takeAxis(this.w, ids, 0);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/** nn.Embedding.as_linear: `x @ weight.T`. */
|
|
26
|
+
asLinear(h: MlxArray): MlxArray {
|
|
27
|
+
return ops.matmul(h, this.wT);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
// Universal-tier primitives: dense (unquantized) linear/embedding modules
|
|
2
|
+
// (mlx nn.Linear / nn.Embedding semantics), quantized-or-dense
|
|
3
|
+
// loader helpers, norm loaders, and the load-time weight audit.
|
|
4
|
+
//
|
|
5
|
+
// The quantized paths delegate to the proven QuantizedLinear/QuantizedEmbedding
|
|
6
|
+
// primitives (packages/inference/src/layers/); the
|
|
7
|
+
// dense paths are verbatim ports of mlx.nn.Linear (`mx.addmm(bias, x, W.T)`
|
|
8
|
+
// / `x @ W.T`) and mlx.nn.Embedding (`weight[ids]`, `x @ weight.T`).
|
|
9
|
+
|
|
10
|
+
import { MlxArray } from "@mlx-bun/mlx/array";
|
|
11
|
+
import * as ops from "@mlx-bun/mlx/ops";
|
|
12
|
+
|
|
13
|
+
/** Plain unquantized linear — mlx nn.Linear:
|
|
14
|
+
* `mx.addmm(bias, x, weight.T)` when bias is present, else `x @ weight.T`. */
|
|
15
|
+
export class DenseLinear {
|
|
16
|
+
readonly wT: MlxArray;
|
|
17
|
+
|
|
18
|
+
constructor(readonly w: MlxArray, readonly bias: MlxArray | null) {
|
|
19
|
+
this.wT = ops.transposeAxes(w, [1, 0]); // lazy view, shared across calls
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
get inFeatures(): number {
|
|
23
|
+
return this.w.shape[1]!;
|
|
24
|
+
}
|
|
25
|
+
get outFeatures(): number {
|
|
26
|
+
return this.w.shape[0]!;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
forward(x: MlxArray): MlxArray {
|
|
30
|
+
return this.bias ? ops.addmm(this.bias, x, this.wT) : ops.matmul(x, this.wT);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import type { MlxArray } from "@mlx-bun/mlx/array";
|
|
2
|
+
import * as ops from "@mlx-bun/mlx/ops";
|
|
3
|
+
import type { QuantizedLinear } from "./quantized-linear";
|
|
4
|
+
|
|
5
|
+
// A prompt piece's affine projection over a loaded QuantizedLinear (borrowed
|
|
6
|
+
// weights, no additive bias). From its fewest rows the weight is dequantized to
|
|
7
|
+
// bf16 for the call and multiplied by MLX's dense GEMM: the same bf16 weights
|
|
8
|
+
// MLX's quantized matmul builds in its tiles and the same float accumulation,
|
|
9
|
+
// so the output is that matmul's bit for bit, from the GEMM's larger tiles
|
|
10
|
+
// (measured on the M1 Max at 3 and 4 bits, group 64, every Qwen3.8 projection
|
|
11
|
+
// whose outputs are whole 64-wide tiles: bit-identical at every row count from
|
|
12
|
+
// 97 to 1100 above the split-K range below, and 1.0x to 1.3x faster from 128
|
|
13
|
+
// rows, 7.8 against 5.7 TFLOPS at 2048). Fewer rows, the rows where MLX's
|
|
14
|
+
// dense GEMM splits K (its own accumulation order: while ceil(M/16) ·
|
|
15
|
+
// ceil(N/16) <= 2048 on a Max GPU, so k_proj and v_proj's 1024 outputs up to
|
|
16
|
+
// 512 rows), and the other projections (DeltaNet's in_proj_a and in_proj_b, 48
|
|
17
|
+
// outputs) take MLX's quantized matmul itself. The identity is MLX's kernel
|
|
18
|
+
// choice at those shapes, not a property of every shape (at 512 inputs the two
|
|
19
|
+
// round differently): a graph selects this layer for the artifact it was
|
|
20
|
+
// measured on. The dense weight is a transient of one call (outputs x inputs x
|
|
21
|
+
// 2 bytes). Applies the request's external adapter delta after the projection.
|
|
22
|
+
|
|
23
|
+
/** The fewest rows the dense GEMM takes at any projection: below this the dequantization costs about what the
|
|
24
|
+
* GEMM saves over MLX's quantized matmul. */
|
|
25
|
+
export const DEQUANTIZED_MIN_ROWS = 128;
|
|
26
|
+
|
|
27
|
+
/** The most tiles of 16 x 16 outputs MLX's dense GEMM runs on its split-K kernel on a Max GPU (the M1 Max's
|
|
28
|
+
* `applegpu_g13s`), whose accumulation order is not the quantized matmul's. */
|
|
29
|
+
const SPLIT_K_TILES = 2048;
|
|
30
|
+
|
|
31
|
+
/** The fewest rows a projection of `outputs` outputs takes the dense GEMM at: DEQUANTIZED_MIN_ROWS or the first row
|
|
32
|
+
* count above the GEMM's split-K range at those outputs, whichever is more; never when they are not whole 64-wide
|
|
33
|
+
* tiles. */
|
|
34
|
+
export function dequantizedMinRows(outputs: number): number {
|
|
35
|
+
return outputs % 64 !== 0 ? Infinity : Math.max(DEQUANTIZED_MIN_ROWS, 16 * Math.floor(SPLIT_K_TILES / Math.ceil(outputs / 16)) + 1);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export class DequantizedLinear {
|
|
39
|
+
readonly #spec: ops.QuantSpec;
|
|
40
|
+
/** The fewest rows this projection takes the dense GEMM at (`dequantizedMinRows`). */
|
|
41
|
+
readonly #minRows: number;
|
|
42
|
+
|
|
43
|
+
constructor(readonly linear: QuantizedLinear) {
|
|
44
|
+
if (!linear.biases || linear.bias || linear.w.ndim !== 2 || linear.spec.mode !== "affine")
|
|
45
|
+
throw new Error("DequantizedLinear: unsupported projection (affine, two-dimensional, no additive bias)");
|
|
46
|
+
this.#spec = linear.spec;
|
|
47
|
+
this.#minRows = dequantizedMinRows(linear.outFeatures);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/** `x` [.., inputs] (borrowed) to an owned [.., outputs], lazy. */
|
|
51
|
+
forward(x: MlxArray): MlxArray {
|
|
52
|
+
const { w, scales, biases } = this.linear;
|
|
53
|
+
if (x.size / x.shape.at(-1)! < this.#minRows) return this.linear.delta.forward(x, ops.quantizedMatmul(x, w, scales, biases, this.#spec, true));
|
|
54
|
+
using dense = ops.dequantize(w, scales, biases, this.#spec);
|
|
55
|
+
using weightT = ops.transposeAxes(dense, [1, 0]);
|
|
56
|
+
return this.linear.delta.forward(x, ops.matmul(x, weightT));
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/** One fixed dequantize-and-GEMM operation. The graph declares its measured row range. */
|
|
61
|
+
export class DequantizedMatmulLinear {
|
|
62
|
+
constructor(readonly linear: QuantizedLinear) {
|
|
63
|
+
if (!linear.biases || linear.bias || linear.w.ndim !== 2 || linear.spec.mode !== "affine")
|
|
64
|
+
throw new Error("DequantizedMatmulLinear: unsupported projection (affine, two-dimensional, no additive bias)");
|
|
65
|
+
}
|
|
66
|
+
forward(x: MlxArray): MlxArray {
|
|
67
|
+
const {w,scales,biases,spec}=this.linear;
|
|
68
|
+
using dense=ops.dequantize(w,scales,biases,spec);
|
|
69
|
+
using weightT=ops.transposeAxes(dense,[1,0]);
|
|
70
|
+
return this.linear.delta.forward(x,ops.matmul(x,weightT));
|
|
71
|
+
}
|
|
72
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { MlxArray } from "@mlx-bun/mlx/array";
|
|
2
|
+
import { Dtype } from "@mlx-bun/mlx/ffi";
|
|
3
|
+
import * as ops from "@mlx-bun/mlx/ops";
|
|
4
|
+
|
|
5
|
+
/** The windows MLX's fused SDPA hands to its unfused fallback for want of a
|
|
6
|
+
* vector kernel: at most 8 causal queries per row (above that its full
|
|
7
|
+
* attention kernel serves), more than 32 query vectors per KV head (the
|
|
8
|
+
* vector kernel's limit), no more queries than keys. q [B, H, L, D], keys
|
|
9
|
+
* [B, KVH, N, D]. */
|
|
10
|
+
export function foldedSdpaEligible(q: MlxArray, keys: MlxArray): boolean {
|
|
11
|
+
const [, H, L] = q.shape as [number, number, number, number];
|
|
12
|
+
const KVH = keys.shape[1]!;
|
|
13
|
+
return L <= 8 && H % KVH === 0 && L * (H / KVH) > 32 && L <= keys.shape[2]!;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/** Causal attention over bf16 keys and values with GQA folded into rows: the
|
|
17
|
+
* rep·L query vectors of each KV head multiply its keys in one matmul and its
|
|
18
|
+
* values in another, so the cache is read once per KV head instead of once per
|
|
19
|
+
* query head (MLX's fallback broadcasts each KV head over its query heads).
|
|
20
|
+
* Otherwise MLX's fallback arithmetic, op for op: the scale cast to the query
|
|
21
|
+
* dtype, the bottom-right causal mask at -inf, the precise softmax. Bit for bit
|
|
22
|
+
* `ops.sdpa` on the windows `foldedSdpaEligible` takes on `applegpu_g13s`, where
|
|
23
|
+
* it was measured, and to bf16 precision elsewhere (rows (r, i): head
|
|
24
|
+
* KVH·rep + r, query i, which sees keys j <= N - L + i). q [B, H, L, D], keys
|
|
25
|
+
* and values [B, KVH, N, D] (any strides) → [B, H, L, D], owned by the caller. */
|
|
26
|
+
export function foldedSdpa(q: MlxArray, keys: MlxArray, values: MlxArray, scale: number): MlxArray {
|
|
27
|
+
const [B, H, L, D] = q.shape as [number, number, number, number];
|
|
28
|
+
const KVH = keys.shape[1]!, N = keys.shape[2]!, rep = H / KVH;
|
|
29
|
+
using scaled = ops.mulScalar(q, scale);
|
|
30
|
+
using rows = ops.reshape(scaled, [B, KVH, rep * L, D]);
|
|
31
|
+
using keysT = ops.transposeAxes(keys, [0, 1, 3, 2]);
|
|
32
|
+
using scores = ops.matmul(rows, keysT); // [B, KVH, rep·L, N]
|
|
33
|
+
using cols = ops.arange(0, N, 1, Dtype.int32);
|
|
34
|
+
using colRow = ops.reshape(cols, [1, N]);
|
|
35
|
+
using limits = ops.fromInt32(Array.from({ length: rep * L }, (_, row) => N - L + (row % L)), [rep * L, 1]);
|
|
36
|
+
using visible = ops.lessEqual(colRow, limits);
|
|
37
|
+
using ninf = ops.scalarLike(-Infinity, scores);
|
|
38
|
+
using masked = ops.where(visible, scores, ninf);
|
|
39
|
+
using probs = ops.softmaxAxis(masked, -1, true);
|
|
40
|
+
using out = ops.matmul(probs, values); // [B, KVH, rep·L, Dv]
|
|
41
|
+
return ops.reshape(out, [B, H, L, out.shape[3]!]);
|
|
42
|
+
}
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
// GeGLU activation and feed-forward shared by the Gemma family: the compiled
|
|
2
|
+
// geglu closure (mlx-lm's @mx.compile geglu), the spelled-out composition, and
|
|
3
|
+
// the dense quantized MLP built on them. Which one a layer runs is its owner's
|
|
4
|
+
// construction-time choice (`compiled`), never read here.
|
|
5
|
+
|
|
6
|
+
import { MlxArray } from "@mlx-bun/mlx/array";
|
|
7
|
+
import * as ops from "@mlx-bun/mlx/ops";
|
|
8
|
+
|
|
9
|
+
import { CompiledFunction } from "@mlx-bun/mlx/compile";
|
|
10
|
+
import type { ModelConfig } from "../artifacts/config";
|
|
11
|
+
import type { Weights } from "../artifacts/weights";
|
|
12
|
+
import { isCompiledTrace } from "../runtime/compiled-trace";
|
|
13
|
+
import { QuantizedLinear, QuantizedLinearPlain } from "./quantized-linear";
|
|
14
|
+
|
|
15
|
+
/** Verbatim port of mlx_lm/models/gemma4_text.py:
|
|
16
|
+
* `@partial(mx.compile, shapeless=True) def geglu(gate, x): return nn.gelu_approx(gate) * x`
|
|
17
|
+
* The oracle @mx.compile's this and uses it for EVERY MLP shape (dense MLP
|
|
18
|
+
* __call__ line 114, and the SwitchGLU GeGLU activation line 149-150). The
|
|
19
|
+
* spelled-out composition runs the SAME math UNFUSED (standalone
|
|
20
|
+
* ops.geluApprox + ops.mul), a different dispatched kernel set + the per-op
|
|
21
|
+
* host tax the MiniCPM5 swiglu fix measured at ~5%. This closure fuses
|
|
22
|
+
* geluApprox's ~9 element-wise ops + the final mul into one traced-once/replayed
|
|
23
|
+
* graph, matching the oracle's kernel set. `geluApprox` is composed op-for-op
|
|
24
|
+
* from the same primitives as the oracle's nn.gelu_approx
|
|
25
|
+
* (0.5·x·(1+tanh(√(2/π)(x+0.044715·x³)))), so the compiled graph is the
|
|
26
|
+
* oracle's geglu graph. Autograd-safe (verified: the vjp through this closure is
|
|
27
|
+
* bit-identical to the plain composition). */
|
|
28
|
+
let _gegluClosure: CompiledFunction | null = null;
|
|
29
|
+
export function compiledGeglu(gate: MlxArray, up: MlxArray): MlxArray {
|
|
30
|
+
if (!_gegluClosure) {
|
|
31
|
+
_gegluClosure = new CompiledFunction((inputs) => {
|
|
32
|
+
const g = inputs[0]!, u = inputs[1]!; // nn.gelu_approx(gate) * x
|
|
33
|
+
const act = ops.geluApprox(g);
|
|
34
|
+
const out = ops.mul(act, u); act.dispose();
|
|
35
|
+
return [out];
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
return _gegluClosure.apply([gate, up])[0]!;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/** gelu_approx(gate) * up, consuming both inputs. `compiled` is the owner's
|
|
42
|
+
* construction-time choice: the compiled closure (the oracle's @mx.compile'd
|
|
43
|
+
* geglu, one kernel set; the default the Gemma graphs compose), or the
|
|
44
|
+
* spelled-out operation (same L1
|
|
45
|
+
* parity, slower). Inside a compiled-decode trace the closure records the
|
|
46
|
+
* spelled-out ops. */
|
|
47
|
+
export function geglu(gate: MlxArray, up: MlxArray, compiled: boolean): MlxArray {
|
|
48
|
+
let out: MlxArray;
|
|
49
|
+
if (compiled && !isCompiledTrace()) {
|
|
50
|
+
out = compiledGeglu(gate, up);
|
|
51
|
+
} else {
|
|
52
|
+
const act = ops.geluApprox(gate);
|
|
53
|
+
out = ops.mul(act, up);
|
|
54
|
+
act.dispose();
|
|
55
|
+
}
|
|
56
|
+
gate.dispose();
|
|
57
|
+
up.dispose();
|
|
58
|
+
return out;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/** Dense GeGLU feed-forward: down(geglu(gate(x), up(x))) over quantized linears,
|
|
62
|
+
* with the activation form its owner chose at construction (`compiled`). */
|
|
63
|
+
export class GegluMLP {
|
|
64
|
+
readonly gate: QuantizedLinear;
|
|
65
|
+
readonly up: QuantizedLinear;
|
|
66
|
+
readonly down: QuantizedLinear;
|
|
67
|
+
|
|
68
|
+
constructor(weights: Weights, config: ModelConfig, prefix: string, readonly compiled: boolean) {
|
|
69
|
+
this.gate = QuantizedLinear.load(weights, `${prefix}.gate_proj`, config);
|
|
70
|
+
this.up = QuantizedLinear.load(weights, `${prefix}.up_proj`, config);
|
|
71
|
+
this.down = QuantizedLinear.load(weights, `${prefix}.down_proj`, config);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
forward(x: MlxArray): MlxArray {
|
|
75
|
+
const m = geglu(this.gate.forward(x), this.up.forward(x), this.compiled);
|
|
76
|
+
const out = this.down.forward(m);
|
|
77
|
+
m.dispose();
|
|
78
|
+
return out;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/** Plain GeGLU consumes both activation inputs. */
|
|
83
|
+
export class PlainGeglu {
|
|
84
|
+
forward(gate: MlxArray, up: MlxArray): MlxArray {
|
|
85
|
+
using act = ops.geluApprox(gate);
|
|
86
|
+
const out = ops.mul(act, up);
|
|
87
|
+
gate.dispose(); up.dispose();
|
|
88
|
+
return out;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/** Compiled GeGLU consumes both activation inputs. */
|
|
93
|
+
export class CompiledGeglu {
|
|
94
|
+
forward(gate: MlxArray, up: MlxArray): MlxArray {
|
|
95
|
+
const out = compiledGeglu(gate, up);
|
|
96
|
+
gate.dispose(); up.dispose();
|
|
97
|
+
return out;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
export class PlainGegluMLP {
|
|
102
|
+
readonly #activation = new PlainGeglu();
|
|
103
|
+
readonly #gate: QuantizedLinearPlain;
|
|
104
|
+
readonly #up: QuantizedLinearPlain;
|
|
105
|
+
readonly #down: QuantizedLinearPlain;
|
|
106
|
+
constructor(readonly base: GegluMLP) {
|
|
107
|
+
this.#gate = new QuantizedLinearPlain(base.gate);
|
|
108
|
+
this.#up = new QuantizedLinearPlain(base.up);
|
|
109
|
+
this.#down = new QuantizedLinearPlain(base.down);
|
|
110
|
+
}
|
|
111
|
+
forward(x: MlxArray): MlxArray {
|
|
112
|
+
using hidden = this.#activation.forward(this.#gate.forward(x), this.#up.forward(x));
|
|
113
|
+
return this.#down.forward(hidden);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
export class CompiledGegluMLP {
|
|
117
|
+
readonly #activation = new CompiledGeglu();
|
|
118
|
+
readonly #gate: QuantizedLinearPlain;
|
|
119
|
+
readonly #up: QuantizedLinearPlain;
|
|
120
|
+
readonly #down: QuantizedLinearPlain;
|
|
121
|
+
constructor(readonly base: GegluMLP) {
|
|
122
|
+
this.#gate = new QuantizedLinearPlain(base.gate);
|
|
123
|
+
this.#up = new QuantizedLinearPlain(base.up);
|
|
124
|
+
this.#down = new QuantizedLinearPlain(base.down);
|
|
125
|
+
}
|
|
126
|
+
forward(x: MlxArray): MlxArray {
|
|
127
|
+
using hidden = this.#activation.forward(this.#gate.forward(x), this.#up.forward(x));
|
|
128
|
+
return this.#down.forward(hidden);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
export * from "./quantized-linear";
|
|
2
|
+
export * from "./quantized-embedding";
|
|
3
|
+
export * from "./normalization";
|
|
4
|
+
export * from "./compiled-normalization";
|
|
5
|
+
export * from "./delta-heads";
|
|
6
|
+
export * from "./trellis-linear";
|
|
7
|
+
export * from "./quantized-switch-linear";
|
|
8
|
+
export * from "./quantized-attention";
|
|
9
|
+
export * from "./quantized-append-attention";
|
|
10
|
+
export * from "../kernels/attention/masks";
|
|
11
|
+
export * from "./helpers";
|
|
12
|
+
export * from "./dense-linear";
|
|
13
|
+
export * from "./dense-embedding";
|
|
14
|
+
export * from "./layer-norm";
|
|
15
|
+
export * from "./loading";
|
|
16
|
+
export * from "./geglu";
|
|
17
|
+
export * from "./swiglu";
|
|
18
|
+
export * from "./qwen-mrope";
|
|
19
|
+
export * from "./rope";
|
|
20
|
+
export * from "./rope-2d";
|
|
21
|
+
|
|
22
|
+
export * from "./trellis-prompt";
|
|
23
|
+
export * from "./affine-verify-linear";
|
|
24
|
+
export * from "./ane-prefill-split";
|
|
25
|
+
export * from "./trellis-gate-up";
|
|
26
|
+
export * from "./trellis-down";
|
|
27
|
+
export * from "./trellis-reduce-gate-up";
|
|
28
|
+
export * from "./trellis-scatter-down";
|
|
29
|
+
export { LoraDelta, LoraOperation, LoraState } from "./lora";
|
|
30
|
+
|
|
31
|
+
export * from "./dequantized-linear";
|
|
32
|
+
export * from "./trellis-codebook-down";
|
|
33
|
+
export * from "./trellis-codebook-gate-up";
|
|
34
|
+
export * from "./folded-attention";
|
|
35
|
+
|
|
36
|
+
export { AneTrellisExpandReduce, AneTrellisExpandScatter, AneTrellisExpandedMlpSplit, AneTrellisExpandedMlpSplitK3i, type AneGpuMlpRows } from "./ane-prefill-split";
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { MlxArray } from "@mlx-bun/mlx/array";
|
|
2
|
+
import type * as ops from "@mlx-bun/mlx/ops";
|
|
3
|
+
import { kvq4DecodeEligible, kvq4DecodeSdpa } from "../kernels/attention/kvq4-decode";
|
|
4
|
+
|
|
5
|
+
/** One-row decode attention over a 4-bit, group-64 quantized KV cache with
|
|
6
|
+
* head dim 256 (kernels/attention/kvq4-decode): every packed K/V row is read
|
|
7
|
+
* once for all query heads of its KV head, `block` tokens per threadgroup.
|
|
8
|
+
* q [1, H, 1, 256] → [1, H, 1, 256]. Not bit-identical to quantizedSdpa
|
|
9
|
+
* (bf16-level). */
|
|
10
|
+
export function kv4DecodeAttention(q: MlxArray, keys: ops.QuantizedTensor, values: ops.QuantizedTensor, scale: number,
|
|
11
|
+
groupSize: number, bits: number, block: number): MlxArray {
|
|
12
|
+
if (!kvq4DecodeEligible(q, keys, groupSize, bits))
|
|
13
|
+
throw new Error("kv4DecodeAttention: needs one query row, head dim 256, a 4-bit group-64 cache and an even GQA factor");
|
|
14
|
+
return kvq4DecodeSdpa(q, keys, values, scale, block);
|
|
15
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
// Universal-tier primitives: dense (unquantized) linear/embedding modules
|
|
2
|
+
// (mlx nn.Linear / nn.Embedding semantics), quantized-or-dense
|
|
3
|
+
// loader helpers, norm loaders, and the load-time weight audit.
|
|
4
|
+
//
|
|
5
|
+
// The quantized paths delegate to the proven QuantizedLinear/QuantizedEmbedding
|
|
6
|
+
// primitives (packages/inference/src/layers/); the
|
|
7
|
+
// dense paths are verbatim ports of mlx.nn.Linear (`mx.addmm(bias, x, W.T)`
|
|
8
|
+
// / `x @ W.T`) and mlx.nn.Embedding (`weight[ids]`, `x @ weight.T`).
|
|
9
|
+
|
|
10
|
+
import { MlxArray } from "@mlx-bun/mlx/array";
|
|
11
|
+
import * as ops from "@mlx-bun/mlx/ops";
|
|
12
|
+
|
|
13
|
+
/** mlx nn.LayerNorm (weight + bias affine — starcoder2's norm). */
|
|
14
|
+
export class LayerNorm {
|
|
15
|
+
constructor(
|
|
16
|
+
readonly weight: MlxArray,
|
|
17
|
+
readonly bias: MlxArray | null,
|
|
18
|
+
readonly eps: number,
|
|
19
|
+
) {}
|
|
20
|
+
|
|
21
|
+
forward(x: MlxArray): MlxArray {
|
|
22
|
+
return ops.layerNorm(x, this.weight, this.bias, this.eps);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
// Universal-tier primitives: dense (unquantized) linear/embedding modules
|
|
2
|
+
// (mlx nn.Linear / nn.Embedding semantics), quantized-or-dense
|
|
3
|
+
// loader helpers, norm loaders, and the load-time weight audit.
|
|
4
|
+
//
|
|
5
|
+
// The quantized paths delegate to the proven QuantizedLinear/QuantizedEmbedding
|
|
6
|
+
// primitives (packages/inference/src/layers/); the
|
|
7
|
+
// dense paths are verbatim ports of mlx.nn.Linear (`mx.addmm(bias, x, W.T)`
|
|
8
|
+
// / `x @ W.T`) and mlx.nn.Embedding (`weight[ids]`, `x @ weight.T`).
|
|
9
|
+
|
|
10
|
+
import * as ops from "@mlx-bun/mlx/ops";
|
|
11
|
+
import type { ModelConfig } from "../artifacts/config";
|
|
12
|
+
import { WeightAudit,tensorUsed } from "../artifacts/weight-audit";
|
|
13
|
+
import type { Weights } from "../artifacts/weights";
|
|
14
|
+
import { DenseEmbedding } from "./dense-embedding";
|
|
15
|
+
import { DenseLinear } from "./dense-linear";
|
|
16
|
+
import { LayerNorm } from "./layer-norm";
|
|
17
|
+
import { RMSNorm } from "./normalization";
|
|
18
|
+
import { QuantizedEmbedding } from "./quantized-embedding";
|
|
19
|
+
import { QuantizedLinear } from "./quantized-linear";
|
|
20
|
+
import { TrellisLinear } from "./trellis-linear";
|
|
21
|
+
|
|
22
|
+
/** Either linear flavor behind one call surface. */
|
|
23
|
+
export type AnyLinear = QuantizedLinear | DenseLinear | TrellisLinear;
|
|
24
|
+
|
|
25
|
+
/** Quantized when `.scales` exists (MLX-quantized checkpoints), else dense
|
|
26
|
+
* bf16/f16/f32. Both flavors carry the optional ADDITIVE
|
|
27
|
+
* `.bias` term (qwen2 qkv, starcoder2, …). */
|
|
28
|
+
export function loadLinear(
|
|
29
|
+
weights: Weights, path: string, config: ModelConfig, audit: WeightAudit, representations?: import("../kernels/trellis/index").TrellisRepresentations,
|
|
30
|
+
): AnyLinear {
|
|
31
|
+
if (TrellisLinear.isTrellis(config, path)) {
|
|
32
|
+
const lin = TrellisLinear.load(weights, path, config, false, representations);
|
|
33
|
+
audit.use(`${path}.weight`);
|
|
34
|
+
audit.use(`${path}.scales`);
|
|
35
|
+
return lin;
|
|
36
|
+
}
|
|
37
|
+
if (weights.has(`${path}.scales`)) {
|
|
38
|
+
const lin = QuantizedLinear.load(weights, path, config);
|
|
39
|
+
audit.use(`${path}.weight`);
|
|
40
|
+
audit.use(`${path}.scales`);
|
|
41
|
+
if (weights.has(`${path}.biases`)) audit.use(`${path}.biases`);
|
|
42
|
+
if (weights.has(`${path}.bias`)) audit.use(`${path}.bias`);
|
|
43
|
+
return lin;
|
|
44
|
+
}
|
|
45
|
+
if (!weights.has(`${path}.weight`))
|
|
46
|
+
throw new Error(`${path}: no .weight tensor (nor .scales) in checkpoint`);
|
|
47
|
+
return new DenseLinear(
|
|
48
|
+
tensorUsed(weights, audit, `${path}.weight`),
|
|
49
|
+
weights.has(`${path}.bias`) ? tensorUsed(weights, audit, `${path}.bias`) : null,
|
|
50
|
+
);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export type AnyEmbedding = QuantizedEmbedding | DenseEmbedding;
|
|
54
|
+
|
|
55
|
+
export function loadEmbedding(
|
|
56
|
+
weights: Weights, path: string, config: ModelConfig, audit: WeightAudit,
|
|
57
|
+
): AnyEmbedding {
|
|
58
|
+
if (weights.has(`${path}.scales`)) {
|
|
59
|
+
const emb = QuantizedEmbedding.load(weights, path, config);
|
|
60
|
+
audit.use(`${path}.weight`);
|
|
61
|
+
audit.use(`${path}.scales`);
|
|
62
|
+
if (weights.has(`${path}.biases`)) audit.use(`${path}.biases`);
|
|
63
|
+
return emb;
|
|
64
|
+
}
|
|
65
|
+
return new DenseEmbedding(tensorUsed(weights, audit, `${path}.weight`));
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/** RMSNorm loader; `plusOne` = the gemma-family `1.0 + weight` variant
|
|
69
|
+
* (the add is folded once at load — identical value to mlx-lm's
|
|
70
|
+
* per-call `1.0 + self.weight`). */
|
|
71
|
+
export function loadRmsNorm(
|
|
72
|
+
weights: Weights, path: string, eps: number, plusOne: boolean, audit: WeightAudit,
|
|
73
|
+
): RMSNorm {
|
|
74
|
+
const w = tensorUsed(weights, audit, `${path}.weight`);
|
|
75
|
+
if (!plusOne) return new RMSNorm(w, eps);
|
|
76
|
+
const one = ops.scalarLike(1, w);
|
|
77
|
+
const w1 = ops.add(one, w);
|
|
78
|
+
one.dispose();
|
|
79
|
+
return new RMSNorm(w1, eps);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
export type AnyNorm = RMSNorm | LayerNorm;
|
|
83
|
+
|
|
84
|
+
export function loadLayerNorm(
|
|
85
|
+
weights: Weights, path: string, eps: number, audit: WeightAudit,
|
|
86
|
+
): LayerNorm {
|
|
87
|
+
return new LayerNorm(
|
|
88
|
+
tensorUsed(weights, audit, `${path}.weight`),
|
|
89
|
+
weights.has(`${path}.bias`) ? tensorUsed(weights, audit, `${path}.bias`) : null,
|
|
90
|
+
eps,
|
|
91
|
+
);
|
|
92
|
+
}
|