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/eval/kl.ts
DELETED
|
@@ -1,590 +0,0 @@
|
|
|
1
|
-
// KL-divergence drift eval — port of optiq/eval/kl.py, adapted for the
|
|
2
|
-
// fused-kernel head-to-head.
|
|
3
|
-
//
|
|
4
|
-
// KL(ref ‖ cand) per token = Σ_v softmax(ref)·(logsoftmax(ref) − logsoftmax(cand)),
|
|
5
|
-
// reported as mean (primary), median, and p95 over N prompts × seq tokens.
|
|
6
|
-
// Computation is TEACHER-FORCED: the same fixed prompt is fed to both
|
|
7
|
-
// arms and the per-position distributions are compared — the repo's rule
|
|
8
|
-
// (free-running greedy "measures chaos"; see teacher-forced-gating).
|
|
9
|
-
//
|
|
10
|
-
// Two reference modes:
|
|
11
|
-
// * self-flag (DEFAULT, the kernel-drift gate): one model, one weight
|
|
12
|
-
// load; forward each prompt twice with a runtime lever set to its
|
|
13
|
-
// reference value vs its candidate value. Directly measures the drift
|
|
14
|
-
// a perf lever introduces. Fits in RAM trivially (no second model).
|
|
15
|
-
// * two-model (optiq-style absolute quality): a separate reference
|
|
16
|
-
// model (bf16 if it fits, else uniform-4bit). Both resident.
|
|
17
|
-
//
|
|
18
|
-
// NOTE (M0 scope): this uses the compat forward() path (plain caches), so
|
|
19
|
-
// it gates the shared-ops fusions (gelu / norm+add) and the tiled-vs-
|
|
20
|
-
// unfused SDPA lever. A serving-path variant (quantized KV + the generated
|
|
21
|
-
// class, teacher-forced prefill) is the next step — see eval README.
|
|
22
|
-
|
|
23
|
-
import { existsSync } from "node:fs";
|
|
24
|
-
import { MlxArray } from "../mlx/array";
|
|
25
|
-
import { clearCache, Dtype } from "../mlx/ffi";
|
|
26
|
-
import * as ops from "../mlx/ops";
|
|
27
|
-
import { Registry } from "../registry";
|
|
28
|
-
import { Weights } from "../weights";
|
|
29
|
-
import { loadModelConfig, type ModelConfig, type TurboQuantScheme } from "../config";
|
|
30
|
-
import { createModel, type RuntimeModel } from "../model/factory";
|
|
31
|
-
import { loadTokenizer, type LoadedTokenizer } from "../tokenizer";
|
|
32
|
-
import { evalCacheState, maybeQuantizeKv } from "../generate";
|
|
33
|
-
import { ReferenceLogitsDump, type ReferenceRecords } from "./reference-logits";
|
|
34
|
-
import {
|
|
35
|
-
configureRuntime,
|
|
36
|
-
runtimeKey,
|
|
37
|
-
} from "../runtime-config";
|
|
38
|
-
|
|
39
|
-
export interface KLResult {
|
|
40
|
-
nPrompts: number;
|
|
41
|
-
seqLen: number;
|
|
42
|
-
meanKl: number; // mean of per-prompt mean KL — the primary scalar
|
|
43
|
-
medianKl: number; // median over all pooled per-token KLs
|
|
44
|
-
p95Kl: number; // tail (long-distribution drift)
|
|
45
|
-
elapsedSec: number;
|
|
46
|
-
refLabel: string;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
/** KL(p ‖ q) per token for logits [1, T, V]; returns a length-T array. */
|
|
50
|
-
export function klPerToken(pLogits: MlxArray, qLogits: MlxArray): Float32Array {
|
|
51
|
-
const f32 = (a: MlxArray): { arr: MlxArray; owned: boolean } =>
|
|
52
|
-
a.dtype === Dtype.float32 ? { arr: a, owned: false } : { arr: a.astype(Dtype.float32), owned: true };
|
|
53
|
-
const pp = f32(pLogits);
|
|
54
|
-
const qq = f32(qLogits);
|
|
55
|
-
const p = pp.arr;
|
|
56
|
-
const q = qq.arr;
|
|
57
|
-
|
|
58
|
-
const lseP = ops.logsumexpAxis(p, -1, true); // [1,T,1]
|
|
59
|
-
const lseQ = ops.logsumexpAxis(q, -1, true);
|
|
60
|
-
const logP = ops.sub(p, lseP); // [1,T,V]
|
|
61
|
-
const logQ = ops.sub(q, lseQ);
|
|
62
|
-
const pProbs = ops.softmaxAxis(p, -1, true); // precise softmax
|
|
63
|
-
const diff = ops.sub(logP, logQ);
|
|
64
|
-
const prod = ops.mul(pProbs, diff);
|
|
65
|
-
const kl = ops.sumAxis(prod, -1, false); // [1,T]
|
|
66
|
-
const out = kl.toFloat32();
|
|
67
|
-
|
|
68
|
-
for (const a of [lseP, lseQ, logP, logQ, pProbs, diff, prod, kl]) a.dispose();
|
|
69
|
-
if (pp.owned) p.dispose();
|
|
70
|
-
if (qq.owned) q.dispose();
|
|
71
|
-
return out;
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
const mean = (xs: number[]): number => (xs.length ? xs.reduce((a, b) => a + b, 0) / xs.length : 0);
|
|
75
|
-
function percentile(xs: number[], pct: number): number {
|
|
76
|
-
if (!xs.length) return 0;
|
|
77
|
-
const s = [...xs].sort((a, b) => a - b);
|
|
78
|
-
const i = Math.min(s.length - 1, Math.max(0, Math.floor((pct / 100) * s.length)));
|
|
79
|
-
return s[i]!;
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
function aggregate(perPrompt: Float32Array[]): { mean: number; median: number; p95: number } {
|
|
83
|
-
const promptMeans = perPrompt.map((a) => mean(Array.from(a)));
|
|
84
|
-
const pooled: number[] = [];
|
|
85
|
-
for (const a of perPrompt) for (const v of a) pooled.push(v);
|
|
86
|
-
return { mean: mean(promptMeans), median: percentile(pooled, 50), p95: percentile(pooled, 95) };
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
/** A local model dir if `query` is a path, else resolved via the registry. */
|
|
90
|
-
export function resolveModelDir(query: string): string {
|
|
91
|
-
if (existsSync(query) && existsSync(`${query}/config.json`)) return query;
|
|
92
|
-
return new Registry().resolve(query).path;
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
export interface Runnable {
|
|
96
|
-
model: RuntimeModel;
|
|
97
|
-
tokenizer: LoadedTokenizer;
|
|
98
|
-
config: ModelConfig;
|
|
99
|
-
dir: string;
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
export async function loadRunnable(query: string): Promise<Runnable> {
|
|
103
|
-
const dir = resolveModelDir(query);
|
|
104
|
-
const config = await loadModelConfig(dir);
|
|
105
|
-
const weights = await Weights.open(dir);
|
|
106
|
-
const model = createModel(weights, config);
|
|
107
|
-
const tokenizer = await loadTokenizer(dir);
|
|
108
|
-
return { model, tokenizer, config, dir };
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
/** Forward a fixed token sequence, return logits [1, L, V] (caller disposes). */
|
|
112
|
-
function forwardLogits(model: RuntimeModel, tokens: number[]): MlxArray {
|
|
113
|
-
const cache = model.makeCache();
|
|
114
|
-
try {
|
|
115
|
-
return model.forward(tokens, cache);
|
|
116
|
-
} finally {
|
|
117
|
-
for (const c of cache) c.dispose();
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
function prepPrompts(prompts: string[], tok: LoadedTokenizer, seqLen: number, n: number): number[][] {
|
|
122
|
-
const tiled: string[] = [];
|
|
123
|
-
while (tiled.length < n) tiled.push(...prompts);
|
|
124
|
-
return tiled.slice(0, n).map((p) => tok.encode(p).slice(0, seqLen));
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
/** self-flag drift gate: ref = env[flag]=refValue, cand = env[flag]=candValue. */
|
|
128
|
-
export async function evaluateKlSelfFlag(opts: {
|
|
129
|
-
candidate: string;
|
|
130
|
-
flag: string;
|
|
131
|
-
refValue: string;
|
|
132
|
-
candValue: string;
|
|
133
|
-
prompts: string[];
|
|
134
|
-
nPrompts?: number;
|
|
135
|
-
seqLen?: number;
|
|
136
|
-
}): Promise<KLResult> {
|
|
137
|
-
const t0 = Date.now();
|
|
138
|
-
const n = opts.nPrompts ?? 64;
|
|
139
|
-
const seqLen = opts.seqLen ?? 256;
|
|
140
|
-
const { model, tokenizer } = await loadRunnable(opts.candidate);
|
|
141
|
-
const tokenized = prepPrompts(opts.prompts, tokenizer, seqLen, n);
|
|
142
|
-
|
|
143
|
-
const key = runtimeKey(opts.flag);
|
|
144
|
-
const perPrompt: Float32Array[] = [];
|
|
145
|
-
for (const ids of tokenized) {
|
|
146
|
-
let p: MlxArray;
|
|
147
|
-
const restoreRef = configureRuntime({ [key]: opts.refValue });
|
|
148
|
-
try {
|
|
149
|
-
p = forwardLogits(model, ids);
|
|
150
|
-
} finally {
|
|
151
|
-
restoreRef();
|
|
152
|
-
}
|
|
153
|
-
let q: MlxArray;
|
|
154
|
-
const restoreCandidate = configureRuntime({ [key]: opts.candValue });
|
|
155
|
-
try {
|
|
156
|
-
q = forwardLogits(model, ids);
|
|
157
|
-
} finally {
|
|
158
|
-
restoreCandidate();
|
|
159
|
-
}
|
|
160
|
-
const T = Math.min(p.shape[1]!, q.shape[1]!);
|
|
161
|
-
const pT = p.slice([0, 0, 0], [1, T, p.shape[2]!]);
|
|
162
|
-
const qT = q.slice([0, 0, 0], [1, T, q.shape[2]!]);
|
|
163
|
-
perPrompt.push(klPerToken(pT, qT));
|
|
164
|
-
for (const a of [p, q, pT, qT]) a.dispose();
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
const agg = aggregate(perPrompt);
|
|
168
|
-
return {
|
|
169
|
-
nPrompts: n, seqLen, meanKl: agg.mean, medianKl: agg.median, p95Kl: agg.p95,
|
|
170
|
-
elapsedSec: (Date.now() - t0) / 1000,
|
|
171
|
-
refLabel: `self:${opts.flag}=${opts.refValue}→${opts.candValue}`,
|
|
172
|
-
};
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
/** two-model absolute drift: KL(reference ‖ candidate) on shared prompts. */
|
|
176
|
-
export async function evaluateKlTwoModel(opts: {
|
|
177
|
-
candidate: string;
|
|
178
|
-
reference: string;
|
|
179
|
-
prompts: string[];
|
|
180
|
-
nPrompts?: number;
|
|
181
|
-
seqLen?: number;
|
|
182
|
-
}): Promise<KLResult> {
|
|
183
|
-
const t0 = Date.now();
|
|
184
|
-
const n = opts.nPrompts ?? 64;
|
|
185
|
-
const seqLen = opts.seqLen ?? 256;
|
|
186
|
-
const ref = await loadRunnable(opts.reference);
|
|
187
|
-
const cand = await loadRunnable(opts.candidate);
|
|
188
|
-
const tokenized = prepPrompts(opts.prompts, ref.tokenizer, seqLen, n);
|
|
189
|
-
|
|
190
|
-
const perPrompt: Float32Array[] = [];
|
|
191
|
-
for (const ids of tokenized) {
|
|
192
|
-
const p = forwardLogits(ref.model, ids);
|
|
193
|
-
const q = forwardLogits(cand.model, ids);
|
|
194
|
-
const T = Math.min(p.shape[1]!, q.shape[1]!);
|
|
195
|
-
const pT = p.slice([0, 0, 0], [1, T, p.shape[2]!]);
|
|
196
|
-
const qT = q.slice([0, 0, 0], [1, T, q.shape[2]!]);
|
|
197
|
-
perPrompt.push(klPerToken(pT, qT));
|
|
198
|
-
for (const a of [p, q, pT, qT]) a.dispose();
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
const agg = aggregate(perPrompt);
|
|
202
|
-
return {
|
|
203
|
-
nPrompts: n, seqLen, meanKl: agg.mean, medianKl: agg.median, p95Kl: agg.p95,
|
|
204
|
-
elapsedSec: (Date.now() - t0) / 1000,
|
|
205
|
-
refLabel: opts.reference,
|
|
206
|
-
};
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
// --- serving-path (decode) KL — the M0b gate -----------------------------
|
|
210
|
-
// The compat forward() KL above runs plain bf16 caches → it can't see the
|
|
211
|
-
// quantized-KV serving path. This variant reproduces serving exactly: bf16
|
|
212
|
-
// prefill, then maybeQuantizeKv (the generate.ts hook) converts the populated
|
|
213
|
-
// mixed-4/8-bit caches, then a TEACHER-FORCED decode over the prompt tail —
|
|
214
|
-
// where the generated quantized SDPA (and the fused kernels) actually run.
|
|
215
|
-
|
|
216
|
-
/** CPU KL(p ‖ q) for two logit vectors (same math as klPerToken, per step). */
|
|
217
|
-
function klScalar(p: Float32Array, q: Float32Array): number {
|
|
218
|
-
const V = p.length;
|
|
219
|
-
let mp = -Infinity;
|
|
220
|
-
let mq = -Infinity;
|
|
221
|
-
for (let i = 0; i < V; i++) { if (p[i]! > mp) mp = p[i]!; if (q[i]! > mq) mq = q[i]!; }
|
|
222
|
-
let sp = 0;
|
|
223
|
-
let sq = 0;
|
|
224
|
-
for (let i = 0; i < V; i++) { sp += Math.exp(p[i]! - mp); sq += Math.exp(q[i]! - mq); }
|
|
225
|
-
const lsep = mp + Math.log(sp);
|
|
226
|
-
const lseq = mq + Math.log(sq);
|
|
227
|
-
let kl = 0;
|
|
228
|
-
for (let i = 0; i < V; i++) {
|
|
229
|
-
const pp = Math.exp(p[i]! - lsep);
|
|
230
|
-
if (pp > 0) kl += pp * ((p[i]! - lsep) - (q[i]! - lseq));
|
|
231
|
-
}
|
|
232
|
-
return kl;
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
/** Prefill (bf16) → quantize → teacher-forced decode; return per-step logit
|
|
236
|
-
* distributions for the last `tokens.length - prefillLen` positions.
|
|
237
|
-
* `kvOverride` replaces the default kvConfig-from-model-config scheme when
|
|
238
|
-
* given — the seam evaluateKlKvArm uses to run a TurboQuant (or bf16-null)
|
|
239
|
-
* arm instead of the env-flag self-flip. */
|
|
240
|
-
function decodeArm(
|
|
241
|
-
model: RuntimeModel, config: ModelConfig, tokens: number[], prefillLen: number,
|
|
242
|
-
flag: string, value: string,
|
|
243
|
-
kvOverride?: Parameters<typeof maybeQuantizeKv>[1],
|
|
244
|
-
): Float32Array[] {
|
|
245
|
-
const restore = configureRuntime({ [runtimeKey(flag)]: value });
|
|
246
|
-
try {
|
|
247
|
-
const cache = model.makeCache();
|
|
248
|
-
try {
|
|
249
|
-
const lp = model.forward(tokens.slice(0, prefillLen), cache); // bf16 prefill
|
|
250
|
-
lp.dispose();
|
|
251
|
-
// quantize the populated caches (mixed 4/8 per kv_config) — exactly
|
|
252
|
-
// what generate() does between prefill and decode.
|
|
253
|
-
maybeQuantizeKv(
|
|
254
|
-
cache,
|
|
255
|
-
kvOverride ?? { kvConfig: config.kvQuant ?? undefined, quantizedKvStart: 0 },
|
|
256
|
-
);
|
|
257
|
-
const out: Float32Array[] = [];
|
|
258
|
-
for (let i = prefillLen; i < tokens.length; i++) {
|
|
259
|
-
const logits = model.forward([tokens[i]!], cache); // [1,1,V] quantized decode
|
|
260
|
-
out.push(logits.toFloat32());
|
|
261
|
-
logits.dispose();
|
|
262
|
-
}
|
|
263
|
-
return out;
|
|
264
|
-
} finally {
|
|
265
|
-
for (const c of cache) c.dispose();
|
|
266
|
-
}
|
|
267
|
-
} finally {
|
|
268
|
-
restore();
|
|
269
|
-
}
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
/** Serving-path drift gate: KL between two arms of a perf lever, measured on
|
|
273
|
-
* the teacher-forced quantized-decode path (the real e4b serving path). */
|
|
274
|
-
export async function evaluateKlServingDecode(opts: {
|
|
275
|
-
candidate: string;
|
|
276
|
-
flag: string;
|
|
277
|
-
refValue: string;
|
|
278
|
-
candValue: string;
|
|
279
|
-
prompts: string[];
|
|
280
|
-
nPrompts?: number;
|
|
281
|
-
seqLen?: number;
|
|
282
|
-
decodeSteps?: number;
|
|
283
|
-
}): Promise<KLResult> {
|
|
284
|
-
const t0 = Date.now();
|
|
285
|
-
const n = opts.nPrompts ?? 64;
|
|
286
|
-
const seqLen = opts.seqLen ?? 256;
|
|
287
|
-
const decodeSteps = opts.decodeSteps ?? 32;
|
|
288
|
-
const { model, tokenizer, config } = await loadRunnable(opts.candidate);
|
|
289
|
-
const tokenized = prepPrompts(opts.prompts, tokenizer, seqLen, n);
|
|
290
|
-
|
|
291
|
-
const perPrompt: Float32Array[] = [];
|
|
292
|
-
for (const tokens of tokenized) {
|
|
293
|
-
if (tokens.length < 2) continue;
|
|
294
|
-
const prefillLen = Math.max(1, tokens.length - decodeSteps);
|
|
295
|
-
const refSteps = decodeArm(model, config, tokens, prefillLen, opts.flag, opts.refValue);
|
|
296
|
-
const candSteps = decodeArm(model, config, tokens, prefillLen, opts.flag, opts.candValue);
|
|
297
|
-
const m = Math.min(refSteps.length, candSteps.length);
|
|
298
|
-
const kls = new Float32Array(m);
|
|
299
|
-
for (let s = 0; s < m; s++) kls[s] = klScalar(refSteps[s]!, candSteps[s]!);
|
|
300
|
-
perPrompt.push(kls);
|
|
301
|
-
}
|
|
302
|
-
|
|
303
|
-
const agg = aggregate(perPrompt);
|
|
304
|
-
return {
|
|
305
|
-
nPrompts: perPrompt.length, seqLen, meanKl: agg.mean, medianKl: agg.median, p95Kl: agg.p95,
|
|
306
|
-
elapsedSec: (Date.now() - t0) / 1000,
|
|
307
|
-
refLabel: `serving-decode self:${opts.flag}=${opts.refValue}→${opts.candValue} (${decodeSteps} steps)`,
|
|
308
|
-
};
|
|
309
|
-
}
|
|
310
|
-
|
|
311
|
-
/** KV-scheme A/B on the teacher-forced serving-decode path: bf16 baseline
|
|
312
|
-
* (no kvOverride) vs an explicit KV scheme (e.g. TurboQuant), same model /
|
|
313
|
-
* same prompts / same weight load — the quality-vs-bpw curve gate
|
|
314
|
-
* (scripts/turboquant/eval-turboquant-curve.ts). Unlike evaluateKlServingDecode (env-flag
|
|
315
|
-
* self-flip), the two arms differ by an actual GenerateOptions kv scheme
|
|
316
|
-
* object, so this is the seam for schemes that aren't env-lever-shaped. */
|
|
317
|
-
export async function evaluateKlKvArm(opts: {
|
|
318
|
-
candidate: string;
|
|
319
|
-
/** Undefined ⇒ bf16 (no quantization). */
|
|
320
|
-
candidateScheme?: { turboQuant?: TurboQuantScheme; kvBits?: number; kvConfig?: ModelConfig["kvQuant"] };
|
|
321
|
-
prompts: string[];
|
|
322
|
-
nPrompts?: number;
|
|
323
|
-
seqLen?: number;
|
|
324
|
-
decodeSteps?: number;
|
|
325
|
-
}): Promise<KLResult> {
|
|
326
|
-
const t0 = Date.now();
|
|
327
|
-
const n = opts.nPrompts ?? 64;
|
|
328
|
-
const seqLen = opts.seqLen ?? 256;
|
|
329
|
-
const decodeSteps = opts.decodeSteps ?? 32;
|
|
330
|
-
const { model, tokenizer, config } = await loadRunnable(opts.candidate);
|
|
331
|
-
const tokenized = prepPrompts(opts.prompts, tokenizer, seqLen, n);
|
|
332
|
-
const noopFlag = "MLX_BUN_EVAL_KV_ARM_NOOP"; // decodeArm always flips a flag; this one is inert
|
|
333
|
-
const refKv = {}; // bf16: maybeQuantizeKv no-ops with no kvBits/kvConfig/turboQuant
|
|
334
|
-
const candKv = opts.candidateScheme
|
|
335
|
-
? { ...opts.candidateScheme, quantizedKvStart: 0, kvConfig: opts.candidateScheme.kvConfig ?? undefined }
|
|
336
|
-
: {};
|
|
337
|
-
|
|
338
|
-
const perPrompt: Float32Array[] = [];
|
|
339
|
-
for (const tokens of tokenized) {
|
|
340
|
-
if (tokens.length < 2) continue;
|
|
341
|
-
const prefillLen = Math.max(1, tokens.length - decodeSteps);
|
|
342
|
-
const refSteps = decodeArm(model, config, tokens, prefillLen, noopFlag, "0", refKv);
|
|
343
|
-
const candSteps = decodeArm(model, config, tokens, prefillLen, noopFlag, "0", candKv);
|
|
344
|
-
const m = Math.min(refSteps.length, candSteps.length);
|
|
345
|
-
const kls = new Float32Array(m);
|
|
346
|
-
for (let s = 0; s < m; s++) kls[s] = klScalar(refSteps[s]!, candSteps[s]!);
|
|
347
|
-
perPrompt.push(kls);
|
|
348
|
-
}
|
|
349
|
-
|
|
350
|
-
const agg = aggregate(perPrompt);
|
|
351
|
-
return {
|
|
352
|
-
nPrompts: perPrompt.length, seqLen, meanKl: agg.mean, medianKl: agg.median, p95Kl: agg.p95,
|
|
353
|
-
elapsedSec: (Date.now() - t0) / 1000,
|
|
354
|
-
refLabel: opts.candidateScheme?.turboQuant
|
|
355
|
-
? `bf16 vs turbo k${opts.candidateScheme.turboQuant.kBits}v${opts.candidateScheme.turboQuant.vBits} (${decodeSteps} steps)`
|
|
356
|
-
: `bf16 vs kv-scheme (${decodeSteps} steps)`,
|
|
357
|
-
};
|
|
358
|
-
}
|
|
359
|
-
|
|
360
|
-
// --- saved-teacher KL (--reference-logits) --------------------------------
|
|
361
|
-
// The two-model mode above needs both arms resident; a bf16 teacher never
|
|
362
|
-
// fits beside a candidate on 32 GB. So the teacher is dumped ONCE from
|
|
363
|
-
// Python (top-k logits + full-vocab logsumexp per position; format and
|
|
364
|
-
// rationale in reference-logits.ts) and every candidate is scored against
|
|
365
|
-
// the dump through OUR engine.
|
|
366
|
-
//
|
|
367
|
-
// Per position, with the teacher's top-k slice j ∈ K:
|
|
368
|
-
// p_j = exp(ref_logit_j − ref_logsumexp) (full-vocab softmax)
|
|
369
|
-
// log q_j = cand_logit_j − logsumexp(cand, FULL vocab)
|
|
370
|
-
// KL = Σ_j p_j · (log p_j − log q_j)
|
|
371
|
-
// The sum is truncated to K, so it under-counts by the tail p carries
|
|
372
|
-
// outside the top-k — `meanCapturedMass` (Σ_j p_j) reports exactly how much
|
|
373
|
-
// of p the number covers, and a run with low captured mass is not a
|
|
374
|
-
// comparable KL. Everything is float32; the candidate's logsumexp is over
|
|
375
|
-
// its FULL vocab (never the top-k slice), so log q is a real log-probability.
|
|
376
|
-
//
|
|
377
|
-
// The forward is the SERVING path (model.makeCache + chunked forwardHidden +
|
|
378
|
-
// logitsFromHidden), NOT trainForward: trainForward's cache stub has no
|
|
379
|
-
// DeltaNet SSMCache.advance, which is why `mlx-bun perplexity` cannot score
|
|
380
|
-
// qwen3_5 at all (docs/design/turboquant.md, "Known engine gaps"). KV stays
|
|
381
|
-
// bf16 — this is a weights-only instrument.
|
|
382
|
-
|
|
383
|
-
export interface RefLogitsKLResult extends KLResult {
|
|
384
|
-
/** Positions actually scored (Σ over sequences). */
|
|
385
|
-
nPositions: number;
|
|
386
|
-
/** Fraction of positions where argmax(ref) == argmax(cand) over full vocab. */
|
|
387
|
-
top1Agreement: number;
|
|
388
|
-
/** Mean Σ_{j∈topK} p_j — how much of the teacher's mass the KL sum covers. */
|
|
389
|
-
meanCapturedMass: number;
|
|
390
|
-
topK: number;
|
|
391
|
-
/** manifest.model — the teacher these numbers are against. */
|
|
392
|
-
refModel: string;
|
|
393
|
-
}
|
|
394
|
-
|
|
395
|
-
/** Teacher-forced candidate logits for one sequence, emitted in
|
|
396
|
-
* position-ordered chunks: `onChunk(startPos, logits[1, C, V])`. The callee
|
|
397
|
-
* owns the array and disposes it after `onChunk` returns. This is the seam
|
|
398
|
-
* the model-free test replaces (no weights, no registry). */
|
|
399
|
-
export type TeacherForcedLogits = (
|
|
400
|
-
tokens: number[],
|
|
401
|
-
onChunk: (startPos: number, logits: MlxArray) => void,
|
|
402
|
-
) => void;
|
|
403
|
-
|
|
404
|
-
/** The real engine forward: one cache for the whole sequence, prefilled in
|
|
405
|
-
* chunks, lm_head applied per chunk so full-vocab logits for a 4k context
|
|
406
|
-
* never exist at once (4096 × 151k × 4 B ≈ 2.5 GB). */
|
|
407
|
-
export function engineTeacherForcedLogits(
|
|
408
|
-
model: RuntimeModel,
|
|
409
|
-
chunkSize: number,
|
|
410
|
-
): TeacherForcedLogits {
|
|
411
|
-
return (tokens, onChunk) => {
|
|
412
|
-
const cache = model.makeCache();
|
|
413
|
-
try {
|
|
414
|
-
for (let pos = 0; pos < tokens.length; pos += chunkSize) {
|
|
415
|
-
const end = Math.min(pos + chunkSize, tokens.length);
|
|
416
|
-
const ids = ops.fromInt32(tokens.slice(pos, end), [1, end - pos]);
|
|
417
|
-
let h: MlxArray;
|
|
418
|
-
try {
|
|
419
|
-
h = model.forwardHidden(ids, cache);
|
|
420
|
-
} finally {
|
|
421
|
-
ids.dispose();
|
|
422
|
-
}
|
|
423
|
-
let logits: MlxArray;
|
|
424
|
-
try {
|
|
425
|
-
logits = model.logitsFromHidden(h);
|
|
426
|
-
} finally {
|
|
427
|
-
h.dispose();
|
|
428
|
-
}
|
|
429
|
-
try {
|
|
430
|
-
onChunk(pos, logits);
|
|
431
|
-
} finally {
|
|
432
|
-
logits.dispose();
|
|
433
|
-
}
|
|
434
|
-
evalCacheState(cache);
|
|
435
|
-
clearCache(); // mlx-lm _prefill cadence: don't let chunk transients pile up
|
|
436
|
-
}
|
|
437
|
-
} finally {
|
|
438
|
-
for (const c of cache) c.dispose();
|
|
439
|
-
}
|
|
440
|
-
};
|
|
441
|
-
}
|
|
442
|
-
|
|
443
|
-
interface ChunkScore {
|
|
444
|
-
kl: Float32Array; // [rows]
|
|
445
|
-
mass: Float32Array; // [rows]
|
|
446
|
-
top1: Uint8Array; // [rows] 1 = candidate argmax == teacher argmax
|
|
447
|
-
}
|
|
448
|
-
|
|
449
|
-
/** Score `rows` candidate positions against the matching teacher records.
|
|
450
|
-
* `logits` is [1, C, V]; rows [rowLo, rowHi) of it line up with
|
|
451
|
-
* `records` rows [0, count). */
|
|
452
|
-
function scoreChunkAgainstRecords(
|
|
453
|
-
logits: MlxArray, rowLo: number, rowHi: number, records: ReferenceRecords,
|
|
454
|
-
): ChunkScore {
|
|
455
|
-
const rows = rowHi - rowLo;
|
|
456
|
-
const K = records.topK;
|
|
457
|
-
const V = logits.shape[2]!;
|
|
458
|
-
if (records.count !== rows)
|
|
459
|
-
throw new Error(`reference-logits: ${records.count} records for ${rows} candidate rows`);
|
|
460
|
-
|
|
461
|
-
// Teacher indices must exist in the candidate's vocabulary.
|
|
462
|
-
let maxIdx = -1;
|
|
463
|
-
for (const v of records.indices) if (v > maxIdx) maxIdx = v;
|
|
464
|
-
if (maxIdx >= V || records.indices.some((v) => v < 0))
|
|
465
|
-
throw new Error(
|
|
466
|
-
`reference-logits: teacher index ${maxIdx} out of range for candidate vocab ${V} ` +
|
|
467
|
-
`— the dump was made with a different tokenizer`,
|
|
468
|
-
);
|
|
469
|
-
|
|
470
|
-
const owned: MlxArray[] = [];
|
|
471
|
-
try {
|
|
472
|
-
const sliced = logits.slice([0, rowLo, 0], [1, rowHi, V]);
|
|
473
|
-
owned.push(sliced);
|
|
474
|
-
const f32 = sliced.dtype === Dtype.float32 ? sliced : sliced.astype(Dtype.float32);
|
|
475
|
-
if (f32 !== sliced) owned.push(f32);
|
|
476
|
-
|
|
477
|
-
const lse = ops.logsumexpAxis(f32, -1, false); // [1, rows], full vocab
|
|
478
|
-
owned.push(lse);
|
|
479
|
-
const argmax = ops.argmaxAxis(f32, -1); // [1, rows], full vocab
|
|
480
|
-
owned.push(argmax);
|
|
481
|
-
const idx = MlxArray.fromInt32(records.indices, [1, rows, K]);
|
|
482
|
-
owned.push(idx);
|
|
483
|
-
const gathered = ops.takeAlongAxis(f32, idx, 2); // [1, rows, K]
|
|
484
|
-
owned.push(gathered);
|
|
485
|
-
|
|
486
|
-
const candTop = gathered.toFloat32();
|
|
487
|
-
const candLse = lse.toFloat32();
|
|
488
|
-
const candArgmax = argmax.toIntTokens();
|
|
489
|
-
|
|
490
|
-
const kl = new Float32Array(rows);
|
|
491
|
-
const mass = new Float32Array(rows);
|
|
492
|
-
const top1 = new Uint8Array(rows);
|
|
493
|
-
for (let r = 0; r < rows; r++) {
|
|
494
|
-
const refLse = records.logsumexp[r]!;
|
|
495
|
-
const qLse = candLse[r]!;
|
|
496
|
-
const base = r * K;
|
|
497
|
-
let acc = 0;
|
|
498
|
-
let m = 0;
|
|
499
|
-
for (let j = 0; j < K; j++) {
|
|
500
|
-
const logP = records.logits[base + j]! - refLse;
|
|
501
|
-
const p = Math.exp(logP);
|
|
502
|
-
if (p === 0) continue;
|
|
503
|
-
m += p;
|
|
504
|
-
acc += p * (logP - (candTop[base + j]! - qLse));
|
|
505
|
-
}
|
|
506
|
-
kl[r] = acc;
|
|
507
|
-
mass[r] = m;
|
|
508
|
-
top1[r] = candArgmax[r] === records.indices[base]! ? 1 : 0;
|
|
509
|
-
}
|
|
510
|
-
return { kl, mass, top1 };
|
|
511
|
-
} finally {
|
|
512
|
-
for (const a of owned) a.dispose();
|
|
513
|
-
}
|
|
514
|
-
}
|
|
515
|
-
|
|
516
|
-
/** KL(saved bf16 teacher ‖ candidate) at EVERY teacher-forced position. */
|
|
517
|
-
export async function evaluateKlVsReferenceLogits(opts: {
|
|
518
|
-
candidate: string;
|
|
519
|
-
/** Dump directory (runs/kl-teacher/<tag>). */
|
|
520
|
-
referenceDir: string;
|
|
521
|
-
/** Cap on sequences scored (default: all in the manifest). */
|
|
522
|
-
nSeqs?: number;
|
|
523
|
-
/** Positions per candidate forward (default 512 — see the memory note). */
|
|
524
|
-
chunkSize?: number;
|
|
525
|
-
/** Test seam: use this forward instead of loading `candidate`. */
|
|
526
|
-
forward?: TeacherForcedLogits;
|
|
527
|
-
}): Promise<RefLogitsKLResult> {
|
|
528
|
-
const t0 = Date.now();
|
|
529
|
-
const dump = ReferenceLogitsDump.open(opts.referenceDir);
|
|
530
|
-
const chunkSize = Math.max(1, opts.chunkSize ?? 512);
|
|
531
|
-
const nSeqs = Math.max(1, Math.min(opts.nSeqs ?? dump.nSeqs, dump.nSeqs));
|
|
532
|
-
|
|
533
|
-
const forward = opts.forward
|
|
534
|
-
?? engineTeacherForcedLogits((await loadRunnable(opts.candidate)).model, chunkSize);
|
|
535
|
-
|
|
536
|
-
try {
|
|
537
|
-
const perSeq: Float32Array[] = [];
|
|
538
|
-
let nPositions = 0;
|
|
539
|
-
let top1Hits = 0;
|
|
540
|
-
let massSum = 0;
|
|
541
|
-
|
|
542
|
-
for (let s = 0; s < nSeqs; s++) {
|
|
543
|
-
const tokens = dump.tokens(s);
|
|
544
|
-
const scored = Math.min(dump.positionsPerSeq, tokens.length - 1);
|
|
545
|
-
const kls = new Float32Array(scored);
|
|
546
|
-
let filled = 0;
|
|
547
|
-
|
|
548
|
-
forward(tokens, (startPos, logits) => {
|
|
549
|
-
const chunkLen = logits.shape[1]!;
|
|
550
|
-
const lo = startPos;
|
|
551
|
-
const hi = Math.min(startPos + chunkLen, scored);
|
|
552
|
-
if (hi <= lo) return; // trailing positions have no teacher record
|
|
553
|
-
const records = dump.readRecords(s, lo, hi);
|
|
554
|
-
const sc = scoreChunkAgainstRecords(logits, lo - startPos, hi - startPos, records);
|
|
555
|
-
for (let r = 0; r < sc.kl.length; r++) {
|
|
556
|
-
kls[lo + r] = sc.kl[r]!;
|
|
557
|
-
massSum += sc.mass[r]!;
|
|
558
|
-
top1Hits += sc.top1[r]!;
|
|
559
|
-
}
|
|
560
|
-
filled += hi - lo;
|
|
561
|
-
});
|
|
562
|
-
|
|
563
|
-
if (filled !== scored)
|
|
564
|
-
throw new Error(
|
|
565
|
-
`reference-logits: candidate forward covered ${filled} of ${scored} positions ` +
|
|
566
|
-
`on sequence ${s}`,
|
|
567
|
-
);
|
|
568
|
-
perSeq.push(kls);
|
|
569
|
-
nPositions += scored;
|
|
570
|
-
}
|
|
571
|
-
|
|
572
|
-
const agg = aggregate(perSeq);
|
|
573
|
-
return {
|
|
574
|
-
nPrompts: perSeq.length,
|
|
575
|
-
seqLen: dump.ctxLen,
|
|
576
|
-
meanKl: agg.mean,
|
|
577
|
-
medianKl: agg.median,
|
|
578
|
-
p95Kl: agg.p95,
|
|
579
|
-
elapsedSec: (Date.now() - t0) / 1000,
|
|
580
|
-
refLabel: `ref-logits:${dump.manifest.model} top${dump.topK} (${opts.referenceDir})`,
|
|
581
|
-
nPositions,
|
|
582
|
-
top1Agreement: nPositions ? top1Hits / nPositions : 0,
|
|
583
|
-
meanCapturedMass: nPositions ? massSum / nPositions : 0,
|
|
584
|
-
topK: dump.topK,
|
|
585
|
-
refModel: dump.manifest.model,
|
|
586
|
-
};
|
|
587
|
-
} finally {
|
|
588
|
-
dump.close();
|
|
589
|
-
}
|
|
590
|
-
}
|