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,540 +0,0 @@
|
|
|
1
|
-
// DSpark draft module — a trainable, semi-autoregressive speculative drafter
|
|
2
|
-
// for frozen Gemma-4 e4b. Port of the architecture in DeepSeek's DSpark paper
|
|
3
|
-
// ("Confidence-Scheduled Speculative Decoding with Semi-Autoregressive
|
|
4
|
-
// Generation"), instantiated against this repo's e4b spine.
|
|
5
|
-
//
|
|
6
|
-
// Three sub-parts (paper §3.1–3.2), all reading e4b's tapped hidden state:
|
|
7
|
-
// 1. DFlash backbone — a lightweight bidirectional transformer over a
|
|
8
|
-
// γ-token block (anchor + γ−1 learned mask tokens) plus one injected
|
|
9
|
-
// context token (the tapped target hidden, H_ctx). One forward pass
|
|
10
|
-
// predicts all γ draft positions in parallel. (paper Eq 2–3, m=1
|
|
11
|
-
// single-vector context for v1.)
|
|
12
|
-
// 2. Markov head — low-rank first-order transition bias added to the base
|
|
13
|
-
// logits, B(x_{k-1},·) = W1[x_{k-1}]·W2, r=256. W2 INIT 0 so the module
|
|
14
|
-
// starts as the pure-parallel DFlash baseline and τ climbs as the head
|
|
15
|
-
// learns intra-block dependency. (paper Eq 5)
|
|
16
|
-
// 3. Confidence head — c_k = σ(wᵀ[h_k; W1[x_{k-1}]]) ∈ (0,1), per-position
|
|
17
|
-
// predicted acceptance probability. (paper Eq 7)
|
|
18
|
-
//
|
|
19
|
-
// It SHARES e4b's frozen embedding + LM head (logits = the same head the
|
|
20
|
-
// target verifies with, so draft tokens live in the same vocab/logit space).
|
|
21
|
-
// Only the parts here are trainable; the target stays frozen.
|
|
22
|
-
//
|
|
23
|
-
// Tap point (v1, by design decision): the final post-norm hidden from
|
|
24
|
-
// model.forwardHidden — the m=1 degenerate of DFlash's multi-layer H_ctx,
|
|
25
|
-
// and exactly what the existing GemmaAssistantDrafter consumes. Zero changes
|
|
26
|
-
// to the parity-gated model files. Richer context injection (intermediate
|
|
27
|
-
// post-PLE residual, multi-layer concat, or borrowing the target's prefix
|
|
28
|
-
// K/V à la GemmaAssistantDrafter) is the main τ lever after v1.
|
|
29
|
-
|
|
30
|
-
import { MlxArray } from "../../mlx/array";
|
|
31
|
-
import { Dtype } from "../../mlx/ffi";
|
|
32
|
-
import * as ops from "../../mlx/ops";
|
|
33
|
-
import type { Gemma4Model } from "../../model/gemma4";
|
|
34
|
-
import type { DraftProjection } from "../source";
|
|
35
|
-
import { loadAdapterTensors } from "../../lora";
|
|
36
|
-
import { writeShardedSafetensors, type NamedTensor } from "../../quantize/safetensors-writer";
|
|
37
|
-
import { processLogits, sampleToken, KeyStream, type DSparkSampleConfig } from "./sample";
|
|
38
|
-
import { mkdirSync, writeFileSync, readFileSync, existsSync } from "node:fs";
|
|
39
|
-
import { join } from "node:path";
|
|
40
|
-
|
|
41
|
-
export interface DSparkConfig {
|
|
42
|
-
/** Max draft-block size γ (paper default 5). */
|
|
43
|
-
gamma: number;
|
|
44
|
-
/** Backbone hidden width. */
|
|
45
|
-
dDraft: number;
|
|
46
|
-
/** Backbone depth (paper default 5; 2 already beats 5-layer DFlash). */
|
|
47
|
-
nLayers: number;
|
|
48
|
-
/** Backbone attention heads (dDraft must be divisible). */
|
|
49
|
-
nHeads: number;
|
|
50
|
-
/** Markov low-rank dim r (paper default 256). */
|
|
51
|
-
markovRank: number;
|
|
52
|
-
/** FFN expansion multiple (dInter = ffMult·dDraft). */
|
|
53
|
-
ffMult: number;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
export const DEFAULT_DSPARK_CONFIG: DSparkConfig = {
|
|
57
|
-
gamma: 5,
|
|
58
|
-
dDraft: 1024,
|
|
59
|
-
nLayers: 2,
|
|
60
|
-
nHeads: 8,
|
|
61
|
-
markovRank: 256,
|
|
62
|
-
ffMult: 2,
|
|
63
|
-
};
|
|
64
|
-
|
|
65
|
-
/** Dims read from the live target model — never hardcoded. */
|
|
66
|
-
export interface TargetDims {
|
|
67
|
-
hiddenSize: number;
|
|
68
|
-
vocabSize: number;
|
|
69
|
-
eps: number;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
/** Output of the parallel training forward over a batch of A anchors. */
|
|
73
|
-
export interface DSparkTrainOut {
|
|
74
|
-
/** Draft logits U_k + B_k, pre-softmax. [A, γ, V] (float32). */
|
|
75
|
-
draftLogits: MlxArray;
|
|
76
|
-
/** Per-position predicted acceptance probability c_k ∈ (0,1). [A, γ]. */
|
|
77
|
-
conf: MlxArray;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
/** Output of one inference draft-block generation. */
|
|
81
|
-
export interface DSparkDraftBlock {
|
|
82
|
-
/** Drafted token ids d_1..d_γ. */
|
|
83
|
-
tokens: number[];
|
|
84
|
-
/** Per-position confidence c_1..c_γ. */
|
|
85
|
-
conf: number[];
|
|
86
|
-
/** Raw per-position draft logits U_k+B_k [1, γ, V] (given the sampled prefix).
|
|
87
|
-
* The verifier reprocesses these with the same sampling config to recover the
|
|
88
|
-
* draft distribution q_k for the accept/residual rule. Caller disposes. */
|
|
89
|
-
draftLogits: MlxArray;
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
/** Options for one draft-block generation. */
|
|
93
|
-
export interface DSparkDraftOpts {
|
|
94
|
-
/** Sampling config; omit (or temperature 0) ⇒ greedy argmax. */
|
|
95
|
-
sample?: DSparkSampleConfig;
|
|
96
|
-
/** Shared key stream (so draft + verify draws are reproducible together). */
|
|
97
|
-
keys?: KeyStream;
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
const CDT = Dtype.float32; // compute & param dtype for the small draft module
|
|
101
|
-
|
|
102
|
-
function disposing(old: MlxArray, next: MlxArray): MlxArray {
|
|
103
|
-
old.dispose();
|
|
104
|
-
return next;
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
// --- seeded init --------------------------------------------------------
|
|
108
|
-
// xorshift32 + Box–Muller. Deterministic given a seed so checkpoints and
|
|
109
|
-
// smoke tests reproduce. (Date/Math.random are unavailable in some harness
|
|
110
|
-
// contexts; this is self-contained anyway.)
|
|
111
|
-
function makeRng(seed: number): () => number {
|
|
112
|
-
let s = seed >>> 0 || 0x9e3779b9;
|
|
113
|
-
return () => {
|
|
114
|
-
s ^= s << 13; s >>>= 0;
|
|
115
|
-
s ^= s >> 17;
|
|
116
|
-
s ^= s << 5; s >>>= 0;
|
|
117
|
-
return s / 0x100000000;
|
|
118
|
-
};
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
function normalArray(rng: () => number, shape: number[], std: number): MlxArray {
|
|
122
|
-
const n = shape.reduce((a, b) => a * b, 1);
|
|
123
|
-
const out = new Float32Array(n);
|
|
124
|
-
for (let i = 0; i < n; i += 2) {
|
|
125
|
-
const u1 = Math.max(rng(), 1e-12);
|
|
126
|
-
const u2 = rng();
|
|
127
|
-
const r = Math.sqrt(-2 * Math.log(u1));
|
|
128
|
-
out[i] = r * Math.cos(2 * Math.PI * u2) * std;
|
|
129
|
-
if (i + 1 < n) out[i + 1] = r * Math.sin(2 * Math.PI * u2) * std;
|
|
130
|
-
}
|
|
131
|
-
return MlxArray.fromFloat32(out, shape);
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
function zerosArray(shape: number[]): MlxArray {
|
|
135
|
-
const n = shape.reduce((a, b) => a * b, 1);
|
|
136
|
-
return MlxArray.fromFloat32(new Float32Array(n), shape);
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
function constArray(shape: number[], value: number): MlxArray {
|
|
140
|
-
const n = shape.reduce((a, b) => a * b, 1);
|
|
141
|
-
return MlxArray.fromFloat32(new Float32Array(n).fill(value), shape);
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
export class DSparkDrafter {
|
|
145
|
-
readonly cfg: DSparkConfig;
|
|
146
|
-
readonly dims: TargetDims;
|
|
147
|
-
/** Stamped onto the checkpoint so the registry can key it to its target. */
|
|
148
|
-
readonly targetId: string;
|
|
149
|
-
/** Trainable params keyed by stable name. */
|
|
150
|
-
#p = new Map<string, MlxArray>();
|
|
151
|
-
/** Canonical flat order — the only source of truth for param ordering. */
|
|
152
|
-
readonly names: string[];
|
|
153
|
-
|
|
154
|
-
private constructor(cfg: DSparkConfig, dims: TargetDims, targetId: string) {
|
|
155
|
-
this.cfg = cfg;
|
|
156
|
-
this.dims = dims;
|
|
157
|
-
this.targetId = targetId;
|
|
158
|
-
if (cfg.dDraft % cfg.nHeads !== 0)
|
|
159
|
-
throw new Error(`dDraft ${cfg.dDraft} not divisible by nHeads ${cfg.nHeads}`);
|
|
160
|
-
this.names = buildNames(cfg);
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
static dimsOf(model: Gemma4Model): TargetDims {
|
|
164
|
-
const t = model.config.text;
|
|
165
|
-
return { hiddenSize: t.hiddenSize, vocabSize: t.vocabSize, eps: t.rmsNormEps };
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
/** Fresh, randomly initialized module sized to `model`. W2=0 (pure DFlash
|
|
169
|
-
* at init), confidence head zero (c≈0.5 at init). */
|
|
170
|
-
static init(model: Gemma4Model, cfg: DSparkConfig, targetId: string, seed = 0): DSparkDrafter {
|
|
171
|
-
return DSparkDrafter.initFromDims(DSparkDrafter.dimsOf(model), cfg, targetId, seed);
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
/** As `init` but sized from explicit dims (no model needed — used by tests
|
|
175
|
-
* and the offline checkpoint path). */
|
|
176
|
-
static initFromDims(dims: TargetDims, cfg: DSparkConfig, targetId: string, seed = 0): DSparkDrafter {
|
|
177
|
-
const d = new DSparkDrafter(cfg, dims, targetId);
|
|
178
|
-
const rng = makeRng(seed);
|
|
179
|
-
const { dDraft, nLayers, markovRank: r, ffMult } = cfg;
|
|
180
|
-
const dInter = ffMult * dDraft;
|
|
181
|
-
const { hiddenSize: H, vocabSize: V } = d.dims;
|
|
182
|
-
const set = (n: string, a: MlxArray) => d.#p.set(n, a.eval());
|
|
183
|
-
|
|
184
|
-
for (let i = 0; i < nLayers; i++) {
|
|
185
|
-
set(`bb.${i}.attn_norm`, constArray([dDraft], 1.0));
|
|
186
|
-
for (const w of ["q", "k", "v", "o"]) set(`bb.${i}.${w}`, normalArray(rng, [dDraft, dDraft], 0.02));
|
|
187
|
-
set(`bb.${i}.ff_norm`, constArray([dDraft], 1.0));
|
|
188
|
-
set(`bb.${i}.gate`, normalArray(rng, [dDraft, dInter], 0.02));
|
|
189
|
-
set(`bb.${i}.up`, normalArray(rng, [dDraft, dInter], 0.02));
|
|
190
|
-
set(`bb.${i}.down`, normalArray(rng, [dInter, dDraft], 0.02));
|
|
191
|
-
}
|
|
192
|
-
set("ctx_proj", normalArray(rng, [H, dDraft], 0.02));
|
|
193
|
-
set("tok_proj", normalArray(rng, [H, dDraft], 0.02));
|
|
194
|
-
set("mask_emb", normalArray(rng, [cfg.gamma - 1, dDraft], 0.02));
|
|
195
|
-
set("pos_emb", normalArray(rng, [cfg.gamma + 1, dDraft], 0.02));
|
|
196
|
-
set("out_norm", constArray([dDraft], 1.0));
|
|
197
|
-
set("out_proj", normalArray(rng, [dDraft, H], 0.02));
|
|
198
|
-
set("markov.w1", normalArray(rng, [V, r], 0.02));
|
|
199
|
-
set("markov.w2", zerosArray([r, V])); // ← starts as pure DFlash
|
|
200
|
-
set("conf.w", zerosArray([dDraft + r, 1])); // ← c≈0.5 at init
|
|
201
|
-
set("conf.b", zerosArray([1]));
|
|
202
|
-
return d;
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
get(name: string): MlxArray {
|
|
206
|
-
const a = this.#p.get(name);
|
|
207
|
-
if (!a) throw new Error(`DSpark param not found: ${name}`);
|
|
208
|
-
return a;
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
/** Params in canonical flat order — the leaves ValueAndGrad differentiates. */
|
|
212
|
-
flatParams(): MlxArray[] {
|
|
213
|
-
return this.names.map((n) => this.get(n));
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
/** Run `fn` with `primals` temporarily installed as the params (then restore
|
|
217
|
-
* the originals). Mirrors the LoRA swapPrimals discipline — lets a
|
|
218
|
-
* ValueAndGrad closure differentiate w.r.t. the flat param list while the
|
|
219
|
-
* forward reads params by name. */
|
|
220
|
-
useParams<T>(primals: MlxArray[], fn: () => T): T {
|
|
221
|
-
if (primals.length !== this.names.length)
|
|
222
|
-
throw new Error(`useParams: ${primals.length} primals vs ${this.names.length} params`);
|
|
223
|
-
const saved = this.names.map((n) => this.get(n));
|
|
224
|
-
this.names.forEach((n, i) => this.#p.set(n, primals[i]!));
|
|
225
|
-
try {
|
|
226
|
-
return fn();
|
|
227
|
-
} finally {
|
|
228
|
-
this.names.forEach((n, i) => this.#p.set(n, saved[i]!));
|
|
229
|
-
}
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
/** Install the optimizer's updated leaf as the i-th param. Does NOT dispose
|
|
233
|
-
* the previous one — AdamW.step already freed it. Use as AdamW's write
|
|
234
|
-
* callback: `new AdamW(d.flatParams(), opts, (i, p) => d.installParam(i, p))`. */
|
|
235
|
-
installParam(i: number, p: MlxArray): void {
|
|
236
|
-
this.#p.set(this.names[i]!, p);
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
// --- backbone -----------------------------------------------------------
|
|
240
|
-
|
|
241
|
-
/** One pre-norm bidirectional transformer layer over [A, S, dDraft]. */
|
|
242
|
-
#layer(i: number, x: MlxArray, A: number, S: number): MlxArray {
|
|
243
|
-
const { dDraft, nHeads } = this.cfg;
|
|
244
|
-
const hd = dDraft / nHeads;
|
|
245
|
-
const eps = this.dims.eps;
|
|
246
|
-
|
|
247
|
-
// attention (full / bidirectional — no mask)
|
|
248
|
-
const residual = x;
|
|
249
|
-
let n = ops.rmsNorm(x, this.get(`bb.${i}.attn_norm`), eps);
|
|
250
|
-
const proj = (w: string) => {
|
|
251
|
-
const m = ops.matmul(n, this.get(`bb.${i}.${w}`)); // [A,S,dDraft]
|
|
252
|
-
const r = ops.reshape(m, [A, S, nHeads, hd]);
|
|
253
|
-
m.dispose();
|
|
254
|
-
const t = ops.transposeAxes(r, [0, 2, 1, 3]); // [A,nHeads,S,hd]
|
|
255
|
-
r.dispose();
|
|
256
|
-
return t;
|
|
257
|
-
};
|
|
258
|
-
const q = proj("q");
|
|
259
|
-
const k = proj("k");
|
|
260
|
-
const v = proj("v");
|
|
261
|
-
n.dispose();
|
|
262
|
-
let attn = ops.sdpa(q, k, v, Math.pow(hd, -0.5), "", null);
|
|
263
|
-
q.dispose(); k.dispose(); v.dispose();
|
|
264
|
-
attn = disposing(attn, ops.transposeAxes(attn, [0, 2, 1, 3])); // [A,S,nHeads,hd]
|
|
265
|
-
attn = disposing(attn, ops.reshape(attn, [A, S, dDraft]));
|
|
266
|
-
attn = disposing(attn, ops.matmul(attn, this.get(`bb.${i}.o`)));
|
|
267
|
-
x = ops.add(residual, attn);
|
|
268
|
-
attn.dispose();
|
|
269
|
-
|
|
270
|
-
// gated-GELU FFN
|
|
271
|
-
const res2 = x;
|
|
272
|
-
n = ops.rmsNorm(x, this.get(`bb.${i}.ff_norm`), eps);
|
|
273
|
-
const g = ops.matmul(n, this.get(`bb.${i}.gate`));
|
|
274
|
-
const u = ops.matmul(n, this.get(`bb.${i}.up`));
|
|
275
|
-
n.dispose();
|
|
276
|
-
const act = ops.geluApprox(g);
|
|
277
|
-
g.dispose();
|
|
278
|
-
let mlp = ops.mul(act, u);
|
|
279
|
-
act.dispose(); u.dispose();
|
|
280
|
-
mlp = disposing(mlp, ops.matmul(mlp, this.get(`bb.${i}.down`)));
|
|
281
|
-
const out = ops.add(res2, mlp);
|
|
282
|
-
res2.dispose(); mlp.dispose();
|
|
283
|
-
return out;
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
/** Build the [A, γ+1, dDraft] input sequence: [ctxToken, anchor, mask₁..].
|
|
287
|
-
* hCtx [A,H], anchorEmb [A,H] (raw embedding, no scale). */
|
|
288
|
-
#buildSeq(hCtx: MlxArray, anchorEmb: MlxArray, A: number): MlxArray {
|
|
289
|
-
const { gamma, dDraft } = this.cfg;
|
|
290
|
-
const posEmb = this.get("pos_emb"); // [γ+1, dDraft]
|
|
291
|
-
|
|
292
|
-
// backbone math is float32; cast the (possibly bf16) target tensors in.
|
|
293
|
-
const hCtxF = hCtx.dtype === CDT ? hCtx : hCtx.astype(CDT);
|
|
294
|
-
const anchorF = anchorEmb.dtype === CDT ? anchorEmb : anchorEmb.astype(CDT);
|
|
295
|
-
|
|
296
|
-
// ctx token = ctx_proj(hCtx) + pos[0]
|
|
297
|
-
let ctx = ops.matmul(hCtxF, this.get("ctx_proj")); // [A,dDraft]
|
|
298
|
-
if (hCtxF !== hCtx) hCtxF.dispose();
|
|
299
|
-
const pos0 = posEmb.slice([0, 0], [1, dDraft]);
|
|
300
|
-
ctx = disposing(ctx, ops.add(ctx, pos0));
|
|
301
|
-
pos0.dispose();
|
|
302
|
-
ctx = disposing(ctx, ops.reshape(ctx, [A, 1, dDraft]));
|
|
303
|
-
|
|
304
|
-
// anchor token (block position 0) = tok_proj(anchorEmb) + pos[1]
|
|
305
|
-
let anchor = ops.matmul(anchorF, this.get("tok_proj")); // [A,dDraft]
|
|
306
|
-
if (anchorF !== anchorEmb) anchorF.dispose();
|
|
307
|
-
const pos1 = posEmb.slice([1, 0], [2, dDraft]);
|
|
308
|
-
anchor = disposing(anchor, ops.add(anchor, pos1));
|
|
309
|
-
pos1.dispose();
|
|
310
|
-
anchor = disposing(anchor, ops.reshape(anchor, [A, 1, dDraft]));
|
|
311
|
-
|
|
312
|
-
const parts = [ctx, anchor];
|
|
313
|
-
if (gamma > 1) {
|
|
314
|
-
// mask tokens (block positions 1..γ-1) = mask_emb[j-1] + pos[j+1], built
|
|
315
|
-
// once at batch 1 then broadcast to A in a single add.
|
|
316
|
-
const maskEmb = this.get("mask_emb"); // [γ-1, dDraft]
|
|
317
|
-
const posMask = posEmb.slice([2, 0], [gamma + 1, dDraft]); // pos[2..γ] → [γ-1,dDraft]
|
|
318
|
-
let masks = ops.add(maskEmb, posMask); // [γ-1, dDraft]
|
|
319
|
-
posMask.dispose();
|
|
320
|
-
masks = disposing(masks, ops.reshape(masks, [1, gamma - 1, dDraft]));
|
|
321
|
-
const zerosA = MlxArray.fromFloat32(new Float32Array(A * dDraft), [A, 1, dDraft]);
|
|
322
|
-
const masksA = ops.add(masks, zerosA); // broadcast → [A, γ-1, dDraft]
|
|
323
|
-
masks.dispose(); zerosA.dispose();
|
|
324
|
-
parts.push(masksA);
|
|
325
|
-
}
|
|
326
|
-
const seq = ops.concatAxis(parts, 1); // [A, γ+1, dDraft]
|
|
327
|
-
for (const p of parts) p.dispose();
|
|
328
|
-
return seq;
|
|
329
|
-
}
|
|
330
|
-
|
|
331
|
-
/** Run the backbone and return the per-block-position hidden h_1..h_γ
|
|
332
|
-
* [A, γ, dDraft]. */
|
|
333
|
-
#backbone(hCtx: MlxArray, anchorEmb: MlxArray, A: number): MlxArray {
|
|
334
|
-
const { gamma, dDraft } = this.cfg;
|
|
335
|
-
const S = gamma + 1;
|
|
336
|
-
let h = this.#buildSeq(hCtx, anchorEmb, A);
|
|
337
|
-
for (let i = 0; i < this.cfg.nLayers; i++) h = disposing(h, this.#layer(i, h, A, S));
|
|
338
|
-
h = disposing(h, ops.rmsNorm(h, this.get("out_norm"), this.dims.eps));
|
|
339
|
-
// drop the ctx position (index 0); keep the γ block outputs
|
|
340
|
-
const block = h.slice([0, 1, 0], [A, S, dDraft]); // [A,γ,dDraft]
|
|
341
|
-
h.dispose();
|
|
342
|
-
return block;
|
|
343
|
-
}
|
|
344
|
-
|
|
345
|
-
/** Base logits U from the SHARED frozen LM head over the backbone block
|
|
346
|
-
* hidden. [A,γ,V] (model dtype). */
|
|
347
|
-
#baseLogits(model: DraftProjection, block: MlxArray): MlxArray {
|
|
348
|
-
const hOut = ops.matmul(block, this.get("out_proj")); // [A,γ,H] (f32)
|
|
349
|
-
const hBf = hOut.astype(model.embed.scales.dtype); // head's activation dtype
|
|
350
|
-
hOut.dispose();
|
|
351
|
-
const logits = model.logitsFromHidden(hBf); // shared head (+softcap) [A,γ,V]
|
|
352
|
-
hBf.dispose();
|
|
353
|
-
return logits;
|
|
354
|
-
}
|
|
355
|
-
|
|
356
|
-
/** Markov transition bias B [A,γ,V] from teacher/prev tokens [A,γ] and the
|
|
357
|
-
* W1-embedding emb1 [A,γ,r] (also returned for the confidence head). */
|
|
358
|
-
#markov(prevToks: MlxArray): { B: MlxArray; emb1: MlxArray } {
|
|
359
|
-
const w1 = this.get("markov.w1"); // [V,r]
|
|
360
|
-
const w2 = this.get("markov.w2"); // [r,V]
|
|
361
|
-
const emb1 = ops.takeAxis(w1, prevToks, 0); // [A,γ,r]
|
|
362
|
-
const B = ops.matmul(emb1, w2); // [A,γ,V]
|
|
363
|
-
return { B, emb1 };
|
|
364
|
-
}
|
|
365
|
-
|
|
366
|
-
/** Confidence c_k = σ(wᵀ[h_k; emb1_k]). block [A,γ,dDraft], emb1 [A,γ,r]. */
|
|
367
|
-
#confidence(block: MlxArray, emb1: MlxArray): MlxArray {
|
|
368
|
-
const inp = ops.concatAxis([block, emb1], 2); // [A,γ,dDraft+r]
|
|
369
|
-
let z = ops.matmul(inp, this.get("conf.w")); // [A,γ,1]
|
|
370
|
-
inp.dispose();
|
|
371
|
-
z = disposing(z, ops.add(z, this.get("conf.b")));
|
|
372
|
-
z = disposing(z, ops.sigmoid(z));
|
|
373
|
-
const A = z.shape[0]!, G = z.shape[1]!;
|
|
374
|
-
const c = ops.reshape(z, [A, G]); // [A,γ]
|
|
375
|
-
z.dispose();
|
|
376
|
-
return c;
|
|
377
|
-
}
|
|
378
|
-
|
|
379
|
-
/**
|
|
380
|
-
* Parallel TRAINING forward over A anchors (teacher-forced Markov).
|
|
381
|
-
* - hCtx [A, H] target final hidden at each anchor (the tap, const)
|
|
382
|
-
* - anchorEmb [A, H] raw embedding of the anchor token x0 (const)
|
|
383
|
-
* - prevToks [A, γ] int32: [x0, x*_1, …, x*_{γ-1}] (teacher tokens)
|
|
384
|
-
* Returns draftLogits = U + B [A,γ,V] (float32) and conf [A,γ].
|
|
385
|
-
*/
|
|
386
|
-
forwardTrain(model: Gemma4Model, hCtx: MlxArray, anchorEmb: MlxArray, prevToks: MlxArray): DSparkTrainOut {
|
|
387
|
-
const A = hCtx.shape[0]!;
|
|
388
|
-
const block = this.#backbone(hCtx, anchorEmb, A); // [A,γ,dDraft]
|
|
389
|
-
const U = this.#baseLogits(model, block); // [A,γ,V]
|
|
390
|
-
const Uf = U.astype(CDT); U.dispose();
|
|
391
|
-
const { B, emb1 } = this.#markov(prevToks);
|
|
392
|
-
let draftLogits = ops.add(Uf, B); // [A,γ,V] f32
|
|
393
|
-
Uf.dispose(); B.dispose();
|
|
394
|
-
const conf = this.#confidence(block, emb1);
|
|
395
|
-
block.dispose(); emb1.dispose();
|
|
396
|
-
return { draftLogits, conf };
|
|
397
|
-
}
|
|
398
|
-
|
|
399
|
-
/**
|
|
400
|
-
* INFERENCE: generate one γ-block by the semi-autoregressive rule — the
|
|
401
|
-
* backbone runs ONCE (parallel U_1..U_γ), then the Markov head walks the block
|
|
402
|
-
* left-to-right (each position conditions on the previously emitted draft
|
|
403
|
-
* token). Greedy argmax when no sampling config (or temperature 0); otherwise
|
|
404
|
-
* samples each token from the SAME processed distribution the verifier
|
|
405
|
-
* reconstructs (so q is consistent). hCtx [1,H], anchorTok the bonus token.
|
|
406
|
-
* Returns the raw per-position logits so the verifier can recover q.
|
|
407
|
-
*/
|
|
408
|
-
forwardInfer(model: DraftProjection, hCtx: MlxArray, anchorTok: number, gamma: number, opts: DSparkDraftOpts = {}): DSparkDraftBlock {
|
|
409
|
-
const { dDraft, markovRank: r } = this.cfg;
|
|
410
|
-
const V = this.dims.vocabSize;
|
|
411
|
-
const A = 1;
|
|
412
|
-
const sample = opts.sample && opts.sample.temperature > 0 ? opts.sample : null;
|
|
413
|
-
const keys = opts.keys ?? new KeyStream(opts.sample?.seed ?? 0);
|
|
414
|
-
|
|
415
|
-
// anchor embedding (raw)
|
|
416
|
-
const ids = ops.fromInt32([anchorTok], [1, 1]);
|
|
417
|
-
const anchorEmb3 = model.embed.encode(ids); // [1,1,H]
|
|
418
|
-
ids.dispose();
|
|
419
|
-
const anchorEmb = ops.reshape(anchorEmb3, [1, this.dims.hiddenSize]);
|
|
420
|
-
anchorEmb3.dispose();
|
|
421
|
-
|
|
422
|
-
const block = this.#backbone(hCtx, anchorEmb, A); // [1,γ,dDraft]
|
|
423
|
-
anchorEmb.dispose();
|
|
424
|
-
const U = this.#baseLogits(model, block); // [1,γ,V]
|
|
425
|
-
const Uf = U.astype(CDT); U.dispose();
|
|
426
|
-
|
|
427
|
-
const w1 = this.get("markov.w1"); // [V,r]
|
|
428
|
-
const w2 = this.get("markov.w2"); // [r,V]
|
|
429
|
-
const tokens: number[] = [];
|
|
430
|
-
const conf: number[] = [];
|
|
431
|
-
const perPosLogits: MlxArray[] = []; // each [1,1,V], stacked into draftLogits
|
|
432
|
-
let prevTok = anchorTok;
|
|
433
|
-
for (let k = 0; k < gamma; k++) {
|
|
434
|
-
// U_k [1,V]
|
|
435
|
-
const Uk = Uf.slice([0, k, 0], [1, k + 1, V]);
|
|
436
|
-
const UkFlat = ops.reshape(Uk, [1, V]);
|
|
437
|
-
Uk.dispose();
|
|
438
|
-
// B_k = W1[prevTok] · W2 → [1,V]
|
|
439
|
-
const prevIdx = ops.fromInt32([prevTok], [1]);
|
|
440
|
-
const e1 = ops.takeAxis(w1, prevIdx, 0); // [1,r]
|
|
441
|
-
prevIdx.dispose();
|
|
442
|
-
const Bk = ops.matmul(e1, w2); // [1,V]
|
|
443
|
-
const logitsK = ops.add(UkFlat, Bk); // raw U_k + B_k [1,V]
|
|
444
|
-
UkFlat.dispose(); Bk.dispose();
|
|
445
|
-
|
|
446
|
-
let tok: number;
|
|
447
|
-
if (sample) {
|
|
448
|
-
const scaled = processLogits(logitsK, sample); // top-p/top-k/temp
|
|
449
|
-
tok = sampleToken(scaled, keys.next());
|
|
450
|
-
scaled.dispose();
|
|
451
|
-
} else {
|
|
452
|
-
const am = ops.argmaxAxis(logitsK, -1);
|
|
453
|
-
tok = ops.itemUint32(am);
|
|
454
|
-
am.dispose();
|
|
455
|
-
}
|
|
456
|
-
perPosLogits.push(ops.reshape(logitsK, [1, 1, V]));
|
|
457
|
-
logitsK.dispose();
|
|
458
|
-
|
|
459
|
-
// confidence c_k = σ(conf.w·[h_k; e1] + b)
|
|
460
|
-
const hk = block.slice([0, k, 0], [1, k + 1, dDraft]);
|
|
461
|
-
const hkFlat = ops.reshape(hk, [1, dDraft]);
|
|
462
|
-
hk.dispose();
|
|
463
|
-
const ci = ops.concatAxis([hkFlat, e1], 1); // [1,dDraft+r]
|
|
464
|
-
hkFlat.dispose(); e1.dispose();
|
|
465
|
-
let cz = ops.matmul(ci, this.get("conf.w"));
|
|
466
|
-
ci.dispose();
|
|
467
|
-
cz = disposing(cz, ops.add(cz, this.get("conf.b")));
|
|
468
|
-
cz = disposing(cz, ops.sigmoid(cz));
|
|
469
|
-
const cv = cz.toFloat32()[0]!;
|
|
470
|
-
cz.dispose();
|
|
471
|
-
tokens.push(tok);
|
|
472
|
-
conf.push(cv);
|
|
473
|
-
prevTok = tok;
|
|
474
|
-
}
|
|
475
|
-
Uf.dispose();
|
|
476
|
-
block.dispose();
|
|
477
|
-
const draftLogits = ops.concatAxis(perPosLogits, 1); // [1,γ,V]
|
|
478
|
-
for (const a of perPosLogits) a.dispose();
|
|
479
|
-
return { tokens, conf, draftLogits };
|
|
480
|
-
}
|
|
481
|
-
|
|
482
|
-
// --- persistence --------------------------------------------------------
|
|
483
|
-
|
|
484
|
-
/** Save params + a sidecar dspark.json (config + target identity). */
|
|
485
|
-
save(dir: string): void {
|
|
486
|
-
mkdirSync(dir, { recursive: true });
|
|
487
|
-
const tensors: NamedTensor[] = this.names.map((name) => ({ name, array: this.get(name) }));
|
|
488
|
-
writeShardedSafetensors(dir, tensors);
|
|
489
|
-
const meta = {
|
|
490
|
-
kind: "dspark-drafter",
|
|
491
|
-
version: 1,
|
|
492
|
-
target_id: this.targetId,
|
|
493
|
-
config: this.cfg,
|
|
494
|
-
dims: this.dims,
|
|
495
|
-
param_names: this.names,
|
|
496
|
-
};
|
|
497
|
-
writeFileSync(join(dir, "dspark.json"), JSON.stringify(meta, null, 2));
|
|
498
|
-
}
|
|
499
|
-
|
|
500
|
-
/** Load a saved module. Validates only that the tensor set matches the
|
|
501
|
-
* declared names (structural staleness lives in the registry association,
|
|
502
|
-
* not a runtime check). */
|
|
503
|
-
static load(dir: string): DSparkDrafter {
|
|
504
|
-
const metaPath = join(dir, "dspark.json");
|
|
505
|
-
if (!existsSync(metaPath)) throw new Error(`no dspark.json in ${dir}`);
|
|
506
|
-
const meta = JSON.parse(readFileSync(metaPath, "utf8")) as {
|
|
507
|
-
target_id: string; config: DSparkConfig; dims: TargetDims; param_names: string[];
|
|
508
|
-
};
|
|
509
|
-
const d = new DSparkDrafter(meta.config, meta.dims, meta.target_id);
|
|
510
|
-
const tensors = loadAdapterTensors(join(dir, "model.safetensors"));
|
|
511
|
-
try {
|
|
512
|
-
for (const name of d.names) {
|
|
513
|
-
const a = tensors.get(name);
|
|
514
|
-
if (!a) throw new Error(`checkpoint missing tensor: ${name}`);
|
|
515
|
-
d.#p.set(name, a);
|
|
516
|
-
}
|
|
517
|
-
} finally {
|
|
518
|
-
// dispose anything not adopted
|
|
519
|
-
for (const [name, arr] of tensors) if (!d.names.includes(name)) arr.dispose();
|
|
520
|
-
}
|
|
521
|
-
return d;
|
|
522
|
-
}
|
|
523
|
-
|
|
524
|
-
dispose(): void {
|
|
525
|
-
for (const a of this.#p.values()) a.dispose();
|
|
526
|
-
this.#p.clear();
|
|
527
|
-
}
|
|
528
|
-
}
|
|
529
|
-
|
|
530
|
-
/** Canonical flat param-name order (single source of truth). */
|
|
531
|
-
function buildNames(cfg: DSparkConfig): string[] {
|
|
532
|
-
const names: string[] = [];
|
|
533
|
-
for (let i = 0; i < cfg.nLayers; i++) {
|
|
534
|
-
names.push(`bb.${i}.attn_norm`, `bb.${i}.q`, `bb.${i}.k`, `bb.${i}.v`, `bb.${i}.o`,
|
|
535
|
-
`bb.${i}.ff_norm`, `bb.${i}.gate`, `bb.${i}.up`, `bb.${i}.down`);
|
|
536
|
-
}
|
|
537
|
-
names.push("ctx_proj", "tok_proj", "mask_emb", "pos_emb", "out_norm", "out_proj",
|
|
538
|
-
"markov.w1", "markov.w2", "conf.w", "conf.b");
|
|
539
|
-
return names;
|
|
540
|
-
}
|
|
@@ -1,91 +0,0 @@
|
|
|
1
|
-
// Quantize a DeepSpec-format drafter checkpoint (Phase 1a of the DSpark
|
|
2
|
-
// serving program, docs/design/speculative-decoding.md).
|
|
3
|
-
//
|
|
4
|
-
// Thin policy layer over the house quantizer (src/quantize): the generic
|
|
5
|
-
// shape-eligibility rule already captures every 2-D matmul weight — the
|
|
6
|
-
// layer projections, fc, lm_head, markov_w2, and the two gather tables
|
|
7
|
-
// (embed_tokens, markov_w1: quantized-embedding gather-dequant at load,
|
|
8
|
-
// mlx QuantizedEmbedding semantics). The drafter-specific overlay:
|
|
9
|
-
//
|
|
10
|
-
// KEEP bf16: confidence_head.* — threshold-sensitive (the truncation
|
|
11
|
-
// comparison runs on its sigmoid; borderline flips change proposal
|
|
12
|
-
// lengths) and tiny (~4k params), so quantizing it buys nothing.
|
|
13
|
-
// Norms / layer_scalar / biases are 1-D and never shape-eligible.
|
|
14
|
-
//
|
|
15
|
-
// Drafter numerics only move ACCEPTANCE, never correctness (the target
|
|
16
|
-
// verifies every draft) — the quality gate for any scheme swept through
|
|
17
|
-
// here is the Phase-1c acceptance A/B, not a KL battery.
|
|
18
|
-
|
|
19
|
-
import { quantizeModelDir, type QuantizeResult } from "../../quantize";
|
|
20
|
-
import { DeepspecDrafter } from "./deepspec-module";
|
|
21
|
-
import { MlxArray } from "../../mlx/array";
|
|
22
|
-
import { Dtype } from "../../mlx/ffi";
|
|
23
|
-
|
|
24
|
-
/** Module bases kept full-precision regardless of shape eligibility. */
|
|
25
|
-
const KEEP_BF16 = [/^confidence_head\./];
|
|
26
|
-
|
|
27
|
-
/** The drafter per-tensor policy: quantize everything shape-eligible
|
|
28
|
-
* except the KEEP_BF16 set. */
|
|
29
|
-
export function drafterQuantizePredicate(base: string): boolean {
|
|
30
|
-
return !KEEP_BF16.some((re) => re.test(base));
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
export interface QuantizeDrafterOptions {
|
|
34
|
-
bits: 4 | 8;
|
|
35
|
-
groupSize: 32 | 64;
|
|
36
|
-
/** Skip the post-write load smoke (tests exercise loading separately). */
|
|
37
|
-
skipLoadSmoke?: boolean;
|
|
38
|
-
onProgress?: (stage: string, message: string, progress: number) => void;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
/**
|
|
42
|
-
* Quantize the DeepSpec drafter at `srcDir` into `outDir` and smoke the
|
|
43
|
-
* result: reload through DeepspecDrafter (quantized detection + graph
|
|
44
|
-
* build) and eval one projectContext row through the quantized fc path.
|
|
45
|
-
*/
|
|
46
|
-
export async function quantizeDrafterDir(
|
|
47
|
-
srcDir: string,
|
|
48
|
-
outDir: string,
|
|
49
|
-
opts: QuantizeDrafterOptions,
|
|
50
|
-
): Promise<QuantizeResult> {
|
|
51
|
-
const raw = (await Bun.file(`${srcDir}/config.json`).json()) as Record<string, any>;
|
|
52
|
-
if (raw.architectures?.[0] !== "Gemma4DSparkModel")
|
|
53
|
-
throw new Error(
|
|
54
|
-
`quantizeDrafterDir: expected a DeepSpec checkpoint (architectures[0]==="Gemma4DSparkModel"), got ${JSON.stringify(raw.architectures)} — for regular models use \`mlx-bun quantize\``,
|
|
55
|
-
);
|
|
56
|
-
if (raw.quantization ?? raw.quantization_config)
|
|
57
|
-
throw new Error("quantizeDrafterDir: source is already quantized — start from the bf16 checkpoint");
|
|
58
|
-
|
|
59
|
-
const result = await quantizeModelDir(
|
|
60
|
-
srcDir,
|
|
61
|
-
outDir,
|
|
62
|
-
{
|
|
63
|
-
bits: opts.bits,
|
|
64
|
-
groupSize: opts.groupSize,
|
|
65
|
-
quantizePredicate: drafterQuantizePredicate,
|
|
66
|
-
},
|
|
67
|
-
opts.onProgress ? (e) => opts.onProgress!(e.stage, e.message, e.progress) : undefined,
|
|
68
|
-
);
|
|
69
|
-
|
|
70
|
-
if (!opts.skipLoadSmoke) {
|
|
71
|
-
// Load smoke: quantized detection + one real quantized matmul (fc) so a
|
|
72
|
-
// wrong spec/layout fails HERE, not at serve time.
|
|
73
|
-
const d = await DeepspecDrafter.load(outDir);
|
|
74
|
-
try {
|
|
75
|
-
const width = d.tapLayers.length * d.hidden;
|
|
76
|
-
const zeros = MlxArray.fromFloat32(new Float32Array(width), [1, 1, width]);
|
|
77
|
-
const x = zeros.astype(Dtype.bfloat16);
|
|
78
|
-
zeros.dispose();
|
|
79
|
-
const proj = d.projectContext(x);
|
|
80
|
-
x.dispose();
|
|
81
|
-
const got = proj.shape;
|
|
82
|
-
proj.dispose();
|
|
83
|
-
if (got.length !== 3 || got[2] !== d.hidden)
|
|
84
|
-
throw new Error(`load smoke: projectContext shape ${JSON.stringify(got)}, expected [1,1,${d.hidden}]`);
|
|
85
|
-
} finally {
|
|
86
|
-
d.dispose();
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
return result;
|
|
91
|
-
}
|