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
|
@@ -1,1987 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
status: active
|
|
3
|
-
axis: ON
|
|
4
|
-
canonical-for: engine-architecture
|
|
5
|
-
plan-anchor: "Interface-based engine refactor `[~]`"
|
|
6
|
-
last-verified: 2026-08-23
|
|
7
|
-
---
|
|
8
|
-
|
|
9
|
-
# Engine architecture — four layers, per-scheme oracles, one request path
|
|
10
|
-
|
|
11
|
-
This is the canonical architecture doc for mlx-bun's engine. It owns:
|
|
12
|
-
|
|
13
|
-
- the **four layers** (L1 graph / L2 KV+quant schemes / L3 engine / L4 surface)
|
|
14
|
-
and the rule that features decompose along them;
|
|
15
|
-
- the **fidelity tiers** — L1 = mlx-lm bit-exact, L2 = mlx-optiq bit-exact,
|
|
16
|
-
Lab = no-oracle experiments gated by KL/eval and a paired A/B before any
|
|
17
|
-
default — and the decision procedure that places every optimization;
|
|
18
|
-
- the **naked default IS L1** decision (2026-07-05);
|
|
19
|
-
- the **engine** decision that concurrency is the batch size;
|
|
20
|
-
- the **request path** as it exists in `src/` today, the single-path rule, and
|
|
21
|
-
the known deviations from it;
|
|
22
|
-
- the **flag end-state** and how it maps onto the layers.
|
|
23
|
-
|
|
24
|
-
The v2 refactor is in [§12](#12-interface-based-engine-refactor).
|
|
25
|
-
Josh requested replaceable implementations behind interfaces on 2026-09-04.
|
|
26
|
-
That section defines the target and migration, with implementation status below.
|
|
27
|
-
The portable session and native implementation ports are documented in the
|
|
28
|
-
library API; existing model-class exports remain supported.
|
|
29
|
-
Earlier sections retain the current architecture and numerical contracts.
|
|
30
|
-
`last-verified` above dates the earlier inventory, not a whole-document reaudit.
|
|
31
|
-
|
|
32
|
-
Folded in (2026-08-23): `docs/design/unified-engine-frontier-plan.md` (tier framing, two axes, flag
|
|
33
|
-
classification) and `docs/archive/investigations/faithful-l1-consolidation.md` (the 2026-07-04 faithful→L1
|
|
34
|
-
consolidation and the 2026-07-05 deletion pass, now the History section).
|
|
35
|
-
Status and changelog prose lives in PLAN.md — see "Decision: naked default =
|
|
36
|
-
--l1; levers must beat the baseline (2026-07-05, Josh)" for the decision
|
|
37
|
-
record and "Serving architecture consolidation" for the live S0–S4 work. Every
|
|
38
|
-
`src/` claim below was re-read against the tree on 2026-08-23; where an older
|
|
39
|
-
draft of this doc disagreed with the code, the code wins and the note says so.
|
|
40
|
-
|
|
41
|
-
Companions: `docs/design/batching.md` (B=1 gap numbers), `docs/design/batching.md` and
|
|
42
|
-
`docs/design/batching.md` (scheduler mechanics — the mode-switch decision there is
|
|
43
|
-
superseded by §5), `docs/design/unified-engine-frontier-plan.md` (the S0–S3 seam),
|
|
44
|
-
`decode-speed-program.md` (the only doc that ranks speed levers; it also
|
|
45
|
-
carries the oMLX port ledger that used to be `docs/design/decode-speed-program.md`).
|
|
46
|
-
|
|
47
|
-
---
|
|
48
|
-
|
|
49
|
-
## 1. The two-part product and the contract
|
|
50
|
-
|
|
51
|
-
1. **A drop-in replacement for mlx-lm: everything they do, bit-exact.** This is
|
|
52
|
-
the default. Parity is only *defined* over outputs mlx-lm can produce — you
|
|
53
|
-
cannot ask for "mlx-lm's bits under mixed-precision KV" because mlx-lm
|
|
54
|
-
cannot output anything under it.
|
|
55
|
-
2. **Beyond mlx-lm — features you opt into by deliberately trading the parity
|
|
56
|
-
guarantee for something you value more**, each answering to its own oracle:
|
|
57
|
-
mixed-precision KV (optiq), structured output (oMLX/xgrammar), speculative
|
|
58
|
-
decoding (mlx-lm's `speculative_generate_step`; optiq for the KV-borrowing
|
|
59
|
-
assistant drafter), prompt caching (mlx-lm's `LRUPromptCache`), prefix
|
|
60
|
-
sharing and paged KV (vLLM/SGLang), multi-model switching (optiq
|
|
61
|
-
per-request switching / oMLX EnginePool).
|
|
62
|
-
|
|
63
|
-
**THE CONTRACT (Josh, 2026-07-05) — two rules that compose:**
|
|
64
|
-
|
|
65
|
-
1. **The drop-in promise: the same BITS as mlx-lm.** How the bits are produced
|
|
66
|
-
(storage, kernels, scheduling, engine, language) is the space we compete in.
|
|
67
|
-
2. **The oracle for anything is whoever already does that thing.** Want
|
|
68
|
-
mlx-lm's decode → mlx-lm. optiq's mixed KV → optiq. vLLM's paged attention
|
|
69
|
-
→ vLLM: read their implementation, copy what they did, verify against them,
|
|
70
|
-
then optimize. "No oracle" means *nobody* does the thing — genuine research
|
|
71
|
-
— and that, and only that, is what the Lab is for.
|
|
72
|
-
|
|
73
|
-
Verification form follows the oracle's framework: same-libmlx oracles (mlx-lm,
|
|
74
|
-
optiq) admit bit-exact gates; cross-framework oracles (vLLM, CUDA/PyTorch)
|
|
75
|
-
anchor the algorithm and behavior while rule 1 still binds the output bits in
|
|
76
|
-
the default regime. "Faithful" kernel-set identity is the easiest route to
|
|
77
|
-
same-bits, not the contract; the one constraint bit-exactness puts on an
|
|
78
|
-
implementation is math/reduction order.
|
|
79
|
-
|
|
80
|
-
Two consequences drive everything below:
|
|
81
|
-
|
|
82
|
-
- **The baseline must be even and proven before optimizing.** The L1 path is
|
|
83
|
-
bit-exact with mlx-lm and at decode parity on every model (PLAN.md, the
|
|
84
|
-
2026-07-05 decision). Anything claiming to beat it proves it with a paired
|
|
85
|
-
A/B on a stable pass; otherwise it is noise or a regression.
|
|
86
|
-
- **Frontier-shifting work is usually a quality-per-byte play, not a raw kernel
|
|
87
|
-
play.** Mixed-precision quantization (weights and KV) moves memory down while
|
|
88
|
-
holding or raising intelligence. Quantized KV stays first-class even though
|
|
89
|
-
it lost the speed A/B: it buys context headroom.
|
|
90
|
-
|
|
91
|
-
The frontier axes we measure: memory (generation peak, fit-model), decode
|
|
92
|
-
tok/s (paired h2h, stable cells), prefill/TTFT, batched aggregate throughput,
|
|
93
|
-
and intelligence (the frozen eval suite in evals.sqlite). Curated numbers live
|
|
94
|
-
in `docs/reference/benchmarks.md`.
|
|
95
|
-
|
|
96
|
-
## 2. The four layers
|
|
97
|
-
|
|
98
|
-
```mermaid
|
|
99
|
-
flowchart TB
|
|
100
|
-
subgraph clients["CLIENTS"]
|
|
101
|
-
direction LR
|
|
102
|
-
PI["Pi agent<br/>chat UI + terminal"]
|
|
103
|
-
CLI["mlx-bun CLI"]
|
|
104
|
-
API["any OpenAI / Anthropic / Responses client"]
|
|
105
|
-
LIB["TS/Bun library import"]
|
|
106
|
-
end
|
|
107
|
-
subgraph surface["L4 SERVING SURFACE — src/server.ts + src/serve/*"]
|
|
108
|
-
V1["/v1 endpoints → prepareCompletion → CompletionExecutor"]
|
|
109
|
-
ADMIT["admission: --memory-budget · --kv-budget"]
|
|
110
|
-
end
|
|
111
|
-
subgraph engine["L3 ENGINE — GenerationGateway.place() → serial | continuous"]
|
|
112
|
-
SCHED["BatchScheduler (--batch N cap, default 8)<br/>B=1 adopted-cache fast path · B≥2 step"]
|
|
113
|
-
SERIAL["strict serial executor (generate.ts)<br/>--batch 1 and not-yet-batchable compositions"]
|
|
114
|
-
FEAT["shared: prompt cache · SSD tier · grammar · samplers"]
|
|
115
|
-
end
|
|
116
|
-
subgraph models["L1 MODEL GRAPH — profile-routed, never flag-routed"]
|
|
117
|
-
OPT["dedicated / generated graphs<br/>gemma4 · MiniCPM5 · Qwen3/3.5/3.8 · Qwen3-MoE · GLM-5.2"]
|
|
118
|
-
UNI["universal dense graph — any supported HF arch, best effort"]
|
|
119
|
-
end
|
|
120
|
-
subgraph numerics["L2 KV / QUANT SCHEMES — per-scheme oracles"]
|
|
121
|
-
BF["bf16 (default) — oracle: mlx-lm"]
|
|
122
|
-
UKV["uniform kv 4/8 — oracle: mlx-lm --kv-bits"]
|
|
123
|
-
MKV["mixed kv_config — oracle: mlx-optiq"]
|
|
124
|
-
LAB["Lab: TurboQuant KV · rotation-folded weights · new kernels — KL + eval gates"]
|
|
125
|
-
end
|
|
126
|
-
HW["libmlx (Metal) via bun:ffi — the only runtime link"]
|
|
127
|
-
PI --> V1
|
|
128
|
-
CLI --> V1
|
|
129
|
-
API --> V1
|
|
130
|
-
LIB --> SERIAL
|
|
131
|
-
V1 --> ADMIT --> SCHED
|
|
132
|
-
ADMIT --> SERIAL
|
|
133
|
-
SCHED -.-> FEAT
|
|
134
|
-
SERIAL -.-> FEAT
|
|
135
|
-
SCHED --> OPT
|
|
136
|
-
SERIAL --> OPT
|
|
137
|
-
SCHED --> UNI
|
|
138
|
-
SERIAL --> UNI
|
|
139
|
-
OPT --> BF
|
|
140
|
-
OPT --> UKV
|
|
141
|
-
OPT --> MKV
|
|
142
|
-
UNI --> BF
|
|
143
|
-
MKV -.-> LAB
|
|
144
|
-
BF --> HW
|
|
145
|
-
UKV --> HW
|
|
146
|
-
MKV --> HW
|
|
147
|
-
```
|
|
148
|
-
|
|
149
|
-
### Layer responsibilities (the contract)
|
|
150
|
-
|
|
151
|
-
1. **Model graph (L1)** — one forward step given hidden + caches; attention
|
|
152
|
-
dispatches on the *cache type it is handed* (bf16 → `ops.sdpa`, quantized →
|
|
153
|
-
the quantized SDPA); shape-generic in B; selected by model profile, never by
|
|
154
|
-
flags. *Responsibility: the numerics of a step, for any B, for whatever
|
|
155
|
-
cache it is given.* The contract ENDS AT LOGITS.
|
|
156
|
-
2. **KV scheme (L2, cache classes)** — the memory format and its semantics:
|
|
157
|
-
bf16 / uniform / mixed per-layer / TurboQuant; conversion timing (bf16
|
|
158
|
-
prefill → quantize populated rows, optiq's hook semantics); in batched form
|
|
159
|
-
the multi-row layout (padding, per-row rope, merge/extract/extend/filter).
|
|
160
|
-
*Responsibility: the scheme PER ROW — a row's bytes and math identical solo
|
|
161
|
-
or batched. This is where each scheme's oracle binds.* In code: `KvScheme`
|
|
162
|
-
(`src/kv-scheme.ts`, kinds `bf16 | affine-uniform | affine-config | turbo`),
|
|
163
|
-
the cache classes in `src/model/gemma4-base.ts`, and the batched variants in
|
|
164
|
-
`src/model/batched-*.ts`.
|
|
165
|
-
3. **Engine (L3, scheduler)** — rows: admission, solo prefill, join/merge, the
|
|
166
|
-
step loop, per-row sampling, eviction, pipelining, the concurrency cap.
|
|
167
|
-
Never implements scheme math; calls layer-2 operations. *Responsibility: how
|
|
168
|
-
many rows and when — never what a row's bytes mean.* In code:
|
|
169
|
-
`src/serve/generation-gateway.ts` (placement + the single mutual-exclusion
|
|
170
|
-
domain), `src/serve/batch-scheduler.ts`, `src/generate.ts` (the strict
|
|
171
|
-
serial loop), `src/spec/serve-loop.ts` (the verify loop).
|
|
172
|
-
4. **Serving surface (L4)** — endpoints, per-request features (adapters,
|
|
173
|
-
grammar, sampling, spec policy), prompt cache (keyed by fingerprint +
|
|
174
|
-
effective scheme + adapter), admission budgets. *Responsibility: requests,
|
|
175
|
-
not tensors.* In code: `src/server.ts`, `src/serve/request-plan.ts`,
|
|
176
|
-
`src/serve/completion-executor.ts`, `src/serve/completion-sink.ts`.
|
|
177
|
-
|
|
178
|
-
### Model selection is a declared profile, not a flag
|
|
179
|
-
|
|
180
|
-
`resolveModelProfile()` (`src/model/profile.ts`) freezes, before construction,
|
|
181
|
-
the artifact/config identity, the fidelity target, the required engine
|
|
182
|
-
capabilities, and the loader/graph/loop composition. Exact artifact profiles
|
|
183
|
-
outrank family profiles; dedicated/generated graphs outrank the universal dense
|
|
184
|
-
fallback; an exact profile whose config or capabilities mismatch refuses
|
|
185
|
-
instead of downgrading. Profiles declare construction only — they cannot
|
|
186
|
-
rewrite MTP, KV scheme, adapters, grammar, or sampling (those are request
|
|
187
|
-
methods resolved independently). Promotion universal → dedicated is a
|
|
188
|
-
checklist: custom graph file, bit-exact goldens vs the scheme oracle, an h2h
|
|
189
|
-
entry at ≥1.00× vs mlx-lm on a stable pass, eval-suite rows recorded.
|
|
190
|
-
|
|
191
|
-
Note: `profile.ts` keeps `FidelityTier = "l1" | "l2" | "l3"`, where `l3` means
|
|
192
|
-
`oracle: null, claim: "measured"` — the Lab, named by its old letter. There is
|
|
193
|
-
no `--l3` on the CLI (it hard-errors; §7).
|
|
194
|
-
|
|
195
|
-
### Features decompose ALONG the layers
|
|
196
|
-
|
|
197
|
-
Per-request LoRA is the worked example: L1 = the math (`Wx + scale·B(Ax)`,
|
|
198
|
-
oracle-gated vs mlx-lm's tuner); L3 = the policy (which rows run which
|
|
199
|
-
adapter; today one active adapter per batch, and adapter requests run on the
|
|
200
|
-
serial mechanism); L4 = the surface (`adapter` field, mount/hot-swap,
|
|
201
|
-
discovery); plus one sideways obligation — KV under adapter A ≠ base KV, so the
|
|
202
|
-
prompt cache keys by adapter namespace (`cacheNs` in `runGeneration`). When
|
|
203
|
-
placing a feature, name its component at each layer and each component's gate.
|
|
204
|
-
|
|
205
|
-
### Sampling's placement and the debranching invariant
|
|
206
|
-
|
|
207
|
-
Sampling is *specified* at L4 (request params → a per-row `StepSampler`,
|
|
208
|
-
`src/sampler.ts`) and *executed* at L3 (each step, on each row's `[1,V]`
|
|
209
|
-
slice; vectorized when all-greedy) — it never enters L1. Everything
|
|
210
|
-
per-request-variable is either POST-GRAPH (sampling, grammar masks, stop
|
|
211
|
-
logic) or DATA the fixed graph consumes (adapter weights, caches). This is
|
|
212
|
-
what keeps the generated graph a straight line. Debranching backlog, still
|
|
213
|
-
open: the generated gemma files carry per-token runtime checks (`L > 1 &&
|
|
214
|
-
fusedSdpaRuntimeOk(q, mask)` in `src/model/generated/gemma4-*.ts`) that are
|
|
215
|
-
per-generation-decidable and should be hoisted out of the token path; compiled
|
|
216
|
-
decode already achieves the debranched line dynamically (trace once, replay).
|
|
217
|
-
|
|
218
|
-
The shared greedy operation uses native logsumexp followed by tiled normalized
|
|
219
|
-
score/index reductions in `src/mlx/normalized-argmax.ts`. It preserves rounding
|
|
220
|
-
and lowest-ID ties without materializing the normalized vocabulary array.
|
|
221
|
-
The step sampler applies processors and grammar first, and selects this operation
|
|
222
|
-
only for built-in greedy requests that do not require metadata. Independent
|
|
223
|
-
verification calls the same operation. Fixed-shape compilation caches each
|
|
224
|
-
geometry; enclosing shapeless graphs retain native operations. No scheduler,
|
|
225
|
-
model-family branch or separate sampling setting selects this optimization.
|
|
226
|
-
Actual-model and operation comparisons, plus both-machine serving measurements,
|
|
227
|
-
are recorded in benchmarks.md under fused normalized greedy selection.
|
|
228
|
-
|
|
229
|
-
### Layer 0 — the SSD spill substrate
|
|
230
|
-
|
|
231
|
-
It is almost always faster to cache to SSD and mmap it back than to
|
|
232
|
-
regenerate, and spilling lets RAM be a cache instead of the only tier. Three
|
|
233
|
-
implementations prove it: the SSD KV cold tier (`src/ssd-cache.ts`, a
|
|
234
|
-
`ColdTier` inside `PromptCache.take()` so both mechanisms restore prefixes
|
|
235
|
-
from disk at admission), MoE expert offload (page-aligned mmap), and the
|
|
236
|
-
byte-capped prompt cache. Decision: one generic substrate — content-addressed
|
|
237
|
-
keys (fingerprint + scheme + adapter + producer version), zero-copy mmap
|
|
238
|
-
restore, byte-capped LRU, corruption self-quarantine — that layers 1/2/4
|
|
239
|
-
consume. Future clients: vision encoder features, compiled grammars,
|
|
240
|
-
quantization results, TurboQuant artifacts. Economics (Josh): the SSD
|
|
241
|
-
competes with RECOMPUTE, not RAM — a long agent context is minutes of prefill
|
|
242
|
-
vs about a second of NVMe restore, and the ratio grows with context.
|
|
243
|
-
|
|
244
|
-
### The option surface IS the four layers
|
|
245
|
-
|
|
246
|
-
Users adjust: (1) how the model graph works — profile, compiled decode; (2)
|
|
247
|
-
how quantization works — weight bpw, KV scheme, TurboQuant; (3) how the
|
|
248
|
-
scheduler works — concurrency cap, KV budget, drafting policy; (4) the serving
|
|
249
|
-
surface — endpoints, adapters, structured output, sampling defaults, caches,
|
|
250
|
-
multi-model. Flags, help text, and reference docs should be arranged in these
|
|
251
|
-
four groups (§7).
|
|
252
|
-
|
|
253
|
-
## 3. Fidelity: per-scheme oracles, two axes, one decision procedure
|
|
254
|
-
|
|
255
|
-
The tier ladder is not a product mode. It is a **map from numeric scheme to
|
|
256
|
-
its verification oracle**:
|
|
257
|
-
|
|
258
|
-
| scheme | oracle | verification |
|
|
259
|
-
|---|---|---|
|
|
260
|
-
| bf16 (default), any batch B | **mlx-lm** at the same composition | bit-exact goldens (serial + B=2) |
|
|
261
|
-
| uniform kv 4/8 | **mlx-lm** `--kv-bits` (+ optiq's rotating cache class where upstream is NYI) | bit-exact (`kv-quant` tests) — `quantizedSdpaUnfused` is op-for-op mlx-lm's `quantized_scaled_dot_product_attention` |
|
|
262
|
-
| mixed per-layer kv (`kv_config.json`) | **mlx-optiq** `install_mixed_kv` | bit-exact (`mixed-kv-parity` test; batched rows per-row vs the serial oracle) |
|
|
263
|
-
| TurboQuant KV, rotation-folded weights, mixed-bpw weights, original kernels, batch-invariant kernels | **none exists** → Lab gates | KL vs our own reference path + frozen eval suite + envelope tests + kill switch |
|
|
264
|
-
|
|
265
|
-
`--l1`/`--l2` therefore name the first three rows' oracles. Mixed-precision
|
|
266
|
-
quantization is NOT demoted by the naked-=-L1 decision — it is the flagship of
|
|
267
|
-
the row that mlx-lm cannot oracle.
|
|
268
|
-
|
|
269
|
-
### The two axes (parity gates performance)
|
|
270
|
-
|
|
271
|
-
Every optimization has two independent coordinates, and conflating them is
|
|
272
|
-
what made the flag surface unreadable:
|
|
273
|
-
|
|
274
|
-
1. **Parity** — which reference does it reproduce bit-for-bit? This sets the
|
|
275
|
-
*lowest* tier it may live in: matches mlx-lm → L1; matches optiq but not
|
|
276
|
-
mlx-lm → L2; matches neither → no oracle, Lab-gated.
|
|
277
|
-
2. **Performance** — is it the fastest correct way? This sets whether it is
|
|
278
|
-
the **default (on)** within its tier or a kept-but-off opt-in.
|
|
279
|
-
|
|
280
|
-
**Parity gates performance.** A faster kernel that breaks mlx-lm parity is not
|
|
281
|
-
"a faster L1" — it bubbles up to whatever tier its parity allows, and the user
|
|
282
|
-
opts in. An *optimization* that still matches the oracle stays low:
|
|
283
|
-
compiled decode is ours but is L1 because it replays the same ops bit-for-bit.
|
|
284
|
-
Only nodes with no oracle are forced into the Lab.
|
|
285
|
-
|
|
286
|
-
### Decision procedure for any new optimization
|
|
287
|
-
|
|
288
|
-
1. **Measure its parity** (run both ways, compare — one flag, one measurement
|
|
289
|
-
per lever). The lowest oracle it matches bit-for-bit is its tier ceiling.
|
|
290
|
-
2. **Measure its performance** vs that tier's current default on a stable
|
|
291
|
-
pass:
|
|
292
|
-
- faster AND holds the guarantee → becomes the **default (on)** for the tier;
|
|
293
|
-
- slower but still correct → a documented **default-off kill switch**
|
|
294
|
-
(useful for A/B; never the default);
|
|
295
|
-
- breaks the guarantee but offers a real trade-off → a **Lab item**
|
|
296
|
-
(env flag, bench script, expiry); earns a default only by beating the L1
|
|
297
|
-
baseline in a paired A/B (+ KL PASS if output-changing).
|
|
298
|
-
|
|
299
|
-
Worked: *5% less memory, still bit-for-bit* → default-on in L1. *2× tok/s at
|
|
300
|
-
KL 0.0015* → Lab item. *Another way, 3% slower, still correct* → kept, off.
|
|
301
|
-
|
|
302
|
-
### Composition rule: a composition inherits its scheme's oracle
|
|
303
|
-
|
|
304
|
-
Batching, prompt cache, spec decode, adapters — none change a scheme's
|
|
305
|
-
numerics, so composing them with a scheme verifies against THAT scheme's
|
|
306
|
-
oracle, per row. Batched bf16 anchors to mlx-lm B=N goldens; batched mixed-KV
|
|
307
|
-
anchors to optiq's per-row mechanics (our serial `maybeQuantizeKv` is the
|
|
308
|
-
verified op-for-op copy) and gates on per-row bit-exactness of the unpadded
|
|
309
|
-
row plus a calibrated envelope for padded rows (their noise is pre-existing
|
|
310
|
-
bf16 reduction order under grid snapping, measured at the pinned join step).
|
|
311
|
-
Do NOT invent Lab-style KL/teacher-forced gates for a composition of an
|
|
312
|
-
oracle-backed scheme; the Lab is only for schemes with no oracle at all.
|
|
313
|
-
|
|
314
|
-
### Flag classification (from the tier framing)
|
|
315
|
-
|
|
316
|
-
A flag falls into exactly one of three buckets:
|
|
317
|
-
|
|
318
|
-
| flag selects… | tier effect | what it IS | action |
|
|
319
|
-
|---|---|---|---|
|
|
320
|
-
| the only viable route | — | not a choice | always-on default; no flag |
|
|
321
|
-
| between two routes at the same tier / same oracle | none | a kill switch (A/B, debugging) | default the fast one; keep the slow one documented |
|
|
322
|
-
| between an oracle-backed route and a no-oracle route | tier ↔ Lab | a real parity ⇄ optimization knob | keep, document as such, group by layer |
|
|
323
|
-
|
|
324
|
-
Training flags classify the same way (verified in `src/cli.ts` train help):
|
|
325
|
-
`--grad-clip` is an always-on guard; `--seg N` / `--no-segment` is a
|
|
326
|
-
memory↔compute knob, bit-exact either way; `--grad-accum` and `--lambda` are
|
|
327
|
-
training-quality/hyperparameter knobs; `--no-flash` (flash-CCE head → the
|
|
328
|
-
MLX fused head) and `--no-prefix` (prefix-shared forward → two-forward) are
|
|
329
|
-
the only true parity ⇄ optimization toggles on that surface. The 2026-06-21
|
|
330
|
-
"parity-tier DAG" HTML map that motivated this classification
|
|
331
|
-
(`docs/dag/training-inference-map.html`) no longer exists in the tree; the
|
|
332
|
-
roadmap it proposed — derive the graph from code, CI-enforce "an L1-tagged
|
|
333
|
-
node has a passing bit-exact test", shrink the no-oracle surface, generate the
|
|
334
|
-
flag surface from the graph — remains an idea, not a phase.
|
|
335
|
-
|
|
336
|
-
### Lab lifecycle rule (the anti-flag-pile law)
|
|
337
|
-
|
|
338
|
-
Every Lab experiment ships with (a) a hypothesis in frontier-axis terms, (b) a
|
|
339
|
-
paired A/B bench script, (c) an expiry review date. Outcomes: promote to
|
|
340
|
-
default (with stable-pass numbers) or delete (with a breadcrumb in the design
|
|
341
|
-
doc). No third state. "Off in every regime with no promotion path" is a
|
|
342
|
-
deletion that hasn't happened yet.
|
|
343
|
-
|
|
344
|
-
## 4. Decision: the naked default IS L1 (2026-07-05, Josh)
|
|
345
|
-
|
|
346
|
-
The 2026-07-05 h2h pass showed the L1 kernel set at decode parity with mlx-lm
|
|
347
|
-
on every model while every output-changing lever failed to beat it in a paired
|
|
348
|
-
A/B, and quantized KV measured slower than bf16 at ≤16k on both stacks (it
|
|
349
|
-
buys memory headroom only). The record with numbers is PLAN.md "Decision:
|
|
350
|
-
naked default = --l1".
|
|
351
|
-
|
|
352
|
-
- **Naked = `--l1`.** `applyDecodeRoute` (`src/cli.ts`) defaults the tier to
|
|
353
|
-
`l1`: bf16 KV, compiled decode on, compiled activations on, fused SDPA off.
|
|
354
|
-
- **Prior perf-optimization work is untrusted until re-proven** from this
|
|
355
|
-
baseline (the losers were deleted the same day — §11 History).
|
|
356
|
-
- **The bar for any lever to earn a default back:** a paired A/B win vs L1 on
|
|
357
|
-
a stable pass (no `unstable` tag), plus KL PASS if output-changing.
|
|
358
|
-
- **Explicit `--kv-quant` picks its oracle's composition**: `config` → optiq's
|
|
359
|
-
fused prefill SDPA + stock unfused decode (the L2 golden composition);
|
|
360
|
-
uniform `4|8` → unfused (mlx-lm's algorithm, L1-eligible); `turbo[:k.v.]` →
|
|
361
|
-
dequantize-on-fetch through stock `ops.sdpa` (Lab). `--fused-sdpa` still
|
|
362
|
-
overrides either.
|
|
363
|
-
- **`--l1`/`--l2` are pure aliases.** Each expands to a fixed set of per-fork
|
|
364
|
-
values (`TIERS` in `applyDecodeRoute`), installed through
|
|
365
|
-
`configureRuntime()` into the immutable runtime snapshot before model modules
|
|
366
|
-
load; a per-fork flag overrides one value. Two invariants: a user can
|
|
367
|
-
reproduce any tier byte-for-byte from individual flags, and no preset may set
|
|
368
|
-
anything that isn't also an individual flag.
|
|
369
|
-
|
|
370
|
-
## 5. The engine: concurrency IS the batch size
|
|
371
|
-
|
|
372
|
-
**Decision (Josh, 2026-07-05): batching is determined by how many concurrent
|
|
373
|
-
requests are in flight, not by a flag.** One request = a lone row at serial
|
|
374
|
-
speed; N requests = continuous batching; rows join and leave running batches.
|
|
375
|
-
This reversed `docs/design/batching.md`'s "`--batch N` is a mode switch" decision.
|
|
376
|
-
The old objection — "an idle vs loaded server produces different numerics for
|
|
377
|
-
the same request" — gets a real answer:
|
|
378
|
-
|
|
379
|
-
1. **The L1 oracle itself behaves this way.** `mlx_lm.server` auto-batches;
|
|
380
|
-
"drop-in for mlx-lm" *requires* concurrency-driven batching. The parity
|
|
381
|
-
contract is **bit-exact to mlx-lm at the same batch composition**.
|
|
382
|
-
2. Anyone who needs load-independent numerics pins `--batch 1`.
|
|
383
|
-
3. **Batch-invariant kernels** (identical numerics regardless of B) are a Lab
|
|
384
|
-
research item; if they land, determinism-under-load returns for free.
|
|
385
|
-
|
|
386
|
-
**The flag stays `--batch`** (no rename); its semantics are the cap on
|
|
387
|
-
concurrent rows (`--decode-concurrency` is accepted as the mlx_lm.server
|
|
388
|
-
alias). **Default 8** (`serverOptions.batch ?? 8` in `src/server.ts` and
|
|
389
|
-
`src/cli.ts`) — optiq's Mac-safe concurrency default and the 4–8-sub-agent
|
|
390
|
-
workload, superseding the earlier 32. `--batch 1` pins the strict serial
|
|
391
|
-
executor. An older draft of this doc and its diagram said 32; the code says 8.
|
|
392
|
-
|
|
393
|
-
**The workload this is for**: a user's agent harness pointing sub-agents at
|
|
394
|
-
one local server. Serial, the Nth agent's first token waits for N−1 full
|
|
395
|
-
generations; batched, every agent starts instantly and the fleet's wall-clock
|
|
396
|
-
collapses. Consequences: concurrency-driven batching (sub-agents don't
|
|
397
|
-
coordinate arrivals), prefix sharing gains priority (shared system prompts),
|
|
398
|
-
per-slot adapters, and batching × quantized KV first (long contexts).
|
|
399
|
-
"Single-user" in this project means single user, many agents.
|
|
400
|
-
|
|
401
|
-
### The B=1 fast path (the crux gate, met)
|
|
402
|
-
|
|
403
|
-
The unified engine could not replace the serial lane until a lone request
|
|
404
|
-
through the scheduler matched serial decode speed and bits. mlx-lm's own
|
|
405
|
-
`BatchGenerator` at B=1 runs within a few percent of its `stream_generate`
|
|
406
|
-
(paired A/B, PLAN.md), so the design was proven achievable; our gap was an
|
|
407
|
-
implementation artifact, closed in two moves (both are now design contracts,
|
|
408
|
-
§8): readbacks in a pipelined loop must not create ops, and a lone row keeps
|
|
409
|
-
bare serial-class caches so the step dispatches the same graph the serial loop
|
|
410
|
-
builds. Today `BatchScheduler` runs, for `B === 1 && unpadded && supports(inners)`
|
|
411
|
-
with a uint32 pipeline register, the serial engine's `CompiledDecode` step
|
|
412
|
-
(adopt-don't-copy: a row joining an empty batch keeps its solo caches as the
|
|
413
|
-
inners; the merge copy runs only when a second row actually joins). The
|
|
414
|
-
recorded scheduler/serial paired decode ratios are 0.992–0.996 (PLAN.md
|
|
415
|
-
"Serving architecture consolidation"), and `GATE-B1-PARITY` (bit-exact vs the
|
|
416
|
-
L1 goldens through the scheduler) is green on the curated probes.
|
|
417
|
-
|
|
418
|
-
### Composition is the product
|
|
419
|
-
|
|
420
|
-
Every serving capability is a STACKABLE layer on one engine — never a
|
|
421
|
-
lane-routing condition, never mutually exclusive. The matrix the engine must
|
|
422
|
-
satisfy, with the state of `GenerationGateway.#supportsContinuous` as read on
|
|
423
|
-
2026-08-23:
|
|
424
|
-
|
|
425
|
-
| layer | today (src) | end state |
|
|
426
|
-
|---|---|---|
|
|
427
|
-
| dedicated per-model graph | both mechanisms (profile-routed) | unchanged |
|
|
428
|
-
| mixed-precision KV (`affine-config`) | supported per-layer and uniform affine KV use continuous groups; incompatible layouts remain open | one active scheme per server, any B |
|
|
429
|
-
| LoRA adapters | compatible ordered adapter sets share a group; context and cache identity bind under the execution lease | per-slot adapter state (vLLM Punica/SGMV pattern: every row runs the adapter math, non-adapter rows at scale 0) |
|
|
430
|
-
| speculative decoding (two-model · assistant · dspark · deepspec · native MTP · ngram) | actual speculation uses the serial verifier; supported ordinary requests can batch with a mounted draft | per-slot drafting behind the `DraftSource` seam |
|
|
431
|
-
| structured output (grammar) | both (per-row matchers; `MLX_BUN_GRAMMAR_BATCH=0` forces serial) | unchanged; keep the conformance gate |
|
|
432
|
-
| sampling (temp/top-p/top-k/min-p/XTC/penalties/HLG/seed) | per-row sampling sessions, including explicit seeds, repetition penalty and logits extras | fully per-row, seeds included |
|
|
433
|
-
| logprobs capture | shared row sampling and readback in continuous groups | preserve method composition |
|
|
434
|
-
| vision / audio media prompts | serial only (`shape.hasVision`; embeddings-prefill bypasses the prompt cache) | batched media prefill |
|
|
435
|
-
| prompt cache / SSD tier | both: scheduler joiners `take()` the longest usable prefix at admission, never-merged rows `put()` back on finish; the cold tier restores inside `take()` | block-granular sharing across rows |
|
|
436
|
-
| paged KV (`--paged-kv`) | serial only, Gemma4 bf16, refuses `--batch N>1`, `--kv-quant`, `--draft-model`; bypasses the prompt cache | block-level CoW prefix sharing (vLLM oracle) |
|
|
437
|
-
|
|
438
|
-
Ordering of the remaining rows (by value): adapters per slot, then spec per
|
|
439
|
-
slot, then logprobs, then chunked prefill interleaving (vLLM policy) so a long
|
|
440
|
-
prefill doesn't stall running streams. `scripts/bench-matrix.ts modes` is the
|
|
441
|
-
composition scoreboard — every layer added to the scheduler gets a cell and a
|
|
442
|
-
parity gate.
|
|
443
|
-
|
|
444
|
-
## 6. Request path today
|
|
445
|
-
|
|
446
|
-
Modules in order, as read in `src/` on 2026-08-30:
|
|
447
|
-
|
|
448
|
-
1. **The request pipeline** (`src/serve/`). A request is data; each stage
|
|
449
|
-
is one program with a declared input and output, composed in order by
|
|
450
|
-
`src/server.ts` (which otherwise only assembles the server — KV scheme,
|
|
451
|
-
prompt cache + SSD tier, gateway, admission — and dispatches routes):
|
|
452
|
-
`new ChatRequest(body)` (`chat-request.ts`; validation at construction,
|
|
453
|
-
mlx-lm's 400 messages) → `ChatStage.run` (`chat-stage.ts`; template render
|
|
454
|
-
+ prompt ids, media embeddings by family, grammar, adapters, sampling
|
|
455
|
-
defaults via `request-prep.ts`) → `InferenceRequest` (`inference-request.ts`)
|
|
456
|
-
→ `InferenceStage.admit` (memory ceiling → reject or clamp; seals the plan)
|
|
457
|
-
→ `InferenceStage.run` → `InferenceResult` → wire. `/v1/completions` is
|
|
458
|
-
`TextCompletionStage` into the same inference stage; `/v1/messages` and
|
|
459
|
-
`/v1/responses` reuse `ChatStage` and format the result themselves. One
|
|
460
|
-
JSON/SSE writer (`http.ts`) serves every surface; the protocol object
|
|
461
|
-
(`openai-wire.ts`, `src/anthropic.ts`, `src/responses.ts`) is the only
|
|
462
|
-
thing that differs.
|
|
463
|
-
2. **`src/serve/completion-executor.ts` `prepareCompletion()`** → **`src/serve/request-plan.ts` `planRequest()`** — admission (memory budget → reject or clamp `maxTokens`), capture options, adapter selection, and the `RequestShape` are derived ONCE for chat and raw-text, streaming and non-streaming. The result is an opaque, single-use `PreparedCompletion`; adapters cannot inspect or rewrite the plan. Owned resources (media arrays, grammar) dispose on rejection.
|
|
464
|
-
3. **`CompletionExecutor.execute()`** — owns one completion attempt: asks the engine for placement, records the lane (`src/serve/lane-registry.ts`), builds the `CompletionSink` (semantic events: content / reasoning / tool calls / stop), collects logprobs, transfers resource ownership exactly once, runs, and settles the terminal summary (finish reason, usage, cached tokens, final lane, speculation stats). Adapters only format that summary.
|
|
465
|
-
4. **`src/serve/generation-gateway.ts` `GenerationGateway.place(shape)`** — freezes one `GenerationPlacement { shape, mechanism: "serial" | "continuous" }`. `#supportsContinuous` is a capability check only (§5 matrix); it never rewrites MTP, KV scheme, TurboQuant, grammar, adapters, or sampling. `run()` rejects a placement made for another shape. One `AsyncMutex` is the single mutual-exclusion domain: a serial run holds it; the scheduler holds it for its whole active period; a waiting serial request drains the batch (mlx-lm's `drain_batch`).
|
|
466
|
-
5. **`continuous` →** `src/serve/batch-scheduler.ts` — admission under `--kv-budget`, chunked interleaved solo prefill, join/merge/extend/filter over per-layer cache types, the pipelined step loop, per-row `StepSampler`, eviction. B=1 takes the adopted-cache fast path (§5). **`serial` →** `runGeneration` in `src/server.ts` → `src/generate.ts` (prompt-cache take/put, snapshot boundary, the chunked prefill, the pipelined compiled decode loop) or, when a draft is mounted and the request is spec-eligible, `src/spec/serve-loop.ts`.
|
|
467
|
-
|
|
468
|
-
**The single-path rule.** Options are *declarations* carried through
|
|
469
|
-
placement, never forks above the scheduler. A request's resolved settings
|
|
470
|
-
(KV scheme, TurboQuant, drafting, grammar, adapters, sampling) are authoritative
|
|
471
|
-
from `planRequest` onward; `place()` may only answer "does the continuous
|
|
472
|
-
mechanism implement exactly this composition?" — it may not substitute a
|
|
473
|
-
cheaper composition to make a request batchable (the optiq bug class: silently
|
|
474
|
-
serving bf16 under a quantized scheme). The scheduler independently refuses a
|
|
475
|
-
scheme it cannot execute at construction, and `KvScheme` freezes its per-layer
|
|
476
|
-
entries so a caller cannot mutate conversion or accounting after resolution.
|
|
477
|
-
|
|
478
|
-
**Known deviations from the single-path rule (verified 2026-08-23):**
|
|
479
|
-
|
|
480
|
-
1. **Two prefill loops.** `src/generate.ts` (the chunk loop with the
|
|
481
|
-
`snapshotAt` split, the mlx-lm tail-split convention
|
|
482
|
-
`min(prefillChunkSize, remaining-1)`, per-chunk `clearCache`) and
|
|
483
|
-
`BatchScheduler.#prefillChunk` in `src/serve/batch-scheduler.ts` (the same
|
|
484
|
-
conventions re-implemented over `PrefillState` for interleaved admission).
|
|
485
|
-
Both are gated bit-exact, but a convention change must land in two places.
|
|
486
|
-
2. **Method selection now precedes placement.** `resolveExecution` selects
|
|
487
|
-
speculative or ordinary decoding from the actual request and backend
|
|
488
|
-
capabilities. Configuring a draft no longer forces supported ordinary work
|
|
489
|
-
into the serial executor. The final design has one shared executor; changing
|
|
490
|
-
method must not select a retired execution path. Concurrent speculation is
|
|
491
|
-
still an implementation gap, tracked in batching.md.
|
|
492
|
-
|
|
493
|
-
3. **Speculative decoding depth** — DFlash/DSpark, native MTP, behind the
|
|
494
|
-
`DraftSource` seam (`docs/design/speculative-decoding.md`).
|
|
495
|
-
4. **Per-model graph work from the baseline** — unroll a model's flat DAG,
|
|
496
|
-
find fusion the compiler misses, prove with kernel-trace diffs, promote per
|
|
497
|
-
model.
|
|
498
|
-
5. **Batch-invariant kernels** (research) — restores determinism under load.
|
|
499
|
-
|
|
500
|
-
## 10. Decisions log and open items
|
|
501
|
-
|
|
502
|
-
1. **Cap default 8** — flipped 2026-07-05 after the B=1 gates; `--batch 1`
|
|
503
|
-
pins arrival-independent numerics; kv-budget admission keeps 8 safe on
|
|
504
|
-
small boxes.
|
|
505
|
-
2. **Flag stays `--batch`**; semantics = cap.
|
|
506
|
-
3. **Perf kernel deleted**; a future flash-decode kernel re-derives from the L1
|
|
507
|
-
baseline in the Lab — no resurrection.
|
|
508
|
-
4. **`--l1`/`--l2` remain user-facing CLI aliases** (`src/cli.ts` documents
|
|
509
|
-
them under "Parity tier"). The 2026-07-05 intent that they become
|
|
510
|
-
bench/test vocabulary only has not been executed; if it is, `serve --help`,
|
|
511
|
-
`docs/reference/cli.md`, and `server-config.md` change in the same commit.
|
|
512
|
-
5. **Block-paged KV**: an optional serial-only v1 exists (`--paged-kv`,
|
|
513
|
-
`docs/design/kv-cache.md`); padded-batch waste removal and block CoW prefix
|
|
514
|
-
sharing are its follow-ups, triggered when prefix sharing under batching
|
|
515
|
-
becomes the bottleneck.
|
|
516
|
-
6. **Prefix sharing scope**: must extend to the disk tier; first-class cases
|
|
517
|
-
are new-session spin-up and server restart — the shared prefix is a durable
|
|
518
|
-
object, not a property of one conversation's entry.
|
|
519
|
-
7. **Open composition rows** (§5): adapters, spec, logprobs, media on the
|
|
520
|
-
continuous mechanism; chunked prefill interleaving as policy.
|
|
521
|
-
8. **Open single-path deviations** (§6): unify the prefill loops; move
|
|
522
|
-
prompt/media/grammar construction behind the seam; lift spec eligibility
|
|
523
|
-
into `RequestShape`.
|
|
524
|
-
9. **Debranching backlog** (§2): hoist the generated files' per-token
|
|
525
|
-
`L > 1 && fusedSdpaRuntimeOk` checks.
|
|
526
|
-
|
|
527
|
-
## 11. History
|
|
528
|
-
|
|
529
|
-
**2026-07-04 — faithful → L1 consolidation.** An audit found three
|
|
530
|
-
overlapping "match mlx-lm" mechanisms that disagreed: the `--l1/--l2/--l3`
|
|
531
|
-
tier presets, an `MLX_BUN_FAITHFUL` preset that forced the gemma monolith and
|
|
532
|
-
set choices no flag could reach, and a family of unwired `Faithful*` model
|
|
533
|
-
subclasses. The decisive rule that collapsed them: **"compiled" kernels
|
|
534
|
-
(`@mx.compile` geglu/swiglu, compiled decode) go through the same libmlx as
|
|
535
|
-
mlx-lm → bit-exact and faster → L1 defaults; custom "fused" Metal kernels were
|
|
536
|
-
mlx-bun originals with a proven residual → not bit-exact.** Landed in four
|
|
537
|
-
phases: compiled activations default-on everywhere (qwen3, qwen3.5, universal
|
|
538
|
-
dense, gemma geglu via `MLX_BUN_COMPILED_GEGLU`, MiniCPM5 swiglu), verified
|
|
539
|
-
`maxDiff === 0` vs mlx-lm; `--compiled-activations` and `--fused-gelu` added as
|
|
540
|
-
per-fork flags so `--l1` became a pure alias; `MLX_BUN_FAITHFUL`, `faithful.ts`
|
|
541
|
-
(→ `flags.ts`, only `flagOn` kept), and the four unwired subclasses deleted;
|
|
542
|
-
docs + the "cost of removing each faithful kernel" bench matrix. The only
|
|
543
|
-
family that had it right from the start was `qwen3_moe`: the production class
|
|
544
|
-
IS the faithful port. Bit-exact-to-mlx-lm *wants* compiled activations (mlx-lm
|
|
545
|
-
`@mx.compile`s them), so the earlier `--l1` "unfused" help text was backwards.
|
|
546
|
-
|
|
547
|
-
**2026-07-05 — the Phase-1 deletion pass** (same day as the naked-=-L1
|
|
548
|
-
decision; ~50 files touched, 23 deleted, suite green). Josh: "we will end up
|
|
549
|
-
redoing all the work we have currently done given that we now have a different
|
|
550
|
-
starting point." Deleted, one funeral each:
|
|
551
|
-
|
|
552
|
-
- `--fused-decode` / `MLX_BUN_FUSED_DECODE` — 1.00×, forced uncompiled decode,
|
|
553
|
-
a silent-wrongness footgun.
|
|
554
|
-
- `--fused-gelu` / `MLX_BUN_FUSED_GELU` and `MLX_BUN_FUSED_SWIGLU` (+
|
|
555
|
-
`fused-mlp-kernel.ts`, `steel-linear-kernel.ts`, the swiglu/geglu/steel
|
|
556
|
-
one-off scripts) — +0–1%; the compiled closures already own the fusion win
|
|
557
|
-
bit-exactly.
|
|
558
|
-
- `--perf-kernel` / `MLX_BUN_PERF_KERNEL` (the fused online-softmax decode
|
|
559
|
-
SDPA) with its frozen-oracle scaffolding (`perf-kernel-oracle.test.ts`,
|
|
560
|
-
`freeze-perf-oracle.ts`) — regressed e4b in the paired A/B; its one win
|
|
561
|
-
carried a KL WARN. Its earlier placement in the L2 preset (commit `f1bf5cc`)
|
|
562
|
-
had claimed a bit-exact optiq oracle; the golden was frozen from mlx-bun's
|
|
563
|
-
own engine and the gate was argmax agreement, so 2026-07-01 had already
|
|
564
|
-
restored the rule that the bare tier is the guarantee.
|
|
565
|
-
- `MLX_BUN_CPM5_FAITHFUL` + `FaithfulMiniCPM5` (`minicpm5-faithful.ts`) — the
|
|
566
|
-
default IS the faithful path; the op-for-op A/B reference served its purpose
|
|
567
|
-
(it is how the unfused-swiglu dispatch tax was found).
|
|
568
|
-
- `--l3` as a product mode — the Lab replaces it; the flag hard-errors.
|
|
569
|
-
- Training-side flag sanitization (`MLX_BUN_PERF_KERNEL=0` /
|
|
570
|
-
`MLX_BUN_FUSED_GELU=0` in trainers, launchers, recipes) — obsolete.
|
|
571
|
-
|
|
572
|
-
**2026-07-05 — engine unification** (Phases 0–3.2 of the original migration
|
|
573
|
-
plan; numbers in PLAN.md): the B=1 batch-lane gap measured, root-caused to the
|
|
574
|
-
two host bugs in §8, closed; batched mixed-KV for full-attention and rotating
|
|
575
|
-
layers; adopt-don't-copy + compiled decode at B=1 + prompt cache on the batch
|
|
576
|
-
lane; SSD tier moved inside `PromptCache.take()`; non-consuming prefix sharing;
|
|
577
|
-
`--isolate` P1 (proxy) and P2 (`ModelPool`, multi-model switching); `--batch`
|
|
578
|
-
default 8.
|
|
579
|
-
|
|
580
|
-
**2026-08-21 — serving architecture consolidation S0–S3** (live in PLAN.md):
|
|
581
|
-
`PreparedCompletion` + `CompletionExecutor` (S0), immutable
|
|
582
|
-
`GenerationPlacement` (S1), declared model profiles (S2), `serial | continuous`
|
|
583
|
-
as the placement vocabulary with the scheduler's B=1 fast path as the default
|
|
584
|
-
lone-request route (S3). S4 (land + post-merge verify) is the open box.
|
|
585
|
-
|
|
586
|
-
## 12. Interface-based engine refactor
|
|
587
|
-
|
|
588
|
-
Design requested 2026-09-04. Initial implementation is recorded in §12.13. The R0–R10
|
|
589
|
-
checkboxes live in PLAN.md under "Interface-based engine refactor". This
|
|
590
|
-
section owns the contracts, migration details, and acceptance criteria.
|
|
591
|
-
|
|
592
|
-
### 12.1 Outcome and scope
|
|
593
|
-
|
|
594
|
-
The product objective is to push the Pareto frontier of **speed, quality, and
|
|
595
|
-
size for local AI on a Mac**. Josh's goal is that a user sees the result and
|
|
596
|
-
asks how that quality, performance, and model size are possible on their
|
|
597
|
-
laptop. Interface consistency is useful when it makes those gains easier to
|
|
598
|
-
build, compare, compose, and ship. It is not an independent reason to accept
|
|
599
|
-
slower execution or a larger working set.
|
|
600
|
-
|
|
601
|
-
The current target is **Josh's designated Qwen3.8-27B quants**. They are on a
|
|
602
|
-
drive unavailable to this session. Artifact access is needed for target-specific
|
|
603
|
-
numerical and performance validation; it does not block the refactor.
|
|
604
|
-
The locally cached published flagship and TQ snapshots are not those targets
|
|
605
|
-
(Josh clarified this on 2026-09-04); availability must not select the product
|
|
606
|
-
baseline. Quant recipes and quality findings remain in [TurboQuant](turboquant.md),
|
|
607
|
-
including rejected variants and raw-EOS regressions. Interfaces must preserve
|
|
608
|
-
exact packing, rotation, per-layer precision, recurrent-state, and kernel
|
|
609
|
-
choices. Other artifacts/families provide compatibility coverage only.
|
|
610
|
-
|
|
611
|
-
A downloaded quant supplies weights, configuration, and tokenizer data. The
|
|
612
|
-
engine owns the hyperoptimized implementations and the rules for identifying
|
|
613
|
-
which quant each one supports. Resolve artifact identity and configuration at
|
|
614
|
-
load time, select registered engine code, then retain that binding for execution.
|
|
615
|
-
The quant does not supply a graph, kernel, method, plugin, or executable manifest.
|
|
616
|
-
An unknown artifact may use a compatible family implementation. An exact
|
|
617
|
-
declaration with missing code or incompatible configuration must fail explicitly.
|
|
618
|
-
Sessions remain independent of the selected implementation.
|
|
619
|
-
|
|
620
|
-
Aggressive specialization for a particular quantization is expected. A
|
|
621
|
-
quant-specific layout, graph, fused kernel, cache scheme, compiled schedule,
|
|
622
|
-
or complete execution method is a legitimate production implementation.
|
|
623
|
-
Several specialized implementations can be worth maintaining when each wins
|
|
624
|
-
in a useful regime. Shared orchestration must not force the fastest numerical
|
|
625
|
-
implementation through an inefficient generic operator path.
|
|
626
|
-
A model implementation may expose several supported execution methods. Loading
|
|
627
|
-
the weights does not permanently choose one method; request planning selects
|
|
628
|
-
among the compatible methods. Their private graphs, state and numerical loops
|
|
629
|
-
can differ while the session contract remains the same.
|
|
630
|
-
|
|
631
|
-
A session must work without knowing the model class, graph implementation,
|
|
632
|
-
decoding algorithm, cache layout, or scheduling mechanism. Every replaceable
|
|
633
|
-
component exposes an interface. Immutable configuration, events, and results
|
|
634
|
-
remain data records; implementations keep private helpers private.
|
|
635
|
-
|
|
636
|
-
There are three distinct replacement operations:
|
|
637
|
-
|
|
638
|
-
| Replacement | Integration change | What must remain compatible |
|
|
639
|
-
|---|---|---|
|
|
640
|
-
| Dedicated graph → generated, compiled, or quant-specialized graph | Replace one graph registration in a model bundle | Graph ABI, backend, input/output shapes, state ABI, numerical contract |
|
|
641
|
-
| Autoregressive → speculative or diffusion method | Select a method registration and its compatible graph bundle | Session lifecycle, committed-output events, cancellation, accounting |
|
|
642
|
-
| MLX implementation → another runtime | Register a complete backend bundle with its graphs, state, sampling, and resource services | Engine/session contracts; a numerical claim requires separate evidence |
|
|
643
|
-
|
|
644
|
-
The first operation must require no session, scheduler-policy, route, or
|
|
645
|
-
application changes. The second must require no method-specific session or
|
|
646
|
-
protocol branches. A different numerical runtime cannot reuse MLX tensor
|
|
647
|
-
handles merely because the TypeScript interface matches.
|
|
648
|
-
|
|
649
|
-
Preserve the existing APIs and numerical defaults during migration. A new
|
|
650
|
-
internal interface does not implicitly expand supported feature combinations.
|
|
651
|
-
Keep one repository and the single-binary distribution. Remote compute, new
|
|
652
|
-
model families, a universal tensor library, a generic graph compiler, and true
|
|
653
|
-
B-wide prefill are separate projects. Training gets its own task interface;
|
|
654
|
-
it does not pretend to be a text-generation session.
|
|
655
|
-
|
|
656
|
-
This scope boundary does not defer quant-specific optimization. The refactor
|
|
657
|
-
must accommodate the existing quantization campaign and future optimized
|
|
658
|
-
implementations throughout migration. New numerical work has separate paired
|
|
659
|
-
validation, so structural changes cannot conceal a quality or performance
|
|
660
|
-
tradeoff. §12.11 defines the shared frontier scorecard.
|
|
661
|
-
|
|
662
|
-
Package organization is now a planned decision in the
|
|
663
|
-
[public-readiness program](../../PLAN.md#public-readiness), separate from
|
|
664
|
-
the optimization campaign. §12.15 records the initial boundary audit and
|
|
665
|
-
remaining evidence needed before choosing a workspace layout. Preserve
|
|
666
|
-
in-process execution and the single-binary distribution; package boundaries
|
|
667
|
-
must follow ownership and dependency needs without adding decode overhead.
|
|
668
|
-
|
|
669
|
-
### 12.2 Dependency structure
|
|
670
|
-
|
|
671
|
-
```mermaid
|
|
672
|
-
flowchart TD
|
|
673
|
-
Apps["CLI / HTTP / Pi / memory / evaluation"] --> Client["CompletionClient and task interfaces"]
|
|
674
|
-
Client --> Prep["Prompt preparation and request planning"]
|
|
675
|
-
Prep --> Engine["InferenceEngine"]
|
|
676
|
-
Engine --> Session["GenerationSession lifecycle"]
|
|
677
|
-
Engine --> Schedule["Scheduler policy and resource admission"]
|
|
678
|
-
Session --> Method["InferenceMethod"]
|
|
679
|
-
Schedule --> Group["SchedulingAdapter / ExecutionGroup"]
|
|
680
|
-
Group --> Method
|
|
681
|
-
Method --> Graph["Graph interface"]
|
|
682
|
-
Method --> State["State and checkpoint interfaces"]
|
|
683
|
-
Method --> Sample["Sampling / constraints / draft interfaces"]
|
|
684
|
-
Graph --> Backend["Backend runtime and resource leases"]
|
|
685
|
-
State --> Backend
|
|
686
|
-
Sample --> Backend
|
|
687
|
-
Compose["Composition root and implementation registry"] -.-> Engine
|
|
688
|
-
Compose -.-> Method
|
|
689
|
-
Compose -.-> Graph
|
|
690
|
-
Compose -.-> Backend
|
|
691
|
-
```
|
|
692
|
-
|
|
693
|
-
Interfaces belong to the consumer's contract layer. Composition roots import
|
|
694
|
-
implementations and supply them explicitly. No service locator inside a token
|
|
695
|
-
loop, import-time self-registration, dependency injection framework, or
|
|
696
|
-
reflection-based constructor discovery is needed.
|
|
697
|
-
|
|
698
|
-
Proposed homes, introduced only as their migration phase lands:
|
|
699
|
-
|
|
700
|
-
| Home | Responsibility and permitted dependencies |
|
|
701
|
-
|---|---|
|
|
702
|
-
| `src/contracts/` | Portable requests, events, results, session/client/task interfaces. No Bun, DOM, MLX, concrete model, or application imports. |
|
|
703
|
-
| `src/engine/` | Session lifecycle, planner, scheduler policy, admission. Depends on contracts and injected ports. |
|
|
704
|
-
| `src/inference/` | Method and graph contracts; reusable AR orchestration, verification, and scheduling adapters. Tensor-facing code is parameterized by a backend binding. |
|
|
705
|
-
| `src/backends/mlx/` | MLX runtime, typed bindings, resource owners, execution groups, state adapters. Wrap existing numerics before relocating files. |
|
|
706
|
-
| `src/model/` | Existing model math behind graph adapters, artifact profiles, loaders. Concrete implementations may use MLX internally. |
|
|
707
|
-
| `src/serve/` | Protocol parsing/framing and transport; calls the completion client. No concrete graph selection or cache surgery. |
|
|
708
|
-
| `src/app/` | Composition roots, runtime bootstrap, server/application assembly. The intentional location for concrete imports. |
|
|
709
|
-
| Existing application directories | Memory, Pi, web, eval, train, quantize consume their declared client/task ports. Move root modules only when their dependencies have been separated. |
|
|
710
|
-
|
|
711
|
-
Use TypeScript projects plus an AST/import-resolution boundary check. The check
|
|
712
|
-
must follow type-only imports, re-exports, aliases, and literal dynamic imports.
|
|
713
|
-
New forbidden edges fail; temporary legacy edges have a named R-phase owner and
|
|
714
|
-
a deletion gate. Browser contracts cannot import declarations out of pi-web.ts.
|
|
715
|
-
No new concrete model checks in engine/session/planner code. Model-specific
|
|
716
|
-
checks remain legitimate inside the model's own adapter.
|
|
717
|
-
|
|
718
|
-
### 12.3 Interface inventory
|
|
719
|
-
|
|
720
|
-
These are responsibility boundaries, not a mandate for one class per row.
|
|
721
|
-
Small stateless ports may be implemented by functions or object literals.
|
|
722
|
-
|
|
723
|
-
| Interface | Owns | Must not own |
|
|
724
|
-
|---|---|---|
|
|
725
|
-
| `CompletionClient` | Semantic completion request, event stream, terminal result, cancellation | Tensor/state handles, model class selection |
|
|
726
|
-
| `PromptPreparer` | Coordinate renderer, tokenizer and media preparation; produce token IDs and a stable-prefix boundary | Template syntax, tokenizer algorithms, GPU scheduling or request-global model mutation |
|
|
727
|
-
| `RequestPolicyResolver` | Resolve defaults and explicit overrides once into immutable policy | Executing model work or resampling defaults inside a token loop |
|
|
728
|
-
| `ChatTemplateRenderer` | Render messages, tools and reasoning markers; identify stable rendered boundaries | Tokenizer algorithms, scheduling or cache retention |
|
|
729
|
-
| `Tokenizer` | Encode/decode, token metadata and incremental encoding | Chat-template policy, sampling or scheduling |
|
|
730
|
-
| `ExecutionPlanner` | Effective immutable policy, implementation selection, capability negotiation, declared implementation choices, plan identity | Starting generation or inventing new feature support |
|
|
731
|
-
| `InferenceEngine` | Session creation, runtime coordination, shutdown | Per-family forward math |
|
|
732
|
-
| `GenerationSession` | Lifecycle, committed output, result, cancellation and close | Token-at-a-time assumption, KV offsets, concrete method branches |
|
|
733
|
-
| `InferenceMethod` | AR/speculative/diffusion algorithm and private per-run state | HTTP framing or application sessions |
|
|
734
|
-
| `SchedulingAdapter` / `ExecutionGroup` | Method-specific join/leave and bounded execution work | Queue priority policy or independent memory admission |
|
|
735
|
-
| `Scheduler` | Fairness, active-row cap, queue limits, safe-point dispatch | Cache merge math, sampler math, model-family checks |
|
|
736
|
-
| `ModelBundle` / `GraphFactory` | Artifact construction, graph selection, compatible backend/state services | Rewriting requested sampling or KV policy |
|
|
737
|
-
| `AutoregressiveGraph` | Forward-to-hidden and selective logits projection | Token selection, prefill loop, stopping, persistence |
|
|
738
|
-
| `DenoisingGraph` | Canvas/noise-step operations required by diffusion | Pretend AR cache or fake next-token API |
|
|
739
|
-
| `SpecializedExecutionFactory` | Quant/artifact/device-specific fused execution behind the same method/group contract | Changing quality policy or observable session semantics without a declared plan |
|
|
740
|
-
| `SamplingPolicy` / `SamplingKernel` | Shared processor/mask/logprob/sample/history semantics and backend execution | Transport, independent request defaults |
|
|
741
|
-
| `ConstraintProvider` / `DraftProvider` | Per-run constraint state or proposals under declared capabilities | Mutating target model fields outside a bound context |
|
|
742
|
-
| `StateFactory` and capability facets | Owned state, borrowing, snapshots, batch operations, rollback where supported | Assuming every state is trimmable token KV |
|
|
743
|
-
| `PrefixStore` / `CheckpointStore` | Lookup, retention, integrity, atomic persistence and version checks | Reconstructing arbitrary concrete cache classes itself |
|
|
744
|
-
| `ResourceManager` / `ResourceLease` | Reservations, backing memory lifetime, device completion, release | Model math or hiding synchronization |
|
|
745
|
-
| `ArtifactResolver` / `TokenizerProvider` | Pinned artifact identity, tokenizer/template provenance and loading | Request execution |
|
|
746
|
-
| `TelemetrySink` / `Clock` | Structured observations and time | Scheduling or output decisions |
|
|
747
|
-
| `EngineHost` / `TaskRunner` | Direct or isolated runtime lifecycle; train/quantize task execution | Sending live tensor handles across a process boundary |
|
|
748
|
-
|
|
749
|
-
Existing `CompletionExecutor`, `CompletionSink`, `DraftProvider`, `DraftSource`,
|
|
750
|
-
model profiles, `KvScheme`, and the cache codec table are starting points.
|
|
751
|
-
Adapt or evolve them; do not retain a second permanent wrapper hierarchy.
|
|
752
|
-
|
|
753
|
-
### 12.4 Session and graph contracts
|
|
754
|
-
|
|
755
|
-
Illustrative signatures below fix the intended separation. Supporting record
|
|
756
|
-
types are specified by the semantics in this section and finalized in R1.
|
|
757
|
-
They are not implemented public exports yet.
|
|
758
|
-
|
|
759
|
-
```ts
|
|
760
|
-
interface InferenceEngine {
|
|
761
|
-
open(request: GenerationRequest, control: RunControl): Promise<GenerationSession>;
|
|
762
|
-
close(): Promise<void>;
|
|
763
|
-
}
|
|
764
|
-
|
|
765
|
-
interface GenerationSession {
|
|
766
|
-
readonly id: string;
|
|
767
|
-
readonly events: AsyncIterable<GenerationEvent>;
|
|
768
|
-
readonly result: Promise<GenerationOutcome>;
|
|
769
|
-
cancel(reason: CancelReason): Promise<void>;
|
|
770
|
-
close(): Promise<void>;
|
|
771
|
-
}
|
|
772
|
-
|
|
773
|
-
type GenerationEvent =
|
|
774
|
-
| { type: "committed"; sequence: number; tokenIds: readonly number[] }
|
|
775
|
-
| { type: "progress"; usage: UsageSnapshot };
|
|
776
|
-
|
|
777
|
-
interface InferenceMethod<Binding> {
|
|
778
|
-
readonly descriptor: MethodDescriptor;
|
|
779
|
-
createRun(plan: ExecutionPlan, binding: Binding): Promise<MethodRun<Binding>>;
|
|
780
|
-
}
|
|
781
|
-
|
|
782
|
-
// Tensor-facing contracts exist only inside a compatible backend bundle.
|
|
783
|
-
interface AutoregressiveGraph<Tensor, State, Inputs> {
|
|
784
|
-
readonly descriptor: GraphDescriptor;
|
|
785
|
-
forwardHidden(inputs: Inputs, state: State): Tensor;
|
|
786
|
-
projectLogits(hidden: Tensor, selection: LogitSelection): Tensor;
|
|
787
|
-
}
|
|
788
|
-
|
|
789
|
-
interface GraphFactory<Graph, Binding> {
|
|
790
|
-
readonly descriptor: GraphDescriptor;
|
|
791
|
-
open(artifact: ResolvedArtifact, binding: Binding): Promise<Graph>;
|
|
792
|
-
}
|
|
793
|
-
```
|
|
794
|
-
|
|
795
|
-
`GenerationSession` is one completion attempt, distinct from a Pi conversation
|
|
796
|
-
or application thread. The engine coordinates independent sessions sharing a
|
|
797
|
-
resident model. The method's private run owns prompt position, sampler history,
|
|
798
|
-
pending device work, and caches/canvas; those do not become session fields.
|
|
799
|
-
`RunControl` uses a portable cancellation port; HTTP adapters translate their
|
|
800
|
-
AbortSignal into it. Contract declarations do not pull in browser/server modules.
|
|
801
|
-
|
|
802
|
-
All methods publish only irrevocably committed token spans. A span can contain
|
|
803
|
-
one token, an accepted speculative group, or a whole completed diffusion
|
|
804
|
-
result. Tentative diffusion canvas revisions and rejected draft tokens are
|
|
805
|
-
private. A non-streaming method may publish nothing until its final output.
|
|
806
|
-
The existing completion sink converts committed tokens to semantic text,
|
|
807
|
-
reasoning, tools, stops, and protocol usage. Tokenizer identity is fixed at
|
|
808
|
-
session open. Task types that cannot provide this token contract use a separate
|
|
809
|
-
task interface rather than fabricated tokens or usage.
|
|
810
|
-
|
|
811
|
-
Lifecycle is `created → preparing → queued → running → settling → terminal`.
|
|
812
|
-
Terminal outcome is exactly one of completed, cancelled, or failed. Each state
|
|
813
|
-
accepts cancellation. Early iterator return initiates cancellation. Only one
|
|
814
|
-
consumer may read events; progress observation cannot steal output. A bounded
|
|
815
|
-
queue propagates backpressure to scheduling between safe work units. Never
|
|
816
|
-
silently drop output or let a slow consumer retain unlimited device state.
|
|
817
|
-
|
|
818
|
-
`result` settles once on every path, including no consumer, worker death,
|
|
819
|
-
preparation failure, and cancellation. It contains a discriminated outcome
|
|
820
|
-
with final usage/error data. Events already emitted remain a partial result
|
|
821
|
-
on failure. GenerationRequest declares streaming or collecting consumption at
|
|
822
|
-
open. Streaming starts on demand and has a configured idle-consumer deadline;
|
|
823
|
-
an abandoned/unread stream cancels when that deadline expires. Collecting runs
|
|
824
|
-
without an event reader, reserves output storage against the admitted maximum,
|
|
825
|
-
and returns collected tokens with the outcome. Insufficient collection capacity
|
|
826
|
-
fails admission; it never silently truncates output. R1 fixes the queue/deadline
|
|
827
|
-
defaults with tests. Completed sessions reject further advancement;
|
|
828
|
-
cancel/close are idempotent. Close cancels live work and awaits safe release.
|
|
829
|
-
|
|
830
|
-
Graph calls remain direct device operations. The interface does not insert
|
|
831
|
-
an await, readback, tensor wrapper, or synchronization for each operator.
|
|
832
|
-
`forwardHidden` plus selective `projectLogits` preserves the existing ability
|
|
833
|
-
to avoid a full prompt-length × vocabulary logits allocation. Compile caches
|
|
834
|
-
belong to the implementation and key on the graph/state/request parameters
|
|
835
|
-
that affect their trace. A graph factory owns and closes resident weights;
|
|
836
|
-
individual runs borrow them through leases.
|
|
837
|
-
|
|
838
|
-
The selective-hidden/logits interface is the reusable AR path. A specialization
|
|
839
|
-
may instead implement a coarse execution contract that fuses graph, head,
|
|
840
|
-
sampling, or state updates and never materializes those intermediate tensors.
|
|
841
|
-
It must preserve the declared sampler/constraint semantics, accounting, safe
|
|
842
|
-
points, and resource ownership, and pass the same conformance suite. Do not
|
|
843
|
-
require a fused kernel to synthesize hidden/logits objects solely to satisfy
|
|
844
|
-
an abstraction. The planner binds this alternative once through the registry;
|
|
845
|
-
the session and scheduler policy remain unchanged.
|
|
846
|
-
|
|
847
|
-
R1 must specify graph ABI dimensions, dtypes, mutation rules, position/mask
|
|
848
|
-
inputs, output ownership, and evaluation semantics. Include media inputs,
|
|
849
|
-
hidden taps, and adapter bindings as typed graph capabilities. Move mRoPE,
|
|
850
|
-
adapter selection, and hidden taps out of mutable model-global request fields
|
|
851
|
-
into bound per-run contexts. While legacy models still mutate those fields,
|
|
852
|
-
their adapter requires the exclusive lease and restores them on every exit.
|
|
853
|
-
|
|
854
|
-
The registration bundle binds graph, tensor type, state factory, sampler,
|
|
855
|
-
device runtime, and optional capabilities together. Use generics and opaque
|
|
856
|
-
handles internally; do not erase them with `any` or public casts. Validate
|
|
857
|
-
backend ID, state ABI, graph ABI, and artifact identity at construction and
|
|
858
|
-
restore. TypeScript compatibility alone does not establish numerical parity.
|
|
859
|
-
|
|
860
|
-
Specialization keys may include exact artifact fingerprint, weight quant/layout
|
|
861
|
-
and packing version, layer/shape geometry, KV scheme, Mac GPU capabilities,
|
|
862
|
-
context regime, and batch regime. Dispatch is planned or bound at a safe shape
|
|
863
|
-
transition, with a validated compatible fallback outside the optimized range.
|
|
864
|
-
It must not become a collection of per-token environment checks. Fused paths
|
|
865
|
-
may retain optional features only when implemented; capability negotiation
|
|
866
|
-
selects another faithful implementation when the requested composition needs it.
|
|
867
|
-
|
|
868
|
-
### 12.5 Capability negotiation and planning
|
|
869
|
-
|
|
870
|
-
Replace scattered feature booleans with versioned capability descriptors and
|
|
871
|
-
typed capability interfaces. Obtain a complete optional facet once during
|
|
872
|
-
planning, such as rollback or batch join. The core never probes a handful of
|
|
873
|
-
optional methods and hopes they form a complete implementation.
|
|
874
|
-
|
|
875
|
-
Evaluate the whole composition: artifact/profile, graph, method, KV scheme,
|
|
876
|
-
sampler, seed, constraints, adapters, media, checkpointing, and batching.
|
|
877
|
-
Two independently supported features do not prove their combination works.
|
|
878
|
-
Each supported composition links to its conformance/oracle test cell.
|
|
879
|
-
|
|
880
|
-
Within a compatible composition, selection may use a measured execution recipe
|
|
881
|
-
for the artifact/quant/device/workload. A recipe binds the entire implementation
|
|
882
|
-
bundle, its quality contract, and resource model. It can choose a quant-specific
|
|
883
|
-
fused method rather than a generic graph. Record provenance and the evidence
|
|
884
|
-
behind automatic selection. Never optimize by changing the requested artifact,
|
|
885
|
-
quant, or quality tier without an explicitly permitted product policy.
|
|
886
|
-
|
|
887
|
-
Planning returns supported, refused, or an explicit policy-permitted fallback
|
|
888
|
-
with reasons. Distinguish required request behavior from preferred acceleration.
|
|
889
|
-
Retain existing intentional fallback behavior during migration and record it
|
|
890
|
-
in the plan. Never silently change a required scheme, constraint, seed, or
|
|
891
|
-
adapter to gain batching. Preserving existing support also means retaining
|
|
892
|
-
explicit refusals. Fallback ordering is deterministic and tested.
|
|
893
|
-
|
|
894
|
-
The plan contains artifact and tokenizer identities, implementation IDs/ABIs,
|
|
895
|
-
oracle tier, actual algorithm, resolved sampling/stop policy, state layout,
|
|
896
|
-
cache/checkpoint policy, resource estimates, and allowed execution shapes.
|
|
897
|
-
Dynamic batch membership is runtime state within those allowed shapes. Record
|
|
898
|
-
it in traces; do not freeze a future arrival schedule into admission.
|
|
899
|
-
|
|
900
|
-
Normalize environment/CLI/request configuration at the boundary. Capture an
|
|
901
|
-
immutable effective snapshot per engine/run. No runtime configuration lookups
|
|
902
|
-
inside forward/decode after binding. Experiment commands construct separate
|
|
903
|
-
bindings with explicit snapshots. Diagnostics may observe a running request
|
|
904
|
-
but cannot change its numeric policy halfway through execution.
|
|
905
|
-
|
|
906
|
-
Configuration follows ownership: scheduling owns concurrency and queue policy;
|
|
907
|
-
methods own sampling, speculation and stopping; backends own kernels and state
|
|
908
|
-
layouts; storage owns cache budgets, tiers and persistence. The application
|
|
909
|
-
composition root binds these interfaces. A single-request caller supplies the
|
|
910
|
-
same method configuration as a batched caller. Consolidate duplicate controls
|
|
911
|
-
as implementations migrate, retaining documented CLI aliases where needed.
|
|
912
|
-
|
|
913
|
-
Default memory estimates are advisory by Josh's instruction. Attempt the
|
|
914
|
-
requested work without predicted-memory refusals or automatic token clamping.
|
|
915
|
-
Explicit user limits and actual layout requirements still apply. Account for
|
|
916
|
-
shared weights once, live state, draft resources, preparation transients and
|
|
917
|
-
retained/write-behind buffers. Release actual resources on failure; a
|
|
918
|
-
conservative estimate does not establish that execution is impossible. This
|
|
919
|
-
supersedes the earlier mandatory reservation-before-preparation design.
|
|
920
|
-
|
|
921
|
-
### 12.6 State, ownership, and persistence
|
|
922
|
-
|
|
923
|
-
Resource rules apply to success, partial construction, eviction, cancellation,
|
|
924
|
-
rollback, shutdown, and native failure:
|
|
925
|
-
|
|
926
|
-
- A resource has one owner, with explicit borrowed views or retained leases.
|
|
927
|
-
Ownership transfer is a checked operation; a resource cannot be disposed by
|
|
928
|
-
both the old and new owner. Close is idempotent and attempts every release
|
|
929
|
-
even if one cleanup fails, preserving the original execution error.
|
|
930
|
-
- Device handles and host/mmap backing memory have distinct lifetimes. A native
|
|
931
|
-
completion fence governs final backing release. JS scope exit or array
|
|
932
|
-
disposal alone is insufficient. Never restore a JS callback destructor on
|
|
933
|
-
a Metal completion thread. Finalization remains a diagnostic/backstop.
|
|
934
|
-
- Replace `stateNeedsDispose` with an explicit owned state-view lease. Snapshot
|
|
935
|
-
creation returns a stable owner; later writes to the donor cannot change it.
|
|
936
|
-
Prefix lookup returns retained state and its exact logical coverage.
|
|
937
|
-
- State capability facets include snapshot, prefix reuse, trimming, batch
|
|
938
|
-
merge/extract/filter, and speculative transaction. Recurrent state supports
|
|
939
|
-
exact restore/replay where proven; diffusion state can expose a different
|
|
940
|
-
snapshot without claiming a token prefix or trim operation.
|
|
941
|
-
- A speculative transaction includes every participating layer and draft-side
|
|
942
|
-
state. Commit or rollback leaves one consistent accepted prefix. Partial
|
|
943
|
-
failure invalidates the run; it cannot return uncertain state to PrefixStore.
|
|
944
|
-
- Storage policy is separate from layout codecs. Provider-owned codecs bind
|
|
945
|
-
formats to a compatible implementation. Keep streamed tensor writes,
|
|
946
|
-
corruption checks, atomic publication, byte caps, and bounded spill queues.
|
|
947
|
-
Do not replace the current copy-restore with unsafe mmap borrowing for style.
|
|
948
|
-
|
|
949
|
-
Prefix identity and generation-resume identity are separate records. Prefix
|
|
950
|
-
identity covers artifact content, tokenizer/template interpretation, adapters
|
|
951
|
-
and their revisions, effective numeric scheme, graph/state compatibility, and
|
|
952
|
-
media content when reuse is supported. Generation identity additionally covers
|
|
953
|
-
the complete normalized request, stop strings, sampling/seed policy, method,
|
|
954
|
-
constraints, generation limit, and resume schema. Canonicalize map keys while
|
|
955
|
-
preserving semantically ordered arrays. Store the descriptor as well as its
|
|
956
|
-
digest, and validate it on restore.
|
|
957
|
-
|
|
958
|
-
A resume snapshot includes consumed input coverage, committed completion count,
|
|
959
|
-
pending token/device work in a restorable form, RNG/history position, and any
|
|
960
|
-
method/constraint state needed for exact continuation. Physical cache offset,
|
|
961
|
-
committed output, and bytes delivered to a client are different quantities.
|
|
962
|
-
Snapshots are legal only at declared safe points. Unsupported exact-resume
|
|
963
|
-
compositions remain refused or disabled as documented.
|
|
964
|
-
|
|
965
|
-
Retries must distinguish a new generation from a resumed attempt. Preserve the
|
|
966
|
-
current replay contract through its compatibility adapter; explicitly design
|
|
967
|
-
any future idempotency/resume field before changing the public API. Never claim
|
|
968
|
-
exactly-once delivery across a broken stream or automatically replay tool side
|
|
969
|
-
effects. Cold-prefix misses may recompute; an incompatible exact-resume request
|
|
970
|
-
must report the mismatch rather than invent a continuation. Version the format
|
|
971
|
-
and define read-old/write-new compatibility or explicit invalidation per change.
|
|
972
|
-
|
|
973
|
-
### 12.7 Scheduling and inference methods
|
|
974
|
-
|
|
975
|
-
Keep policy independent from mechanics. Scheduler chooses eligible work,
|
|
976
|
-
fairness, queue bounds and active-row limits. A method's
|
|
977
|
-
scheduling adapter creates execution groups and implements join/leave/advance
|
|
978
|
-
over its own state. Native batch merge and filter stay inside the MLX adapter.
|
|
979
|
-
Scheduler must not import KV classes or perform a per-layer tensor loop.
|
|
980
|
-
|
|
981
|
-
The consolidation target is single-request execution as a batch of one through
|
|
982
|
-
these same contracts. Methods publish reusable checkpoints through the shared
|
|
983
|
-
cache interface at completed boundaries. The cache owns prefix selection,
|
|
984
|
-
retention and RAM/SSD placement; scheduling does not choose a storage tier, and
|
|
985
|
-
decode does not inspect the request queue. Model/method codecs describe the
|
|
986
|
-
state needed to restore a prefix, including draft state when applicable.
|
|
987
|
-
Prefill and generated tokens populate the same cache. R17 in the decode-speed
|
|
988
|
-
program owns the current implementation and acceptance work.
|
|
989
|
-
|
|
990
|
-
Full batch feature parity is required, including speculation. The current
|
|
991
|
-
serial exclusions are migration work, not the target architecture. Keep an
|
|
992
|
-
explicit feature matrix in the batching design and retire duplicate request
|
|
993
|
-
lifecycles only after the batched implementation covers every serial feature
|
|
994
|
-
and equals or beats serial performance in matched measurements. B=1 latency
|
|
995
|
-
and feature-specific costs must pass independently of aggregate throughput.
|
|
996
|
-
The optimized kernels already built remain behind the backend interface;
|
|
997
|
-
scheduling policy does not choose or reimplement their arithmetic. Continue
|
|
998
|
-
building faster specializations, fusing operations, removing work and avoiding
|
|
999
|
-
materialization. Interfaces must permit complete fused work units rather than
|
|
1000
|
-
force one call or intermediate tensor per logical operation. Measure kernel
|
|
1001
|
-
changes separately from composition refactors so their effects are attributable. Interface
|
|
1002
|
-
extraction must not force tensor copies, materialization, synchronization or
|
|
1003
|
-
additional dispatches; compare B=1 latency and B>1 throughput at fixed settings.
|
|
1004
|
-
|
|
1005
|
-
An advancement is a bounded safe unit, not necessarily a token: one prefill
|
|
1006
|
-
chunk, a pipelined decode step, one verify round, or one denoising iteration.
|
|
1007
|
-
Budgets describe admitted resources and work hints separately. A synchronous
|
|
1008
|
-
kernel cannot be interrupted; cancellation is honored at the next safe point.
|
|
1009
|
-
Keep pending MLX work between advancements to preserve decode overlap. No
|
|
1010
|
-
mandatory GPU synchronize or full logits readback at the scheduling boundary.
|
|
1011
|
-
|
|
1012
|
-
An execution group owns its resident run handles exclusively. Join/leave
|
|
1013
|
-
validates compatibility before state mutation. Group-wide failure either
|
|
1014
|
-
proves unaffected rows safe or fails the entire group; it cannot publish
|
|
1015
|
-
possibly corrupted snapshots. Slow readers stop receiving dispatch while their
|
|
1016
|
-
reservations remain accounted for; cancellation releases them after pending
|
|
1017
|
-
device work is safe. Queued cancellation removes the waiter promptly so a dead
|
|
1018
|
-
serial request cannot keep batch admission in drain mode.
|
|
1019
|
-
|
|
1020
|
-
Migrate these existing algorithms behind the contracts:
|
|
1021
|
-
|
|
1022
|
-
| Method/component | Preserved behavior |
|
|
1023
|
-
|---|---|
|
|
1024
|
-
| AR method | Shared prefill program, existing tail split/snapshot boundaries, sampler order, pending-token pipeline |
|
|
1025
|
-
| Speculative method | Existing verifier and DraftSource variants, actual proposal length, target taps, per-step RNG, recurrent rollback, source-specific prefill convention |
|
|
1026
|
-
| Fill/grammar acceleration | Explicit assert/verify proposal policy and constraint state; preserve current exclusions and fidelity gates |
|
|
1027
|
-
| Diffusion method | Existing denoising behavior with private canvas state and committed output only; no fabricated AR state |
|
|
1028
|
-
| Continuous execution adapter | B=1 adopted-cache path; existing merge/extract/filter operations and per-row sampler history |
|
|
1029
|
-
| Quant-specific execution | Fused or precompiled work units with the same observable semantics and explicit numerical tier; no forced intermediate allocations |
|
|
1030
|
-
|
|
1031
|
-
Shared AR prefill does not imply full-prompt forwarding for every method.
|
|
1032
|
-
Native GLM MTP already declares a different prefill convention. Preserve it as
|
|
1033
|
-
data in the method plan. Likewise, unifying solo prefill code does not establish
|
|
1034
|
-
bit identity with B-wide prefill or broaden the batch support matrix.
|
|
1035
|
-
|
|
1036
|
-
The shared prefill program is the canonical policy for segmentation, snapshots,
|
|
1037
|
-
and cancellation. A measured specialization can execute that program through
|
|
1038
|
-
a different kernel schedule while satisfying its numerical and resource
|
|
1039
|
-
contract. Share the decisions; do not prohibit a faster executor merely because
|
|
1040
|
-
its implementation cannot reuse a helper function.
|
|
1041
|
-
|
|
1042
|
-
### 12.8 Applications, library, and process boundaries
|
|
1043
|
-
|
|
1044
|
-
Keep the existing token-to-semantic completion pipeline. `CompletionClient`
|
|
1045
|
-
is the application/transport boundary; `GenerationSession` is the worker's
|
|
1046
|
-
method-neutral token boundary. An ordinary OpenAI-compatible remote endpoint
|
|
1047
|
-
can implement CompletionClient without exposing token IDs or local checkpoints.
|
|
1048
|
-
It cannot masquerade as a fully capable local GenerationSession.
|
|
1049
|
-
|
|
1050
|
-
Provide direct and isolated CompletionClient/EngineHost implementations. Evolve
|
|
1051
|
-
the existing `src/serve/isolate.ts` EngineChild, ModelPool, health gating,
|
|
1052
|
-
restart policy, and HTTP-over-Unix-socket proxy. Isolation already exists.
|
|
1053
|
-
Do not build a competing supervisor or change the wire protocol merely to
|
|
1054
|
-
match internal interfaces. Current whole-server isolation remains supported
|
|
1055
|
-
while CPU application services are separated from worker-owned compute.
|
|
1056
|
-
|
|
1057
|
-
Worker requests contain portable policy and media descriptors/bytes. Grammar
|
|
1058
|
-
controllers, media tensors, sampler closures, state handles, and device leases
|
|
1059
|
-
are created in the worker. A crash fails in-flight completion attempts, resets
|
|
1060
|
-
worker-owned residency, and preserves parent health/application state. Existing
|
|
1061
|
-
GET/HEAD retry behavior does not authorize automatic generation POST replay.
|
|
1062
|
-
Cross-process resume requires the explicit checkpoint/replay contract above.
|
|
1063
|
-
|
|
1064
|
-
One resource coordinator covers inference and managed training/quantization
|
|
1065
|
-
jobs that share a runtime host. Preserve the existing jobs subprocess design
|
|
1066
|
-
and persist terminal job state. Do not describe this coordinator as controlling
|
|
1067
|
-
unrelated external Python processes or a separately launched training run.
|
|
1068
|
-
|
|
1069
|
-
The high-level library opens a runtime asynchronously before importing/loading
|
|
1070
|
-
native implementations. Root high-level imports must work without installed
|
|
1071
|
-
MLX. Keep advanced native/model access in explicit low-level exports with clear
|
|
1072
|
-
ownership and bootstrap requirements. Compatibility wrappers preserve current
|
|
1073
|
-
exports until a deliberate versioned removal; they may not maintain duplicate
|
|
1074
|
-
generation loops. Validate the packaged binary and native sidecars, not only
|
|
1075
|
-
source execution, before release.
|
|
1076
|
-
|
|
1077
|
-
### 12.9 Current-to-target migration map
|
|
1078
|
-
|
|
1079
|
-
| Current code | Target and removal condition |
|
|
1080
|
-
|---|---|
|
|
1081
|
-
| `src/server.ts` runGeneration | Method/cache orchestration moves to inference/engine services; server retains composition and route dispatch |
|
|
1082
|
-
| `src/generate.ts` | Compatibility entry around the AR method/session; one shared prefill and pending-token implementation |
|
|
1083
|
-
| `src/serve/batch-scheduler.ts` | Split queue policy from MLX execution-group mechanics; delete duplicate prefill after parity gates |
|
|
1084
|
-
| `src/serve/generation-gateway.ts` | Planner plus scheduling/resource coordination; remove late feature eligibility and concrete model probes |
|
|
1085
|
-
| `src/serve/{request-plan,completion-executor,completion-sink}.ts` | Evolve into the request/session boundary and semantic adapter; retain tested accounting/framing behavior |
|
|
1086
|
-
| `src/model/{factory,profile}.ts` and concrete graph files | Model bundle registration and graph adapters; replace the central concrete RuntimeModel union in generic consumers |
|
|
1087
|
-
| `src/model/gemma4-base.ts` cache classes | Shared state contracts leave the Gemma module; implementations remain behind MLX state adapters until moved independently |
|
|
1088
|
-
| `src/{prompt-cache,kv-store,ssd-cache}.ts` | Prefix/checkpoint policies use provider codecs and explicit retained snapshots |
|
|
1089
|
-
| `src/{runtime-config,mlx/array,mlx/ffi}.ts` | Bound immutable configuration, explicit runtime opening, native resource owners |
|
|
1090
|
-
| `src/spec/` and `src/fill/` | Typed method/draft/constraint capabilities; existing algorithms and oracle fixtures retained |
|
|
1091
|
-
| `src/pi-web.ts`, Pi provider files, `src/web/src/` | Shared portable protocol declarations, client adapters, one provider-wiring implementation |
|
|
1092
|
-
| `src/memory/`, `src/eval/`, `src/train/`, `src/quantize/`, `src/jobs/` | Completion/task clients and explicit artifact/resource services; preserve task-specific semantics |
|
|
1093
|
-
| `src/serve/isolate.ts`, `src/index.ts`, `src/cli.ts` | Host/client adapters and composition roots; async high-level bootstrap and compatibility exports |
|
|
1094
|
-
|
|
1095
|
-
File moves follow responsibility extraction. Every temporary adapter has a
|
|
1096
|
-
deletion criterion. Do not combine renames, numerical rewrites, and protocol
|
|
1097
|
-
changes in one patch. Preserve failure reproduction fixtures through migration.
|
|
1098
|
-
|
|
1099
|
-
### 12.10 Implementation stages and dependencies
|
|
1100
|
-
|
|
1101
|
-
Each stage is one or more reviewable PRs. No calendar promise is made before R0
|
|
1102
|
-
establishes the fixture and machine prerequisites. Checkboxes are in PLAN.md.
|
|
1103
|
-
|
|
1104
|
-
**R0. Stabilize and record the baseline.** Pin the compiler and align local/CI
|
|
1105
|
-
typechecks. Reproduce and fix checkpoint stop-policy identity and serial
|
|
1106
|
-
cancellation with targeted tests. Diagnose the recorded Qwen cache-reuse crash
|
|
1107
|
-
before migrating its state implementation. Record exact revisions, existing
|
|
1108
|
-
support/refusal cells, public defaults, ABI/schema versions, and resource
|
|
1109
|
-
ownership. Capture quiet-machine baselines using existing bench tooling.
|
|
1110
|
-
Structural refactoring and model-free validation proceed while target artifacts,
|
|
1111
|
-
quiet hardware, or crash diagnosis are unavailable. Preserve existing numerical
|
|
1112
|
-
and state behavior; changing the affected state implementation or promoting a
|
|
1113
|
-
default still requires its relevant correctness and performance gates.
|
|
1114
|
-
Exit: fixes independently verified, baseline manifest available, missing
|
|
1115
|
-
machine/oracle cells explicitly listed. No unverified previous-review claim
|
|
1116
|
-
becomes a passing gate merely by entering this plan.
|
|
1117
|
-
|
|
1118
|
-
**R1. Land contracts and prove method independence.** Depends on R0's inventory.
|
|
1119
|
-
Create portable interfaces and dependency checks. Implement scripted AR-like
|
|
1120
|
-
and final-output-only fake methods with different private state. Run the exact
|
|
1121
|
-
same session lifecycle suite against both, including cancellation, failure,
|
|
1122
|
-
backpressure, no-consumer behavior, and close. Introduce a legacy adapter around
|
|
1123
|
-
the current executor so existing APIs still run. Exit: engine/session modules
|
|
1124
|
-
import no concrete graph/native module; switching fake methods edits registration
|
|
1125
|
-
only. Finalize the illustrative signatures through these executable contracts.
|
|
1126
|
-
|
|
1127
|
-
**R2. Bind real graphs and backend capabilities.** Depends on R1. Wrap existing
|
|
1128
|
-
models with GraphFactory/ModelBundle bindings, beginning with one dedicated
|
|
1129
|
-
graph and its existing generated counterpart. Bind sampler/state/runtime types,
|
|
1130
|
-
resource estimates, artifact profile, media inputs, taps, and adapter context.
|
|
1131
|
-
Exit: both real graphs run through the same method/session without consumer
|
|
1132
|
-
edits; direct forward logits match their pinned oracle; backend/state mismatch
|
|
1133
|
-
fails before allocation. Keep old models reachable through adapters until their
|
|
1134
|
-
family-specific tests have migrated.
|
|
1135
|
-
|
|
1136
|
-
Also adapt an existing quant-specific path through its bundle and verify that
|
|
1137
|
-
the interface adds no obligatory dequantization, tensor copy, intermediate
|
|
1138
|
-
allocation, or synchronization. Validate the coarse fused-execution contract
|
|
1139
|
-
before standardizing the reusable graph ABI.
|
|
1140
|
-
|
|
1141
|
-
**R3. Establish resource and state ownership.** Depends on R2 and the relevant
|
|
1142
|
-
R0 crash fix. Introduce explicit state views, retained snapshots, device-backed
|
|
1143
|
-
leases, and complete rollback facets. Evolve the codec table into provider-bound
|
|
1144
|
-
codecs. Validate prefix and resume identities, including stop policy and adapter
|
|
1145
|
-
revision. Exit: injected failures release all owners; donor/clone isolation,
|
|
1146
|
-
ring wrap, recurrent rollback, cold restore, and restart fixtures pass. No new
|
|
1147
|
-
GC-dependent lifetime or unsafe mmap release is accepted.
|
|
1148
|
-
|
|
1149
|
-
**R4. Resolve plans and reservations once.** Depends on R1–R3. Move speculation,
|
|
1150
|
-
fill, compilation, cache bypass, and capability selection into one planner.
|
|
1151
|
-
Use exact resolved plan data for execution, metrics, and checkpoint identity.
|
|
1152
|
-
Move native media/constraint allocation behind preparation admission. Capture
|
|
1153
|
-
configuration per binding. Exit: table-driven tests cover every shipped
|
|
1154
|
-
composition and refusal; lane reports agree before/after execution; engine code
|
|
1155
|
-
does not reread mutable global configuration. Existing fallbacks stay explicit.
|
|
1156
|
-
|
|
1157
|
-
**R5. Share AR prefill and session execution.** Depends on R2–R4. Extract a
|
|
1158
|
-
step-able prefill program preserving chunk/eval/quantization/snapshot/final-token
|
|
1159
|
-
order. Route serial execution and current solo batch-prefill through it. Move
|
|
1160
|
-
pending-token, history, and checkpoint-safe-point state into the AR method run.
|
|
1161
|
-
Thread cancellation through queue, preparation, prefill, and decode. Exit:
|
|
1162
|
-
duplicate prefill loops are removed, phase-specific abort tests release the
|
|
1163
|
-
lease, and cold/warm/restored logits plus streamed results match the baseline.
|
|
1164
|
-
This is the Maintainability prefill item; Phase 18 S1a remains separate.
|
|
1165
|
-
|
|
1166
|
-
**R6. Adapt other methods and extensions.** Depends on R3–R5. Move the existing
|
|
1167
|
-
speculative verifier and all retained DraftSource implementations behind typed
|
|
1168
|
-
target views. Adapt fill/grammar acceleration and diffusion without expanding
|
|
1169
|
-
their support. Exit: the same session suite passes for each; accepted/rejected
|
|
1170
|
-
trace, pending-token accounting, stop handling, and recurrent rollback match
|
|
1171
|
-
their method oracle. No session branch identifies AR/spec/diffusion by name.
|
|
1172
|
-
|
|
1173
|
-
**R7. Separate scheduler policy from batch execution.** Depends on R5–R6.
|
|
1174
|
-
Move merge/extract/filter and B=1 adoption into execution groups. Centralize
|
|
1175
|
-
fairness, drain policy, queue bounds, reservations, and cancellation. Exit:
|
|
1176
|
-
dynamic join/leave, uneven rows, slow consumers, group failure, mixed-KV,
|
|
1177
|
-
recurrent state, and ring-wrap cells pass wherever supported; unsupported
|
|
1178
|
-
compositions retain their recorded placement/refusal. Preserve pipeline overlap.
|
|
1179
|
-
Do not merge true B-wide prefill or new concurrency features into this stage.
|
|
1180
|
-
|
|
1181
|
-
**R8. Move applications onto client/task interfaces.** Depends on R1 and R4;
|
|
1182
|
-
runtime cutover follows R5–R7. Separate shared web/Pi protocol declarations,
|
|
1183
|
-
consolidate Pi provider configuration, and route memory/eval through clients.
|
|
1184
|
-
Train/quantize retain task ports and dedicated numerical graphs. Add async
|
|
1185
|
-
high-level library bootstrap and compatibility exports. Exit: CPU-only clients
|
|
1186
|
-
and high-level package imports need no MLX; API/CLI/UI fixtures preserve current
|
|
1187
|
-
behavior; task progress/cancellation and artifact semantics remain intact.
|
|
1188
|
-
|
|
1189
|
-
**R9. Adapt isolation and resource coordination.** Depends on R7–R8. Implement
|
|
1190
|
-
EngineHost over existing isolation/model-pool code, separate parent application
|
|
1191
|
-
state from worker compute, and coordinate managed GPU jobs. Exit: worker startup
|
|
1192
|
-
failure, death mid-stream, bounded restart, model eviction, disconnect, and
|
|
1193
|
-
shutdown tests pass; no automatic POST replay or native object serialization;
|
|
1194
|
-
direct/isolated clients share the semantic contract. Compare transport overhead
|
|
1195
|
-
before any default change. Existing `--isolate` behavior remains available.
|
|
1196
|
-
|
|
1197
|
-
**R10. Cut over, remove duplication, and close.** Depends on R0–R9. Default to
|
|
1198
|
-
the new engine only after the full supported matrix and performance gates pass.
|
|
1199
|
-
Delete legacy executor branches and temporary import exceptions. Review generated
|
|
1200
|
-
twins, diffusion, curve/HLG, expert offload, paged KV, DSpark variants, compiled
|
|
1201
|
-
decode, and Pi wiring using the existing D6 requirement: demonstrated use or
|
|
1202
|
-
measured value, otherwise an explicit deletion decision. Retained experiments
|
|
1203
|
-
register through declared interfaces. Update reference docs and package exports
|
|
1204
|
-
in the same change as any public difference. Exit: replacement exercise below
|
|
1205
|
-
passes, no duplicate engine remains, binary packaging works, and open-phase
|
|
1206
|
-
blocks close without archiving this still-canonical architecture document.
|
|
1207
|
-
|
|
1208
|
-
### 12.11 Validation and release gates
|
|
1209
|
-
|
|
1210
|
-
**Contract tests on every PR.** Run without native MLX: scripted alternate
|
|
1211
|
-
methods, lifecycle, ownership transfer, capability composition/refusal, stable
|
|
1212
|
-
identity, queue fairness, resource accounting, event ordering/backpressure,
|
|
1213
|
-
partial result/error behavior, and dependency boundaries. Add graph adapter
|
|
1214
|
-
type-tests that reject incompatible backend/state bindings. Existing protocol
|
|
1215
|
-
and UI tests remain their behavioral reference.
|
|
1216
|
-
|
|
1217
|
-
**Numerical and state matrix on available Apple Silicon machines.** Use the
|
|
1218
|
-
pinned oracle and existing machine-layered goldens. Cover dedicated/generated
|
|
1219
|
-
graphs, dense/MoE/recurrent/rotating state, bf16/uniform/mixed/TurboQuant where
|
|
1220
|
-
supported, cold/warm/SSD/resume, B=1 and matching-B concurrent composition,
|
|
1221
|
-
constraints, seeds, logprobs, adapters, media, speculation, and fill. Use targeted
|
|
1222
|
-
pairwise cases plus every known failure reproduction; do not imply every
|
|
1223
|
-
Cartesian combination is supported. Diffusion keeps its distinct oracle gate.
|
|
1224
|
-
Exact cells remain exact. Existing tolerance cells require their recorded
|
|
1225
|
-
justification; a refactor cannot loosen a gate to get green.
|
|
1226
|
-
|
|
1227
|
-
**Lifecycle sequences.** Exercise cancel before preparation, during admission,
|
|
1228
|
-
between prefill chunks, after dispatch but before readback, during verify, during
|
|
1229
|
-
checkpoint write, and on slow/broken streams. Check one terminal outcome and
|
|
1230
|
-
eventual reservation release after device completion. Restore-and-continue must
|
|
1231
|
-
equal uninterrupted execution for the exact supported resume policy. Test
|
|
1232
|
-
incompatible/corrupt checkpoints and failed cleanup. Measure steady memory
|
|
1233
|
-
after synchronization across repeated warm and aborted requests.
|
|
1234
|
-
|
|
1235
|
-
**Frontier scorecard.** Speed, quality, and size are independent axes. Keep a
|
|
1236
|
-
Pareto set rather than collapsing them into one weighted score that hides a
|
|
1237
|
-
regression. Every optimization names its target Mac memory budget, workload,
|
|
1238
|
-
context, and concurrency before measurement.
|
|
1239
|
-
|
|
1240
|
-
| Axis | Required evidence |
|
|
1241
|
-
|---|---|
|
|
1242
|
-
| Speed | Short/long-context TTFT, sustained decode, inter-token latency, concurrent throughput; include startup/compile and cold/warm behavior separately |
|
|
1243
|
-
| Quality | Oracle identity for unchanged numerics; for changed quants/numerics, KL as a screen plus frozen task evaluations, raw-prompt/EOS checks, and representative multi-turn agent/tool outcomes |
|
|
1244
|
-
| Size | Actual artifact bytes and effective bpw including scales/codebooks/sidecars; peak unified-memory footprint at the declared context, including KV, draft model, workspaces and retained snapshots |
|
|
1245
|
-
| Practical experience | Largest useful context that fits, responsiveness during long work, completion correctness, restart behavior, and a reproducible local task with visible user benefit |
|
|
1246
|
-
|
|
1247
|
-
A frontier improvement improves at least one axis without a meaningful loss on
|
|
1248
|
-
the others at the declared measurement precision. A useful tradeoff can also be
|
|
1249
|
-
a new non-dominated point; describe the lost/gained quantities explicitly and
|
|
1250
|
-
apply the intended quality floor. A smaller model that causes an EOS/task
|
|
1251
|
-
failure is not a quality-preserving win because its KL or aggregate benchmark
|
|
1252
|
-
looked similar. Neither faster kernels alone nor smaller on-disk weights alone
|
|
1253
|
-
establish a better product experience.
|
|
1254
|
-
|
|
1255
|
-
Compare to the best relevant measured recipe, including the current shipping
|
|
1256
|
-
bundle and credible same-budget alternatives, not an intentionally weak
|
|
1257
|
-
baseline. Publish artifact provenance, input corpus, evaluator, uncertainty,
|
|
1258
|
-
machine and memory accounting. Keep training/tuning examples separate from the
|
|
1259
|
-
held-out promotion set. Include ordinary laptop use and cold-start experience
|
|
1260
|
-
in product evaluation while keeping quotable paired microbenchmarks quiet.
|
|
1261
|
-
|
|
1262
|
-
Optimization cycle: choose a bottleneck and target budget → propose a quant,
|
|
1263
|
-
layout, graph/kernel or execution recipe → establish its numerical/quality
|
|
1264
|
-
contract → measure the full scorecard → retain the non-dominated recipes →
|
|
1265
|
-
register validated selectors for the appropriate Macs and workloads. Negative
|
|
1266
|
-
findings belong in the topic doc; one-off research scripts are then removed.
|
|
1267
|
-
The existing TurboQuant, decode-speed, KV and speculative programs own their
|
|
1268
|
-
experiments. This architecture supplies the common registration and evaluation
|
|
1269
|
-
contract without duplicating their backlogs.
|
|
1270
|
-
|
|
1271
|
-
Pure refactor PRs may be frontier-neutral. V2 product promotion requires at
|
|
1272
|
-
least one reproducible frontier advance plus a representative local workload
|
|
1273
|
-
that demonstrates the benefit. Until measured, it is an objective, not a claim.
|
|
1274
|
-
Supporting multiple useful quant-specialized implementations is intentional;
|
|
1275
|
-
remove duplicated lifecycle policy, not a demonstrated numerical advantage.
|
|
1276
|
-
|
|
1277
|
-
**Performance regression guard.** Record host/chip/RAM, revisions, artifact, effective plan,
|
|
1278
|
-
concurrency, context, cache warmth and native runtime. Compare paired old/new
|
|
1279
|
-
runs on the same quiet machine with existing tooling. Track startup, short/long
|
|
1280
|
-
TTFT, inter-token latency, decode throughput, concurrent throughput/fairness,
|
|
1281
|
-
peak memory, cancellation delay, and checkpoint stall. Predeclare a 3% median
|
|
1282
|
-
regression investigation trigger for TTFT/decode on each representative cell, with
|
|
1283
|
-
enough repetitions to distinguish it from noise; noisy results are unresolved.
|
|
1284
|
-
Even smaller repeatable losses require a fix or an explicit measured benefit
|
|
1285
|
-
elsewhere. No unexplained growing memory retention or disabled pipeline overlap.
|
|
1286
|
-
The trigger prioritizes investigation; it is not an acceptable abstraction tax,
|
|
1287
|
-
does not redefine a Pareto improvement, and does not permit quality degradation.
|
|
1288
|
-
Report on both dev machines before final cutover; do not compare bits across
|
|
1289
|
-
their different metallibs. Curated numbers go only in benchmarks.md.
|
|
1290
|
-
|
|
1291
|
-
**Replacement exercise.** Before closure, replace a real compatible graph with
|
|
1292
|
-
another registered graph, run a quant-specific coarse/fused implementation
|
|
1293
|
-
without adding session branches, then swap the method for a final-output-only test
|
|
1294
|
-
implementation, then run the client through direct and isolated hosts. Session,
|
|
1295
|
-
scheduler-policy, protocol, and application code must remain unchanged. Changes
|
|
1296
|
-
belong only to the implementation/bundle registration and its tests. This is the
|
|
1297
|
-
acceptance test for Josh's "swap one piece" requirement.
|
|
1298
|
-
|
|
1299
|
-
### 12.12 Rollout rules and remaining design decisions
|
|
1300
|
-
|
|
1301
|
-
Each stage routes a bounded set of existing configurations through a temporary
|
|
1302
|
-
implementation selector in the composition root. Preserve the old implementation
|
|
1303
|
-
only for paired comparison and rollback while that stage is open. Do not add
|
|
1304
|
-
permanent user modes for intermediate architecture. Rollback selects a coherent
|
|
1305
|
-
bundle and compatible persistence schema; never mix old graph state with a new
|
|
1306
|
-
codec because both happen to implement an interface.
|
|
1307
|
-
|
|
1308
|
-
Decisions still requiring implementation evidence have explicit owners:
|
|
1309
|
-
|
|
1310
|
-
| Decision | Owner / decision gate |
|
|
1311
|
-
|---|---|
|
|
1312
|
-
| Exact event buffering and collect-mode limits | R1 contract tests; no-consumer and slow-consumer behavior must be bounded |
|
|
1313
|
-
| Smallest graph ABI that covers existing taps/media/compiled paths | R2 real graph replacement plus per-family adapters |
|
|
1314
|
-
| Fence/lease implementation and old checkpoint compatibility | R3 native lifetime tests and restore/restart fixtures |
|
|
1315
|
-
| Which batch mechanics can share a method adapter | R7 parity and pipeline-overlap measurements |
|
|
1316
|
-
| Whether finer worker separation should become a default | R9 crash containment, packaging, and transport measurements |
|
|
1317
|
-
| Retirement of each experimental/duplicate implementation | R10 D6 usage or paired measurement; no deletion by interface preference |
|
|
1318
|
-
| Which optimized recipe becomes the automatic choice for a Mac/workload | R10 full frontier scorecard and held-out quality gate; no universal winner assumed |
|
|
1319
|
-
|
|
1320
|
-
R0 fixes are small independent changes. R1–R4 establish and validate the
|
|
1321
|
-
contracts. R5–R7 perform the execution migration. R8–R10 complete applications,
|
|
1322
|
-
isolation, and deletion. Contract drafting must lead to the first real graph
|
|
1323
|
-
replacement in R2; it cannot grow indefinitely without that working proof.
|
|
1324
|
-
|
|
1325
|
-
### 12.13 Implementation status (2026-09-05)
|
|
1326
|
-
|
|
1327
|
-
Branch: `refactor/interface-engine-v2`. The comparison baseline is
|
|
1328
|
-
`6d45ca1e17e825c48af9b246a37486380117f640` (`origin/main`, fetched again
|
|
1329
|
-
2026-09-05). Its reference docs and tests freeze the pre-refactor public
|
|
1330
|
-
defaults, supported combinations and refusals; use `git show <revision>:<path>`
|
|
1331
|
-
to inspect that baseline without consulting a moving branch.
|
|
1332
|
-
|
|
1333
|
-
| Baseline dimension | Frozen source / compatibility rule |
|
|
1334
|
-
|---|---|
|
|
1335
|
-
| Flags, defaults and routes | Baseline `docs/reference/{server-config,server-api,cli}.md`; no new architecture mode becomes a default in this phase |
|
|
1336
|
-
| Families, quants and feature support | Baseline `docs/reference/models.md`, model profiles and parity tests; the locally available published Qwen artifacts supply compatibility evidence only |
|
|
1337
|
-
| Native oracle and machine | Baseline `docs/reference/environment.md` plus its machine-layered golden manifests; all branch numerical comparisons reported here use the M1 Max 32 GB and the pinned venv |
|
|
1338
|
-
| Toolchain | Bun 1.4.0 (`34cbb9a40`), TypeScript pinned to 6.0.3; Python MLX/Metal 0.31.2, mlx-lm 0.31.3, mlx-optiq 0.2.15 |
|
|
1339
|
-
| Graph/state representation | Existing MLX hidden `[batch, positions, width]` and legacy cache arrays; newly declared `mlx-hidden-bsh-v1` / `legacy-cache-array-v1` describe those representations without converting them. Denoising uses its distinct `mlx-denoising-v1` graph ABI |
|
|
1340
|
-
| Persistence | SSD prefix format 3 is retained; legacy codec identity remains readable. Generation resume identity advances from the baseline's unversioned policy hash to version 4, including stops, adapter content, implementation and resolved policy |
|
|
1341
|
-
| Ownership | Resident weights remain borrowed; request caches, rollback scratch, native preparation and retained prefix backing release at their existing device-safe boundaries, now expressed through owners and leases |
|
|
1342
|
-
| Performance | Baseline/candidate paired diagnostics exist for available artifacts; quiet-machine preflight did not pass, so none establishes a quotable regression result or frontier advance |
|
|
1343
|
-
|
|
1344
|
-
Outstanding evidence is explicit: Josh's designated quant artifacts, the M4 Pro
|
|
1345
|
-
24 GB matrix, quiet paired performance, unavailable diffusion/drafter weights,
|
|
1346
|
-
the Qwen 4B B=2/persistence oracle fixtures, and reconciliation of the reported
|
|
1347
|
-
other-machine Metal-memory fix. The crash is diagnosed as a native allocation
|
|
1348
|
-
failure; this branch preserves the affected cache math. These missing cells
|
|
1349
|
-
do not prevent interface work. They keep the full frontier scorecard and
|
|
1350
|
-
production acceptance gate open after the branch implementation is complete.
|
|
1351
|
-
|
|
1352
|
-
R0 fixes pin TypeScript 6.0.3 for
|
|
1353
|
-
local/CI checks, add stop strings and a version to generation-checkpoint
|
|
1354
|
-
identity, remove cancelled serial waiters immediately, and check cancellation
|
|
1355
|
-
between AR/spec target-prefill chunks and committed-token boundaries.
|
|
1356
|
-
|
|
1357
|
-
`src/contracts/generation.ts` defines portable planner, method/run, session,
|
|
1358
|
-
output, result, cancellation, and timer ports. `src/engine/` implements lifecycle
|
|
1359
|
-
and delivery without model or runtime imports. The dedicated TypeScript project
|
|
1360
|
-
has ES2022 only and no ambient runtime types; an AST/resolved-import test also
|
|
1361
|
-
checks type imports, re-exports, and dynamic imports against dependency layers.
|
|
1362
|
-
|
|
1363
|
-
Streaming starts on the first reader demand. Defaults are 32 queued events,
|
|
1364
|
-
256 queued token IDs, 20 top-logprob entries per token, and a 30-second
|
|
1365
|
-
idle-consumer deadline. Large committed spans split under backpressure.
|
|
1366
|
-
Collecting reserves a Uint32 buffer before method creation, with an aggregate
|
|
1367
|
-
65,536-token active-collection ceiling; terminal output ownership transfers to
|
|
1368
|
-
the caller. Collection currently returns IDs only; logprobs require streaming.
|
|
1369
|
-
Cancellation and early iterator return wait for run cleanup. Failure outcomes
|
|
1370
|
-
retain the execution error if cleanup also fails. These are internal defaults,
|
|
1371
|
-
not new server flags.
|
|
1372
|
-
|
|
1373
|
-
HTTP completion execution now uses the shared session by default.
|
|
1374
|
-
`createSessionCompletionEngine` delivers tokens directly to the existing
|
|
1375
|
-
stop/tool parser through callback output, avoiding a second queue. The callback
|
|
1376
|
-
is awaited and can request a normal stop; cleanup completes before the result
|
|
1377
|
-
settles. Streaming/collection library consumers retain their bounded delivery.
|
|
1378
|
-
AR, speculative and denoising methods honor callback stops. Denoising now settles
|
|
1379
|
-
its emitted-token count when delivery closes before the completed canvas ends.
|
|
1380
|
-
`src/backends/mlx/text-engine.ts` is the data-only token API. It snapshots requests
|
|
1381
|
-
before demand-start and shares `createCompletionMethod` with HTTP. Native media,
|
|
1382
|
-
adapters and grammar still require prepared inputs; their HTTP requests now run
|
|
1383
|
-
through the same session lifecycle. The temporary text-only legacy engine is gone.
|
|
1384
|
-
|
|
1385
|
-
`ModelServingBinding` owns the gateway binding, serial execution construction,
|
|
1386
|
-
prompt/media preparation, SSD restore, signal evaluation, embedding execution and
|
|
1387
|
-
model diagnostics. The server consumes model metadata and this binding.
|
|
1388
|
-
`MlxGatewayBinding` owns compatibility decisions and batch-group construction;
|
|
1389
|
-
method IDs are implementation-owned strings. A model can expose several methods
|
|
1390
|
-
with unrelated private state. Existing classes enter through the MLX binder;
|
|
1391
|
-
replacement implementations supply the port directly. `loadContext` selects an
|
|
1392
|
-
engine-owned host implementation before either default weight loader runs.
|
|
1393
|
-
The HTTP replacement test selects a synthetic exact artifact registration and
|
|
1394
|
-
runs two custom methods with no concrete model, forward function or cache factory.
|
|
1395
|
-
This proves the construction-to-session path, not quant quality or performance.
|
|
1396
|
-
|
|
1397
|
-
`src/inference/graph.ts` declares the backend-bound graph ABI.
|
|
1398
|
-
`src/backends/mlx/graph.ts` binds synchronous/streamed forwards once and selects
|
|
1399
|
-
hidden positions before vocabulary projection. `src/backends/mlx/autoregressive.ts`
|
|
1400
|
-
defines one `MlxAutoregressiveBinding` for the graph, cache construction, media
|
|
1401
|
-
forwarding, adapter state, memory accounting, and optional compiled/fused decode.
|
|
1402
|
-
`generateAutoregressive()` consumes that interface without requiring a
|
|
1403
|
-
`RuntimeModel`. The existing `generate()` API adapts AR models into it, preserving
|
|
1404
|
-
the serial loop's sampling, prefill chunks, lazy evaluation, and decode pipeline.
|
|
1405
|
-
No tensor wrapper, device readback, or synchronization was introduced.
|
|
1406
|
-
|
|
1407
|
-
Concrete Gemma compiled-decode selection and rollback-based fallback now live
|
|
1408
|
-
in the legacy binding. A replacement supplies its own decoder; the loop never
|
|
1409
|
-
infers one from the model family. A declined step must leave state unchanged.
|
|
1410
|
-
Unrecovered errors propagate without retry. Bindings must declare the MLX
|
|
1411
|
-
hidden-state ABI and legacy `Cache[]` ABI; mismatches fail before cache allocation.
|
|
1412
|
-
|
|
1413
|
-
The host now captures AR/denoising and speculative bindings once. Compiled
|
|
1414
|
-
replay permission and grammar jumping are resolved alongside placement and
|
|
1415
|
-
included in checkpoint identity. Serial execution consumes that policy; B=1
|
|
1416
|
-
batch replay also honors it, with dynamic cache geometry still allowed to
|
|
1417
|
-
decline replay transactionally. A lazily created batch group inherits the
|
|
1418
|
-
gateway's runtime snapshot. Composition and snapshot tests cover later config
|
|
1419
|
-
changes, adapters, paged/media fallback, speculation, denoising and logprobs.
|
|
1420
|
-
Legacy kernel flag reads now resolve through an execution-local runtime snapshot.
|
|
1421
|
-
AR/denoising generator resumes and cleanup, the speculative verifier and its
|
|
1422
|
-
memory scope, and each batch driver retain that snapshot across awaits. A later
|
|
1423
|
-
host configuration change cannot alter a running binding's kernel policy.
|
|
1424
|
-
Nested/concurrent scope tests and native binding tests cover early close,
|
|
1425
|
-
verification callbacks and lazy batch construction. The scope adds no tensor
|
|
1426
|
-
copy, evaluation or device fence; its performance remains part of the paired gate.
|
|
1427
|
-
Rejected initial state releases owned caches while preserving borrowed caches.
|
|
1428
|
-
Decoder cleanup completes before cache disposal, including early iterator return.
|
|
1429
|
-
If execution and decoder cleanup both fail, the aggregate retains both errors.
|
|
1430
|
-
The legacy descriptor is not a persistence identity. Rich media remains a native
|
|
1431
|
-
preparation input; tap capabilities and provider-bound persistence are described
|
|
1432
|
-
below. A different cache ABI requires its own compatible method/backend binding.
|
|
1433
|
-
|
|
1434
|
-
Serial cache lookup, checkpoint replay/persistence and prompt-boundary snapshots
|
|
1435
|
-
now live in `src/backends/mlx/serial-executor.ts`. The HTTP server injects a bound
|
|
1436
|
-
generator/verifier, cache constructor, prefix/checkpoint stores, clone function
|
|
1437
|
-
and adapter namespace service. Native Qwen media context is installed/restored
|
|
1438
|
-
by its compatibility binder. The executor has no concrete model dispatch;
|
|
1439
|
-
the existing gateway still owns scheduling and exclusive execution.
|
|
1440
|
-
Native input ownership starts before cache lookup/construction. A failed lookup,
|
|
1441
|
-
cache constructor or trace hook releases prepared grammar/media and any acquired
|
|
1442
|
-
cache state; one failed destructor does not skip sibling releases or replace
|
|
1443
|
-
the execution error. Checkpoint replay checks cancellation before each saved
|
|
1444
|
-
token and retains its durable checkpoint when interrupted.
|
|
1445
|
-
Failed prefix trimming releases acquired clone/restored state. Prefix insertion
|
|
1446
|
-
validates cache metadata before adopting ownership; eviction cleanup errors are
|
|
1447
|
-
reported after adoption without inviting the caller to dispose the live stored
|
|
1448
|
-
entry. Clear detaches entries and attempts cleanup for every sibling. Backing
|
|
1449
|
-
retention is released only after successful cache disposal. Rejected optional
|
|
1450
|
-
prompt-boundary snapshots release their clones while generation retains its
|
|
1451
|
-
live state. These are failure-path ownership changes, with no cache-math change.
|
|
1452
|
-
|
|
1453
|
-
Model-free binding tests exercise an independent graph, a replacement fused
|
|
1454
|
-
decoder, declined steps, unrecovered errors, and unsupported ABI/media/adapter
|
|
1455
|
-
requests. The native `generated-parity` gate runs dedicated and generated Gemma
|
|
1456
|
-
bindings through the same gateway method and portable session consumer. Tokens
|
|
1457
|
-
and cache coverage match, and its counter verifies the generated path executed.
|
|
1458
|
-
This is a compatibility gate using available weights, not a product speed claim.
|
|
1459
|
-
The binding migration also passes all eight compiled-decode parity/recovery
|
|
1460
|
-
checks and the Qwen3.8-27B TQ smoke below on the M1 Max 32 GB.
|
|
1461
|
-
|
|
1462
|
-
`src/model/implementation.ts` defines the backend-parameterized
|
|
1463
|
-
`ModelImplementation` construction port and immutable registration table.
|
|
1464
|
-
`ModelExecutionComposition.implementation` lets an exact engine-owned artifact
|
|
1465
|
-
profile name its code. Existing identity/config guards perform the matching;
|
|
1466
|
-
the registry does not introduce another artifact matcher. `src/model/factory.ts`
|
|
1467
|
-
now registers the existing resident constructors, including generated Gemma,
|
|
1468
|
-
and selects one before construction. `openModel` checks the binding before
|
|
1469
|
-
opening weights; callers can compose profiles and implementations through its
|
|
1470
|
-
options. `createModel` accepts a registry for already-open weights. No selection
|
|
1471
|
-
is added to the token loop, and no model file format changes.
|
|
1472
|
-
Both factories preserve a supplied registry's return interface; replacement
|
|
1473
|
-
implementations need not join the concrete `RuntimeModel` union. Construction
|
|
1474
|
-
does not select the request's execution method. An implementation can support
|
|
1475
|
-
several methods, including quant-specific paths, while the session consumes
|
|
1476
|
-
the selected method's execution, output and cleanup contract. The shared
|
|
1477
|
-
contract does not require a shared numerical loop.
|
|
1478
|
-
|
|
1479
|
-
Unknown artifacts retain existing family selection. Missing implementations,
|
|
1480
|
-
graph/loader/loop mismatches, duplicate IDs, and inconsistent exact identities
|
|
1481
|
-
fail explicitly. Construction failures propagate without trying another graph.
|
|
1482
|
-
Model-free tests exercise the factory with a synthetic exact quant identity and
|
|
1483
|
-
an alternate constructor; this establishes selection, not numerical or speed
|
|
1484
|
-
claims. No registration pretends to identify Josh's inaccessible quants.
|
|
1485
|
-
This step covers resident graph construction. Colibri retains its existing
|
|
1486
|
-
streamed opener and refuses supplied resident registries or named overrides
|
|
1487
|
-
until its resident loader binding exists. Existing class-based library exports
|
|
1488
|
-
remain available through compatibility binders. The server consumes the
|
|
1489
|
-
model-owned serving port; host implementations can own resident or streamed
|
|
1490
|
-
loading. Specialized inference methods remain.
|
|
1491
|
-
|
|
1492
|
-
Artifact-parameterized native smoke gate:
|
|
1493
|
-
`MLX_BUN_QWEN_QUANT_PATH=/path/to/our/artifact bun test tests/parity/qwen-quant-engine.test.ts`.
|
|
1494
|
-
Run one artifact per process. Compatibility-only checks on the M1 Max 32 GB
|
|
1495
|
-
pass for the locally cached published `mjriii/Qwen3.8-27B` and
|
|
1496
|
-
`mjriii/Qwen3.8-27B-TQ`: direct-versus-bound logits, legacy-versus-session greedy
|
|
1497
|
-
output/cache coverage, and repeated recurrent-prefix borrowing. These are not
|
|
1498
|
-
Josh's current target quants. Target validation awaits access to those artifacts;
|
|
1499
|
-
implementation continues independently. The test is a bounded smoke, not a full model oracle or the
|
|
1500
|
-
recorded turn-8 repro. Gemma compiled-decode checks are secondary coverage too.
|
|
1501
|
-
|
|
1502
|
-
R1 is complete. Incremental and final-only producers run the same lifecycle
|
|
1503
|
-
cases for collection/streaming, blocked-consumer cancellation, partial failure,
|
|
1504
|
-
and no-consumer/pre-cancelled settlement. Additional tests cover preparation
|
|
1505
|
-
cancellation, admission refusal, metadata bounds, and cleanup failures.
|
|
1506
|
-
|
|
1507
|
-
R3 now gives request resources one checked owner. Transfer invalidates the
|
|
1508
|
-
previous owner, close is idempotent even after a destructor failure, and cleanup
|
|
1509
|
-
attempts all releases while preserving the original execution error. MLX state
|
|
1510
|
-
views expose a lease; prefill and prefix-cache accounting close it without
|
|
1511
|
-
knowing whether handles are borrowed or temporary. Only the compatibility
|
|
1512
|
-
adapter reads the legacy ownership marker. No tensor copy, evaluation or device
|
|
1513
|
-
synchronization is added by these leases. Fault-injection tests cover transfer,
|
|
1514
|
-
partial view acquisition and throwing destructors. Existing native fences remain
|
|
1515
|
-
in place; codec binding and persistence identity are described below.
|
|
1516
|
-
|
|
1517
|
-
R4 now resolves method, scheduling mechanism, paged-KV fallback, prompt-cache
|
|
1518
|
-
bypass, fill eligibility and checkpoint eligibility in one portable planner.
|
|
1519
|
-
The gateway passes that immutable decision to serial execution; lane accounting
|
|
1520
|
-
uses the actual method, including AR fallback with a configured draft. Request
|
|
1521
|
-
policy arrays/maps are copied and frozen at admission. AR runtime settings and
|
|
1522
|
-
batch work flags use a binding snapshot. Native grammar/media preparation takes
|
|
1523
|
-
the gateway execution lease before allocation; text rendering remains outside
|
|
1524
|
-
that lease. Cancellation before/during preparation is covered with allocation
|
|
1525
|
-
and cleanup assertions.
|
|
1526
|
-
Native AR/speculative/denoising method creation now uses the same policy snapshot
|
|
1527
|
-
as HTTP admission. Scalar settings and nested policy arrays/maps cannot change
|
|
1528
|
-
between registration and the first reader demand. A binding without an explicit
|
|
1529
|
-
runtime captures the host default at method creation; kernels execute under
|
|
1530
|
-
that snapshot. Native caches, controllers and callbacks retain their declared
|
|
1531
|
-
ownership instead of being cloned with policy data.
|
|
1532
|
-
|
|
1533
|
-
Checkpoint request identity is now canonical SHA-256 over sampling/stop policy,
|
|
1534
|
-
resolved execution and the artifact/implementation/state ABI. Object insertion
|
|
1535
|
-
order is ignored; array order remains meaningful. Version-4 keys include the
|
|
1536
|
-
resolved compiled/grammar policy; version-2/3 generation keys do
|
|
1537
|
-
not resume through this version; ordinary prefix-store format is unchanged.
|
|
1538
|
-
Nine native scheduling gates pass after planner integration, including rotating
|
|
1539
|
-
dynamic joins, row failure containment, serial drain, prefix sharing, SSD restore
|
|
1540
|
-
and compiled B=1. Preparation reservations now remain owned through execution; see below.
|
|
1541
|
-
|
|
1542
|
-
R3 state persistence now uses `CacheCodecProvider`, bound through the server's
|
|
1543
|
-
model context, RAM cloner, batch snapshots and SSD store. A provider supplies
|
|
1544
|
-
clone/snapshot/restore/trimmability together; ambiguous matches refuse. Persisted
|
|
1545
|
-
provider identity is checked before cache allocation or mmap. Earlier v3 files
|
|
1546
|
-
implicitly use the legacy provider; a different provider must identify itself.
|
|
1547
|
-
Restore still copies one tensor at a time and unmaps only after those copies,
|
|
1548
|
-
so this change introduces no new device/backing lifetime assumption. Failed
|
|
1549
|
-
clone and snapshot construction release intermediate owned views.
|
|
1550
|
-
|
|
1551
|
-
Adapter namespaces now hash the weight file plus scale/rank policy once at
|
|
1552
|
-
mount. Remounting the same name with different bytes or scale cannot reuse its
|
|
1553
|
-
old RAM prefix or generation checkpoint. The shared server cache uses that
|
|
1554
|
-
namespace for both lookup and persistence. Codec provider fault/round-trip tests
|
|
1555
|
-
pass; native persistence passes five cells with one unavailable golden skipped,
|
|
1556
|
-
and dedicated/generated Gemma passes six cells, including direct logit identity.
|
|
1557
|
-
|
|
1558
|
-
R5 now shares a portable prefill program between serial AR and solo batch
|
|
1559
|
-
admission. Its MLX executor preserves drain evaluation, KV maintenance, allocator
|
|
1560
|
-
clears, stable-boundary snapshots, and the separate final-token forward. Batch
|
|
1561
|
-
admission retains its short-tail scheduling behavior. Six native scheduler
|
|
1562
|
-
checks pass, including dynamic rows, prompt reuse, SSD restore and compiled B=1;
|
|
1563
|
-
the dedicated/generated same-session test also passes on the M1 Max 32 GB.
|
|
1564
|
-
The native AR method run owns its generator's pending tokens, history and
|
|
1565
|
-
checkpoint boundary. Phase-specific tests now cover cancellation before any
|
|
1566
|
-
cache allocation, after a prefill chunk, after decode dispatch/before emission,
|
|
1567
|
-
and while an asynchronous checkpoint borrows live state. Cancellation waits for
|
|
1568
|
-
the checkpoint to finish before releasing state. Current-token logprob arrays
|
|
1569
|
-
remain owned until readback succeeds, including forward/grammar failure;
|
|
1570
|
-
cancelled execution stops before emission or a subsequent checkpoint write.
|
|
1571
|
-
|
|
1572
|
-
R6 now runs the speculative verifier through `MlxSpeculativeBinding`. Target
|
|
1573
|
-
forwards, projection, tap capture, draft construction and kernel pinning bind
|
|
1574
|
-
outside the verifier. Legacy tap contexts restore their previous value on exit.
|
|
1575
|
-
The complete rollback facet validates recurrent begin/commit/replay together;
|
|
1576
|
-
partial layer failures invalidate the transaction and the run discards its state.
|
|
1577
|
-
Ring-capacity fallback retains its strict pre-write boundary. The verifier owns
|
|
1578
|
-
input/hidden scratch on failure and attempts every final release.
|
|
1579
|
-
|
|
1580
|
-
AR and speculative methods now implement `InferenceMethod` directly. Their shared
|
|
1581
|
-
host adapter translates cancellation and waits for native cleanup. The same
|
|
1582
|
-
session tests exercise collection, streaming, early reader closure and forward
|
|
1583
|
-
failure for both. Four native Qwen3.5-0.8B gates pass, including recurrent
|
|
1584
|
-
rejections and identical speculative acceptance traces through a portable
|
|
1585
|
-
session. This smaller available model supplies compatibility coverage only.
|
|
1586
|
-
Denoising now implements that same method/session contract through a separate
|
|
1587
|
-
`DenoisingGraph<Tensor, State>`. Its test binding uses a position-only state
|
|
1588
|
-
record, with no AR cache or token-prefix API. The existing synchronous diffusion
|
|
1589
|
-
entry and cooperative generation drain one denoising program. Cooperative calls
|
|
1590
|
-
yield between denoising steps and publish only the final output; cancellation
|
|
1591
|
-
releases canvas, feedback, embedding weights and graph state. Generation holds
|
|
1592
|
-
the existing exclusive runtime lease, including the diffusion global RNG.
|
|
1593
|
-
|
|
1594
|
-
Scripted regression tests cover both samplers, RNG-dependent canvases across
|
|
1595
|
-
multiple blocks, sync/async identity, preparation failure, cancellation between
|
|
1596
|
-
steps and repeated-run native memory accounting. The existing soft-embedding
|
|
1597
|
-
lifetime test passes. Diffusion weights are absent on this machine, so its
|
|
1598
|
-
weight/oracle gates remain unrun. Draft sources now consume declared target
|
|
1599
|
-
ports for assistant donor views/scaled embeddings, Gemma hidden taps/output
|
|
1600
|
-
projection and Qwen MTP embeddings/output projection. The target view contains
|
|
1601
|
-
no concrete model or cache array; the MLX compatibility binder owns family
|
|
1602
|
-
checks and donor layout. Native GLM providers compare an opaque target identity
|
|
1603
|
-
before borrowing their own model-owned weights. Both retained DSpark variants
|
|
1604
|
-
use the projection interface. Missing extensions refuse before draft allocation.
|
|
1605
|
-
An independent assistant target fixture proves construction and draft cleanup
|
|
1606
|
-
without a model class; donor acquisition releases partial views on failure.
|
|
1607
|
-
The locally cached published Qwen3.8-27B and its bundled MTP head pass the
|
|
1608
|
-
same-artifact greedy comparison after this migration. This does not establish
|
|
1609
|
-
performance or compatibility for Josh's unavailable exact quants.
|
|
1610
|
-
|
|
1611
|
-
R7 now separates the portable scheduling driver from `MlxBatchExecutionGroup`.
|
|
1612
|
-
The driver sees queue/active counts, admission readiness and bounded work units;
|
|
1613
|
-
it imports no model, cache, tensor or runtime implementation. Native admission,
|
|
1614
|
-
merge/extract/filter, sampling and pipeline state live in `src/backends/mlx/`.
|
|
1615
|
-
A compatibility re-export preserves existing batch-scheduler imports.
|
|
1616
|
-
|
|
1617
|
-
The driver retains short-admission grouping, long-prefill interleaving, serial
|
|
1618
|
-
drain and the 25 ms single-row responsiveness budget. Six native scheduler
|
|
1619
|
-
checks and two native failure-containment/serial-drain checks pass. Policy tests cover those ordering rules, execution failure and
|
|
1620
|
-
lease release; backend fault tests cover a request removed from the queue when
|
|
1621
|
-
admission fails, retained-prefix cleanup, shutdown and submission after close.
|
|
1622
|
-
Closing a group stops at a safe boundary, rejects pending/active requests and
|
|
1623
|
-
releases owned state. Bounded request and preparation queues now reject overflow explicitly. The full
|
|
1624
|
-
mixed-state concurrency/performance matrix remains open.
|
|
1625
|
-
|
|
1626
|
-
R8 now shares Pi/browser messages, history, sampling data and route IDs in
|
|
1627
|
-
`src/contracts/pi.ts`. Compatibility re-exports preserve server-side imports.
|
|
1628
|
-
The browser TypeScript project has no Bun ambient types; Bun UI tests remain
|
|
1629
|
-
covered by the root project. The resolved-import gate prevents browser modules
|
|
1630
|
-
from importing server implementations, including type-only imports.
|
|
1631
|
-
|
|
1632
|
-
R4/R7 admission now uses a portable FIFO `AdmissionPool`. The gateway bounds
|
|
1633
|
-
active requests and queued waiters; cancelled waiters do not release another
|
|
1634
|
-
request's capacity. Media and grammar preparation reserve capacity before native
|
|
1635
|
-
allocation. The request owner retains that reservation after transferring native
|
|
1636
|
-
resources to execution, then releases it on success, failure or cancellation.
|
|
1637
|
-
The direct batch group also bounds pending submissions. Overload is explicit in
|
|
1638
|
-
the existing HTTP/SSE error contract. Nine native scheduling checks pass after
|
|
1639
|
-
this integration, including rotating joins, failure containment, prefix/SSD reuse
|
|
1640
|
-
and compiled B=1. The gateway's shared execution lease covers preparation,
|
|
1641
|
-
generation and managed GPU jobs.
|
|
1642
|
-
|
|
1643
|
-
R8 is complete: completion/batch/task contracts are portable. Memory calls accept an injected
|
|
1644
|
-
client; their existing native implementation moved behind a lazy backend import.
|
|
1645
|
-
Eval generation accepts a replacement completion client and retains its separate
|
|
1646
|
-
bit-exact greedy oracle path in the MLX backend. Training and quantization keep
|
|
1647
|
-
their numerical runners and artifact results; both job execution modes now use
|
|
1648
|
-
the task adapter. Progress delivery is synchronous and unbuffered; cooperative
|
|
1649
|
-
cancellation checks before work and at progress boundaries. Native work already
|
|
1650
|
-
dispatched still completes at its safe boundary.
|
|
1651
|
-
|
|
1652
|
-
Pi's embedded registry and generated extension use one model-definition builder.
|
|
1653
|
-
Job and Pi/browser messages now share portable declarations. New `mlx-bun/engine`
|
|
1654
|
-
and `mlx-bun/client` exports import without MLX; `initializeMlx()` explicitly
|
|
1655
|
-
bootstraps the compatibility API. The existing root import remains compatible.
|
|
1656
|
-
The JSON completion client uses either HTTP or an `EngineHost` without changing
|
|
1657
|
-
callers, preserves abort, and never retries completion POSTs.
|
|
1658
|
-
|
|
1659
|
-
R9 adapts the existing `EngineChild` into `EngineHost`, bounds restart attempts,
|
|
1660
|
-
cancels restart backoff on close, kills failed startup, and checks disconnect
|
|
1661
|
-
while waiting for readiness. Model-pool startup failures and shutdown close their
|
|
1662
|
-
owned children; an evicted default can be resolved again for an absent/unknown
|
|
1663
|
-
model request. The fake-host proxy suite now runs in the model-free CI tier.
|
|
1664
|
-
Real MiniCPM JSON and incremental SSE requests pass through the isolated host.
|
|
1665
|
-
|
|
1666
|
-
Managed GPU subprocess jobs reserve the same gateway lease as inference: the
|
|
1667
|
-
current batch drains before spawn, and the job retains the lease through child
|
|
1668
|
-
exit, including crashes. Host shutdown cancels admission/queued jobs and terminates
|
|
1669
|
-
its active job before releasing the lease. Fault tests cover rejected admission,
|
|
1670
|
-
spawn failure, child death and shutdown. The isolation parent now owns job/settings routes and their store. A portable
|
|
1671
|
-
shared/exclusive coordinator covers every worker's startup, restart, response
|
|
1672
|
-
body and eviction. Before GPU job spawn, live UDS lease responses reserve each
|
|
1673
|
-
worker's gateway after durability flush; disconnect releases the worker lock.
|
|
1674
|
-
Those connections remain owned through subprocess exit, not merely until a
|
|
1675
|
-
client HTTP disconnect. Native MiniCPM checks verify that generation waits for
|
|
1676
|
-
the parent lease and resumes after release. Worker death does not remove parent
|
|
1677
|
-
job records. In-process task cancellation waits for runner cleanup before closing
|
|
1678
|
-
the store. The parent serves the same embedded web assets and owns Responses
|
|
1679
|
-
conversation history; direct and isolated serving share conversation-resolution
|
|
1680
|
-
policy. Workers skip duplicate history retention for parent-owned requests. A
|
|
1681
|
-
real worker replacement preserves previous-response continuation and streamed
|
|
1682
|
-
metadata. WebSocket chat remains an explicit unsupported isolation cell. No
|
|
1683
|
-
process-host default has changed. R9's direct/isolated transport comparison is
|
|
1684
|
-
complete on the M1 Max using the same MiniCPM artifact and CLI/request cells:
|
|
1685
|
-
completion and chat probes each matched 64 greedy tokens; cold, warm, SSD
|
|
1686
|
-
restart and concurrent legs completed. The run is diagnostic because the quiet
|
|
1687
|
-
gate failed. The optional `mlx-bun-isolated` benchmark arm accounts for parent
|
|
1688
|
-
and worker RSS; raw reports stay machine-local. R9 is complete for the retained
|
|
1689
|
-
opt-in host; promotion and the other machine's scorecard remain R10 gates.
|
|
1690
|
-
|
|
1691
|
-
The current model-free suite passes; root, browser and portable typechecks pass.
|
|
1692
|
-
Native state checks cover mixed-KV oracle logits, wrapped-ring conversion,
|
|
1693
|
-
speculative recurrent rollback and persistence. The Qwen B=2 oracle and one
|
|
1694
|
-
Qwen persistence fixture are absent and skip. The binary builds and its CLI/Pi
|
|
1695
|
-
asset smoke passes. Managed jobs now self-exec the packaged binary; literal
|
|
1696
|
-
runner imports retain quantize/train code in the bundle, and a compiled
|
|
1697
|
-
subprocess smoke verifies progress and terminal persistence. These checks do not replace the unavailable artifact/machine
|
|
1698
|
-
cells or the final production acceptance gate.
|
|
1699
|
-
|
|
1700
|
-
The Qwen replay now has a native exception diagnosis: Metal reports insufficient
|
|
1701
|
-
memory from its completion handler. Details remain in the existing turn-8 repro.
|
|
1702
|
-
Josh reports a possible fix on the other machine; reconcile it before changing
|
|
1703
|
-
the affected state path. The 2026-09-05 benchmark preflight found 4 GB of existing swap and high
|
|
1704
|
-
background CPU load. Measurements taken without that gate are diagnostic only.
|
|
1705
|
-
Quiet-machine baselines remain open. Remaining R0–R10
|
|
1706
|
-
work is tracked in PLAN.md; no speed/quality/size improvement is claimed yet.
|
|
1707
|
-
|
|
1708
|
-
The first per-file native matrix at `a75cd39` ran 84 local parity files with
|
|
1709
|
-
batch-decode opt-in: 338 passes, 44 skips and seven failed assertions. Five
|
|
1710
|
-
audio failures were a fixture path left behind by the test-directory move.
|
|
1711
|
-
The two numerical failures reproduced on baseline `6d45ca1`: the local CPM
|
|
1712
|
-
mixed-KV blobs did not match their manifest hashes, and CPM extend-join fell
|
|
1713
|
-
back to the M4 reference because no M1 override existed. The pinned Python
|
|
1714
|
-
oracle regenerated the mixed-KV manifest's exact hashes and an M1 extend-join
|
|
1715
|
-
trajectory identical to the implementation. The corrected batch suites pass
|
|
1716
|
-
15 tests with one unavailable e4b oracle skip. Tests now check blob hashes;
|
|
1717
|
-
the mixed-KV generator writes blobs and manifests to the same resolved output
|
|
1718
|
-
directory. A second per-file run enables the local train/quantize/LoRA/generated
|
|
1719
|
-
and model-family gates. Two rotating-quantized continuation failures also
|
|
1720
|
-
reproduced on the baseline: the test compared `generate()`'s bf16-head/quantize/
|
|
1721
|
-
tail prefill with a fully quantized single-forward oracle. The generator now
|
|
1722
|
-
records both procedures separately. Existing mechanics, single-forward logits
|
|
1723
|
-
and trajectories regenerated unchanged; the matching serving trajectories pass
|
|
1724
|
-
the original prefix threshold. All six rotating tests pass. Missing new
|
|
1725
|
-
continuation fixtures skip explicitly on other machines until regeneration.
|
|
1726
|
-
A process that exits successfully without registering tests is not a passing
|
|
1727
|
-
matrix cell; absent large-model/drafter fixtures remain open.
|
|
1728
|
-
The production test runner now uses a fresh process for each native test file,
|
|
1729
|
-
preserving model residency and runtime isolation between cells. The complete
|
|
1730
|
-
default runner passed at `2a14021`, including hygiene,
|
|
1731
|
-
all TypeScript projects, the model-free suite and available parity/research
|
|
1732
|
-
tests. Optional cells are reported separately; a green default run does not
|
|
1733
|
-
imply unavailable weights or opt-in cases ran.
|
|
1734
|
-
That run reports 2,344 passes, 98 skips and no failures, with 109 native files
|
|
1735
|
-
each receiving a fresh process.
|
|
1736
|
-
The expanded runner at `ab0db74` enabled the locally applicable model-family,
|
|
1737
|
-
training, quantization, LoRA and batch-decode gates: 2,427 passes, 44 skips and
|
|
1738
|
-
no failures across the model-free tier and 109 native files. Ten native files
|
|
1739
|
-
registered no tests because their configured model/drafter fixtures were absent;
|
|
1740
|
-
those are unavailable cells, not passes. At `b9b56aa`, the model-free suite
|
|
1741
|
-
passed 1,718 tests with 10 skips. All TypeScript projects, hygiene and compiled
|
|
1742
|
-
CLI/Pi/assets/job smokes passed. The subsequent focused native run passed 44
|
|
1743
|
-
tests covering batch lifecycle, SSD state, generated graphs, ngram verification,
|
|
1744
|
-
both available published Qwen graph/session bindings and the published Qwen MTP
|
|
1745
|
-
target/draft pair. Explicit MTP paths supplied one previously unavailable cell.
|
|
1746
|
-
These results do not close the target-artifact, second-machine or default-cutover
|
|
1747
|
-
gates.
|
|
1748
|
-
|
|
1749
|
-
The sequential Gemma e4b repeat compares baseline `6d45ca1` with `5e3b92e`
|
|
1750
|
-
using default and serial HTTP arms, the same artifact, a 4K context and 96
|
|
1751
|
-
requested tokens. Both arms preserve the completion/chat greedy probes and
|
|
1752
|
-
durable restart state. The earlier long-context prefill slowdown and default-arm
|
|
1753
|
-
RSS increase did not reproduce; warm-cache latency still varies across runs.
|
|
1754
|
-
Background load and existing swap keep these reports diagnostic. This repeat
|
|
1755
|
-
does not establish a speed win or satisfy the quiet-machine frontier gate.
|
|
1756
|
-
|
|
1757
|
-
R10's implementation-retention review currently records these decisions. None
|
|
1758
|
-
of the open measurement cells changes an existing numerical default:
|
|
1759
|
-
|
|
1760
|
-
| Implementation | Current disposition and remaining evidence |
|
|
1761
|
-
|---|---|
|
|
1762
|
-
| Pi provider wiring | Consolidated into one builder; generated-extension and binary asset tests pass. Duplicate policy is removed |
|
|
1763
|
-
| Dedicated/generated Gemma | Both register through the engine and pass the same session/oracle gates. Keep both during paired comparison; numerical equivalence alone does not choose a winner |
|
|
1764
|
-
| Compiled decode | Retained behind the declared decoder capability and resolved eligibility. Existing recovery/parity gates pass; final paired regression measurements remain required |
|
|
1765
|
-
| Diffusion | One denoising program and method interface replace duplicate orchestration. Real model/oracle fixtures remain unavailable; no promotion or deletion decision is implied by scripted tests |
|
|
1766
|
-
| Assistant/DSpark/DeepSpec/MTP | Typed draft target ports replace concrete target dispatch. Available Qwen MTP and ngram verification pass; source-specific drafter validation and the DSpark wall-clock decision remain open in the speculative program |
|
|
1767
|
-
| Curve/HLG and paged KV | Existing opt-in placement and refusals remain. Their experiment-specific quality/performance gates remain open; this refactor does not make them defaults |
|
|
1768
|
-
| Expert offload | Existing streamed GLM loading/task semantics remain behind native bindings; model-free streamed/provider tests and packaged task entry pass. The larger-model value/footprint decision remains in its own program |
|
|
1769
|
-
The final server cutover is implemented at `015f56d`. The model-free suite passes
|
|
1770
|
-
1,732 tests with 10 skips. Fresh native processes run all 109 parity/research
|
|
1771
|
-
files with the locally applicable opt-ins, including the published Qwen target
|
|
1772
|
-
and MTP paths: 720 passes, 33 skips, no failures. Nine fixture-dependent files
|
|
1773
|
-
register no tests and remain unavailable cells. The second published Qwen TQ
|
|
1774
|
-
artifact also passes the graph/session test. The public replacement and import/
|
|
1775
|
-
docs boundary checks pass after the final exports. Commit `d1abd60` also puts
|
|
1776
|
-
embeddings under the shared GPU lease. Its new ownership test, the public
|
|
1777
|
-
replacement test and both native embedding-route tests pass. All three
|
|
1778
|
-
TypeScript projects pass, as does hygiene. The standalone binary built at
|
|
1779
|
-
`d1abd60` passes CLI, Pi asset and managed-job subprocess smoke checks.
|
|
1780
|
-
|
|
1781
|
-
The final HTTP comparison uses the frozen `6d45ca1` baseline and this branch on
|
|
1782
|
-
the M1 Max 32 GB, with MiniCPM5 and Gemma e4b, default and serial arms, a 4k
|
|
1783
|
-
context and 96 generated tokens. The first candidate run overlapped a repository
|
|
1784
|
-
hygiene scan and showed slower e4b long prefill and SSD restart. A sequential
|
|
1785
|
-
e4b repeat without other checks removed the long-prefill gap, but restart
|
|
1786
|
-
latency still varied. A further candidate-then-baseline default-arm pair removed
|
|
1787
|
-
that restart gap too. Completion and chat parity probes match between default
|
|
1788
|
-
and serial arms; every restart restores a durable prefix with no failed or
|
|
1789
|
-
dropped spills. These loaded-machine diagnostics do not establish a quiet
|
|
1790
|
-
performance acceptance result. Raw reports remain local in
|
|
1791
|
-
`/tmp/mlx-bun-cutover-{baseline,candidate}-report.md`,
|
|
1792
|
-
`/tmp/mlx-bun-cutover-repeat-{baseline,candidate}-report.md` and
|
|
1793
|
-
`/tmp/mlx-bun-cutover-reverse-{baseline,candidate}-report.md`.
|
|
1794
|
-
|
|
1795
|
-
R1–R9 implementation and R10 code migration are complete. Existing model-class
|
|
1796
|
-
exports use backend compatibility binders; there is one default session lifecycle
|
|
1797
|
-
and no alternate legacy HTTP executor. R10's retained implementations keep their
|
|
1798
|
-
existing placement and numerical defaults. Their independent experiment programs
|
|
1799
|
-
still own promotion/deletion decisions. Quiet performance, exact target quants,
|
|
1800
|
-
unavailable oracle/drafter fixtures and the second machine remain acceptance
|
|
1801
|
-
work, not missing interface code. No frontier advance is claimed by this refactor.
|
|
1802
|
-
|
|
1803
|
-
### 12.14 Request flow and interface ownership
|
|
1804
|
-
|
|
1805
|
-
This is the target responsibility map for Phase 6/18. A request carries one
|
|
1806
|
-
resolved policy: measured defaults plus explicit user overrides. Each component
|
|
1807
|
-
consumes its own part of that policy. The table below distinguishes existing
|
|
1808
|
-
contracts from implementation and migration work still in progress.
|
|
1809
|
-
|
|
1810
|
-
```mermaid
|
|
1811
|
-
flowchart TB
|
|
1812
|
-
client["Client: chat, Pi, API or library"]
|
|
1813
|
-
server["Server adapter<br/>receive requests and send responses"]
|
|
1814
|
-
policy["Request policy interface<br/>resolve defaults and user overrides once"]
|
|
1815
|
-
template["Chat template interface<br/>messages and tools → rendered prompt"]
|
|
1816
|
-
tokenizer["Tokenizer interface<br/>rendered prompt → token IDs"]
|
|
1817
|
-
session["InferenceEngine / GenerationSession<br/>own request lifecycle and cancellation"]
|
|
1818
|
-
scheduler["Scheduler / ExecutionGroup<br/>choose when ready work runs"]
|
|
1819
|
-
method["InferenceMethod<br/>ordinary decode or MTP proposal / verification"]
|
|
1820
|
-
graph["Model graph interface<br/>prefill, forward passes and specialized kernels"]
|
|
1821
|
-
sampler["SamplingSession<br/>apply settings and grammar; select tokens"]
|
|
1822
|
-
output["Response interface<br/>decode committed tokens; emit text and tool events"]
|
|
1823
|
-
state["Active state interface<br/>target KV, recurrent state, draft state and positions"]
|
|
1824
|
-
cache["PrefixCache interface<br/>restore and retain aligned token / state checkpoints"]
|
|
1825
|
-
ram["RAM cache<br/>retain reusable checkpoints"]
|
|
1826
|
-
persistence["Persistence interface<br/>queue background writes and restore from SSD"]
|
|
1827
|
-
|
|
1828
|
-
client --> server --> policy --> template --> tokenizer --> session
|
|
1829
|
-
session -->|ready work| scheduler
|
|
1830
|
-
scheduler -->|admit and advance a batch of 1 or more| method
|
|
1831
|
-
method -->|inputs and state| graph
|
|
1832
|
-
graph -->|device logits| sampler
|
|
1833
|
-
sampler -->|selected tokens or proposals| method
|
|
1834
|
-
method -->|committed tokens only| output
|
|
1835
|
-
output -->|response events| server
|
|
1836
|
-
method <-->|borrow, update, snapshot, rollback| state
|
|
1837
|
-
session <-->|restore / publish prefill checkpoint| cache
|
|
1838
|
-
method -->|publish generated checkpoint| cache
|
|
1839
|
-
cache <-->|fast reuse| ram
|
|
1840
|
-
ram <-->|spill and restore when needed| persistence
|
|
1841
|
-
```
|
|
1842
|
-
|
|
1843
|
-
The scheduler chooses **when** work runs and which requests are active. The
|
|
1844
|
-
inference method chooses **what numerical work** advances them. A batch of one
|
|
1845
|
-
uses the same method and state contracts as a larger batch. The final design
|
|
1846
|
-
has one shared executor and no separate serial executor to fall back to.
|
|
1847
|
-
|
|
1848
|
-
The model graph returns logits to the sampler. The sampler applies temperature,
|
|
1849
|
-
penalties, grammar, sampling filters and RNG policy, and returns selected tokens
|
|
1850
|
-
with requested logprobs. MTP keeps proposals private until verification commits
|
|
1851
|
-
them. The response formatter sees committed tokens only.
|
|
1852
|
-
|
|
1853
|
-
Live KV is working state for the current computation. A reusable checkpoint
|
|
1854
|
-
contains token IDs plus the corresponding target, recurrent and optional draft
|
|
1855
|
-
state. Both prefill and generated output must feed the same cache interface.
|
|
1856
|
-
Only an exact, rendered-stable token boundary can be published for state that
|
|
1857
|
-
cannot be trimmed. RAM retention, eviction, asynchronous SSD writes and restart
|
|
1858
|
-
restore belong behind that interface. Scheduling does not wait for an ordinary
|
|
1859
|
-
SSD spill; an explicit durability flush can wait for persistence.
|
|
1860
|
-
|
|
1861
|
-
| Piece | Current code or contract | Remaining work |
|
|
1862
|
-
|---|---|---|
|
|
1863
|
-
| Server / response adapters | `CompletionEngine`, `CompletionSink`, `GenerationOutput` | Preserve the same semantics through the final shared-executor cutover. |
|
|
1864
|
-
| Request policy | `RequestPlan`, request preparation and execution planning | Consolidate configuration into one resolved policy; choose measured defaults for typical multi-turn use and retain user overrides. |
|
|
1865
|
-
| Chat template | `ChatTemplate.render` | Expose the renderer as its own narrow port instead of requiring a concrete serving context. Record rendered-stable boundaries for generated checkpoint alignment. |
|
|
1866
|
-
| Tokenizer | `LoadedTokenizer` | Reuse the same encode/decode contract across preparation, caching and output. Keep incremental encoding inside this component. |
|
|
1867
|
-
| Session / scheduling | `InferenceEngine`, `GenerationSession`, `ExecutionGroup`, `SchedulingClock` | Close all feature and performance gaps before deleting the remaining serial executor. |
|
|
1868
|
-
| Inference method | `InferenceMethod`; shared ordinary and speculative methods | Complete every shared-method composition and acceptance gate. Draft depth belongs here, independently of queue policy. |
|
|
1869
|
-
| Numerical graph / kernels | `AutoregressiveGraph`, `GraphFactory`, backend bindings | Continue hardware-specific fusion and kernel optimization behind these contracts. |
|
|
1870
|
-
| Sampler | `SamplingSession` | Retain one set of sampling/history/logprob semantics for ordinary and speculative execution. |
|
|
1871
|
-
| Active state / codec | `Cache`, `KvAttentionState` / `KvAttentionView`, row layouts, `SpeculativeTransaction`, checkpoint attachments | Appending and attending are separate operations. One captured view can serve multiple model layers while retaining pre-write positions and tensor ownership. Delayed affine/TurboQuant and rotating layouts are integrated; qualify additional model/layout combinations separately. |
|
|
1872
|
-
| Reusable cache | `PrefixCache.take/put`, shared `PromptCache` | Prefill and processed generated output populate the same immutable RAM/SSD cache. Session lookup and rendered-token alignment are integrated. |
|
|
1873
|
-
| Persistence | `ColdTier`, `SpillSink`, `SsdCacheStore`, `SsdDurabilityCoordinator` | Queued persistence, native/restart checks and full Kanban durability acceptance are complete. RAM/SSD retention remains behind cache operations. |
|
|
1874
|
-
|
|
1875
|
-
An interface boundary does not require copying tensors, downloading logits,
|
|
1876
|
-
or adding an RPC or synchronization per token. Device handles can stay lazy;
|
|
1877
|
-
the backend may fuse compatible graph and sampling operations while preserving
|
|
1878
|
-
policy, ownership and observable results. Each component can improve its own
|
|
1879
|
-
implementation without adding model, cache or sampling decisions to scheduling.
|
|
1880
|
-
|
|
1881
|
-
Contract sources: [generation](../../src/contracts/generation.ts),
|
|
1882
|
-
[scheduling](../../src/contracts/scheduling.ts),
|
|
1883
|
-
[sampling](../../src/contracts/sampling.ts),
|
|
1884
|
-
[prefix cache](../../src/contracts/prefix-cache.ts),
|
|
1885
|
-
[graph](../../src/inference/graph.ts),
|
|
1886
|
-
[tokenizer](../../src/tokenizer.ts),
|
|
1887
|
-
[cache tiers](../../src/prompt-cache.ts).
|
|
1888
|
-
Performance evidence and default selection live in
|
|
1889
|
-
[benchmarks.md](../reference/benchmarks.md); open acceptance remains in Phase 6/18.
|
|
1890
|
-
|
|
1891
|
-
#### Kernel configuration ownership
|
|
1892
|
-
|
|
1893
|
-
Shared and serial bindings execute within one immutable `RuntimeConfig`.
|
|
1894
|
-
Numerical helpers read that scope; they do not read process environment in
|
|
1895
|
-
forward loops. The serial speculative trace switch is captured once per run.
|
|
1896
|
-
Trellis mode resolves through the same configuration port at weight creation.
|
|
1897
|
-
|
|
1898
|
-
TurboQuant caches capture their codec's fused-decode choice at construction.
|
|
1899
|
-
RAM clones, full-prefill row restoration, batch layout factories, extraction
|
|
1900
|
-
and delayed conversion preserve that choice. KV maintenance binds its runtime
|
|
1901
|
-
before conversion, including conversion performed after a host setting changes.
|
|
1902
|
-
SSD formats contain numerical state, not a frozen process configuration; their
|
|
1903
|
-
receiving cache factory selects the destination binding's policy.
|
|
1904
|
-
|
|
1905
|
-
The configuration tests change host settings around scoped construction,
|
|
1906
|
-
copy/extraction and delayed conversion. Existing codec/donor tests now select
|
|
1907
|
-
both fused settings through `configureRuntime`, so they exercise the same
|
|
1908
|
-
configuration contract as serving. Paged request policies also bind the numerical
|
|
1909
|
-
namespace and construction policy before deferred lookup or allocation, including
|
|
1910
|
-
when a gateway outlives later host configuration changes. The serving reference
|
|
1911
|
-
maps flags to their owning interfaces and records supported combinations. The
|
|
1912
|
-
legacy internal `flagOn` wrapper is removed; CLI controls remain compatible.
|
|
1913
|
-
The new paged-policy tests first reproduce both deferred-setting failures, then
|
|
1914
|
-
pass with the captured policy. Paged operation/layout checks pass on both Macs;
|
|
1915
|
-
the full local model-free suite and all typechecks pass.
|
|
1916
|
-
|
|
1917
|
-
### 12.15 Package boundaries before community outreach
|
|
1918
|
-
|
|
1919
|
-
Initial audit, 2026-09-11. The public-readiness program owns the packaging
|
|
1920
|
-
work; the existing interface and optimization milestones retain their scope.
|
|
1921
|
-
The three published entry points need different treatment:
|
|
1922
|
-
|
|
1923
|
-
| Entry or layer | Verified dependency boundary | Packaging consequence |
|
|
1924
|
-
|---|---|---|
|
|
1925
|
-
| `mlx-bun/client`, `src/client.ts` | Imports only completion/host contracts; uses standard Request, Response, fetch and cancellation APIs | A candidate for independent client installation. The current npm package still has Darwin/arm64 metadata and application dependencies; a portable source file alone does not change that install contract. |
|
|
1926
|
-
| `src/contracts/`, `src/engine/`, `src/inference/` | Separate TypeScript project excludes Bun and DOM types; the AST boundary test limits imports by layer | Keep these interfaces and policies together inside the engine. They do not each need a published package. |
|
|
1927
|
-
| `mlx-bun/engine`, `src/library.ts` | CPU-safe entry exports engine/client APIs, but `initializeMlx()` dynamically imports the broad root API; `openIsolatedHost()` imports serving isolation and locates the CLI | Preserve this compatibility entry. Separate native engine initialization from application/worker assembly before treating it as a standalone engine package. |
|
|
1928
|
-
| `mlx-bun`, `src/index.ts` | Re-exports concrete models, generation, downloads, registry, fit and server construction | Already a published compatibility API. A workspace move needs forwarding exports, not a silent reduction of available functionality. |
|
|
1929
|
-
| Browser application | Own TypeScript project; boundary test allows web code and contracts | A candidate private application workspace. Its assets still participate in the CLI/native bundle. |
|
|
1930
|
-
| Website | Already has its own package manifest and build; generates reference pages from canonical docs | Keep one source for reference facts. A root workspace declaration alone would not improve this ownership. |
|
|
1931
|
-
|
|
1932
|
-
The source audit followed static imports, re-exports, type imports and literal
|
|
1933
|
-
`import()`/`require()` references using TypeScript module resolution. The
|
|
1934
|
-
client closure contained four source files and no external module imports.
|
|
1935
|
-
The high-level engine entry reached the broad root API, including Pi and web
|
|
1936
|
-
assets. This is a dependency inventory, not a claim that importing the
|
|
1937
|
-
CPU-safe entry eagerly loads those modules. Non-code assets and executable
|
|
1938
|
-
paths also need a packaging check; import analysis cannot establish that they
|
|
1939
|
-
ship correctly.
|
|
1940
|
-
|
|
1941
|
-
Recommended direction for the remaining audit: one engine package containing
|
|
1942
|
-
models, native bindings, cache codecs, inference methods and their interfaces;
|
|
1943
|
-
application assembly outside it; a small client package if independent
|
|
1944
|
-
installation is useful. Keep specialized kernels and tensor ownership within
|
|
1945
|
-
that engine. Memory, Pi and training require their own dependency and asset
|
|
1946
|
-
review before deciding whether they become private workspaces. A general MLX
|
|
1947
|
-
array binding is a separate API commitment and is not implied by this split.
|
|
1948
|
-
|
|
1949
|
-
Before choosing and implementing the layout, map the engine-to-application
|
|
1950
|
-
edges through server construction, native bootstrap, worker commands and
|
|
1951
|
-
bundled assets. Verify the package tarball and a consumer installed outside
|
|
1952
|
-
the repository. Public import compatibility and the single-binary release are
|
|
1953
|
-
acceptance requirements. The initial audit does not yet close the package
|
|
1954
|
-
organization milestone.
|
|
1955
|
-
|
|
1956
|
-
The initial `bun pm pack --dry-run --ignore-scripts` also confirms that the
|
|
1957
|
-
package includes the whole `docs/` tree, including archived investigations
|
|
1958
|
-
and active plans. Review that allowlist during packaging work; these are not
|
|
1959
|
-
runtime dependencies. This dry run inventories the candidate but does not
|
|
1960
|
-
replace installation and asset checks against an actual tarball.
|
|
1961
|
-
|
|
1962
|
-
|
|
1963
|
-
### 12.15 Prefill workspace policy
|
|
1964
|
-
|
|
1965
|
-
`PrefillPolicy` selects a request's chunk size independently of scheduling,
|
|
1966
|
-
cache placement and sampling. The MLX backend captures model geometry and
|
|
1967
|
-
explicit configuration when it binds the policy. Ordinary generation,
|
|
1968
|
-
shared rows and speculative preparation consume the selected size through
|
|
1969
|
-
their existing prefill interfaces. A caller's explicit request value wins.
|
|
1970
|
-
The automatic recurrent-attention policy bounds the temporary materialized
|
|
1971
|
-
SDPA score workspace; it does not inspect live free memory or refuse work.
|
|
1972
|
-
Default values and precedence live in [server configuration](../reference/server-config.md).
|
|
1973
|
-
|
|
1974
|
-
### 12.16 Committed append cache formats
|
|
1975
|
-
|
|
1976
|
-
`MlxTokenAppend` declares supported affine precisions and TurboQuant K/V
|
|
1977
|
-
formats. Qualified Qwen27B bindings expose KV4/KV8 and K8V3.
|
|
1978
|
-
Request preparation supplies template-derived candidates; placement selects
|
|
1979
|
-
an eligible method without inspecting numerical cache formats. The ordinary
|
|
1980
|
-
method consumes the binding's declaration once and uses its committed-append
|
|
1981
|
-
operation. Qwen shares projection work over known tokens while retaining each
|
|
1982
|
-
query's one-token affine attention calculation and causal KV extent.
|
|
1983
|
-
`KvMaintenance.maxAppendTokens` bounds a committed chunk at a pending
|
|
1984
|
-
precision transition; the method runs maintenance before continuing.
|
|
1985
|
-
Verification remains a separate method capability: enabling committed
|
|
1986
|
-
quantized appends does not enable quantized echo verification. No default fill setting or
|
|
1987
|
-
shared-group support is inferred from that declaration.
|