mlx-bun 0.4.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 +1453 -88
- 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 +10 -8
- 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 +12 -10
- package/src/{serve → server}/chat-stage.ts +27 -22
- package/src/{client.ts → server/client.ts} +28 -2
- package/src/{serve → server}/completion-executor.ts +42 -42
- 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 +42 -83
- package/src/server/generated-token-history.ts +57 -0
- 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 +8 -8
- package/src/{serve → server}/request-prep.ts +82 -68
- 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 -94
- package/docs/archive/hlg-sampling.md +0 -350
- package/docs/archive/investigations/audio-input-plan.md +0 -356
- 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/web-ui-pass-plan.md +0 -213
- package/docs/archive/planning/website-readme-pass-plan.md +0 -224
- package/docs/design/batching.md +0 -1841
- package/docs/design/decode-speed-program.md +0 -2349
- package/docs/design/dreaming-nightly-pipeline.md +0 -684
- package/docs/design/generic-model-support.md +0 -705
- package/docs/design/kv-cache.md +0 -824
- package/docs/design/orpo-training.md +0 -680
- package/docs/design/speculative-decoding.md +0 -1990
- package/docs/design/turboquant.md +0 -2212
- package/docs/design/unified-engine-frontier-plan.md +0 -1880
- package/docs/design/web-chat-redesign.md +0 -695
- package/docs/planning/PRODUCT_ROADMAP.md +0 -594
- package/docs/planning/ResearchTopics.md +0 -119
- package/docs/planning/release-notes-v0.4.0.md +0 -45
- package/docs/planning/video-series.md +0 -421
- package/docs/reference/benchmarks.md +0 -3613
- package/docs/reference/cli.md +0 -585
- package/docs/reference/distribution.md +0 -355
- package/docs/reference/environment.md +0 -398
- package/docs/reference/glossary.md +0 -39
- package/docs/reference/library-api.md +0 -674
- package/docs/reference/memory.md +0 -260
- package/docs/reference/models.md +0 -334
- package/docs/reference/server-api.md +0 -1775
- package/docs/reference/server-config.md +0 -846
- package/docs/reference/training.md +0 -462
- package/docs/reference/troubleshooting.md +0 -158
- package/src/admission-plan.ts +0 -18
- package/src/audio/conformer.ts +0 -647
- package/src/audio/decode.ts +0 -133
- package/src/audio/features.ts +0 -202
- package/src/audio/transcode.ts +0 -67
- 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 -108
- package/src/backends/mlx/batch-group.ts +0 -1790
- 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 -106
- 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/evaluation.ts +0 -105
- package/src/backends/mlx/fill-append.ts +0 -45
- 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 -130
- 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 -133
- 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/model-prompt.ts +0 -164
- package/src/backends/mlx/model-serving.ts +0 -79
- package/src/backends/mlx/prefill-cohort.ts +0 -89
- package/src/backends/mlx/prefill-rows.ts +0 -200
- package/src/backends/mlx/prefill.ts +0 -33
- package/src/backends/mlx/projected-context-rows.ts +0 -72
- package/src/backends/mlx/request-policy.ts +0 -20
- package/src/backends/mlx/request-state-policy.ts +0 -41
- package/src/backends/mlx/rollback.ts +0 -89
- package/src/backends/mlx/row-sampling.ts +0 -49
- package/src/backends/mlx/serial-executor.ts +0 -242
- package/src/backends/mlx/speculative-group.ts +0 -359
- package/src/backends/mlx/speculative-round.ts +0 -161
- package/src/backends/mlx/speculative.ts +0 -114
- 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 -165
- package/src/chat-template.ts +0 -382
- package/src/cli.ts +0 -3168
- package/src/config.ts +0 -399
- package/src/contracts/completion.ts +0 -16
- package/src/contracts/execution.ts +0 -60
- package/src/contracts/generation.ts +0 -103
- package/src/contracts/host.ts +0 -7
- package/src/contracts/pi-provider.ts +0 -30
- package/src/contracts/pi.ts +0 -259
- package/src/contracts/prefix-cache.ts +0 -23
- package/src/contracts/resources.ts +0 -25
- package/src/contracts/sampling.ts +0 -23
- package/src/contracts/scheduling.ts +0 -45
- 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 -53
- package/src/engine/resources.ts +0 -53
- package/src/engine/scheduler.ts +0 -72
- 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 -452
- 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 -1346
- package/src/grammar.ts +0 -591
- 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 -39
- 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 -257
- package/src/kv-store.ts +0 -1099
- package/src/lab/README.md +0 -18
- 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-kv-rows.ts +0 -83
- package/src/lab/paged-kv/paged-kv.ts +0 -270
- package/src/library.ts +0 -40
- package/src/lora.ts +0 -408
- package/src/md-modules.d.ts +0 -49
- 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 -388
- 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 -512
- package/src/mlx/materialize.ts +0 -23
- package/src/mlx/metal-kernel.ts +0 -159
- package/src/mlx/ops.ts +0 -1021
- 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 -93
- 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 -55
- package/src/model/diffusion-gemma.ts +0 -1026
- package/src/model/factory.ts +0 -189
- package/src/model/fingerprint.ts +0 -33
- 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 -2351
- package/src/model/gemma4.ts +0 -1315
- 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 -67
- package/src/model/minicpm5.ts +0 -376
- package/src/model/profile.ts +0 -443
- 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 -252
- package/src/model/qwen3.ts +0 -277
- package/src/model/qwen3_5-checkpoint.ts +0 -164
- package/src/model/qwen3_5.ts +0 -819
- 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 -102
- 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 -83
- 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/native/expert_io.c +0 -523
- package/src/native/frame_extract.swift +0 -140
- package/src/native-pack.ts +0 -162
- 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 -1932
- package/src/preflight.ts +0 -158
- package/src/prompt-cache.ts +0 -460
- 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 -81
- package/src/safetensors.ts +0 -158
- package/src/sampler.ts +0 -1011
- 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/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 -496
- 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 -43
- package/src/serve/model-host.ts +0 -511
- package/src/serve/parent-application.ts +0 -56
- package/src/serve/prompt-response-trace.ts +0 -147
- 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/server.ts +0 -1314
- package/src/spec/assistant-rows.ts +0 -92
- 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 -317
- package/src/spec/glm52-mtp-state.ts +0 -33
- package/src/spec/ngram-source.ts +0 -204
- 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 -219
- package/src/spec/qwen-mtp-source.ts +0 -383
- package/src/spec/qwen-mtp-state.ts +0 -30
- package/src/spec/serve-loop.ts +0 -585
- package/src/spec/source.ts +0 -215
- package/src/spec/two-model-rows.ts +0 -61
- package/src/spec/two-model.ts +0 -113
- package/src/ssd-cache.ts +0 -372
- package/src/ssd-durability.ts +0 -211
- 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 -168
- package/src/vision/preprocess.ts +0 -247
- package/src/vision/prompt.ts +0 -373
- package/src/vision/qwen3vl-preprocess.ts +0 -409
- package/src/vision/qwen3vl-prompt.ts +0 -196
- package/src/vision/qwen3vl-tower.ts +0 -555
- package/src/vision/siglip.ts +0 -599
- package/src/vision/video-frames.ts +0 -148
- package/src/web/app.html +0 -2143
- package/src/web/app.js +0 -5703
- 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 -1057
- package/src/web/src/composer.ts +0 -959
- 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/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/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,249 +0,0 @@
|
|
|
1
|
-
// Sharded safetensors writer: takes a list of named mlx arrays and writes
|
|
2
|
-
// them to disk as one or more `model*.safetensors` files via mlx's native
|
|
3
|
-
// saver (mlx_save_safetensors), matching the on-disk layout the loader
|
|
4
|
-
// (src/weights.ts → ShardedSafetensors) reads back.
|
|
5
|
-
//
|
|
6
|
-
// Layout parity with mlx-lm / the MiniCPM5-OptiQ target:
|
|
7
|
-
// - single shard → `model.safetensors`, NO index file.
|
|
8
|
-
// - multiple shards → `model-00001-of-0000N.safetensors`, plus a
|
|
9
|
-
// `model.safetensors.index.json` { metadata:{total_size,
|
|
10
|
-
// total_parameters}, weight_map: <name → shard> }.
|
|
11
|
-
// - metadata map carries {"format":"mlx"} so the file round-trips through
|
|
12
|
-
// mlx_load_safetensors with the same provenance HF/mlx writes.
|
|
13
|
-
//
|
|
14
|
-
// Memory discipline: each array is eval'd immediately before insertion so its
|
|
15
|
-
// bytes are materialized one tensor at a time (the caller hands us already-
|
|
16
|
-
// disposed-after-write arrays), bounding peak memory to ~one tensor over the
|
|
17
|
-
// resident weight set rather than the whole model.
|
|
18
|
-
|
|
19
|
-
import { ptr } from "bun:ffi";
|
|
20
|
-
import { renameSync, writeFileSync } from "node:fs";
|
|
21
|
-
import { join } from "node:path";
|
|
22
|
-
import { C, takeMlxError } from "../mlx/ffi";
|
|
23
|
-
import type { MlxArray } from "../mlx/array";
|
|
24
|
-
|
|
25
|
-
const cstr = (s: string) => Buffer.from(s + "\0", "utf8");
|
|
26
|
-
|
|
27
|
-
/** Default greedy shard ceiling: 5 GiB (mlx-lm's MAX shard size). */
|
|
28
|
-
export const DEFAULT_SHARD_BYTES = 5 << 30;
|
|
29
|
-
|
|
30
|
-
export interface NamedTensor {
|
|
31
|
-
name: string;
|
|
32
|
-
array: MlxArray;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
export interface ShardInfo {
|
|
36
|
-
/** Filename written into outDir (e.g. "model.safetensors"). */
|
|
37
|
-
file: string;
|
|
38
|
-
/** Tensor names placed in this shard, in insertion order. */
|
|
39
|
-
names: string[];
|
|
40
|
-
/** Byte size of the tensors in this shard (sum of nbytes). */
|
|
41
|
-
bytes: number;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
export interface SafetensorsIndex {
|
|
45
|
-
metadata: { total_size: number; total_parameters: number };
|
|
46
|
-
weight_map: Record<string, string>;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
export interface WriteResult {
|
|
50
|
-
shards: ShardInfo[];
|
|
51
|
-
totalSize: number;
|
|
52
|
-
totalParams: number;
|
|
53
|
-
/** The index object (also written to disk when shards.length > 1). */
|
|
54
|
-
index: SafetensorsIndex;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
export interface WriteOpts {
|
|
58
|
-
/** Greedy shard ceiling in bytes (default DEFAULT_SHARD_BYTES). */
|
|
59
|
-
shardBytes?: number;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
/** Insert one array into a native string→array map (key cstring, handle u64).
|
|
63
|
-
* Evals the array first so its bytes are materialized exactly here. */
|
|
64
|
-
function insertArray(map: bigint, name: string, array: MlxArray): void {
|
|
65
|
-
array.eval();
|
|
66
|
-
if (C.mlx_map_string_to_array_insert(map, ptr(cstr(name)), array.handle) !== 0)
|
|
67
|
-
throw new Error(`map insert ${name} failed: ${takeMlxError() ?? ""}`);
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
/** Build the {"format":"mlx"} metadata map. Caller frees it. */
|
|
71
|
-
function newMetaMap(): bigint {
|
|
72
|
-
const map = C.mlx_map_string_to_string_new();
|
|
73
|
-
if (C.mlx_map_string_to_string_insert(map, ptr(cstr("format")), ptr(cstr("mlx"))) !== 0)
|
|
74
|
-
throw new Error(`metadata insert failed: ${takeMlxError() ?? ""}`);
|
|
75
|
-
return map;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
/** Pack the shard's tensors into a fresh native map and save to `path`. */
|
|
79
|
-
function saveShard(path: string, tensors: NamedTensor[]): void {
|
|
80
|
-
const arrMap = C.mlx_map_string_to_array_new();
|
|
81
|
-
const metaMap = newMetaMap();
|
|
82
|
-
try {
|
|
83
|
-
for (const { name, array } of tensors) insertArray(arrMap, name, array);
|
|
84
|
-
if (C.mlx_save_safetensors(ptr(cstr(path)), arrMap, metaMap) !== 0)
|
|
85
|
-
throw new Error(`mlx_save_safetensors(${path}) failed: ${takeMlxError() ?? ""}`);
|
|
86
|
-
} finally {
|
|
87
|
-
C.mlx_map_string_to_array_free(arrMap);
|
|
88
|
-
C.mlx_map_string_to_string_free(metaMap);
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
/** Shard filename for shard i of n (1-based, 5-digit, matches mlx-lm). */
|
|
93
|
-
function shardName(i: number, n: number): string {
|
|
94
|
-
if (n === 1) return "model.safetensors";
|
|
95
|
-
const pad = (x: number) => String(x).padStart(5, "0");
|
|
96
|
-
return `model-${pad(i + 1)}-of-${pad(n)}.safetensors`;
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
/** Greedily bin tensors into shards no larger than `shardBytes`. A single
|
|
100
|
-
* tensor larger than the ceiling still gets its own shard (never split). */
|
|
101
|
-
function planShards(tensors: NamedTensor[], shardBytes: number): NamedTensor[][] {
|
|
102
|
-
const shards: NamedTensor[][] = [];
|
|
103
|
-
let cur: NamedTensor[] = [];
|
|
104
|
-
let curBytes = 0;
|
|
105
|
-
for (const t of tensors) {
|
|
106
|
-
const nb = t.array.nbytes;
|
|
107
|
-
if (cur.length > 0 && curBytes + nb > shardBytes) {
|
|
108
|
-
shards.push(cur);
|
|
109
|
-
cur = [];
|
|
110
|
-
curBytes = 0;
|
|
111
|
-
}
|
|
112
|
-
cur.push(t);
|
|
113
|
-
curBytes += nb;
|
|
114
|
-
}
|
|
115
|
-
if (cur.length > 0) shards.push(cur);
|
|
116
|
-
return shards.length > 0 ? shards : [[]];
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
/**
|
|
120
|
-
* Write `tensors` to `outDir` as sharded safetensors. Returns shard layout,
|
|
121
|
-
* total byte size, total parameter count, and the (single source of truth)
|
|
122
|
-
* index object. An index file is written only when there is more than one
|
|
123
|
-
* shard — matching the loader's expectation that a lone `model.safetensors`
|
|
124
|
-
* carries no sidecar index.
|
|
125
|
-
*/
|
|
126
|
-
export function writeShardedSafetensors(
|
|
127
|
-
outDir: string,
|
|
128
|
-
tensors: NamedTensor[],
|
|
129
|
-
opts: WriteOpts = {},
|
|
130
|
-
): WriteResult {
|
|
131
|
-
const shardBytes = opts.shardBytes ?? DEFAULT_SHARD_BYTES;
|
|
132
|
-
const plan = planShards(tensors, shardBytes);
|
|
133
|
-
const n = plan.length;
|
|
134
|
-
|
|
135
|
-
const shards: ShardInfo[] = [];
|
|
136
|
-
const weight_map: Record<string, string> = {};
|
|
137
|
-
let totalSize = 0;
|
|
138
|
-
let totalParams = 0;
|
|
139
|
-
|
|
140
|
-
for (let i = 0; i < n; i++) {
|
|
141
|
-
const group = plan[i]!;
|
|
142
|
-
const file = shardName(i, n);
|
|
143
|
-
let bytes = 0;
|
|
144
|
-
for (const t of group) {
|
|
145
|
-
bytes += t.array.nbytes;
|
|
146
|
-
totalParams += t.array.size;
|
|
147
|
-
weight_map[t.name] = file;
|
|
148
|
-
}
|
|
149
|
-
totalSize += bytes;
|
|
150
|
-
saveShard(join(outDir, file), group);
|
|
151
|
-
shards.push({ file, names: group.map((t) => t.name), bytes });
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
// weight_map sorted by name for a stable, diff-friendly index.
|
|
155
|
-
const sortedMap: Record<string, string> = {};
|
|
156
|
-
for (const name of Object.keys(weight_map).sort()) sortedMap[name] = weight_map[name]!;
|
|
157
|
-
|
|
158
|
-
const index: SafetensorsIndex = {
|
|
159
|
-
metadata: { total_size: totalSize, total_parameters: totalParams },
|
|
160
|
-
weight_map: sortedMap,
|
|
161
|
-
};
|
|
162
|
-
|
|
163
|
-
if (n > 1) {
|
|
164
|
-
writeFileSync(
|
|
165
|
-
join(outDir, "model.safetensors.index.json"),
|
|
166
|
-
JSON.stringify(index, null, 2),
|
|
167
|
-
);
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
return { shards, totalSize, totalParams, index };
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
/**
|
|
174
|
-
* Incremental sharded writer for model-scale streaming transforms (27B fold/
|
|
175
|
-
* quantize): tensors are added one at a time; when the current shard reaches
|
|
176
|
-
* the byte ceiling it is SAVED AND ITS ARRAYS DISPOSED immediately, so peak
|
|
177
|
-
* memory is one shard plus the tensor in flight — never the whole model
|
|
178
|
-
* (the whole-list writeShardedSafetensors path holds every array until the
|
|
179
|
-
* caller disposes them, which OOMs a 51 GB model on a 32 GB box).
|
|
180
|
-
*
|
|
181
|
-
* Shards are written under temp names (the final `-of-NNNNN` count is unknown
|
|
182
|
-
* until finish()) and renamed at finish, which also writes the index.
|
|
183
|
-
* add() takes ownership of the array (evaluates it now, disposes after save).
|
|
184
|
-
*/
|
|
185
|
-
export class ShardedWriter {
|
|
186
|
-
readonly #outDir: string;
|
|
187
|
-
readonly #shardBytes: number;
|
|
188
|
-
#cur: NamedTensor[] = [];
|
|
189
|
-
#curBytes = 0;
|
|
190
|
-
#done: { tmp: string; names: string[]; bytes: number }[] = [];
|
|
191
|
-
#totalParams = 0;
|
|
192
|
-
|
|
193
|
-
constructor(outDir: string, opts: WriteOpts = {}) {
|
|
194
|
-
this.#outDir = outDir;
|
|
195
|
-
this.#shardBytes = opts.shardBytes ?? DEFAULT_SHARD_BYTES;
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
add(name: string, array: MlxArray): void {
|
|
199
|
-
array.eval();
|
|
200
|
-
const nb = array.nbytes;
|
|
201
|
-
if (this.#cur.length > 0 && this.#curBytes + nb > this.#shardBytes) this.#flush();
|
|
202
|
-
this.#cur.push({ name, array });
|
|
203
|
-
this.#curBytes += nb;
|
|
204
|
-
this.#totalParams += array.size;
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
#flush(): void {
|
|
208
|
-
if (this.#cur.length === 0) return;
|
|
209
|
-
const tmp = `model-shard-${String(this.#done.length + 1).padStart(5, "0")}.tmp.safetensors`;
|
|
210
|
-
saveShard(join(this.#outDir, tmp), this.#cur);
|
|
211
|
-
this.#done.push({
|
|
212
|
-
tmp,
|
|
213
|
-
names: this.#cur.map((t) => t.name),
|
|
214
|
-
bytes: this.#curBytes,
|
|
215
|
-
});
|
|
216
|
-
for (const t of this.#cur) t.array.dispose();
|
|
217
|
-
this.#cur = [];
|
|
218
|
-
this.#curBytes = 0;
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
finish(): WriteResult {
|
|
222
|
-
this.#flush();
|
|
223
|
-
const n = this.#done.length;
|
|
224
|
-
const shards: ShardInfo[] = [];
|
|
225
|
-
const weight_map: Record<string, string> = {};
|
|
226
|
-
let totalSize = 0;
|
|
227
|
-
for (let i = 0; i < n; i++) {
|
|
228
|
-
const d = this.#done[i]!;
|
|
229
|
-
const file = shardName(i, n);
|
|
230
|
-
renameSync(join(this.#outDir, d.tmp), join(this.#outDir, file));
|
|
231
|
-
for (const name of d.names) weight_map[name] = file;
|
|
232
|
-
totalSize += d.bytes;
|
|
233
|
-
shards.push({ file, names: d.names, bytes: d.bytes });
|
|
234
|
-
}
|
|
235
|
-
const sortedMap: Record<string, string> = {};
|
|
236
|
-
for (const name of Object.keys(weight_map).sort()) sortedMap[name] = weight_map[name]!;
|
|
237
|
-
const index: SafetensorsIndex = {
|
|
238
|
-
metadata: { total_size: totalSize, total_parameters: this.#totalParams },
|
|
239
|
-
weight_map: sortedMap,
|
|
240
|
-
};
|
|
241
|
-
if (n > 1) {
|
|
242
|
-
writeFileSync(
|
|
243
|
-
join(this.#outDir, "model.safetensors.index.json"),
|
|
244
|
-
JSON.stringify(index, null, 2),
|
|
245
|
-
);
|
|
246
|
-
}
|
|
247
|
-
return { shards, totalSize, totalParams: this.#totalParams, index };
|
|
248
|
-
}
|
|
249
|
-
}
|
|
@@ -1,216 +0,0 @@
|
|
|
1
|
-
// Per-layer quantization sensitivity analysis (native TS port of
|
|
2
|
-
// optiq/core/sensitivity.py `analyze_sensitivity_exact`, uniform-baseline path).
|
|
3
|
-
//
|
|
4
|
-
// For each quantizable Linear in a loaded (already-quantized) model:
|
|
5
|
-
// 1. dequantize its packed weight back to bf16 — this is the bf16 "source"
|
|
6
|
-
// the OptIQ uniform_4bit path streams off disk; here it's self-contained
|
|
7
|
-
// because the running model already carries quantized weights.
|
|
8
|
-
// 2. for each candidate bit-width, re-quantize that bf16 source at the new
|
|
9
|
-
// bits and SWAP it into the running QuantizedLinear (mutate w/scales/biases
|
|
10
|
-
// + the QuantSpec bits/groupSize).
|
|
11
|
-
// 3. run a no-KV full-sequence forward on each calibration sample, compute
|
|
12
|
-
// KL(reference || current) (port of `_kl_from_ref`), average over samples.
|
|
13
|
-
// 4. restore the layer's original quantized weight.
|
|
14
|
-
//
|
|
15
|
-
// Reference logits = the UNMODIFIED running model (taken once up front). When a
|
|
16
|
-
// candidate bit equals the layer's baseline bit-width, re-quantizing reproduces
|
|
17
|
-
// exactly what the layer already is, so KL is 0 by construction — we record 0.0
|
|
18
|
-
// and skip the forward passes (port of the OptIQ baseline-bit short-circuit).
|
|
19
|
-
//
|
|
20
|
-
// Faithful to: `_simulate_quantize` (quantize→dequantize via MlxArray ops),
|
|
21
|
-
// `_mutate_quantized_layer_to_bits`, `_kl_from_ref`, the uniform-4bit-baseline
|
|
22
|
-
// path, and the bits==baseline ⇒ 0 short-circuit.
|
|
23
|
-
|
|
24
|
-
import { Dtype } from "../mlx/ffi";
|
|
25
|
-
import { cpuStream, MlxArray } from "../mlx/array";
|
|
26
|
-
import * as ops from "../mlx/ops";
|
|
27
|
-
import { trainForward } from "../train/forward";
|
|
28
|
-
import type { RuntimeModel } from "../model/factory";
|
|
29
|
-
import type {
|
|
30
|
-
QuantizedLinear,
|
|
31
|
-
QuantizedLinearState,
|
|
32
|
-
} from "../model/gemma4-base";
|
|
33
|
-
|
|
34
|
-
/** Per-layer KL sensitivity at each candidate bit-width (port of
|
|
35
|
-
* optiq SensitivityResult). */
|
|
36
|
-
export interface SensitivityResult {
|
|
37
|
-
layerName: string;
|
|
38
|
-
/** bit-width → mean KL(reference || that-bit) over calibration samples. */
|
|
39
|
-
sensitivities: Record<number, number>;
|
|
40
|
-
paramCount: number;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
export interface AnalyzeSensitivityOptions {
|
|
44
|
-
candidateBits?: number[];
|
|
45
|
-
groupSize?: number;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
// --------------------------------------------------------------------------
|
|
49
|
-
// Scoped state exchange for sensitivity probes. QuantizedLinear owns the only
|
|
50
|
-
// mutation capability; inference consumers retain a read-only getter surface.
|
|
51
|
-
// --------------------------------------------------------------------------
|
|
52
|
-
|
|
53
|
-
/** Snapshot of a QuantizedLinear's quantized state (for restore). */
|
|
54
|
-
type LayerState = QuantizedLinearState;
|
|
55
|
-
|
|
56
|
-
function captureState(layer: QuantizedLinear): LayerState {
|
|
57
|
-
return { w: layer.w, scales: layer.scales, biases: layer.biases, spec: layer.spec };
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
function restoreState(layer: QuantizedLinear, state: LayerState): void {
|
|
61
|
-
const transient = layer.exchangeQuantizedState(state);
|
|
62
|
-
// Dispose the transient swapped-in tensors before restoring the originals.
|
|
63
|
-
if (transient.w !== state.w) transient.w.dispose();
|
|
64
|
-
if (transient.scales !== state.scales) transient.scales.dispose();
|
|
65
|
-
if (transient.biases && transient.biases !== state.biases) transient.biases.dispose();
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
/** Quantize `bf16Weight` at `newBits`/`groupSize` and swap it into `layer`
|
|
69
|
-
* in place (port of `_mutate_quantized_layer_to_bits`). The previously
|
|
70
|
-
* swapped-in tensors (if any beyond the captured original) are released by
|
|
71
|
-
* the caller via restoreState; this only installs the new ones. */
|
|
72
|
-
function mutateLayerToBits(
|
|
73
|
-
layer: QuantizedLinear,
|
|
74
|
-
bf16Weight: MlxArray,
|
|
75
|
-
newBits: number,
|
|
76
|
-
groupSize: number,
|
|
77
|
-
original: LayerState,
|
|
78
|
-
): void {
|
|
79
|
-
const q = ops.quantize(bf16Weight, groupSize, newBits, "affine", cpuStream);
|
|
80
|
-
const previous = layer.exchangeQuantizedState({
|
|
81
|
-
w: q.packed,
|
|
82
|
-
scales: q.scales,
|
|
83
|
-
biases: q.biases,
|
|
84
|
-
spec: { bits: newBits, groupSize, mode: "affine" },
|
|
85
|
-
});
|
|
86
|
-
// Free any previously swapped-in transient tensors (not the original).
|
|
87
|
-
if (previous.w !== original.w) previous.w.dispose();
|
|
88
|
-
if (previous.scales !== original.scales) previous.scales.dispose();
|
|
89
|
-
if (previous.biases && previous.biases !== original.biases) previous.biases.dispose();
|
|
90
|
-
ops.evalAll([q.packed, q.scales, q.biases]);
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
// --------------------------------------------------------------------------
|
|
94
|
-
// KL primitive (port of _kl_from_ref)
|
|
95
|
-
// --------------------------------------------------------------------------
|
|
96
|
-
|
|
97
|
-
/** KL(reference || current) averaged across batch/seq (port of `_kl_from_ref`):
|
|
98
|
-
* log_cur = cur - logsumexp(cur); log_ref = ref - logsumexp(ref)
|
|
99
|
-
* ref_probs = softmax(ref)
|
|
100
|
-
* mean( sum( ref_probs * (log_ref - log_cur), axis=-1 ) )
|
|
101
|
-
* Returns the scalar KL as a JS number. Casts to f32 for stability. */
|
|
102
|
-
export function klFromRef(curLogits: MlxArray, refLogits: MlxArray): number {
|
|
103
|
-
const cur = curLogits.dtype === Dtype.float32 ? curLogits : curLogits.astype(Dtype.float32);
|
|
104
|
-
const ref = refLogits.dtype === Dtype.float32 ? refLogits : refLogits.astype(Dtype.float32);
|
|
105
|
-
|
|
106
|
-
const lseCur = ops.logsumexpAxis(cur, -1, true);
|
|
107
|
-
const lseRef = ops.logsumexpAxis(ref, -1, true);
|
|
108
|
-
const logCur = ops.sub(cur, lseCur);
|
|
109
|
-
const logRef = ops.sub(ref, lseRef);
|
|
110
|
-
const refProbs = ops.softmaxAxis(ref, -1, true);
|
|
111
|
-
|
|
112
|
-
const diff = ops.sub(logRef, logCur);
|
|
113
|
-
const weighted = ops.mul(refProbs, diff);
|
|
114
|
-
const summed = ops.sumAxis(weighted, -1, false);
|
|
115
|
-
const meaned = ops.meanAll(summed, false);
|
|
116
|
-
|
|
117
|
-
const val = meaned.toFloat32()[0]!;
|
|
118
|
-
|
|
119
|
-
for (const a of [lseCur, lseRef, logCur, logRef, refProbs, diff, weighted, summed, meaned]) {
|
|
120
|
-
a.dispose();
|
|
121
|
-
}
|
|
122
|
-
if (cur !== curLogits) cur.dispose();
|
|
123
|
-
if (ref !== refLogits) ref.dispose();
|
|
124
|
-
return val;
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
// --------------------------------------------------------------------------
|
|
128
|
-
// Public entry: analyzeSensitivityExact
|
|
129
|
-
// --------------------------------------------------------------------------
|
|
130
|
-
|
|
131
|
-
/** Per-layer KL sensitivity of an already-quantized MLX model.
|
|
132
|
-
*
|
|
133
|
-
* @param model loaded RuntimeModel (its QuantizedLinears are the
|
|
134
|
-
* uniform baseline; their dequantized weights are the
|
|
135
|
-
* self-contained bf16 source).
|
|
136
|
-
* @param layers the quantizable linears to probe, keyed by module path
|
|
137
|
-
* (typically `model.loraTargets()`).
|
|
138
|
-
* @param calIds calibration samples — each a row of int32 token ids.
|
|
139
|
-
* @param options candidateBits (default [4,8]) and groupSize (default 64).
|
|
140
|
-
*/
|
|
141
|
-
export function analyzeSensitivityExact(
|
|
142
|
-
model: RuntimeModel,
|
|
143
|
-
layers: Map<string, QuantizedLinear>,
|
|
144
|
-
calIds: number[][],
|
|
145
|
-
options: AnalyzeSensitivityOptions = {},
|
|
146
|
-
onProgress?: (done: number, total: number, layerName: string) => void,
|
|
147
|
-
): SensitivityResult[] {
|
|
148
|
-
const candidateBits = [...(options.candidateBits ?? [4, 8])];
|
|
149
|
-
const groupSize = options.groupSize ?? 64;
|
|
150
|
-
|
|
151
|
-
// Calibration sample arrays (int32 [1, L]).
|
|
152
|
-
const calArrays = calIds.map((ids) =>
|
|
153
|
-
MlxArray.fromInt32(new Int32Array(ids), [1, ids.length]),
|
|
154
|
-
);
|
|
155
|
-
|
|
156
|
-
try {
|
|
157
|
-
// Reference logits from the unmodified running model (taken once).
|
|
158
|
-
const refLogits: MlxArray[] = calArrays.map((ids) => trainForward(model, ids));
|
|
159
|
-
ops.evalAll(refLogits);
|
|
160
|
-
|
|
161
|
-
const entries = [...layers.entries()];
|
|
162
|
-
const results: SensitivityResult[] = [];
|
|
163
|
-
|
|
164
|
-
try {
|
|
165
|
-
for (let li = 0; li < entries.length; li++) {
|
|
166
|
-
const [layerName, layer] = entries[li]!;
|
|
167
|
-
const original = captureState(layer);
|
|
168
|
-
const baselineBits = layer.spec.bits;
|
|
169
|
-
|
|
170
|
-
// Self-contained bf16 source: dequantize the layer's own packed weight.
|
|
171
|
-
const bf16Source = ops.dequantize(
|
|
172
|
-
original.w, original.scales, original.biases, original.spec, cpuStream,
|
|
173
|
-
).astype(Dtype.bfloat16, cpuStream);
|
|
174
|
-
ops.evalAll([bf16Source]);
|
|
175
|
-
|
|
176
|
-
const sensitivities: Record<number, number> = {};
|
|
177
|
-
try {
|
|
178
|
-
for (const bits of candidateBits) {
|
|
179
|
-
if (bits === baselineBits) {
|
|
180
|
-
// KL is 0 by construction (re-quantizing to the baseline bit-width
|
|
181
|
-
// reproduces the running model). Skip the forwards.
|
|
182
|
-
sensitivities[bits] = 0.0;
|
|
183
|
-
continue;
|
|
184
|
-
}
|
|
185
|
-
mutateLayerToBits(layer, bf16Source, bits, groupSize, original);
|
|
186
|
-
|
|
187
|
-
let klSum = 0;
|
|
188
|
-
for (let i = 0; i < calArrays.length; i++) {
|
|
189
|
-
const cur = trainForward(model, calArrays[i]!);
|
|
190
|
-
klSum += klFromRef(cur, refLogits[i]!);
|
|
191
|
-
cur.dispose();
|
|
192
|
-
}
|
|
193
|
-
sensitivities[bits] = klSum / Math.max(calArrays.length, 1);
|
|
194
|
-
}
|
|
195
|
-
} finally {
|
|
196
|
-
// Restore even when quantization or a calibration forward throws.
|
|
197
|
-
restoreState(layer, original);
|
|
198
|
-
bf16Source.dispose();
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
// param count = product of the dequantized (full) weight shape.
|
|
202
|
-
const fullShape = [layer.outFeatures, layer.inFeatures];
|
|
203
|
-
const paramCount = fullShape.reduce((a, b) => a * b, 1);
|
|
204
|
-
|
|
205
|
-
results.push({ layerName, sensitivities, paramCount });
|
|
206
|
-
onProgress?.(li + 1, entries.length, layerName);
|
|
207
|
-
}
|
|
208
|
-
} finally {
|
|
209
|
-
for (const r of refLogits) r.dispose();
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
return results;
|
|
213
|
-
} finally {
|
|
214
|
-
for (const a of calArrays) a.dispose();
|
|
215
|
-
}
|
|
216
|
-
}
|