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
package/src/lora.ts
DELETED
|
@@ -1,408 +0,0 @@
|
|
|
1
|
-
// Hot-swap mounted LoRA adapters — port of optiq/adapters/{mount,
|
|
2
|
-
// registry,resolver}.py (serving side; lora/apply.py is the training-
|
|
3
|
-
// side rank logic). Mount N adapters on one quantized base, select per
|
|
4
|
-
// request by id, never reload the base.
|
|
5
|
-
//
|
|
6
|
-
// Deviations from the reference, both deliberate (PLAN Phase 8):
|
|
7
|
-
// - No ContextVar/serve-pin: our generation queue is serialized, so the
|
|
8
|
-
// active adapter is a plain field (LoraState) set by generate().
|
|
9
|
-
// - Residual composition is mlx-lm LoRALinear / optiq apply.py
|
|
10
|
-
// (`y + (scale·z).astype(x.dtype)`), not mount.py's uncast f32 add —
|
|
11
|
-
// the cast form is what the adapters were trained behind.
|
|
12
|
-
|
|
13
|
-
import { existsSync, readdirSync, statSync } from "node:fs";
|
|
14
|
-
import { resolve } from "node:path";
|
|
15
|
-
import { createHash } from "node:crypto";
|
|
16
|
-
import { ptr, read } from "bun:ffi";
|
|
17
|
-
import { MlxArray, cpuStream } from "./mlx/array";
|
|
18
|
-
import { C } from "./mlx/ffi";
|
|
19
|
-
import { transposeAxes } from "./mlx/ops";
|
|
20
|
-
import { SafetensorsFile } from "./safetensors";
|
|
21
|
-
import type { LoraWeights } from "./model/gemma4";
|
|
22
|
-
import type { RuntimeModel } from "./model/factory";
|
|
23
|
-
|
|
24
|
-
const cstr = (s: string) => Buffer.from(s + "\0", "utf8");
|
|
25
|
-
|
|
26
|
-
export interface AdapterInfo {
|
|
27
|
-
id: string;
|
|
28
|
-
path: string;
|
|
29
|
-
rank: number | null;
|
|
30
|
-
scale: number;
|
|
31
|
-
sizeBytes: number;
|
|
32
|
-
mountedLayers: number;
|
|
33
|
-
/** Adapter tensors for modules outside the 7 target suffixes
|
|
34
|
-
* (per-layer-input projections etc.) — skipped, like the reference. */
|
|
35
|
-
skippedTensors: number;
|
|
36
|
-
/** Actual resident bytes of this adapter's mounted lora_a/lora_b arrays
|
|
37
|
-
* (sum of MlxArray.nbytes — the real RAM cost while mounted, not the
|
|
38
|
-
* on-disk safetensors size). Web chat's adapter routing table (plan
|
|
39
|
-
* §5.6/§9 Phase 2) shows this per loaded adapter instead of guessing
|
|
40
|
-
* from file size. */
|
|
41
|
-
ramBytes: number;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
/** Read every tensor from an adapter safetensors file (small, f32) into
|
|
45
|
-
* materialized mlx arrays. Tensor names come from our header parser;
|
|
46
|
-
* arrays from mlx's native loader via the proven map-get pattern
|
|
47
|
-
* (weights.ts). The map and header mmap are freed before returning. */
|
|
48
|
-
export function loadAdapterTensors(file: string): Map<string, MlxArray> {
|
|
49
|
-
const sf = SafetensorsFile.open(file);
|
|
50
|
-
const names = [...sf.tensors.keys()];
|
|
51
|
-
sf.mmap.unmap();
|
|
52
|
-
|
|
53
|
-
const arrMapSlot = new BigUint64Array([C.mlx_map_string_to_array_new()]);
|
|
54
|
-
const metaMapSlot = new BigUint64Array([C.mlx_map_string_to_string_new()]);
|
|
55
|
-
const arrMapPtr = ptr(arrMapSlot);
|
|
56
|
-
const metaMapPtr = ptr(metaMapSlot);
|
|
57
|
-
const status = C.mlx_load_safetensors(arrMapPtr, metaMapPtr, ptr(cstr(file)), cpuStream);
|
|
58
|
-
C.mlx_map_string_to_string_free(read.u64(metaMapPtr, 0));
|
|
59
|
-
const mapHandle = read.u64(arrMapPtr, 0);
|
|
60
|
-
if (status !== 0) {
|
|
61
|
-
C.mlx_map_string_to_array_free(mapHandle);
|
|
62
|
-
throw new Error(`mlx_load_safetensors(${file}) failed`);
|
|
63
|
-
}
|
|
64
|
-
const out = new Map<string, MlxArray>();
|
|
65
|
-
try {
|
|
66
|
-
for (const name of names) {
|
|
67
|
-
const slot = new BigUint64Array([C.mlx_array_new()]);
|
|
68
|
-
const slotPtr = ptr(slot);
|
|
69
|
-
if (C.mlx_map_string_to_array_get(slotPtr, mapHandle, ptr(cstr(name))) !== 0)
|
|
70
|
-
throw new Error(`adapter tensor ${name} missing from native map`);
|
|
71
|
-
const arr = new MlxArray(read.u64(slotPtr, 0));
|
|
72
|
-
arr.eval(); // materialize — the map (and its Load refs) is freed below
|
|
73
|
-
out.set(name, arr);
|
|
74
|
-
}
|
|
75
|
-
} catch (e) {
|
|
76
|
-
for (const a of out.values()) a.dispose();
|
|
77
|
-
C.mlx_map_string_to_array_free(mapHandle);
|
|
78
|
-
throw e;
|
|
79
|
-
}
|
|
80
|
-
C.mlx_map_string_to_array_free(mapHandle);
|
|
81
|
-
return out;
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
/** Adapter scale from its config: mlx-lm writes lora_parameters.scale;
|
|
85
|
-
* PEFT writes lora_alpha + r and optionally use_rslora. For ordinary PEFT
|
|
86
|
-
* return alpha/r as the scale. For PEFT rsLoRA return alpha and set rsLora,
|
|
87
|
-
* so the caller's one per-layer division produces alpha/√rank exactly once.
|
|
88
|
-
* Internal configs already store their pre-√rank scale directly. */
|
|
89
|
-
export async function readAdapterScale(dir: string): Promise<{ scale: number; rank: number | null; rsLora: boolean }> {
|
|
90
|
-
for (const name of ["optiq_lora_config.json", "adapter_config.json"]) {
|
|
91
|
-
const f = Bun.file(`${dir}/${name}`);
|
|
92
|
-
if (await f.exists()) {
|
|
93
|
-
const cfg = (await f.json()) as Record<string, any>;
|
|
94
|
-
const lp = cfg.lora_parameters;
|
|
95
|
-
const rsLora = Boolean(cfg.rs_lora ?? lp?.rs_lora ?? cfg.use_rslora ?? false);
|
|
96
|
-
if (lp && typeof lp === "object")
|
|
97
|
-
return { scale: Number(lp.scale ?? 20.0), rank: lp.rank ?? null, rsLora };
|
|
98
|
-
const alpha = Number(cfg.lora_alpha ?? 16);
|
|
99
|
-
const r = Number(cfg.r ?? 8);
|
|
100
|
-
return {
|
|
101
|
-
scale: rsLora ? alpha : r ? alpha / r : 1.0,
|
|
102
|
-
rank: r || null,
|
|
103
|
-
rsLora,
|
|
104
|
-
};
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
throw new Error(`no adapter_config.json in ${dir}`);
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
export function adapterWeightsFile(dir: string): string {
|
|
111
|
-
for (const name of ["adapters.safetensors", "adapter_model.safetensors"]) {
|
|
112
|
-
const p = `${dir}/${name}`;
|
|
113
|
-
if (existsSync(p)) return p;
|
|
114
|
-
}
|
|
115
|
-
throw new Error(`no adapter weights at ${dir}/adapters.safetensors or adapter_model.safetensors`);
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
/** A mountable adapter found on disk (not yet mounted). */
|
|
119
|
-
export interface AvailableAdapter {
|
|
120
|
-
id: string; // directory basename — the handle to mount it under
|
|
121
|
-
path: string; // absolute adapter dir
|
|
122
|
-
scale: number;
|
|
123
|
-
rank: number | null;
|
|
124
|
-
/** Base model repo id (org/name) the adapter was trained on, or null if the
|
|
125
|
-
* config doesn't record it. Lets the chat selector hide adapters that don't
|
|
126
|
-
* fit the served model (a MiniCPM5 adapter can't mount on Gemma). */
|
|
127
|
-
baseModel: string | null;
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
/** The base-model repo id an adapter was trained on, from its config's
|
|
131
|
-
* source_model / base_model_name_or_path. These are stored as machine-local
|
|
132
|
-
* snapshot PATHS (…/models--ORG--NAME/snapshots/HASH), so recover the stable
|
|
133
|
-
* repo id (ORG/NAME) from the path; returns null if unrecorded. */
|
|
134
|
-
async function readAdapterBaseRepoId(dir: string): Promise<string | null> {
|
|
135
|
-
for (const [name, key] of [
|
|
136
|
-
["optiq_lora_config.json", "source_model"],
|
|
137
|
-
["adapter_config.json", "base_model_name_or_path"],
|
|
138
|
-
] as const) {
|
|
139
|
-
const f = Bun.file(`${dir}/${name}`);
|
|
140
|
-
if (await f.exists()) {
|
|
141
|
-
const cfg = (await f.json()) as Record<string, any>;
|
|
142
|
-
const src = cfg[key];
|
|
143
|
-
if (typeof src === "string" && src) {
|
|
144
|
-
const m = src.match(/models--([^/]+)/);
|
|
145
|
-
return m ? m[1]!.replace(/--/g, "/") : src;
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
return null;
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
/** Scan adapter stores for mountable adapters: directories holding an adapter
|
|
153
|
-
* weights file. id = dir basename; scale/rank/baseModel read from each adapter's
|
|
154
|
-
* config. Dirs without weights (dataset folders) and unreadable stores are skipped.
|
|
155
|
-
* Backs GET /v1/adapters/available, which populates the chat adapter selector. */
|
|
156
|
-
export async function listAvailableAdapters(stores: string[]): Promise<AvailableAdapter[]> {
|
|
157
|
-
const out: AvailableAdapter[] = [];
|
|
158
|
-
const seen = new Set<string>();
|
|
159
|
-
for (const store of stores) {
|
|
160
|
-
let entries;
|
|
161
|
-
try {
|
|
162
|
-
entries = readdirSync(store, { withFileTypes: true });
|
|
163
|
-
} catch {
|
|
164
|
-
continue; // store missing → skip
|
|
165
|
-
}
|
|
166
|
-
for (const e of entries) {
|
|
167
|
-
if (!e.isDirectory()) continue;
|
|
168
|
-
const dir = resolve(store, e.name);
|
|
169
|
-
try {
|
|
170
|
-
adapterWeightsFile(dir);
|
|
171
|
-
} catch {
|
|
172
|
-
continue; // no weights → not an adapter
|
|
173
|
-
}
|
|
174
|
-
if (seen.has(dir)) continue;
|
|
175
|
-
seen.add(dir);
|
|
176
|
-
let scale = 1;
|
|
177
|
-
let rank: number | null = null;
|
|
178
|
-
try {
|
|
179
|
-
({ scale, rank } = await readAdapterScale(dir));
|
|
180
|
-
} catch {
|
|
181
|
-
// keep defaults if the config is unreadable
|
|
182
|
-
}
|
|
183
|
-
const baseModel = await readAdapterBaseRepoId(dir).catch(() => null);
|
|
184
|
-
out.push({ id: e.name, path: dir, scale, rank, baseModel });
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
return out;
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
/** Parse an adapter selection spec: "sft" | "sft+dpo" | "sft,dpo"
|
|
191
|
-
* (reference mount.py stacking syntax — residuals sum in order). */
|
|
192
|
-
export function parseAdapterSpec(spec: string): string[] {
|
|
193
|
-
const sep = spec.includes("+") ? "+" : ",";
|
|
194
|
-
return spec.split(sep).map((s) => s.trim()).filter(Boolean);
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
export class AdapterManager {
|
|
198
|
-
readonly #model: RuntimeModel;
|
|
199
|
-
readonly #mounted = new Map<string, AdapterInfo>();
|
|
200
|
-
/** Owned adapter arrays per id (disposed on unmount). */
|
|
201
|
-
readonly #arrays = new Map<string, MlxArray[]>();
|
|
202
|
-
readonly #revisions = new Map<string, string>();
|
|
203
|
-
|
|
204
|
-
constructor(model: RuntimeModel) {
|
|
205
|
-
this.#model = model;
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
/** Mount an adapter directory under `id`. Validates layer-name and
|
|
209
|
-
* rank/shape compatibility against the base BEFORE any weights are
|
|
210
|
-
* attached — a bad adapter fails here, never at request time
|
|
211
|
-
* (reference: resolver.py + mount.py add_adapter checks). */
|
|
212
|
-
async mount(id: string, dir: string): Promise<AdapterInfo> {
|
|
213
|
-
if (this.#mounted.has(id)) return this.#mounted.get(id)!;
|
|
214
|
-
if (id.includes("+") || id.includes(","))
|
|
215
|
-
throw new Error(`adapter id ${JSON.stringify(id)} may not contain '+' or ','`);
|
|
216
|
-
const path = resolve(dir);
|
|
217
|
-
if (!existsSync(path)) throw new Error(`adapter dir not found: ${path}`);
|
|
218
|
-
|
|
219
|
-
const weightsFile = adapterWeightsFile(path);
|
|
220
|
-
const { scale, rank: configRank, rsLora } = await readAdapterScale(path);
|
|
221
|
-
// Hash once at mount, before native allocation. Reusing an adapter name
|
|
222
|
-
// for different weights or scale must never reuse its prefix/checkpoint.
|
|
223
|
-
const digest = createHash("sha256").update(JSON.stringify({ scale, rank: configRank, rsLora }));
|
|
224
|
-
for await (const chunk of Bun.file(weightsFile).stream()) digest.update(chunk);
|
|
225
|
-
const revision = digest.digest("hex");
|
|
226
|
-
const tensors = loadAdapterTensors(weightsFile);
|
|
227
|
-
const targets = this.#model.loraTargets();
|
|
228
|
-
|
|
229
|
-
// Group adapter tensors into (modulePath → {a, b}), probing both the
|
|
230
|
-
// pure-LLM and VLM-wrapped prefixes like the reference _find_weight_pair.
|
|
231
|
-
const pairs = new Map<string, {
|
|
232
|
-
a?: MlxArray;
|
|
233
|
-
b?: MlxArray;
|
|
234
|
-
aIsPeft?: boolean;
|
|
235
|
-
bIsPeft?: boolean;
|
|
236
|
-
}>();
|
|
237
|
-
let skipped = 0;
|
|
238
|
-
const ourPrefix = `${this.#model.prefixBase}.layers.`;
|
|
239
|
-
const altPrefix = ourPrefix.startsWith("language_model.")
|
|
240
|
-
? ourPrefix.slice("language_model.".length)
|
|
241
|
-
: `language_model.${ourPrefix}`;
|
|
242
|
-
for (const [name, arr] of tensors) {
|
|
243
|
-
const m = name.match(/^(.*)\.(lora_a|lora_A|lora_b|lora_B)(\.weight)?$/);
|
|
244
|
-
if (!m) { skipped++; arr.dispose(); continue; }
|
|
245
|
-
let modulePath = m[1]!;
|
|
246
|
-
// Standard PEFT state dicts wrap the model path in
|
|
247
|
-
// `base_model.model.`. The remainder is the underlying HF module path
|
|
248
|
-
// (`model.layers...` or `language_model.model.layers...`).
|
|
249
|
-
if (modulePath.startsWith("base_model.model."))
|
|
250
|
-
modulePath = modulePath.slice("base_model.model.".length);
|
|
251
|
-
if (modulePath.startsWith(altPrefix))
|
|
252
|
-
modulePath = ourPrefix + modulePath.slice(altPrefix.length);
|
|
253
|
-
if (!targets.has(modulePath)) { skipped++; arr.dispose(); continue; }
|
|
254
|
-
const slot = pairs.get(modulePath) ?? {};
|
|
255
|
-
const peftName = m[3] === ".weight" || m[2] === "lora_A" || m[2] === "lora_B";
|
|
256
|
-
if (m[2]!.toLowerCase() === "lora_a") {
|
|
257
|
-
slot.a = arr;
|
|
258
|
-
slot.aIsPeft = peftName;
|
|
259
|
-
} else {
|
|
260
|
-
slot.b = arr;
|
|
261
|
-
slot.bIsPeft = peftName;
|
|
262
|
-
}
|
|
263
|
-
pairs.set(modulePath, slot);
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
// Validate every pair against the base linear's dims before mounting
|
|
267
|
-
// anything (all-or-nothing: a bad adapter must not half-mount).
|
|
268
|
-
const validated: { linear: import("./model/gemma4").QuantizedLinear; lw: LoraWeights }[] = [];
|
|
269
|
-
const dispose = () => {
|
|
270
|
-
for (const { a, b } of pairs.values()) { a?.dispose(); b?.dispose(); }
|
|
271
|
-
};
|
|
272
|
-
try {
|
|
273
|
-
for (const [modulePath, pair] of pairs) {
|
|
274
|
-
const { a, b } = pair;
|
|
275
|
-
if (!a || !b)
|
|
276
|
-
throw new Error(`${modulePath}: adapter has only one of lora_a/lora_b`);
|
|
277
|
-
const linear = targets.get(modulePath)!;
|
|
278
|
-
if (a.shape.length !== 2 || b.shape.length !== 2)
|
|
279
|
-
throw new Error(
|
|
280
|
-
`${modulePath}: LoRA tensors must be rank-2; got ` +
|
|
281
|
-
`lora_a [${a.shape}] / lora_b [${b.shape}]`,
|
|
282
|
-
);
|
|
283
|
-
|
|
284
|
-
const internalLayout =
|
|
285
|
-
a.shape[0] === linear.inFeatures &&
|
|
286
|
-
b.shape[0] === a.shape[1] &&
|
|
287
|
-
b.shape[1] === linear.outFeatures;
|
|
288
|
-
const peftLayout =
|
|
289
|
-
a.shape[1] === linear.inFeatures &&
|
|
290
|
-
b.shape[1] === a.shape[0] &&
|
|
291
|
-
b.shape[0] === linear.outFeatures;
|
|
292
|
-
if (!internalLayout && !peftLayout)
|
|
293
|
-
throw new Error(
|
|
294
|
-
`${modulePath}: shape mismatch — lora_a [${a.shape}] / lora_b [${b.shape}] ` +
|
|
295
|
-
`vs base [in ${linear.inFeatures}, out ${linear.outFeatures}]. Expected ` +
|
|
296
|
-
`mlx-lm [in, rank] + [rank, out] or PEFT [rank, in] + [out, rank].`,
|
|
297
|
-
);
|
|
298
|
-
|
|
299
|
-
// Full-rank square adapters satisfy both shape predicates. In that
|
|
300
|
-
// ambiguous case the PEFT spelling is authoritative; otherwise the
|
|
301
|
-
// unique compatible layout decides.
|
|
302
|
-
const usePeftLayout =
|
|
303
|
-
peftLayout && (!internalLayout || (pair.aIsPeft === true && pair.bIsPeft === true));
|
|
304
|
-
let mountedA = a;
|
|
305
|
-
let mountedB = b;
|
|
306
|
-
if (usePeftLayout) {
|
|
307
|
-
let transposedA: MlxArray | null = null;
|
|
308
|
-
let transposedB: MlxArray | null = null;
|
|
309
|
-
try {
|
|
310
|
-
transposedA = transposeAxes(a, [1, 0]);
|
|
311
|
-
transposedB = transposeAxes(b, [1, 0]);
|
|
312
|
-
} catch (e) {
|
|
313
|
-
transposedA?.dispose();
|
|
314
|
-
transposedB?.dispose();
|
|
315
|
-
throw e;
|
|
316
|
-
}
|
|
317
|
-
mountedA = transposedA;
|
|
318
|
-
mountedB = transposedB;
|
|
319
|
-
pair.a = mountedA;
|
|
320
|
-
pair.b = mountedB;
|
|
321
|
-
a.dispose();
|
|
322
|
-
b.dispose();
|
|
323
|
-
}
|
|
324
|
-
const rank = mountedA.shape[1]!;
|
|
325
|
-
// rsLoRA: effective per-layer scale is α/√rank (matches training).
|
|
326
|
-
const effScale = rsLora ? scale / Math.sqrt(rank) : scale;
|
|
327
|
-
validated.push({ linear, lw: { a: mountedA, b: mountedB, scale: effScale, rank } });
|
|
328
|
-
}
|
|
329
|
-
if (validated.length === 0)
|
|
330
|
-
throw new Error(
|
|
331
|
-
`failed to mount adapter ${JSON.stringify(id)}: no tensors match the ` +
|
|
332
|
-
`target modules (q/k/v/o/gate/up/down_proj). Check that the adapter ` +
|
|
333
|
-
`was trained for this base model.`,
|
|
334
|
-
);
|
|
335
|
-
} catch (e) {
|
|
336
|
-
dispose();
|
|
337
|
-
throw e;
|
|
338
|
-
}
|
|
339
|
-
|
|
340
|
-
for (const { linear, lw } of validated) {
|
|
341
|
-
(linear.adapters ??= new Map()).set(id, lw);
|
|
342
|
-
linear.loraState = this.#model.loraState;
|
|
343
|
-
}
|
|
344
|
-
|
|
345
|
-
const ramBytes = validated.reduce((sum, { lw }) => sum + lw.a.nbytes + lw.b.nbytes, 0);
|
|
346
|
-
const info: AdapterInfo = {
|
|
347
|
-
id,
|
|
348
|
-
path,
|
|
349
|
-
rank: configRank,
|
|
350
|
-
scale,
|
|
351
|
-
sizeBytes: statSync(weightsFile).size,
|
|
352
|
-
mountedLayers: validated.length,
|
|
353
|
-
skippedTensors: skipped,
|
|
354
|
-
ramBytes,
|
|
355
|
-
};
|
|
356
|
-
this.#mounted.set(id, info);
|
|
357
|
-
this.#revisions.set(id, revision);
|
|
358
|
-
this.#arrays.set(id, validated.flatMap(({ lw }) => [lw.a, lw.b]));
|
|
359
|
-
return info;
|
|
360
|
-
}
|
|
361
|
-
|
|
362
|
-
/** Remove `id` from every linear (frees its arrays). The mount points
|
|
363
|
-
* stay in place for other adapters, like the reference. */
|
|
364
|
-
unmount(id: string): number {
|
|
365
|
-
if (!this.#mounted.delete(id)) return 0;
|
|
366
|
-
this.#revisions.delete(id);
|
|
367
|
-
let removed = 0;
|
|
368
|
-
for (const linear of this.#model.loraTargets().values()) {
|
|
369
|
-
if (linear.adapters?.delete(id)) removed++;
|
|
370
|
-
}
|
|
371
|
-
for (const a of this.#arrays.get(id) ?? []) a.dispose();
|
|
372
|
-
this.#arrays.delete(id);
|
|
373
|
-
if (this.#model.loraState.active.includes(id))
|
|
374
|
-
this.#model.loraState.active = this.#model.loraState.active.filter((x) => x !== id);
|
|
375
|
-
return removed;
|
|
376
|
-
}
|
|
377
|
-
|
|
378
|
-
/** Ordered, content-addressed namespace for the actual mounted composition. */
|
|
379
|
-
cacheNamespace(ids: readonly string[]): string {
|
|
380
|
-
return ids.map((id) => {
|
|
381
|
-
const revision = this.#revisions.get(id);
|
|
382
|
-
if (!revision) throw new Error(`adapter ${id} is no longer mounted`);
|
|
383
|
-
return `${id}@${revision}`;
|
|
384
|
-
}).join("+");
|
|
385
|
-
}
|
|
386
|
-
|
|
387
|
-
list(): AdapterInfo[] {
|
|
388
|
-
return [...this.#mounted.values()];
|
|
389
|
-
}
|
|
390
|
-
|
|
391
|
-
get(id: string): AdapterInfo | undefined {
|
|
392
|
-
return this.#mounted.get(id);
|
|
393
|
-
}
|
|
394
|
-
|
|
395
|
-
/** Resolve a request's adapter spec to validated ids ([] for none).
|
|
396
|
-
* Unknown ids are an error — selection must fail loudly, not no-op. */
|
|
397
|
-
resolveSpec(spec: string | null | undefined): string[] {
|
|
398
|
-
if (!spec || spec.toLowerCase() === "none") return [];
|
|
399
|
-
const ids = parseAdapterSpec(spec);
|
|
400
|
-
for (const id of ids)
|
|
401
|
-
if (!this.#mounted.has(id))
|
|
402
|
-
throw new Error(
|
|
403
|
-
`unknown adapter ${JSON.stringify(id)} — mounted: ` +
|
|
404
|
-
`${[...this.#mounted.keys()].join(", ") || "(none)"}`,
|
|
405
|
-
);
|
|
406
|
-
return ids;
|
|
407
|
-
}
|
|
408
|
-
}
|
package/src/md-modules.d.ts
DELETED
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
// Ambient type for `import md from "./foo.md" with { type: "text" }`.
|
|
2
|
-
// Bun reads the file as a string, but bun-types only declares .txt/.html,
|
|
3
|
-
// not .md — so we declare it here (used by src/web/skills.ts).
|
|
4
|
-
declare module "*.md" {
|
|
5
|
-
const content: string;
|
|
6
|
-
export default content;
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
// Same deal for vendored text-imported assets under src/web/vendor/ (see
|
|
10
|
-
// that dir's README) — served as raw strings via `with { type: "text" }`,
|
|
11
|
-
// but bun-types has no ambient declaration for .js/.css read as text.
|
|
12
|
-
// Scoped to the vendor path (not a blanket "*.js"/"*.css") so ordinary JS/CSS
|
|
13
|
-
// module resolution elsewhere in the repo is untouched.
|
|
14
|
-
declare module "./web/vendor/*.js" {
|
|
15
|
-
const content: string;
|
|
16
|
-
export default content;
|
|
17
|
-
}
|
|
18
|
-
declare module "./web/vendor/*.css" {
|
|
19
|
-
const content: string;
|
|
20
|
-
export default content;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
// The frontend bundle (plan §7/§9 Phase 2 module split): GENERATED from
|
|
24
|
-
// src/web/src/*.ts by scripts/build-web.ts into src/web/app.js, imported as
|
|
25
|
-
// raw text in src/server.ts the same way as the vendored assets above.
|
|
26
|
-
// Must stay a glob ("./web/*.js"), not the exact "./web/app.js" path — TS's
|
|
27
|
-
// ambient-module resolution only matches the real on-disk src/web/app.js
|
|
28
|
-
// against a wildcard pattern here, not an exact-path declaration (verified
|
|
29
|
-
// 2026-07: an exact-path declare module silently failed to match while the
|
|
30
|
-
// file existed, and "cannot find module" once it didn't — a TS quirk, not
|
|
31
|
-
// intentional design; keep the glob if this ever needs revisiting).
|
|
32
|
-
declare module "./web/*.js" {
|
|
33
|
-
const content: string;
|
|
34
|
-
export default content;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
// PWA sources (plan §9 Phase 3): manifest.webmanifest + icon.svg,
|
|
38
|
-
// text-imported into src/server.ts the same way. Globs, not exact paths —
|
|
39
|
-
// the app.js comment above already found (2026-07) that TS's ambient
|
|
40
|
-
// module resolution only matches a real on-disk file against a wildcard
|
|
41
|
-
// pattern, not an exact-path declaration; same quirk applies here.
|
|
42
|
-
declare module "./web/*.webmanifest" {
|
|
43
|
-
const content: string;
|
|
44
|
-
export default content;
|
|
45
|
-
}
|
|
46
|
-
declare module "./web/*.svg" {
|
|
47
|
-
const content: string;
|
|
48
|
-
export default content;
|
|
49
|
-
}
|