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/model/glm52.ts
DELETED
|
@@ -1,1132 +0,0 @@
|
|
|
1
|
-
// Dedicated GLM-5.2 correctness graph over the direct Colibri artifact.
|
|
2
|
-
//
|
|
3
|
-
// G2 deliberately favors an auditable dequantize->f32 path. Routed experts are
|
|
4
|
-
// resolved by their exact tensor names and composed in route order. G3 swaps
|
|
5
|
-
// that expert resolver for bounded slabs/LRU without changing this graph.
|
|
6
|
-
|
|
7
|
-
import type { ModelConfig } from "../config";
|
|
8
|
-
import { loadModelConfig } from "../config";
|
|
9
|
-
import { gpuStream, MlxArray } from "../mlx/array";
|
|
10
|
-
import { synchronize } from "../mlx/ffi";
|
|
11
|
-
import * as ops from "../mlx/ops";
|
|
12
|
-
import {
|
|
13
|
-
argmaxLastPosition,
|
|
14
|
-
LoraState,
|
|
15
|
-
type Cache,
|
|
16
|
-
type QuantizedLinear,
|
|
17
|
-
} from "./gemma4-base";
|
|
18
|
-
import {
|
|
19
|
-
Glm52DsaSelectionState,
|
|
20
|
-
glm52DsaScoresMlx,
|
|
21
|
-
type Glm52DsaSelectionObserver,
|
|
22
|
-
} from "./glm52-dsa";
|
|
23
|
-
import { MLACache } from "./glm52-cache";
|
|
24
|
-
import {
|
|
25
|
-
loadGlm52Config,
|
|
26
|
-
type Glm52Config,
|
|
27
|
-
} from "./glm52-config";
|
|
28
|
-
import {
|
|
29
|
-
Glm52Mla,
|
|
30
|
-
partialInterleavedRopeMlx,
|
|
31
|
-
rmsNormF32Mlx,
|
|
32
|
-
type Glm52MlaBatchedSelection,
|
|
33
|
-
type Glm52MlaWeightSource,
|
|
34
|
-
} from "./glm52-mla";
|
|
35
|
-
import { validateGlm52ContainerLayout } from "./glm52-layout";
|
|
36
|
-
import {
|
|
37
|
-
composeGlm52MoeOutputsMlx,
|
|
38
|
-
planGlm52MoeBatchF32,
|
|
39
|
-
routeGlm52MoeF32,
|
|
40
|
-
type Glm52RoutedExpertOutput,
|
|
41
|
-
} from "./glm52-moe";
|
|
42
|
-
import { Glm52PilotTracker } from "./glm52-pilot";
|
|
43
|
-
import type { Glm52ExpertExecutionBackend } from "./glm52-streamed-experts";
|
|
44
|
-
import {
|
|
45
|
-
Glm52ExpertRuntime,
|
|
46
|
-
type Glm52ExpertRuntimeOptions,
|
|
47
|
-
} from "./glm52-residency";
|
|
48
|
-
import { ColibriGlm52ResidentWeights } from "./glm52-resident-weights";
|
|
49
|
-
import { ColibriGlm52Weights } from "./glm52-weights";
|
|
50
|
-
|
|
51
|
-
export interface Glm52WeightSource extends Glm52MlaWeightSource {
|
|
52
|
-
readonly weightsBytes: number;
|
|
53
|
-
has(name: string): boolean;
|
|
54
|
-
embedding(
|
|
55
|
-
ids: MlxArray,
|
|
56
|
-
name: string,
|
|
57
|
-
vocabSize: number,
|
|
58
|
-
hiddenSize: number,
|
|
59
|
-
): MlxArray;
|
|
60
|
-
dispose(): void;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
export interface Glm52ModelCapabilities {
|
|
64
|
-
readonly dsa: boolean;
|
|
65
|
-
/** The artifact contains the complete native MTP metadata/tensor family. */
|
|
66
|
-
readonly mtpMetadata: boolean;
|
|
67
|
-
/** The native MTP weights/tier are loaded for this model instance. */
|
|
68
|
-
readonly mtpEnabled?: boolean;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
export interface Glm52StreamedOpenOptions
|
|
72
|
-
extends Omit<Glm52ExpertRuntimeOptions, "fixedBytes"> {
|
|
73
|
-
/** KV/transient/allocator/Bun/OS reserve, excluding resident weights. */
|
|
74
|
-
readonly reserveBytes: number;
|
|
75
|
-
/** Internal counterfactual control; indexer weights remain resident. */
|
|
76
|
-
readonly enableDsa?: boolean;
|
|
77
|
-
/**
|
|
78
|
-
* Stage-2 benchmark seam: build long contexts with dense batched prefill,
|
|
79
|
-
* then exercise exact DSA on one-token decode. Normal serving stays exact.
|
|
80
|
-
*/
|
|
81
|
-
readonly dsaPrefillMode?: "exact" | "dense-benchmark";
|
|
82
|
-
/** Exact prompt length covered by `dense-benchmark`; required in that mode. */
|
|
83
|
-
readonly dsaBenchmarkPrefillTokens?: number;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
interface DsaStep {
|
|
87
|
-
readonly key: MlxArray;
|
|
88
|
-
/** Borrowed from the request-local selection state; do not dispose here. */
|
|
89
|
-
readonly selectedPositions: MlxArray | Glm52MlaBatchedSelection | null;
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
/** Native MTP verifies at most gamma+1 rows under the 64-slot expert union. */
|
|
93
|
-
const GLM52_DSA_SPARSE_DECODE_BATCH_MAX = 8;
|
|
94
|
-
|
|
95
|
-
function swiglu(
|
|
96
|
-
source: Glm52WeightSource,
|
|
97
|
-
input: MlxArray,
|
|
98
|
-
prefix: string,
|
|
99
|
-
intermediate: number,
|
|
100
|
-
hidden: number,
|
|
101
|
-
): MlxArray {
|
|
102
|
-
const gate = source.linear(
|
|
103
|
-
input,
|
|
104
|
-
`${prefix}.gate_proj.weight`,
|
|
105
|
-
intermediate,
|
|
106
|
-
hidden,
|
|
107
|
-
);
|
|
108
|
-
const up = source.linear(
|
|
109
|
-
input,
|
|
110
|
-
`${prefix}.up_proj.weight`,
|
|
111
|
-
intermediate,
|
|
112
|
-
hidden,
|
|
113
|
-
);
|
|
114
|
-
const activated = ops.silu(gate);
|
|
115
|
-
const product = ops.mul(activated, up);
|
|
116
|
-
gate.dispose();
|
|
117
|
-
up.dispose();
|
|
118
|
-
activated.dispose();
|
|
119
|
-
const output = source.linear(
|
|
120
|
-
product,
|
|
121
|
-
`${prefix}.down_proj.weight`,
|
|
122
|
-
hidden,
|
|
123
|
-
intermediate,
|
|
124
|
-
);
|
|
125
|
-
product.dispose();
|
|
126
|
-
return output;
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
class Glm52DsaIndexer {
|
|
130
|
-
readonly prefix: string;
|
|
131
|
-
|
|
132
|
-
constructor(
|
|
133
|
-
readonly config: Glm52Config,
|
|
134
|
-
readonly weights: Glm52WeightSource,
|
|
135
|
-
readonly layer: number,
|
|
136
|
-
) {
|
|
137
|
-
this.prefix = `model.layers.${layer}.self_attn.indexer`;
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
projectAndSelect(
|
|
141
|
-
input: MlxArray,
|
|
142
|
-
cache: MLACache,
|
|
143
|
-
state: Glm52DsaSelectionState,
|
|
144
|
-
forceDense = false,
|
|
145
|
-
): DsaStep {
|
|
146
|
-
const [batch, tokens, hidden] = input.shape;
|
|
147
|
-
if (hidden !== this.config.hiddenSize)
|
|
148
|
-
throw new Error(`DSA hidden width ${hidden} != ${this.config.hiddenSize}`);
|
|
149
|
-
|
|
150
|
-
const positionOffset = batch! > 1
|
|
151
|
-
? (cache.rowOffsets.length
|
|
152
|
-
? cache.rowOffsets
|
|
153
|
-
: new Array(batch!).fill(0) as number[])
|
|
154
|
-
: cache.offset;
|
|
155
|
-
const qA = this.weights.linear(
|
|
156
|
-
input,
|
|
157
|
-
`model.layers.${this.layer}.self_attn.q_a_proj.weight`,
|
|
158
|
-
this.config.qLoraRank,
|
|
159
|
-
this.config.hiddenSize,
|
|
160
|
-
);
|
|
161
|
-
const qNorm = rmsNormF32Mlx(
|
|
162
|
-
qA,
|
|
163
|
-
this.weights.tensor(
|
|
164
|
-
`model.layers.${this.layer}.self_attn.q_a_layernorm.weight`,
|
|
165
|
-
),
|
|
166
|
-
this.config.rmsNormEps,
|
|
167
|
-
);
|
|
168
|
-
qA.dispose();
|
|
169
|
-
const queryFlat = this.weights.linear(
|
|
170
|
-
qNorm,
|
|
171
|
-
`${this.prefix}.wq_b.weight`,
|
|
172
|
-
this.config.indexNumHeads * this.config.indexHeadDim,
|
|
173
|
-
this.config.qLoraRank,
|
|
174
|
-
);
|
|
175
|
-
qNorm.dispose();
|
|
176
|
-
const queryRaw = ops.reshape(queryFlat, [
|
|
177
|
-
batch!,
|
|
178
|
-
tokens!,
|
|
179
|
-
this.config.indexNumHeads,
|
|
180
|
-
this.config.indexHeadDim,
|
|
181
|
-
]);
|
|
182
|
-
queryFlat.dispose();
|
|
183
|
-
const query = partialInterleavedRopeMlx(
|
|
184
|
-
queryRaw,
|
|
185
|
-
positionOffset,
|
|
186
|
-
this.config.qkRopeHeadDim,
|
|
187
|
-
this.config.ropeTheta,
|
|
188
|
-
1,
|
|
189
|
-
);
|
|
190
|
-
queryRaw.dispose();
|
|
191
|
-
|
|
192
|
-
const keyRaw = this.weights.linear(
|
|
193
|
-
input,
|
|
194
|
-
`${this.prefix}.wk.weight`,
|
|
195
|
-
this.config.indexHeadDim,
|
|
196
|
-
this.config.hiddenSize,
|
|
197
|
-
);
|
|
198
|
-
const keyNorm = ops.layerNorm(
|
|
199
|
-
keyRaw,
|
|
200
|
-
this.weights.tensor(`${this.prefix}.k_norm.weight`),
|
|
201
|
-
this.weights.tensor(`${this.prefix}.k_norm.bias`),
|
|
202
|
-
1e-6,
|
|
203
|
-
);
|
|
204
|
-
keyRaw.dispose();
|
|
205
|
-
const key = partialInterleavedRopeMlx(
|
|
206
|
-
keyNorm,
|
|
207
|
-
positionOffset,
|
|
208
|
-
this.config.qkRopeHeadDim,
|
|
209
|
-
this.config.ropeTheta,
|
|
210
|
-
1,
|
|
211
|
-
);
|
|
212
|
-
keyNorm.dispose();
|
|
213
|
-
|
|
214
|
-
const headWeights = this.weights.linear(
|
|
215
|
-
input,
|
|
216
|
-
`${this.prefix}.weights_proj.weight`,
|
|
217
|
-
this.config.indexNumHeads,
|
|
218
|
-
this.config.hiddenSize,
|
|
219
|
-
);
|
|
220
|
-
|
|
221
|
-
let allKeys = key;
|
|
222
|
-
if (cache.dsa?.offset) {
|
|
223
|
-
const prior = cache.dsa.fetch();
|
|
224
|
-
allKeys = ops.concatAxis([prior, key], 1);
|
|
225
|
-
prior.dispose();
|
|
226
|
-
}
|
|
227
|
-
const contextLength = allKeys.shape[1]!;
|
|
228
|
-
let selectedPositions: MlxArray | Glm52MlaBatchedSelection | null;
|
|
229
|
-
if (forceDense || contextLength <= this.config.indexTopk) {
|
|
230
|
-
state.selectFullDense(this.layer, contextLength);
|
|
231
|
-
selectedPositions = null;
|
|
232
|
-
} else if (batch! > 1) {
|
|
233
|
-
const rowSelections: Array<MlxArray | null> = [];
|
|
234
|
-
for (let row = 0; row < batch!; row++) {
|
|
235
|
-
const rowContext = (cache.rowOffsets[row] ?? 0) + tokens!;
|
|
236
|
-
if (rowContext <= this.config.indexTopk) {
|
|
237
|
-
rowSelections.push(null);
|
|
238
|
-
continue;
|
|
239
|
-
}
|
|
240
|
-
const pad = contextLength - rowContext;
|
|
241
|
-
const queryRow = query.slice(
|
|
242
|
-
[row, 0, 0, 0],
|
|
243
|
-
[row + 1, 1, this.config.indexNumHeads, this.config.indexHeadDim],
|
|
244
|
-
);
|
|
245
|
-
const query2d = ops.reshape(queryRow, [
|
|
246
|
-
this.config.indexNumHeads,
|
|
247
|
-
this.config.indexHeadDim,
|
|
248
|
-
]);
|
|
249
|
-
queryRow.dispose();
|
|
250
|
-
const keysRow = allKeys.slice(
|
|
251
|
-
[row, pad, 0],
|
|
252
|
-
[row + 1, contextLength, this.config.indexHeadDim],
|
|
253
|
-
);
|
|
254
|
-
const keys2d = ops.reshape(keysRow, [
|
|
255
|
-
rowContext,
|
|
256
|
-
this.config.indexHeadDim,
|
|
257
|
-
]);
|
|
258
|
-
keysRow.dispose();
|
|
259
|
-
const weightsRow = headWeights.slice(
|
|
260
|
-
[row, 0, 0],
|
|
261
|
-
[row + 1, 1, this.config.indexNumHeads],
|
|
262
|
-
);
|
|
263
|
-
const weights1d = ops.reshape(weightsRow, [this.config.indexNumHeads]);
|
|
264
|
-
weightsRow.dispose();
|
|
265
|
-
const scores = glm52DsaScoresMlx(query2d, keys2d, weights1d);
|
|
266
|
-
rowSelections.push(state.selectFullDevice(this.layer, scores, row));
|
|
267
|
-
query2d.dispose();
|
|
268
|
-
keys2d.dispose();
|
|
269
|
-
weights1d.dispose();
|
|
270
|
-
scores.dispose();
|
|
271
|
-
}
|
|
272
|
-
selectedPositions = { rows: rowSelections };
|
|
273
|
-
} else {
|
|
274
|
-
if (tokens !== 1) {
|
|
275
|
-
if (allKeys !== key) allKeys.dispose();
|
|
276
|
-
query.dispose();
|
|
277
|
-
headWeights.dispose();
|
|
278
|
-
key.dispose();
|
|
279
|
-
throw new Error(
|
|
280
|
-
"G2 DSA sparse prefill beyond index_topk is not yet supported; " +
|
|
281
|
-
"use serial decode or a shorter prefill",
|
|
282
|
-
);
|
|
283
|
-
}
|
|
284
|
-
const query2d = ops.reshape(query, [
|
|
285
|
-
this.config.indexNumHeads,
|
|
286
|
-
this.config.indexHeadDim,
|
|
287
|
-
]);
|
|
288
|
-
const keys2d = ops.reshape(allKeys, [
|
|
289
|
-
contextLength,
|
|
290
|
-
this.config.indexHeadDim,
|
|
291
|
-
]);
|
|
292
|
-
const weights1d = ops.reshape(headWeights, [
|
|
293
|
-
this.config.indexNumHeads,
|
|
294
|
-
]);
|
|
295
|
-
const scores = glm52DsaScoresMlx(query2d, keys2d, weights1d);
|
|
296
|
-
selectedPositions = state.selectFullDevice(this.layer, scores);
|
|
297
|
-
query2d.dispose();
|
|
298
|
-
keys2d.dispose();
|
|
299
|
-
weights1d.dispose();
|
|
300
|
-
scores.dispose();
|
|
301
|
-
}
|
|
302
|
-
if (allKeys !== key) allKeys.dispose();
|
|
303
|
-
query.dispose();
|
|
304
|
-
headWeights.dispose();
|
|
305
|
-
return { key, selectedPositions };
|
|
306
|
-
}
|
|
307
|
-
}
|
|
308
|
-
|
|
309
|
-
class Glm52Mlp {
|
|
310
|
-
constructor(
|
|
311
|
-
readonly config: Glm52Config,
|
|
312
|
-
readonly weights: Glm52WeightSource,
|
|
313
|
-
readonly layer: number,
|
|
314
|
-
readonly expertBackend: Glm52ExpertExecutionBackend | null = null,
|
|
315
|
-
readonly pilot: Glm52PilotTracker | null = null,
|
|
316
|
-
) {}
|
|
317
|
-
|
|
318
|
-
forward(input: MlxArray): MlxArray {
|
|
319
|
-
const prefix = `model.layers.${this.layer}.mlp`;
|
|
320
|
-
if (this.layer < this.config.firstKDenseReplace) {
|
|
321
|
-
return swiglu(
|
|
322
|
-
this.weights,
|
|
323
|
-
input,
|
|
324
|
-
prefix,
|
|
325
|
-
this.config.intermediateSize,
|
|
326
|
-
this.config.hiddenSize,
|
|
327
|
-
);
|
|
328
|
-
}
|
|
329
|
-
if (this.expertBackend)
|
|
330
|
-
throw new Error("streamed GLM routed experts require forwardAsync()");
|
|
331
|
-
|
|
332
|
-
const router = this.weights.tensor(`${prefix}.gate.weight`);
|
|
333
|
-
const routerTranspose = ops.transposeAxes(router, [1, 0]);
|
|
334
|
-
const logits = ops.matmul(input, routerTranspose);
|
|
335
|
-
routerTranspose.dispose();
|
|
336
|
-
const logitsHost = logits.toFloat32();
|
|
337
|
-
logits.dispose();
|
|
338
|
-
const correctionBias = this.weights
|
|
339
|
-
.tensor(`${prefix}.gate.e_score_correction_bias`)
|
|
340
|
-
.toFloat32();
|
|
341
|
-
const [batch, tokens] = input.shape;
|
|
342
|
-
|
|
343
|
-
const sharedIntermediate =
|
|
344
|
-
this.config.moeIntermediateSize * this.config.numSharedExperts;
|
|
345
|
-
const shared = sharedIntermediate > 0
|
|
346
|
-
? swiglu(
|
|
347
|
-
this.weights,
|
|
348
|
-
input,
|
|
349
|
-
`${prefix}.shared_experts`,
|
|
350
|
-
sharedIntermediate,
|
|
351
|
-
this.config.hiddenSize,
|
|
352
|
-
)
|
|
353
|
-
: null;
|
|
354
|
-
|
|
355
|
-
const batchOutputs: MlxArray[] = [];
|
|
356
|
-
try {
|
|
357
|
-
for (let b = 0; b < batch!; b++) {
|
|
358
|
-
const tokenOutputs: MlxArray[] = [];
|
|
359
|
-
try {
|
|
360
|
-
for (let token = 0; token < tokens!; token++) {
|
|
361
|
-
const base = (b * tokens! + token) * this.config.numRoutedExperts;
|
|
362
|
-
const route = routeGlm52MoeF32(
|
|
363
|
-
logitsHost.subarray(
|
|
364
|
-
base,
|
|
365
|
-
base + this.config.numRoutedExperts,
|
|
366
|
-
),
|
|
367
|
-
correctionBias,
|
|
368
|
-
{
|
|
369
|
-
topK: this.config.numExpertsPerToken,
|
|
370
|
-
normalize: this.config.normTopkProb,
|
|
371
|
-
routedScale: this.config.routedScalingFactor,
|
|
372
|
-
},
|
|
373
|
-
);
|
|
374
|
-
const row = input.slice(
|
|
375
|
-
[b, token, 0],
|
|
376
|
-
[b + 1, token + 1, this.config.hiddenSize],
|
|
377
|
-
);
|
|
378
|
-
const routed: Array<Glm52RoutedExpertOutput<MlxArray>> = [];
|
|
379
|
-
try {
|
|
380
|
-
for (const expertId of route.indices) {
|
|
381
|
-
routed.push({
|
|
382
|
-
expertId,
|
|
383
|
-
output: swiglu(
|
|
384
|
-
this.weights,
|
|
385
|
-
row,
|
|
386
|
-
`${prefix}.experts.${expertId}`,
|
|
387
|
-
this.config.moeIntermediateSize,
|
|
388
|
-
this.config.hiddenSize,
|
|
389
|
-
),
|
|
390
|
-
});
|
|
391
|
-
}
|
|
392
|
-
const sharedRow = shared?.slice(
|
|
393
|
-
[b, token, 0],
|
|
394
|
-
[b + 1, token + 1, this.config.hiddenSize],
|
|
395
|
-
) ?? null;
|
|
396
|
-
const output = composeGlm52MoeOutputsMlx(
|
|
397
|
-
route,
|
|
398
|
-
routed,
|
|
399
|
-
sharedRow,
|
|
400
|
-
);
|
|
401
|
-
sharedRow?.dispose();
|
|
402
|
-
tokenOutputs.push(output);
|
|
403
|
-
} finally {
|
|
404
|
-
row.dispose();
|
|
405
|
-
for (const contribution of routed)
|
|
406
|
-
contribution.output.dispose();
|
|
407
|
-
}
|
|
408
|
-
}
|
|
409
|
-
const batchOutput = tokenOutputs.length === 1
|
|
410
|
-
? tokenOutputs[0]!
|
|
411
|
-
: ops.concatAxis(tokenOutputs, 1);
|
|
412
|
-
batchOutputs.push(batchOutput);
|
|
413
|
-
} finally {
|
|
414
|
-
if (tokenOutputs.length > 1)
|
|
415
|
-
for (const output of tokenOutputs) output.dispose();
|
|
416
|
-
}
|
|
417
|
-
}
|
|
418
|
-
return batchOutputs.length === 1
|
|
419
|
-
? batchOutputs[0]!
|
|
420
|
-
: ops.concatAxis(batchOutputs, 0);
|
|
421
|
-
} finally {
|
|
422
|
-
shared?.dispose();
|
|
423
|
-
if (batchOutputs.length > 1)
|
|
424
|
-
for (const output of batchOutputs) output.dispose();
|
|
425
|
-
}
|
|
426
|
-
}
|
|
427
|
-
|
|
428
|
-
async forwardAsync(input: MlxArray): Promise<MlxArray> {
|
|
429
|
-
const prefix = `model.layers.${this.layer}.mlp`;
|
|
430
|
-
if (this.layer < this.config.firstKDenseReplace || !this.expertBackend)
|
|
431
|
-
return this.forward(input);
|
|
432
|
-
|
|
433
|
-
const router = this.weights.tensor(`${prefix}.gate.weight`);
|
|
434
|
-
const routerTranspose = ops.transposeAxes(router, [1, 0]);
|
|
435
|
-
const logits = ops.matmul(input, routerTranspose);
|
|
436
|
-
routerTranspose.dispose();
|
|
437
|
-
const logitsHost = logits.toFloat32();
|
|
438
|
-
logits.dispose();
|
|
439
|
-
const correctionBias = this.weights
|
|
440
|
-
.tensor(`${prefix}.gate.e_score_correction_bias`)
|
|
441
|
-
.toFloat32();
|
|
442
|
-
const [batch, tokens] = input.shape;
|
|
443
|
-
const logitsByRow: Float32Array[] = [];
|
|
444
|
-
for (let row = 0; row < batch! * tokens!; row++) {
|
|
445
|
-
const begin = row * this.config.numRoutedExperts;
|
|
446
|
-
logitsByRow.push(
|
|
447
|
-
logitsHost.subarray(begin, begin + this.config.numRoutedExperts),
|
|
448
|
-
);
|
|
449
|
-
}
|
|
450
|
-
const plan = planGlm52MoeBatchF32(
|
|
451
|
-
logitsByRow,
|
|
452
|
-
correctionBias,
|
|
453
|
-
{
|
|
454
|
-
topK: this.config.numExpertsPerToken,
|
|
455
|
-
normalize: this.config.normTopkProb,
|
|
456
|
-
routedScale: this.config.routedScalingFactor,
|
|
457
|
-
},
|
|
458
|
-
);
|
|
459
|
-
this.pilot?.observeActual(this.layer, plan.routes);
|
|
460
|
-
const sharedIntermediate =
|
|
461
|
-
this.config.moeIntermediateSize * this.config.numSharedExperts;
|
|
462
|
-
const shared = sharedIntermediate > 0
|
|
463
|
-
? swiglu(
|
|
464
|
-
this.weights,
|
|
465
|
-
input,
|
|
466
|
-
`${prefix}.shared_experts`,
|
|
467
|
-
sharedIntermediate,
|
|
468
|
-
this.config.hiddenSize,
|
|
469
|
-
)
|
|
470
|
-
: null;
|
|
471
|
-
try {
|
|
472
|
-
return await this.expertBackend.execute({
|
|
473
|
-
layer: this.layer,
|
|
474
|
-
input,
|
|
475
|
-
plan,
|
|
476
|
-
shared,
|
|
477
|
-
});
|
|
478
|
-
} finally {
|
|
479
|
-
shared?.dispose();
|
|
480
|
-
}
|
|
481
|
-
}
|
|
482
|
-
}
|
|
483
|
-
|
|
484
|
-
export class Glm52DecoderLayer {
|
|
485
|
-
readonly mla: Glm52Mla;
|
|
486
|
-
readonly mlp: Glm52Mlp;
|
|
487
|
-
readonly dsa: Glm52DsaIndexer | null;
|
|
488
|
-
readonly inputNorm: MlxArray;
|
|
489
|
-
readonly postAttentionNorm: MlxArray;
|
|
490
|
-
|
|
491
|
-
constructor(
|
|
492
|
-
readonly config: Glm52Config,
|
|
493
|
-
readonly weights: Glm52WeightSource,
|
|
494
|
-
readonly layer: number,
|
|
495
|
-
hasDsa: boolean,
|
|
496
|
-
expertBackend: Glm52ExpertExecutionBackend | null = null,
|
|
497
|
-
pilot: Glm52PilotTracker | null = null,
|
|
498
|
-
readonly denseBenchmarkPrefillTokens = 0,
|
|
499
|
-
) {
|
|
500
|
-
const prefix = `model.layers.${layer}`;
|
|
501
|
-
this.mla = new Glm52Mla(config, weights, layer);
|
|
502
|
-
this.mlp = new Glm52Mlp(config, weights, layer, expertBackend, pilot);
|
|
503
|
-
this.inputNorm = weights.tensor(`${prefix}.input_layernorm.weight`);
|
|
504
|
-
this.postAttentionNorm = weights.tensor(
|
|
505
|
-
`${prefix}.post_attention_layernorm.weight`,
|
|
506
|
-
);
|
|
507
|
-
this.dsa = hasDsa && config.indexerTypes[layer] === "full"
|
|
508
|
-
? new Glm52DsaIndexer(config, weights, layer)
|
|
509
|
-
: null;
|
|
510
|
-
}
|
|
511
|
-
|
|
512
|
-
/**
|
|
513
|
-
* Keep a small sparse verify window batched through residual/MLP while
|
|
514
|
-
* evaluating its causal DSA+MLA attention rows serially. This preserves one
|
|
515
|
-
* exact selection per query without collapsing native MTP into full-model
|
|
516
|
-
* M=1 forwards.
|
|
517
|
-
*/
|
|
518
|
-
private attend(
|
|
519
|
-
input: MlxArray,
|
|
520
|
-
cache: MLACache,
|
|
521
|
-
dsaState: Glm52DsaSelectionState | null,
|
|
522
|
-
): MlxArray {
|
|
523
|
-
const normalized = rmsNormF32Mlx(
|
|
524
|
-
input,
|
|
525
|
-
this.inputNorm,
|
|
526
|
-
this.config.rmsNormEps,
|
|
527
|
-
);
|
|
528
|
-
const batch = input.shape[0]!;
|
|
529
|
-
const tokens = input.shape[1]!;
|
|
530
|
-
const denseBenchmarkPrefill =
|
|
531
|
-
this.denseBenchmarkPrefillTokens > 0 &&
|
|
532
|
-
tokens > 1 &&
|
|
533
|
-
cache.offset + tokens <= this.denseBenchmarkPrefillTokens;
|
|
534
|
-
const sparseVerifyBatch =
|
|
535
|
-
dsaState !== null &&
|
|
536
|
-
tokens > 1 &&
|
|
537
|
-
tokens <= GLM52_DSA_SPARSE_DECODE_BATCH_MAX &&
|
|
538
|
-
cache.offset + tokens > this.config.indexTopk &&
|
|
539
|
-
!denseBenchmarkPrefill;
|
|
540
|
-
|
|
541
|
-
try {
|
|
542
|
-
if (sparseVerifyBatch) {
|
|
543
|
-
const rows: MlxArray[] = [];
|
|
544
|
-
try {
|
|
545
|
-
for (let token = 0; token < tokens; token++) {
|
|
546
|
-
const row = normalized.slice(
|
|
547
|
-
[0, token, 0],
|
|
548
|
-
[batch, token + 1, this.config.hiddenSize],
|
|
549
|
-
);
|
|
550
|
-
let dsaKey: MlxArray | null = null;
|
|
551
|
-
let positions: MlxArray | Glm52MlaBatchedSelection | null = null;
|
|
552
|
-
try {
|
|
553
|
-
if (this.dsa) {
|
|
554
|
-
const step = this.dsa.projectAndSelect(
|
|
555
|
-
row,
|
|
556
|
-
cache,
|
|
557
|
-
dsaState,
|
|
558
|
-
);
|
|
559
|
-
dsaKey = step.key;
|
|
560
|
-
positions = step.selectedPositions;
|
|
561
|
-
} else {
|
|
562
|
-
positions = batch > 1
|
|
563
|
-
? { rows: Array.from({ length: batch }, (_, row) =>
|
|
564
|
-
dsaState.selectSharedPositions(this.layer, (cache.rowOffsets[row] ?? 0) + 1, row)) }
|
|
565
|
-
: dsaState.selectSharedPositions(this.layer, cache.offset + 1);
|
|
566
|
-
}
|
|
567
|
-
rows.push(this.mla.forward(
|
|
568
|
-
row,
|
|
569
|
-
cache,
|
|
570
|
-
dsaKey,
|
|
571
|
-
"auto",
|
|
572
|
-
positions,
|
|
573
|
-
));
|
|
574
|
-
} finally {
|
|
575
|
-
row.dispose();
|
|
576
|
-
dsaKey?.dispose();
|
|
577
|
-
}
|
|
578
|
-
}
|
|
579
|
-
return ops.concatAxis(rows, 1);
|
|
580
|
-
} finally {
|
|
581
|
-
for (const row of rows) row.dispose();
|
|
582
|
-
}
|
|
583
|
-
}
|
|
584
|
-
|
|
585
|
-
let dsaKey: MlxArray | null = null;
|
|
586
|
-
let positions: MlxArray | Glm52MlaBatchedSelection | null = null;
|
|
587
|
-
try {
|
|
588
|
-
if (this.dsa) {
|
|
589
|
-
if (!dsaState) throw new Error("DSA full layer has no selection state");
|
|
590
|
-
const step = this.dsa.projectAndSelect(
|
|
591
|
-
normalized,
|
|
592
|
-
cache,
|
|
593
|
-
dsaState,
|
|
594
|
-
denseBenchmarkPrefill,
|
|
595
|
-
);
|
|
596
|
-
dsaKey = step.key;
|
|
597
|
-
positions = step.selectedPositions;
|
|
598
|
-
} else if (dsaState) {
|
|
599
|
-
positions = denseBenchmarkPrefill || cache.offset + tokens <= this.config.indexTopk
|
|
600
|
-
? null
|
|
601
|
-
: cache.batchSize !== null && cache.batchSize > 1
|
|
602
|
-
? {
|
|
603
|
-
rows: cache.rowOffsets.map((offset, row) =>
|
|
604
|
-
dsaState.selectSharedPositions(
|
|
605
|
-
this.layer,
|
|
606
|
-
offset + tokens,
|
|
607
|
-
row,
|
|
608
|
-
)
|
|
609
|
-
),
|
|
610
|
-
}
|
|
611
|
-
: dsaState.selectSharedPositions(
|
|
612
|
-
this.layer,
|
|
613
|
-
cache.offset + tokens,
|
|
614
|
-
);
|
|
615
|
-
}
|
|
616
|
-
return this.mla.forward(
|
|
617
|
-
normalized,
|
|
618
|
-
cache,
|
|
619
|
-
dsaKey,
|
|
620
|
-
"auto",
|
|
621
|
-
positions,
|
|
622
|
-
);
|
|
623
|
-
} finally {
|
|
624
|
-
dsaKey?.dispose();
|
|
625
|
-
}
|
|
626
|
-
} finally {
|
|
627
|
-
normalized.dispose();
|
|
628
|
-
}
|
|
629
|
-
}
|
|
630
|
-
|
|
631
|
-
forward(
|
|
632
|
-
input: MlxArray,
|
|
633
|
-
cache: MLACache,
|
|
634
|
-
dsaState: Glm52DsaSelectionState | null,
|
|
635
|
-
): MlxArray {
|
|
636
|
-
const attention = this.attend(input, cache, dsaState);
|
|
637
|
-
const residual = ops.add(input, attention);
|
|
638
|
-
attention.dispose();
|
|
639
|
-
const postNorm = rmsNormF32Mlx(
|
|
640
|
-
residual,
|
|
641
|
-
this.postAttentionNorm,
|
|
642
|
-
this.config.rmsNormEps,
|
|
643
|
-
);
|
|
644
|
-
const feedForward = this.mlp.forward(postNorm);
|
|
645
|
-
postNorm.dispose();
|
|
646
|
-
const output = ops.add(residual, feedForward);
|
|
647
|
-
residual.dispose();
|
|
648
|
-
feedForward.dispose();
|
|
649
|
-
return output;
|
|
650
|
-
}
|
|
651
|
-
|
|
652
|
-
async forwardAsync(
|
|
653
|
-
input: MlxArray,
|
|
654
|
-
cache: MLACache,
|
|
655
|
-
dsaState: Glm52DsaSelectionState | null,
|
|
656
|
-
): Promise<MlxArray> {
|
|
657
|
-
const attention = this.attend(input, cache, dsaState);
|
|
658
|
-
const residual = ops.add(input, attention);
|
|
659
|
-
attention.dispose();
|
|
660
|
-
this.mlp.pilot?.predictNext(this.layer, residual);
|
|
661
|
-
const postNorm = rmsNormF32Mlx(
|
|
662
|
-
residual,
|
|
663
|
-
this.postAttentionNorm,
|
|
664
|
-
this.config.rmsNormEps,
|
|
665
|
-
);
|
|
666
|
-
let feedForward: MlxArray | null = null;
|
|
667
|
-
try {
|
|
668
|
-
feedForward = await this.mlp.forwardAsync(postNorm);
|
|
669
|
-
return ops.add(residual, feedForward);
|
|
670
|
-
} finally {
|
|
671
|
-
postNorm.dispose();
|
|
672
|
-
residual.dispose();
|
|
673
|
-
feedForward?.dispose();
|
|
674
|
-
}
|
|
675
|
-
}
|
|
676
|
-
}
|
|
677
|
-
|
|
678
|
-
export class Glm52Model {
|
|
679
|
-
readonly config: ModelConfig;
|
|
680
|
-
readonly glmConfig: Glm52Config;
|
|
681
|
-
readonly weights: Glm52WeightSource;
|
|
682
|
-
readonly weightsBytes: number;
|
|
683
|
-
readonly capabilities: Glm52ModelCapabilities;
|
|
684
|
-
readonly prefixBase = "model";
|
|
685
|
-
readonly loraState = new LoraState();
|
|
686
|
-
readonly layers: Glm52DecoderLayer[];
|
|
687
|
-
readonly finalNorm: MlxArray;
|
|
688
|
-
readonly expertBackend: Glm52ExpertExecutionBackend | null;
|
|
689
|
-
readonly expertRuntime: Glm52ExpertRuntime | null;
|
|
690
|
-
readonly pilot: Glm52PilotTracker | null;
|
|
691
|
-
readonly dsaPrefillMode: "exact" | "dense-benchmark";
|
|
692
|
-
readonly dsaBenchmarkPrefillTokens: number;
|
|
693
|
-
#dsaSelectionObserver: Glm52DsaSelectionObserver | null = null;
|
|
694
|
-
|
|
695
|
-
constructor(
|
|
696
|
-
weights: Glm52WeightSource,
|
|
697
|
-
config: ModelConfig,
|
|
698
|
-
glmConfig: Glm52Config,
|
|
699
|
-
capabilities: Glm52ModelCapabilities,
|
|
700
|
-
expertBackend: Glm52ExpertExecutionBackend | null = null,
|
|
701
|
-
expertRuntime: Glm52ExpertRuntime | null = null,
|
|
702
|
-
dsaPrefillMode: "exact" | "dense-benchmark" = "exact",
|
|
703
|
-
dsaBenchmarkPrefillTokens = 0,
|
|
704
|
-
) {
|
|
705
|
-
if (config.modelType !== "glm_moe_dsa" ||
|
|
706
|
-
glmConfig.modelType !== "glm_moe_dsa") {
|
|
707
|
-
throw new Error("Glm52Model requires glm_moe_dsa configuration");
|
|
708
|
-
}
|
|
709
|
-
if (config.text.numHiddenLayers !== glmConfig.numHiddenLayers)
|
|
710
|
-
throw new Error("generic and dedicated GLM-5.2 configs disagree");
|
|
711
|
-
this.weights = weights;
|
|
712
|
-
this.config = config;
|
|
713
|
-
this.glmConfig = glmConfig;
|
|
714
|
-
this.weightsBytes = weights.weightsBytes;
|
|
715
|
-
this.capabilities = capabilities;
|
|
716
|
-
this.dsaPrefillMode = dsaPrefillMode;
|
|
717
|
-
if (
|
|
718
|
-
!Number.isSafeInteger(dsaBenchmarkPrefillTokens) ||
|
|
719
|
-
dsaBenchmarkPrefillTokens < 0 ||
|
|
720
|
-
(dsaPrefillMode === "dense-benchmark" && dsaBenchmarkPrefillTokens < 1) ||
|
|
721
|
-
(dsaPrefillMode === "exact" && dsaBenchmarkPrefillTokens !== 0)
|
|
722
|
-
) {
|
|
723
|
-
throw new Error(
|
|
724
|
-
"dense-benchmark DSA prefill requires a positive exact prompt length",
|
|
725
|
-
);
|
|
726
|
-
}
|
|
727
|
-
this.dsaBenchmarkPrefillTokens = dsaBenchmarkPrefillTokens;
|
|
728
|
-
this.expertBackend = expertBackend;
|
|
729
|
-
this.expertRuntime = expertRuntime;
|
|
730
|
-
this.pilot = expertRuntime?.pilotMeasureEnabled
|
|
731
|
-
? new Glm52PilotTracker({
|
|
732
|
-
config: glmConfig,
|
|
733
|
-
weights,
|
|
734
|
-
hintK: expertRuntime.pilotHintK,
|
|
735
|
-
twoStep: expertRuntime.pilotTwoStep,
|
|
736
|
-
hintSink: expertRuntime.pilotHintK > 0
|
|
737
|
-
? expertRuntime.manager
|
|
738
|
-
: undefined,
|
|
739
|
-
})
|
|
740
|
-
: null;
|
|
741
|
-
if (this.pilot) expertRuntime!.attachPilot(this.pilot);
|
|
742
|
-
this.layers = Array.from(
|
|
743
|
-
{ length: glmConfig.numHiddenLayers },
|
|
744
|
-
(_, layer) => new Glm52DecoderLayer(
|
|
745
|
-
glmConfig,
|
|
746
|
-
weights,
|
|
747
|
-
layer,
|
|
748
|
-
capabilities.dsa,
|
|
749
|
-
expertBackend,
|
|
750
|
-
this.pilot,
|
|
751
|
-
dsaBenchmarkPrefillTokens,
|
|
752
|
-
),
|
|
753
|
-
);
|
|
754
|
-
this.finalNorm = weights.tensor("model.norm.weight");
|
|
755
|
-
}
|
|
756
|
-
|
|
757
|
-
static async open(modelDir: string): Promise<Glm52Model> {
|
|
758
|
-
const glmConfig = await loadGlm52Config(modelDir);
|
|
759
|
-
const config = await loadModelConfig(modelDir);
|
|
760
|
-
const weights = ColibriGlm52Weights.open(modelDir);
|
|
761
|
-
try {
|
|
762
|
-
const detected = validateGlm52ContainerLayout(
|
|
763
|
-
weights.container,
|
|
764
|
-
glmConfig,
|
|
765
|
-
);
|
|
766
|
-
return new Glm52Model(weights, config, glmConfig, {
|
|
767
|
-
dsa: detected.hasDsa,
|
|
768
|
-
mtpMetadata: detected.hasMtp,
|
|
769
|
-
});
|
|
770
|
-
} catch (error) {
|
|
771
|
-
weights.dispose();
|
|
772
|
-
throw error;
|
|
773
|
-
}
|
|
774
|
-
}
|
|
775
|
-
|
|
776
|
-
static async openStreamed(
|
|
777
|
-
modelDir: string,
|
|
778
|
-
options: Glm52StreamedOpenOptions,
|
|
779
|
-
): Promise<Glm52Model> {
|
|
780
|
-
const glmConfig = await loadGlm52Config(modelDir);
|
|
781
|
-
const config = await loadModelConfig(modelDir);
|
|
782
|
-
const weights = ColibriGlm52ResidentWeights.open(modelDir, {
|
|
783
|
-
includeMtp: options.enableMtp !== false,
|
|
784
|
-
});
|
|
785
|
-
let runtime: Glm52ExpertRuntime | null = null;
|
|
786
|
-
try {
|
|
787
|
-
const detected = validateGlm52ContainerLayout(
|
|
788
|
-
weights.container,
|
|
789
|
-
glmConfig,
|
|
790
|
-
);
|
|
791
|
-
const {
|
|
792
|
-
enableDsa: _enableDsa,
|
|
793
|
-
dsaPrefillMode,
|
|
794
|
-
dsaBenchmarkPrefillTokens,
|
|
795
|
-
...runtimeOptions
|
|
796
|
-
} = options;
|
|
797
|
-
runtime = await Glm52ExpertRuntime.open(modelDir, glmConfig, {
|
|
798
|
-
...runtimeOptions,
|
|
799
|
-
fixedBytes: weights.weightsBytes + options.reserveBytes,
|
|
800
|
-
});
|
|
801
|
-
return new Glm52Model(
|
|
802
|
-
weights,
|
|
803
|
-
config,
|
|
804
|
-
glmConfig,
|
|
805
|
-
{
|
|
806
|
-
dsa: detected.hasDsa && options.enableDsa !== false,
|
|
807
|
-
mtpMetadata: detected.hasMtp,
|
|
808
|
-
mtpEnabled: detected.hasMtp && options.enableMtp !== false,
|
|
809
|
-
},
|
|
810
|
-
runtime.executor,
|
|
811
|
-
runtime,
|
|
812
|
-
dsaPrefillMode ?? "exact",
|
|
813
|
-
dsaBenchmarkPrefillTokens ?? 0,
|
|
814
|
-
);
|
|
815
|
-
} catch (error) {
|
|
816
|
-
runtime?.close();
|
|
817
|
-
weights.dispose();
|
|
818
|
-
throw error;
|
|
819
|
-
}
|
|
820
|
-
}
|
|
821
|
-
|
|
822
|
-
loraTargets(): Map<string, QuantizedLinear> {
|
|
823
|
-
return new Map();
|
|
824
|
-
}
|
|
825
|
-
|
|
826
|
-
makeCache(): MLACache[] {
|
|
827
|
-
return this.layers.map((layer) => new MLACache({
|
|
828
|
-
kvLoraRank: this.glmConfig.kvLoraRank,
|
|
829
|
-
ropeHeadDim: this.glmConfig.qkRopeHeadDim,
|
|
830
|
-
maxTokens: this.glmConfig.maxPositionEmbeddings,
|
|
831
|
-
...(this.capabilities.dsa && layer.dsa
|
|
832
|
-
? { dsa: { headDim: this.glmConfig.indexHeadDim } }
|
|
833
|
-
: {}),
|
|
834
|
-
}));
|
|
835
|
-
}
|
|
836
|
-
|
|
837
|
-
/** Attach probe-only telemetry for selections computed by FULL DSA layers. */
|
|
838
|
-
setDsaSelectionObserver(observer: Glm52DsaSelectionObserver | null): void {
|
|
839
|
-
this.#dsaSelectionObserver = observer;
|
|
840
|
-
}
|
|
841
|
-
|
|
842
|
-
/** Pin streamed Q4 expert jobs to the row-independent M=1 kernel family.
|
|
843
|
-
* Native MTP enables this only around the batched target verify forward. */
|
|
844
|
-
setSpecKernelPinned(enabled: boolean): void {
|
|
845
|
-
this.expertRuntime?.executor.setFixedKernelFamily(enabled);
|
|
846
|
-
}
|
|
847
|
-
|
|
848
|
-
forwardHidden(ids: MlxArray, cache: Cache[]): MlxArray {
|
|
849
|
-
if (this.expertBackend)
|
|
850
|
-
throw new Error("streamed GLM model requires forwardHiddenAsync()");
|
|
851
|
-
const tokenCount = ids.shape[1] ?? 1;
|
|
852
|
-
const firstOffset = cache[0]?.offset ?? 0;
|
|
853
|
-
if (
|
|
854
|
-
this.capabilities.dsa &&
|
|
855
|
-
!(
|
|
856
|
-
this.dsaPrefillMode === "dense-benchmark" &&
|
|
857
|
-
firstOffset + tokenCount <= this.dsaBenchmarkPrefillTokens
|
|
858
|
-
) &&
|
|
859
|
-
tokenCount > 1 &&
|
|
860
|
-
tokenCount > GLM52_DSA_SPARSE_DECODE_BATCH_MAX &&
|
|
861
|
-
firstOffset + tokenCount > this.glmConfig.indexTopk
|
|
862
|
-
) {
|
|
863
|
-
// Bound sparse-selection state for long prefills while retaining all
|
|
864
|
-
// request rows in each forward. Short verify windows keep the residual
|
|
865
|
-
// and expert graph batched across both requests and query positions.
|
|
866
|
-
const rows: MlxArray[] = [];
|
|
867
|
-
try {
|
|
868
|
-
for (let token = 0; token < tokenCount; token++) {
|
|
869
|
-
const row = ids.slice([0, token], [ids.shape[0]!, token + 1]);
|
|
870
|
-
try {
|
|
871
|
-
rows.push(this.forwardHidden(row, cache));
|
|
872
|
-
} finally {
|
|
873
|
-
row.dispose();
|
|
874
|
-
}
|
|
875
|
-
}
|
|
876
|
-
if (rows.length === 1) return rows[0]!;
|
|
877
|
-
return ops.concatAxis(rows, 1);
|
|
878
|
-
} finally {
|
|
879
|
-
if (rows.length > 1)
|
|
880
|
-
for (const row of rows) row.dispose();
|
|
881
|
-
}
|
|
882
|
-
}
|
|
883
|
-
const embedded = this.weights.embedding(
|
|
884
|
-
ids,
|
|
885
|
-
"model.embed_tokens.weight",
|
|
886
|
-
this.glmConfig.vocabSize,
|
|
887
|
-
this.glmConfig.hiddenSize,
|
|
888
|
-
);
|
|
889
|
-
try {
|
|
890
|
-
return this.forwardEmbeddings(embedded, cache, null);
|
|
891
|
-
} finally {
|
|
892
|
-
embedded.dispose();
|
|
893
|
-
}
|
|
894
|
-
}
|
|
895
|
-
|
|
896
|
-
async forwardHiddenAsync(ids: MlxArray, cache: Cache[]): Promise<MlxArray> {
|
|
897
|
-
const tokenCount = ids.shape[1] ?? 1;
|
|
898
|
-
const firstOffset = cache[0]?.offset ?? 0;
|
|
899
|
-
if (
|
|
900
|
-
this.capabilities.dsa &&
|
|
901
|
-
!(
|
|
902
|
-
this.dsaPrefillMode === "dense-benchmark" &&
|
|
903
|
-
firstOffset + tokenCount <= this.dsaBenchmarkPrefillTokens
|
|
904
|
-
) &&
|
|
905
|
-
tokenCount > 1 &&
|
|
906
|
-
tokenCount > GLM52_DSA_SPARSE_DECODE_BATCH_MAX &&
|
|
907
|
-
firstOffset + tokenCount > this.glmConfig.indexTopk
|
|
908
|
-
) {
|
|
909
|
-
const rows: MlxArray[] = [];
|
|
910
|
-
try {
|
|
911
|
-
for (let token = 0; token < tokenCount; token++) {
|
|
912
|
-
const row = ids.slice([0, token], [ids.shape[0]!, token + 1]);
|
|
913
|
-
try {
|
|
914
|
-
rows.push(await this.forwardHiddenAsync(row, cache));
|
|
915
|
-
} finally {
|
|
916
|
-
row.dispose();
|
|
917
|
-
}
|
|
918
|
-
}
|
|
919
|
-
if (rows.length === 1) return rows[0]!;
|
|
920
|
-
return ops.concatAxis(rows, 1);
|
|
921
|
-
} finally {
|
|
922
|
-
if (rows.length > 1)
|
|
923
|
-
for (const row of rows) row.dispose();
|
|
924
|
-
}
|
|
925
|
-
}
|
|
926
|
-
const embedded = this.weights.embedding(
|
|
927
|
-
ids,
|
|
928
|
-
"model.embed_tokens.weight",
|
|
929
|
-
this.glmConfig.vocabSize,
|
|
930
|
-
this.glmConfig.hiddenSize,
|
|
931
|
-
);
|
|
932
|
-
try {
|
|
933
|
-
return await this.forwardEmbeddingsAsync(embedded, cache, null);
|
|
934
|
-
} finally {
|
|
935
|
-
embedded.dispose();
|
|
936
|
-
}
|
|
937
|
-
}
|
|
938
|
-
|
|
939
|
-
forwardEmbeddings(
|
|
940
|
-
embeddings: MlxArray,
|
|
941
|
-
cache: Cache[],
|
|
942
|
-
_bidir: MlxArray | null,
|
|
943
|
-
): MlxArray {
|
|
944
|
-
if (cache.length !== this.layers.length)
|
|
945
|
-
throw new Error(`GLM cache has ${cache.length} layers, expected ${this.layers.length}`);
|
|
946
|
-
const dsaState = this.capabilities.dsa
|
|
947
|
-
? new Glm52DsaSelectionState(
|
|
948
|
-
this.glmConfig.indexTopk,
|
|
949
|
-
this.#dsaSelectionObserver,
|
|
950
|
-
)
|
|
951
|
-
: null;
|
|
952
|
-
// The RuntimeModel contract keeps caller-provided embeddings caller-owned.
|
|
953
|
-
// Take our own handle before entering the consuming layer loop.
|
|
954
|
-
let current = ops.contiguous(embeddings);
|
|
955
|
-
try {
|
|
956
|
-
for (let layer = 0; layer < this.layers.length; layer++) {
|
|
957
|
-
const layerCache = cache[layer];
|
|
958
|
-
if (!(layerCache instanceof MLACache))
|
|
959
|
-
throw new Error(`GLM layer ${layer} requires MLACache`);
|
|
960
|
-
const next = this.layers[layer]!.forward(
|
|
961
|
-
current,
|
|
962
|
-
layerCache,
|
|
963
|
-
dsaState,
|
|
964
|
-
);
|
|
965
|
-
current.dispose();
|
|
966
|
-
current = next;
|
|
967
|
-
}
|
|
968
|
-
return rmsNormF32Mlx(
|
|
969
|
-
current,
|
|
970
|
-
this.finalNorm,
|
|
971
|
-
this.glmConfig.rmsNormEps,
|
|
972
|
-
);
|
|
973
|
-
} finally {
|
|
974
|
-
current.dispose();
|
|
975
|
-
dsaState?.dispose();
|
|
976
|
-
}
|
|
977
|
-
}
|
|
978
|
-
|
|
979
|
-
async forwardEmbeddingsAsync(
|
|
980
|
-
embeddings: MlxArray,
|
|
981
|
-
cache: Cache[],
|
|
982
|
-
_bidir: MlxArray | null,
|
|
983
|
-
): Promise<MlxArray> {
|
|
984
|
-
if (cache.length !== this.layers.length)
|
|
985
|
-
throw new Error(`GLM cache has ${cache.length} layers, expected ${this.layers.length}`);
|
|
986
|
-
const dsaState = this.capabilities.dsa
|
|
987
|
-
? new Glm52DsaSelectionState(
|
|
988
|
-
this.glmConfig.indexTopk,
|
|
989
|
-
this.#dsaSelectionObserver,
|
|
990
|
-
)
|
|
991
|
-
: null;
|
|
992
|
-
let current = ops.contiguous(embeddings);
|
|
993
|
-
try {
|
|
994
|
-
for (let layer = 0; layer < this.layers.length; layer++) {
|
|
995
|
-
const layerCache = cache[layer];
|
|
996
|
-
if (!(layerCache instanceof MLACache))
|
|
997
|
-
throw new Error(`GLM layer ${layer} requires MLACache`);
|
|
998
|
-
const next = await this.layers[layer]!.forwardAsync(
|
|
999
|
-
current,
|
|
1000
|
-
layerCache,
|
|
1001
|
-
dsaState,
|
|
1002
|
-
);
|
|
1003
|
-
// The streamed path is a bounded-residency graph. Detach every layer
|
|
1004
|
-
// before advancing so dense-prefix and post-expert compose graphs
|
|
1005
|
-
// cannot retain transient dequantized weights across layer boundaries.
|
|
1006
|
-
next.eval();
|
|
1007
|
-
synchronize(gpuStream);
|
|
1008
|
-
current.dispose();
|
|
1009
|
-
current = next;
|
|
1010
|
-
}
|
|
1011
|
-
return rmsNormF32Mlx(
|
|
1012
|
-
current,
|
|
1013
|
-
this.finalNorm,
|
|
1014
|
-
this.glmConfig.rmsNormEps,
|
|
1015
|
-
);
|
|
1016
|
-
} finally {
|
|
1017
|
-
current.dispose();
|
|
1018
|
-
dsaState?.dispose();
|
|
1019
|
-
}
|
|
1020
|
-
}
|
|
1021
|
-
|
|
1022
|
-
logitsFromHidden(hidden: MlxArray): MlxArray {
|
|
1023
|
-
return this.weights.linear(
|
|
1024
|
-
hidden,
|
|
1025
|
-
"lm_head.weight",
|
|
1026
|
-
this.glmConfig.vocabSize,
|
|
1027
|
-
this.glmConfig.hiddenSize,
|
|
1028
|
-
);
|
|
1029
|
-
}
|
|
1030
|
-
|
|
1031
|
-
forward(tokens: number[] | MlxArray, cache: Cache[]): MlxArray {
|
|
1032
|
-
if (this.expertBackend)
|
|
1033
|
-
throw new Error("streamed GLM model requires forwardAsync()");
|
|
1034
|
-
const ids = Array.isArray(tokens)
|
|
1035
|
-
? ops.fromInt32(tokens, [1, tokens.length])
|
|
1036
|
-
: tokens;
|
|
1037
|
-
const hidden = this.forwardHidden(ids, cache);
|
|
1038
|
-
if (Array.isArray(tokens)) ids.dispose();
|
|
1039
|
-
const logits = this.logitsFromHidden(hidden);
|
|
1040
|
-
hidden.dispose();
|
|
1041
|
-
return logits;
|
|
1042
|
-
}
|
|
1043
|
-
|
|
1044
|
-
async forwardAsync(
|
|
1045
|
-
tokens: number[] | MlxArray,
|
|
1046
|
-
cache: Cache[],
|
|
1047
|
-
): Promise<MlxArray> {
|
|
1048
|
-
const offsets = cache.map((layer) => layer.offset);
|
|
1049
|
-
const ids = Array.isArray(tokens)
|
|
1050
|
-
? ops.fromInt32(tokens, [1, tokens.length])
|
|
1051
|
-
: tokens;
|
|
1052
|
-
let hidden: MlxArray | null = null;
|
|
1053
|
-
try {
|
|
1054
|
-
hidden = await this.forwardHiddenAsync(ids, cache);
|
|
1055
|
-
return this.logitsFromHidden(hidden);
|
|
1056
|
-
} catch (error) {
|
|
1057
|
-
const rollbackErrors: unknown[] = [];
|
|
1058
|
-
for (let layer = 0; layer < cache.length; layer++) {
|
|
1059
|
-
const appended = cache[layer]!.offset - offsets[layer]!;
|
|
1060
|
-
if (appended <= 0) continue;
|
|
1061
|
-
try {
|
|
1062
|
-
cache[layer]!.trim(appended, true);
|
|
1063
|
-
} catch (rollbackError) {
|
|
1064
|
-
rollbackErrors.push(rollbackError);
|
|
1065
|
-
}
|
|
1066
|
-
}
|
|
1067
|
-
if (rollbackErrors.length) {
|
|
1068
|
-
throw new AggregateError(
|
|
1069
|
-
[error, ...rollbackErrors],
|
|
1070
|
-
"streamed GLM forward failed and cache rollback was incomplete",
|
|
1071
|
-
);
|
|
1072
|
-
}
|
|
1073
|
-
throw error;
|
|
1074
|
-
} finally {
|
|
1075
|
-
hidden?.dispose();
|
|
1076
|
-
if (Array.isArray(tokens)) ids.dispose();
|
|
1077
|
-
}
|
|
1078
|
-
}
|
|
1079
|
-
|
|
1080
|
-
generate(
|
|
1081
|
-
promptTokens: number[],
|
|
1082
|
-
maxTokens: number,
|
|
1083
|
-
eosIds: number[] = this.glmConfig.eosTokenIds,
|
|
1084
|
-
): number[] {
|
|
1085
|
-
const cache = this.makeCache();
|
|
1086
|
-
const output: number[] = [];
|
|
1087
|
-
try {
|
|
1088
|
-
let tokens = promptTokens;
|
|
1089
|
-
for (let step = 0; step < maxTokens; step++) {
|
|
1090
|
-
const logits = this.forward(tokens, cache);
|
|
1091
|
-
const next = argmaxLastPosition(logits);
|
|
1092
|
-
logits.dispose();
|
|
1093
|
-
if (eosIds.includes(next)) break;
|
|
1094
|
-
output.push(next);
|
|
1095
|
-
tokens = [next];
|
|
1096
|
-
}
|
|
1097
|
-
return output;
|
|
1098
|
-
} finally {
|
|
1099
|
-
for (const layer of cache) layer.dispose();
|
|
1100
|
-
this.expertRuntime?.flushUsage();
|
|
1101
|
-
}
|
|
1102
|
-
}
|
|
1103
|
-
|
|
1104
|
-
async generateAsync(
|
|
1105
|
-
promptTokens: number[],
|
|
1106
|
-
maxTokens: number,
|
|
1107
|
-
eosIds: number[] = this.glmConfig.eosTokenIds,
|
|
1108
|
-
): Promise<number[]> {
|
|
1109
|
-
const cache = this.makeCache();
|
|
1110
|
-
const output: number[] = [];
|
|
1111
|
-
try {
|
|
1112
|
-
let tokens = promptTokens;
|
|
1113
|
-
for (let step = 0; step < maxTokens; step++) {
|
|
1114
|
-
const logits = await this.forwardAsync(tokens, cache);
|
|
1115
|
-
const next = argmaxLastPosition(logits);
|
|
1116
|
-
logits.dispose();
|
|
1117
|
-
if (eosIds.includes(next)) break;
|
|
1118
|
-
output.push(next);
|
|
1119
|
-
tokens = [next];
|
|
1120
|
-
}
|
|
1121
|
-
return output;
|
|
1122
|
-
} finally {
|
|
1123
|
-
for (const layer of cache) layer.dispose();
|
|
1124
|
-
await this.expertRuntime?.finishUsage();
|
|
1125
|
-
}
|
|
1126
|
-
}
|
|
1127
|
-
|
|
1128
|
-
dispose(): void {
|
|
1129
|
-
this.weights.dispose();
|
|
1130
|
-
this.expertRuntime?.close();
|
|
1131
|
-
}
|
|
1132
|
-
}
|