@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,510 @@
|
|
|
1
|
+
import type { MlxArray } from "@mlx-bun/mlx/array";
|
|
2
|
+
import type { Dtype } from "@mlx-bun/mlx/ffi";
|
|
3
|
+
import type * as ops from "@mlx-bun/mlx/ops";
|
|
4
|
+
|
|
5
|
+
export type MaskMode = "" | "causal";
|
|
6
|
+
export interface Mask {
|
|
7
|
+
mode: MaskMode | "array";
|
|
8
|
+
arr: MlxArray | null;
|
|
9
|
+
/** True when `arr` is exactly the bottom-right-aligned causal matrix
|
|
10
|
+
* (offset continuation, no window) — the case where mlx-lm would
|
|
11
|
+
* have handed the string "causal" instead. Only these array masks
|
|
12
|
+
* are eligible for the fused tiled SDPA: the optiq wrapper falls
|
|
13
|
+
* back to unfused on every array mask, and window/bidir masks must
|
|
14
|
+
* match that to stay scenario-bit-exact. */
|
|
15
|
+
causalEquivalent?: boolean;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/** Fetched KV handed from a donor layer to its sharers (and to the
|
|
19
|
+
* speculative drafter). Owned by forwardLayers for the pass.
|
|
20
|
+
* `offsetArr` is an owned pre-write position snapshot. Donor and sharing
|
|
21
|
+
* attention layers keep it until the fetched KV is released, even if the
|
|
22
|
+
* cache advances or replaces its borrowed row-position array. */
|
|
23
|
+
export type SharedKv =
|
|
24
|
+
| { kind: "plain"; keys: MlxArray; values: MlxArray; offset: number;
|
|
25
|
+
offsetArr?: MlxArray;
|
|
26
|
+
/** TurboQuant deferred-V: `values` are still in the rotated (FWHT)
|
|
27
|
+
* domain — every consumer must un-rotate its attention OUTPUT
|
|
28
|
+
* (tq.unrotateValues) after sdpa. Attention is linear in V, so the
|
|
29
|
+
* result is the same decode, just transformed once per query row
|
|
30
|
+
* instead of once per cached token. */
|
|
31
|
+
vRotated?: boolean;
|
|
32
|
+
restoreValues?: (output: MlxArray) => MlxArray }
|
|
33
|
+
| { kind: "quant"; keys: ops.QuantizedTensor; values: ops.QuantizedTensor;
|
|
34
|
+
offset: number; groupSize: number; bits: number; offsetArr?: MlxArray }
|
|
35
|
+
| { kind: "view"; attention: KvAttentionView; offset: number; offsetArr?: MlxArray };
|
|
36
|
+
|
|
37
|
+
/** Attention over a cache's positions as of one phase-named call. The cache
|
|
38
|
+
* picked the kernel when it was built and builds the mask from the offsets, row
|
|
39
|
+
* layout and sliding window it owns. The caller supplies only queries.
|
|
40
|
+
*
|
|
41
|
+
* The read owns its tensor handles. It stays valid after later appends, trims,
|
|
42
|
+
* row changes or disposal of its cache. Holding it across the cache's next
|
|
43
|
+
* append can make that append copy storage instead of writing in place, so
|
|
44
|
+
* dispose it when the forward that made it is done. It does no attention work
|
|
45
|
+
* before `attend`; disposing an unused read only releases handles. */
|
|
46
|
+
export interface AttentionRead {
|
|
47
|
+
/** Queries `q` [B, Hq, L, Dk] (borrowed, positional encoding applied, Hq a
|
|
48
|
+
* multiple of the stored Hkv) to an owned output [B, Hq, L, Dv]. `B` and `L`
|
|
49
|
+
* must match the call that made this read, and the result is defined only for
|
|
50
|
+
* that call's phase. Callable any number of times: layers that share a
|
|
51
|
+
* donor's keys and values attend the donor's read with their own queries. */
|
|
52
|
+
attend(q: MlxArray, scale: number): MlxArray;
|
|
53
|
+
/** Releases the read's handles. Call exactly once. */
|
|
54
|
+
dispose(): void;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/** A key/value cache that owns its attention read. Each method appends the new
|
|
58
|
+
* keys and values for the phase it names and returns the read for that phase.
|
|
59
|
+
* The caller never sees stored keys or values and never chooses a kernel. The
|
|
60
|
+
* storage (bf16, affine, TurboQuant, paged, rotating, delayed quantization) is
|
|
61
|
+
* not visible here: the loader composes the cache, and the cache fixes one
|
|
62
|
+
* kernel per read at construction.
|
|
63
|
+
*
|
|
64
|
+
* Every append has these obligations:
|
|
65
|
+
* - `k` [B, Hkv, L, Dk] and `v` [B, Hkv, L, Dv] are borrowed. The caller
|
|
66
|
+
* disposes them after the call returns. `k` already carries the positional
|
|
67
|
+
* encoding for the positions it occupies, which start at each row's offset.
|
|
68
|
+
* - Rows follow this cache's row layout: one row for a single-sequence cache;
|
|
69
|
+
* `rowOffsets`, `leftPad` and padding prepared through `PaddedPrefillCache`
|
|
70
|
+
* for a batchable layout. Each row appends at its own offset, and the offsets
|
|
71
|
+
* have advanced by `L` when the call returns.
|
|
72
|
+
* - The caller owns the returned read (see {@link AttentionRead}).
|
|
73
|
+
* - The method name is the phase. A cache never infers the phase from `L`, from
|
|
74
|
+
* the query shape or from a mask. Calling a method outside its phase gives an
|
|
75
|
+
* undefined result. */
|
|
76
|
+
export interface AttentionCache extends Cache {
|
|
77
|
+
/** Decode: one new position per row (`L` = 1). Each row's query sees that
|
|
78
|
+
* row's valid stored positions up to and including the one just appended,
|
|
79
|
+
* limited to the cache's sliding window. */
|
|
80
|
+
appendDecode(k: MlxArray, v: MlxArray): AttentionRead;
|
|
81
|
+
/** Window: `L` new positions per row, causal within the window, for prefill
|
|
82
|
+
* chunks, prefill tails and speculative verify windows. Query `i` of a row
|
|
83
|
+
* sees the row's earlier valid positions and window positions `0..i`, limited
|
|
84
|
+
* to the cache's sliding window. Left padding and prepared prefill padding are
|
|
85
|
+
* never visible. Outputs at padded query positions are unspecified and the
|
|
86
|
+
* caller ignores them. To append context without attending, make this call
|
|
87
|
+
* and dispose the read unused. */
|
|
88
|
+
appendWindow(k: MlxArray, v: MlxArray): AttentionRead;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/** A training pass's cache: it stores nothing and owns the positions its pass
|
|
92
|
+
* reads at, the uniform positions from its offset or, for a prefix-shared
|
|
93
|
+
* concat [prompt; chosen; rejected], each response restarted after the prompt. */
|
|
94
|
+
export interface TrainingAttentionCache extends AttentionCache {
|
|
95
|
+
/** `x` [B, H, T, D] rotated at this pass's positions: `rope` rotates one
|
|
96
|
+
* contiguous block of positions from a scalar offset. The caller owns `x`. */
|
|
97
|
+
ropePositions(x: MlxArray, rope: (block: MlxArray, offset: number) => MlxArray): MlxArray;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/** A cache composed for committed-token appends (token fill), where every
|
|
101
|
+
* position of the span is already decided. */
|
|
102
|
+
export interface CommittedAttentionCache extends AttentionCache {
|
|
103
|
+
/** Committed span: `L` decided positions per row, causal within the span.
|
|
104
|
+
* Each query attends its own causal prefix with the arithmetic of a
|
|
105
|
+
* one-position read, so the span keeps the single-position reduction order
|
|
106
|
+
* the graph qualifies per KV format (`MlxKnownSpans`, read by `appendKnown`). This replaces the
|
|
107
|
+
* `independentPositions` flag. The only caller today runs one row with up to
|
|
108
|
+
* four positions. */
|
|
109
|
+
appendCommitted(k: MlxArray, v: MlxArray): AttentionRead;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/** A cache composed for prompts whose media tokens attend each other in both
|
|
113
|
+
* directions (Gemma 4 vision prefill). */
|
|
114
|
+
export interface BidirectionalAttentionCache extends AttentionCache {
|
|
115
|
+
/** Bidirectional window: the same as `appendWindow`, except that two
|
|
116
|
+
* positions both flagged in `bidirectional` see each other in either
|
|
117
|
+
* direction, regardless of order or the sliding window. `bidirectional` is a
|
|
118
|
+
* borrowed bool [L] that applies to every row. Defined only for the first
|
|
119
|
+
* window of a sequence (offset 0). */
|
|
120
|
+
appendBidirectional(k: MlxArray, v: MlxArray, bidirectional: MlxArray): AttentionRead;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/** A cache composed for an encoder that reads its whole prompt with no sliding
|
|
124
|
+
* window, its media tokens attending each other in both directions (the
|
|
125
|
+
* DiffusionGemma vision encoder, which reads every layer, sliding or full,
|
|
126
|
+
* through one mask over the whole prompt). */
|
|
127
|
+
export interface EncoderAttentionCache extends AttentionCache {
|
|
128
|
+
/** Encoder window: the first window of a sequence (offset 0), `L` new
|
|
129
|
+
* positions per row, stored as `appendWindow` stores them. Query `i` sees
|
|
130
|
+
* window positions `0..i`, and two positions both flagged in `bidirectional`
|
|
131
|
+
* see each other in either direction. The cache's sliding window does not
|
|
132
|
+
* limit this read: every query sees the whole window, whatever its length.
|
|
133
|
+
* (`appendBidirectional` is the read the sliding window does limit.)
|
|
134
|
+
* `bidirectional` is a borrowed bool [L] that applies to every row. */
|
|
135
|
+
appendEncoderWindow(k: MlxArray, v: MlxArray, bidirectional: MlxArray): AttentionRead;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/** A cache composed for block reads, where a block's queries attend the stored
|
|
139
|
+
* context plus the block's own keys and values without storing them
|
|
140
|
+
* (DiffusionGemma's canvas pass, the DFlash 2 drafter's block over its
|
|
141
|
+
* projected context). */
|
|
142
|
+
export interface BlockAttentionCache extends AttentionCache {
|
|
143
|
+
/** Block read: `k` [B, Hkv, L, Dk] and `v` [B, Hkv, L, Dv] are the block's
|
|
144
|
+
* keys and values, borrowed and not appended. Offsets do not move. Every
|
|
145
|
+
* query of a row sees that row's valid stored positions, limited to the
|
|
146
|
+
* cache's sliding window, and all `L` block positions. The read takes queries
|
|
147
|
+
* for exactly this block. */
|
|
148
|
+
readBlock(k: MlxArray, v: MlxArray): AttentionRead;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/** A gated DeltaNet block's heads for one recurrence call. */
|
|
152
|
+
export interface GatedDeltaHeads {
|
|
153
|
+
/** [B, S, Hk, Dk], normalized and scaled by the block. */
|
|
154
|
+
readonly q: MlxArray;
|
|
155
|
+
/** [B, S, Hk, Dk], normalized and scaled by the block. */
|
|
156
|
+
readonly k: MlxArray;
|
|
157
|
+
/** [B, S, Hv, Dv]. */
|
|
158
|
+
readonly v: MlxArray;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/** What a gated DeltaNet block lends its recurrent cache for one call: the
|
|
162
|
+
* layer's recurrence weights and the block's glue between the convolution and
|
|
163
|
+
* the recurrence. The block keeps its projections, norms and activations. The
|
|
164
|
+
* cache keeps the convolution state, the recurrent state and the kernels that
|
|
165
|
+
* update them. */
|
|
166
|
+
export interface GatedDeltaParameters {
|
|
167
|
+
/** Depthwise causal convolution weight [convDim, K, 1]. */
|
|
168
|
+
readonly convWeight: MlxArray;
|
|
169
|
+
/** Per-value-head decay logarithm (`A_log`) [Hv]. */
|
|
170
|
+
readonly aLog: MlxArray;
|
|
171
|
+
/** Per-value-head timestep bias [Hv]. */
|
|
172
|
+
readonly dtBias: MlxArray;
|
|
173
|
+
/** The block's glue: the activation of the convolution output, the split
|
|
174
|
+
* into q, k and v heads, and their norms and scaling. Pure. `convolved`
|
|
175
|
+
* [B, S, convDim] is the raw convolution output (before activation) and is
|
|
176
|
+
* borrowed. The cache owns and disposes the returned heads. The cache calls
|
|
177
|
+
* this once per recurrence call; a speculative round keeps the window's k and
|
|
178
|
+
* v for the rows a rollback retains. */
|
|
179
|
+
heads(convolved: MlxArray): GatedDeltaHeads;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/** Recurrent state for one gated DeltaNet layer. It owns its read the way
|
|
183
|
+
* {@link AttentionCache} does: the block hands over its projected inputs and
|
|
184
|
+
* receives the recurrence output. The cache zeroes padded positions, runs the
|
|
185
|
+
* causal convolution over its stored convolution state, keeps each row's
|
|
186
|
+
* convolution tail, runs the gated-delta recurrence with the kernels in
|
|
187
|
+
* `kernels/delta`, replaces both states and advances its offsets. A training
|
|
188
|
+
* cache runs the differentiable recurrence behind the same calls.
|
|
189
|
+
*
|
|
190
|
+
* Both calls have these obligations:
|
|
191
|
+
* - `qkv` [B, S, convDim] is the `in_proj_qkv` output before convolution, and
|
|
192
|
+
* `a`, `b` [B, S, Hv] are the raw `in_proj_a` and `in_proj_b` outputs. The
|
|
193
|
+
* call consumes all three: the cache disposes them, or keeps them for an
|
|
194
|
+
* armed speculative round. The caller must not use or dispose them after the
|
|
195
|
+
* call.
|
|
196
|
+
* - `layer` is borrowed and must stay valid until an armed speculative round
|
|
197
|
+
* resolves, because rollback replays through it.
|
|
198
|
+
* - The caller owns the output [B, S, Hv, Dv]. The block applies the output
|
|
199
|
+
* gate (`z`) and the output projection itself.
|
|
200
|
+
* - Inside an armed round (`specRoundBegin`), the call records the pre-call
|
|
201
|
+
* states and its inputs, so `specRoundRollback(keep)` restores and replays the
|
|
202
|
+
* accepted prefix inside the cache. At most one call per armed round.
|
|
203
|
+
* - Rows follow this cache's row layout, as for {@link AttentionCache}. The
|
|
204
|
+
* method name is the phase; a cache never infers it from `S`. */
|
|
205
|
+
export interface GatedDeltaCache extends Cache {
|
|
206
|
+
/** Decode: one new position per row (`S` = 1), with no prefill padding in
|
|
207
|
+
* effect. */
|
|
208
|
+
recurDecode(qkv: MlxArray, a: MlxArray, b: MlxArray, layer: GatedDeltaParameters): MlxArray;
|
|
209
|
+
/** Window: `S` positions per row, for prefill chunks and tails, speculative
|
|
210
|
+
* verify windows and committed spans. Padding prepared through
|
|
211
|
+
* `PaddedPrefillCache` holds: padded positions change neither state, each
|
|
212
|
+
* row's convolution tail ends at its last real position, and each row's offset
|
|
213
|
+
* advances by its real count. Outputs at padded positions are unspecified. */
|
|
214
|
+
recurWindow(qkv: MlxArray, a: MlxArray, b: MlxArray, layer: GatedDeltaParameters): MlxArray;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
/** The compressed state of one latent attention layer after an append, as
|
|
218
|
+
* caller-owned views of every stored position in order (float32). The caller
|
|
219
|
+
* disposes all three. Rows follow the cache's row layout: right-justified, row
|
|
220
|
+
* `b`'s positions starting at `leftPad[b]`. */
|
|
221
|
+
export interface LatentAttentionState {
|
|
222
|
+
/** [B, T, kvLoraRank]: the normalized compressed content state. */
|
|
223
|
+
readonly latent: MlxArray;
|
|
224
|
+
/** [B, T, ropeHeadDim]: the decoupled RoPE key, already rotated. */
|
|
225
|
+
readonly rope: MlxArray;
|
|
226
|
+
/** [B, T, indexHeadDim]: the sparse-attention (DSA) index keys, on a cache
|
|
227
|
+
* composed to store them; null otherwise. */
|
|
228
|
+
readonly indexKeys: MlxArray | null;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
/** State for one multi-head latent attention layer (GLM-5.2's MLA): it stores
|
|
232
|
+
* the checkpoint-native compressed state per position (the latent and the
|
|
233
|
+
* decoupled RoPE key, and on a sparse-attention layer the DSA index key), never
|
|
234
|
+
* per-head keys and values. The attention block projects its queries and that
|
|
235
|
+
* state, appends the state here and reads back everything stored, from which
|
|
236
|
+
* it reconstructs or absorbs keys and values itself (the same split as
|
|
237
|
+
* {@link GatedDeltaCache}: the block keeps its projections, the cache keeps the
|
|
238
|
+
* state and its row layout). A layer composed with DSA appends an index key
|
|
239
|
+
* with every position and reads the index keys stored before its append to
|
|
240
|
+
* select positions.
|
|
241
|
+
*
|
|
242
|
+
* Rows: one row for a single sequence; a batch keeps its rows right-justified
|
|
243
|
+
* along the sequence axis, `rowOffsets[b]` positions in row `b` starting at
|
|
244
|
+
* `leftPad[b]`. Inputs to an append are borrowed and float32. */
|
|
245
|
+
export interface LatentAttentionCache extends Cache {
|
|
246
|
+
readonly kvLoraRank: number;
|
|
247
|
+
readonly ropeHeadDim: number;
|
|
248
|
+
/** Rows in the layout, or null before the first append. */
|
|
249
|
+
readonly batchSize: number | null;
|
|
250
|
+
readonly rowOffsets: readonly number[];
|
|
251
|
+
readonly leftPad: readonly number[];
|
|
252
|
+
/** The index keys stored so far, [B, offset, indexHeadDim], owned by the
|
|
253
|
+
* caller; null when none are stored (a cache without DSA, or an empty one). */
|
|
254
|
+
storedIndexKeys(): MlxArray | null;
|
|
255
|
+
/** Appends `L` positions per row (`latent` [B, L, kvLoraRank], `rope`
|
|
256
|
+
* [B, L, ropeHeadDim], and `indexKeys` [B, L, indexHeadDim] exactly when the
|
|
257
|
+
* cache stores them), advancing every row by `L`, and returns the state as of
|
|
258
|
+
* this append. A rejected append leaves the cache unchanged. */
|
|
259
|
+
appendLatent(latent: MlxArray, rope: MlxArray, indexKeys: MlxArray | null): LatentAttentionState;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
/** A captured numerical view supports multiple queries without appending KV
|
|
263
|
+
* again. It owns its tensor handles independently of later cache membership or
|
|
264
|
+
* precision changes. Query/mask inputs are borrowed; outputs are owned. */
|
|
265
|
+
export interface KvAttentionView {
|
|
266
|
+
/** Qualified committed spans retain the single-position reduction order. */
|
|
267
|
+
attend(q: MlxArray, scale: number, mask: Mask, independentPositions?: boolean): MlxArray;
|
|
268
|
+
dispose(): void;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
/** Owned read-only planes with validity separate from physical padding. */
|
|
272
|
+
export interface KvDonorRows {
|
|
273
|
+
readonly keys: MlxArray;
|
|
274
|
+
readonly values: MlxArray;
|
|
275
|
+
readonly offsets: readonly number[];
|
|
276
|
+
readonly starts: readonly number[];
|
|
277
|
+
readonly ends: readonly number[];
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
/** Captured Q-only attention hides plain or encoded donor storage. */
|
|
281
|
+
export interface KvDonorAttention extends KvAttentionView {
|
|
282
|
+
readonly width: number;
|
|
283
|
+
readonly dtype: Dtype;
|
|
284
|
+
readonly offsets: readonly number[];
|
|
285
|
+
readonly starts: readonly number[];
|
|
286
|
+
readonly ends: readonly number[];
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
/** The row-layout half of a composition's KV scheme, over one request's layer
|
|
290
|
+
* caches: where its serial caches (the graph's composed legos) join row
|
|
291
|
+
* layouts. The legos convert themselves inside their own appends; nothing here
|
|
292
|
+
* converts a serial cache. */
|
|
293
|
+
export interface KvMaintenance {
|
|
294
|
+
/** Limit committed work at a pending precision transition. */
|
|
295
|
+
maxAppendTokens?(cache: readonly Cache[]): number;
|
|
296
|
+
/** Bind state requiring row-local maintenance before shared decode. */
|
|
297
|
+
prepareBatch?(cache: Cache[]): void;
|
|
298
|
+
/** Bind all precision policies before a prefill cohort owns row boundaries. */
|
|
299
|
+
preparePrefill?(cache: Cache[]): void;
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
/** The storage a composed cache holds and converts (the bf16-first KV legos a
|
|
303
|
+
* graph's `makeCache` builds for its composition's KV scheme). The row
|
|
304
|
+
* layouts, clones and saved files take the storage, never the lego; whoever
|
|
305
|
+
* hands storage back to serial use composes it with `over`. */
|
|
306
|
+
export interface ComposedStorage {
|
|
307
|
+
/** The storage held now, borrowed: bf16 before the transition, quantized or
|
|
308
|
+
* encoded after. */
|
|
309
|
+
storage(): Cache;
|
|
310
|
+
/** This lego's composition over `storage`, which the result owns: storage
|
|
311
|
+
* that already holds the conversion start converts before this returns, and
|
|
312
|
+
* quantized storage reads with this lego's kernels. */
|
|
313
|
+
over(storage: Cache): Cache;
|
|
314
|
+
/** Hands the storage held now to the caller and leaves this lego empty. */
|
|
315
|
+
release(): Cache;
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
export interface Cache {
|
|
319
|
+
/** Present on a cache that composes the storage it holds (see ComposedStorage). */
|
|
320
|
+
readonly composed?: ComposedStorage;
|
|
321
|
+
/** Maximum committed positions before this state changes precision. */
|
|
322
|
+
maxAppendTokens?(): number;
|
|
323
|
+
captureDonorRows?(): KvDonorRows;
|
|
324
|
+
captureDonorAttention?(): KvDonorAttention;
|
|
325
|
+
/** A preparation method commits each request's own precision boundary.
|
|
326
|
+
* Splitting a forward for a sibling must not move that boundary. */
|
|
327
|
+
readonly prefillMaintenance?: {
|
|
328
|
+
beginPrefill(): void;
|
|
329
|
+
commitPrefill(rows: readonly number[]): void;
|
|
330
|
+
endPrefill(): void;
|
|
331
|
+
};
|
|
332
|
+
/** Earliest prefix whose retained representation can resume generation.
|
|
333
|
+
* Irreversible transitions may preserve bytes while invalidating older
|
|
334
|
+
* precision boundaries. Reuse policy must not trim below this offset. */
|
|
335
|
+
minimumReusableOffset?: number;
|
|
336
|
+
offset: number;
|
|
337
|
+
/** Stable storage identity for compatibility guards and persistence.
|
|
338
|
+
* REQUIRED: every capability predicate (isPlainKvCache, isRotating*,
|
|
339
|
+
* packages/inference/src/state/persistence.ts codecs) is a string compare on
|
|
340
|
+
* this value, so a missing
|
|
341
|
+
* override used to fail OPEN into wrong routing (PRs #42/#43:
|
|
342
|
+
* BatchedRotatingCache shipped without one and batched joins dropped
|
|
343
|
+
* running rows). Wrappers report their own kind plus the inner kind. */
|
|
344
|
+
signature(): string;
|
|
345
|
+
/** Physical cache storage consumed by one additional token for one row.
|
|
346
|
+
* Recurrent caches return 0 because their state does not grow with the
|
|
347
|
+
* sequence. Optional for stateless/training adapters that are never
|
|
348
|
+
* admitted or persisted. */
|
|
349
|
+
bytesPerToken?(): number;
|
|
350
|
+
/** state() returned temporary views that the caller must release. */
|
|
351
|
+
readonly stateNeedsDispose?: boolean;
|
|
352
|
+
/** Compiled-decode trace adapters expose the RoPE offset as an int32
|
|
353
|
+
* array input here; real caches leave it unset (static int path). */
|
|
354
|
+
readonly ropeOffsetArr?: MlxArray;
|
|
355
|
+
state(): MlxArray[];
|
|
356
|
+
/** Can `trim(n)` drop the last n tokens? (Ring caches lose trimability
|
|
357
|
+
* once wrapped.) */
|
|
358
|
+
isTrimmable(): boolean;
|
|
359
|
+
/** Drop the last n tokens (future writes overwrite them). `bypass` (default
|
|
360
|
+
* false → unchanged behavior) skips the isTrimmable guard for the
|
|
361
|
+
* speculative-decode rollback case (trim the last n ≤ γ tips right after a
|
|
362
|
+
* >1 concat write); rotating caches then physically shrink the buffer tail. */
|
|
363
|
+
trim(n: number, bypass?: boolean): void;
|
|
364
|
+
/** Speculative verify-round support for NON-trimmable recurrent caches
|
|
365
|
+
* (SSMCache — gated-DeltaNet conv + recurrent state). A cache exposing
|
|
366
|
+
* these is spec-eligible without isTrimmable(): the serve loop arms a
|
|
367
|
+
* round before the verify forward (the layer snapshots pre-round state —
|
|
368
|
+
* free, MLX arrays are immutable — and records its position-local kernel
|
|
369
|
+
* inputs), then resolves it: commit on full accept, or rollback(keep)
|
|
370
|
+
* which restores the snapshot and bit-exactly REPLAYS the first `keep`
|
|
371
|
+
* window tokens through the recurrence (identical arithmetic prefix ⇒
|
|
372
|
+
* identical state). Trimmable caches leave these unset and keep trim(). */
|
|
373
|
+
specRoundBegin?(): void;
|
|
374
|
+
specRoundCommit?(): void;
|
|
375
|
+
specRoundRollback?(keep: number): void;
|
|
376
|
+
dispose(): void;
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
export interface RowBatchCache extends Cache {
|
|
380
|
+
readonly batchSize: number;
|
|
381
|
+
filterRows(keep: readonly number[]): void;
|
|
382
|
+
extractRow(row: number): Cache | null;
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
/**
|
|
386
|
+
* Capability contract for cache layouts that own their dynamic-row batching.
|
|
387
|
+
* The scheduler uses this for every storage family (plain and quantized KV,
|
|
388
|
+
* sliding windows, recurrent state, and layouts such as GLM's compressed MLA/DSA
|
|
389
|
+
* state) instead of teaching the scheduler their tensor layout. `mergeRows`
|
|
390
|
+
* writes into an empty cache and does not consume inputs: its sources are a
|
|
391
|
+
* running layout or one serial cache, then one serial cache per joining row.
|
|
392
|
+
* Extracted rows are independent owned serial caches.
|
|
393
|
+
*/
|
|
394
|
+
export interface BatchableCache extends Cache {
|
|
395
|
+
readonly batchSize: number | null;
|
|
396
|
+
readonly rowOffsets: readonly number[];
|
|
397
|
+
readonly leftPad: readonly number[];
|
|
398
|
+
readonly maxTokens?: number;
|
|
399
|
+
makeEmptyBatch(): BatchableCache;
|
|
400
|
+
mergeRows(rows: readonly Cache[]): void;
|
|
401
|
+
extractRow(row: number): Cache;
|
|
402
|
+
filterRows(keep: readonly number[]): void;
|
|
403
|
+
projectedBytes(tokens: number): number;
|
|
404
|
+
/** Whether `row` can be published as a cache covering exactly `tokens`
|
|
405
|
+
* positions. State that cannot be trimmed (recurrent) refuses a row whose own
|
|
406
|
+
* count differs: an entry keyed to other tokens would corrupt every later
|
|
407
|
+
* exact hit. Absent: any row can be published. */
|
|
408
|
+
canPublishRow?(row: number, tokens: number): boolean;
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
/**
|
|
412
|
+
* Verification rows: the row layout a speculative method keeps its target rows
|
|
413
|
+
* in, holding the speculative transaction. Every storage a cache lego holds
|
|
414
|
+
* names one (state's `targetCacheLayout`), so any lego serves speculation.
|
|
415
|
+
*
|
|
416
|
+
* The method arms a round before the verify window (`specRoundBegin`), appends
|
|
417
|
+
* the window, then resolves it: `specRoundCommit` keeps every row's window;
|
|
418
|
+
* `specRoundRollback(keep)` keeps the first `keep` positions of each row's
|
|
419
|
+
* window (one count for every row, or one per row). After either, every row is
|
|
420
|
+
* exactly as if only its kept positions had been appended: the same offsets and
|
|
421
|
+
* stored positions, the same reads from then on.
|
|
422
|
+
*/
|
|
423
|
+
export interface SpeculativeRowLayout extends BatchableCache {
|
|
424
|
+
makeEmptyBatch(): SpeculativeRowLayout;
|
|
425
|
+
specRoundBegin(): void;
|
|
426
|
+
specRoundCommit(): void;
|
|
427
|
+
specRoundRollback(keep: number | readonly number[]): void;
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
/** Padding is interpreted by cache geometry, independently of scheduling.
|
|
431
|
+
* Left padding initializes an empty group; lengths count input columns before
|
|
432
|
+
* trailing padding. Finalize before ordinary decode or publishing checkpoints. */
|
|
433
|
+
export interface PrefillPadding {
|
|
434
|
+
readonly leftPadding?: readonly number[];
|
|
435
|
+
readonly lengths: readonly number[];
|
|
436
|
+
readonly rightPadding?: readonly number[];
|
|
437
|
+
}
|
|
438
|
+
export interface PaddedPrefillCache extends Cache {
|
|
439
|
+
preparePrefill(padding: PrefillPadding): void;
|
|
440
|
+
finalizePrefill(): void;
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
/** How one decode step interacts with a cache under compiled decode
|
|
444
|
+
* (returned by prepareDecodeStep, consumed by compiled-decode.ts):
|
|
445
|
+
* - "concat": the compiled graph fetches concat(active prefix, new kv)
|
|
446
|
+
* — same values as today's write-then-slice — and the WRITE happens
|
|
447
|
+
* outside the graph right after (writeDecodeStep), keeping the buffer
|
|
448
|
+
* single-referenced at its slice_update so mlx donates it in place.
|
|
449
|
+
* - "ring": the write happens IN-graph (slice_update_dynamic at
|
|
450
|
+
* writePos) and the fetch is the full updated buffer — the rotating
|
|
451
|
+
* steady state, where attention reads the whole ring in ring order
|
|
452
|
+
* (a concat would permute KV positions and change summation order).
|
|
453
|
+
* The updated buffers come back as closure outputs; adoptDecodeStep
|
|
454
|
+
* swaps them in. */
|
|
455
|
+
export interface DecodeStepPlan {
|
|
456
|
+
fetch: "concat" | "ring";
|
|
457
|
+
/** Write position on axis 2 (== ring index for rotating caches). */
|
|
458
|
+
writePos: number;
|
|
459
|
+
/** Valid prefix length for "concat" fetches (== offset). */
|
|
460
|
+
activeLen: number;
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
/** What a compiled decode step hands a cache to assemble its closure inputs. The
|
|
464
|
+
* arrays it returns live for one step; the runner releases them afterwards. */
|
|
465
|
+
export interface DecodeStepInputs {
|
|
466
|
+
/** `array[.., 0:length, ..]` along the sequence axis (axis 2). */
|
|
467
|
+
activeView(array: MlxArray, length: number): MlxArray;
|
|
468
|
+
/** The int32 `[1]` write position (shared between caches at the same position). */
|
|
469
|
+
writePosition(position: number): MlxArray;
|
|
470
|
+
/** Registers `array`, which the cache computed for this step's inputs (a
|
|
471
|
+
* prefix it decodes outside the recorded graph), for release after the step;
|
|
472
|
+
* returns it. Takes ownership. */
|
|
473
|
+
own(array: MlxArray): MlxArray;
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
/** The stand-in a cache places in the traced graph for one step: attention
|
|
477
|
+
* appends to it exactly as it would to the real cache, and the arrays it appends
|
|
478
|
+
* become closure outputs (`outs`) instead of a buffer write. */
|
|
479
|
+
export interface DecodeTrace extends Cache {
|
|
480
|
+
outs: MlxArray[];
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
/** One cache's slot in a compiled decode closure. Plain data: it captures no
|
|
484
|
+
* cache, so a closure built once serves every later step and generation. */
|
|
485
|
+
export interface DecodeSlot {
|
|
486
|
+
/** Graph-shape signature (cache kind, quantization); offsets and capacities
|
|
487
|
+
* are array values or shapeless dimensions and stay out of it. */
|
|
488
|
+
readonly key: string;
|
|
489
|
+
/** The write happens in the graph (ring) or outside it after the step (concat). */
|
|
490
|
+
readonly fetch: DecodeStepPlan["fetch"];
|
|
491
|
+
/** Closure inputs this cache feeds, and closure outputs it returns. */
|
|
492
|
+
readonly inputs: number;
|
|
493
|
+
readonly outputs: number;
|
|
494
|
+
/** The traced stand-in over this slot's `inputs`; `ropeOffset` is the int32 RoPE position input. */
|
|
495
|
+
trace(inputs: readonly MlxArray[], ropeOffset: MlxArray): DecodeTrace;
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
/** A cache the compiled decode step can drive: it declares the slot it occupies
|
|
499
|
+
* in the closure for the coming step and applies the closure's outputs back. */
|
|
500
|
+
export interface CompiledDecodeCache extends Cache {
|
|
501
|
+
/** Host-side bookkeeping for a 1-token step (growth, rotation), without the write. */
|
|
502
|
+
prepareDecodeStep(): DecodeStepPlan;
|
|
503
|
+
/** Non-mutating: the fetch `prepareDecodeStep` will choose. */
|
|
504
|
+
decodePhase(): DecodeStepPlan["fetch"];
|
|
505
|
+
decodeSlot(plan: DecodeStepPlan): DecodeSlot;
|
|
506
|
+
/** The closure inputs of `slot`, in order. */
|
|
507
|
+
decodeInputs(plan: DecodeStepPlan, step: DecodeStepInputs): MlxArray[];
|
|
508
|
+
/** Apply the closure's outputs (takes ownership); returns arrays to evaluate with the step. */
|
|
509
|
+
commitDecodeStep(slot: DecodeSlot, outputs: MlxArray[]): MlxArray[];
|
|
510
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { MlxArray } from "@mlx-bun/mlx/array";
|
|
2
|
+
|
|
3
|
+
/** Generation-method state accompanying the target cache. The method owns
|
|
4
|
+
* its schema and alignment; storage owns these immutable tensor snapshots.
|
|
5
|
+
* Attachments require an exact prefix boundary and are never trimmed. */
|
|
6
|
+
export interface CheckpointAttachment {
|
|
7
|
+
schema: string;
|
|
8
|
+
metadata: Record<string, string | number | boolean>;
|
|
9
|
+
tensors: MlxArray[];
|
|
10
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { CheckpointAttachment } from "./checkpoint";
|
|
2
|
+
|
|
3
|
+
export interface DraftRowCheckpoint {
|
|
4
|
+
readonly processedTokens: number;
|
|
5
|
+
readonly attachment: CheckpointAttachment;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
/** Attachment schemas of the draft methods' persisted row state. The strings
|
|
9
|
+
* are stored in checkpoints, so they never change with the code that reads them. */
|
|
10
|
+
export const DRAFT_CHECKPOINT_SCHEMA = Object.freeze({
|
|
11
|
+
assistant: "gemma-assistant-v1",
|
|
12
|
+
qwenMtp: "qwen-mtp-v1",
|
|
13
|
+
glm52Mtp: "glm52-native-mtp-v1",
|
|
14
|
+
});
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { MlxArray } from "@mlx-bun/mlx/array";
|
|
2
|
+
import type { Dtype } from "@mlx-bun/mlx/ffi";
|
|
3
|
+
import type { MlxRowTable } from "./row-table";
|
|
4
|
+
import type { MlxHeadForward, MlxHeadRange } from "./head";
|
|
5
|
+
|
|
6
|
+
export type DraftHeadOperations = MlxRowTable<MlxHeadForward> | readonly MlxHeadRange[];
|
|
7
|
+
|
|
8
|
+
/** Numerical ports are backend-specific; returned arrays are caller-owned. */
|
|
9
|
+
export interface DraftProjection {
|
|
10
|
+
readonly embed: {
|
|
11
|
+
encode(ids: MlxArray): MlxArray;
|
|
12
|
+
readonly scales: { readonly dtype: Dtype };
|
|
13
|
+
};
|
|
14
|
+
/** The target's output head per row count or range: the drafter indexes it by the
|
|
15
|
+
* rows it projects. Borrows the hidden; the logits belong to the caller. */
|
|
16
|
+
readonly logits: DraftHeadOperations;
|
|
17
|
+
/** Declared by a graph whose composition measured a drafter selecting over the
|
|
18
|
+
* target's frequency-ranked draft vocabulary: its ids [N] (ascending, uint32,
|
|
19
|
+
* borrowed) and the head's projection onto those rows per row count or range
|
|
20
|
+
* (logits [..., N], caller-owned). A drafter that selects by its scores alone
|
|
21
|
+
* selects over these rows; the target still verifies over its full head.
|
|
22
|
+
* Absent: the full head. */
|
|
23
|
+
readonly vocabulary?: {
|
|
24
|
+
readonly ids: MlxArray;
|
|
25
|
+
readonly logits: DraftHeadOperations;
|
|
26
|
+
};
|
|
27
|
+
}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import type { MlxArray } from "@mlx-bun/mlx/array";
|
|
2
|
+
import type { AssistantDonors } from "./attention";
|
|
3
|
+
import type { DraftProjection } from "./draft-projection";
|
|
4
|
+
import type { MlxRowTable } from "./row-table";
|
|
5
|
+
|
|
6
|
+
/** Read-only target state and embedding, independent of draft scheduling. */
|
|
7
|
+
export interface AssistantRowsTarget {
|
|
8
|
+
readonly hiddenSize: number;
|
|
9
|
+
embed(ids: MlxArray): MlxArray;
|
|
10
|
+
readDonors(): AssistantDonors & {
|
|
11
|
+
readonly positions: readonly number[];
|
|
12
|
+
dispose(): void;
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/** What a recurrent multi-token-prediction head reads from its target: the
|
|
17
|
+
* final hidden layer's output (tapped before the final norm), the token
|
|
18
|
+
* embedding, and the output head. */
|
|
19
|
+
export interface RecurrentMtpTarget {
|
|
20
|
+
readonly hiddenSize: number;
|
|
21
|
+
readonly layerCount: number;
|
|
22
|
+
embed(ids: MlxArray): MlxArray;
|
|
23
|
+
/** The output head per row count or range, indexed by the rows the drafter projects. */
|
|
24
|
+
readonly logits: MlxRowTable<(hidden: MlxArray) => MlxArray>;
|
|
25
|
+
/** The untied quantized vocabulary projection, when the drafter may project
|
|
26
|
+
* onto a row subset of it (frequency-ranked draft vocabulary). Borrowed. */
|
|
27
|
+
readonly vocabularyHead?: {
|
|
28
|
+
readonly w: MlxArray; readonly scales: MlxArray; readonly biases: MlxArray | null;
|
|
29
|
+
readonly spec: { bits: number; groupSize: number; mode: string };
|
|
30
|
+
readonly vocabSize: number;
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/** Multi-layer hidden-state taps and the embedding/head projection a drafter
|
|
35
|
+
* conditions on. */
|
|
36
|
+
export interface HiddenLayerTapsTarget {
|
|
37
|
+
readonly layerCount: number;
|
|
38
|
+
readonly projection: DraftProjection;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/** A residual stream in another basis than the trained model's: the TurboQuant
|
|
42
|
+
* R1 fold (packages/quantize/src/rotate.ts) stores h·R1, R1 = diag(s)·M, with s
|
|
43
|
+
* the seed's lane-0 sign vector and M MLX's hadamard_transform/√n, and moves
|
|
44
|
+
* the final-norm gain into the head. */
|
|
45
|
+
export interface ResidualBasis {
|
|
46
|
+
/** Seed of R1's sign vector. */
|
|
47
|
+
readonly r1Seed: number;
|
|
48
|
+
/** The final-norm gain the fold moved into the head (effective, 1+w), one per hidden channel. */
|
|
49
|
+
readonly finalGain: Float32Array;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/** A projection kernel the target's composition measured on its device, built over a 4-bit, group-64 affine
|
|
53
|
+
* projection a drafter quantized itself (its packed weight, scales and biases, borrowed for the kernel's life):
|
|
54
|
+
* the forward over [.., inputs] activations, caller-owned output. */
|
|
55
|
+
export type DraftProjectionKernel = (w: MlxArray, scales: MlxArray, biases: MlxArray) => (x: MlxArray) => MlxArray;
|
|
56
|
+
export interface DraftProjectionRange { readonly from: number; readonly to: number; readonly operation: DraftProjectionKernel }
|
|
57
|
+
export type DraftProjectionKernels = MlxRowTable<DraftProjectionKernel> | readonly DraftProjectionRange[];
|
|
58
|
+
|
|
59
|
+
/** Graph-declared ports over the target's live state, named for what they
|
|
60
|
+
* provide. Sources request only the ports they consume and never inspect a
|
|
61
|
+
* concrete model or cache; a source refuses a target that lacks one with
|
|
62
|
+
* `targetLacks(port)` before any draft-side allocation. */
|
|
63
|
+
export interface TargetView {
|
|
64
|
+
/** Opaque identity for providers borrowing weights from one exact target. */
|
|
65
|
+
readonly identity: object;
|
|
66
|
+
readonly assistantRows?: AssistantRowsTarget;
|
|
67
|
+
readonly hiddenLayerTaps?: HiddenLayerTapsTarget;
|
|
68
|
+
readonly recurrentMtp?: RecurrentMtpTarget;
|
|
69
|
+
/** Declared by a graph whose residual stream carries a rotation fold; absent,
|
|
70
|
+
* the stream is in the trained model's basis. The same object on every view. */
|
|
71
|
+
readonly residualBasis?: ResidualBasis;
|
|
72
|
+
/** Declared by a graph whose composition measured the kernels a drafter's own 4-bit projections run on its
|
|
73
|
+
* device: one per row count or range of the rows they project. Absent, the drafter keeps its own rule. The same
|
|
74
|
+
* table on every view. */
|
|
75
|
+
readonly draftProjections?: DraftProjectionKernels;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export type TargetPort = "assistantRows" | "hiddenLayerTaps" | "recurrentMtp";
|
|
79
|
+
|
|
80
|
+
/** The refusal for a target graph that does not provide a requested port. */
|
|
81
|
+
export function targetLacks(port: TargetPort): Error {
|
|
82
|
+
return new Error(`target graph does not provide ${port}`);
|
|
83
|
+
}
|
|
84
|
+
|