mlx-bun 0.5.0 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1449 -109
- package/THIRD_PARTY_NOTICES.md +882 -0
- package/bin/mlx-bun.convert.mjs +4 -0
- package/bin/mlx-bun.fuse.mjs +4 -0
- package/bin/mlx-bun.generate.mjs +4 -0
- package/bin/mlx-bun.lora.mjs +4 -0
- package/bin/mlx-bun.mjs +13 -21
- package/bin/mlx-bun.server.mjs +4 -0
- package/bin/mlx-bun.upload.mjs +4 -0
- package/dist/web/app.js +9584 -0
- package/package.json +50 -53
- package/src/cli/ane-install.ts +76 -0
- package/src/cli/args.ts +179 -0
- package/src/cli/engine-entry.ts +68 -0
- package/src/cli/inference.ts +214 -0
- package/src/cli/job-entry.ts +97 -0
- package/src/cli/library-host.ts +117 -0
- package/src/cli/main.ts +57 -0
- package/src/cli/memory-engine.ts +163 -0
- package/src/cli/memory.ts +36 -0
- package/src/cli/mlx-lm-aliases.ts +309 -0
- package/src/cli/model-choice.ts +33 -0
- package/src/cli/model-selection.ts +84 -0
- package/src/cli/module-host.ts +11 -0
- package/src/cli/module-verbs.ts +50 -0
- package/src/cli/numerical-policy.ts +12 -0
- package/src/cli/perplexity.ts +89 -0
- package/src/cli/serve-host.ts +423 -0
- package/src/cli/serve-isolated.ts +217 -0
- package/src/cli/serve-options.ts +106 -0
- package/src/cli/serve-state.ts +205 -0
- package/src/cli/serve.ts +500 -0
- package/src/cli/served-model-host.ts +102 -0
- package/src/cli/server-entry.ts +148 -0
- package/src/cli/serving-unit.ts +177 -0
- package/src/{tui.ts → cli/terminal.ts} +13 -8
- package/src/cli/worker-adapters.ts +34 -0
- package/src/cli/worker-entry.ts +272 -0
- package/src/cli/worker-unit.ts +179 -0
- package/src/engine/adapter-operation.ts +26 -0
- package/src/engine/cache-services.ts +114 -0
- package/src/engine/completion.ts +39 -0
- package/src/engine/generation-gateway.ts +358 -0
- package/src/engine/index.ts +59 -0
- package/src/engine/kv-budget.ts +120 -0
- package/src/engine/media-preparation.ts +232 -0
- package/src/engine/model-binding.ts +24 -0
- package/src/engine/model-host.ts +513 -0
- package/src/engine/model-serving.ts +89 -0
- package/src/{serve → engine}/preparation.ts +7 -5
- package/src/{serve → engine}/session-completion-engine.ts +6 -6
- package/src/engine/telemetry.ts +109 -0
- package/src/hub/downloads.ts +116 -0
- package/src/jobs/db.ts +16 -7
- package/src/jobs/events.ts +29 -0
- package/src/jobs/executable.ts +5 -0
- package/src/jobs/host.ts +51 -0
- package/src/jobs/in-process.ts +55 -0
- package/src/{contracts/jobs.ts → jobs/protocol.ts} +7 -9
- package/src/jobs/runner.ts +150 -231
- package/src/jobs/service.ts +75 -0
- package/src/jobs/sse.ts +59 -23
- package/src/jobs/worker-memory.ts +46 -0
- package/src/jobs/worker-process.ts +163 -0
- package/src/jobs/worker-supervisor.ts +258 -0
- package/src/modules.ts +58 -0
- package/src/publishing/catalog-hub.ts +18 -0
- package/src/publishing/credentials.ts +31 -0
- package/src/publishing/upload.ts +37 -0
- package/src/residency/leased-adapters.ts +21 -0
- package/src/residency/local-records.ts +16 -0
- package/src/residency/model-residency.ts +405 -0
- package/src/residency/record-index.ts +28 -0
- package/src/residency/resident-estimate.ts +50 -0
- package/src/{anthropic.ts → server/anthropic.ts} +3 -81
- package/src/server/cache-routes.ts +36 -0
- package/src/{serve → server}/chat-request.ts +10 -10
- package/src/{serve → server}/chat-stage.ts +14 -14
- package/src/{client.ts → server/client.ts} +28 -2
- package/src/{serve → server}/completion-executor.ts +33 -41
- package/src/server/decision-body.ts +55 -0
- package/src/server/decision-routes.ts +134 -0
- package/src/server/decision-wire.ts +228 -0
- package/src/{serve → server}/discovery-routes.ts +25 -82
- package/src/{serve → server}/http.ts +25 -13
- package/src/{serve → server}/inference-request.ts +5 -5
- package/src/server/job-routes.ts +20 -0
- package/src/server/media-prompt.ts +63 -0
- package/src/server/memory-completion-client.ts +46 -0
- package/src/server/model-routes.ts +192 -0
- package/src/{serve → server}/openai-wire.ts +3 -2
- package/src/{serve → server}/pipeline.ts +1 -1
- package/src/server/prompt-builder.ts +13 -0
- package/src/server/prompt-contracts.ts +17 -0
- package/src/server/proxy-routes.ts +187 -0
- package/src/server/publishing-routes.ts +41 -0
- package/src/{serve → server}/request-plan.ts +6 -8
- package/src/{serve → server}/request-prep.ts +47 -50
- package/src/{serve → server}/responses-client.ts +30 -13
- package/src/{responses.ts → server/responses.ts} +12 -93
- package/src/server/routes.ts +205 -0
- package/src/server/start.ts +72 -0
- package/src/server/status-routes.ts +108 -0
- package/src/{serve → server}/text-completion-stage.ts +25 -4
- package/src/server/text-prompt.ts +12 -0
- package/src/{serve → server}/token-streams.ts +36 -38
- package/src/server/worker-routes.ts +311 -0
- package/src/storage/paths.ts +61 -0
- package/src/web/assets.ts +37 -0
- package/src/web/{src → browser}/api.ts +5 -23
- package/src/web/browser/chat-host.ts +17 -0
- package/src/web/browser/installed-panels.ts +6 -0
- package/src/web/browser/main.ts +55 -0
- package/src/web/browser/markdown.ts +279 -0
- package/src/web/browser/memory-panel.ts +9 -0
- package/src/web/browser/palette.ts +64 -0
- package/src/web/browser/protocol.ts +13 -0
- package/src/web/browser/shell.ts +467 -0
- package/src/web/{src → browser}/status.ts +32 -36
- package/src/web/build.ts +51 -0
- package/src/web/public/app.html +1054 -0
- package/src/web/{sw.js → public/sw.js} +4 -3
- package/src/web/{vendor → public/vendor}/hljs-theme.css +2 -2
- package/src/web/{vendor → public/vendor}/hljs.js +2 -2
- package/THIRD_PARTY_LICENSES.md +0 -51
- package/docs/README.md +0 -107
- package/docs/archive/hlg-sampling.md +0 -350
- package/docs/archive/investigations/audio-input-plan.md +0 -356
- package/docs/archive/investigations/benchmark-ledger-through-v0.4.0.md +0 -3617
- package/docs/archive/investigations/chunk-finetune-experiment.md +0 -84
- package/docs/archive/investigations/colibri-glm52-port.md +0 -1486
- package/docs/archive/investigations/colibri-oracle-pin.md +0 -1284
- package/docs/archive/investigations/curve-bisector-routing.md +0 -123
- package/docs/archive/investigations/decode-roofline-lookagain.md +0 -348
- package/docs/archive/investigations/diffusion-gemma-port.md +0 -602
- package/docs/archive/investigations/dspark-handoff.md +0 -224
- package/docs/archive/investigations/expert-offload-single-user-moe.md +0 -292
- package/docs/archive/investigations/faithful-l1-consolidation.md +0 -310
- package/docs/archive/investigations/hlg-sampling-investigation.md +0 -970
- package/docs/archive/investigations/indexshare-performance-spike.md +0 -357
- package/docs/archive/investigations/kernel-perf-review-2026-07.md +0 -171
- package/docs/archive/investigations/lab-build-journal.md +0 -157
- package/docs/archive/investigations/minicpm5-decode-megakernel.md +0 -489
- package/docs/archive/investigations/openjarvis-fit.md +0 -198
- package/docs/archive/investigations/openwiki-evaluation.md +0 -249
- package/docs/archive/investigations/optimization_plan.md +0 -346
- package/docs/archive/investigations/orpo-base-uf-experiment-and-directions.md +0 -120
- package/docs/archive/investigations/orpo-flash-cce-pin-leak.md +0 -167
- package/docs/archive/investigations/orpo-uf-testing-handoff.md +0 -126
- package/docs/archive/investigations/pareto-specialized-runtime-findings.md +0 -92
- package/docs/archive/investigations/pi-builtin-investigation.md +0 -308
- package/docs/archive/investigations/pre-colibri-stabilization.md +0 -329
- package/docs/archive/investigations/qwen38-27b-campaign-log.md +0 -1092
- package/docs/archive/investigations/segmented-backward-handoff.md +0 -148
- package/docs/archive/investigations/starter-model-port-handoff.md +0 -342
- package/docs/archive/investigations/steel-flash-cce-handoff.md +0 -489
- package/docs/archive/investigations/the-dreaming-handoff.md +0 -141
- package/docs/archive/investigations/trainer-validation-experiment.md +0 -173
- package/docs/archive/planning/chat-ui-vision-memory-first.md +0 -199
- package/docs/archive/planning/chat-ui-vision.md +0 -50
- package/docs/archive/planning/chunk-task-roadmap.md +0 -77
- package/docs/archive/planning/curve-sampler-research-plan.md +0 -331
- package/docs/archive/planning/journal.md +0 -316
- package/docs/archive/planning/memory-docs-and-dag-plan.md +0 -194
- package/docs/archive/planning/pi-integration-review.md +0 -178
- package/docs/archive/planning/release-notes-v0.0.10.md +0 -57
- package/docs/archive/planning/release-notes-v0.0.11.md +0 -239
- package/docs/archive/planning/release-notes-v0.0.12.md +0 -80
- package/docs/archive/planning/release-notes-v0.0.13.md +0 -77
- package/docs/archive/planning/release-notes-v0.0.9.md +0 -122
- package/docs/archive/planning/release-notes-v0.2.0.md +0 -49
- package/docs/archive/planning/release-notes-v0.3.0.md +0 -35
- package/docs/archive/planning/release-notes-v0.4.0.md +0 -45
- package/docs/archive/planning/release-notes-v0.5.0.md +0 -37
- package/docs/archive/planning/web-ui-pass-plan.md +0 -213
- package/docs/archive/planning/website-readme-pass-plan.md +0 -224
- package/docs/design/batching.md +0 -2054
- package/docs/design/decode-speed-program.md +0 -2404
- package/docs/design/dreaming-nightly-pipeline.md +0 -684
- package/docs/design/generic-model-support.md +0 -821
- package/docs/design/kv-cache.md +0 -993
- package/docs/design/orpo-training.md +0 -680
- package/docs/design/speculative-decoding.md +0 -2129
- package/docs/design/turboquant.md +0 -2225
- package/docs/design/unified-engine-frontier-plan.md +0 -1987
- package/docs/design/web-chat-redesign.md +0 -695
- package/docs/planning/PRODUCT_ROADMAP.md +0 -593
- package/docs/planning/ResearchTopics.md +0 -119
- package/docs/planning/public-readiness-handoff.md +0 -244
- package/docs/planning/public-readiness.md +0 -149
- package/docs/planning/video-series.md +0 -421
- package/docs/reference/benchmarks.md +0 -3587
- package/docs/reference/cli.md +0 -646
- package/docs/reference/distribution.md +0 -380
- package/docs/reference/environment.md +0 -494
- package/docs/reference/glossary.md +0 -39
- package/docs/reference/library-api.md +0 -688
- package/docs/reference/memory.md +0 -260
- package/docs/reference/models.md +0 -346
- package/docs/reference/server-api.md +0 -1945
- package/docs/reference/server-config.md +0 -973
- package/docs/reference/training.md +0 -462
- package/docs/reference/troubleshooting.md +0 -158
- package/src/admission-plan.ts +0 -18
- package/src/audio/audiotoolbox.ts +0 -112
- package/src/audio/conformer.ts +0 -655
- package/src/audio/decode.ts +0 -133
- package/src/audio/features.ts +0 -202
- package/src/audio/mic-capture.ts +0 -98
- package/src/audio/silero-vad.ts +0 -379
- package/src/audio/transcode.ts +0 -67
- package/src/audio/whisper-decode.ts +0 -774
- package/src/audio/whisper-fast.ts +0 -732
- package/src/audio/whisper-format.ts +0 -73
- package/src/audio/whisper-mel.ts +0 -185
- package/src/audio/whisper-timing.ts +0 -274
- package/src/audio/whisper-tokenizer.ts +0 -239
- package/src/audio/whisper-transcribe.ts +0 -410
- package/src/backends/mlx/assistant-target.ts +0 -46
- package/src/backends/mlx/autoregressive-draft-rows.ts +0 -120
- package/src/backends/mlx/autoregressive.ts +0 -129
- package/src/backends/mlx/batch-group.ts +0 -1874
- package/src/backends/mlx/cache-attachment.ts +0 -67
- package/src/backends/mlx/cache-layout.ts +0 -31
- package/src/backends/mlx/checkpoint-state.ts +0 -53
- package/src/backends/mlx/continuation-persistence.ts +0 -107
- package/src/backends/mlx/continuation-request.ts +0 -43
- package/src/backends/mlx/continuation.ts +0 -77
- package/src/backends/mlx/diffusion.ts +0 -39
- package/src/backends/mlx/draft-target.ts +0 -32
- package/src/backends/mlx/encoder-cache.ts +0 -25
- package/src/backends/mlx/evaluation.ts +0 -105
- package/src/backends/mlx/fill-append.ts +0 -58
- package/src/backends/mlx/fill-group.ts +0 -497
- package/src/backends/mlx/full-kv-row-append.ts +0 -32
- package/src/backends/mlx/full-kv-row-donor.ts +0 -54
- package/src/backends/mlx/full-transitioning-kv-rows.ts +0 -65
- package/src/backends/mlx/gateway-binding.ts +0 -174
- package/src/backends/mlx/graph.ts +0 -38
- package/src/backends/mlx/kv-codec.ts +0 -9
- package/src/backends/mlx/kv-maintenance.ts +0 -161
- package/src/backends/mlx/kv-tensor-rows.ts +0 -212
- package/src/backends/mlx/memory-client.ts +0 -189
- package/src/backends/mlx/methods.ts +0 -90
- package/src/backends/mlx/mixed-iteration.ts +0 -62
- package/src/backends/mlx/model-prompt.ts +0 -178
- package/src/backends/mlx/model-serving.ts +0 -80
- package/src/backends/mlx/paged-cache-codec.ts +0 -27
- package/src/backends/mlx/prefill-cohort.ts +0 -100
- package/src/backends/mlx/prefill-policy.ts +0 -26
- package/src/backends/mlx/prefill-rows.ts +0 -244
- package/src/backends/mlx/prefill.ts +0 -33
- package/src/backends/mlx/projected-context-rows.ts +0 -72
- package/src/backends/mlx/prompt-input.ts +0 -29
- package/src/backends/mlx/qwen-prompt-input.ts +0 -40
- package/src/backends/mlx/request-policy.ts +0 -20
- package/src/backends/mlx/request-state-policy.ts +0 -54
- package/src/backends/mlx/rollback.ts +0 -92
- package/src/backends/mlx/row-sampling.ts +0 -49
- package/src/backends/mlx/serial-executor.ts +0 -251
- package/src/backends/mlx/speculative-group.ts +0 -438
- package/src/backends/mlx/speculative-round.ts +0 -161
- package/src/backends/mlx/speculative.ts +0 -131
- package/src/backends/mlx/state-rows.ts +0 -104
- package/src/backends/mlx/state-views.ts +0 -46
- package/src/backends/mlx/target-layout-capability.ts +0 -35
- package/src/backends/mlx/text-engine.ts +0 -73
- package/src/backends/mlx/transitioning-kv-rows.ts +0 -173
- package/src/chat-template.ts +0 -382
- package/src/cli.ts +0 -3490
- package/src/config.ts +0 -399
- package/src/contracts/completion.ts +0 -16
- package/src/contracts/execution.ts +0 -70
- package/src/contracts/generation.ts +0 -103
- package/src/contracts/host.ts +0 -7
- package/src/contracts/object-cache.ts +0 -8
- package/src/contracts/pi-provider.ts +0 -30
- package/src/contracts/pi.ts +0 -261
- package/src/contracts/prefix-cache.ts +0 -33
- package/src/contracts/resources.ts +0 -25
- package/src/contracts/sampling.ts +0 -23
- package/src/contracts/scheduling.ts +0 -54
- package/src/contracts/tsconfig.json +0 -14
- package/src/dataset/generators.ts +0 -1087
- package/src/dataset/index.ts +0 -12
- package/src/dataset/job.ts +0 -81
- package/src/dataset/llm.ts +0 -71
- package/src/dataset/registry.ts +0 -528
- package/src/diffusion/diffusion-generate.ts +0 -507
- package/src/download.ts +0 -505
- package/src/embed.ts +0 -77
- package/src/engine/admission.ts +0 -59
- package/src/engine/cancellation.ts +0 -38
- package/src/engine/engine.ts +0 -56
- package/src/engine/execution-coordinator.ts +0 -70
- package/src/engine/execution-plan.ts +0 -64
- package/src/engine/execution-tasks.ts +0 -44
- package/src/engine/namespaced-cache.ts +0 -13
- package/src/engine/resources.ts +0 -53
- package/src/engine/scheduler.ts +0 -92
- package/src/engine/session.ts +0 -247
- package/src/eval/README.md +0 -130
- package/src/eval/ifeval.ts +0 -81
- package/src/eval/kl-prompts.ts +0 -29
- package/src/eval/kl.ts +0 -590
- package/src/eval/perplexity.ts +0 -164
- package/src/eval/quality-db.ts +0 -92
- package/src/eval/reference-logits.ts +0 -207
- package/src/eval/runner.ts +0 -124
- package/src/eval/score.ts +0 -49
- package/src/eval/tasks/bfcl.ts +0 -535
- package/src/eval/tasks/gsm8k.ts +0 -98
- package/src/eval/tasks/hashhop.ts +0 -139
- package/src/eval/tasks/humaneval.ts +0 -275
- package/src/eval/tasks/ifeval.ts +0 -525
- package/src/eval/tasks/mmlu.ts +0 -157
- package/src/eval/ultrafeedback.ts +0 -60
- package/src/evaldb.ts +0 -199
- package/src/expert-io.ts +0 -393
- package/src/expert-offload-build.ts +0 -77
- package/src/expert-offload.ts +0 -76
- package/src/expert-residency.ts +0 -1134
- package/src/expert-usage.ts +0 -415
- package/src/fill/echo-index.ts +0 -188
- package/src/fill/fill-session.ts +0 -463
- package/src/fill/proposal.ts +0 -68
- package/src/fill/schema-rows.ts +0 -506
- package/src/fill/tool-boundary.ts +0 -103
- package/src/fit.ts +0 -249
- package/src/generate.ts +0 -1352
- package/src/grammar.ts +0 -604
- package/src/harness-pi.ts +0 -184
- package/src/hf-push.ts +0 -628
- package/src/hub-rest.ts +0 -242
- package/src/index.ts +0 -63
- package/src/inference/denoising.ts +0 -17
- package/src/inference/draft-acceptance.ts +0 -41
- package/src/inference/draft-output.ts +0 -49
- package/src/inference/graph.ts +0 -33
- package/src/inference/prefill.ts +0 -45
- package/src/inference/rollback.ts +0 -7
- package/src/jobs/index.ts +0 -31
- package/src/jobs/job-entry.ts +0 -107
- package/src/jobs/task-client.ts +0 -19
- package/src/jobs/types.ts +0 -2
- package/src/kv-scheme.ts +0 -279
- package/src/kv-store.ts +0 -1135
- package/src/lab/README.md +0 -22
- package/src/lab/curve/curve-designer.html +0 -303
- package/src/lab/curve/curve-sampler.ts +0 -122
- package/src/lab/expert-trace/expert-trace.ts +0 -69
- package/src/lab/paged-kv/paged-attention.ts +0 -117
- package/src/lab/paged-kv/paged-kv-rows.ts +0 -111
- package/src/lab/paged-kv/paged-kv.ts +0 -336
- package/src/library.ts +0 -40
- package/src/lora.ts +0 -408
- package/src/md-modules.d.ts +0 -54
- package/src/media-fetch.ts +0 -442
- package/src/memory/article.ts +0 -558
- package/src/memory/chunk-validation.ts +0 -150
- package/src/memory/chunk.ts +0 -318
- package/src/memory/cluster.ts +0 -351
- package/src/memory/coverage.ts +0 -134
- package/src/memory/crosslink.ts +0 -0
- package/src/memory/db.ts +0 -253
- package/src/memory/entity.ts +0 -203
- package/src/memory/gate.ts +0 -187
- package/src/memory/history.ts +0 -152
- package/src/memory/ingest.ts +0 -335
- package/src/memory/model.ts +0 -183
- package/src/memory/normalize.ts +0 -671
- package/src/memory/parse.ts +0 -22
- package/src/memory/pipeline.ts +0 -275
- package/src/memory/prompts.ts +0 -65
- package/src/memory/query.ts +0 -334
- package/src/memory/reconcile.ts +0 -734
- package/src/memory/redirect.ts +0 -108
- package/src/memory/reindex.ts +0 -325
- package/src/memory/resolve.ts +0 -307
- package/src/memory/rest.ts +0 -245
- package/src/memory/route.ts +0 -272
- package/src/memory/schedule.ts +0 -165
- package/src/memory/stages.ts +0 -777
- package/src/memory/synthesize.ts +0 -1638
- package/src/memory/tools.ts +0 -749
- package/src/memory/vault.ts +0 -1194
- package/src/memory/wikify.ts +0 -1064
- package/src/mlx/array.ts +0 -425
- package/src/mlx/autograd.ts +0 -304
- package/src/mlx/checkpoint.ts +0 -149
- package/src/mlx/compile.ts +0 -168
- package/src/mlx/custom-vjp.ts +0 -188
- package/src/mlx/ffi.ts +0 -531
- package/src/mlx/materialize.ts +0 -23
- package/src/mlx/metal-kernel.ts +0 -159
- package/src/mlx/normalized-argmax.ts +0 -116
- package/src/mlx/ops.ts +0 -1108
- package/src/mlx/quantized-rows.ts +0 -36
- package/src/mlx/token-bitmask.ts +0 -52
- package/src/mlx/turboquant-kv-decode.ts +0 -82
- package/src/mlx/turboquant-kv-inverse.ts +0 -122
- package/src/mlx/turboquant-ops.ts +0 -861
- package/src/mlx/turboquant-tables.ts +0 -237
- package/src/mmap.ts +0 -90
- package/src/model/artifact-identity.ts +0 -73
- package/src/model/batched-kv.ts +0 -235
- package/src/model/batched-mask.ts +0 -279
- package/src/model/batched-quant.ts +0 -212
- package/src/model/batched-quantized-kv.ts +0 -144
- package/src/model/batched-rotating-quant.ts +0 -353
- package/src/model/batched-rotating-state.ts +0 -149
- package/src/model/batched-rotating.ts +0 -338
- package/src/model/batched-row-storage.ts +0 -179
- package/src/model/batched-ssm.ts +0 -52
- package/src/model/batched-turboquant-kv.ts +0 -94
- package/src/model/compiled-decode.ts +0 -712
- package/src/model/decoded-kv-donor.ts +0 -12
- package/src/model/delayed-quantized-kv.ts +0 -72
- package/src/model/delayed-rotating-quantized-kv.ts +0 -93
- package/src/model/delayed-turboquant-kv.ts +0 -57
- package/src/model/diffusion-gemma.ts +0 -1026
- package/src/model/factory.ts +0 -215
- package/src/model/fingerprint.ts +0 -45
- package/src/model/flash-attention.ts +0 -694
- package/src/model/full-prefill-padding.ts +0 -56
- package/src/model/full-prefill-row.ts +0 -105
- package/src/model/gemma4-base.ts +0 -2370
- package/src/model/gemma4.ts +0 -1395
- package/src/model/generated/gemma4-12b.ts +0 -429
- package/src/model/generated/gemma4-26b.ts +0 -448
- package/src/model/generated/gemma4-e4b.ts +0 -717
- package/src/model/generated/index.ts +0 -18
- package/src/model/glm52-atlas.ts +0 -511
- package/src/model/glm52-cache.ts +0 -792
- package/src/model/glm52-config.ts +0 -262
- package/src/model/glm52-container.ts +0 -305
- package/src/model/glm52-coupling.ts +0 -388
- package/src/model/glm52-dsa.ts +0 -606
- package/src/model/glm52-expert-layout.ts +0 -253
- package/src/model/glm52-layout.ts +0 -152
- package/src/model/glm52-memory.ts +0 -500
- package/src/model/glm52-mla.ts +0 -792
- package/src/model/glm52-moe.ts +0 -223
- package/src/model/glm52-pilot.ts +0 -537
- package/src/model/glm52-reference.ts +0 -445
- package/src/model/glm52-residency.ts +0 -557
- package/src/model/glm52-resident-weights.ts +0 -135
- package/src/model/glm52-streamed-experts.ts +0 -453
- package/src/model/glm52-streamed-metal.ts +0 -610
- package/src/model/glm52-weights.ts +0 -503
- package/src/model/glm52.ts +0 -1132
- package/src/model/implementation.ts +0 -69
- package/src/model/kv-attention-view.ts +0 -70
- package/src/model/minicpm5.ts +0 -376
- package/src/model/profile.ts +0 -468
- package/src/model/quantized-append-attention.ts +0 -31
- package/src/model/qwen-append.ts +0 -12
- package/src/model/qwen-conv.ts +0 -52
- package/src/model/qwen3-delta-state.ts +0 -74
- package/src/model/qwen3-delta.ts +0 -451
- package/src/model/qwen3-moe.ts +0 -404
- package/src/model/qwen3-mrope.ts +0 -250
- package/src/model/qwen3.ts +0 -277
- package/src/model/qwen3_5-checkpoint.ts +0 -164
- package/src/model/qwen3_5.ts +0 -881
- package/src/model/rotating-kv-donor.ts +0 -35
- package/src/model/rotating-kv-layout.ts +0 -262
- package/src/model/rotating-row-transaction.ts +0 -35
- package/src/model/speculative-rotating-kv.ts +0 -101
- package/src/model/ssm-prefill-padding.ts +0 -39
- package/src/model/support.ts +0 -110
- package/src/model/token-groups.ts +0 -66
- package/src/model/trellis-balanced-scatter.ts +0 -51
- package/src/model/trellis-linear.ts +0 -672
- package/src/model/trellis-shared-m.ts +0 -151
- package/src/model/trellis-shared-scatter.ts +0 -144
- package/src/model/trellis-splitk-prefill.ts +0 -158
- package/src/model/trellis-tiled-prefill.ts +0 -136
- package/src/model/trellis-vector-expand.ts +0 -62
- package/src/model/trellis-wide-prefill.ts +0 -94
- package/src/model/turboquant-codec.ts +0 -89
- package/src/model/universal/archs.ts +0 -332
- package/src/model/universal/dense.ts +0 -612
- package/src/model/universal/modules.ts +0 -170
- package/src/model/universal/rope.ts +0 -381
- package/src/model/whisper.ts +0 -435
- package/src/native/expert_io.c +0 -523
- package/src/native/frame_extract.swift +0 -140
- package/src/native/mic_capture.swift +0 -92
- package/src/native-pack.ts +0 -163
- package/src/pi-provider.ts +0 -53
- package/src/pi-session.ts +0 -81
- package/src/pi-terminal.ts +0 -274
- package/src/pi-web.ts +0 -1940
- package/src/preflight.ts +0 -158
- package/src/prompt-cache.ts +0 -682
- package/src/quantize/allocator.ts +0 -627
- package/src/quantize/atomic-output.ts +0 -38
- package/src/quantize/calibration.ts +0 -181
- package/src/quantize/config-writer.ts +0 -145
- package/src/quantize/index.ts +0 -84
- package/src/quantize/job.ts +0 -162
- package/src/quantize/quantizer.ts +0 -666
- package/src/quantize/rotate.ts +0 -603
- package/src/quantize/safetensors-writer.ts +0 -249
- package/src/quantize/sensitivity.ts +0 -216
- package/src/quantize/trellis.ts +0 -586
- package/src/quantize/weight-transform.ts +0 -292
- package/src/registry.ts +0 -602
- package/src/runtime-config.ts +0 -77
- package/src/safetensors.ts +0 -165
- package/src/sampler.ts +0 -1012
- package/src/serve/admin-routes.ts +0 -184
- package/src/serve/assets/curve-terrain.html +0 -105
- package/src/serve/assets/training-inference-map.html +0 -575
- package/src/serve/audio-routes.ts +0 -323
- package/src/serve/aux-routes.ts +0 -132
- package/src/serve/batch-scheduler.ts +0 -8
- package/src/serve/checkpoint-identity.ts +0 -64
- package/src/serve/generation-gateway.ts +0 -537
- package/src/serve/isolate.ts +0 -609
- package/src/serve/kv-budget.ts +0 -14
- package/src/serve/lab-routes.ts +0 -341
- package/src/serve/lane-registry.ts +0 -45
- package/src/serve/model-admin-routes.ts +0 -155
- package/src/serve/model-binding.ts +0 -49
- package/src/serve/model-host.ts +0 -511
- package/src/serve/parent-application.ts +0 -56
- package/src/serve/prompt-response-trace.ts +0 -161
- package/src/serve/response-lease.ts +0 -24
- package/src/serve/session-search.ts +0 -326
- package/src/serve/static-routes.ts +0 -101
- package/src/serve/transcription-server.ts +0 -64
- package/src/serve/transcription-service.ts +0 -502
- package/src/server.ts +0 -1282
- package/src/spec/assistant-rows.ts +0 -93
- package/src/spec/assistant-source.ts +0 -126
- package/src/spec/cache-identity.ts +0 -22
- package/src/spec/deepspec-rows.ts +0 -29
- package/src/spec/deepspec-source.ts +0 -145
- package/src/spec/dflash-source.ts +0 -149
- package/src/spec/drafter.ts +0 -304
- package/src/spec/dspark/ab-stats.ts +0 -136
- package/src/spec/dspark/calibration.ts +0 -112
- package/src/spec/dspark/data-dflash.ts +0 -156
- package/src/spec/dspark/data.ts +0 -201
- package/src/spec/dspark/deepspec-module.ts +0 -776
- package/src/spec/dspark/generate-dflash.ts +0 -245
- package/src/spec/dspark/generate.ts +0 -290
- package/src/spec/dspark/loader.ts +0 -23
- package/src/spec/dspark/loss.ts +0 -213
- package/src/spec/dspark/module-dflash.ts +0 -560
- package/src/spec/dspark/module.ts +0 -540
- package/src/spec/dspark/quantize-drafter.ts +0 -91
- package/src/spec/dspark/sample.ts +0 -112
- package/src/spec/generate.ts +0 -276
- package/src/spec/glm52-mtp-graph.ts +0 -29
- package/src/spec/glm52-mtp-rows.ts +0 -132
- package/src/spec/glm52-mtp-source.ts +0 -318
- package/src/spec/glm52-mtp-state.ts +0 -33
- package/src/spec/ngram-source.ts +0 -226
- package/src/spec/projected-draft-rows.ts +0 -73
- package/src/spec/qwen-mtp-module.ts +0 -171
- package/src/spec/qwen-mtp-rows.ts +0 -230
- package/src/spec/qwen-mtp-source.ts +0 -386
- package/src/spec/qwen-mtp-state.ts +0 -30
- package/src/spec/serve-loop.ts +0 -587
- package/src/spec/source.ts +0 -228
- package/src/spec/two-model-rows.ts +0 -62
- package/src/spec/two-model.ts +0 -113
- package/src/ssd-cache.ts +0 -431
- package/src/ssd-durability.ts +0 -209
- package/src/storage/host-buffer.ts +0 -24
- package/src/storage/kv-writer.ts +0 -83
- package/src/storage/kv-writer.worker.js +0 -264
- package/src/storage/retention-policy.ts +0 -37
- package/src/tiered-prompt-cache.ts +0 -45
- package/src/tokenizer.ts +0 -335
- package/src/tool-approvals.ts +0 -131
- package/src/tool-call.ts +0 -695
- package/src/train/dataset.ts +0 -484
- package/src/train/diffusion-lora.ts +0 -216
- package/src/train/export.ts +0 -32
- package/src/train/flash-cce.ts +0 -1234
- package/src/train/forward.ts +0 -266
- package/src/train/fuse.ts +0 -243
- package/src/train/index.ts +0 -46
- package/src/train/job.ts +0 -205
- package/src/train/lora-params.ts +0 -254
- package/src/train/loss.ts +0 -1591
- package/src/train/merge.ts +0 -195
- package/src/train/optimizer.ts +0 -183
- package/src/train/prefix-shared.ts +0 -490
- package/src/train/rank.ts +0 -137
- package/src/train/segmented.ts +0 -1828
- package/src/train/steel-qmm-header.ts +0 -1461
- package/src/train/trainer.ts +0 -1221
- package/src/train/watch.ts +0 -542
- package/src/vision/diffusion-vision.ts +0 -620
- package/src/vision/embedder.ts +0 -176
- package/src/vision/preprocess.ts +0 -247
- package/src/vision/prompt.ts +0 -409
- package/src/vision/qwen3vl-preprocess.ts +0 -409
- package/src/vision/qwen3vl-prompt.ts +0 -233
- package/src/vision/qwen3vl-tower.ts +0 -566
- package/src/vision/siglip.ts +0 -607
- package/src/vision/video-frames.ts +0 -148
- package/src/web/app.html +0 -2155
- package/src/web/app.js +0 -5863
- package/src/web/skills/memory/SKILL.md +0 -120
- package/src/web/skills/web-research/SKILL.md +0 -46
- package/src/web/skills.ts +0 -97
- package/src/web/src/adapters-panel.ts +0 -288
- package/src/web/src/assistant.ts +0 -451
- package/src/web/src/chat.ts +0 -1060
- package/src/web/src/composer.ts +0 -962
- package/src/web/src/dataset.ts +0 -132
- package/src/web/src/finetune.ts +0 -267
- package/src/web/src/hub.ts +0 -428
- package/src/web/src/main.ts +0 -98
- package/src/web/src/markdown.ts +0 -0
- package/src/web/src/memory-panel.ts +0 -572
- package/src/web/src/model-picker.ts +0 -159
- package/src/web/src/palette.ts +0 -346
- package/src/web/src/protocol.ts +0 -26
- package/src/web/src/quantize.ts +0 -167
- package/src/web/src/rag.ts +0 -274
- package/src/web/src/sessions.ts +0 -469
- package/src/web/src/shell.ts +0 -804
- package/src/web/src/ui-catalog.ts +0 -78
- package/src/web/src/voice.ts +0 -141
- package/src/web/vendor/README.md +0 -61
- package/src/web-assets.ts +0 -47
- package/src/web-tools.ts +0 -478
- package/src/weights.ts +0 -255
- /package/src/{serve → server}/completion-sink.ts +0 -0
- /package/src/{serve → server}/generated-token-history.ts +0 -0
- /package/src/web/{icon.svg → public/icon.svg} +0 -0
- /package/src/web/{manifest.webmanifest → public/manifest.webmanifest} +0 -0
- /package/src/web/{vendor → public/vendor}/hljs-LICENSE +0 -0
package/src/serve/isolate.ts
DELETED
|
@@ -1,609 +0,0 @@
|
|
|
1
|
-
import { ExecutionCoordinator } from "../engine/execution-coordinator";
|
|
2
|
-
import { AdmissionPool, AdmissionRejected } from "../engine/admission";
|
|
3
|
-
import { acquireReservation } from "./preparation";
|
|
4
|
-
import { createParentApplication } from "./parent-application";
|
|
5
|
-
import type { DisposableResource } from "../contracts/resources";
|
|
6
|
-
import { retainResponseLease } from "./response-lease";
|
|
7
|
-
import type { EngineHost } from "../contracts/host";
|
|
8
|
-
// Runtime isolation — the parent half (docs/reference/server-config.md).
|
|
9
|
-
//
|
|
10
|
-
// ARCHITECTURE (decision 2026-07-05, deviating from the doc's original
|
|
11
|
-
// structured-IPC sketch — recorded there): the inference ENGINE is the
|
|
12
|
-
// ENTIRE existing server, spawned as a child process listening on a unix
|
|
13
|
-
// domain socket; this module is the parent — a thin reverse proxy that
|
|
14
|
-
// binds the TCP port, forwards everything to the child, and NEVER touches
|
|
15
|
-
// MLX. Rationale: the gateway-as-IPC-client cut would have to serialize
|
|
16
|
-
// grammar controllers (WASM), vision embeddings (GPU arrays), sampler
|
|
17
|
-
// closures, and prompt-cache hooks across a message protocol — weeks of
|
|
18
|
-
// re-plumbing; HTTP-over-UDS reuses the whole serving stack verbatim,
|
|
19
|
-
// streams SSE for free, and turns cancellation into plain abort
|
|
20
|
-
// propagation (client disconnect → proxied fetch aborts → the child's
|
|
21
|
-
// existing disconnect handling fires).
|
|
22
|
-
//
|
|
23
|
-
// Isolation properties delivered:
|
|
24
|
-
// - The parent event loop only proxies (fully async) — UI/API stay
|
|
25
|
-
// instant no matter what the GPU is doing.
|
|
26
|
-
// - A child crash (uncatchable Metal OOM/SIGTRAP) 502s in-flight requests
|
|
27
|
-
// and RESPAWNS the engine; the parent — and the user's session — never
|
|
28
|
-
// go down. "The AI may crash, the UI never may."
|
|
29
|
-
// - P2 (multi-model): one child per model, each on its own socket; the
|
|
30
|
-
// parent routes by the request's `model` field and switches by
|
|
31
|
-
// spawn-overlap (new child loads while the old one keeps serving).
|
|
32
|
-
//
|
|
33
|
-
// Not proxied in v1: /ws/chat (WebSocket upgrade) — answered 501 with a
|
|
34
|
-
// pointer; the pi-based chat UI runs against the direct (non-isolated)
|
|
35
|
-
// server until WS proxying lands.
|
|
36
|
-
|
|
37
|
-
import { unlinkSync } from "node:fs";
|
|
38
|
-
import { tmpdir } from "node:os";
|
|
39
|
-
import { join } from "node:path";
|
|
40
|
-
|
|
41
|
-
/** How to (re)start the engine child. `argv[0]` is the executable. */
|
|
42
|
-
export interface EngineSpec {
|
|
43
|
-
/** Parent-owned activity lease; covers startup and complete response bodies. */
|
|
44
|
-
acquire?: (signal: AbortSignal) => Promise<DisposableResource>;
|
|
45
|
-
argv: string[];
|
|
46
|
-
socketPath: string;
|
|
47
|
-
/** Max ms to wait for the child's /health after spawn (weights load —
|
|
48
|
-
* large models take a while). Default 15 min. */
|
|
49
|
-
readyTimeoutMs?: number;
|
|
50
|
-
/** Bound automatic restarts in a rolling window, including startup failure. */
|
|
51
|
-
maxRestarts?: number;
|
|
52
|
-
restartWindowMs?: number;
|
|
53
|
-
restartDelayMs?: number;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
const HOP_BY_HOP = new Set([
|
|
57
|
-
"connection", "keep-alive", "proxy-authenticate", "proxy-authorization",
|
|
58
|
-
"te", "trailer", "transfer-encoding", "upgrade",
|
|
59
|
-
]);
|
|
60
|
-
|
|
61
|
-
export function defaultSocketPath(): string {
|
|
62
|
-
return join(tmpdir(), `mlx-bun-engine-${process.pid}.sock`);
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
/** The persistent engine child: spawn, health-gate, respawn-on-crash. */
|
|
66
|
-
export class EngineChild implements EngineHost<Request, Response> {
|
|
67
|
-
readonly spec: EngineSpec;
|
|
68
|
-
#proc: ReturnType<typeof Bun.spawn> | null = null;
|
|
69
|
-
#ready: Promise<void>;
|
|
70
|
-
#stopping = false;
|
|
71
|
-
#lifetime = new AbortController();
|
|
72
|
-
restarts = 0;
|
|
73
|
-
#lastSpawnAt = 0;
|
|
74
|
-
#restartTimes: number[] = [];
|
|
75
|
-
#backoff: ReturnType<typeof setTimeout> | undefined;
|
|
76
|
-
#wakeBackoff: (() => void) | undefined;
|
|
77
|
-
#startups = new Set<Promise<void>>();
|
|
78
|
-
|
|
79
|
-
constructor(spec: EngineSpec) {
|
|
80
|
-
this.spec = Object.freeze({ ...spec, argv: [...spec.argv] });
|
|
81
|
-
this.#ready = this.#spawn();
|
|
82
|
-
void this.#ready.catch(() => {}); // failures remain observable through ready/forward
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
get ready(): Promise<void> {
|
|
86
|
-
return this.#ready;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
get pid(): number | null {
|
|
90
|
-
return this.#proc?.pid ?? null;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
#spawn(): Promise<void> {
|
|
94
|
-
const work = this.#start();
|
|
95
|
-
this.#startups.add(work);
|
|
96
|
-
void work.finally(() => this.#startups.delete(work)).catch(() => {});
|
|
97
|
-
return work;
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
async #start(): Promise<void> {
|
|
101
|
-
if (this.#stopping) throw new Error("engine host is closed");
|
|
102
|
-
const lease = await this.spec.acquire?.(this.#lifetime.signal);
|
|
103
|
-
let starting: ReturnType<typeof Bun.spawn> | undefined;
|
|
104
|
-
let healthy = false;
|
|
105
|
-
try {
|
|
106
|
-
if (this.#stopping) throw new Error("engine host is closed");
|
|
107
|
-
this.#lastSpawnAt = Date.now();
|
|
108
|
-
try { unlinkSync(this.spec.socketPath); } catch {}
|
|
109
|
-
const proc = Bun.spawn(this.spec.argv, {
|
|
110
|
-
stdio: ["ignore", "inherit", "inherit"], // load progress → user's terminal
|
|
111
|
-
env: process.env,
|
|
112
|
-
});
|
|
113
|
-
this.#proc = proc;
|
|
114
|
-
starting = proc;
|
|
115
|
-
void proc.exited.then((code) => {
|
|
116
|
-
if (this.#stopping || this.#proc !== proc) return;
|
|
117
|
-
const now = Date.now();
|
|
118
|
-
const window = this.spec.restartWindowMs ?? 60_000;
|
|
119
|
-
this.#restartTimes = this.#restartTimes.filter((time) => now - time < window);
|
|
120
|
-
if (this.#restartTimes.length >= (this.spec.maxRestarts ?? 3)) {
|
|
121
|
-
this.#ready = Promise.reject(new Error(`engine restart limit reached after exit ${code}`));
|
|
122
|
-
void this.#ready.catch(() => {});
|
|
123
|
-
return;
|
|
124
|
-
}
|
|
125
|
-
this.#restartTimes.push(now);
|
|
126
|
-
console.error(`[isolate] engine exited (code ${code}) — respawning`);
|
|
127
|
-
this.restarts++;
|
|
128
|
-
// Crash-loop backoff: an engine that dies within 10 s of spawning
|
|
129
|
-
// (bad flags, OOM on load) waits 5 s before the retry.
|
|
130
|
-
const delay = this.spec.restartDelayMs ?? (Date.now() - this.#lastSpawnAt < 10_000 ? 5_000 : 0);
|
|
131
|
-
this.#ready = new Promise<void>((resolve) => {
|
|
132
|
-
this.#wakeBackoff = resolve;
|
|
133
|
-
this.#backoff = setTimeout(resolve, delay);
|
|
134
|
-
}).then(() => {
|
|
135
|
-
this.#backoff = undefined; this.#wakeBackoff = undefined;
|
|
136
|
-
return this.#spawn();
|
|
137
|
-
});
|
|
138
|
-
void this.#ready.catch(() => {});
|
|
139
|
-
});
|
|
140
|
-
// Health-gate: poll the child's /health over the socket until it
|
|
141
|
-
// answers — model load happens behind this.
|
|
142
|
-
const deadline = Date.now() + (this.spec.readyTimeoutMs ?? 15 * 60_000);
|
|
143
|
-
while (Date.now() < deadline) {
|
|
144
|
-
if (this.#stopping || proc.killed || proc.exitCode !== null || this.#proc !== proc)
|
|
145
|
-
throw new Error("engine died during startup");
|
|
146
|
-
try {
|
|
147
|
-
const r = await fetch("http://engine/health", {
|
|
148
|
-
unix: this.spec.socketPath,
|
|
149
|
-
signal: AbortSignal.timeout(2_000),
|
|
150
|
-
} as RequestInit & { unix: string });
|
|
151
|
-
if (r.ok) { healthy = true; return; }
|
|
152
|
-
} catch { /* not up yet */ }
|
|
153
|
-
await new Promise((r) => setTimeout(r, 250));
|
|
154
|
-
}
|
|
155
|
-
proc.kill();
|
|
156
|
-
throw new Error("engine did not become healthy in time");
|
|
157
|
-
} finally {
|
|
158
|
-
if (!healthy && starting && starting.exitCode === null) {
|
|
159
|
-
starting.kill();
|
|
160
|
-
const force = setTimeout(() => { if (starting!.exitCode === null) starting!.kill("SIGKILL"); }, 3000);
|
|
161
|
-
try { await starting.exited; } finally { clearTimeout(force); }
|
|
162
|
-
}
|
|
163
|
-
lease?.dispose();
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
/** Forward one request to the child; the response streams through.
|
|
168
|
-
* Bodyless requests (GET/HEAD) retry ONCE after a respawn completes —
|
|
169
|
-
* a request that races an engine crash waits out the reload instead of
|
|
170
|
-
* 502ing; requests with consumed stream bodies cannot be replayed and
|
|
171
|
-
* 502 by design (the doc's "fail in-flight cleanly"). */
|
|
172
|
-
async forward(request: Request): Promise<Response> {
|
|
173
|
-
try {
|
|
174
|
-
return await this.#forwardOnce(request);
|
|
175
|
-
} catch (e) {
|
|
176
|
-
const retriable = (request.method === "GET" || request.method === "HEAD") &&
|
|
177
|
-
!request.signal.aborted;
|
|
178
|
-
if (!retriable) throw e;
|
|
179
|
-
// The exited-handler may not have swapped #ready yet — give it a beat.
|
|
180
|
-
await new Promise((r) => setTimeout(r, 250));
|
|
181
|
-
return await this.#forwardOnce(request);
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
async #forwardOnce(request: Request): Promise<Response> {
|
|
186
|
-
if (this.#stopping) throw new Error("engine host is closed");
|
|
187
|
-
request.signal.throwIfAborted();
|
|
188
|
-
await new Promise<void>((resolve, reject) => {
|
|
189
|
-
const abort = () => { request.signal.removeEventListener("abort", abort); reject(request.signal.reason); };
|
|
190
|
-
request.signal.addEventListener("abort", abort, { once: true });
|
|
191
|
-
this.#ready.then(() => { request.signal.removeEventListener("abort", abort); resolve(); },
|
|
192
|
-
(error) => { request.signal.removeEventListener("abort", abort); reject(error); });
|
|
193
|
-
});
|
|
194
|
-
if (this.#stopping) throw new Error("engine host is closed");
|
|
195
|
-
request.signal.throwIfAborted();
|
|
196
|
-
const signal = AbortSignal.any([request.signal, this.#lifetime.signal]);
|
|
197
|
-
const lease = await this.spec.acquire?.(signal);
|
|
198
|
-
try {
|
|
199
|
-
signal.throwIfAborted();
|
|
200
|
-
const headers = new Headers();
|
|
201
|
-
request.headers.forEach((v, k) => {
|
|
202
|
-
if (!HOP_BY_HOP.has(k.toLowerCase())) headers.set(k, v);
|
|
203
|
-
});
|
|
204
|
-
const proxied = await fetch(request.url, {
|
|
205
|
-
method: request.method,
|
|
206
|
-
headers,
|
|
207
|
-
body: request.body,
|
|
208
|
-
signal, // client abort → child sees the disconnect
|
|
209
|
-
redirect: "manual",
|
|
210
|
-
unix: this.spec.socketPath,
|
|
211
|
-
// Streaming request bodies need half-duplex; buffered bodies ignore it.
|
|
212
|
-
duplex: "half",
|
|
213
|
-
} as RequestInit & { unix: string; duplex: string });
|
|
214
|
-
const outHeaders = new Headers();
|
|
215
|
-
proxied.headers.forEach((v, k) => {
|
|
216
|
-
if (!HOP_BY_HOP.has(k.toLowerCase())) outHeaders.set(k, v);
|
|
217
|
-
});
|
|
218
|
-
const response = new Response(proxied.body, { status: proxied.status, headers: outHeaders });
|
|
219
|
-
return lease ? retainResponseLease(response, lease) : response;
|
|
220
|
-
} catch (error) { lease?.dispose(); throw error; }
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
/** A live UDS response owns the worker's native lease. Disconnect releases it
|
|
224
|
-
* even if the parent crashes. External cancellation applies to acquisition;
|
|
225
|
-
* the returned owner alone releases an admitted lease after job death. */
|
|
226
|
-
async reserveExecution(signal: AbortSignal): Promise<DisposableResource> {
|
|
227
|
-
if (!this.#proc || this.#proc.exitCode !== null) return { dispose() {} };
|
|
228
|
-
const abort = new AbortController();
|
|
229
|
-
const cancel = () => abort.abort(signal.reason);
|
|
230
|
-
signal.throwIfAborted();
|
|
231
|
-
signal.addEventListener("abort", cancel, { once: true });
|
|
232
|
-
try {
|
|
233
|
-
const response = await fetch("http://engine/admin/lease", {
|
|
234
|
-
method: "POST", unix: this.spec.socketPath, signal: abort.signal,
|
|
235
|
-
} as RequestInit & { unix: string });
|
|
236
|
-
if (!response.ok) { await response.body?.cancel(); throw new Error(`worker lease failed (${response.status})`); }
|
|
237
|
-
return { dispose() { abort.abort(); void response.body?.cancel().catch(() => {}); } };
|
|
238
|
-
} catch (error) { abort.abort(); throw error; }
|
|
239
|
-
finally { signal.removeEventListener("abort", cancel); }
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
stop(): void {
|
|
243
|
-
this.#stopping = true;
|
|
244
|
-
this.#lifetime.abort(new Error("engine host is closed"));
|
|
245
|
-
clearTimeout(this.#backoff);
|
|
246
|
-
this.#wakeBackoff?.();
|
|
247
|
-
this.#proc?.kill();
|
|
248
|
-
try { unlinkSync(this.spec.socketPath); } catch {}
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
async close(): Promise<void> {
|
|
252
|
-
this.stop();
|
|
253
|
-
const process = this.#proc;
|
|
254
|
-
const force = process ? setTimeout(() => { if (process.exitCode === null) process.kill("SIGKILL"); }, 3000) : undefined;
|
|
255
|
-
try {
|
|
256
|
-
// Startup owns an admission lease even before a child exists. Earlier
|
|
257
|
-
// crashed attempts can still be unwinding after #ready switches to a retry.
|
|
258
|
-
await Promise.allSettled([this.#ready, ...this.#startups, ...(process ? [process.exited] : [])]);
|
|
259
|
-
} finally { if (force) clearTimeout(force); }
|
|
260
|
-
}
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
/** Model resolution the parent injects (Registry-backed in production;
|
|
264
|
-
* a plain map in tests). Returns null for unknown names — those keep the
|
|
265
|
-
* drop-in ignore semantics (served by the default model, like mlx-lm). */
|
|
266
|
-
export type ModelResolver = (query: string) => { repoId: string; path: string } | null;
|
|
267
|
-
|
|
268
|
-
/** Child-per-model pool (P2, docs/reference/server-config.md): LRU residency over
|
|
269
|
-
* engine children. Eviction is graceful and lossless — POST /admin/drain
|
|
270
|
-
* (gateway quiesce + demote the prompt cache to the SSD tier, keyed by
|
|
271
|
-
* that model's own fingerprint dir) and only then stop the child; the
|
|
272
|
-
* evicted model's whole state survives on disk, so bringing it back is a
|
|
273
|
-
* spawn + mmap fault-in + zero-copy KV restore, not a re-prefill. A
|
|
274
|
-
* SWITCH is spawn-overlap: the new child health-gates while the old one
|
|
275
|
-
* keeps serving — nobody's session is interrupted. */
|
|
276
|
-
export class ModelPool {
|
|
277
|
-
#children = new Map<string, EngineChild>(); // repoId → child
|
|
278
|
-
#lru: string[] = []; // most-recent last
|
|
279
|
-
#spawning = new Map<string, Promise<EngineChild>>();
|
|
280
|
-
#coldStarts = new AdmissionPool(1);
|
|
281
|
-
#starting = new Set<EngineChild>();
|
|
282
|
-
#stopping = false;
|
|
283
|
-
readonly defaultKey: string;
|
|
284
|
-
|
|
285
|
-
constructor(
|
|
286
|
-
private readonly opts: {
|
|
287
|
-
rawArgs: string[];
|
|
288
|
-
selfArgv: string[]; // how to re-exec this CLI
|
|
289
|
-
poolMax: number; // resident children cap (≥1)
|
|
290
|
-
resolve: ModelResolver;
|
|
291
|
-
defaultKey: string;
|
|
292
|
-
defaultChild: EngineChild;
|
|
293
|
-
socketFor?: (repoId: string) => string;
|
|
294
|
-
},
|
|
295
|
-
) {
|
|
296
|
-
this.defaultKey = opts.defaultKey;
|
|
297
|
-
this.#children.set(opts.defaultKey, opts.defaultChild);
|
|
298
|
-
this.#lru.push(opts.defaultKey);
|
|
299
|
-
}
|
|
300
|
-
|
|
301
|
-
get residentKeys(): string[] {
|
|
302
|
-
return [...this.#children.keys()];
|
|
303
|
-
}
|
|
304
|
-
|
|
305
|
-
child(key: string): EngineChild | undefined {
|
|
306
|
-
return this.#children.get(key);
|
|
307
|
-
}
|
|
308
|
-
|
|
309
|
-
#bump(key: string): void {
|
|
310
|
-
this.#lru = this.#lru.filter((k) => k !== key);
|
|
311
|
-
this.#lru.push(key);
|
|
312
|
-
}
|
|
313
|
-
|
|
314
|
-
#socketFor(repoId: string): string {
|
|
315
|
-
if (this.opts.socketFor) return this.opts.socketFor(repoId);
|
|
316
|
-
const slug = repoId.replace(/[^a-zA-Z0-9.-]+/g, "_").slice(-60);
|
|
317
|
-
return join(tmpdir(), `mlx-bun-engine-${process.pid}-${slug}.sock`);
|
|
318
|
-
}
|
|
319
|
-
|
|
320
|
-
/** Route a request's `model` field to a child, spawning on first use.
|
|
321
|
-
* undefined/empty/unknown → the default child (drop-in semantics). */
|
|
322
|
-
async childFor(modelField: string | undefined | null): Promise<EngineChild> {
|
|
323
|
-
if (this.#stopping) throw new Error("model pool is closed");
|
|
324
|
-
modelField ||= this.defaultKey;
|
|
325
|
-
// Already resident under this exact id?
|
|
326
|
-
if (this.#children.has(modelField)) return this.#use(modelField);
|
|
327
|
-
const rec = (() => {
|
|
328
|
-
try { return this.opts.resolve(modelField); } catch { return null; }
|
|
329
|
-
})();
|
|
330
|
-
if (!rec && modelField !== this.defaultKey) return this.childFor(this.defaultKey);
|
|
331
|
-
const resolved = rec ?? { repoId: this.defaultKey, path: "" };
|
|
332
|
-
if (this.#children.has(resolved.repoId)) return this.#use(resolved.repoId);
|
|
333
|
-
const inflight = this.#spawning.get(resolved.repoId);
|
|
334
|
-
if (inflight) return inflight.then(() => this.#use(resolved.repoId));
|
|
335
|
-
const spawnP = (async () => {
|
|
336
|
-
const admission = await this.#coldStarts.acquire();
|
|
337
|
-
try {
|
|
338
|
-
if (this.#stopping) throw new Error("model pool is closed");
|
|
339
|
-
const sock = this.#socketFor(resolved.repoId);
|
|
340
|
-
const child = new EngineChild(resolved.repoId === this.defaultKey ? this.opts.defaultChild.spec : {
|
|
341
|
-
argv: [...this.opts.selfArgv, ...engineArgvForModel(this.opts.rawArgs, sock, resolved.path)],
|
|
342
|
-
socketPath: sock,
|
|
343
|
-
acquire: this.opts.defaultChild.spec.acquire,
|
|
344
|
-
});
|
|
345
|
-
this.#starting.add(child);
|
|
346
|
-
try {
|
|
347
|
-
await child.ready;
|
|
348
|
-
if (this.#stopping) throw new Error("model pool is closed");
|
|
349
|
-
this.#children.set(resolved.repoId, child);
|
|
350
|
-
this.#lru.push(resolved.repoId);
|
|
351
|
-
await this.#evictOverCap();
|
|
352
|
-
return child;
|
|
353
|
-
} catch (error) {
|
|
354
|
-
await child.close();
|
|
355
|
-
throw error;
|
|
356
|
-
} finally { this.#starting.delete(child); }
|
|
357
|
-
} finally { admission.dispose(); }
|
|
358
|
-
})();
|
|
359
|
-
this.#spawning.set(resolved.repoId, spawnP);
|
|
360
|
-
try {
|
|
361
|
-
return await spawnP;
|
|
362
|
-
} finally {
|
|
363
|
-
this.#spawning.delete(resolved.repoId);
|
|
364
|
-
}
|
|
365
|
-
}
|
|
366
|
-
|
|
367
|
-
#use(key: string): EngineChild {
|
|
368
|
-
this.#bump(key);
|
|
369
|
-
const child = this.#children.get(key);
|
|
370
|
-
if (!child) throw new Error(`model ${key} is no longer resident`);
|
|
371
|
-
return child;
|
|
372
|
-
}
|
|
373
|
-
|
|
374
|
-
/** Evict least-recently-used children over the cap: drain + demote (the
|
|
375
|
-
* child's caches spill to its SSD fingerprint dir), then stop. */
|
|
376
|
-
async #evictOverCap(): Promise<void> {
|
|
377
|
-
while (this.#children.size > Math.max(1, this.opts.poolMax)) {
|
|
378
|
-
const victim = this.#lru.find((k) => this.#children.has(k));
|
|
379
|
-
if (!victim || this.#children.size <= 1) return;
|
|
380
|
-
const child = this.#children.get(victim)!;
|
|
381
|
-
const lease = await child.spec.acquire?.(AbortSignal.timeout(120_000));
|
|
382
|
-
try {
|
|
383
|
-
// Another overlapping eviction may have completed while we waited.
|
|
384
|
-
if (this.#children.get(victim) !== child) continue;
|
|
385
|
-
this.#children.delete(victim);
|
|
386
|
-
this.#lru = this.#lru.filter((k) => k !== victim);
|
|
387
|
-
try {
|
|
388
|
-
const response = await fetch("http://engine/admin/drain", {
|
|
389
|
-
method: "POST", unix: child.spec.socketPath,
|
|
390
|
-
signal: AbortSignal.timeout(120_000),
|
|
391
|
-
} as RequestInit & { unix: string });
|
|
392
|
-
await response.arrayBuffer();
|
|
393
|
-
} catch { /* best-effort — state also persists via evict-spill */ }
|
|
394
|
-
await child.close();
|
|
395
|
-
console.log(`[isolate] evicted engine ${victim} (pool cap ${this.opts.poolMax})`);
|
|
396
|
-
} finally { lease?.dispose(); }
|
|
397
|
-
}
|
|
398
|
-
}
|
|
399
|
-
|
|
400
|
-
stopAll(): void {
|
|
401
|
-
this.#stopping = true;
|
|
402
|
-
this.#coldStarts.close();
|
|
403
|
-
for (const child of new Set([...this.#children.values(), ...this.#starting])) child.stop();
|
|
404
|
-
this.#children.clear();
|
|
405
|
-
this.#lru = [];
|
|
406
|
-
}
|
|
407
|
-
|
|
408
|
-
async close(): Promise<void> {
|
|
409
|
-
const children = new Set([...this.#children.values(), ...this.#starting]);
|
|
410
|
-
this.stopAll();
|
|
411
|
-
await Promise.all([...children].map((child) => child.close()));
|
|
412
|
-
await Promise.allSettled(this.#spawning.values());
|
|
413
|
-
}
|
|
414
|
-
}
|
|
415
|
-
|
|
416
|
-
/** Generation endpoints whose JSON body carries the routing `model` field. */
|
|
417
|
-
const MODEL_ROUTED = new Set([
|
|
418
|
-
"/v1/chat/completions", "/v1/completions", "/v1/messages",
|
|
419
|
-
"/v1/responses", "/v1/embeddings",
|
|
420
|
-
]);
|
|
421
|
-
|
|
422
|
-
export interface ProxyServerOptions {
|
|
423
|
-
/** Application-store injection for embedded hosts and model-free tests. */
|
|
424
|
-
createJobStore?: () => Promise<import("../jobs/db").JobStore>;
|
|
425
|
-
port: number;
|
|
426
|
-
hostname?: string;
|
|
427
|
-
engine: EngineSpec;
|
|
428
|
-
/** Multi-model pool (P2). Omitted = single-engine P1 behavior. */
|
|
429
|
-
pool?: {
|
|
430
|
-
rawArgs: string[];
|
|
431
|
-
selfArgv: string[];
|
|
432
|
-
poolMax: number;
|
|
433
|
-
resolve: ModelResolver;
|
|
434
|
-
defaultKey: string;
|
|
435
|
-
socketFor?: (repoId: string) => string;
|
|
436
|
-
};
|
|
437
|
-
}
|
|
438
|
-
|
|
439
|
-
/** The parent server: UI-facing TCP listener that proxies to the engine
|
|
440
|
-
* child (or, with `pool`, to the request's model's child — P2 routing).
|
|
441
|
-
* Returns the Bun server + handles (tests kill/inspect). */
|
|
442
|
-
export function startProxyServer(opts: ProxyServerOptions): {
|
|
443
|
-
server: ReturnType<typeof Bun.serve>;
|
|
444
|
-
engine: EngineChild;
|
|
445
|
-
pool: ModelPool | null;
|
|
446
|
-
close(): Promise<void>;
|
|
447
|
-
} {
|
|
448
|
-
const coordinator = new ExecutionCoordinator();
|
|
449
|
-
const acquire = (mode: "shared" | "exclusive", signal: AbortSignal) =>
|
|
450
|
-
acquireReservation({ acquire: (cancellation) => coordinator.acquire(mode, cancellation) }, signal);
|
|
451
|
-
const engine = new EngineChild({ ...opts.engine, async acquire(signal) {
|
|
452
|
-
const parent = await acquire("shared", signal);
|
|
453
|
-
try {
|
|
454
|
-
const supplied = await opts.engine.acquire?.(signal);
|
|
455
|
-
return { dispose() { try { supplied?.dispose(); } finally { parent.dispose(); } } };
|
|
456
|
-
} catch (error) { parent.dispose(); throw error; }
|
|
457
|
-
} });
|
|
458
|
-
const pool = opts.pool
|
|
459
|
-
? new ModelPool({ ...opts.pool, defaultChild: engine })
|
|
460
|
-
: null;
|
|
461
|
-
const children = () => pool ? pool.residentKeys.map((key) => pool.child(key)!).filter(Boolean) : [engine];
|
|
462
|
-
const forwardRequest = async (request: Request): Promise<Response> => {
|
|
463
|
-
const url = new URL(request.url);
|
|
464
|
-
// P2 routing: generation endpoints carry `model` in the JSON body —
|
|
465
|
-
// buffer it (small), pick/spawn that model's child, forward the
|
|
466
|
-
// buffered body. Everything else rides the default engine.
|
|
467
|
-
if (pool && request.method === "POST" && MODEL_ROUTED.has(url.pathname)) {
|
|
468
|
-
const raw = await request.text();
|
|
469
|
-
let modelField: string | undefined;
|
|
470
|
-
try { modelField = (JSON.parse(raw) as { model?: string }).model; } catch { /* malformed → default child answers with its own 400 */ }
|
|
471
|
-
const target = await pool.childFor(modelField);
|
|
472
|
-
return await target.forward(new Request(request.url, {
|
|
473
|
-
method: request.method,
|
|
474
|
-
headers: request.headers,
|
|
475
|
-
body: raw,
|
|
476
|
-
signal: request.signal,
|
|
477
|
-
}));
|
|
478
|
-
}
|
|
479
|
-
return await (pool ? await pool.childFor(undefined) : engine).forward(request);
|
|
480
|
-
};
|
|
481
|
-
const application = createParentApplication({
|
|
482
|
-
createJobStore: opts.createJobStore,
|
|
483
|
-
serverPort: () => server.port,
|
|
484
|
-
async acquireGpu(signal) {
|
|
485
|
-
const lease = await acquire("exclusive", signal);
|
|
486
|
-
try {
|
|
487
|
-
// Network cancellation is not a native completion fence. Explicitly
|
|
488
|
-
// drain every resident worker before the subprocess may touch the GPU.
|
|
489
|
-
const results = await Promise.allSettled(children().map((child) => child.reserveExecution(signal)));
|
|
490
|
-
const held = results.filter((result) => result.status === "fulfilled").map((result) => result.value);
|
|
491
|
-
const failed = results.find((result) => result.status === "rejected");
|
|
492
|
-
if (failed) { for (const worker of held) worker.dispose(); throw failed.reason; }
|
|
493
|
-
return { dispose() { for (const worker of held) worker.dispose(); lease.dispose(); } };
|
|
494
|
-
} catch (error) { lease.dispose(); throw error; }
|
|
495
|
-
},
|
|
496
|
-
invalidateLibrary() {
|
|
497
|
-
for (const child of children()) void child.forward(new Request("http://engine/library?refresh=1"))
|
|
498
|
-
.then((response) => response.arrayBuffer()).catch(() => {});
|
|
499
|
-
},
|
|
500
|
-
});
|
|
501
|
-
const server = Bun.serve({
|
|
502
|
-
port: opts.port,
|
|
503
|
-
...(opts.hostname ? { hostname: opts.hostname } : {}),
|
|
504
|
-
idleTimeout: 0,
|
|
505
|
-
async fetch(request) {
|
|
506
|
-
const url = new URL(request.url);
|
|
507
|
-
if (url.pathname === "/ws/chat")
|
|
508
|
-
return Response.json(
|
|
509
|
-
{ error: { message: "WebSocket chat is not proxied under --isolate yet; run without --isolate for the web chat UI" } },
|
|
510
|
-
{ status: 501 },
|
|
511
|
-
);
|
|
512
|
-
if (url.pathname === "/engine" && request.method === "GET") {
|
|
513
|
-
// A pool may have evicted and recreated the default worker. Inspect
|
|
514
|
-
// current residency without starting a worker merely for diagnostics.
|
|
515
|
-
const current = pool ? pool.child(pool.defaultKey) : engine;
|
|
516
|
-
return Response.json({
|
|
517
|
-
isolated: true,
|
|
518
|
-
response_store: application.responseStats,
|
|
519
|
-
pid: current?.pid ?? null,
|
|
520
|
-
restarts: current?.restarts ?? null,
|
|
521
|
-
socket: current?.spec.socketPath ?? null,
|
|
522
|
-
...(pool ? { pool: { resident: pool.residentKeys, default: pool.defaultKey } } : {}),
|
|
523
|
-
});
|
|
524
|
-
}
|
|
525
|
-
try {
|
|
526
|
-
const local = await application.handle(request, forwardRequest);
|
|
527
|
-
if (local) return local;
|
|
528
|
-
return await forwardRequest(request);
|
|
529
|
-
} catch (e) {
|
|
530
|
-
if (e instanceof AdmissionRejected) return Response.json(
|
|
531
|
-
{ error: { message: e.message, type: "resource_admission", code: "queue_full" } }, { status: 429 });
|
|
532
|
-
if (request.signal.aborted) return new Response(null, { status: 499 });
|
|
533
|
-
return Response.json(
|
|
534
|
-
{
|
|
535
|
-
error: {
|
|
536
|
-
message: `inference engine unavailable (${(e as Error).message}) — respawning; retry shortly`,
|
|
537
|
-
type: "engine_unavailable",
|
|
538
|
-
},
|
|
539
|
-
},
|
|
540
|
-
{ status: 502 },
|
|
541
|
-
);
|
|
542
|
-
}
|
|
543
|
-
},
|
|
544
|
-
});
|
|
545
|
-
let closing: Promise<void> | undefined;
|
|
546
|
-
return { server, engine, pool, close: () => closing ??= (async () => {
|
|
547
|
-
await server.stop(true);
|
|
548
|
-
coordinator.close();
|
|
549
|
-
await application.close();
|
|
550
|
-
if (pool) await pool.close(); else await engine.close();
|
|
551
|
-
})() };
|
|
552
|
-
}
|
|
553
|
-
|
|
554
|
-
/** serve's value-taking flags — needed to tell a flag VALUE from the bare
|
|
555
|
-
* model positional when stripping. Keep in sync with cli.ts serve opts
|
|
556
|
-
* (a stale entry here mis-classifies one token as a positional). */
|
|
557
|
-
const SERVE_VALUE_FLAGS = new Set([
|
|
558
|
-
"--port", "--host", "--model", "--query", "--draft-model",
|
|
559
|
-
"--num-draft-tokens", "--draft-kind", "--ngram-max", "--ngram-min",
|
|
560
|
-
"--batch", "--decode-concurrency", "--kv-quant",
|
|
561
|
-
"--kv-group-size", "--quantized-kv-start", "--kv-budget",
|
|
562
|
-
"--memory-budget", "--prompt-cache", "--ssd-cache", "--ssd-cache-max",
|
|
563
|
-
"--ssd-demote-idle", "--generation-checkpoint", "--adapter", "--max-tokens", "--unix",
|
|
564
|
-
"--model-pool", "--compiled-decode", "--compiled-activations",
|
|
565
|
-
"--fused-sdpa", "--thinking",
|
|
566
|
-
]);
|
|
567
|
-
const PARENT_BOOL_FLAGS = new Set(["--isolate", "--open", "--no-open"]);
|
|
568
|
-
const PARENT_VALUE_FLAGS = new Set(["--port", "--host", "--model-pool"]);
|
|
569
|
-
|
|
570
|
-
/** Build the engine child's argv from the parent's raw CLI args: strip the
|
|
571
|
-
* parent-only flags (--isolate, --port/--host — the child binds the
|
|
572
|
-
* socket; --open/--no-open — the browser is the parent's business;
|
|
573
|
-
* --model-pool — pool policy is the parent's) and append the socket.
|
|
574
|
-
* Exported for tests. */
|
|
575
|
-
export function engineArgv(rawArgs: string[], socketPath: string): string[] {
|
|
576
|
-
const out: string[] = [];
|
|
577
|
-
for (let i = 0; i < rawArgs.length; i++) {
|
|
578
|
-
const a = rawArgs[i]!;
|
|
579
|
-
if (PARENT_BOOL_FLAGS.has(a)) continue;
|
|
580
|
-
if (PARENT_VALUE_FLAGS.has(a)) { i++; continue; }
|
|
581
|
-
out.push(a);
|
|
582
|
-
}
|
|
583
|
-
out.push("--unix", socketPath);
|
|
584
|
-
return out;
|
|
585
|
-
}
|
|
586
|
-
|
|
587
|
-
/** engineArgv for a SPECIFIC model (the pool's per-model children): also
|
|
588
|
-
* strip every model selector — --model/--query values AND the bare
|
|
589
|
-
* positional query after `serve` — then pin `--model <path>`. */
|
|
590
|
-
export function engineArgvForModel(
|
|
591
|
-
rawArgs: string[], socketPath: string, modelPath: string,
|
|
592
|
-
): string[] {
|
|
593
|
-
const stripped: string[] = [];
|
|
594
|
-
let positionalSkipped = false;
|
|
595
|
-
for (let i = 0; i < rawArgs.length; i++) {
|
|
596
|
-
const a = rawArgs[i]!;
|
|
597
|
-
if (PARENT_BOOL_FLAGS.has(a)) continue;
|
|
598
|
-
if (a === "--model" || a === "--query") { i++; continue; }
|
|
599
|
-
if (PARENT_VALUE_FLAGS.has(a)) { i++; continue; }
|
|
600
|
-
if (SERVE_VALUE_FLAGS.has(a)) { stripped.push(a, rawArgs[++i]!); continue; }
|
|
601
|
-
if (!a.startsWith("-") && a !== "serve" && !positionalSkipped) {
|
|
602
|
-
positionalSkipped = true; // the bare model query
|
|
603
|
-
continue;
|
|
604
|
-
}
|
|
605
|
-
stripped.push(a);
|
|
606
|
-
}
|
|
607
|
-
if (stripped[0] !== "serve") stripped.unshift("serve");
|
|
608
|
-
return [...stripped, "--model", modelPath, "--unix", socketPath];
|
|
609
|
-
}
|
package/src/serve/kv-budget.ts
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import type { ModelConfig } from "../config";
|
|
2
|
-
import { kvBytesAt, KvScheme } from "../kv-scheme";
|
|
3
|
-
|
|
4
|
-
/** Project one batch row's worst-case KV bytes using the same per-layer
|
|
5
|
-
* scheme that the server-wide admission ceiling uses. */
|
|
6
|
-
export function batchRowKvBytes(
|
|
7
|
-
config: ModelConfig,
|
|
8
|
-
promptTokens: number,
|
|
9
|
-
maxTokens: number,
|
|
10
|
-
scheme?: KvScheme,
|
|
11
|
-
): number {
|
|
12
|
-
const tokens = promptTokens + maxTokens;
|
|
13
|
-
return scheme ? scheme.bytesAt(config, tokens) : kvBytesAt(config, tokens);
|
|
14
|
-
}
|