@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,262 @@
|
|
|
1
|
+
// Dedicated GLM-5.2 / glm_moe_dsa configuration.
|
|
2
|
+
//
|
|
3
|
+
// This intentionally does not extend the universal dense descriptor. GLM-5.2
|
|
4
|
+
// has a different attention state (compressed MLA + DSA), a correction-biased
|
|
5
|
+
// sigmoid router, a native MTP row, and a converted Colibri container whose
|
|
6
|
+
// quantization metadata is carried by tensor byte geometry rather than the
|
|
7
|
+
// source checkpoint's FP8 quantization_config.
|
|
8
|
+
|
|
9
|
+
export type Glm52IndexerType = "full" | "shared";
|
|
10
|
+
|
|
11
|
+
export interface Glm52Config {
|
|
12
|
+
readonly modelDir: string;
|
|
13
|
+
readonly modelType: "glm_moe_dsa";
|
|
14
|
+
readonly architectures: string[];
|
|
15
|
+
readonly hiddenSize: number;
|
|
16
|
+
readonly numHiddenLayers: number;
|
|
17
|
+
readonly numAttentionHeads: number;
|
|
18
|
+
readonly numKeyValueHeads: number;
|
|
19
|
+
readonly qLoraRank: number;
|
|
20
|
+
readonly kvLoraRank: number;
|
|
21
|
+
readonly qkNopeHeadDim: number;
|
|
22
|
+
readonly qkRopeHeadDim: number;
|
|
23
|
+
readonly qkHeadDim: number;
|
|
24
|
+
readonly vHeadDim: number;
|
|
25
|
+
readonly firstKDenseReplace: number;
|
|
26
|
+
readonly intermediateSize: number;
|
|
27
|
+
readonly moeIntermediateSize: number;
|
|
28
|
+
readonly numRoutedExperts: number;
|
|
29
|
+
readonly numExpertsPerToken: number;
|
|
30
|
+
readonly numSharedExperts: number;
|
|
31
|
+
readonly nGroup: number;
|
|
32
|
+
readonly topkGroup: number;
|
|
33
|
+
readonly normTopkProb: boolean;
|
|
34
|
+
readonly routedScalingFactor: number;
|
|
35
|
+
readonly rmsNormEps: number;
|
|
36
|
+
readonly ropeTheta: number;
|
|
37
|
+
readonly ropeInterleave: boolean;
|
|
38
|
+
readonly vocabSize: number;
|
|
39
|
+
readonly maxPositionEmbeddings: number;
|
|
40
|
+
readonly indexTopk: number;
|
|
41
|
+
readonly indexNumHeads: number;
|
|
42
|
+
readonly indexHeadDim: number;
|
|
43
|
+
readonly indexerRopeInterleave: boolean;
|
|
44
|
+
readonly indexerTypes: Glm52IndexerType[];
|
|
45
|
+
readonly numNextnPredictLayers: number;
|
|
46
|
+
readonly indexShareForMtpIteration: boolean;
|
|
47
|
+
readonly eosTokenIds: number[];
|
|
48
|
+
readonly padTokenId: number;
|
|
49
|
+
readonly raw: Record<string, unknown>;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function integer(
|
|
53
|
+
raw: Record<string, any>,
|
|
54
|
+
key: string,
|
|
55
|
+
options: { min?: number; max?: number; fallback?: number } = {},
|
|
56
|
+
): number {
|
|
57
|
+
const value = raw[key] ?? options.fallback;
|
|
58
|
+
if (!Number.isInteger(value))
|
|
59
|
+
throw new Error(`GLM-5.2 config: ${key} must be an integer (got ${String(value)})`);
|
|
60
|
+
if (options.min !== undefined && value < options.min)
|
|
61
|
+
throw new Error(`GLM-5.2 config: ${key}=${value} is below ${options.min}`);
|
|
62
|
+
if (options.max !== undefined && value > options.max)
|
|
63
|
+
throw new Error(`GLM-5.2 config: ${key}=${value} exceeds ${options.max}`);
|
|
64
|
+
return value;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function finite(
|
|
68
|
+
raw: Record<string, any>,
|
|
69
|
+
key: string,
|
|
70
|
+
options: { min?: number; fallback?: number } = {},
|
|
71
|
+
): number {
|
|
72
|
+
const value = raw[key] ?? options.fallback;
|
|
73
|
+
if (typeof value !== "number" || !Number.isFinite(value))
|
|
74
|
+
throw new Error(`GLM-5.2 config: ${key} must be finite (got ${String(value)})`);
|
|
75
|
+
if (options.min !== undefined && value < options.min)
|
|
76
|
+
throw new Error(`GLM-5.2 config: ${key}=${value} is below ${options.min}`);
|
|
77
|
+
return value;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function boolean(raw: Record<string, any>, key: string, fallback = false): boolean {
|
|
81
|
+
const value = raw[key] ?? fallback;
|
|
82
|
+
if (typeof value !== "boolean")
|
|
83
|
+
throw new Error(`GLM-5.2 config: ${key} must be boolean (got ${String(value)})`);
|
|
84
|
+
return value;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
function tokenIds(value: unknown, source: string): number[] {
|
|
88
|
+
if (value === undefined || value === null) return [];
|
|
89
|
+
const values = Array.isArray(value) ? value : [value];
|
|
90
|
+
return values.map((id) => {
|
|
91
|
+
if (!Number.isInteger(id) || id < 0)
|
|
92
|
+
throw new Error(`GLM-5.2 config: ${source} contains invalid token id ${String(id)}`);
|
|
93
|
+
return id as number;
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
function unionTokenIds(...groups: number[][]): number[] {
|
|
98
|
+
const seen = new Set<number>();
|
|
99
|
+
const out: number[] = [];
|
|
100
|
+
for (const group of groups) {
|
|
101
|
+
for (const id of group) {
|
|
102
|
+
if (seen.has(id)) continue;
|
|
103
|
+
seen.add(id);
|
|
104
|
+
out.push(id);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
return out;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
function indexerSchedule(raw: Record<string, any>, layers: number): Glm52IndexerType[] {
|
|
111
|
+
const explicit = raw.indexer_types;
|
|
112
|
+
if (explicit !== undefined) {
|
|
113
|
+
if (!Array.isArray(explicit) || explicit.length !== layers)
|
|
114
|
+
throw new Error(
|
|
115
|
+
`GLM-5.2 config: indexer_types must have ${layers} entries ` +
|
|
116
|
+
`(got ${Array.isArray(explicit) ? explicit.length : typeof explicit})`,
|
|
117
|
+
);
|
|
118
|
+
return explicit.map((entry, layer) => {
|
|
119
|
+
if (entry !== "full" && entry !== "shared")
|
|
120
|
+
throw new Error(`GLM-5.2 config: indexer_types[${layer}]=${String(entry)}`);
|
|
121
|
+
return entry;
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
const frequency = integer(raw, "index_topk_freq", { min: 1, fallback: 1 });
|
|
126
|
+
const offset = integer(raw, "index_skip_topk_offset", { min: 0, fallback: 2 });
|
|
127
|
+
// Exact pinned-Colibri fallback:
|
|
128
|
+
// v = max(layer - offset + 1, 0); full iff v % frequency == 0.
|
|
129
|
+
return Array.from({ length: layers }, (_, layer) => {
|
|
130
|
+
const v = Math.max(layer - offset + 1, 0);
|
|
131
|
+
return v % frequency === 0 ? "full" : "shared";
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
export function parseGlm52Config(
|
|
136
|
+
modelDir: string,
|
|
137
|
+
raw: Record<string, any>,
|
|
138
|
+
generation: Record<string, any> | null = null,
|
|
139
|
+
): Glm52Config {
|
|
140
|
+
if (raw.model_type !== "glm_moe_dsa")
|
|
141
|
+
throw new Error(`expected model_type "glm_moe_dsa" (got ${String(raw.model_type)})`);
|
|
142
|
+
|
|
143
|
+
const hiddenSize = integer(raw, "hidden_size", { min: 1, max: 1 << 20 });
|
|
144
|
+
const numHiddenLayers = integer(raw, "num_hidden_layers", { min: 1, max: 128 });
|
|
145
|
+
const numAttentionHeads = integer(raw, "num_attention_heads", { min: 1, max: 1024 });
|
|
146
|
+
const numKeyValueHeads = integer(raw, "num_key_value_heads", {
|
|
147
|
+
min: 1,
|
|
148
|
+
max: 1024,
|
|
149
|
+
fallback: numAttentionHeads,
|
|
150
|
+
});
|
|
151
|
+
const qLoraRank = integer(raw, "q_lora_rank", { min: 1, max: 1 << 20 });
|
|
152
|
+
const kvLoraRank = integer(raw, "kv_lora_rank", { min: 1, max: 1 << 20 });
|
|
153
|
+
const qkNopeHeadDim = integer(raw, "qk_nope_head_dim", { min: 1, max: 1 << 16 });
|
|
154
|
+
const qkRopeHeadDim = integer(raw, "qk_rope_head_dim", { min: 1, max: 1 << 16 });
|
|
155
|
+
const qkHeadDim = integer(raw, "qk_head_dim", {
|
|
156
|
+
min: 1,
|
|
157
|
+
max: 1 << 16,
|
|
158
|
+
fallback: qkNopeHeadDim + qkRopeHeadDim,
|
|
159
|
+
});
|
|
160
|
+
if (qkHeadDim !== qkNopeHeadDim + qkRopeHeadDim)
|
|
161
|
+
throw new Error(
|
|
162
|
+
`GLM-5.2 config: qk_head_dim=${qkHeadDim} != qk_nope_head_dim + ` +
|
|
163
|
+
`qk_rope_head_dim (${qkNopeHeadDim + qkRopeHeadDim})`,
|
|
164
|
+
);
|
|
165
|
+
|
|
166
|
+
const numRoutedExperts = integer(raw, "n_routed_experts", { min: 1, max: 4096 });
|
|
167
|
+
const numExpertsPerToken = integer(raw, "num_experts_per_tok", {
|
|
168
|
+
min: 1,
|
|
169
|
+
max: numRoutedExperts,
|
|
170
|
+
});
|
|
171
|
+
const nGroup = integer(raw, "n_group", { min: 1 });
|
|
172
|
+
const topkGroup = integer(raw, "topk_group", { min: 1 });
|
|
173
|
+
// The pinned GLM engine implements the n_group=1 noaux_tc router exactly.
|
|
174
|
+
// Refuse a future grouped-router architecture instead of silently selecting
|
|
175
|
+
// from the wrong candidate set.
|
|
176
|
+
if (nGroup !== 1 || topkGroup !== 1)
|
|
177
|
+
throw new Error(`GLM-5.2 config: only n_group=1/topk_group=1 is supported`);
|
|
178
|
+
|
|
179
|
+
const indexTopk = integer(raw, "index_topk", { min: 0, max: 1 << 20, fallback: 0 });
|
|
180
|
+
const indexNumHeads = integer(raw, "index_n_heads", { min: 0, max: 1024, fallback: 0 });
|
|
181
|
+
const indexHeadDim = integer(raw, "index_head_dim", { min: 0, max: 1 << 16, fallback: 0 });
|
|
182
|
+
if ((indexTopk === 0) !== (indexNumHeads === 0 || indexHeadDim === 0))
|
|
183
|
+
throw new Error(
|
|
184
|
+
`GLM-5.2 config: incomplete DSA geometry ` +
|
|
185
|
+
`(topk=${indexTopk}, heads=${indexNumHeads}, head_dim=${indexHeadDim})`,
|
|
186
|
+
);
|
|
187
|
+
|
|
188
|
+
const eosTokenIds = unionTokenIds(
|
|
189
|
+
tokenIds(raw.eos_token_id, "config.json:eos_token_id"),
|
|
190
|
+
tokenIds(generation?.eos_token_id, "generation_config.json:eos_token_id"),
|
|
191
|
+
);
|
|
192
|
+
if (eosTokenIds.length === 0)
|
|
193
|
+
throw new Error("GLM-5.2 config: no EOS token ids in config or generation config");
|
|
194
|
+
|
|
195
|
+
return {
|
|
196
|
+
modelDir,
|
|
197
|
+
modelType: "glm_moe_dsa",
|
|
198
|
+
architectures: Array.isArray(raw.architectures)
|
|
199
|
+
? raw.architectures.map((entry: unknown) => String(entry))
|
|
200
|
+
: [],
|
|
201
|
+
hiddenSize,
|
|
202
|
+
numHiddenLayers,
|
|
203
|
+
numAttentionHeads,
|
|
204
|
+
numKeyValueHeads,
|
|
205
|
+
qLoraRank,
|
|
206
|
+
kvLoraRank,
|
|
207
|
+
qkNopeHeadDim,
|
|
208
|
+
qkRopeHeadDim,
|
|
209
|
+
qkHeadDim,
|
|
210
|
+
vHeadDim: integer(raw, "v_head_dim", { min: 1, max: 1 << 16 }),
|
|
211
|
+
firstKDenseReplace: integer(raw, "first_k_dense_replace", {
|
|
212
|
+
min: 0,
|
|
213
|
+
max: numHiddenLayers,
|
|
214
|
+
}),
|
|
215
|
+
intermediateSize: integer(raw, "intermediate_size", { min: 1, max: 1 << 24 }),
|
|
216
|
+
moeIntermediateSize: integer(raw, "moe_intermediate_size", { min: 1, max: 1 << 20 }),
|
|
217
|
+
numRoutedExperts,
|
|
218
|
+
numExpertsPerToken,
|
|
219
|
+
numSharedExperts: integer(raw, "n_shared_experts", { min: 0, max: 64, fallback: 0 }),
|
|
220
|
+
nGroup,
|
|
221
|
+
topkGroup,
|
|
222
|
+
normTopkProb: boolean(raw, "norm_topk_prob", false),
|
|
223
|
+
routedScalingFactor: finite(raw, "routed_scaling_factor", { min: 0, fallback: 1 }),
|
|
224
|
+
rmsNormEps: finite(raw, "rms_norm_eps", { min: 0, fallback: 1e-5 }),
|
|
225
|
+
ropeTheta: finite(raw.rope_parameters ?? raw, "rope_theta", {
|
|
226
|
+
min: Number.MIN_VALUE,
|
|
227
|
+
fallback: 10000,
|
|
228
|
+
}),
|
|
229
|
+
ropeInterleave: boolean(raw, "rope_interleave", true),
|
|
230
|
+
vocabSize: integer(raw, "vocab_size", { min: 1, max: 1 << 24 }),
|
|
231
|
+
maxPositionEmbeddings: integer(raw, "max_position_embeddings", {
|
|
232
|
+
min: 1,
|
|
233
|
+
max: 1 << 30,
|
|
234
|
+
}),
|
|
235
|
+
indexTopk,
|
|
236
|
+
indexNumHeads,
|
|
237
|
+
indexHeadDim,
|
|
238
|
+
indexerRopeInterleave: boolean(raw, "indexer_rope_interleave", true),
|
|
239
|
+
indexerTypes: indexerSchedule(raw, numHiddenLayers),
|
|
240
|
+
numNextnPredictLayers: integer(raw, "num_nextn_predict_layers", {
|
|
241
|
+
min: 0,
|
|
242
|
+
max: 8,
|
|
243
|
+
fallback: 0,
|
|
244
|
+
}),
|
|
245
|
+
indexShareForMtpIteration: boolean(raw, "index_share_for_mtp_iteration", false),
|
|
246
|
+
eosTokenIds,
|
|
247
|
+
padTokenId: integer(raw, "pad_token_id", { min: 0, fallback: eosTokenIds[0] }),
|
|
248
|
+
raw,
|
|
249
|
+
};
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
export async function loadGlm52Config(modelDir: string): Promise<Glm52Config> {
|
|
253
|
+
const configFile = Bun.file(`${modelDir}/config.json`);
|
|
254
|
+
if (!(await configFile.exists()))
|
|
255
|
+
throw new Error(`${modelDir}: missing config.json`);
|
|
256
|
+
const raw = (await configFile.json()) as Record<string, any>;
|
|
257
|
+
const generationFile = Bun.file(`${modelDir}/generation_config.json`);
|
|
258
|
+
const generation = await generationFile.exists()
|
|
259
|
+
? await generationFile.json() as Record<string, any>
|
|
260
|
+
: null;
|
|
261
|
+
return parseGlm52Config(modelDir, raw, generation);
|
|
262
|
+
}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { createHash, randomUUID } from "node:crypto";
|
|
2
|
+
import { mkdir, readdir, readFile, realpath, rename, rm, stat, writeFile } from "node:fs/promises";
|
|
3
|
+
import { homedir } from "node:os";
|
|
4
|
+
import { join, resolve } from "node:path";
|
|
5
|
+
import { runtimeValue } from "../runtime/config";
|
|
6
|
+
|
|
7
|
+
/** Identity calculation owns bytes; this interface owns memo persistence. */
|
|
8
|
+
export interface ArtifactIdentityStore {
|
|
9
|
+
get(key: string): Promise<string | undefined>;
|
|
10
|
+
put(key: string, digest: string): void;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export class FileArtifactIdentityStore implements ArtifactIdentityStore {
|
|
14
|
+
readonly #memory = new Map<string, string>();
|
|
15
|
+
readonly #pending = new Set<Promise<void>>();
|
|
16
|
+
constructor(readonly directory: string) {}
|
|
17
|
+
|
|
18
|
+
async get(key: string): Promise<string | undefined> {
|
|
19
|
+
const memory = this.#memory.get(key);
|
|
20
|
+
if (memory) return memory;
|
|
21
|
+
try {
|
|
22
|
+
const digest = await readFile(join(this.directory, key), "utf8");
|
|
23
|
+
if (!/^[0-9a-f]{64}$/.test(digest)) return undefined;
|
|
24
|
+
this.#memory.set(key, digest);
|
|
25
|
+
return digest;
|
|
26
|
+
} catch { return undefined; }
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
put(key: string, digest: string): void {
|
|
30
|
+
this.#memory.set(key, digest);
|
|
31
|
+
const temporary = join(this.directory, `${key}.${process.pid}.${randomUUID()}.tmp`);
|
|
32
|
+
const write = async () => {
|
|
33
|
+
try {
|
|
34
|
+
await mkdir(this.directory, { recursive: true });
|
|
35
|
+
await writeFile(temporary, digest);
|
|
36
|
+
await rename(temporary, join(this.directory, key));
|
|
37
|
+
} catch { await rm(temporary, { force: true }).catch(() => {}); }
|
|
38
|
+
};
|
|
39
|
+
const pending = write().finally(() => this.#pending.delete(pending));
|
|
40
|
+
this.#pending.add(pending);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
async flush(): Promise<void> { await Promise.all(this.#pending); }
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
let defaultStore: FileArtifactIdentityStore | undefined;
|
|
47
|
+
/** The memo directory under the mlx-bun storage root (MLX_BUN_HOME, default
|
|
48
|
+
* ~/.mlx-bun), read at call time so an isolated environment gets its own. */
|
|
49
|
+
function defaultIdentityStore(): FileArtifactIdentityStore {
|
|
50
|
+
const configured = runtimeValue("MLX_BUN_HOME");
|
|
51
|
+
const root = configured ? resolve(configured) : join(process.env.HOME || homedir(), ".mlx-bun");
|
|
52
|
+
const directory = join(root, "cache", "artifact-identities");
|
|
53
|
+
if (defaultStore?.directory !== directory) defaultStore = new FileArtifactIdentityStore(directory);
|
|
54
|
+
return defaultStore;
|
|
55
|
+
}
|
|
56
|
+
export interface ArtifactIdentityFile { name: string; path: string; }
|
|
57
|
+
|
|
58
|
+
async function revision(files: readonly ArtifactIdentityFile[]): Promise<string> {
|
|
59
|
+
return JSON.stringify(await Promise.all(files.map(async file => {
|
|
60
|
+
const path = await realpath(file.path), info = await stat(path, { bigint: true });
|
|
61
|
+
return [file.name, path, info.dev, info.ino, info.size, info.mtimeNs, info.ctimeNs].map(String);
|
|
62
|
+
})));
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/** Preserve the existing seed/name/byte digest, reusing it while file revisions
|
|
66
|
+
* are unchanged. ctime catches same-size edits even when mtime is restored.
|
|
67
|
+
* A memo miss computes the full identity; persistence never delays its caller. */
|
|
68
|
+
export async function artifactIdentity(seed: string, input: readonly ArtifactIdentityFile[],
|
|
69
|
+
store: ArtifactIdentityStore = defaultIdentityStore()): Promise<string> {
|
|
70
|
+
const files = [...input].sort((a, b) => a.name < b.name ? -1 : a.name > b.name ? 1 : 0);
|
|
71
|
+
const before = await revision(files);
|
|
72
|
+
const key = createHash("sha256").update(JSON.stringify([seed, before])).digest("hex");
|
|
73
|
+
const cached = await store.get(key);
|
|
74
|
+
if (cached) return cached;
|
|
75
|
+
const digest = createHash("sha256").update(seed);
|
|
76
|
+
for (const file of files) {
|
|
77
|
+
digest.update(file.name);
|
|
78
|
+
for await (const chunk of Bun.file(file.path).stream()) digest.update(chunk);
|
|
79
|
+
}
|
|
80
|
+
const value = digest.digest("hex");
|
|
81
|
+
if (before === await revision(files)) store.put(key, value);
|
|
82
|
+
return value;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/** Content identity of a model directory's weights: config.json plus every
|
|
86
|
+
* safetensors shard (and the shard index), so quantization, fine-tunes and
|
|
87
|
+
* revised weights each get their own digest under one repo id. Memoized by
|
|
88
|
+
* file revision like every artifactIdentity. */
|
|
89
|
+
export async function modelWeightsIdentity(modelDir: string, seed: string,
|
|
90
|
+
store?: ArtifactIdentityStore): Promise<string> {
|
|
91
|
+
const names = (await readdir(modelDir)).filter(name =>
|
|
92
|
+
name === "config.json" || name === "model.safetensors.index.json" || name.endsWith(".safetensors"));
|
|
93
|
+
return artifactIdentity(seed, names.map(name => ({ name, path: join(modelDir, name) })), store);
|
|
94
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export * from "./config";
|
|
2
|
+
export * from "./glm52-config";
|
|
3
|
+
export * from "./weights";
|
|
4
|
+
export * from "./safetensors";
|
|
5
|
+
export { MmapFile } from "./mmap";
|
|
6
|
+
export * from "./expert-offload";
|
|
7
|
+
export * from "./expert-offload-build";
|
|
8
|
+
export * from "./fingerprint";
|
|
9
|
+
export * from "./identity";
|
|
10
|
+
export * from "./weight-audit";
|
|
11
|
+
export * from "./safetensors-writer";
|
|
12
|
+
export * from "./auxiliary-files";
|
|
13
|
+
export * from "./turboquant-fold";
|
|
14
|
+
|
|
15
|
+
export * from "./draft-vocabulary";
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
// libc mmap via bun:ffi.
|
|
2
|
+
//
|
|
3
|
+
// Bun.mmap panics (SIGTRAP, Bun 1.3.3) on files larger than 4 GB because
|
|
4
|
+
// JSC ArrayBuffers cap at 2^32 bytes — and weight shards routinely exceed
|
|
5
|
+
// that. We don't need a whole-file ArrayBuffer anyway: tensors go to mlx
|
|
6
|
+
// as raw pointers (base + offset), and only small ranges (headers) are
|
|
7
|
+
// ever viewed from JS.
|
|
8
|
+
|
|
9
|
+
import { dlopen, FFIType, toArrayBuffer } from "bun:ffi";
|
|
10
|
+
import { closeSync, fstatSync, openSync } from "node:fs";
|
|
11
|
+
|
|
12
|
+
const libc = dlopen("/usr/lib/libSystem.B.dylib", {
|
|
13
|
+
mmap: {
|
|
14
|
+
args: [FFIType.u64, FFIType.u64, FFIType.i32, FFIType.i32, FFIType.i32, FFIType.i64],
|
|
15
|
+
returns: FFIType.u64,
|
|
16
|
+
},
|
|
17
|
+
munmap: { args: [FFIType.u64, FFIType.u64], returns: FFIType.i32 },
|
|
18
|
+
madvise: { args: [FFIType.u64, FFIType.u64, FFIType.i32], returns: FFIType.i32 },
|
|
19
|
+
}).symbols;
|
|
20
|
+
|
|
21
|
+
const PROT_READ = 0x1;
|
|
22
|
+
const PROT_WRITE = 0x2;
|
|
23
|
+
const MAP_SHARED = 0x1;
|
|
24
|
+
const MAP_PRIVATE = 0x2;
|
|
25
|
+
const MAP_FAILED = 0xffffffffffffffffn;
|
|
26
|
+
|
|
27
|
+
// madvise advice (macOS <sys/mman.h>). DONTNEED drops clean file-backed
|
|
28
|
+
// pages (they re-fault from the file); FREE_REUSABLE is the Apple-specific
|
|
29
|
+
// lazy-reclaim variant.
|
|
30
|
+
export const MADV_DONTNEED = 4;
|
|
31
|
+
export const MADV_FREE = 5;
|
|
32
|
+
export const MADV_FREE_REUSABLE = 7;
|
|
33
|
+
|
|
34
|
+
export class MmapFile {
|
|
35
|
+
readonly path: string;
|
|
36
|
+
readonly base: bigint;
|
|
37
|
+
readonly size: number;
|
|
38
|
+
#mapped = true;
|
|
39
|
+
|
|
40
|
+
private constructor(path: string, base: bigint, size: number) {
|
|
41
|
+
this.path = path;
|
|
42
|
+
this.base = base;
|
|
43
|
+
this.size = size;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/** Open read-only (MAP_SHARED) or copy-on-write (MAP_PRIVATE +
|
|
47
|
+
* PROT_WRITE — writes go to private pages, never the file; used for
|
|
48
|
+
* KV-cache reloads where mlx may donate buffers). */
|
|
49
|
+
static open(path: string, mode: "ro" | "cow" = "ro"): MmapFile {
|
|
50
|
+
const fd = openSync(path, "r");
|
|
51
|
+
try {
|
|
52
|
+
const size = fstatSync(fd).size;
|
|
53
|
+
if (size === 0) throw new Error(`${path}: empty file`);
|
|
54
|
+
const prot = mode === "cow" ? PROT_READ | PROT_WRITE : PROT_READ;
|
|
55
|
+
const flags = mode === "cow" ? MAP_PRIVATE : MAP_SHARED;
|
|
56
|
+
const base = libc.mmap(0n, BigInt(size), prot, flags, fd, 0n);
|
|
57
|
+
if (base === MAP_FAILED) throw new Error(`${path}: mmap failed`);
|
|
58
|
+
return new MmapFile(path, base, size);
|
|
59
|
+
} finally {
|
|
60
|
+
closeSync(fd); // mapping survives close
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/** Raw pointer to byte `offset` (for FFI consumers like mlx). */
|
|
65
|
+
pointer(offset: number): number {
|
|
66
|
+
if (offset < 0 || offset > this.size) throw new RangeError(`offset ${offset} out of range`);
|
|
67
|
+
return Number(this.base + BigInt(offset));
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/** JS view of a range. Only for small ranges (headers, spot checks);
|
|
71
|
+
* the view aliases the mapping — do not retain past munmap. */
|
|
72
|
+
view(offset: number, length: number): Uint8Array {
|
|
73
|
+
if (offset + length > this.size) throw new RangeError("view out of range");
|
|
74
|
+
if (length >= 2 ** 32) throw new RangeError("JS views cap at 4 GB");
|
|
75
|
+
return new Uint8Array(toArrayBuffer(this.pointer(offset) as never, 0, length));
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/** madvise a page-aligned sub-range (offset + length should be page
|
|
79
|
+
* multiples). e.g. advise(off, len, MADV_DONTNEED) to release clean
|
|
80
|
+
* expert pages back to the OS; they re-fault from the file on next read. */
|
|
81
|
+
advise(offset: number, length: number, advice: number): number {
|
|
82
|
+
return Number(libc.madvise(this.base + BigInt(offset), BigInt(length), advice));
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
unmap(): void {
|
|
86
|
+
if (!this.#mapped) return;
|
|
87
|
+
this.#mapped = false;
|
|
88
|
+
libc.munmap(this.base, BigInt(this.size));
|
|
89
|
+
}
|
|
90
|
+
}
|