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,438 +0,0 @@
|
|
|
1
|
-
import {captureSpeculativeOptions, speculativePrefixNamespace} from "../../spec/cache-identity";
|
|
2
|
-
import type { RuntimeModel } from "../../model/factory";
|
|
3
|
-
import type { GenerateOptions } from "../../generate";
|
|
4
|
-
import type { FillSession, Proposal } from "../../fill/fill-session";
|
|
5
|
-
import type { DraftProvider, DraftRowGroup, DraftPrefillGroup, DraftRowCheckpoint } from "../../spec/source";
|
|
6
|
-
import { makeSampler, makeStepSampler, readStepExtras, type NumberStepSampler, type Sampler } from "../../sampler";
|
|
7
|
-
import { MlxArray } from "../../mlx/array";
|
|
8
|
-
import * as ops from "../../mlx/ops";
|
|
9
|
-
import { clearCache } from "../../mlx/ffi";
|
|
10
|
-
import { applyStateChanges, cleanupFailure, disposeResources } from "../../engine/resources";
|
|
11
|
-
import { cloneKvCaches } from "../../kv-store";
|
|
12
|
-
import type { Cache } from "../../model/gemma4-base";
|
|
13
|
-
import { targetCacheLayout } from "./cache-layout";
|
|
14
|
-
import { MlxStateRows } from "./state-rows";
|
|
15
|
-
import { bindSpeculativeTargetModel, type MlxSpeculativeTargetBinding } from "./speculative";
|
|
16
|
-
import { bindLegacyDraftTarget } from "./draft-target";
|
|
17
|
-
import { bindRowCacheRollback } from "./rollback";
|
|
18
|
-
import { createKvMaintenance } from "./kv-maintenance";
|
|
19
|
-
import { disposeAttachments, type CheckpointAttachment } from "./checkpoint-state";
|
|
20
|
-
import { advanceSpeculativeOutputs } from "./speculative-round";
|
|
21
|
-
import { MlxPrefillRows, type MlxPrefillState } from "./prefill-rows";
|
|
22
|
-
import type { MlxForwardWork } from "./mixed-iteration";
|
|
23
|
-
import type { MlxGroupMethodHost, MlxGroupMethodRequest, MlxGroupPreparation, MlxGroupedMethod, Row } from "./batch-group";
|
|
24
|
-
|
|
25
|
-
interface RequestState {
|
|
26
|
-
fill?: FillSession;
|
|
27
|
-
proposal?: { value: Proposal; emitted: number };
|
|
28
|
-
sampling: NumberStepSampler;
|
|
29
|
-
draftSampling: Sampler;
|
|
30
|
-
retain?: () => void;
|
|
31
|
-
namespace: string;
|
|
32
|
-
prefixLength: number;
|
|
33
|
-
/** Generated inputs retained by committed target/draft rounds. The pending
|
|
34
|
-
* correction is excluded until a later round actually processes it. */
|
|
35
|
-
processed?: number[];
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
/** Binding owns graph/layout selection. The executor receives only the method
|
|
39
|
-
* key and lifecycle; sampling, checkpoints and numerical state remain ports. */
|
|
40
|
-
export function bindSpeculativeGroupRequests(model: RuntimeModel, provider: Pick<DraftProvider, "id" | "grouped">, depth: number) {
|
|
41
|
-
const binding = bindSpeculativeTargetModel(model);
|
|
42
|
-
return (input: GenerateOptions): MlxGroupMethodRequest => {
|
|
43
|
-
const options = captureSpeculativeOptions(input);
|
|
44
|
-
return {
|
|
45
|
-
key: JSON.stringify(["speculative", provider.id, depth, options.kvBits ?? null,
|
|
46
|
-
options.kvGroupSize ?? 64, options.quantizedKvStart ?? null, options.turboQuant ?? null,
|
|
47
|
-
...(options.kvConfig?.length ? [options.kvConfig] : [])]),
|
|
48
|
-
data: options,
|
|
49
|
-
open: host => new SpeculativeGroup(host, model, provider, binding, depth),
|
|
50
|
-
};
|
|
51
|
-
};
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
class SpeculativeGroup implements MlxGroupedMethod {
|
|
55
|
-
#target: MlxStateRows<ReturnType<typeof targetCacheLayout>> | null = null;
|
|
56
|
-
#draft: DraftRowGroup | null = null;
|
|
57
|
-
readonly #requests = new Map<Row, RequestState>();
|
|
58
|
-
#steps = 0;
|
|
59
|
-
|
|
60
|
-
constructor(readonly host: MlxGroupMethodHost, readonly model: RuntimeModel,
|
|
61
|
-
readonly provider: Pick<DraftProvider, "id" | "grouped">, readonly binding: MlxSpeculativeTargetBinding, readonly depth: number) {}
|
|
62
|
-
|
|
63
|
-
get runningTokens(): number {
|
|
64
|
-
const rows = this.host.rows;
|
|
65
|
-
if (!rows.length) return 0;
|
|
66
|
-
// Target verification consumes the pending token and the draft candidates.
|
|
67
|
-
const echo = Math.max(...rows.map(row => {
|
|
68
|
-
const proposal = this.#requests.get(row)?.proposal;
|
|
69
|
-
return proposal?.emitted ? proposal.value.ids.length - proposal.emitted : 0;
|
|
70
|
-
}));
|
|
71
|
-
return rows.length * (1 + (echo || Math.min(this.depth, Math.max(...rows.map(row => row.req.maxTokens - row.generated)))));
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
prepare(first: Row): MlxGroupPreparation {
|
|
75
|
-
const method = this;
|
|
76
|
-
const options = first.req.method!.data as GenerateOptions;
|
|
77
|
-
const maintain = createKvMaintenance(options);
|
|
78
|
-
interface Preparation extends MlxPrefillState {
|
|
79
|
-
request: RequestState;
|
|
80
|
-
end: number;
|
|
81
|
-
chunkSize: number;
|
|
82
|
-
pendingPrompt: boolean;
|
|
83
|
-
boundary: number;
|
|
84
|
-
transferred: boolean;
|
|
85
|
-
closed: boolean;
|
|
86
|
-
}
|
|
87
|
-
interface Ready {
|
|
88
|
-
row: Row;
|
|
89
|
-
request: RequestState;
|
|
90
|
-
caches: Cache[];
|
|
91
|
-
draft: DraftRowCheckpoint;
|
|
92
|
-
retain?: () => void;
|
|
93
|
-
transferred: boolean;
|
|
94
|
-
}
|
|
95
|
-
let prefix: DraftPrefillGroup | undefined;
|
|
96
|
-
let context: MlxArray | null = null;
|
|
97
|
-
const ready: Ready[] = [];
|
|
98
|
-
const closeReady = (state: Ready) => {
|
|
99
|
-
const caches = state.caches.splice(0), attachments = [state.draft.attachment];
|
|
100
|
-
const release = state.retain; state.retain = undefined;
|
|
101
|
-
disposeResources([...caches, { dispose: () => disposeAttachments(attachments) },
|
|
102
|
-
{ dispose: () => release?.() }, ...(!state.transferred ? [state.request.sampling] : [])]);
|
|
103
|
-
};
|
|
104
|
-
const capture = (state: Preparation, snapshot: () => Cache[], index: number) => {
|
|
105
|
-
let caches: Cache[] = [], attachments: CheckpointAttachment[] = [];
|
|
106
|
-
try {
|
|
107
|
-
caches = snapshot(); attachments.push(prefix!.capture(index).attachment);
|
|
108
|
-
method.host.promptCache!.put(state.row.req.promptIds.slice(0, state.pos), caches,
|
|
109
|
-
state.request.namespace, undefined, attachments, state.row.req.cacheSessionId);
|
|
110
|
-
caches = []; attachments = [];
|
|
111
|
-
} finally { disposeResources([...caches, { dispose: () => disposeAttachments(attachments) }]); }
|
|
112
|
-
};
|
|
113
|
-
const target = new MlxPrefillRows<Preparation>({
|
|
114
|
-
maintain,
|
|
115
|
-
open(row) {
|
|
116
|
-
const options = row.req.method!.data as GenerateOptions;
|
|
117
|
-
row.spec = { drafted: 0, accepted: 0, targetCalls: 0, rejected: 0, rounds: 0,
|
|
118
|
-
acceptanceLengths: [], tokensPerForward: 0, forwardsSaved: 0, draftedByPos: [], acceptedByPos: [] };
|
|
119
|
-
const sampler = makeSampler(options);
|
|
120
|
-
const request: RequestState = { draftSampling: sampler, namespace: "", prefixLength: 0,
|
|
121
|
-
fill: method.provider.grouped?.supportsExternalTokens ? options.fill : undefined,
|
|
122
|
-
processed: method.host.promptCache ? [] : undefined,
|
|
123
|
-
sampling: makeStepSampler(options, { tokenRepresentation: "number", grammarWait: "before-sample",
|
|
124
|
-
historyUpdate: "after-sample", initialHistory: row.req.promptIds, acceptGrammar: true,
|
|
125
|
-
eosTokenIds: row.req.eosTokenIds, captureSelectedLogprob: options.logprobs === true,
|
|
126
|
-
captureTopLogprobs: options.topLogprobs }) };
|
|
127
|
-
if (request.fill) row.fill = request.fill.stats;
|
|
128
|
-
let caches: Cache[] = [], retained: (() => void) | undefined;
|
|
129
|
-
let appended = false;
|
|
130
|
-
const previous = prefix?.rowCount ?? 0;
|
|
131
|
-
try {
|
|
132
|
-
caches = method.binding.makeCache();
|
|
133
|
-
prefix ??= method.provider.grouped!.openPrefill({ target: bindLegacyDraftTarget(method.model, caches), checkpoints: [] });
|
|
134
|
-
const prompt = row.req.promptIds;
|
|
135
|
-
const pendingPrompt = prefix.prefillMode !== "full" && method.binding.prefillTailSplit && prompt.length > 1;
|
|
136
|
-
request.prefixLength = prompt.length - Number(pendingPrompt);
|
|
137
|
-
request.namespace = speculativePrefixNamespace(prefix.namespace, row.cacheNamespace ?? "", options);
|
|
138
|
-
const hit = method.host.promptCache?.take(prompt, request.namespace, row.req.cacheSessionId);
|
|
139
|
-
if (hit) {
|
|
140
|
-
try {
|
|
141
|
-
disposeResources(caches); caches = hit.caches.splice(0);
|
|
142
|
-
retained = hit.retain; hit.retain = undefined;
|
|
143
|
-
prefix.append([{ processedTokens: hit.tokens.length, attachment: hit.attachments![0]! }]);
|
|
144
|
-
appended = true;
|
|
145
|
-
// Target membership later releases backing leases after its own
|
|
146
|
-
// copies resolve. Settle companion copies under the same lease.
|
|
147
|
-
if (retained) prefix.materialize();
|
|
148
|
-
row.cachedTokens = hit.tokens.length;
|
|
149
|
-
} finally { disposeResources([...hit.caches, { dispose: () => disposeAttachments(hit.attachments) },
|
|
150
|
-
{ dispose: () => hit.retain?.() }]); }
|
|
151
|
-
} else { prefix.append([null]); appended = true; }
|
|
152
|
-
return { row, request, solo: caches, retain: retained, pos: row.cachedTokens,
|
|
153
|
-
end: request.prefixLength, pendingPrompt, transferred: false, closed: false,
|
|
154
|
-
chunkSize: options.prefillChunkSize ?? row.req.prefillChunkSize ?? method.host.prefillChunkSize,
|
|
155
|
-
boundary: method.host.promptCache ? Math.min(row.req.snapshotAt ?? prompt.length, prompt.length - 1) : -1 };
|
|
156
|
-
} catch (error) {
|
|
157
|
-
return cleanupFailure(error, () => disposeResources([
|
|
158
|
-
{ dispose: () => { if (appended) prefix!.filterRows(Array.from({ length: previous }, (_, i) => i)); } },
|
|
159
|
-
...caches, request.sampling, { dispose: () => retained?.() },
|
|
160
|
-
]));
|
|
161
|
-
}
|
|
162
|
-
},
|
|
163
|
-
plan(state) {
|
|
164
|
-
const end = Math.min(state.pos + state.chunkSize, state.end, state.boundary > state.pos ? state.boundary : Infinity);
|
|
165
|
-
return { start: state.pos, end, kind: end === state.end ? "final" : "drain",
|
|
166
|
-
snapshot: end === state.boundary && end > state.row.cachedTokens, batchYield: true, maintain: true };
|
|
167
|
-
},
|
|
168
|
-
async forward(ids, caches, _states, work) {
|
|
169
|
-
const taps = prefix!.tapLayers;
|
|
170
|
-
const output = await method.binding.forward(ids, caches, taps.length ? [...taps] : undefined, work);
|
|
171
|
-
context = output.ctxML;
|
|
172
|
-
return output.hidden;
|
|
173
|
-
},
|
|
174
|
-
afterForward(ids, _caches, _states, hidden) {
|
|
175
|
-
// Tapped providers consume their captured layers; assistant drafting
|
|
176
|
-
// consumes the true target hidden. Other providers ignore context.
|
|
177
|
-
const captured = context; context = null;
|
|
178
|
-
try {
|
|
179
|
-
const pending = prefix!.prefill(ids, captured ?? hidden);
|
|
180
|
-
if (pending) return pending.finally(() => captured?.dispose());
|
|
181
|
-
} catch (error) { captured?.dispose(); throw error; }
|
|
182
|
-
captured?.dispose();
|
|
183
|
-
},
|
|
184
|
-
project(hidden, _caches, completed) {
|
|
185
|
-
if (completed.every(state => state.pendingPrompt)) return null;
|
|
186
|
-
using last = hidden.slice([0, hidden.shape[1]! - 1, 0], [hidden.shape[0]!, hidden.shape[1]!, hidden.shape[2]!]);
|
|
187
|
-
return method.binding.projectLogits(last);
|
|
188
|
-
},
|
|
189
|
-
checkpoint: capture,
|
|
190
|
-
async complete(state, logits, index) {
|
|
191
|
-
const row = state.row;
|
|
192
|
-
row.spec!.targetCalls++;
|
|
193
|
-
if (state.pendingPrompt) { row.current = row.req.promptIds[state.end]!; row.generated = row.sampled = 0; }
|
|
194
|
-
else {
|
|
195
|
-
using scores = ops.reshape(logits!, [1, logits!.shape.at(-1)!]);
|
|
196
|
-
const sampled = await state.request.sampling.sample(scores, 0);
|
|
197
|
-
row.current = sampled.token; row.generated = row.sampled = 1;
|
|
198
|
-
if (row.req.eosTokenIds.includes(row.current)) {
|
|
199
|
-
if (method.host.promptCache) capture(state, () => cloneKvCaches(state.solo), index);
|
|
200
|
-
disposeResources(state.solo.splice(0)); state.retain?.(); state.retain = undefined;
|
|
201
|
-
method.host.finish(row, "stop"); return;
|
|
202
|
-
}
|
|
203
|
-
const more = await method.host.publish(row, row.current, readStepExtras(sampled.extras));
|
|
204
|
-
state.request.fill?.observe(row.current);
|
|
205
|
-
if (more === false || row.req.grammar?.isTerminated || row.generated >= row.req.maxTokens) {
|
|
206
|
-
if (method.host.promptCache && !row.req.signal?.aborted) capture(state, () => cloneKvCaches(state.solo), index);
|
|
207
|
-
disposeResources(state.solo.splice(0)); state.retain?.(); state.retain = undefined;
|
|
208
|
-
method.host.finish(row, more === false || row.req.grammar?.isTerminated ? "stop" : "length"); return;
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
|
-
method.#proposeEcho(row, state.request);
|
|
212
|
-
ready.push({ row, request: state.request, caches: state.solo, retain: state.retain,
|
|
213
|
-
draft: prefix!.capture(index), transferred: false });
|
|
214
|
-
state.transferred = true;
|
|
215
|
-
},
|
|
216
|
-
reject(row, error) { row.reject(error); },
|
|
217
|
-
close(state) {
|
|
218
|
-
if (state.closed) return;
|
|
219
|
-
state.closed = true;
|
|
220
|
-
if (!state.transferred) state.request.sampling.dispose();
|
|
221
|
-
},
|
|
222
|
-
filterRows(keep) { prefix!.filterRows(keep); },
|
|
223
|
-
dispose() {
|
|
224
|
-
const held = [prefix, context].filter(value => value != null);
|
|
225
|
-
prefix = undefined; context = null; disposeResources(held);
|
|
226
|
-
},
|
|
227
|
-
});
|
|
228
|
-
const preparation: MlxGroupPreparation = {
|
|
229
|
-
get rows() { return [...target.rows, ...ready.map(state => state.row)]; },
|
|
230
|
-
get canAdmit() { return target.canAdmit; },
|
|
231
|
-
get tokenWeight() { return target.tokenWeight + ready.reduce((sum, state) => sum + state.row.promptTokens - state.row.cachedTokens, 0); },
|
|
232
|
-
admit: row => target.admit(row),
|
|
233
|
-
advance: async work => {
|
|
234
|
-
// Publication returns to scheduling before prepared state joins active
|
|
235
|
-
// decode. This preserves the first-output flush boundary at every B.
|
|
236
|
-
if (ready.length) {
|
|
237
|
-
while (ready.length) {
|
|
238
|
-
const state = ready[0]!;
|
|
239
|
-
try {
|
|
240
|
-
if (state.row.req.signal?.aborted) {
|
|
241
|
-
state.row.reject(state.row.req.signal.reason);
|
|
242
|
-
continue;
|
|
243
|
-
}
|
|
244
|
-
maintain.prepareBatch?.(state.caches);
|
|
245
|
-
this.#target ??= new MlxStateRows(state.caches.map(targetCacheLayout));
|
|
246
|
-
this.#draft ??= this.provider.grouped!.open({ target: bindLegacyDraftTarget(this.model, this.#target.caches),
|
|
247
|
-
checkpoints: [], sampling: { sample: (lp, steps) => this.#sampleDraftRows(lp, steps) },
|
|
248
|
-
constraints: { propose: async (row, maxTokens) => this.host.rows[row]!.req.grammar?.proposeTokens(maxTokens) ?? [] } });
|
|
249
|
-
applyStateChanges([() => this.#target!.prepareAppend(state.caches),
|
|
250
|
-
() => this.#draft!.prepareAppend([state.draft]), () => ({ commit: () => {
|
|
251
|
-
state.request.retain = state.retain; state.retain = undefined;
|
|
252
|
-
this.#requests.set(state.row, state.request); state.transferred = true;
|
|
253
|
-
this.host.join(state.row);
|
|
254
|
-
}, dispose() {} })]);
|
|
255
|
-
} finally { ready.shift(); closeReady(state); }
|
|
256
|
-
}
|
|
257
|
-
return target.rows.length === 0;
|
|
258
|
-
}
|
|
259
|
-
const done = await target.advance(work);
|
|
260
|
-
return done && ready.length === 0;
|
|
261
|
-
},
|
|
262
|
-
dispose() {
|
|
263
|
-
const held = ready.splice(0);
|
|
264
|
-
disposeResources([target, ...held.map(state => ({ dispose: () => closeReady(state) }))]);
|
|
265
|
-
},
|
|
266
|
-
};
|
|
267
|
-
try { target.admit(first); return preparation; }
|
|
268
|
-
catch (error) { return cleanupFailure(error, () => preparation.dispose()); }
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
#sampleDraftRows(logprobs: MlxArray, steps: readonly number[]): MlxArray {
|
|
272
|
-
const tokens: MlxArray[] = [];
|
|
273
|
-
try {
|
|
274
|
-
for (let row = 0; row < this.host.rows.length; row++) {
|
|
275
|
-
using scores = logprobs.slice([row, 0], [row + 1, logprobs.shape[1]!]);
|
|
276
|
-
tokens.push(this.#requests.get(this.host.rows[row]!)!.draftSampling(scores, steps[row]!));
|
|
277
|
-
}
|
|
278
|
-
return ops.concatAxis(tokens, 0);
|
|
279
|
-
} finally { disposeResources(tokens); }
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
async advance(work?: MlxForwardWork): Promise<void> {
|
|
283
|
-
const active = [...this.host.rows];
|
|
284
|
-
const live = active.flatMap((row, index) => row.req.signal?.aborted ? [] : [index]);
|
|
285
|
-
if (live.length !== active.length) {
|
|
286
|
-
for (const row of active) if (row.req.signal?.aborted) row.reject(row.req.signal.reason);
|
|
287
|
-
this.host.filterRows(live);
|
|
288
|
-
}
|
|
289
|
-
const rows = [...this.host.rows];
|
|
290
|
-
if (!rows.length) return;
|
|
291
|
-
const depth = Math.min(this.depth, Math.max(...rows.map(row => row.req.maxTokens - row.generated)));
|
|
292
|
-
// The ordinary MTP round already supplies samples that can establish a
|
|
293
|
-
// copied prefix. Do not verify a wide span before any sample matches it.
|
|
294
|
-
const proposals = rows.map(row => {
|
|
295
|
-
const proposal = this.#requests.get(row)!.proposal;
|
|
296
|
-
return proposal?.emitted ? proposal.value.ids.slice(proposal.emitted) : [];
|
|
297
|
-
});
|
|
298
|
-
const echoDepth = Math.max(...proposals.map(ids => ids.length));
|
|
299
|
-
let externalTokens: MlxArray | undefined;
|
|
300
|
-
const rollback = bindRowCacheRollback(this.#target!.caches, rows.length);
|
|
301
|
-
const fills = echoDepth ? rows.flatMap((row, index) => {
|
|
302
|
-
const request = this.#requests.get(row)!;
|
|
303
|
-
return proposals[index]!.length ? [request.fill!] : [];
|
|
304
|
-
}) : [];
|
|
305
|
-
const halted = new Set<Row>();
|
|
306
|
-
const pin = this.binding.pinVerify?.();
|
|
307
|
-
try {
|
|
308
|
-
const completed = await advanceSpeculativeOutputs(rows.map(row => ({ pending: row.current,
|
|
309
|
-
step: row.sampled, remaining: row.req.maxTokens - row.generated, eosTokenIds: row.req.eosTokenIds,
|
|
310
|
-
sampling: this.#requests.get(row)!.sampling, grammarDone: () => row.req.grammar?.isTerminated === true,
|
|
311
|
-
output: { commit: async (ids, metadata) => {
|
|
312
|
-
row.generated++;
|
|
313
|
-
const more = await this.host.publish(row, ids[0]!, metadata?.[0]);
|
|
314
|
-
if (more === false) { halted.add(row); return false; }
|
|
315
|
-
} },
|
|
316
|
-
})), echoDepth || depth, echoDepth ? {
|
|
317
|
-
draft: () => proposals,
|
|
318
|
-
commit: (accepted, context) => this.#draft!.consume!(externalTokens!, context, accepted.map(n => n + 1)),
|
|
319
|
-
} : this.#draft!, {
|
|
320
|
-
transaction: !echoDepth ? rollback : { ...rollback,
|
|
321
|
-
begin(depth) {
|
|
322
|
-
const start = performance.now(); rollback.begin(depth);
|
|
323
|
-
const elapsed = performance.now() - start;
|
|
324
|
-
for (const fill of fills) fill.noteVerifyEvent(elapsed);
|
|
325
|
-
},
|
|
326
|
-
resolve(accepted) {
|
|
327
|
-
const start = performance.now(); rollback.resolve(accepted);
|
|
328
|
-
const elapsed = performance.now() - start;
|
|
329
|
-
for (const fill of fills) fill.stats.checkpointMs += elapsed;
|
|
330
|
-
},
|
|
331
|
-
},
|
|
332
|
-
forward: async ids => {
|
|
333
|
-
if (echoDepth) externalTokens = ops.copyOf(ids);
|
|
334
|
-
const taps = this.#draft!.tapLayers;
|
|
335
|
-
const result = await this.binding.forward(ids, this.#target!.caches, taps.length ? [...taps] : undefined,
|
|
336
|
-
work ? (tokens, caches, options) => work(tokens, caches, { ...options, preserveTokenGeometry: true }) : undefined);
|
|
337
|
-
const context = result.ctxML ?? result.hidden;
|
|
338
|
-
try { return { logits: this.binding.projectLogits(result.hidden), context }; }
|
|
339
|
-
catch (error) { context.dispose(); throw error; }
|
|
340
|
-
finally { if (result.ctxML) result.hidden.dispose(); }
|
|
341
|
-
},
|
|
342
|
-
});
|
|
343
|
-
const keep: number[] = [];
|
|
344
|
-
for (let index = 0; index < rows.length; index++) {
|
|
345
|
-
const row = rows[index]!, output = completed.outputs[index]!, round = completed.rounds[index]!;
|
|
346
|
-
const request = this.#requests.get(row)!;
|
|
347
|
-
if (request.fill) {
|
|
348
|
-
for (const token of round.acceptance.emitted.slice(0, output.generated)) {
|
|
349
|
-
const proposal = request.proposal;
|
|
350
|
-
if (proposal && token === proposal.value.ids[proposal.emitted]) {
|
|
351
|
-
if (++proposal.emitted === proposal.value.ids.length) this.#settleEcho(request);
|
|
352
|
-
} else {
|
|
353
|
-
this.#settleEcho(request); request.fill.observe(token);
|
|
354
|
-
}
|
|
355
|
-
}
|
|
356
|
-
if (output.kind === "continue") this.#proposeEcho(row, request);
|
|
357
|
-
else this.#settleEcho(request);
|
|
358
|
-
}
|
|
359
|
-
if (output.kind !== "failed" && output.kind !== "cancelled")
|
|
360
|
-
request.processed?.push(row.current, ...round.drafts.slice(0, output.accepted));
|
|
361
|
-
const stats = row.spec!;
|
|
362
|
-
stats.drafted += echoDepth ? 0 : round.drafts.length;
|
|
363
|
-
stats.accepted += echoDepth ? 0 : round.acceptance.accepted;
|
|
364
|
-
stats.rejected = stats.drafted - stats.accepted;
|
|
365
|
-
stats.targetCalls++;
|
|
366
|
-
if (!echoDepth) {
|
|
367
|
-
stats.rounds!++;
|
|
368
|
-
stats.acceptanceLengths!.push(round.acceptance.accepted);
|
|
369
|
-
for (let p = 0; p < round.drafts.length; p++) stats.draftedByPos![p] = (stats.draftedByPos![p] ?? 0) + 1;
|
|
370
|
-
for (let p = 0; p < round.acceptance.accepted; p++) stats.acceptedByPos![p] = (stats.acceptedByPos![p] ?? 0) + 1;
|
|
371
|
-
}
|
|
372
|
-
row.sampled += round.acceptance.emitted.length + Number(round.acceptance.sawEos);
|
|
373
|
-
// A consumer may stop inside a verified burst before its terminal EOS.
|
|
374
|
-
if (output.kind === "stop" && !halted.has(row) && round.acceptance.sawEos &&
|
|
375
|
-
output.generated === round.acceptance.emitted.length && row.generated < row.req.maxTokens)
|
|
376
|
-
row.generated++;
|
|
377
|
-
const forwards = stats.targetCalls - 1;
|
|
378
|
-
stats.tokensPerForward = row.generated / forwards;
|
|
379
|
-
stats.forwardsSaved = Math.max(0, row.generated - 1 - forwards);
|
|
380
|
-
if (output.kind === "continue") { row.current = output.pending; keep.push(index); }
|
|
381
|
-
else if (output.kind === "failed") row.reject(output.error);
|
|
382
|
-
else if (output.kind === "cancelled") row.reject(row.req.signal?.reason ?? new Error(output.reason));
|
|
383
|
-
else {
|
|
384
|
-
if (!row.req.signal?.aborted) this.#publishCheckpoint(row, index, request);
|
|
385
|
-
this.host.finish(row, output.kind);
|
|
386
|
-
}
|
|
387
|
-
}
|
|
388
|
-
if (keep.length !== rows.length) this.host.filterRows(keep);
|
|
389
|
-
if (++this.#steps % 256 === 0) clearCache();
|
|
390
|
-
} finally { externalTokens?.dispose(); pin?.close(); }
|
|
391
|
-
}
|
|
392
|
-
|
|
393
|
-
#proposeEcho(row: Row, request: RequestState): void {
|
|
394
|
-
if (request.proposal || !request.fill) return;
|
|
395
|
-
const value = request.fill.propose(row.req.maxTokens - row.generated, "verify");
|
|
396
|
-
if (value) request.proposal = { value, emitted: 0 };
|
|
397
|
-
}
|
|
398
|
-
|
|
399
|
-
#settleEcho(request: RequestState): void {
|
|
400
|
-
if (!request.proposal) return;
|
|
401
|
-
request.fill!.commit(request.proposal.value, request.proposal.emitted);
|
|
402
|
-
request.proposal = undefined;
|
|
403
|
-
}
|
|
404
|
-
|
|
405
|
-
/** The method aligns token coverage and captures its state. The cache owns
|
|
406
|
-
* RAM retention and eventual SSD persistence; no storage work is awaited. */
|
|
407
|
-
#publishCheckpoint(row: Row, index: number, request: RequestState): void {
|
|
408
|
-
if (!this.host.promptCache || !request.processed) return;
|
|
409
|
-
let target: Cache[] = [], attachments: CheckpointAttachment[] = [];
|
|
410
|
-
try {
|
|
411
|
-
target = this.#target!.extractRow(index);
|
|
412
|
-
attachments.push(this.#draft!.capture(index).attachment);
|
|
413
|
-
this.host.promptCache.put([...row.req.promptIds.slice(0, request.prefixLength), ...request.processed], target,
|
|
414
|
-
request.namespace, undefined, attachments, row.req.cacheSessionId);
|
|
415
|
-
target = []; attachments = [];
|
|
416
|
-
} finally { disposeResources([...target, { dispose: () => disposeAttachments(attachments) }]); }
|
|
417
|
-
}
|
|
418
|
-
|
|
419
|
-
filterRows(keep: readonly number[], _discard: boolean): void {
|
|
420
|
-
this.#target?.filterRows(keep); this.#draft?.filterRows(keep);
|
|
421
|
-
const retained = new Set(keep.map(index => this.host.rows[index]!));
|
|
422
|
-
const releases: { dispose(): void }[] = [];
|
|
423
|
-
for (const [row, request] of this.#requests) if (!retained.has(row)) {
|
|
424
|
-
this.#settleEcho(request);
|
|
425
|
-
this.#requests.delete(row);
|
|
426
|
-
releases.push(request.sampling, { dispose: () => request.retain?.() });
|
|
427
|
-
}
|
|
428
|
-
disposeResources(releases);
|
|
429
|
-
}
|
|
430
|
-
|
|
431
|
-
dispose(): void {
|
|
432
|
-
for (const request of this.#requests.values()) this.#settleEcho(request);
|
|
433
|
-
const resources = [...(this.#target ? [this.#target] : []), ...(this.#draft ? [this.#draft] : []),
|
|
434
|
-
...[...this.#requests.values()].flatMap(request => [request.sampling, { dispose: () => request.retain?.() }])];
|
|
435
|
-
this.#target = null; this.#draft = null; this.#requests.clear();
|
|
436
|
-
disposeResources(resources);
|
|
437
|
-
}
|
|
438
|
-
}
|
|
@@ -1,161 +0,0 @@
|
|
|
1
|
-
import type { MlxArray } from "../../mlx/array";
|
|
2
|
-
import * as ops from "../../mlx/ops";
|
|
3
|
-
import type { Cancellation, GenerationOutput, TokenLogprobs } from "../../contracts/generation";
|
|
4
|
-
import type { DisposableResource } from "../../contracts/resources";
|
|
5
|
-
import { cleanupFailure, disposeResources } from "../../engine/resources";
|
|
6
|
-
import type { SpeculativeTransaction } from "../../inference/rollback";
|
|
7
|
-
import { DraftAcceptance } from "../../inference/draft-acceptance";
|
|
8
|
-
import { deliverDraftOutputs, type DraftOutputResult } from "../../inference/draft-output";
|
|
9
|
-
import { readStepExtras, type NumberStepSampler } from "../../sampler";
|
|
10
|
-
|
|
11
|
-
/** Draft state owns proposal generation and its committed hidden/KV state.
|
|
12
|
-
* It borrows verification context and knows nothing about target storage. */
|
|
13
|
-
export interface MlxDraftRows<Context = MlxArray> {
|
|
14
|
-
/** Each row returns 0..depth proposals. The method verifies the returned
|
|
15
|
-
* lengths; an empty row still consumes its pending token. */
|
|
16
|
-
draft(pending: readonly number[], depth: number, steps: readonly number[]): number[][] | Promise<number[][]>;
|
|
17
|
-
commit(accepted: readonly number[], context: Context): void | Promise<void>;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
/** A bound graph transfers both tensors on success and releases partial
|
|
21
|
-
* allocations on failure. State retention is a separate injected interface. */
|
|
22
|
-
export interface MlxRowVerification<Context extends DisposableResource = MlxArray> {
|
|
23
|
-
readonly transaction: SpeculativeTransaction<readonly number[]>;
|
|
24
|
-
forward(ids: MlxArray): Promise<{ logits: MlxArray; context: Context }>;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
export interface MlxSpeculativeRow {
|
|
28
|
-
readonly pending: number;
|
|
29
|
-
readonly step: number;
|
|
30
|
-
readonly remaining: number;
|
|
31
|
-
readonly eosTokenIds: readonly number[];
|
|
32
|
-
readonly sampling: NumberStepSampler;
|
|
33
|
-
readonly grammarDone?: () => boolean;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
export interface MlxSpeculativeRowResult {
|
|
37
|
-
readonly drafts: readonly number[];
|
|
38
|
-
readonly acceptance: DraftAcceptance;
|
|
39
|
-
/** One entry per content token; stopping EOS is excluded. */
|
|
40
|
-
readonly logprobs: readonly (TokenLogprobs | undefined)[];
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
export interface MlxSpeculativeOutputRow extends MlxSpeculativeRow {
|
|
44
|
-
readonly output: Pick<GenerationOutput, "commit">;
|
|
45
|
-
readonly cancellation?: Cancellation;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
/** Execute one method step through output delivery and aligned state commit.
|
|
49
|
-
* The caller retires terminal rows and publishes eligible completed state
|
|
50
|
-
* before changing membership. Consumer failures are returned per request;
|
|
51
|
-
* a graph/state failure throws and requires discarding the whole group. */
|
|
52
|
-
export async function advanceSpeculativeOutputs<Context extends DisposableResource = MlxArray>(
|
|
53
|
-
rows: readonly MlxSpeculativeOutputRow[], depth: number,
|
|
54
|
-
draft: MlxDraftRows<NoInfer<Context>>, target: MlxRowVerification<Context>,
|
|
55
|
-
): Promise<{ rounds: readonly MlxSpeculativeRowResult[]; outputs: readonly DraftOutputResult[] }> {
|
|
56
|
-
const round = await prepareSpeculativeRows(rows, depth, draft, target);
|
|
57
|
-
let outputs: DraftOutputResult[];
|
|
58
|
-
try {
|
|
59
|
-
outputs = await deliverDraftOutputs(round.results.map((result, row) => ({
|
|
60
|
-
acceptance: result.acceptance, logprobs: result.logprobs,
|
|
61
|
-
output: rows[row]!.output, cancellation: rows[row]!.cancellation,
|
|
62
|
-
})));
|
|
63
|
-
await round.commit(outputs.map(output => output.accepted));
|
|
64
|
-
} catch (error) { return cleanupFailure(error, () => round.dispose()); }
|
|
65
|
-
round.dispose();
|
|
66
|
-
return { rounds: round.results, outputs };
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
/** Retention stays unresolved while the method delivers output. A terminal
|
|
70
|
-
* row may keep fewer accepted inputs for an output-aligned checkpoint;
|
|
71
|
-
* continuing rows retain their complete accepted prefix. Commit exactly once,
|
|
72
|
-
* then dispose; disposing an uncommitted round requires discarding its state. */
|
|
73
|
-
export interface MlxPreparedSpeculativeRound extends DisposableResource {
|
|
74
|
-
readonly results: readonly MlxSpeculativeRowResult[];
|
|
75
|
-
commit(keepAccepted?: readonly number[]): Promise<void>;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
/** One committed method step at B=1 or B>1. The caller supplies live rows with
|
|
79
|
-
* a positive token budget and a common nonnegative draft depth. Admission,
|
|
80
|
-
* cancellation boundaries, output delivery and cache publication stay outside
|
|
81
|
-
* this step. On failure the caller discards the participating method state. */
|
|
82
|
-
export async function advanceSpeculativeRows<Context extends DisposableResource = MlxArray>(
|
|
83
|
-
rows: readonly MlxSpeculativeRow[], depth: number,
|
|
84
|
-
draft: MlxDraftRows<NoInfer<Context>>, target: MlxRowVerification<Context>,
|
|
85
|
-
): Promise<readonly MlxSpeculativeRowResult[]> {
|
|
86
|
-
const round = await prepareSpeculativeRows(rows, depth, draft, target);
|
|
87
|
-
try { await round.commit(); }
|
|
88
|
-
catch (error) { return cleanupFailure(error, () => round.dispose()); }
|
|
89
|
-
round.dispose();
|
|
90
|
-
return round.results;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
/** Draft, verify and sample without deciding which output-aligned state to
|
|
94
|
-
* retain. Graph-specific context is opaque to this operation. */
|
|
95
|
-
export async function prepareSpeculativeRows<Context extends DisposableResource = MlxArray>(
|
|
96
|
-
rows: readonly MlxSpeculativeRow[], depth: number,
|
|
97
|
-
draft: MlxDraftRows<NoInfer<Context>>, target: MlxRowVerification<Context>,
|
|
98
|
-
): Promise<MlxPreparedSpeculativeRound> {
|
|
99
|
-
const proposals = await draft.draft(rows.map(row => row.pending), depth, rows.map(row => row.step));
|
|
100
|
-
const B = rows.length;
|
|
101
|
-
const verifyDepth = proposals.reduce((max, tokens) => Math.max(max, tokens.length), 0);
|
|
102
|
-
using ids = ops.fromInt32(proposals.flatMap((tokens, row) => {
|
|
103
|
-
const window = [rows[row]!.pending, ...tokens];
|
|
104
|
-
// Causal right padding only fills the rectangular graph. Sampling stops
|
|
105
|
-
// at this row's own bonus position; commit discards every padded input.
|
|
106
|
-
while (window.length <= verifyDepth) window.push(rows[row]!.pending);
|
|
107
|
-
return window;
|
|
108
|
-
}), [B, verifyDepth + 1]);
|
|
109
|
-
target.transaction.begin(verifyDepth);
|
|
110
|
-
const verification = await target.forward(ids);
|
|
111
|
-
const dispose = () => disposeResources([verification.context, verification.logits]);
|
|
112
|
-
try {
|
|
113
|
-
const results = await sampleSpeculativeRows(rows, proposals, verification.logits);
|
|
114
|
-
return {
|
|
115
|
-
results,
|
|
116
|
-
async commit(accepted = results.map(result => result.acceptance.accepted)) {
|
|
117
|
-
target.transaction.resolve(accepted);
|
|
118
|
-
await draft.commit(accepted, verification.context);
|
|
119
|
-
},
|
|
120
|
-
dispose,
|
|
121
|
-
};
|
|
122
|
-
} catch (error) { return cleanupFailure(error, dispose); }
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
/** Sample a borrowed verify window. Each request owns its processor history,
|
|
126
|
-
* grammar and RNG stream; completing one walk never samples its unused suffix.
|
|
127
|
-
* The existing request adapter and grouped method use this same operation. */
|
|
128
|
-
export async function sampleSpeculativeRows(
|
|
129
|
-
rows: readonly MlxSpeculativeRow[], proposals: readonly (readonly number[])[], logits: MlxArray,
|
|
130
|
-
): Promise<MlxSpeculativeRowResult[]> {
|
|
131
|
-
const V = logits.shape[2]!, width = logits.shape[1]!;
|
|
132
|
-
const independent = rows[0]?.sampling.independent;
|
|
133
|
-
let tokens: number[] | undefined;
|
|
134
|
-
if (independent && rows.every(row => row.sampling.independent === independent)) {
|
|
135
|
-
using flat = ops.reshape(logits, [rows.length * width, V]);
|
|
136
|
-
using sampled = independent.sample(flat);
|
|
137
|
-
tokens = sampled.toIntTokens();
|
|
138
|
-
}
|
|
139
|
-
const results: MlxSpeculativeRowResult[] = [];
|
|
140
|
-
for (let row = 0; row < rows.length; row++) {
|
|
141
|
-
const request = rows[row]!;
|
|
142
|
-
const acceptance = new DraftAcceptance(proposals[row]!, request.remaining, request.eosTokenIds);
|
|
143
|
-
const logprobs: (TokenLogprobs | undefined)[] = [];
|
|
144
|
-
while (!acceptance.done) {
|
|
145
|
-
const position = acceptance.position;
|
|
146
|
-
let token: number, metadata: TokenLogprobs | undefined;
|
|
147
|
-
if (tokens) token = tokens[row * width + position]!;
|
|
148
|
-
else {
|
|
149
|
-
using slice = logits.slice([row, position, 0], [row + 1, position + 1, V]);
|
|
150
|
-
using scores = ops.reshape(slice, [1, V]);
|
|
151
|
-
const sampled = await request.sampling.sample(scores, request.step + acceptance.emitted.length);
|
|
152
|
-
token = sampled.token;
|
|
153
|
-
metadata = readStepExtras(sampled.extras);
|
|
154
|
-
}
|
|
155
|
-
acceptance.accept(token, request.grammarDone?.() ?? false);
|
|
156
|
-
if (!acceptance.sawEos) logprobs.push(metadata);
|
|
157
|
-
}
|
|
158
|
-
results.push({ drafts: proposals[row]!, acceptance, logprobs });
|
|
159
|
-
}
|
|
160
|
-
return results;
|
|
161
|
-
}
|