mlx-bun 0.2.0 → 0.3.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 +71 -588
- package/docs/README.md +91 -0
- package/docs/{design → archive/investigations}/audio-input-plan.md +4 -4
- package/docs/{design → archive/investigations}/diffusion-gemma-port.md +3 -3
- package/docs/{design → archive/investigations}/faithful-l1-consolidation.md +4 -4
- package/docs/{design → archive/investigations}/minicpm5-decode-megakernel.md +11 -11
- package/docs/{design → archive/investigations}/optimization_plan.md +1 -1
- package/docs/{design → archive/investigations}/pre-colibri-stabilization.md +5 -5
- package/docs/{design → archive/investigations}/the-dreaming-handoff.md +2 -2
- package/docs/design/batching.md +569 -0
- package/docs/design/decode-speed-program.md +3178 -169
- package/docs/design/dreaming-nightly-pipeline.md +675 -282
- package/docs/design/generic-model-support.md +579 -334
- package/docs/design/kv-cache.md +680 -0
- package/docs/design/orpo-training.md +673 -1239
- package/docs/design/speculative-decoding.md +1627 -0
- package/docs/design/turboquant.md +2102 -0
- package/docs/design/unified-engine-frontier-plan.md +1831 -727
- package/docs/design/web-chat-redesign.md +666 -1083
- package/docs/planning/PRODUCT_ROADMAP.md +34 -1
- package/docs/planning/release-notes-v0.3.0.md +35 -0
- package/docs/planning/video-series.md +2 -2
- package/docs/reference/benchmarks.md +1162 -0
- package/docs/reference/cli.md +394 -159
- package/docs/reference/distribution.md +321 -182
- package/docs/reference/environment.md +348 -0
- package/docs/reference/glossary.md +39 -0
- package/docs/reference/library-api.md +566 -168
- package/docs/reference/memory.md +227 -64
- package/docs/reference/models.md +104 -6
- package/docs/reference/server-api.md +886 -425
- package/docs/reference/server-config.md +638 -330
- package/docs/reference/training.md +393 -254
- package/docs/reference/troubleshooting.md +166 -0
- package/package.json +9 -4
- package/src/audio/decode.ts +2 -2
- package/src/audio/features.ts +2 -2
- package/src/backends/mlx/autoregressive.ts +108 -0
- package/src/backends/mlx/batch-group.ts +1646 -0
- package/src/backends/mlx/diffusion.ts +39 -0
- package/src/backends/mlx/draft-target.ts +47 -0
- package/src/backends/mlx/evaluation.ts +105 -0
- package/src/backends/mlx/fill-append.ts +45 -0
- package/src/backends/mlx/gateway-binding.ts +71 -0
- package/src/backends/mlx/graph.ts +38 -0
- package/src/backends/mlx/memory-client.ts +189 -0
- package/src/backends/mlx/memory-guard.ts +40 -0
- package/src/backends/mlx/methods.ts +90 -0
- package/src/backends/mlx/model-prompt.ts +164 -0
- package/src/backends/mlx/model-serving.ts +79 -0
- package/src/backends/mlx/prefill.ts +33 -0
- package/src/backends/mlx/request-policy.ts +20 -0
- package/src/backends/mlx/rollback.ts +51 -0
- package/src/backends/mlx/serial-executor.ts +273 -0
- package/src/backends/mlx/speculative.ts +114 -0
- package/src/backends/mlx/state-views.ts +26 -0
- package/src/backends/mlx/text-engine.ts +73 -0
- package/src/cli.ts +58 -25
- package/src/client.ts +66 -0
- package/src/config.ts +21 -4
- package/src/contracts/completion.ts +16 -0
- package/src/contracts/execution.ts +49 -0
- package/src/contracts/generation.ts +103 -0
- package/src/contracts/host.ts +7 -0
- package/src/contracts/jobs.ts +66 -0
- package/src/contracts/pi-provider.ts +30 -0
- package/src/contracts/pi.ts +259 -0
- package/src/contracts/resources.ts +18 -0
- package/src/contracts/scheduling.ts +27 -0
- package/src/contracts/tsconfig.json +14 -0
- package/src/diffusion/diffusion-generate.ts +218 -153
- package/src/embed.ts +1 -1
- package/src/engine/admission.ts +59 -0
- package/src/engine/cancellation.ts +38 -0
- package/src/engine/engine.ts +56 -0
- package/src/engine/execution-coordinator.ts +70 -0
- package/src/engine/execution-plan.ts +51 -0
- package/src/engine/resources.ts +42 -0
- package/src/engine/scheduler.ts +67 -0
- package/src/engine/session.ts +247 -0
- package/src/eval/README.md +44 -1
- package/src/eval/kl.ts +236 -3
- package/src/eval/reference-logits.ts +207 -0
- package/src/eval/runner.ts +8 -96
- package/src/fill/echo-index.ts +188 -0
- package/src/fill/fill-session.ts +452 -0
- package/src/fill/proposal.ts +68 -0
- package/src/fill/schema-rows.ts +506 -0
- package/src/fill/tool-boundary.ts +103 -0
- package/src/fit.ts +1 -1
- package/src/generate.ts +656 -268
- package/src/grammar.ts +12 -7
- package/src/harness-pi.ts +14 -33
- package/src/hub-rest.ts +4 -4
- package/src/index.ts +7 -0
- package/src/inference/denoising.ts +17 -0
- package/src/inference/graph.ts +33 -0
- package/src/inference/prefill.ts +39 -0
- package/src/inference/rollback.ts +7 -0
- package/src/jobs/db.ts +4 -0
- package/src/jobs/index.ts +2 -0
- package/src/jobs/job-entry.ts +12 -12
- package/src/jobs/runner.ts +98 -13
- package/src/jobs/task-client.ts +19 -0
- package/src/jobs/types.ts +2 -58
- package/src/kv-store.ts +109 -49
- package/src/lab/README.md +18 -0
- package/src/{assets → lab/curve}/curve-designer.html +2 -2
- package/src/{curve-sampler.ts → lab/curve/curve-sampler.ts} +2 -2
- package/src/{expert-trace.ts → lab/expert-trace/expert-trace.ts} +5 -5
- package/src/{model → lab/paged-kv}/paged-kv.ts +9 -6
- package/src/library.ts +40 -0
- package/src/lora.ts +18 -0
- package/src/media-fetch.ts +1 -1
- package/src/memory/article.ts +1 -1
- package/src/memory/chunk.ts +1 -1
- package/src/memory/model.ts +30 -169
- package/src/memory/prompts.ts +1 -1
- package/src/memory/rest.ts +1 -1
- package/src/memory/schedule.ts +1 -1
- package/src/memory/stages.ts +4 -1
- package/src/memory/vault.ts +1 -3
- package/src/mlx/array.ts +9 -10
- package/src/mlx/compile.ts +12 -2
- package/src/mlx/ffi.ts +58 -11
- package/src/mlx/materialize.ts +23 -0
- package/src/mlx/metal-kernel.ts +10 -11
- package/src/mlx/ops.ts +33 -13
- package/src/mlx/quantized-rows.ts +36 -0
- package/src/mlx/token-bitmask.ts +52 -0
- package/src/mlx/turboquant-kv-decode.ts +82 -0
- package/src/mlx/turboquant-kv-inverse.ts +122 -0
- package/src/mlx/turboquant-ops.ts +33 -3
- package/src/mlx/turboquant-tables.ts +2 -2
- package/src/model/batched-mask.ts +8 -2
- package/src/model/batched-quant.ts +1 -1
- package/src/model/batched-rotating-quant.ts +2 -2
- package/src/model/batched-rotating.ts +1 -1
- package/src/model/compiled-decode.ts +1 -1
- package/src/model/diffusion-gemma.ts +8 -8
- package/src/model/factory.ts +76 -33
- package/src/model/fingerprint.ts +1 -1
- package/src/model/flash-attention.ts +3 -3
- package/src/model/gemma4-base.ts +26 -9
- package/src/model/gemma4.ts +6 -6
- package/src/model/generated/gemma4-12b.ts +2 -2
- package/src/model/generated/gemma4-26b.ts +2 -2
- package/src/model/generated/gemma4-e4b.ts +2 -2
- package/src/model/glm52-dsa.ts +13 -9
- package/src/model/glm52-memory.ts +1 -1
- package/src/model/implementation.ts +69 -0
- package/src/model/minicpm5.ts +6 -8
- package/src/model/profile.ts +12 -2
- package/src/model/qwen-append.ts +12 -0
- package/src/model/qwen-conv.ts +52 -0
- package/src/model/qwen3_5-checkpoint.ts +164 -0
- package/src/model/qwen3_5.ts +140 -56
- package/src/model/support.ts +1 -1
- package/src/model/trellis-balanced-scatter.ts +51 -0
- package/src/model/trellis-linear.ts +672 -0
- package/src/model/trellis-shared-m.ts +151 -0
- package/src/model/trellis-shared-scatter.ts +144 -0
- package/src/model/trellis-splitk-prefill.ts +158 -0
- package/src/model/trellis-tiled-prefill.ts +136 -0
- package/src/model/trellis-vector-expand.ts +62 -0
- package/src/model/trellis-wide-prefill.ts +94 -0
- package/src/model/universal/dense.ts +1 -1
- package/src/model/universal/modules.ts +8 -1
- package/src/native-pack.ts +6 -5
- package/src/pi-provider.ts +6 -64
- package/src/pi-web.ts +8 -315
- package/src/prompt-cache.ts +96 -53
- package/src/quantize/allocator.ts +1 -1
- package/src/quantize/config-writer.ts +10 -3
- package/src/quantize/rotate.ts +4 -4
- package/src/quantize/trellis.ts +586 -0
- package/src/responses.ts +28 -1
- package/src/runtime-config.ts +18 -4
- package/src/sampler.ts +4 -4
- package/src/serve/batch-scheduler.ts +8 -1671
- package/src/serve/chat-request.ts +391 -0
- package/src/serve/chat-stage.ts +195 -0
- package/src/serve/checkpoint-identity.ts +64 -0
- package/src/serve/completion-executor.ts +15 -7
- package/src/serve/discovery-routes.ts +12 -13
- package/src/serve/generation-gateway.ts +154 -193
- package/src/serve/http.ts +159 -0
- package/src/serve/inference-request.ts +79 -0
- package/src/serve/isolate.ts +297 -105
- package/src/serve/lab-routes.ts +3 -0
- package/src/serve/lane-registry.ts +2 -1
- package/src/serve/model-admin-routes.ts +7 -5
- package/src/serve/model-binding.ts +43 -0
- package/src/serve/model-host.ts +512 -0
- package/src/serve/openai-wire.ts +103 -0
- package/src/serve/parent-application.ts +56 -0
- package/src/serve/pipeline.ts +33 -0
- package/src/serve/preparation.ts +33 -0
- package/src/serve/request-plan.ts +19 -15
- package/src/serve/request-prep.ts +346 -0
- package/src/serve/response-lease.ts +24 -0
- package/src/serve/responses-client.ts +69 -0
- package/src/serve/session-completion-engine.ts +110 -0
- package/src/serve/session-search.ts +1 -1
- package/src/serve/static-routes.ts +5 -5
- package/src/serve/text-completion-stage.ts +104 -0
- package/src/serve/token-streams.ts +519 -0
- package/src/server.ts +317 -2649
- package/src/spec/assistant-source.ts +10 -44
- package/src/spec/deepspec-source.ts +6 -6
- package/src/spec/dflash-source.ts +8 -8
- package/src/spec/dspark/ab-stats.ts +3 -3
- package/src/spec/dspark/calibration.ts +2 -2
- package/src/spec/dspark/deepspec-module.ts +2 -2
- package/src/spec/dspark/generate-dflash.ts +2 -2
- package/src/spec/dspark/generate.ts +2 -2
- package/src/spec/dspark/loader.ts +1 -1
- package/src/spec/dspark/module-dflash.ts +4 -3
- package/src/spec/dspark/module.ts +3 -3
- package/src/spec/dspark/quantize-drafter.ts +1 -1
- package/src/spec/generate.ts +1 -1
- package/src/spec/glm52-mtp-source.ts +1 -1
- package/src/spec/ngram-source.ts +1 -1
- package/src/spec/prefix-state.ts +45 -0
- package/src/spec/qwen-mtp-source.ts +166 -69
- package/src/spec/serve-loop.ts +154 -156
- package/src/spec/source.ts +42 -10
- package/src/spec/two-model.ts +1 -1
- package/src/ssd-cache.ts +80 -12
- package/src/ssd-durability.ts +25 -13
- package/src/tool-call.ts +51 -14
- package/src/train/flash-cce.ts +2 -2
- package/src/train/forward.ts +6 -0
- package/src/train/loss.ts +1 -1
- package/src/train/prefix-shared.ts +5 -1
- package/src/train/segmented.ts +5 -3
- package/src/train/trainer.ts +6 -6
- package/src/vision/prompt.ts +1 -1
- package/src/vision/qwen3vl-tower.ts +52 -10
- package/src/web/app.html +1 -1
- package/src/web/app.js +5 -3
- package/src/web/src/adapters-panel.ts +3 -3
- package/src/web/src/assistant.ts +2 -36
- package/src/web/src/chat.ts +4 -4
- package/src/web/src/composer.ts +4 -4
- package/src/web/src/hub.ts +1 -1
- package/src/web/src/markdown.ts +0 -0
- package/src/web/src/memory-panel.ts +1 -1
- package/src/web/src/model-picker.ts +1 -1
- package/src/web/src/palette.ts +1 -1
- package/src/web/src/protocol.ts +3 -39
- package/src/web/src/sessions.ts +1 -1
- package/src/web/src/ui-catalog.ts +4 -18
- package/src/web-assets.ts +47 -0
- package/src/weights.ts +55 -9
- package/docs/archive/investigations/curve-runs/bisector-route.json +0 -98
- package/docs/archive/investigations/curve-runs/bisector-trace.json +0 -1393
- package/docs/archive/investigations/curve-runs/curve-terrain.json +0 -1179
- package/docs/archive/investigations/curve-runs/curve-terrain.svg +0 -42
- package/docs/archive/investigations/hlg-ab.html +0 -34
- package/docs/archive/investigations/hlg-explorer.html +0 -238
- package/docs/archive/investigations/hlg-figs/cliff.svg +0 -1
- package/docs/archive/investigations/hlg-figs/cross.svg +0 -1
- package/docs/archive/investigations/hlg-figs/edges.svg +0 -1
- package/docs/archive/investigations/hlg-figs/k20-grids.svg +0 -1
- package/docs/archive/investigations/hlg-figs/k20-peaks.svg +0 -1
- package/docs/archive/investigations/hlg-figs/lw-curve.svg +0 -1
- package/docs/archive/investigations/hlg-figs/terrain.svg +0 -1
- package/docs/archive/investigations/hlg-report.html +0 -262
- package/docs/archive/investigations/hlg-runs/hlg-ab.json +0 -149
- package/docs/archive/investigations/hlg-runs/hlg-blind-prompts.md +0 -87
- package/docs/archive/investigations/hlg-runs/hlg-blind.json +0 -107
- package/docs/archive/investigations/hlg-runs/hlg-cliff.json +0 -197
- package/docs/archive/investigations/hlg-runs/hlg-cross.json +0 -505
- package/docs/archive/investigations/hlg-runs/hlg-edge.json +0 -388
- package/docs/archive/investigations/hlg-runs/hlg-eval1.json +0 -25
- package/docs/archive/investigations/hlg-runs/hlg-frontier.json +0 -86
- package/docs/archive/investigations/hlg-runs/hlg-grid.json +0 -242
- package/docs/archive/investigations/hlg-runs/hlg-grid2.json +0 -343
- package/docs/archive/investigations/hlg-runs/hlg-lw-coarse.json +0 -110
- package/docs/archive/investigations/hlg-runs/hlg-map.json +0 -383
- package/docs/archive/investigations/hlg-runs/run0-original.log +0 -159
- package/docs/archive/investigations/hlg-runs/runA-recommended.log +0 -131
- package/docs/archive/investigations/hlg-runs/runAA-cliff-cpm5.log +0 -26
- package/docs/archive/investigations/hlg-runs/runAB-grid2-e4b.log +0 -18
- package/docs/archive/investigations/hlg-runs/runAC-peak-e4b-partial.log +0 -25
- package/docs/archive/investigations/hlg-runs/runAD-ab-samples.log +0 -8
- package/docs/archive/investigations/hlg-runs/runAE-edge-e4b.log +0 -51
- package/docs/archive/investigations/hlg-runs/runAF-logit-calibration.log +0 -10
- package/docs/archive/investigations/hlg-runs/runAG-eval-config2.log +0 -16
- package/docs/archive/investigations/hlg-runs/runB-gain-variants.log +0 -192
- package/docs/archive/investigations/hlg-runs/runC-pivots.log +0 -162
- package/docs/archive/investigations/hlg-runs/runD-oetf.log +0 -132
- package/docs/archive/investigations/hlg-runs/runE-eotf.log +0 -162
- package/docs/archive/investigations/hlg-runs/runF-shaper-working.log +0 -86
- package/docs/archive/investigations/hlg-runs/runG-shaper-sweep.log +0 -101
- package/docs/archive/investigations/hlg-runs/runH-wsweep.log +0 -176
- package/docs/archive/investigations/hlg-runs/runI-asweep.log +0 -176
- package/docs/archive/investigations/hlg-runs/runJ-knobmap.log +0 -49
- package/docs/archive/investigations/hlg-runs/runK-frontier.log +0 -19
- package/docs/archive/investigations/hlg-runs/runL-widemap.log +0 -65
- package/docs/archive/investigations/hlg-runs/runM-frontier-emb.log +0 -15
- package/docs/archive/investigations/hlg-runs/runN-verify.log +0 -116
- package/docs/archive/investigations/hlg-runs/runO-frontier-seed5000.log +0 -15
- package/docs/archive/investigations/hlg-runs/runP-grid-AxSm.log +0 -15
- package/docs/archive/investigations/hlg-runs/runQ-grid-tgW.log +0 -15
- package/docs/archive/investigations/hlg-runs/runR-blind-transcript.log +0 -79
- package/docs/archive/investigations/hlg-runs/runS-cross-coherence.log +0 -33
- package/docs/archive/investigations/hlg-runs/runT-cross-cpm5.log +0 -33
- package/docs/archive/investigations/hlg-runs/runU-cross-12b.log +0 -33
- package/docs/archive/investigations/hlg-runs/runV-lw-e4b.log +0 -22
- package/docs/archive/investigations/hlg-runs/runW-lw-12b.log +0 -22
- package/docs/archive/investigations/hlg-runs/runX-lw-cpm5.log +0 -22
- package/docs/archive/investigations/hlg-runs/runY-cliff-e4b.log +0 -26
- package/docs/archive/investigations/hlg-runs/runZ-cliff-12b.log +0 -26
- package/docs/archive/mlx-bun-lab-report.html +0 -275
- package/docs/archive/wwdc-mlx-bun.html +0 -848
- package/docs/design/adapters-end-to-end.md +0 -205
- package/docs/design/batching-perf-path.md +0 -255
- package/docs/design/batching-v2-plan.md +0 -529
- package/docs/design/bucketing-stage.md +0 -197
- package/docs/design/compat-cli-surface-design.md +0 -230
- package/docs/design/docs-reorg-plan.md +0 -165
- package/docs/design/dspark-serving-program.md +0 -371
- package/docs/design/dspark-speculative-decoding.md +0 -318
- package/docs/design/grammar-spec-batching-integration.md +0 -301
- package/docs/design/memory-inference-path.md +0 -422
- package/docs/design/memory-synthesis.md +0 -287
- package/docs/design/memory-system.md +0 -237
- package/docs/design/mlx-lm-serving-execution-seam.md +0 -81
- package/docs/design/mlx-lm-tool-parity-plan.md +0 -545
- package/docs/design/omlx-adoption-map.md +0 -98
- package/docs/design/orpo-dynamic-lambda.md +0 -220
- package/docs/design/orpo-future-enhancements.md +0 -340
- package/docs/design/paged-kv-cache.md +0 -214
- package/docs/design/parallel-slots.md +0 -567
- package/docs/design/parity-tier-dag.md +0 -161
- package/docs/design/repo-cleanup-plan.md +0 -231
- package/docs/design/runtime-isolation.md +0 -263
- package/docs/design/segmented-backward-training.md +0 -543
- package/docs/design/spec-decode-larger-targets.md +0 -229
- package/docs/design/ssd-kv-cold-tier.md +0 -415
- package/docs/design/structured-output.md +0 -484
- package/docs/design/tauri-desktop-app.md +0 -127
- package/docs/design/the-dreaming-master-plan.md +0 -445
- package/docs/design/turboquant-kv.md +0 -235
- package/docs/design/turboquant-weights.md +0 -467
- package/docs/design/w4a16-compute-precision-spike.md +0 -232
- package/docs/design/web-chat-beat-matrix.md +0 -315
- package/docs/design/write-pipeline-entity.md +0 -468
- package/docs/planning/IDEAS.md +0 -69
- package/docs/reference/embedding.md +0 -197
- package/docs/reference/features-matrix.md +0 -101
- package/docs/reference/orpo-quickstart.md +0 -135
- package/src/flags.ts +0 -11
- /package/docs/{design → archive/investigations}/colibri-glm52-port.md +0 -0
- /package/docs/{planning → archive/planning}/chunk-task-roadmap.md +0 -0
- /package/docs/{planning → archive/planning}/curve-sampler-research-plan.md +0 -0
- /package/docs/{planning → archive/planning}/memory-docs-and-dag-plan.md +0 -0
- /package/docs/{planning → archive/planning}/pi-integration-review.md +0 -0
- /package/docs/{planning → archive/planning}/release-notes-v0.2.0.md +0 -0
- /package/src/{memory-plan.ts → admission-plan.ts} +0 -0
- /package/{docs/archive/investigations → src/serve/assets}/curve-terrain.html +0 -0
- /package/{docs/dag → src/serve/assets}/training-inference-map.html +0 -0
|
@@ -1,214 +0,0 @@
|
|
|
1
|
-
# Optional paged KV cache (vLLM-style) — v1 design
|
|
2
|
-
|
|
3
|
-
Status: **v1 in progress** (this PR)
|
|
4
|
-
Default: **off** (`--paged-kv` unset ⇒ today's `KVCache`/`RotatingKVCache`
|
|
5
|
-
path, byte-identical — the flag-off proof is that zero new code executes).
|
|
6
|
-
|
|
7
|
-
Plan produced by a multi-agent design pass (4 subsystem readers +
|
|
8
|
-
prior-art scout → 3 competing designs → judged synthesis), then vetted
|
|
9
|
-
against the code by hand. Judge's pick: minimal-seam (8.25) over
|
|
10
|
-
serving-first (6.5) and future-proof (7.25); build-order discipline
|
|
11
|
-
grafted from future-proof.
|
|
12
|
-
|
|
13
|
-
## Motivation — what paged buys here, honestly
|
|
14
|
-
|
|
15
|
-
vLLM's PagedAttention (Kwon et al., SOSP 2023, arXiv 2309.06180) solves
|
|
16
|
-
contiguous worst-case per-sequence KV reservation + allocator
|
|
17
|
-
fragmentation. mlx-bun is a single process on unified memory with
|
|
18
|
-
byte-budget admission already shipped (parallel-slots.md rung 2), so the
|
|
19
|
-
fragmentation story mostly doesn't transfer. What does:
|
|
20
|
-
|
|
21
|
-
- **Padded-batch waste removal** — today's batched buffer width tracks
|
|
22
|
-
the LONGEST live row (`mergeKVRows`/`extendKVRows`,
|
|
23
|
-
src/model/batched-mask.ts): a 50-token row batched with a 4000-token
|
|
24
|
-
row pays ~4000 tokens of KV while they cohabit. Block-granular
|
|
25
|
-
allocation removes this. **A batching feature; v1 does NOT implement
|
|
26
|
-
it** (non-goal — follow-up PR).
|
|
27
|
-
- **Block-level prefix sharing / copy-on-write** — PromptCache clones at
|
|
28
|
-
entry granularity; block CoW is vLLM's headline win for concurrent
|
|
29
|
-
agents sharing a system prompt. **Not in v1.**
|
|
30
|
-
- **At batch=1, paging buys nothing** — gather-before-attend is pure
|
|
31
|
-
bandwidth tax on a bandwidth-bound decode. Measured and reported
|
|
32
|
-
plainly, never spun.
|
|
33
|
-
|
|
34
|
-
v1 therefore ships the correctness-proven block-manager abstraction at
|
|
35
|
-
serial (batch=1) scope, expecting a small decode regression and zero
|
|
36
|
-
density win — scaffolding for the follow-ups, not a standalone perf win.
|
|
37
|
-
parallel-slots.md already names paged KV "rung 3 / S3+ deferred";
|
|
38
|
-
unified-engine-frontier-plan.md names block-paged KV the long-term
|
|
39
|
-
unifier. This PR is the first, narrowest slice.
|
|
40
|
-
|
|
41
|
-
Prior-rejection reconciliation (the record already says "no paging"
|
|
42
|
-
twice, for different axes, and both stand): the 2026-07-07 vLLM-mining
|
|
43
|
-
pass rejected paged KV as a PROMPT-CACHE substitute (take()'s zero-copy
|
|
44
|
-
entry clones already share physically), and ssd-kv-cold-tier.md D1
|
|
45
|
-
rejected paged BLOCKS as the SSD-spill granularity (per-block hashing on
|
|
46
|
-
the token loop = oMLX's ~20% tax). This PR is neither: it's the rung-3
|
|
47
|
-
ALLOCATION abstraction (parallel-slots.md), explicitly requested as an
|
|
48
|
-
optional flag, with the padded-batch/CoW payoff deferred to follow-ups.
|
|
49
|
-
|
|
50
|
-
**No external oracle exists**: mlx-lm's cache.py has no paged/block
|
|
51
|
-
cache (verified in the oracle venv). The correctness gate is mlx-bun's
|
|
52
|
-
own plain `KVCache` — valid because v1's claim is storage-layout
|
|
53
|
-
equivalence (same bytes, different physical arrangement), not new
|
|
54
|
-
arithmetic. Bit-exactness (tol 0) is the bar.
|
|
55
|
-
|
|
56
|
-
## v1 scope
|
|
57
|
-
|
|
58
|
-
- Serial (non-batched) single-sequence decode; Gemma4-family models
|
|
59
|
-
(modelType `gemma4*`), plain full-attention layers only. Sliding
|
|
60
|
-
(`RotatingKVCache`) layers keep today's scheme untouched — mixed
|
|
61
|
-
per-layer paged-full + rotating-sliding is the supported shape.
|
|
62
|
-
- bf16 only. No `--kv-quant`/TurboQuant composition.
|
|
63
|
-
- Strategy: **block pool + gather-to-contiguous, then the unchanged
|
|
64
|
-
`ops.sdpa()`** (gemma4.ts Attention.forward's plain-cache `else`
|
|
65
|
-
branch consumes any `Cache` whose updateAndFetch returns contiguous
|
|
66
|
-
[1,H,S,D] views). No new attention math, no new kernel, no new branch
|
|
67
|
-
in the forward.
|
|
68
|
-
- Fixed pool per request, sized up front from prompt length + maxTokens
|
|
69
|
-
(capacity is known at generate() time) — exhaustion is a typed
|
|
70
|
-
`PagedPoolExhausted` error, never silent truncation or OOM.
|
|
71
|
-
|
|
72
|
-
## Non-goals (v1)
|
|
73
|
-
|
|
74
|
-
- No `--batch N` integration (`--paged-kv` + `--batch N>1` refused at
|
|
75
|
-
startup). No `LayerInner` union change in batch-scheduler.ts.
|
|
76
|
-
- No sliding-window paging; no quantized blocks; no CoW/prefix sharing;
|
|
77
|
-
no MoE/SSM/universal/CPM/Diffusion models; no vision/audio; no
|
|
78
|
-
LoRA/adapters; no speculative decode (spec eligibility excludes paged).
|
|
79
|
-
- No fused paged-attention Metal kernel (follow-up once the gather tax
|
|
80
|
-
is measured to matter; metal-kernel.ts infra + optiq's
|
|
81
|
-
sdpa_2pass_paged are the port sources).
|
|
82
|
-
- No compiled-decode composability: a data-dependent block-list length
|
|
83
|
-
is the exact shape shapeless replay already broke on (tiled quantized
|
|
84
|
-
SDPA precedent). `CompiledDecode.supports()` excludes PagedKVCache
|
|
85
|
-
automatically (it's not one of the four supported classes); the
|
|
86
|
-
serve/CLI layer also refuses the explicit combination.
|
|
87
|
-
- No PromptCache integration: paged requests bypass take/put (the
|
|
88
|
-
vision precedent in server.ts runGeneration) and dispose caches on
|
|
89
|
-
completion. `state()` exists only for evalCacheState.
|
|
90
|
-
|
|
91
|
-
## Design
|
|
92
|
-
|
|
93
|
-
New file `src/model/paged-kv.ts`:
|
|
94
|
-
|
|
95
|
-
- **`BlockPool`** — per-layer arena. K and V pool tensors shaped
|
|
96
|
-
`[numBlocks, H_kv, blockSize, headDim]`, allocated via `ops.zeros`
|
|
97
|
-
(mlx-owned end to end — no host-pointer alignment/dtor hazards).
|
|
98
|
-
`alloc()` pops the free list or throws `PagedPoolExhausted`;
|
|
99
|
-
`free(idx)` pushes back. Incoming K/V write via the existing
|
|
100
|
-
`ops.sliceUpdate` at `[block, 0, within, 0]` — the incoming
|
|
101
|
-
`[1,H,l,D]` piece matches the destination slice directly, no
|
|
102
|
-
transpose.
|
|
103
|
-
- **`PagedKVCache implements Cache`** — standalone implementation
|
|
104
|
-
(deliberately NOT a `KVCache` subclass, same reasoning as
|
|
105
|
-
`TurboQuantKVCache`: every instanceof gate — CompiledDecode.supports,
|
|
106
|
-
gateway #modelCachesBatchable, generated `#matches()` — then excludes
|
|
107
|
-
it automatically and routes to the monolith forward).
|
|
108
|
-
- `updateAndFetch(k, v)`: split the incoming L along block boundaries,
|
|
109
|
-
sliceUpdate each piece into pool blocks (allocating from the free
|
|
110
|
-
list as the tail block fills), then fetch: `ops.takeAxis(pool,
|
|
111
|
-
blockTable, 0)` → `[nb,H,bs,D]`, transpose `[1,0,2,3]` →
|
|
112
|
-
`[H,nb,bs,D]`, reshape `[1,H,nb*bs,D]` (the gather copy), slice to
|
|
113
|
-
offset. **Uses only existing bound ops** — the plan's proposed
|
|
114
|
-
`mlx_gather` FFI binding is unnecessary (`takeAxis` gathers whole
|
|
115
|
-
blocks along axis 0), which deletes the bun:ffi stack-arg ABI risk
|
|
116
|
-
outright.
|
|
117
|
-
- `makeMask`: same logic as `KVCache.makeMask` (reads only offset).
|
|
118
|
-
- `trim(n)`: rewind offset, free now-unoccupied tail blocks. Stale
|
|
119
|
-
bytes past offset are never read (fetch slices to offset; writes
|
|
120
|
-
cover exact ranges) — same invariant as KVCache's padding.
|
|
121
|
-
- Block table is host-side `number[]` — no device indirection.
|
|
122
|
-
- All intermediates bound to locals and disposed
|
|
123
|
-
(mlx-inline-slice-leak-pattern discipline).
|
|
124
|
-
|
|
125
|
-
**Wiring** — mirrors the verified `maybeQuantizeKv` precedent
|
|
126
|
-
(post-construction in-place mutation of the cache array,
|
|
127
|
-
generate.ts:153; no makeCache() signature change): `maybePageKv(cache,
|
|
128
|
-
options, capacityTokens)` called ONCE at generation setup (unlike
|
|
129
|
-
quantization there is no "convert when populated" trigger — paged
|
|
130
|
-
replaces EMPTY plain `KVCache` entries, offset 0 only, before prefill).
|
|
131
|
-
`GenerateOptions.pagedKv?: { blockSize?: number }`.
|
|
132
|
-
|
|
133
|
-
Gates:
|
|
134
|
-
- server startup (explicit refuse, not silent downgrade): `--paged-kv` +
|
|
135
|
-
any of `--batch N>1`, `--kv-quant`≠off, TurboQuant, `--draft-model`,
|
|
136
|
-
non-gemma4 model ⇒ exit with a clear message. With no explicit
|
|
137
|
-
`--batch`, the CLI pins `--batch 1` (default is 8) and says so.
|
|
138
|
-
- request scope (documented v1 non-goal CELLS, scoped per request rather
|
|
139
|
-
than 400'd): media (vision/audio) and LoRA-adapter requests strip the
|
|
140
|
-
flag and run the plain cache path — one effective `pagedKv` value in
|
|
141
|
-
runGeneration keeps the strip and the prompt-cache bypass coherent.
|
|
142
|
-
- serve serial lane: paged requests skip promptCache.take/put and the
|
|
143
|
-
boundary snapshot; caches dispose on completion. Spec-decode
|
|
144
|
-
eligibility gains `!options.pagedKv` (belt — the startup refusal
|
|
145
|
-
already excludes the combination).
|
|
146
|
-
- batch lane: unreachable by construction (startup refusal pins serial),
|
|
147
|
-
so no RequestShape change — noted here so the next increment knows the
|
|
148
|
-
gate to add when batched paging lands.
|
|
149
|
-
|
|
150
|
-
Flag surface:
|
|
151
|
-
- CLI: `mlx-bun serve --paged-kv [--paged-kv-block-size N]` (default
|
|
152
|
-
block size 256 = `KVCache.STEP`, so v1's growth granularity is a
|
|
153
|
-
permutation of today's into reusable slots, not a new tuning axis).
|
|
154
|
-
- Env: `MLX_BUN_PAGED_KV=1` via `flagOn()` (explicit env wins).
|
|
155
|
-
- ServerOptions: `pagedKv?: { blockSize?: number }`, doc-commented like
|
|
156
|
-
the neighboring kvQuant/turboQuant fields.
|
|
157
|
-
|
|
158
|
-
## Implementation order
|
|
159
|
-
|
|
160
|
-
1. **BlockPool + PagedKVCache + model-free unit tests**
|
|
161
|
-
(tests/paged-kv.test.ts, FAST tier): block-boundary crossing,
|
|
162
|
-
free-list reuse after trim, pool-exhaustion typed error, gathered
|
|
163
|
-
fetch vs a plain-KVCache reference fed identical synthetic k/v
|
|
164
|
-
(bit-equal every step), dispose-doesn't-leak. Exit: green with no
|
|
165
|
-
weights.
|
|
166
|
-
2. **Wiring**: `maybePageKv` in generate.ts; GenerateOptions/
|
|
167
|
-
ServerOptions/CLI flags; startup refusals; gateway shape exclusion;
|
|
168
|
-
prompt-cache/spec bypass. Exit: flag parses, default-off inert;
|
|
169
|
-
flag-on serves a completion end-to-end (gemma4); incompatible combos
|
|
170
|
-
fail fast.
|
|
171
|
-
3. **Parity gate** (tests/paged-kv-parity.test.ts, weights-gated,
|
|
172
|
-
skipIf pattern): bit-exact (tol 0) full greedy trajectory paged-on
|
|
173
|
-
vs paged-off, incl. a ≥2-block prompt and a trim/rollback case.
|
|
174
|
-
Exit: bit-exact; any divergence documented, never a loosened
|
|
175
|
-
tolerance.
|
|
176
|
-
4. **Perf disclosure**: paged-on vs paged-off decode/prefill on a quiet
|
|
177
|
-
machine via the preflight-gated harness (expected: small decode
|
|
178
|
-
regression at M=1; report plainly). Numbers land in
|
|
179
|
-
benchmarks/RESULTS.md when run on the reference machine.
|
|
180
|
-
5. **Docs, same commit**: server-config.md, cli.md flag rows;
|
|
181
|
-
parallel-slots.md S3+ status flip (v1 shipped: serial, bf16,
|
|
182
|
-
full-attention-only, gather-then-sdpa; batched + CoW + kernel still
|
|
183
|
-
deferred); STATUS.md handoff; this doc.
|
|
184
|
-
|
|
185
|
-
## Risks
|
|
186
|
-
|
|
187
|
-
- Gather pays a full K/V copy per decode step once >1 block is occupied
|
|
188
|
-
— pure tax at M=1 (disclosed, measured; the fused-kernel follow-up is
|
|
189
|
-
the cure if it matters).
|
|
190
|
-
- Fixed pool sizing from prompt+maxTokens: a trim past a block boundary
|
|
191
|
-
followed by regrowth must re-alloc from the free list correctly —
|
|
192
|
-
dedicated test.
|
|
193
|
-
- trim/rollback against a block table is more failure-prone than
|
|
194
|
-
KVCache's offset rewind — dedicated test, not incidental coverage.
|
|
195
|
-
- Every caller that could receive a PagedKVCache it can't handle
|
|
196
|
-
(cloneKvCaches, prompt-cache put, compiled decode, batch scheduler)
|
|
197
|
-
is excluded by gates above; the ones reached only through excluded
|
|
198
|
-
paths throw typed errors if ever reached anyway.
|
|
199
|
-
|
|
200
|
-
## Follow-ups (out of scope, in dependency order)
|
|
201
|
-
|
|
202
|
-
1. **Batched integration** — PagedKVCache into the scheduler's
|
|
203
|
-
LayerInner union; block-count admission replacing byte-projection;
|
|
204
|
-
#mergeJoiner/#applyFilter/#extractAndPut allocate/free blocks
|
|
205
|
-
instead of pad+concat. This is where the padded-batch-waste win
|
|
206
|
-
actually lives.
|
|
207
|
-
2. **Block-level CoW prefix sharing** — refcounted block table
|
|
208
|
-
(retain/release), fork-on-divergent-write; extends PromptCache's
|
|
209
|
-
entry-level ref-counting down to blocks.
|
|
210
|
-
3. **Quantized paged blocks** — dtype-parametric block descriptor
|
|
211
|
-
(packed/scales/biases pools sharing one block-index space).
|
|
212
|
-
4. **Fused paged-attention Metal kernel** — port optiq's
|
|
213
|
-
sdpa_2pass_paged via the copy-verbatim methodology; kills the
|
|
214
|
-
per-step gather copy.
|