@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,277 @@
|
|
|
1
|
+
import type { BatchableCache, Cache, KvMaintenance, SpeculativeRowLayout } from "../contracts/mlx/cache";
|
|
2
|
+
import type { KvStorageScheme } from "../contracts/portable/composition";
|
|
3
|
+
import { isBatchableCache } from "./capabilities";
|
|
4
|
+
import { composedAffineKernels, unfusedAffineKernels } from "./affine-attention";
|
|
5
|
+
import { turboQuantFusedDecode } from "./turboquant-codec";
|
|
6
|
+
import { PaddedKVRows } from "./batched-mask";
|
|
7
|
+
import { PaddedQuantKVRows } from "./batched-quant";
|
|
8
|
+
import { BatchedKVCache } from "./batched-kv";
|
|
9
|
+
import { BatchedQuantizedKVCache } from "./batched-quantized-kv";
|
|
10
|
+
import { BatchedRotatingCache } from "./batched-rotating";
|
|
11
|
+
import { BatchedRotatingQuantCache } from "./batched-rotating-quant";
|
|
12
|
+
import { BatchedSSMCache } from "./batched-ssm";
|
|
13
|
+
import { BatchedTurboQuantKVCache } from "./batched-turboquant-kv";
|
|
14
|
+
import { DelayedQuantizedKVCache } from "./delayed-quantized-kv";
|
|
15
|
+
import { DelayedRotatingQuantizedKVCache } from "./delayed-rotating-quantized-kv";
|
|
16
|
+
import { DelayedTurboQuantKVCache } from "./delayed-turboquant-kv";
|
|
17
|
+
import { MLACache } from "./glm52-cache";
|
|
18
|
+
import { EncodedLatentCache, PagedLatentCache } from "./latent-legos";
|
|
19
|
+
import { KVCache } from "./kv";
|
|
20
|
+
import { PagedKVCache } from "./paged/cache";
|
|
21
|
+
import { PagedKvRows } from "./paged/rows";
|
|
22
|
+
import { QuantizedKVCache } from "./quantized-kv";
|
|
23
|
+
import { RotatingKVCache } from "./rotating-kv";
|
|
24
|
+
import { RotatingAffineLayout, SpeculativeRotatingAffineLayout } from "./rotating-kv-layout";
|
|
25
|
+
import { RotatingQuantizedKVCache } from "./rotating-quantized-kv";
|
|
26
|
+
import { SpeculativeRotatingKVCache } from "./speculative-rotating-kv";
|
|
27
|
+
import { SSMCache } from "./ssm";
|
|
28
|
+
import { TurboQuantKVCache } from "./turboquant-kv";
|
|
29
|
+
|
|
30
|
+
/** The row layouts one storage joins, declared together. Each returns a new
|
|
31
|
+
* empty layout whose `mergeRows` takes this storage (and the layouts the same
|
|
32
|
+
* call makes):
|
|
33
|
+
* - `decode`: the layout a running batch keeps the rows in for continuous
|
|
34
|
+
* decoding;
|
|
35
|
+
* - `prefill`: the layout a prefill cohort keeps them in;
|
|
36
|
+
* - `verify`: the verification rows, which hold the speculative transaction. */
|
|
37
|
+
interface RowLayouts<C extends Cache> {
|
|
38
|
+
decode(cache: C): BatchableCache;
|
|
39
|
+
prefill(cache: C): BatchableCache;
|
|
40
|
+
verify(cache: C): SpeculativeRowLayout;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/** A storage class: what `instanceof` tests (its constructor may be private). */
|
|
44
|
+
type StorageClass<C extends Cache> = Function & { readonly prototype: C };
|
|
45
|
+
interface RowLayoutEntry<C extends Cache> extends RowLayouts<C> {
|
|
46
|
+
readonly storage: StorageClass<C>;
|
|
47
|
+
}
|
|
48
|
+
const entry = <C extends Cache>(storage: StorageClass<C>, layouts: RowLayouts<NoInfer<C>>): RowLayoutEntry<C> =>
|
|
49
|
+
({ storage, ...layouts });
|
|
50
|
+
/** A row layout's own declaration: its decode and prefill siblings are its
|
|
51
|
+
* empty batch, and so are its verification rows when it holds the transaction. */
|
|
52
|
+
const ownEmptyBatch = <C extends SpeculativeRowLayout>(storage: StorageClass<C>): RowLayoutEntry<C> =>
|
|
53
|
+
entry(storage, { decode: cache => cache.makeEmptyBatch(), prefill: cache => cache.makeEmptyBatch(), verify: cache => cache.makeEmptyBatch() });
|
|
54
|
+
|
|
55
|
+
const pagedRows = (cache: PagedKVCache) => new PagedKvRows(cache.capacityTokens, cache.blockSize, cache.direct, cache.quantization, cache.turbo);
|
|
56
|
+
const rotatingAffineVerify = (cache: { readonly maxSize: number; readonly groupSize: number; readonly bits: number;
|
|
57
|
+
readonly kernels: RotatingAffineLayout["kernels"]; readonly masks: RotatingAffineLayout["masks"] }) =>
|
|
58
|
+
new SpeculativeRotatingAffineLayout(cache.maxSize, cache.groupSize, cache.bits, cache.kernels, cache.masks);
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Every storage a cache lego holds and the row layouts it joins: the row-layout
|
|
62
|
+
* port's one table, as the codec table in `state/persistence.ts` is the SSD
|
|
63
|
+
* form's. A lego's storage (its graph cache, the storage a bf16-first lego
|
|
64
|
+
* holds, the delayed rows kv maintenance makes, the paged blocks the request
|
|
65
|
+
* policy pages a layer with) declares all three layouts here; a storage with no
|
|
66
|
+
* entry joins no rows and is not a lego. First match wins: a subclass precedes
|
|
67
|
+
* its base. A row layout reached through an entry is not looked up again: its
|
|
68
|
+
* sibling is its own empty batch (the `BatchableCache` port).
|
|
69
|
+
*/
|
|
70
|
+
const ROW_LAYOUTS: readonly RowLayoutEntry<Cache>[] = [
|
|
71
|
+
entry(PagedKVCache, { decode: pagedRows, prefill: pagedRows, verify: pagedRows }),
|
|
72
|
+
ownEmptyBatch(PagedKvRows),
|
|
73
|
+
ownEmptyBatch(MLACache),
|
|
74
|
+
ownEmptyBatch(EncodedLatentCache),
|
|
75
|
+
ownEmptyBatch(PagedLatentCache),
|
|
76
|
+
entry(DelayedRotatingQuantizedKVCache, {
|
|
77
|
+
decode: cache => cache.makeEmptyBatch(), prefill: cache => cache.makeEmptyBatch(),
|
|
78
|
+
verify: cache => new DelayedRotatingQuantizedKVCache(cache.maxSize, cache.groupSize, cache.bits, cache.start,
|
|
79
|
+
cache.kernelSet, undefined, true, cache.compose),
|
|
80
|
+
}),
|
|
81
|
+
entry(RotatingAffineLayout, { decode: cache => cache.makeEmptyBatch(), prefill: cache => cache.makeEmptyBatch(),
|
|
82
|
+
verify: rotatingAffineVerify }),
|
|
83
|
+
entry(BatchedRotatingQuantCache, { decode: cache => cache.makeEmptyBatch(), prefill: cache => cache.makeEmptyBatch(),
|
|
84
|
+
verify: rotatingAffineVerify }),
|
|
85
|
+
entry(RotatingQuantizedKVCache, {
|
|
86
|
+
decode: cache => BatchedRotatingQuantCache.empty(cache.maxSize, cache.groupSize, cache.bits, cache.kernels, [], cache.masks),
|
|
87
|
+
prefill: cache => new RotatingAffineLayout(cache.maxSize, cache.groupSize, cache.bits, cache.kernels, cache.masks),
|
|
88
|
+
verify: rotatingAffineVerify,
|
|
89
|
+
}),
|
|
90
|
+
ownEmptyBatch(SpeculativeRotatingKVCache),
|
|
91
|
+
entry(RotatingKVCache, {
|
|
92
|
+
decode: cache => new BatchedRotatingCache(cache.maxSize, [], cache.masks),
|
|
93
|
+
// Plain rotating rows never convert here (a start of Infinity), so no read
|
|
94
|
+
// takes the layout's kernel set; their dense reads say so.
|
|
95
|
+
prefill: cache => new DelayedRotatingQuantizedKVCache(cache.maxSize, 64, 4, Infinity, unfusedAffineKernels),
|
|
96
|
+
verify: cache => new SpeculativeRotatingKVCache(cache.maxSize, cache.masks),
|
|
97
|
+
}),
|
|
98
|
+
ownEmptyBatch(DelayedTurboQuantKVCache),
|
|
99
|
+
ownEmptyBatch(DelayedQuantizedKVCache),
|
|
100
|
+
ownEmptyBatch(BatchedTurboQuantKVCache),
|
|
101
|
+
ownEmptyBatch(BatchedKVCache),
|
|
102
|
+
ownEmptyBatch(BatchedQuantizedKVCache),
|
|
103
|
+
ownEmptyBatch(BatchedSSMCache),
|
|
104
|
+
entry(TurboQuantKVCache, {
|
|
105
|
+
decode: cache => new BatchedTurboQuantKVCache(cache.kBits, cache.vBits, cache.turboQuantKernels, cache.fusedDecode, cache.masks),
|
|
106
|
+
prefill: cache => new BatchedTurboQuantKVCache(cache.kBits, cache.vBits, cache.turboQuantKernels, cache.fusedDecode, cache.masks),
|
|
107
|
+
verify: cache => new BatchedTurboQuantKVCache(cache.kBits, cache.vBits, cache.turboQuantKernels, cache.fusedDecode, cache.masks),
|
|
108
|
+
}),
|
|
109
|
+
entry(SSMCache, { decode: () => new BatchedSSMCache(), prefill: () => new BatchedSSMCache(), verify: () => new BatchedSSMCache() }),
|
|
110
|
+
entry(QuantizedKVCache, {
|
|
111
|
+
decode: cache => new PaddedQuantKVRows(cache.groupSize, cache.bits, cache.kernels, cache.masks),
|
|
112
|
+
prefill: cache => new BatchedQuantizedKVCache(cache.groupSize, cache.bits, cache.kernels, cache.masks),
|
|
113
|
+
verify: cache => new BatchedQuantizedKVCache(cache.groupSize, cache.bits, cache.kernels, cache.masks),
|
|
114
|
+
}),
|
|
115
|
+
entry(KVCache, {
|
|
116
|
+
decode: cache => new PaddedKVRows(cache.masks),
|
|
117
|
+
prefill: cache => new BatchedKVCache(cache.masks, cache.windowRead),
|
|
118
|
+
verify: cache => new BatchedKVCache(cache.masks, cache.windowRead),
|
|
119
|
+
}),
|
|
120
|
+
];
|
|
121
|
+
|
|
122
|
+
/** The table's entry for `cache`'s storage class; undefined for a storage that
|
|
123
|
+
* joins no rows. */
|
|
124
|
+
function declaredRowLayouts(cache: Cache): RowLayouts<Cache> | undefined {
|
|
125
|
+
return ROW_LAYOUTS.find(item => cache instanceof item.storage);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/** The row layout a running batch keeps this cache's rows in, for ordinary
|
|
129
|
+
* continuous decoding: an empty layout whose `mergeRows` accepts the cache (and
|
|
130
|
+
* the layouts it made). Every storage a graph's caches, or their precision
|
|
131
|
+
* maintenance, produce has one; undefined for a cache that cannot batch. Answers
|
|
132
|
+
* without allocating, so a binding can probe support. */
|
|
133
|
+
export function ownedCacheLayoutFactory(cache: Cache): (() => BatchableCache) | undefined {
|
|
134
|
+
const layouts = declaredRowLayouts(cache);
|
|
135
|
+
if (layouts) return () => layouts.decode(cache);
|
|
136
|
+
return isBatchableCache(cache) ? () => cache.makeEmptyBatch() : undefined;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/** Bind encoded state to its row layout. Execution owners only move rows. */
|
|
140
|
+
export function ownedCacheLayout(cache: Cache): BatchableCache | undefined {
|
|
141
|
+
return ownedCacheLayoutFactory(cache)?.();
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/** The layout a prefill cohort keeps this cache's rows in. */
|
|
145
|
+
export function prefillCacheLayout(cache: Cache): BatchableCache {
|
|
146
|
+
const layouts = declaredRowLayouts(cache);
|
|
147
|
+
if (layouts) return layouts.prefill(cache);
|
|
148
|
+
if (isBatchableCache(cache)) return cache.makeEmptyBatch();
|
|
149
|
+
throw new Error(`No prefill row layout for ${cache.signature()}`);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/** The verification rows of this cache's storage, an empty layout holding the
|
|
153
|
+
* speculative transaction, built over the cache's own numerical codec;
|
|
154
|
+
* undefined for a storage that joins no rows. Answers without allocating. */
|
|
155
|
+
export function targetRowLayoutFactory(cache: Cache): (() => SpeculativeRowLayout) | undefined {
|
|
156
|
+
const layouts = declaredRowLayouts(cache);
|
|
157
|
+
return layouts ? () => layouts.verify(cache) : undefined;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/** The verification rows of this cache's storage (see `targetRowLayoutFactory`). */
|
|
161
|
+
export function targetCacheLayout(cache: Cache): SpeculativeRowLayout {
|
|
162
|
+
const make = targetRowLayoutFactory(cache);
|
|
163
|
+
if (!make) throw new Error(`No target row layout for ${cache.signature()}`);
|
|
164
|
+
return make();
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/** A one-row layout's row in its serial form (owned; the layout keeps its own
|
|
168
|
+
* state), or null for a cache that is already serial: what persistence takes
|
|
169
|
+
* for a row that never joined another. */
|
|
170
|
+
export function extractSoleRow(cache: Cache): Cache | null {
|
|
171
|
+
return isBatchableCache(cache) && cache.batchSize === 1 ? cache.extractRow(0) : null;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/** Row `row` of a running layout in its serial form (owned), or null when the
|
|
175
|
+
* layout cannot publish that row covering exactly `tokens` positions (a
|
|
176
|
+
* recurrence that cannot be trimmed to them). */
|
|
177
|
+
export function publishRow(layout: Cache, row: number, tokens: number): Cache | null {
|
|
178
|
+
return isBatchableCache(layout) && (layout.canPublishRow?.(row, tokens) ?? true) ? layout.extractRow(row) : null;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/** Keep only the rows `keep` (sorted ascending) of a running layout. Serial
|
|
182
|
+
* state is not row-filtered: a lone adopted row leaves with the whole batch. */
|
|
183
|
+
export function filterLayoutRows(layout: Cache, keep: readonly number[]): void {
|
|
184
|
+
if (!isBatchableCache(layout)) throw new Error(`applyFilter: adopted ${layout.signature()} state cannot be row-filtered`);
|
|
185
|
+
layout.filterRows(keep);
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/** What a graph's fresh caches say about admitting a row when each one's
|
|
189
|
+
* storage owns its dynamic-row batching (a layout such as GLM-5.2's compressed
|
|
190
|
+
* state): its projected KV bytes at a length, and the most positions it holds.
|
|
191
|
+
* Null otherwise: admission bills the composition's KV scheme by the config.
|
|
192
|
+
* The projections read geometry only, so the caches may be released after. */
|
|
193
|
+
export function rowAdmission(caches: readonly Cache[]): { bytes(tokens: number): number; readonly maxTokens: number } | null {
|
|
194
|
+
if (!caches.every(isBatchableCache)) return null;
|
|
195
|
+
const layouts = caches as readonly BatchableCache[];
|
|
196
|
+
const projectors = layouts.map(cache => (tokens: number) => cache.projectedBytes(tokens));
|
|
197
|
+
return Object.freeze({
|
|
198
|
+
bytes: (tokens: number) => projectors.reduce((sum, project) => sum + project(tokens), 0),
|
|
199
|
+
maxTokens: Math.min(...layouts.map(cache => cache.maxTokens ?? Infinity)),
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
// Batch preparation: where a request's serial caches join row layouts under the
|
|
204
|
+
// composition's KV scheme. The graph's `makeCache` composes the scheme's legos
|
|
205
|
+
// (`state/bf16-first-kv.ts`), which convert themselves inside their own
|
|
206
|
+
// appends, so nothing here converts a serial cache. A lego's storage moves into
|
|
207
|
+
// the layout, and the rows of a scheme that converts later than the first
|
|
208
|
+
// append (or inside a prefill cohort) take the delayed row layouts, which
|
|
209
|
+
// convert each row at its own planned boundary.
|
|
210
|
+
|
|
211
|
+
export type { KvMaintenance };
|
|
212
|
+
|
|
213
|
+
/** Maintenance of the bf16 scheme: no layer converts. */
|
|
214
|
+
export const unchangedKv: KvMaintenance = Object.freeze({});
|
|
215
|
+
|
|
216
|
+
/** One layer's serial cache made ready for a row layout: a lego hands over its
|
|
217
|
+
* storage (and how it composes storage back for serial use); other storage is
|
|
218
|
+
* itself. */
|
|
219
|
+
function released(cache: Cache): { row: Cache; compose?: (storage: Cache) => Cache } {
|
|
220
|
+
const composed = cache.composed;
|
|
221
|
+
return composed ? { row: composed.release(), compose: composed.over } : { row: cache };
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
/** The positions a committed append may add before any layer's transition. */
|
|
225
|
+
function maxAppendTokens(cache: readonly Cache[]): number {
|
|
226
|
+
return Math.min(Infinity, ...cache.map(c => c.maxAppendTokens?.() ?? Infinity));
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
/** The row-layout maintenance of the composition's KV scheme `kv`.
|
|
230
|
+
* `preparePrefill` (a prefill cohort forms) routes every converting layer into
|
|
231
|
+
* its delayed row layout, built with the scheme's kernel set; `prepareBatch`
|
|
232
|
+
* (a prefilled row joins decode) routes a lego's storage to the batch layouts
|
|
233
|
+
* and, when the scheme converts after a start, into the same delayed layouts.
|
|
234
|
+
* A layout built from a lego hands back the lego's composition for the rows it
|
|
235
|
+
* extracts. */
|
|
236
|
+
export function createKvMaintenance(kv: KvStorageScheme): KvMaintenance {
|
|
237
|
+
if (kv.kind === "bf16") return unchangedKv;
|
|
238
|
+
const start = kv.quantizedKvStart ?? 0;
|
|
239
|
+
if (kv.kind === "turbo") {
|
|
240
|
+
const fusedDecode = turboQuantFusedDecode();
|
|
241
|
+
const preparePrefill = (cache: Cache[]): void => {
|
|
242
|
+
for (let layer = 0; layer < cache.length; layer++) {
|
|
243
|
+
const { row, compose } = released(cache[layer]!);
|
|
244
|
+
cache[layer] = row instanceof KVCache || row instanceof TurboQuantKVCache
|
|
245
|
+
? new DelayedTurboQuantKVCache(kv.kBits, kv.vBits, start, fusedDecode, row.turboQuantKernels, row, compose) : row;
|
|
246
|
+
}
|
|
247
|
+
};
|
|
248
|
+
return Object.freeze(start > 0 ? { preparePrefill, prepareBatch: preparePrefill, maxAppendTokens }
|
|
249
|
+
: { preparePrefill, prepareBatch: routeStorage });
|
|
250
|
+
}
|
|
251
|
+
const kernelSet = composedAffineKernels(kv.kernels);
|
|
252
|
+
// Resolve layer policy once when composing execution, never per token.
|
|
253
|
+
const spec = kv.kind === "affine" ? () => ({ bits: kv.bits, groupSize: kv.groupSize })
|
|
254
|
+
: (() => { const layers = new Map(kv.layers.map(entry => [entry.layer, entry])); return (layer: number) => layers.get(layer); })();
|
|
255
|
+
const preparePrefill = (cache: Cache[]): void => {
|
|
256
|
+
for (let layer = 0; layer < cache.length; layer++) {
|
|
257
|
+
const { row, compose } = released(cache[layer]!);
|
|
258
|
+
const scheme = spec(layer);
|
|
259
|
+
if (!scheme || !(row instanceof KVCache || row instanceof QuantizedKVCache || row instanceof RotatingKVCache ||
|
|
260
|
+
row instanceof RotatingQuantizedKVCache)) { cache[layer] = row; continue; }
|
|
261
|
+
cache[layer] = row instanceof RotatingKVCache || row instanceof RotatingQuantizedKVCache
|
|
262
|
+
? new DelayedRotatingQuantizedKVCache(row.maxSize, scheme.groupSize, scheme.bits, start, kernelSet, row, false, compose)
|
|
263
|
+
: new DelayedQuantizedKVCache(scheme.groupSize, scheme.bits, start, kernelSet, row, compose);
|
|
264
|
+
}
|
|
265
|
+
};
|
|
266
|
+
return Object.freeze(start > 0 ? { preparePrefill, prepareBatch: preparePrefill, maxAppendTokens }
|
|
267
|
+
: { preparePrefill, prepareBatch: routeStorage });
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
/** A prefilled row joins decode under a scheme that converts after the first
|
|
271
|
+
* append: every lego has converted (or holds a layer the scheme leaves bf16),
|
|
272
|
+
* so its storage joins the batch layouts as it is. */
|
|
273
|
+
function routeStorage(cache: Cache[]): void {
|
|
274
|
+
for (let layer = 0; layer < cache.length; layer++) cache[layer] = released(cache[layer]!).row;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
export { pagedDecodeCompiles } from "./paged/cache";
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { MlxArray } from "@mlx-bun/mlx/array";
|
|
2
|
+
import { type Cache } from "../contracts/mlx/cache";
|
|
3
|
+
import type { StateView } from "../contracts/portable/resources";
|
|
4
|
+
import { disposeResources,ownResource } from "../runtime/resources";
|
|
5
|
+
|
|
6
|
+
/** Compatibility boundary for legacy state(). Numerical code consumes a lease,
|
|
7
|
+
* never the legacy ownership marker. No copy, evaluation or fence is added. */
|
|
8
|
+
export function leaseCacheState(cache: Cache): StateView<MlxArray> {
|
|
9
|
+
return ownResource<readonly MlxArray[]>(cache.state(), cache.stateNeedsDispose ? disposeResources : () => {});
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/** Preserve the existing prefill evaluation order: temporary views first,
|
|
13
|
+
* borrowed state second. Partial acquisition releases every acquired view. */
|
|
14
|
+
export function leaseCacheStates(caches: readonly Cache[]): StateView<MlxArray> {
|
|
15
|
+
const leases: StateView<MlxArray>[] = [];
|
|
16
|
+
const close = () => disposeResources(leases.map((lease) => ({ dispose: () => lease.close() })));
|
|
17
|
+
try {
|
|
18
|
+
for (const owned of [true, false]) {
|
|
19
|
+
for (const cache of caches) if (!!cache.stateNeedsDispose === owned) leases.push(leaseCacheState(cache));
|
|
20
|
+
}
|
|
21
|
+
return ownResource(leases.flatMap((lease) => [...lease.borrow()]), close);
|
|
22
|
+
} catch (error) {
|
|
23
|
+
try { close(); } catch (cleanupError) { throw new AggregateError([error, cleanupError], "state view acquisition failed"); }
|
|
24
|
+
throw error;
|
|
25
|
+
}
|
|
26
|
+
}
|