mlx-bun 0.5.0 → 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/README.md +1449 -109
- package/THIRD_PARTY_NOTICES.md +882 -0
- package/bin/mlx-bun.convert.mjs +4 -0
- package/bin/mlx-bun.fuse.mjs +4 -0
- package/bin/mlx-bun.generate.mjs +4 -0
- package/bin/mlx-bun.lora.mjs +4 -0
- package/bin/mlx-bun.mjs +13 -21
- package/bin/mlx-bun.server.mjs +4 -0
- package/bin/mlx-bun.upload.mjs +4 -0
- package/dist/web/app.js +9584 -0
- package/package.json +50 -53
- package/src/cli/ane-install.ts +76 -0
- package/src/cli/args.ts +179 -0
- package/src/cli/engine-entry.ts +68 -0
- package/src/cli/inference.ts +214 -0
- package/src/cli/job-entry.ts +97 -0
- package/src/cli/library-host.ts +117 -0
- package/src/cli/main.ts +57 -0
- package/src/cli/memory-engine.ts +163 -0
- package/src/cli/memory.ts +36 -0
- package/src/cli/mlx-lm-aliases.ts +309 -0
- package/src/cli/model-choice.ts +33 -0
- package/src/cli/model-selection.ts +84 -0
- package/src/cli/module-host.ts +11 -0
- package/src/cli/module-verbs.ts +50 -0
- package/src/cli/numerical-policy.ts +12 -0
- package/src/cli/perplexity.ts +89 -0
- package/src/cli/serve-host.ts +423 -0
- package/src/cli/serve-isolated.ts +217 -0
- package/src/cli/serve-options.ts +106 -0
- package/src/cli/serve-state.ts +205 -0
- package/src/cli/serve.ts +500 -0
- package/src/cli/served-model-host.ts +102 -0
- package/src/cli/server-entry.ts +148 -0
- package/src/cli/serving-unit.ts +177 -0
- package/src/{tui.ts → cli/terminal.ts} +13 -8
- package/src/cli/worker-adapters.ts +34 -0
- package/src/cli/worker-entry.ts +272 -0
- package/src/cli/worker-unit.ts +179 -0
- package/src/engine/adapter-operation.ts +26 -0
- package/src/engine/cache-services.ts +114 -0
- package/src/engine/completion.ts +39 -0
- package/src/engine/generation-gateway.ts +358 -0
- package/src/engine/index.ts +59 -0
- package/src/engine/kv-budget.ts +120 -0
- package/src/engine/media-preparation.ts +232 -0
- package/src/engine/model-binding.ts +24 -0
- package/src/engine/model-host.ts +513 -0
- package/src/engine/model-serving.ts +89 -0
- package/src/{serve → engine}/preparation.ts +7 -5
- package/src/{serve → engine}/session-completion-engine.ts +6 -6
- package/src/engine/telemetry.ts +109 -0
- package/src/hub/downloads.ts +116 -0
- package/src/jobs/db.ts +16 -7
- package/src/jobs/events.ts +29 -0
- package/src/jobs/executable.ts +5 -0
- package/src/jobs/host.ts +51 -0
- package/src/jobs/in-process.ts +55 -0
- package/src/{contracts/jobs.ts → jobs/protocol.ts} +7 -9
- package/src/jobs/runner.ts +150 -231
- package/src/jobs/service.ts +75 -0
- package/src/jobs/sse.ts +59 -23
- package/src/jobs/worker-memory.ts +46 -0
- package/src/jobs/worker-process.ts +163 -0
- package/src/jobs/worker-supervisor.ts +258 -0
- package/src/modules.ts +58 -0
- package/src/publishing/catalog-hub.ts +18 -0
- package/src/publishing/credentials.ts +31 -0
- package/src/publishing/upload.ts +37 -0
- package/src/residency/leased-adapters.ts +21 -0
- package/src/residency/local-records.ts +16 -0
- package/src/residency/model-residency.ts +405 -0
- package/src/residency/record-index.ts +28 -0
- package/src/residency/resident-estimate.ts +50 -0
- package/src/{anthropic.ts → server/anthropic.ts} +3 -81
- package/src/server/cache-routes.ts +36 -0
- package/src/{serve → server}/chat-request.ts +10 -10
- package/src/{serve → server}/chat-stage.ts +14 -14
- package/src/{client.ts → server/client.ts} +28 -2
- package/src/{serve → server}/completion-executor.ts +33 -41
- package/src/server/decision-body.ts +55 -0
- package/src/server/decision-routes.ts +134 -0
- package/src/server/decision-wire.ts +228 -0
- package/src/{serve → server}/discovery-routes.ts +25 -82
- package/src/{serve → server}/http.ts +25 -13
- package/src/{serve → server}/inference-request.ts +5 -5
- package/src/server/job-routes.ts +20 -0
- package/src/server/media-prompt.ts +63 -0
- package/src/server/memory-completion-client.ts +46 -0
- package/src/server/model-routes.ts +192 -0
- package/src/{serve → server}/openai-wire.ts +3 -2
- package/src/{serve → server}/pipeline.ts +1 -1
- package/src/server/prompt-builder.ts +13 -0
- package/src/server/prompt-contracts.ts +17 -0
- package/src/server/proxy-routes.ts +187 -0
- package/src/server/publishing-routes.ts +41 -0
- package/src/{serve → server}/request-plan.ts +6 -8
- package/src/{serve → server}/request-prep.ts +47 -50
- package/src/{serve → server}/responses-client.ts +30 -13
- package/src/{responses.ts → server/responses.ts} +12 -93
- package/src/server/routes.ts +205 -0
- package/src/server/start.ts +72 -0
- package/src/server/status-routes.ts +108 -0
- package/src/{serve → server}/text-completion-stage.ts +25 -4
- package/src/server/text-prompt.ts +12 -0
- package/src/{serve → server}/token-streams.ts +36 -38
- package/src/server/worker-routes.ts +311 -0
- package/src/storage/paths.ts +61 -0
- package/src/web/assets.ts +37 -0
- package/src/web/{src → browser}/api.ts +5 -23
- package/src/web/browser/chat-host.ts +17 -0
- package/src/web/browser/installed-panels.ts +6 -0
- package/src/web/browser/main.ts +55 -0
- package/src/web/browser/markdown.ts +279 -0
- package/src/web/browser/memory-panel.ts +9 -0
- package/src/web/browser/palette.ts +64 -0
- package/src/web/browser/protocol.ts +13 -0
- package/src/web/browser/shell.ts +467 -0
- package/src/web/{src → browser}/status.ts +32 -36
- package/src/web/build.ts +51 -0
- package/src/web/public/app.html +1054 -0
- package/src/web/{sw.js → public/sw.js} +4 -3
- package/src/web/{vendor → public/vendor}/hljs-theme.css +2 -2
- package/src/web/{vendor → public/vendor}/hljs.js +2 -2
- package/THIRD_PARTY_LICENSES.md +0 -51
- package/docs/README.md +0 -107
- package/docs/archive/hlg-sampling.md +0 -350
- package/docs/archive/investigations/audio-input-plan.md +0 -356
- package/docs/archive/investigations/benchmark-ledger-through-v0.4.0.md +0 -3617
- package/docs/archive/investigations/chunk-finetune-experiment.md +0 -84
- package/docs/archive/investigations/colibri-glm52-port.md +0 -1486
- package/docs/archive/investigations/colibri-oracle-pin.md +0 -1284
- package/docs/archive/investigations/curve-bisector-routing.md +0 -123
- package/docs/archive/investigations/decode-roofline-lookagain.md +0 -348
- package/docs/archive/investigations/diffusion-gemma-port.md +0 -602
- package/docs/archive/investigations/dspark-handoff.md +0 -224
- package/docs/archive/investigations/expert-offload-single-user-moe.md +0 -292
- package/docs/archive/investigations/faithful-l1-consolidation.md +0 -310
- package/docs/archive/investigations/hlg-sampling-investigation.md +0 -970
- package/docs/archive/investigations/indexshare-performance-spike.md +0 -357
- package/docs/archive/investigations/kernel-perf-review-2026-07.md +0 -171
- package/docs/archive/investigations/lab-build-journal.md +0 -157
- package/docs/archive/investigations/minicpm5-decode-megakernel.md +0 -489
- package/docs/archive/investigations/openjarvis-fit.md +0 -198
- package/docs/archive/investigations/openwiki-evaluation.md +0 -249
- package/docs/archive/investigations/optimization_plan.md +0 -346
- package/docs/archive/investigations/orpo-base-uf-experiment-and-directions.md +0 -120
- package/docs/archive/investigations/orpo-flash-cce-pin-leak.md +0 -167
- package/docs/archive/investigations/orpo-uf-testing-handoff.md +0 -126
- package/docs/archive/investigations/pareto-specialized-runtime-findings.md +0 -92
- package/docs/archive/investigations/pi-builtin-investigation.md +0 -308
- package/docs/archive/investigations/pre-colibri-stabilization.md +0 -329
- package/docs/archive/investigations/qwen38-27b-campaign-log.md +0 -1092
- package/docs/archive/investigations/segmented-backward-handoff.md +0 -148
- package/docs/archive/investigations/starter-model-port-handoff.md +0 -342
- package/docs/archive/investigations/steel-flash-cce-handoff.md +0 -489
- package/docs/archive/investigations/the-dreaming-handoff.md +0 -141
- package/docs/archive/investigations/trainer-validation-experiment.md +0 -173
- package/docs/archive/planning/chat-ui-vision-memory-first.md +0 -199
- package/docs/archive/planning/chat-ui-vision.md +0 -50
- package/docs/archive/planning/chunk-task-roadmap.md +0 -77
- package/docs/archive/planning/curve-sampler-research-plan.md +0 -331
- package/docs/archive/planning/journal.md +0 -316
- package/docs/archive/planning/memory-docs-and-dag-plan.md +0 -194
- package/docs/archive/planning/pi-integration-review.md +0 -178
- package/docs/archive/planning/release-notes-v0.0.10.md +0 -57
- package/docs/archive/planning/release-notes-v0.0.11.md +0 -239
- package/docs/archive/planning/release-notes-v0.0.12.md +0 -80
- package/docs/archive/planning/release-notes-v0.0.13.md +0 -77
- package/docs/archive/planning/release-notes-v0.0.9.md +0 -122
- package/docs/archive/planning/release-notes-v0.2.0.md +0 -49
- package/docs/archive/planning/release-notes-v0.3.0.md +0 -35
- package/docs/archive/planning/release-notes-v0.4.0.md +0 -45
- package/docs/archive/planning/release-notes-v0.5.0.md +0 -37
- package/docs/archive/planning/web-ui-pass-plan.md +0 -213
- package/docs/archive/planning/website-readme-pass-plan.md +0 -224
- package/docs/design/batching.md +0 -2054
- package/docs/design/decode-speed-program.md +0 -2404
- package/docs/design/dreaming-nightly-pipeline.md +0 -684
- package/docs/design/generic-model-support.md +0 -821
- package/docs/design/kv-cache.md +0 -993
- package/docs/design/orpo-training.md +0 -680
- package/docs/design/speculative-decoding.md +0 -2129
- package/docs/design/turboquant.md +0 -2225
- package/docs/design/unified-engine-frontier-plan.md +0 -1987
- package/docs/design/web-chat-redesign.md +0 -695
- package/docs/planning/PRODUCT_ROADMAP.md +0 -593
- package/docs/planning/ResearchTopics.md +0 -119
- package/docs/planning/public-readiness-handoff.md +0 -244
- package/docs/planning/public-readiness.md +0 -149
- package/docs/planning/video-series.md +0 -421
- package/docs/reference/benchmarks.md +0 -3587
- package/docs/reference/cli.md +0 -646
- package/docs/reference/distribution.md +0 -380
- package/docs/reference/environment.md +0 -494
- package/docs/reference/glossary.md +0 -39
- package/docs/reference/library-api.md +0 -688
- package/docs/reference/memory.md +0 -260
- package/docs/reference/models.md +0 -346
- package/docs/reference/server-api.md +0 -1945
- package/docs/reference/server-config.md +0 -973
- package/docs/reference/training.md +0 -462
- package/docs/reference/troubleshooting.md +0 -158
- package/src/admission-plan.ts +0 -18
- package/src/audio/audiotoolbox.ts +0 -112
- package/src/audio/conformer.ts +0 -655
- package/src/audio/decode.ts +0 -133
- package/src/audio/features.ts +0 -202
- package/src/audio/mic-capture.ts +0 -98
- package/src/audio/silero-vad.ts +0 -379
- package/src/audio/transcode.ts +0 -67
- package/src/audio/whisper-decode.ts +0 -774
- package/src/audio/whisper-fast.ts +0 -732
- package/src/audio/whisper-format.ts +0 -73
- package/src/audio/whisper-mel.ts +0 -185
- package/src/audio/whisper-timing.ts +0 -274
- package/src/audio/whisper-tokenizer.ts +0 -239
- package/src/audio/whisper-transcribe.ts +0 -410
- package/src/backends/mlx/assistant-target.ts +0 -46
- package/src/backends/mlx/autoregressive-draft-rows.ts +0 -120
- package/src/backends/mlx/autoregressive.ts +0 -129
- package/src/backends/mlx/batch-group.ts +0 -1874
- package/src/backends/mlx/cache-attachment.ts +0 -67
- package/src/backends/mlx/cache-layout.ts +0 -31
- package/src/backends/mlx/checkpoint-state.ts +0 -53
- package/src/backends/mlx/continuation-persistence.ts +0 -107
- package/src/backends/mlx/continuation-request.ts +0 -43
- package/src/backends/mlx/continuation.ts +0 -77
- package/src/backends/mlx/diffusion.ts +0 -39
- package/src/backends/mlx/draft-target.ts +0 -32
- package/src/backends/mlx/encoder-cache.ts +0 -25
- package/src/backends/mlx/evaluation.ts +0 -105
- package/src/backends/mlx/fill-append.ts +0 -58
- package/src/backends/mlx/fill-group.ts +0 -497
- package/src/backends/mlx/full-kv-row-append.ts +0 -32
- package/src/backends/mlx/full-kv-row-donor.ts +0 -54
- package/src/backends/mlx/full-transitioning-kv-rows.ts +0 -65
- package/src/backends/mlx/gateway-binding.ts +0 -174
- package/src/backends/mlx/graph.ts +0 -38
- package/src/backends/mlx/kv-codec.ts +0 -9
- package/src/backends/mlx/kv-maintenance.ts +0 -161
- package/src/backends/mlx/kv-tensor-rows.ts +0 -212
- package/src/backends/mlx/memory-client.ts +0 -189
- package/src/backends/mlx/methods.ts +0 -90
- package/src/backends/mlx/mixed-iteration.ts +0 -62
- package/src/backends/mlx/model-prompt.ts +0 -178
- package/src/backends/mlx/model-serving.ts +0 -80
- package/src/backends/mlx/paged-cache-codec.ts +0 -27
- package/src/backends/mlx/prefill-cohort.ts +0 -100
- package/src/backends/mlx/prefill-policy.ts +0 -26
- package/src/backends/mlx/prefill-rows.ts +0 -244
- package/src/backends/mlx/prefill.ts +0 -33
- package/src/backends/mlx/projected-context-rows.ts +0 -72
- package/src/backends/mlx/prompt-input.ts +0 -29
- package/src/backends/mlx/qwen-prompt-input.ts +0 -40
- package/src/backends/mlx/request-policy.ts +0 -20
- package/src/backends/mlx/request-state-policy.ts +0 -54
- package/src/backends/mlx/rollback.ts +0 -92
- package/src/backends/mlx/row-sampling.ts +0 -49
- package/src/backends/mlx/serial-executor.ts +0 -251
- package/src/backends/mlx/speculative-group.ts +0 -438
- package/src/backends/mlx/speculative-round.ts +0 -161
- package/src/backends/mlx/speculative.ts +0 -131
- package/src/backends/mlx/state-rows.ts +0 -104
- package/src/backends/mlx/state-views.ts +0 -46
- package/src/backends/mlx/target-layout-capability.ts +0 -35
- package/src/backends/mlx/text-engine.ts +0 -73
- package/src/backends/mlx/transitioning-kv-rows.ts +0 -173
- package/src/chat-template.ts +0 -382
- package/src/cli.ts +0 -3490
- package/src/config.ts +0 -399
- package/src/contracts/completion.ts +0 -16
- package/src/contracts/execution.ts +0 -70
- package/src/contracts/generation.ts +0 -103
- package/src/contracts/host.ts +0 -7
- package/src/contracts/object-cache.ts +0 -8
- package/src/contracts/pi-provider.ts +0 -30
- package/src/contracts/pi.ts +0 -261
- package/src/contracts/prefix-cache.ts +0 -33
- package/src/contracts/resources.ts +0 -25
- package/src/contracts/sampling.ts +0 -23
- package/src/contracts/scheduling.ts +0 -54
- package/src/contracts/tsconfig.json +0 -14
- package/src/dataset/generators.ts +0 -1087
- package/src/dataset/index.ts +0 -12
- package/src/dataset/job.ts +0 -81
- package/src/dataset/llm.ts +0 -71
- package/src/dataset/registry.ts +0 -528
- package/src/diffusion/diffusion-generate.ts +0 -507
- package/src/download.ts +0 -505
- package/src/embed.ts +0 -77
- package/src/engine/admission.ts +0 -59
- package/src/engine/cancellation.ts +0 -38
- package/src/engine/engine.ts +0 -56
- package/src/engine/execution-coordinator.ts +0 -70
- package/src/engine/execution-plan.ts +0 -64
- package/src/engine/execution-tasks.ts +0 -44
- package/src/engine/namespaced-cache.ts +0 -13
- package/src/engine/resources.ts +0 -53
- package/src/engine/scheduler.ts +0 -92
- package/src/engine/session.ts +0 -247
- package/src/eval/README.md +0 -130
- package/src/eval/ifeval.ts +0 -81
- package/src/eval/kl-prompts.ts +0 -29
- package/src/eval/kl.ts +0 -590
- package/src/eval/perplexity.ts +0 -164
- package/src/eval/quality-db.ts +0 -92
- package/src/eval/reference-logits.ts +0 -207
- package/src/eval/runner.ts +0 -124
- package/src/eval/score.ts +0 -49
- package/src/eval/tasks/bfcl.ts +0 -535
- package/src/eval/tasks/gsm8k.ts +0 -98
- package/src/eval/tasks/hashhop.ts +0 -139
- package/src/eval/tasks/humaneval.ts +0 -275
- package/src/eval/tasks/ifeval.ts +0 -525
- package/src/eval/tasks/mmlu.ts +0 -157
- package/src/eval/ultrafeedback.ts +0 -60
- package/src/evaldb.ts +0 -199
- package/src/expert-io.ts +0 -393
- package/src/expert-offload-build.ts +0 -77
- package/src/expert-offload.ts +0 -76
- package/src/expert-residency.ts +0 -1134
- package/src/expert-usage.ts +0 -415
- package/src/fill/echo-index.ts +0 -188
- package/src/fill/fill-session.ts +0 -463
- package/src/fill/proposal.ts +0 -68
- package/src/fill/schema-rows.ts +0 -506
- package/src/fill/tool-boundary.ts +0 -103
- package/src/fit.ts +0 -249
- package/src/generate.ts +0 -1352
- package/src/grammar.ts +0 -604
- package/src/harness-pi.ts +0 -184
- package/src/hf-push.ts +0 -628
- package/src/hub-rest.ts +0 -242
- package/src/index.ts +0 -63
- package/src/inference/denoising.ts +0 -17
- package/src/inference/draft-acceptance.ts +0 -41
- package/src/inference/draft-output.ts +0 -49
- package/src/inference/graph.ts +0 -33
- package/src/inference/prefill.ts +0 -45
- package/src/inference/rollback.ts +0 -7
- package/src/jobs/index.ts +0 -31
- package/src/jobs/job-entry.ts +0 -107
- package/src/jobs/task-client.ts +0 -19
- package/src/jobs/types.ts +0 -2
- package/src/kv-scheme.ts +0 -279
- package/src/kv-store.ts +0 -1135
- package/src/lab/README.md +0 -22
- package/src/lab/curve/curve-designer.html +0 -303
- package/src/lab/curve/curve-sampler.ts +0 -122
- package/src/lab/expert-trace/expert-trace.ts +0 -69
- package/src/lab/paged-kv/paged-attention.ts +0 -117
- package/src/lab/paged-kv/paged-kv-rows.ts +0 -111
- package/src/lab/paged-kv/paged-kv.ts +0 -336
- package/src/library.ts +0 -40
- package/src/lora.ts +0 -408
- package/src/md-modules.d.ts +0 -54
- package/src/media-fetch.ts +0 -442
- package/src/memory/article.ts +0 -558
- package/src/memory/chunk-validation.ts +0 -150
- package/src/memory/chunk.ts +0 -318
- package/src/memory/cluster.ts +0 -351
- package/src/memory/coverage.ts +0 -134
- package/src/memory/crosslink.ts +0 -0
- package/src/memory/db.ts +0 -253
- package/src/memory/entity.ts +0 -203
- package/src/memory/gate.ts +0 -187
- package/src/memory/history.ts +0 -152
- package/src/memory/ingest.ts +0 -335
- package/src/memory/model.ts +0 -183
- package/src/memory/normalize.ts +0 -671
- package/src/memory/parse.ts +0 -22
- package/src/memory/pipeline.ts +0 -275
- package/src/memory/prompts.ts +0 -65
- package/src/memory/query.ts +0 -334
- package/src/memory/reconcile.ts +0 -734
- package/src/memory/redirect.ts +0 -108
- package/src/memory/reindex.ts +0 -325
- package/src/memory/resolve.ts +0 -307
- package/src/memory/rest.ts +0 -245
- package/src/memory/route.ts +0 -272
- package/src/memory/schedule.ts +0 -165
- package/src/memory/stages.ts +0 -777
- package/src/memory/synthesize.ts +0 -1638
- package/src/memory/tools.ts +0 -749
- package/src/memory/vault.ts +0 -1194
- package/src/memory/wikify.ts +0 -1064
- package/src/mlx/array.ts +0 -425
- package/src/mlx/autograd.ts +0 -304
- package/src/mlx/checkpoint.ts +0 -149
- package/src/mlx/compile.ts +0 -168
- package/src/mlx/custom-vjp.ts +0 -188
- package/src/mlx/ffi.ts +0 -531
- package/src/mlx/materialize.ts +0 -23
- package/src/mlx/metal-kernel.ts +0 -159
- package/src/mlx/normalized-argmax.ts +0 -116
- package/src/mlx/ops.ts +0 -1108
- package/src/mlx/quantized-rows.ts +0 -36
- package/src/mlx/token-bitmask.ts +0 -52
- package/src/mlx/turboquant-kv-decode.ts +0 -82
- package/src/mlx/turboquant-kv-inverse.ts +0 -122
- package/src/mlx/turboquant-ops.ts +0 -861
- package/src/mlx/turboquant-tables.ts +0 -237
- package/src/mmap.ts +0 -90
- package/src/model/artifact-identity.ts +0 -73
- package/src/model/batched-kv.ts +0 -235
- package/src/model/batched-mask.ts +0 -279
- package/src/model/batched-quant.ts +0 -212
- package/src/model/batched-quantized-kv.ts +0 -144
- package/src/model/batched-rotating-quant.ts +0 -353
- package/src/model/batched-rotating-state.ts +0 -149
- package/src/model/batched-rotating.ts +0 -338
- package/src/model/batched-row-storage.ts +0 -179
- package/src/model/batched-ssm.ts +0 -52
- package/src/model/batched-turboquant-kv.ts +0 -94
- package/src/model/compiled-decode.ts +0 -712
- package/src/model/decoded-kv-donor.ts +0 -12
- package/src/model/delayed-quantized-kv.ts +0 -72
- package/src/model/delayed-rotating-quantized-kv.ts +0 -93
- package/src/model/delayed-turboquant-kv.ts +0 -57
- package/src/model/diffusion-gemma.ts +0 -1026
- package/src/model/factory.ts +0 -215
- package/src/model/fingerprint.ts +0 -45
- package/src/model/flash-attention.ts +0 -694
- package/src/model/full-prefill-padding.ts +0 -56
- package/src/model/full-prefill-row.ts +0 -105
- package/src/model/gemma4-base.ts +0 -2370
- package/src/model/gemma4.ts +0 -1395
- package/src/model/generated/gemma4-12b.ts +0 -429
- package/src/model/generated/gemma4-26b.ts +0 -448
- package/src/model/generated/gemma4-e4b.ts +0 -717
- package/src/model/generated/index.ts +0 -18
- package/src/model/glm52-atlas.ts +0 -511
- package/src/model/glm52-cache.ts +0 -792
- package/src/model/glm52-config.ts +0 -262
- package/src/model/glm52-container.ts +0 -305
- package/src/model/glm52-coupling.ts +0 -388
- package/src/model/glm52-dsa.ts +0 -606
- package/src/model/glm52-expert-layout.ts +0 -253
- package/src/model/glm52-layout.ts +0 -152
- package/src/model/glm52-memory.ts +0 -500
- package/src/model/glm52-mla.ts +0 -792
- package/src/model/glm52-moe.ts +0 -223
- package/src/model/glm52-pilot.ts +0 -537
- package/src/model/glm52-reference.ts +0 -445
- package/src/model/glm52-residency.ts +0 -557
- package/src/model/glm52-resident-weights.ts +0 -135
- package/src/model/glm52-streamed-experts.ts +0 -453
- package/src/model/glm52-streamed-metal.ts +0 -610
- package/src/model/glm52-weights.ts +0 -503
- package/src/model/glm52.ts +0 -1132
- package/src/model/implementation.ts +0 -69
- package/src/model/kv-attention-view.ts +0 -70
- package/src/model/minicpm5.ts +0 -376
- package/src/model/profile.ts +0 -468
- package/src/model/quantized-append-attention.ts +0 -31
- package/src/model/qwen-append.ts +0 -12
- package/src/model/qwen-conv.ts +0 -52
- package/src/model/qwen3-delta-state.ts +0 -74
- package/src/model/qwen3-delta.ts +0 -451
- package/src/model/qwen3-moe.ts +0 -404
- package/src/model/qwen3-mrope.ts +0 -250
- package/src/model/qwen3.ts +0 -277
- package/src/model/qwen3_5-checkpoint.ts +0 -164
- package/src/model/qwen3_5.ts +0 -881
- package/src/model/rotating-kv-donor.ts +0 -35
- package/src/model/rotating-kv-layout.ts +0 -262
- package/src/model/rotating-row-transaction.ts +0 -35
- package/src/model/speculative-rotating-kv.ts +0 -101
- package/src/model/ssm-prefill-padding.ts +0 -39
- package/src/model/support.ts +0 -110
- package/src/model/token-groups.ts +0 -66
- package/src/model/trellis-balanced-scatter.ts +0 -51
- package/src/model/trellis-linear.ts +0 -672
- package/src/model/trellis-shared-m.ts +0 -151
- package/src/model/trellis-shared-scatter.ts +0 -144
- package/src/model/trellis-splitk-prefill.ts +0 -158
- package/src/model/trellis-tiled-prefill.ts +0 -136
- package/src/model/trellis-vector-expand.ts +0 -62
- package/src/model/trellis-wide-prefill.ts +0 -94
- package/src/model/turboquant-codec.ts +0 -89
- package/src/model/universal/archs.ts +0 -332
- package/src/model/universal/dense.ts +0 -612
- package/src/model/universal/modules.ts +0 -170
- package/src/model/universal/rope.ts +0 -381
- package/src/model/whisper.ts +0 -435
- package/src/native/expert_io.c +0 -523
- package/src/native/frame_extract.swift +0 -140
- package/src/native/mic_capture.swift +0 -92
- package/src/native-pack.ts +0 -163
- package/src/pi-provider.ts +0 -53
- package/src/pi-session.ts +0 -81
- package/src/pi-terminal.ts +0 -274
- package/src/pi-web.ts +0 -1940
- package/src/preflight.ts +0 -158
- package/src/prompt-cache.ts +0 -682
- package/src/quantize/allocator.ts +0 -627
- package/src/quantize/atomic-output.ts +0 -38
- package/src/quantize/calibration.ts +0 -181
- package/src/quantize/config-writer.ts +0 -145
- package/src/quantize/index.ts +0 -84
- package/src/quantize/job.ts +0 -162
- package/src/quantize/quantizer.ts +0 -666
- package/src/quantize/rotate.ts +0 -603
- package/src/quantize/safetensors-writer.ts +0 -249
- package/src/quantize/sensitivity.ts +0 -216
- package/src/quantize/trellis.ts +0 -586
- package/src/quantize/weight-transform.ts +0 -292
- package/src/registry.ts +0 -602
- package/src/runtime-config.ts +0 -77
- package/src/safetensors.ts +0 -165
- package/src/sampler.ts +0 -1012
- package/src/serve/admin-routes.ts +0 -184
- package/src/serve/assets/curve-terrain.html +0 -105
- package/src/serve/assets/training-inference-map.html +0 -575
- package/src/serve/audio-routes.ts +0 -323
- package/src/serve/aux-routes.ts +0 -132
- package/src/serve/batch-scheduler.ts +0 -8
- package/src/serve/checkpoint-identity.ts +0 -64
- package/src/serve/generation-gateway.ts +0 -537
- package/src/serve/isolate.ts +0 -609
- package/src/serve/kv-budget.ts +0 -14
- package/src/serve/lab-routes.ts +0 -341
- package/src/serve/lane-registry.ts +0 -45
- package/src/serve/model-admin-routes.ts +0 -155
- package/src/serve/model-binding.ts +0 -49
- package/src/serve/model-host.ts +0 -511
- package/src/serve/parent-application.ts +0 -56
- package/src/serve/prompt-response-trace.ts +0 -161
- package/src/serve/response-lease.ts +0 -24
- package/src/serve/session-search.ts +0 -326
- package/src/serve/static-routes.ts +0 -101
- package/src/serve/transcription-server.ts +0 -64
- package/src/serve/transcription-service.ts +0 -502
- package/src/server.ts +0 -1282
- package/src/spec/assistant-rows.ts +0 -93
- package/src/spec/assistant-source.ts +0 -126
- package/src/spec/cache-identity.ts +0 -22
- package/src/spec/deepspec-rows.ts +0 -29
- package/src/spec/deepspec-source.ts +0 -145
- package/src/spec/dflash-source.ts +0 -149
- package/src/spec/drafter.ts +0 -304
- package/src/spec/dspark/ab-stats.ts +0 -136
- package/src/spec/dspark/calibration.ts +0 -112
- package/src/spec/dspark/data-dflash.ts +0 -156
- package/src/spec/dspark/data.ts +0 -201
- package/src/spec/dspark/deepspec-module.ts +0 -776
- package/src/spec/dspark/generate-dflash.ts +0 -245
- package/src/spec/dspark/generate.ts +0 -290
- package/src/spec/dspark/loader.ts +0 -23
- package/src/spec/dspark/loss.ts +0 -213
- package/src/spec/dspark/module-dflash.ts +0 -560
- package/src/spec/dspark/module.ts +0 -540
- package/src/spec/dspark/quantize-drafter.ts +0 -91
- package/src/spec/dspark/sample.ts +0 -112
- package/src/spec/generate.ts +0 -276
- package/src/spec/glm52-mtp-graph.ts +0 -29
- package/src/spec/glm52-mtp-rows.ts +0 -132
- package/src/spec/glm52-mtp-source.ts +0 -318
- package/src/spec/glm52-mtp-state.ts +0 -33
- package/src/spec/ngram-source.ts +0 -226
- package/src/spec/projected-draft-rows.ts +0 -73
- package/src/spec/qwen-mtp-module.ts +0 -171
- package/src/spec/qwen-mtp-rows.ts +0 -230
- package/src/spec/qwen-mtp-source.ts +0 -386
- package/src/spec/qwen-mtp-state.ts +0 -30
- package/src/spec/serve-loop.ts +0 -587
- package/src/spec/source.ts +0 -228
- package/src/spec/two-model-rows.ts +0 -62
- package/src/spec/two-model.ts +0 -113
- package/src/ssd-cache.ts +0 -431
- package/src/ssd-durability.ts +0 -209
- package/src/storage/host-buffer.ts +0 -24
- package/src/storage/kv-writer.ts +0 -83
- package/src/storage/kv-writer.worker.js +0 -264
- package/src/storage/retention-policy.ts +0 -37
- package/src/tiered-prompt-cache.ts +0 -45
- package/src/tokenizer.ts +0 -335
- package/src/tool-approvals.ts +0 -131
- package/src/tool-call.ts +0 -695
- package/src/train/dataset.ts +0 -484
- package/src/train/diffusion-lora.ts +0 -216
- package/src/train/export.ts +0 -32
- package/src/train/flash-cce.ts +0 -1234
- package/src/train/forward.ts +0 -266
- package/src/train/fuse.ts +0 -243
- package/src/train/index.ts +0 -46
- package/src/train/job.ts +0 -205
- package/src/train/lora-params.ts +0 -254
- package/src/train/loss.ts +0 -1591
- package/src/train/merge.ts +0 -195
- package/src/train/optimizer.ts +0 -183
- package/src/train/prefix-shared.ts +0 -490
- package/src/train/rank.ts +0 -137
- package/src/train/segmented.ts +0 -1828
- package/src/train/steel-qmm-header.ts +0 -1461
- package/src/train/trainer.ts +0 -1221
- package/src/train/watch.ts +0 -542
- package/src/vision/diffusion-vision.ts +0 -620
- package/src/vision/embedder.ts +0 -176
- package/src/vision/preprocess.ts +0 -247
- package/src/vision/prompt.ts +0 -409
- package/src/vision/qwen3vl-preprocess.ts +0 -409
- package/src/vision/qwen3vl-prompt.ts +0 -233
- package/src/vision/qwen3vl-tower.ts +0 -566
- package/src/vision/siglip.ts +0 -607
- package/src/vision/video-frames.ts +0 -148
- package/src/web/app.html +0 -2155
- package/src/web/app.js +0 -5863
- package/src/web/skills/memory/SKILL.md +0 -120
- package/src/web/skills/web-research/SKILL.md +0 -46
- package/src/web/skills.ts +0 -97
- package/src/web/src/adapters-panel.ts +0 -288
- package/src/web/src/assistant.ts +0 -451
- package/src/web/src/chat.ts +0 -1060
- package/src/web/src/composer.ts +0 -962
- package/src/web/src/dataset.ts +0 -132
- package/src/web/src/finetune.ts +0 -267
- package/src/web/src/hub.ts +0 -428
- package/src/web/src/main.ts +0 -98
- package/src/web/src/markdown.ts +0 -0
- package/src/web/src/memory-panel.ts +0 -572
- package/src/web/src/model-picker.ts +0 -159
- package/src/web/src/palette.ts +0 -346
- package/src/web/src/protocol.ts +0 -26
- package/src/web/src/quantize.ts +0 -167
- package/src/web/src/rag.ts +0 -274
- package/src/web/src/sessions.ts +0 -469
- package/src/web/src/shell.ts +0 -804
- package/src/web/src/ui-catalog.ts +0 -78
- package/src/web/src/voice.ts +0 -141
- package/src/web/vendor/README.md +0 -61
- package/src/web-assets.ts +0 -47
- package/src/web-tools.ts +0 -478
- package/src/weights.ts +0 -255
- /package/src/{serve → server}/completion-sink.ts +0 -0
- /package/src/{serve → server}/generated-token-history.ts +0 -0
- /package/src/web/{icon.svg → public/icon.svg} +0 -0
- /package/src/web/{manifest.webmanifest → public/manifest.webmanifest} +0 -0
- /package/src/web/{vendor → public/vendor}/hljs-LICENSE +0 -0
package/src/model/glm52-cache.ts
DELETED
|
@@ -1,792 +0,0 @@
|
|
|
1
|
-
// GLM-5.2 compressed attention state.
|
|
2
|
-
//
|
|
3
|
-
// One MLACache corresponds to one decoder layer. It stores only the
|
|
4
|
-
// checkpoint-native compressed state:
|
|
5
|
-
// - latent: [B, T, kv_lora_rank]
|
|
6
|
-
// - decoupled RoPE key: [B, T, qk_rope_head_dim]
|
|
7
|
-
// - optional DSA index key: [B, T, index_head_dim]
|
|
8
|
-
//
|
|
9
|
-
// Serial rows and dynamic batches use the same checkpoint-native tensors.
|
|
10
|
-
// Batched rows are right-justified along T; rowOffsets/leftPad preserve each
|
|
11
|
-
// row's logical position without reconstructing per-head K/V.
|
|
12
|
-
|
|
13
|
-
import { MlxArray } from "../mlx/array";
|
|
14
|
-
import { FullPrefillPadding } from "./full-prefill-padding";
|
|
15
|
-
import type { PrefillPadding } from "./gemma4-base";
|
|
16
|
-
import { Dtype } from "../mlx/ffi";
|
|
17
|
-
import * as ops from "../mlx/ops";
|
|
18
|
-
import {
|
|
19
|
-
type BatchableCache,
|
|
20
|
-
createCausalMask,
|
|
21
|
-
type Cache,
|
|
22
|
-
type Mask,
|
|
23
|
-
} from "./gemma4-base";
|
|
24
|
-
|
|
25
|
-
export interface DSAIndexGeometry {
|
|
26
|
-
readonly headDim: number;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
export interface MLACacheGeometry {
|
|
30
|
-
readonly kvLoraRank: number;
|
|
31
|
-
readonly ropeHeadDim: number;
|
|
32
|
-
readonly dsa?: DSAIndexGeometry;
|
|
33
|
-
/** Optional hard context bound from the model config. */
|
|
34
|
-
readonly maxTokens?: number;
|
|
35
|
-
/** Persistence discriminator; native MTP owns an independent MLA row. */
|
|
36
|
-
readonly role?: "target" | "mtp";
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
export interface MLACompressedState {
|
|
40
|
-
/** Caller-owned view [B, T, kv_lora_rank]. */
|
|
41
|
-
latent: MlxArray;
|
|
42
|
-
/** Caller-owned view [B, T, qk_rope_head_dim]. */
|
|
43
|
-
rope: MlxArray;
|
|
44
|
-
/** Caller-owned view [B, T, index_head_dim], when enabled. */
|
|
45
|
-
dsa: MlxArray | null;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
function positiveInteger(name: string, value: number): void {
|
|
49
|
-
if (!Number.isSafeInteger(value) || value <= 0)
|
|
50
|
-
throw new Error(`${name} must be a positive safe integer`);
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
function safeProduct(label: string, values: readonly number[]): number {
|
|
54
|
-
let product = 1;
|
|
55
|
-
for (const value of values) {
|
|
56
|
-
if (!Number.isSafeInteger(value) || value < 0)
|
|
57
|
-
throw new Error(`${label}: invalid dimension ${String(value)}`);
|
|
58
|
-
product *= value;
|
|
59
|
-
if (!Number.isSafeInteger(product))
|
|
60
|
-
throw new Error(`${label} exceeds the safe integer range`);
|
|
61
|
-
}
|
|
62
|
-
return product;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
function validateF32(
|
|
66
|
-
name: string,
|
|
67
|
-
array: MlxArray,
|
|
68
|
-
expected: readonly number[],
|
|
69
|
-
): void {
|
|
70
|
-
if (array.dtype !== Dtype.float32)
|
|
71
|
-
throw new Error(`${name} must be float32`);
|
|
72
|
-
const shape = array.shape;
|
|
73
|
-
if (
|
|
74
|
-
shape.length !== expected.length ||
|
|
75
|
-
shape.some((dimension, index) => dimension !== expected[index])
|
|
76
|
-
) {
|
|
77
|
-
throw new Error(
|
|
78
|
-
`${name} shape ${JSON.stringify(shape)} != ${JSON.stringify(expected)}`,
|
|
79
|
-
);
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
function appendAlongTokens(current: MlxArray | null, update: MlxArray): MlxArray {
|
|
84
|
-
if (!current) return ops.contiguous(update);
|
|
85
|
-
return ops.concatAxis([current, update], 1);
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
function trimToTokens(array: MlxArray, tokens: number): MlxArray {
|
|
89
|
-
const start = array.shape.map(() => 0);
|
|
90
|
-
const stop = [...array.shape];
|
|
91
|
-
stop[1] = tokens;
|
|
92
|
-
const view = array.slice(start, stop);
|
|
93
|
-
const exact = ops.copyOf(view); // TRUE copy: see 2026-08-20 contiguous-view pin class
|
|
94
|
-
view.dispose();
|
|
95
|
-
return exact;
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
function padLeftTokens(array: MlxArray, tokens: number): MlxArray {
|
|
99
|
-
if (tokens === 0) return ops.contiguous(array);
|
|
100
|
-
const shape = [...array.shape];
|
|
101
|
-
shape[1] = tokens;
|
|
102
|
-
const padding = ops.zeros(shape, Dtype.float32);
|
|
103
|
-
const result = ops.concatAxis([padding, array], 1);
|
|
104
|
-
padding.dispose();
|
|
105
|
-
return result;
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
function validateRowIndex(row: number, batch: number, label: string): void {
|
|
109
|
-
if (!Number.isSafeInteger(row) || row < 0 || row >= batch)
|
|
110
|
-
throw new RangeError(`${label} row ${row} is outside batch ${batch}`);
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
/** Optional DSA index-key state owned by one MLACache. */
|
|
114
|
-
export class DSAIndexCache {
|
|
115
|
-
readonly headDim: number;
|
|
116
|
-
data: MlxArray | null = null;
|
|
117
|
-
offset = 0;
|
|
118
|
-
batchSize: number | null = null;
|
|
119
|
-
|
|
120
|
-
constructor(geometry: DSAIndexGeometry) {
|
|
121
|
-
positiveInteger("DSA headDim", geometry.headDim);
|
|
122
|
-
this.headDim = geometry.headDim;
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
validateAppend(value: MlxArray, batch: number, tokens: number): void {
|
|
126
|
-
validateF32(
|
|
127
|
-
"DSA index state",
|
|
128
|
-
value,
|
|
129
|
-
[batch, tokens, this.headDim],
|
|
130
|
-
);
|
|
131
|
-
if (this.batchSize !== null && batch !== this.batchSize)
|
|
132
|
-
throw new Error(`DSA batch size ${batch} != existing ${this.batchSize}`);
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
append(value: MlxArray, batch: number, tokens: number): void {
|
|
136
|
-
this.validateAppend(value, batch, tokens);
|
|
137
|
-
const next = appendAlongTokens(this.data, value);
|
|
138
|
-
this.data?.dispose();
|
|
139
|
-
this.data = next;
|
|
140
|
-
this.batchSize ??= batch;
|
|
141
|
-
this.offset += tokens;
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
fetch(): MlxArray {
|
|
145
|
-
if (!this.data || this.batchSize === null || this.offset === 0)
|
|
146
|
-
throw new Error("DSA index cache is empty");
|
|
147
|
-
return this.data.slice(
|
|
148
|
-
[0, 0, 0],
|
|
149
|
-
[this.batchSize, this.offset, this.headDim],
|
|
150
|
-
);
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
get byteLength(): number {
|
|
154
|
-
if (this.batchSize === null) return 0;
|
|
155
|
-
return safeProduct(
|
|
156
|
-
"DSA cache byte length",
|
|
157
|
-
[this.batchSize, this.offset, this.headDim, 4],
|
|
158
|
-
);
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
state(): MlxArray[] {
|
|
162
|
-
return this.data ? [this.data] : [];
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
/** Adopt persisted compressed index-key state after validating it. */
|
|
166
|
-
restoreState(data: MlxArray, offset: number): void {
|
|
167
|
-
positiveInteger("DSA restored offset", offset);
|
|
168
|
-
const [batch, tokens] = data.shape;
|
|
169
|
-
positiveInteger("DSA restored batch size", batch!);
|
|
170
|
-
if (tokens !== offset)
|
|
171
|
-
throw new Error(`DSA restored token length ${tokens} != offset ${offset}`);
|
|
172
|
-
validateF32("DSA restored index state", data, [batch!, offset, this.headDim]);
|
|
173
|
-
this.dispose();
|
|
174
|
-
this.data = data;
|
|
175
|
-
this.batchSize = batch!;
|
|
176
|
-
this.offset = offset;
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
trim(n: number): void {
|
|
180
|
-
if (!Number.isSafeInteger(n) || n < 0 || n > this.offset)
|
|
181
|
-
throw new RangeError(`cannot trim ${n} tokens from DSA offset ${this.offset}`);
|
|
182
|
-
if (n === 0) return;
|
|
183
|
-
const nextOffset = this.offset - n;
|
|
184
|
-
if (nextOffset === 0) {
|
|
185
|
-
this.dispose();
|
|
186
|
-
return;
|
|
187
|
-
}
|
|
188
|
-
const next = trimToTokens(this.data!, nextOffset);
|
|
189
|
-
this.data!.dispose();
|
|
190
|
-
this.data = next;
|
|
191
|
-
this.offset = nextOffset;
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
dispose(): void {
|
|
195
|
-
this.data?.dispose();
|
|
196
|
-
this.data = null;
|
|
197
|
-
this.offset = 0;
|
|
198
|
-
this.batchSize = null;
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
export class Glm52Cache implements BatchableCache {
|
|
203
|
-
readonly kvLoraRank: number;
|
|
204
|
-
readonly ropeHeadDim: number;
|
|
205
|
-
readonly maxTokens: number;
|
|
206
|
-
readonly dsa: DSAIndexCache | null;
|
|
207
|
-
readonly role: "target" | "mtp";
|
|
208
|
-
|
|
209
|
-
latent: MlxArray | null = null;
|
|
210
|
-
rope: MlxArray | null = null;
|
|
211
|
-
offset = 0;
|
|
212
|
-
batchSize: number | null = null;
|
|
213
|
-
rowOffsets: number[] = [];
|
|
214
|
-
leftPad: number[] = [];
|
|
215
|
-
#beforeRound: number[] | undefined;
|
|
216
|
-
readonly #padding = new FullPrefillPadding(1);
|
|
217
|
-
|
|
218
|
-
constructor(geometry: MLACacheGeometry) {
|
|
219
|
-
positiveInteger("MLA kvLoraRank", geometry.kvLoraRank);
|
|
220
|
-
positiveInteger("MLA ropeHeadDim", geometry.ropeHeadDim);
|
|
221
|
-
if (geometry.maxTokens !== undefined)
|
|
222
|
-
positiveInteger("MLA maxTokens", geometry.maxTokens);
|
|
223
|
-
this.kvLoraRank = geometry.kvLoraRank;
|
|
224
|
-
this.ropeHeadDim = geometry.ropeHeadDim;
|
|
225
|
-
this.maxTokens = geometry.maxTokens ?? Number.MAX_SAFE_INTEGER;
|
|
226
|
-
this.dsa = geometry.dsa ? new DSAIndexCache(geometry.dsa) : null;
|
|
227
|
-
this.role = geometry.role ?? "target";
|
|
228
|
-
if (this.role === "mtp" && this.dsa)
|
|
229
|
-
throw new Error("native MTP cache cannot contain target DSA state");
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
signature(): string {
|
|
233
|
-
if (this.role === "mtp") return "kv:mla:mtp";
|
|
234
|
-
return this.dsa ? "kv:mla:target:dsa" : "kv:mla:target";
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
bytesPerToken(): number {
|
|
238
|
-
return (this.kvLoraRank + this.ropeHeadDim + (this.dsa?.headDim ?? 0)) * 4;
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
/** Append one equal-width row block without expanding it to per-head K/V. */
|
|
242
|
-
append(latent: MlxArray, rope: MlxArray, dsa: MlxArray | null = null): void {
|
|
243
|
-
const latentShape = latent.shape;
|
|
244
|
-
if (latentShape.length !== 3)
|
|
245
|
-
throw new Error(`MLA latent must have rank 3 (got ${latentShape.length})`);
|
|
246
|
-
const [batch, tokens] = latentShape as [number, number, number];
|
|
247
|
-
positiveInteger("MLA batch size", batch);
|
|
248
|
-
positiveInteger("MLA token count", tokens);
|
|
249
|
-
validateF32("MLA latent", latent, [batch, tokens, this.kvLoraRank]);
|
|
250
|
-
validateF32("MLA RoPE state", rope, [batch, tokens, this.ropeHeadDim]);
|
|
251
|
-
if (this.batchSize !== null && batch !== this.batchSize)
|
|
252
|
-
throw new Error(`MLA batch size ${batch} != existing ${this.batchSize}`);
|
|
253
|
-
const priorRowOffsets = this.rowOffsets.length
|
|
254
|
-
? this.rowOffsets
|
|
255
|
-
: new Array(batch).fill(0) as number[];
|
|
256
|
-
const longestRow = Math.max(...priorRowOffsets);
|
|
257
|
-
if (longestRow > this.maxTokens - tokens)
|
|
258
|
-
throw new RangeError(
|
|
259
|
-
`MLA append would exceed maxTokens ${this.maxTokens}: ` +
|
|
260
|
-
`${longestRow} + ${tokens}`,
|
|
261
|
-
);
|
|
262
|
-
|
|
263
|
-
if (this.dsa) {
|
|
264
|
-
if (!dsa) throw new Error("MLA cache requires DSA index state");
|
|
265
|
-
this.dsa.validateAppend(dsa, batch, tokens);
|
|
266
|
-
if (this.dsa.offset !== this.offset)
|
|
267
|
-
throw new Error(
|
|
268
|
-
`DSA offset ${this.dsa.offset} != MLA offset ${this.offset}`,
|
|
269
|
-
);
|
|
270
|
-
} else if (dsa) {
|
|
271
|
-
throw new Error("MLA cache was created without DSA index state");
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
// Build both MLA arrays before publishing either one. Shape and offset
|
|
275
|
-
// validation above also runs before DSA mutates, so rejected appends leave
|
|
276
|
-
// every state family unchanged.
|
|
277
|
-
let nextLatent: MlxArray | null = null;
|
|
278
|
-
let nextRope: MlxArray | null = null;
|
|
279
|
-
try {
|
|
280
|
-
nextLatent = appendAlongTokens(this.latent, latent);
|
|
281
|
-
nextRope = appendAlongTokens(this.rope, rope);
|
|
282
|
-
if (this.dsa) this.dsa.append(dsa!, batch, tokens);
|
|
283
|
-
} catch (error) {
|
|
284
|
-
nextLatent?.dispose();
|
|
285
|
-
nextRope?.dispose();
|
|
286
|
-
throw error;
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
this.latent?.dispose();
|
|
290
|
-
this.rope?.dispose();
|
|
291
|
-
this.latent = nextLatent;
|
|
292
|
-
this.rope = nextRope;
|
|
293
|
-
this.batchSize ??= batch;
|
|
294
|
-
if (this.rowOffsets.length === 0) {
|
|
295
|
-
this.rowOffsets = new Array(batch).fill(0) as number[];
|
|
296
|
-
this.leftPad = new Array(batch).fill(0) as number[];
|
|
297
|
-
}
|
|
298
|
-
this.rowOffsets = this.rowOffsets.map((value) => value + tokens);
|
|
299
|
-
this.offset += tokens;
|
|
300
|
-
}
|
|
301
|
-
|
|
302
|
-
/** Append and return caller-owned chronological views. */
|
|
303
|
-
appendAndFetch(
|
|
304
|
-
latent: MlxArray,
|
|
305
|
-
rope: MlxArray,
|
|
306
|
-
dsa: MlxArray | null = null,
|
|
307
|
-
): MLACompressedState {
|
|
308
|
-
this.append(latent, rope, dsa);
|
|
309
|
-
return this.fetch();
|
|
310
|
-
}
|
|
311
|
-
|
|
312
|
-
/**
|
|
313
|
-
* GLM attention integration seam. The returned arrays are caller-owned
|
|
314
|
-
* chronological views; the cache retains its own full state.
|
|
315
|
-
*/
|
|
316
|
-
appendCompressed(
|
|
317
|
-
latent: MlxArray,
|
|
318
|
-
rope: MlxArray,
|
|
319
|
-
dsa: MlxArray | null = null,
|
|
320
|
-
): MLACompressedState {
|
|
321
|
-
return this.appendAndFetch(latent, rope, dsa);
|
|
322
|
-
}
|
|
323
|
-
|
|
324
|
-
/** Caller-owned chronological views of all valid compressed state. */
|
|
325
|
-
fetch(): MLACompressedState {
|
|
326
|
-
if (
|
|
327
|
-
!this.latent ||
|
|
328
|
-
!this.rope ||
|
|
329
|
-
this.batchSize === null ||
|
|
330
|
-
this.offset === 0
|
|
331
|
-
) {
|
|
332
|
-
throw new Error("MLA cache is empty");
|
|
333
|
-
}
|
|
334
|
-
return {
|
|
335
|
-
latent: this.latent.slice(
|
|
336
|
-
[0, 0, 0],
|
|
337
|
-
[this.batchSize, this.offset, this.kvLoraRank],
|
|
338
|
-
),
|
|
339
|
-
rope: this.rope.slice(
|
|
340
|
-
[0, 0, 0],
|
|
341
|
-
[this.batchSize, this.offset, this.ropeHeadDim],
|
|
342
|
-
),
|
|
343
|
-
dsa: this.dsa?.fetch() ?? null,
|
|
344
|
-
};
|
|
345
|
-
}
|
|
346
|
-
|
|
347
|
-
/** Caller-owned view of one row with its synthetic left padding removed. */
|
|
348
|
-
fetchRow(row: number): MLACompressedState {
|
|
349
|
-
if (!this.latent || !this.rope || this.batchSize === null)
|
|
350
|
-
throw new Error("MLA cache is empty");
|
|
351
|
-
validateRowIndex(row, this.batchSize, "MLA");
|
|
352
|
-
const start = this.leftPad[row]!;
|
|
353
|
-
const stop = this.offset;
|
|
354
|
-
return {
|
|
355
|
-
latent: this.latent.slice(
|
|
356
|
-
[row, start, 0],
|
|
357
|
-
[row + 1, stop, this.kvLoraRank],
|
|
358
|
-
),
|
|
359
|
-
rope: this.rope.slice(
|
|
360
|
-
[row, start, 0],
|
|
361
|
-
[row + 1, stop, this.ropeHeadDim],
|
|
362
|
-
),
|
|
363
|
-
dsa: this.dsa?.data?.slice(
|
|
364
|
-
[row, start, 0],
|
|
365
|
-
[row + 1, stop, this.dsa.headDim],
|
|
366
|
-
) ?? null,
|
|
367
|
-
};
|
|
368
|
-
}
|
|
369
|
-
|
|
370
|
-
rowOffset(row: number): number {
|
|
371
|
-
if (this.batchSize === null) throw new Error("MLA cache is empty");
|
|
372
|
-
validateRowIndex(row, this.batchSize, "MLA");
|
|
373
|
-
return this.rowOffsets[row]!;
|
|
374
|
-
}
|
|
375
|
-
|
|
376
|
-
/**
|
|
377
|
-
* Compatibility with the generic Cache interface. GLM layers with DSA use
|
|
378
|
-
* appendAndFetch so all three state families advance atomically.
|
|
379
|
-
*/
|
|
380
|
-
updateAndFetch(latent: MlxArray, rope: MlxArray): [MlxArray, MlxArray] {
|
|
381
|
-
if (this.dsa)
|
|
382
|
-
throw new Error("DSA-enabled MLACache requires appendAndFetch");
|
|
383
|
-
const state = this.appendAndFetch(latent, rope);
|
|
384
|
-
return [state.latent, state.rope];
|
|
385
|
-
}
|
|
386
|
-
|
|
387
|
-
makeMask(tokens: number, windowSize: number | null): Mask {
|
|
388
|
-
positiveInteger("MLA mask token count", tokens);
|
|
389
|
-
if (
|
|
390
|
-
windowSize !== null &&
|
|
391
|
-
(!Number.isSafeInteger(windowSize) || windowSize <= 0)
|
|
392
|
-
) {
|
|
393
|
-
throw new Error("MLA attention window must be a positive integer");
|
|
394
|
-
}
|
|
395
|
-
if (tokens === 1) return { mode: "", arr: null };
|
|
396
|
-
if (windowSize === null) return { mode: "causal", arr: null };
|
|
397
|
-
if (this.offset === 0 && tokens <= windowSize)
|
|
398
|
-
return { mode: "causal", arr: null };
|
|
399
|
-
return {
|
|
400
|
-
mode: "array",
|
|
401
|
-
arr: createCausalMask(tokens, this.offset, windowSize),
|
|
402
|
-
};
|
|
403
|
-
}
|
|
404
|
-
|
|
405
|
-
/** Live cache arrays to materialize at a prefill boundary. */
|
|
406
|
-
state(): MlxArray[] {
|
|
407
|
-
if (!this.latent || !this.rope) return [];
|
|
408
|
-
return [this.latent, this.rope, ...(this.dsa?.state() ?? [])];
|
|
409
|
-
}
|
|
410
|
-
|
|
411
|
-
/**
|
|
412
|
-
* Adopt persisted checkpoint-native state. Arrays become cache-owned only
|
|
413
|
-
* after every shape/dtype/geometry check passes.
|
|
414
|
-
*/
|
|
415
|
-
restoreCompressedState(
|
|
416
|
-
latent: MlxArray,
|
|
417
|
-
rope: MlxArray,
|
|
418
|
-
dsa: MlxArray | null,
|
|
419
|
-
offset: number,
|
|
420
|
-
): void {
|
|
421
|
-
positiveInteger("MLA restored offset", offset);
|
|
422
|
-
if (offset > this.maxTokens)
|
|
423
|
-
throw new RangeError(
|
|
424
|
-
`MLA restored offset ${offset} exceeds maxTokens ${this.maxTokens}`,
|
|
425
|
-
);
|
|
426
|
-
const [batch, tokens] = latent.shape;
|
|
427
|
-
positiveInteger("MLA restored batch size", batch!);
|
|
428
|
-
if (tokens !== offset)
|
|
429
|
-
throw new Error(`MLA restored token length ${tokens} != offset ${offset}`);
|
|
430
|
-
validateF32(
|
|
431
|
-
"MLA restored latent",
|
|
432
|
-
latent,
|
|
433
|
-
[batch!, offset, this.kvLoraRank],
|
|
434
|
-
);
|
|
435
|
-
validateF32(
|
|
436
|
-
"MLA restored RoPE state",
|
|
437
|
-
rope,
|
|
438
|
-
[batch!, offset, this.ropeHeadDim],
|
|
439
|
-
);
|
|
440
|
-
if (this.dsa) {
|
|
441
|
-
if (!dsa) throw new Error("MLA restored state requires DSA index state");
|
|
442
|
-
validateF32(
|
|
443
|
-
"MLA restored DSA state",
|
|
444
|
-
dsa,
|
|
445
|
-
[batch!, offset, this.dsa.headDim],
|
|
446
|
-
);
|
|
447
|
-
} else if (dsa) {
|
|
448
|
-
throw new Error("MLA restored state has unexpected DSA index state");
|
|
449
|
-
}
|
|
450
|
-
|
|
451
|
-
this.dispose();
|
|
452
|
-
this.latent = latent;
|
|
453
|
-
this.rope = rope;
|
|
454
|
-
this.batchSize = batch!;
|
|
455
|
-
this.offset = offset;
|
|
456
|
-
this.rowOffsets = new Array(batch!).fill(offset) as number[];
|
|
457
|
-
this.leftPad = new Array(batch!).fill(0) as number[];
|
|
458
|
-
if (this.dsa) this.dsa.restoreState(dsa!, offset);
|
|
459
|
-
}
|
|
460
|
-
|
|
461
|
-
isTrimmable(): boolean {
|
|
462
|
-
return true;
|
|
463
|
-
}
|
|
464
|
-
|
|
465
|
-
trim(n: number): void {
|
|
466
|
-
const shortestRow = this.rowOffsets.length
|
|
467
|
-
? Math.min(...this.rowOffsets)
|
|
468
|
-
: this.offset;
|
|
469
|
-
if (!Number.isSafeInteger(n) || n < 0 || n > shortestRow)
|
|
470
|
-
throw new RangeError(`cannot trim ${n} tokens from MLA offset ${this.offset}`);
|
|
471
|
-
if (n === 0) return;
|
|
472
|
-
const nextOffset = this.offset - n;
|
|
473
|
-
if (nextOffset === 0) {
|
|
474
|
-
this.dispose();
|
|
475
|
-
return;
|
|
476
|
-
}
|
|
477
|
-
|
|
478
|
-
const nextLatent = trimToTokens(this.latent!, nextOffset);
|
|
479
|
-
const nextRope = trimToTokens(this.rope!, nextOffset);
|
|
480
|
-
this.dsa?.trim(n);
|
|
481
|
-
this.latent!.dispose();
|
|
482
|
-
this.rope!.dispose();
|
|
483
|
-
this.latent = nextLatent;
|
|
484
|
-
this.rope = nextRope;
|
|
485
|
-
this.offset = nextOffset;
|
|
486
|
-
this.rowOffsets = this.rowOffsets.map((value) => value - n);
|
|
487
|
-
}
|
|
488
|
-
|
|
489
|
-
preparePrefill(padding: PrefillPadding): void { this.#padding.prepare(this, padding); }
|
|
490
|
-
finalizePrefill(): void {
|
|
491
|
-
const next = this.#padding.finalize(this.state(), this);
|
|
492
|
-
if (!next) return;
|
|
493
|
-
this.latent?.dispose(); this.rope?.dispose();
|
|
494
|
-
this.latent = next[0] ?? null; this.rope = next[1] ?? null;
|
|
495
|
-
if (this.dsa && next[2]) this.dsa.restoreState(next[2], this.offset);
|
|
496
|
-
}
|
|
497
|
-
|
|
498
|
-
specRoundBegin(): void { this.#beforeRound = [...this.rowOffsets]; }
|
|
499
|
-
specRoundCommit(): void { this.#beforeRound = undefined; }
|
|
500
|
-
|
|
501
|
-
/** Keep each accepted prefix in compressed form. Right alignment lets the
|
|
502
|
-
* next shared append reuse the existing MLA/DSA attention geometry. */
|
|
503
|
-
specRoundRollback(keep: number | readonly number[]): void {
|
|
504
|
-
const nextOffsets = this.#beforeRound!.map((before, row) => before +
|
|
505
|
-
(typeof keep === "number" ? keep : keep[row]!));
|
|
506
|
-
const rejected = this.rowOffsets.map((offset, row) => offset - nextOffsets[row]!);
|
|
507
|
-
if (rejected.every(count => count === rejected[0])) {
|
|
508
|
-
const count = this.batchSize!;
|
|
509
|
-
this.trim(rejected[0]!);
|
|
510
|
-
if (this.batchSize === null) {
|
|
511
|
-
const empty = this.makeEmptyBatch();
|
|
512
|
-
try { this.mergeRows(Array.from({ length: count }, () => empty)); }
|
|
513
|
-
finally { empty.dispose(); }
|
|
514
|
-
}
|
|
515
|
-
this.#beforeRound = undefined; return;
|
|
516
|
-
}
|
|
517
|
-
const width = this.offset;
|
|
518
|
-
const pads = this.leftPad.map((pad, row) => pad + rejected[row]!);
|
|
519
|
-
const removable = Math.min(...pads);
|
|
520
|
-
using indices = ops.fromInt32(rejected.flatMap(count =>
|
|
521
|
-
Array.from({ length: width }, (_, column) => (column - count + width) % width)),
|
|
522
|
-
[this.batchSize!, width, 1]);
|
|
523
|
-
const next: MlxArray[] = [];
|
|
524
|
-
try {
|
|
525
|
-
for (const array of this.state()) {
|
|
526
|
-
using shifted = ops.takeAlongAxis(array, indices, 1);
|
|
527
|
-
next.push(shifted.slice([0, removable, 0], [this.batchSize!, width, array.shape[2]!]));
|
|
528
|
-
}
|
|
529
|
-
} catch (error) { for (const array of next) array.dispose(); throw error; }
|
|
530
|
-
this.latent!.dispose(); this.rope!.dispose();
|
|
531
|
-
this.latent = next[0]!; this.rope = next[1]!;
|
|
532
|
-
if (this.dsa) this.dsa.restoreState(next[2]!, width - removable);
|
|
533
|
-
this.offset = width - removable;
|
|
534
|
-
this.rowOffsets = nextOffsets;
|
|
535
|
-
this.leftPad = pads.map(pad => pad - removable);
|
|
536
|
-
this.#beforeRound = undefined;
|
|
537
|
-
}
|
|
538
|
-
|
|
539
|
-
/** Exact logical bytes of valid f32 compressed state. */
|
|
540
|
-
get byteLength(): number {
|
|
541
|
-
if (this.batchSize === null) return 0;
|
|
542
|
-
const logicalTokens = this.rowOffsets.reduce((sum, value) => sum + value, 0);
|
|
543
|
-
return safeProduct(
|
|
544
|
-
"MLA cache byte length",
|
|
545
|
-
[
|
|
546
|
-
logicalTokens,
|
|
547
|
-
this.kvLoraRank + this.ropeHeadDim + (this.dsa?.headDim ?? 0),
|
|
548
|
-
4,
|
|
549
|
-
],
|
|
550
|
-
);
|
|
551
|
-
}
|
|
552
|
-
|
|
553
|
-
makeEmptyBatch(): Glm52Cache {
|
|
554
|
-
const CacheType = this.constructor as typeof Glm52Cache;
|
|
555
|
-
return new CacheType({
|
|
556
|
-
kvLoraRank: this.kvLoraRank,
|
|
557
|
-
ropeHeadDim: this.ropeHeadDim,
|
|
558
|
-
maxTokens: this.maxTokens,
|
|
559
|
-
role: this.role,
|
|
560
|
-
...(this.dsa ? { dsa: { headDim: this.dsa.headDim } } : {}),
|
|
561
|
-
});
|
|
562
|
-
}
|
|
563
|
-
|
|
564
|
-
/** Merge serial or already-batched rows into this empty cache. */
|
|
565
|
-
mergeRows(rows: readonly Cache[]): void {
|
|
566
|
-
if (this.batchSize !== null || this.offset !== 0)
|
|
567
|
-
throw new Error("MLA mergeRows requires an empty destination cache");
|
|
568
|
-
if (rows.length === 0)
|
|
569
|
-
throw new Error("MLA mergeRows requires at least one row");
|
|
570
|
-
|
|
571
|
-
const states: MLACompressedState[] = [];
|
|
572
|
-
const offsets: number[] = [];
|
|
573
|
-
try {
|
|
574
|
-
for (const generic of rows) {
|
|
575
|
-
if (!(generic instanceof Glm52Cache))
|
|
576
|
-
throw new Error("MLA mergeRows requires GLM compressed caches");
|
|
577
|
-
if (
|
|
578
|
-
generic.kvLoraRank !== this.kvLoraRank ||
|
|
579
|
-
generic.ropeHeadDim !== this.ropeHeadDim ||
|
|
580
|
-
generic.maxTokens !== this.maxTokens ||
|
|
581
|
-
generic.role !== this.role ||
|
|
582
|
-
(generic.dsa?.headDim ?? null) !== (this.dsa?.headDim ?? null)
|
|
583
|
-
) {
|
|
584
|
-
throw new Error("MLA mergeRows cache geometry does not match");
|
|
585
|
-
}
|
|
586
|
-
if (generic.batchSize === null || generic.offset === 0) {
|
|
587
|
-
const count = generic.batchSize ?? 1;
|
|
588
|
-
for (let row = 0; row < count; row++) {
|
|
589
|
-
states.push({ latent: ops.zeros([1, 0, this.kvLoraRank], Dtype.float32),
|
|
590
|
-
rope: ops.zeros([1, 0, this.ropeHeadDim], Dtype.float32),
|
|
591
|
-
dsa: this.dsa ? ops.zeros([1, 0, this.dsa.headDim], Dtype.float32) : null });
|
|
592
|
-
offsets.push(0);
|
|
593
|
-
}
|
|
594
|
-
continue;
|
|
595
|
-
}
|
|
596
|
-
for (let row = 0; row < generic.batchSize; row++) {
|
|
597
|
-
states.push(generic.fetchRow(row));
|
|
598
|
-
offsets.push(generic.rowOffset(row));
|
|
599
|
-
}
|
|
600
|
-
}
|
|
601
|
-
|
|
602
|
-
const width = Math.max(...offsets);
|
|
603
|
-
if (width > this.maxTokens)
|
|
604
|
-
throw new RangeError(`MLA merged width ${width} exceeds maxTokens ${this.maxTokens}`);
|
|
605
|
-
const mergeFamily = (
|
|
606
|
-
select: (state: MLACompressedState) => MlxArray,
|
|
607
|
-
): MlxArray => {
|
|
608
|
-
const padded = states.map((state, row) =>
|
|
609
|
-
padLeftTokens(select(state), width - offsets[row]!)
|
|
610
|
-
);
|
|
611
|
-
try {
|
|
612
|
-
return ops.concatAxis(padded, 0);
|
|
613
|
-
} finally {
|
|
614
|
-
for (const array of padded) array.dispose();
|
|
615
|
-
}
|
|
616
|
-
};
|
|
617
|
-
|
|
618
|
-
const latent = mergeFamily((state) => state.latent);
|
|
619
|
-
let rope: MlxArray | null = null;
|
|
620
|
-
let dsa: MlxArray | null = null;
|
|
621
|
-
try {
|
|
622
|
-
rope = mergeFamily((state) => state.rope);
|
|
623
|
-
if (this.dsa) {
|
|
624
|
-
dsa = mergeFamily((state) => {
|
|
625
|
-
if (!state.dsa) throw new Error("MLA mergeRows is missing DSA state");
|
|
626
|
-
return state.dsa;
|
|
627
|
-
});
|
|
628
|
-
}
|
|
629
|
-
} catch (error) {
|
|
630
|
-
latent.dispose();
|
|
631
|
-
rope?.dispose();
|
|
632
|
-
dsa?.dispose();
|
|
633
|
-
throw error;
|
|
634
|
-
}
|
|
635
|
-
|
|
636
|
-
this.latent = latent;
|
|
637
|
-
this.rope = rope;
|
|
638
|
-
this.batchSize = offsets.length;
|
|
639
|
-
this.offset = width;
|
|
640
|
-
this.rowOffsets = [...offsets];
|
|
641
|
-
this.leftPad = offsets.map((value) => width - value);
|
|
642
|
-
if (this.dsa) {
|
|
643
|
-
if (width) this.dsa.restoreState(dsa!, width);
|
|
644
|
-
else { this.dsa.data = dsa!; this.dsa.batchSize = offsets.length; }
|
|
645
|
-
}
|
|
646
|
-
} finally {
|
|
647
|
-
for (const state of states) {
|
|
648
|
-
state.latent.dispose();
|
|
649
|
-
state.rope.dispose();
|
|
650
|
-
state.dsa?.dispose();
|
|
651
|
-
}
|
|
652
|
-
}
|
|
653
|
-
}
|
|
654
|
-
|
|
655
|
-
/** Copy one logical row into an independently-owned serial cache. */
|
|
656
|
-
extractRow(row: number): Glm52Cache {
|
|
657
|
-
if (this.batchSize === null) throw new Error("MLA cache is empty");
|
|
658
|
-
validateRowIndex(row, this.batchSize, "MLA extract");
|
|
659
|
-
if (this.rowOffsets[row] === 0) return this.makeEmptyBatch();
|
|
660
|
-
const state = this.fetchRow(row);
|
|
661
|
-
const copy = (array: MlxArray): MlxArray => ops.mulScalar(array, 1);
|
|
662
|
-
const latent = copy(state.latent);
|
|
663
|
-
const rope = copy(state.rope);
|
|
664
|
-
const dsa = state.dsa ? copy(state.dsa) : null;
|
|
665
|
-
const out = this.makeEmptyBatch();
|
|
666
|
-
try {
|
|
667
|
-
out.restoreCompressedState(latent, rope, dsa, this.rowOffsets[row]!);
|
|
668
|
-
return out;
|
|
669
|
-
} catch (error) {
|
|
670
|
-
latent.dispose();
|
|
671
|
-
rope.dispose();
|
|
672
|
-
dsa?.dispose();
|
|
673
|
-
out.dispose();
|
|
674
|
-
throw error;
|
|
675
|
-
} finally {
|
|
676
|
-
state.latent.dispose();
|
|
677
|
-
state.rope.dispose();
|
|
678
|
-
state.dsa?.dispose();
|
|
679
|
-
}
|
|
680
|
-
}
|
|
681
|
-
|
|
682
|
-
/** Keep selected rows and normalize removable common left padding. */
|
|
683
|
-
filterRows(keep: readonly number[]): void {
|
|
684
|
-
if (this.batchSize === null) throw new Error("MLA cache is empty");
|
|
685
|
-
if (keep.length === 0) throw new Error("MLA filterRows cannot keep zero rows");
|
|
686
|
-
const unique = new Set<number>();
|
|
687
|
-
for (const row of keep) {
|
|
688
|
-
validateRowIndex(row, this.batchSize, "MLA filter");
|
|
689
|
-
if (unique.has(row)) throw new Error(`MLA filter row ${row} is duplicated`);
|
|
690
|
-
unique.add(row);
|
|
691
|
-
}
|
|
692
|
-
const nextOffsets = keep.map((row) => this.rowOffsets[row]!);
|
|
693
|
-
const selectedPad = keep.map((row) => this.leftPad[row]!);
|
|
694
|
-
const removablePad = Math.min(...selectedPad);
|
|
695
|
-
const nextWidth = this.offset - removablePad;
|
|
696
|
-
const indices = ops.fromInt32([...keep], [keep.length]);
|
|
697
|
-
const filterFamily = (array: MlxArray): MlxArray => {
|
|
698
|
-
const trimmed = removablePad === 0
|
|
699
|
-
? array
|
|
700
|
-
: array.slice(
|
|
701
|
-
[0, removablePad, 0],
|
|
702
|
-
[this.batchSize!, this.offset, array.shape[2]!],
|
|
703
|
-
);
|
|
704
|
-
const selected = ops.takeAxis(trimmed, indices, 0);
|
|
705
|
-
const exact = ops.copyOf(selected); // TRUE copy: see 2026-08-20 contiguous-view pin class
|
|
706
|
-
selected.dispose();
|
|
707
|
-
if (trimmed !== array) trimmed.dispose();
|
|
708
|
-
return exact;
|
|
709
|
-
};
|
|
710
|
-
|
|
711
|
-
let latent: MlxArray | null = null;
|
|
712
|
-
let rope: MlxArray | null = null;
|
|
713
|
-
let dsa: MlxArray | null = null;
|
|
714
|
-
try {
|
|
715
|
-
latent = filterFamily(this.latent!);
|
|
716
|
-
rope = filterFamily(this.rope!);
|
|
717
|
-
if (this.dsa) dsa = filterFamily(this.dsa.data!);
|
|
718
|
-
} catch (error) {
|
|
719
|
-
latent?.dispose();
|
|
720
|
-
rope?.dispose();
|
|
721
|
-
dsa?.dispose();
|
|
722
|
-
throw error;
|
|
723
|
-
} finally {
|
|
724
|
-
indices.dispose();
|
|
725
|
-
}
|
|
726
|
-
|
|
727
|
-
this.latent!.dispose();
|
|
728
|
-
this.rope!.dispose();
|
|
729
|
-
this.latent = latent;
|
|
730
|
-
this.rope = rope;
|
|
731
|
-
this.batchSize = keep.length;
|
|
732
|
-
this.offset = nextWidth;
|
|
733
|
-
this.rowOffsets = nextOffsets;
|
|
734
|
-
this.leftPad = selectedPad.map((value) => value - removablePad);
|
|
735
|
-
this.#padding.filter(keep);
|
|
736
|
-
if (this.dsa) {
|
|
737
|
-
if (nextWidth) this.dsa.restoreState(dsa!, nextWidth);
|
|
738
|
-
else {
|
|
739
|
-
// A retained cold row still owns batch membership, even though the
|
|
740
|
-
// strict persisted-state restore contract requires nonempty tokens.
|
|
741
|
-
this.dsa.dispose(); this.dsa.data = dsa!; this.dsa.batchSize = keep.length;
|
|
742
|
-
}
|
|
743
|
-
}
|
|
744
|
-
}
|
|
745
|
-
|
|
746
|
-
projectedBytes(tokens: number): number {
|
|
747
|
-
return Glm52Cache.projectedByteLength({
|
|
748
|
-
kvLoraRank: this.kvLoraRank,
|
|
749
|
-
ropeHeadDim: this.ropeHeadDim,
|
|
750
|
-
...(this.dsa ? { dsa: { headDim: this.dsa.headDim } } : {}),
|
|
751
|
-
}, 1, tokens);
|
|
752
|
-
}
|
|
753
|
-
|
|
754
|
-
static projectedByteLength(
|
|
755
|
-
geometry: MLACacheGeometry,
|
|
756
|
-
batchSize: number,
|
|
757
|
-
tokens: number,
|
|
758
|
-
): number {
|
|
759
|
-
positiveInteger("MLA projected batch size", batchSize);
|
|
760
|
-
if (!Number.isSafeInteger(tokens) || tokens < 0)
|
|
761
|
-
throw new Error("MLA projected token count must be a non-negative safe integer");
|
|
762
|
-
positiveInteger("MLA projected kvLoraRank", geometry.kvLoraRank);
|
|
763
|
-
positiveInteger("MLA projected ropeHeadDim", geometry.ropeHeadDim);
|
|
764
|
-
const dsaWidth = geometry.dsa?.headDim ?? 0;
|
|
765
|
-
return safeProduct(
|
|
766
|
-
"MLA projected byte length",
|
|
767
|
-
[
|
|
768
|
-
batchSize,
|
|
769
|
-
tokens,
|
|
770
|
-
geometry.kvLoraRank + geometry.ropeHeadDim + dsaWidth,
|
|
771
|
-
4,
|
|
772
|
-
],
|
|
773
|
-
);
|
|
774
|
-
}
|
|
775
|
-
|
|
776
|
-
dispose(): void {
|
|
777
|
-
this.latent?.dispose();
|
|
778
|
-
this.rope?.dispose();
|
|
779
|
-
this.dsa?.dispose();
|
|
780
|
-
this.latent = null;
|
|
781
|
-
this.rope = null;
|
|
782
|
-
this.offset = 0;
|
|
783
|
-
this.batchSize = null;
|
|
784
|
-
this.rowOffsets = [];
|
|
785
|
-
this.leftPad = [];
|
|
786
|
-
this.#beforeRound = undefined;
|
|
787
|
-
this.#padding.clear();
|
|
788
|
-
}
|
|
789
|
-
}
|
|
790
|
-
|
|
791
|
-
/** Architecture-name alias retained for code that speaks in MLA terms. */
|
|
792
|
-
export class MLACache extends Glm52Cache {}
|