mlx-bun 0.4.0 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1453 -88
- package/THIRD_PARTY_NOTICES.md +882 -0
- package/bin/mlx-bun.convert.mjs +4 -0
- package/bin/mlx-bun.fuse.mjs +4 -0
- package/bin/mlx-bun.generate.mjs +4 -0
- package/bin/mlx-bun.lora.mjs +4 -0
- package/bin/mlx-bun.mjs +13 -21
- package/bin/mlx-bun.server.mjs +4 -0
- package/bin/mlx-bun.upload.mjs +4 -0
- package/dist/web/app.js +9584 -0
- package/package.json +50 -53
- package/src/cli/ane-install.ts +76 -0
- package/src/cli/args.ts +179 -0
- package/src/cli/engine-entry.ts +68 -0
- package/src/cli/inference.ts +214 -0
- package/src/cli/job-entry.ts +97 -0
- package/src/cli/library-host.ts +117 -0
- package/src/cli/main.ts +57 -0
- package/src/cli/memory-engine.ts +163 -0
- package/src/cli/memory.ts +36 -0
- package/src/cli/mlx-lm-aliases.ts +309 -0
- package/src/cli/model-choice.ts +33 -0
- package/src/cli/model-selection.ts +84 -0
- package/src/cli/module-host.ts +11 -0
- package/src/cli/module-verbs.ts +50 -0
- package/src/cli/numerical-policy.ts +12 -0
- package/src/cli/perplexity.ts +89 -0
- package/src/cli/serve-host.ts +423 -0
- package/src/cli/serve-isolated.ts +217 -0
- package/src/cli/serve-options.ts +106 -0
- package/src/cli/serve-state.ts +205 -0
- package/src/cli/serve.ts +500 -0
- package/src/cli/served-model-host.ts +102 -0
- package/src/cli/server-entry.ts +148 -0
- package/src/cli/serving-unit.ts +177 -0
- package/src/{tui.ts → cli/terminal.ts} +13 -8
- package/src/cli/worker-adapters.ts +34 -0
- package/src/cli/worker-entry.ts +272 -0
- package/src/cli/worker-unit.ts +179 -0
- package/src/engine/adapter-operation.ts +26 -0
- package/src/engine/cache-services.ts +114 -0
- package/src/engine/completion.ts +39 -0
- package/src/engine/generation-gateway.ts +358 -0
- package/src/engine/index.ts +59 -0
- package/src/engine/kv-budget.ts +120 -0
- package/src/engine/media-preparation.ts +232 -0
- package/src/engine/model-binding.ts +24 -0
- package/src/engine/model-host.ts +513 -0
- package/src/engine/model-serving.ts +89 -0
- package/src/{serve → engine}/preparation.ts +10 -8
- package/src/{serve → engine}/session-completion-engine.ts +6 -6
- package/src/engine/telemetry.ts +109 -0
- package/src/hub/downloads.ts +116 -0
- package/src/jobs/db.ts +16 -7
- package/src/jobs/events.ts +29 -0
- package/src/jobs/executable.ts +5 -0
- package/src/jobs/host.ts +51 -0
- package/src/jobs/in-process.ts +55 -0
- package/src/{contracts/jobs.ts → jobs/protocol.ts} +7 -9
- package/src/jobs/runner.ts +150 -231
- package/src/jobs/service.ts +75 -0
- package/src/jobs/sse.ts +59 -23
- package/src/jobs/worker-memory.ts +46 -0
- package/src/jobs/worker-process.ts +163 -0
- package/src/jobs/worker-supervisor.ts +258 -0
- package/src/modules.ts +58 -0
- package/src/publishing/catalog-hub.ts +18 -0
- package/src/publishing/credentials.ts +31 -0
- package/src/publishing/upload.ts +37 -0
- package/src/residency/leased-adapters.ts +21 -0
- package/src/residency/local-records.ts +16 -0
- package/src/residency/model-residency.ts +405 -0
- package/src/residency/record-index.ts +28 -0
- package/src/residency/resident-estimate.ts +50 -0
- package/src/{anthropic.ts → server/anthropic.ts} +3 -81
- package/src/server/cache-routes.ts +36 -0
- package/src/{serve → server}/chat-request.ts +12 -10
- package/src/{serve → server}/chat-stage.ts +27 -22
- package/src/{client.ts → server/client.ts} +28 -2
- package/src/{serve → server}/completion-executor.ts +42 -42
- package/src/server/decision-body.ts +55 -0
- package/src/server/decision-routes.ts +134 -0
- package/src/server/decision-wire.ts +228 -0
- package/src/{serve → server}/discovery-routes.ts +42 -83
- package/src/server/generated-token-history.ts +57 -0
- package/src/{serve → server}/http.ts +25 -13
- package/src/{serve → server}/inference-request.ts +5 -5
- package/src/server/job-routes.ts +20 -0
- package/src/server/media-prompt.ts +63 -0
- package/src/server/memory-completion-client.ts +46 -0
- package/src/server/model-routes.ts +192 -0
- package/src/{serve → server}/openai-wire.ts +3 -2
- package/src/{serve → server}/pipeline.ts +1 -1
- package/src/server/prompt-builder.ts +13 -0
- package/src/server/prompt-contracts.ts +17 -0
- package/src/server/proxy-routes.ts +187 -0
- package/src/server/publishing-routes.ts +41 -0
- package/src/{serve → server}/request-plan.ts +8 -8
- package/src/{serve → server}/request-prep.ts +82 -68
- package/src/{serve → server}/responses-client.ts +30 -13
- package/src/{responses.ts → server/responses.ts} +12 -93
- package/src/server/routes.ts +205 -0
- package/src/server/start.ts +72 -0
- package/src/server/status-routes.ts +108 -0
- package/src/{serve → server}/text-completion-stage.ts +25 -4
- package/src/server/text-prompt.ts +12 -0
- package/src/{serve → server}/token-streams.ts +36 -38
- package/src/server/worker-routes.ts +311 -0
- package/src/storage/paths.ts +61 -0
- package/src/web/assets.ts +37 -0
- package/src/web/{src → browser}/api.ts +5 -23
- package/src/web/browser/chat-host.ts +17 -0
- package/src/web/browser/installed-panels.ts +6 -0
- package/src/web/browser/main.ts +55 -0
- package/src/web/browser/markdown.ts +279 -0
- package/src/web/browser/memory-panel.ts +9 -0
- package/src/web/browser/palette.ts +64 -0
- package/src/web/browser/protocol.ts +13 -0
- package/src/web/browser/shell.ts +467 -0
- package/src/web/{src → browser}/status.ts +32 -36
- package/src/web/build.ts +51 -0
- package/src/web/public/app.html +1054 -0
- package/src/web/{sw.js → public/sw.js} +4 -3
- package/src/web/{vendor → public/vendor}/hljs-theme.css +2 -2
- package/src/web/{vendor → public/vendor}/hljs.js +2 -2
- package/THIRD_PARTY_LICENSES.md +0 -51
- package/docs/README.md +0 -94
- package/docs/archive/hlg-sampling.md +0 -350
- package/docs/archive/investigations/audio-input-plan.md +0 -356
- package/docs/archive/investigations/chunk-finetune-experiment.md +0 -84
- package/docs/archive/investigations/colibri-glm52-port.md +0 -1486
- package/docs/archive/investigations/colibri-oracle-pin.md +0 -1284
- package/docs/archive/investigations/curve-bisector-routing.md +0 -123
- package/docs/archive/investigations/decode-roofline-lookagain.md +0 -348
- package/docs/archive/investigations/diffusion-gemma-port.md +0 -602
- package/docs/archive/investigations/dspark-handoff.md +0 -224
- package/docs/archive/investigations/expert-offload-single-user-moe.md +0 -292
- package/docs/archive/investigations/faithful-l1-consolidation.md +0 -310
- package/docs/archive/investigations/hlg-sampling-investigation.md +0 -970
- package/docs/archive/investigations/indexshare-performance-spike.md +0 -357
- package/docs/archive/investigations/kernel-perf-review-2026-07.md +0 -171
- package/docs/archive/investigations/lab-build-journal.md +0 -157
- package/docs/archive/investigations/minicpm5-decode-megakernel.md +0 -489
- package/docs/archive/investigations/openjarvis-fit.md +0 -198
- package/docs/archive/investigations/openwiki-evaluation.md +0 -249
- package/docs/archive/investigations/optimization_plan.md +0 -346
- package/docs/archive/investigations/orpo-base-uf-experiment-and-directions.md +0 -120
- package/docs/archive/investigations/orpo-flash-cce-pin-leak.md +0 -167
- package/docs/archive/investigations/orpo-uf-testing-handoff.md +0 -126
- package/docs/archive/investigations/pareto-specialized-runtime-findings.md +0 -92
- package/docs/archive/investigations/pi-builtin-investigation.md +0 -308
- package/docs/archive/investigations/pre-colibri-stabilization.md +0 -329
- package/docs/archive/investigations/qwen38-27b-campaign-log.md +0 -1092
- package/docs/archive/investigations/segmented-backward-handoff.md +0 -148
- package/docs/archive/investigations/starter-model-port-handoff.md +0 -342
- package/docs/archive/investigations/steel-flash-cce-handoff.md +0 -489
- package/docs/archive/investigations/the-dreaming-handoff.md +0 -141
- package/docs/archive/investigations/trainer-validation-experiment.md +0 -173
- package/docs/archive/planning/chat-ui-vision-memory-first.md +0 -199
- package/docs/archive/planning/chat-ui-vision.md +0 -50
- package/docs/archive/planning/chunk-task-roadmap.md +0 -77
- package/docs/archive/planning/curve-sampler-research-plan.md +0 -331
- package/docs/archive/planning/journal.md +0 -316
- package/docs/archive/planning/memory-docs-and-dag-plan.md +0 -194
- package/docs/archive/planning/pi-integration-review.md +0 -178
- package/docs/archive/planning/release-notes-v0.0.10.md +0 -57
- package/docs/archive/planning/release-notes-v0.0.11.md +0 -239
- package/docs/archive/planning/release-notes-v0.0.12.md +0 -80
- package/docs/archive/planning/release-notes-v0.0.13.md +0 -77
- package/docs/archive/planning/release-notes-v0.0.9.md +0 -122
- package/docs/archive/planning/release-notes-v0.2.0.md +0 -49
- package/docs/archive/planning/release-notes-v0.3.0.md +0 -35
- package/docs/archive/planning/web-ui-pass-plan.md +0 -213
- package/docs/archive/planning/website-readme-pass-plan.md +0 -224
- package/docs/design/batching.md +0 -1841
- package/docs/design/decode-speed-program.md +0 -2349
- package/docs/design/dreaming-nightly-pipeline.md +0 -684
- package/docs/design/generic-model-support.md +0 -705
- package/docs/design/kv-cache.md +0 -824
- package/docs/design/orpo-training.md +0 -680
- package/docs/design/speculative-decoding.md +0 -1990
- package/docs/design/turboquant.md +0 -2212
- package/docs/design/unified-engine-frontier-plan.md +0 -1880
- package/docs/design/web-chat-redesign.md +0 -695
- package/docs/planning/PRODUCT_ROADMAP.md +0 -594
- package/docs/planning/ResearchTopics.md +0 -119
- package/docs/planning/release-notes-v0.4.0.md +0 -45
- package/docs/planning/video-series.md +0 -421
- package/docs/reference/benchmarks.md +0 -3613
- package/docs/reference/cli.md +0 -585
- package/docs/reference/distribution.md +0 -355
- package/docs/reference/environment.md +0 -398
- package/docs/reference/glossary.md +0 -39
- package/docs/reference/library-api.md +0 -674
- package/docs/reference/memory.md +0 -260
- package/docs/reference/models.md +0 -334
- package/docs/reference/server-api.md +0 -1775
- package/docs/reference/server-config.md +0 -846
- package/docs/reference/training.md +0 -462
- package/docs/reference/troubleshooting.md +0 -158
- package/src/admission-plan.ts +0 -18
- package/src/audio/conformer.ts +0 -647
- package/src/audio/decode.ts +0 -133
- package/src/audio/features.ts +0 -202
- package/src/audio/transcode.ts +0 -67
- package/src/backends/mlx/assistant-target.ts +0 -46
- package/src/backends/mlx/autoregressive-draft-rows.ts +0 -120
- package/src/backends/mlx/autoregressive.ts +0 -108
- package/src/backends/mlx/batch-group.ts +0 -1790
- package/src/backends/mlx/cache-attachment.ts +0 -67
- package/src/backends/mlx/cache-layout.ts +0 -31
- package/src/backends/mlx/checkpoint-state.ts +0 -53
- package/src/backends/mlx/continuation-persistence.ts +0 -106
- package/src/backends/mlx/continuation-request.ts +0 -43
- package/src/backends/mlx/continuation.ts +0 -77
- package/src/backends/mlx/diffusion.ts +0 -39
- package/src/backends/mlx/draft-target.ts +0 -32
- package/src/backends/mlx/evaluation.ts +0 -105
- package/src/backends/mlx/fill-append.ts +0 -45
- package/src/backends/mlx/full-kv-row-append.ts +0 -32
- package/src/backends/mlx/full-kv-row-donor.ts +0 -54
- package/src/backends/mlx/full-transitioning-kv-rows.ts +0 -65
- package/src/backends/mlx/gateway-binding.ts +0 -130
- package/src/backends/mlx/graph.ts +0 -38
- package/src/backends/mlx/kv-codec.ts +0 -9
- package/src/backends/mlx/kv-maintenance.ts +0 -133
- package/src/backends/mlx/kv-tensor-rows.ts +0 -212
- package/src/backends/mlx/memory-client.ts +0 -189
- package/src/backends/mlx/methods.ts +0 -90
- package/src/backends/mlx/model-prompt.ts +0 -164
- package/src/backends/mlx/model-serving.ts +0 -79
- package/src/backends/mlx/prefill-cohort.ts +0 -89
- package/src/backends/mlx/prefill-rows.ts +0 -200
- package/src/backends/mlx/prefill.ts +0 -33
- package/src/backends/mlx/projected-context-rows.ts +0 -72
- package/src/backends/mlx/request-policy.ts +0 -20
- package/src/backends/mlx/request-state-policy.ts +0 -41
- package/src/backends/mlx/rollback.ts +0 -89
- package/src/backends/mlx/row-sampling.ts +0 -49
- package/src/backends/mlx/serial-executor.ts +0 -242
- package/src/backends/mlx/speculative-group.ts +0 -359
- package/src/backends/mlx/speculative-round.ts +0 -161
- package/src/backends/mlx/speculative.ts +0 -114
- package/src/backends/mlx/state-rows.ts +0 -104
- package/src/backends/mlx/state-views.ts +0 -46
- package/src/backends/mlx/target-layout-capability.ts +0 -35
- package/src/backends/mlx/text-engine.ts +0 -73
- package/src/backends/mlx/transitioning-kv-rows.ts +0 -165
- package/src/chat-template.ts +0 -382
- package/src/cli.ts +0 -3168
- package/src/config.ts +0 -399
- package/src/contracts/completion.ts +0 -16
- package/src/contracts/execution.ts +0 -60
- package/src/contracts/generation.ts +0 -103
- package/src/contracts/host.ts +0 -7
- package/src/contracts/pi-provider.ts +0 -30
- package/src/contracts/pi.ts +0 -259
- package/src/contracts/prefix-cache.ts +0 -23
- package/src/contracts/resources.ts +0 -25
- package/src/contracts/sampling.ts +0 -23
- package/src/contracts/scheduling.ts +0 -45
- package/src/contracts/tsconfig.json +0 -14
- package/src/dataset/generators.ts +0 -1087
- package/src/dataset/index.ts +0 -12
- package/src/dataset/job.ts +0 -81
- package/src/dataset/llm.ts +0 -71
- package/src/dataset/registry.ts +0 -528
- package/src/diffusion/diffusion-generate.ts +0 -507
- package/src/download.ts +0 -505
- package/src/embed.ts +0 -77
- package/src/engine/admission.ts +0 -59
- package/src/engine/cancellation.ts +0 -38
- package/src/engine/engine.ts +0 -56
- package/src/engine/execution-coordinator.ts +0 -70
- package/src/engine/execution-plan.ts +0 -53
- package/src/engine/resources.ts +0 -53
- package/src/engine/scheduler.ts +0 -72
- package/src/engine/session.ts +0 -247
- package/src/eval/README.md +0 -130
- package/src/eval/ifeval.ts +0 -81
- package/src/eval/kl-prompts.ts +0 -29
- package/src/eval/kl.ts +0 -590
- package/src/eval/perplexity.ts +0 -164
- package/src/eval/quality-db.ts +0 -92
- package/src/eval/reference-logits.ts +0 -207
- package/src/eval/runner.ts +0 -124
- package/src/eval/score.ts +0 -49
- package/src/eval/tasks/bfcl.ts +0 -535
- package/src/eval/tasks/gsm8k.ts +0 -98
- package/src/eval/tasks/hashhop.ts +0 -139
- package/src/eval/tasks/humaneval.ts +0 -275
- package/src/eval/tasks/ifeval.ts +0 -525
- package/src/eval/tasks/mmlu.ts +0 -157
- package/src/eval/ultrafeedback.ts +0 -60
- package/src/evaldb.ts +0 -199
- package/src/expert-io.ts +0 -393
- package/src/expert-offload-build.ts +0 -77
- package/src/expert-offload.ts +0 -76
- package/src/expert-residency.ts +0 -1134
- package/src/expert-usage.ts +0 -415
- package/src/fill/echo-index.ts +0 -188
- package/src/fill/fill-session.ts +0 -452
- package/src/fill/proposal.ts +0 -68
- package/src/fill/schema-rows.ts +0 -506
- package/src/fill/tool-boundary.ts +0 -103
- package/src/fit.ts +0 -249
- package/src/generate.ts +0 -1346
- package/src/grammar.ts +0 -591
- package/src/harness-pi.ts +0 -184
- package/src/hf-push.ts +0 -628
- package/src/hub-rest.ts +0 -242
- package/src/index.ts +0 -63
- package/src/inference/denoising.ts +0 -17
- package/src/inference/draft-acceptance.ts +0 -41
- package/src/inference/draft-output.ts +0 -49
- package/src/inference/graph.ts +0 -33
- package/src/inference/prefill.ts +0 -39
- package/src/inference/rollback.ts +0 -7
- package/src/jobs/index.ts +0 -31
- package/src/jobs/job-entry.ts +0 -107
- package/src/jobs/task-client.ts +0 -19
- package/src/jobs/types.ts +0 -2
- package/src/kv-scheme.ts +0 -257
- package/src/kv-store.ts +0 -1099
- package/src/lab/README.md +0 -18
- package/src/lab/curve/curve-designer.html +0 -303
- package/src/lab/curve/curve-sampler.ts +0 -122
- package/src/lab/expert-trace/expert-trace.ts +0 -69
- package/src/lab/paged-kv/paged-kv-rows.ts +0 -83
- package/src/lab/paged-kv/paged-kv.ts +0 -270
- package/src/library.ts +0 -40
- package/src/lora.ts +0 -408
- package/src/md-modules.d.ts +0 -49
- package/src/media-fetch.ts +0 -442
- package/src/memory/article.ts +0 -558
- package/src/memory/chunk-validation.ts +0 -150
- package/src/memory/chunk.ts +0 -318
- package/src/memory/cluster.ts +0 -351
- package/src/memory/coverage.ts +0 -134
- package/src/memory/crosslink.ts +0 -0
- package/src/memory/db.ts +0 -253
- package/src/memory/entity.ts +0 -203
- package/src/memory/gate.ts +0 -187
- package/src/memory/history.ts +0 -152
- package/src/memory/ingest.ts +0 -335
- package/src/memory/model.ts +0 -183
- package/src/memory/normalize.ts +0 -671
- package/src/memory/parse.ts +0 -22
- package/src/memory/pipeline.ts +0 -275
- package/src/memory/prompts.ts +0 -65
- package/src/memory/query.ts +0 -334
- package/src/memory/reconcile.ts +0 -734
- package/src/memory/redirect.ts +0 -108
- package/src/memory/reindex.ts +0 -325
- package/src/memory/resolve.ts +0 -307
- package/src/memory/rest.ts +0 -245
- package/src/memory/route.ts +0 -272
- package/src/memory/schedule.ts +0 -165
- package/src/memory/stages.ts +0 -777
- package/src/memory/synthesize.ts +0 -1638
- package/src/memory/tools.ts +0 -749
- package/src/memory/vault.ts +0 -1194
- package/src/memory/wikify.ts +0 -1064
- package/src/mlx/array.ts +0 -388
- package/src/mlx/autograd.ts +0 -304
- package/src/mlx/checkpoint.ts +0 -149
- package/src/mlx/compile.ts +0 -168
- package/src/mlx/custom-vjp.ts +0 -188
- package/src/mlx/ffi.ts +0 -512
- package/src/mlx/materialize.ts +0 -23
- package/src/mlx/metal-kernel.ts +0 -159
- package/src/mlx/ops.ts +0 -1021
- package/src/mlx/quantized-rows.ts +0 -36
- package/src/mlx/token-bitmask.ts +0 -52
- package/src/mlx/turboquant-kv-decode.ts +0 -82
- package/src/mlx/turboquant-kv-inverse.ts +0 -122
- package/src/mlx/turboquant-ops.ts +0 -861
- package/src/mlx/turboquant-tables.ts +0 -237
- package/src/mmap.ts +0 -90
- package/src/model/artifact-identity.ts +0 -73
- package/src/model/batched-kv.ts +0 -235
- package/src/model/batched-mask.ts +0 -279
- package/src/model/batched-quant.ts +0 -212
- package/src/model/batched-quantized-kv.ts +0 -144
- package/src/model/batched-rotating-quant.ts +0 -353
- package/src/model/batched-rotating-state.ts +0 -149
- package/src/model/batched-rotating.ts +0 -338
- package/src/model/batched-row-storage.ts +0 -179
- package/src/model/batched-ssm.ts +0 -52
- package/src/model/batched-turboquant-kv.ts +0 -93
- package/src/model/compiled-decode.ts +0 -712
- package/src/model/decoded-kv-donor.ts +0 -12
- package/src/model/delayed-quantized-kv.ts +0 -72
- package/src/model/delayed-rotating-quantized-kv.ts +0 -93
- package/src/model/delayed-turboquant-kv.ts +0 -55
- package/src/model/diffusion-gemma.ts +0 -1026
- package/src/model/factory.ts +0 -189
- package/src/model/fingerprint.ts +0 -33
- package/src/model/flash-attention.ts +0 -694
- package/src/model/full-prefill-padding.ts +0 -56
- package/src/model/full-prefill-row.ts +0 -105
- package/src/model/gemma4-base.ts +0 -2351
- package/src/model/gemma4.ts +0 -1315
- package/src/model/generated/gemma4-12b.ts +0 -429
- package/src/model/generated/gemma4-26b.ts +0 -448
- package/src/model/generated/gemma4-e4b.ts +0 -717
- package/src/model/generated/index.ts +0 -18
- package/src/model/glm52-atlas.ts +0 -511
- package/src/model/glm52-cache.ts +0 -792
- package/src/model/glm52-config.ts +0 -262
- package/src/model/glm52-container.ts +0 -305
- package/src/model/glm52-coupling.ts +0 -388
- package/src/model/glm52-dsa.ts +0 -606
- package/src/model/glm52-expert-layout.ts +0 -253
- package/src/model/glm52-layout.ts +0 -152
- package/src/model/glm52-memory.ts +0 -500
- package/src/model/glm52-mla.ts +0 -792
- package/src/model/glm52-moe.ts +0 -223
- package/src/model/glm52-pilot.ts +0 -537
- package/src/model/glm52-reference.ts +0 -445
- package/src/model/glm52-residency.ts +0 -557
- package/src/model/glm52-resident-weights.ts +0 -135
- package/src/model/glm52-streamed-experts.ts +0 -453
- package/src/model/glm52-streamed-metal.ts +0 -610
- package/src/model/glm52-weights.ts +0 -503
- package/src/model/glm52.ts +0 -1132
- package/src/model/implementation.ts +0 -69
- package/src/model/kv-attention-view.ts +0 -67
- package/src/model/minicpm5.ts +0 -376
- package/src/model/profile.ts +0 -443
- package/src/model/qwen-append.ts +0 -12
- package/src/model/qwen-conv.ts +0 -52
- package/src/model/qwen3-delta-state.ts +0 -74
- package/src/model/qwen3-delta.ts +0 -451
- package/src/model/qwen3-moe.ts +0 -404
- package/src/model/qwen3-mrope.ts +0 -252
- package/src/model/qwen3.ts +0 -277
- package/src/model/qwen3_5-checkpoint.ts +0 -164
- package/src/model/qwen3_5.ts +0 -819
- package/src/model/rotating-kv-donor.ts +0 -35
- package/src/model/rotating-kv-layout.ts +0 -262
- package/src/model/rotating-row-transaction.ts +0 -35
- package/src/model/speculative-rotating-kv.ts +0 -101
- package/src/model/ssm-prefill-padding.ts +0 -39
- package/src/model/support.ts +0 -102
- package/src/model/trellis-balanced-scatter.ts +0 -51
- package/src/model/trellis-linear.ts +0 -672
- package/src/model/trellis-shared-m.ts +0 -151
- package/src/model/trellis-shared-scatter.ts +0 -144
- package/src/model/trellis-splitk-prefill.ts +0 -158
- package/src/model/trellis-tiled-prefill.ts +0 -136
- package/src/model/trellis-vector-expand.ts +0 -62
- package/src/model/trellis-wide-prefill.ts +0 -94
- package/src/model/turboquant-codec.ts +0 -83
- package/src/model/universal/archs.ts +0 -332
- package/src/model/universal/dense.ts +0 -612
- package/src/model/universal/modules.ts +0 -170
- package/src/model/universal/rope.ts +0 -381
- package/src/native/expert_io.c +0 -523
- package/src/native/frame_extract.swift +0 -140
- package/src/native-pack.ts +0 -162
- package/src/pi-provider.ts +0 -53
- package/src/pi-session.ts +0 -81
- package/src/pi-terminal.ts +0 -274
- package/src/pi-web.ts +0 -1932
- package/src/preflight.ts +0 -158
- package/src/prompt-cache.ts +0 -460
- package/src/quantize/allocator.ts +0 -627
- package/src/quantize/atomic-output.ts +0 -38
- package/src/quantize/calibration.ts +0 -181
- package/src/quantize/config-writer.ts +0 -145
- package/src/quantize/index.ts +0 -84
- package/src/quantize/job.ts +0 -162
- package/src/quantize/quantizer.ts +0 -666
- package/src/quantize/rotate.ts +0 -603
- package/src/quantize/safetensors-writer.ts +0 -249
- package/src/quantize/sensitivity.ts +0 -216
- package/src/quantize/trellis.ts +0 -586
- package/src/quantize/weight-transform.ts +0 -292
- package/src/registry.ts +0 -602
- package/src/runtime-config.ts +0 -81
- package/src/safetensors.ts +0 -158
- package/src/sampler.ts +0 -1011
- package/src/serve/admin-routes.ts +0 -184
- package/src/serve/assets/curve-terrain.html +0 -105
- package/src/serve/assets/training-inference-map.html +0 -575
- package/src/serve/aux-routes.ts +0 -132
- package/src/serve/batch-scheduler.ts +0 -8
- package/src/serve/checkpoint-identity.ts +0 -64
- package/src/serve/generation-gateway.ts +0 -496
- package/src/serve/isolate.ts +0 -609
- package/src/serve/kv-budget.ts +0 -14
- package/src/serve/lab-routes.ts +0 -341
- package/src/serve/lane-registry.ts +0 -45
- package/src/serve/model-admin-routes.ts +0 -155
- package/src/serve/model-binding.ts +0 -43
- package/src/serve/model-host.ts +0 -511
- package/src/serve/parent-application.ts +0 -56
- package/src/serve/prompt-response-trace.ts +0 -147
- package/src/serve/response-lease.ts +0 -24
- package/src/serve/session-search.ts +0 -326
- package/src/serve/static-routes.ts +0 -101
- package/src/server.ts +0 -1314
- package/src/spec/assistant-rows.ts +0 -92
- package/src/spec/assistant-source.ts +0 -126
- package/src/spec/cache-identity.ts +0 -22
- package/src/spec/deepspec-rows.ts +0 -29
- package/src/spec/deepspec-source.ts +0 -145
- package/src/spec/dflash-source.ts +0 -149
- package/src/spec/drafter.ts +0 -304
- package/src/spec/dspark/ab-stats.ts +0 -136
- package/src/spec/dspark/calibration.ts +0 -112
- package/src/spec/dspark/data-dflash.ts +0 -156
- package/src/spec/dspark/data.ts +0 -201
- package/src/spec/dspark/deepspec-module.ts +0 -776
- package/src/spec/dspark/generate-dflash.ts +0 -245
- package/src/spec/dspark/generate.ts +0 -290
- package/src/spec/dspark/loader.ts +0 -23
- package/src/spec/dspark/loss.ts +0 -213
- package/src/spec/dspark/module-dflash.ts +0 -560
- package/src/spec/dspark/module.ts +0 -540
- package/src/spec/dspark/quantize-drafter.ts +0 -91
- package/src/spec/dspark/sample.ts +0 -112
- package/src/spec/generate.ts +0 -276
- package/src/spec/glm52-mtp-graph.ts +0 -29
- package/src/spec/glm52-mtp-rows.ts +0 -132
- package/src/spec/glm52-mtp-source.ts +0 -317
- package/src/spec/glm52-mtp-state.ts +0 -33
- package/src/spec/ngram-source.ts +0 -204
- package/src/spec/projected-draft-rows.ts +0 -73
- package/src/spec/qwen-mtp-module.ts +0 -171
- package/src/spec/qwen-mtp-rows.ts +0 -219
- package/src/spec/qwen-mtp-source.ts +0 -383
- package/src/spec/qwen-mtp-state.ts +0 -30
- package/src/spec/serve-loop.ts +0 -585
- package/src/spec/source.ts +0 -215
- package/src/spec/two-model-rows.ts +0 -61
- package/src/spec/two-model.ts +0 -113
- package/src/ssd-cache.ts +0 -372
- package/src/ssd-durability.ts +0 -211
- package/src/tokenizer.ts +0 -335
- package/src/tool-approvals.ts +0 -131
- package/src/tool-call.ts +0 -695
- package/src/train/dataset.ts +0 -484
- package/src/train/diffusion-lora.ts +0 -216
- package/src/train/export.ts +0 -32
- package/src/train/flash-cce.ts +0 -1234
- package/src/train/forward.ts +0 -266
- package/src/train/fuse.ts +0 -243
- package/src/train/index.ts +0 -46
- package/src/train/job.ts +0 -205
- package/src/train/lora-params.ts +0 -254
- package/src/train/loss.ts +0 -1591
- package/src/train/merge.ts +0 -195
- package/src/train/optimizer.ts +0 -183
- package/src/train/prefix-shared.ts +0 -490
- package/src/train/rank.ts +0 -137
- package/src/train/segmented.ts +0 -1828
- package/src/train/steel-qmm-header.ts +0 -1461
- package/src/train/trainer.ts +0 -1221
- package/src/train/watch.ts +0 -542
- package/src/vision/diffusion-vision.ts +0 -620
- package/src/vision/embedder.ts +0 -168
- package/src/vision/preprocess.ts +0 -247
- package/src/vision/prompt.ts +0 -373
- package/src/vision/qwen3vl-preprocess.ts +0 -409
- package/src/vision/qwen3vl-prompt.ts +0 -196
- package/src/vision/qwen3vl-tower.ts +0 -555
- package/src/vision/siglip.ts +0 -599
- package/src/vision/video-frames.ts +0 -148
- package/src/web/app.html +0 -2143
- package/src/web/app.js +0 -5703
- package/src/web/skills/memory/SKILL.md +0 -120
- package/src/web/skills/web-research/SKILL.md +0 -46
- package/src/web/skills.ts +0 -97
- package/src/web/src/adapters-panel.ts +0 -288
- package/src/web/src/assistant.ts +0 -451
- package/src/web/src/chat.ts +0 -1057
- package/src/web/src/composer.ts +0 -959
- package/src/web/src/dataset.ts +0 -132
- package/src/web/src/finetune.ts +0 -267
- package/src/web/src/hub.ts +0 -428
- package/src/web/src/main.ts +0 -98
- package/src/web/src/markdown.ts +0 -0
- package/src/web/src/memory-panel.ts +0 -572
- package/src/web/src/model-picker.ts +0 -159
- package/src/web/src/palette.ts +0 -346
- package/src/web/src/protocol.ts +0 -26
- package/src/web/src/quantize.ts +0 -167
- package/src/web/src/rag.ts +0 -274
- package/src/web/src/sessions.ts +0 -469
- package/src/web/src/shell.ts +0 -804
- package/src/web/src/ui-catalog.ts +0 -78
- package/src/web/vendor/README.md +0 -61
- package/src/web-assets.ts +0 -47
- package/src/web-tools.ts +0 -478
- package/src/weights.ts +0 -255
- /package/src/{serve → server}/completion-sink.ts +0 -0
- /package/src/web/{icon.svg → public/icon.svg} +0 -0
- /package/src/web/{manifest.webmanifest → public/manifest.webmanifest} +0 -0
- /package/src/web/{vendor → public/vendor}/hljs-LICENSE +0 -0
|
@@ -1,356 +0,0 @@
|
|
|
1
|
-
# Audio input — design & implementation plan (gemma-4 audio tower)
|
|
2
|
-
|
|
3
|
-
Status: **A0–A4 DONE** (2026-07-07: served end to end on e4b, oracle-EXACT
|
|
4
|
-
greedy offline AND over HTTP; A5 bench + 12B coverage open).
|
|
5
|
-
Scope: audio **understanding** — audio-in, text-out through the chat API.
|
|
6
|
-
TTS / STT-as-an-endpoint / STS stay out of scope (see
|
|
7
|
-
docs/design/omlx-adoption-map.md); §5 lists non-goals explicitly.
|
|
8
|
-
|
|
9
|
-
## 0. TL;DR
|
|
10
|
-
|
|
11
|
-
e4b ships a 12-block Conformer audio tower that we already have on disk —
|
|
12
|
-
the `optiq_vision.safetensors` sidecar in the local e4b OptiQ-4bit snapshot
|
|
13
|
-
contains 752 `audio_tower.*`/`embed_audio.*` tensors, and its `config.json`
|
|
14
|
-
carries the full `audio_config` plus the audio token ids. mlx-lm strips all
|
|
15
|
-
of this and rejects audio requests, so (as with vision) **the oracle is
|
|
16
|
-
optiq's internal machinery**, which is complete end-to-end but not exposed
|
|
17
|
-
by optiq's own serve frontend. The implementation is a fourth tower next to
|
|
18
|
-
`src/vision/{siglip,embedder,diffusion-vision}.ts`, reusing every existing
|
|
19
|
-
multimodal seam: sidecar lazy-load, `<|placeholder|>` splice, merged
|
|
20
|
-
embeddings into `forwardEmbeddings`, serial-lane routing. New primitives
|
|
21
|
-
needed: a `mlx_conv2d` binding (SSCP subsampler) and a small TS-side
|
|
22
|
-
mel-spectrogram extractor (USM pipeline). Everything else is pattern-match
|
|
23
|
-
on the vision port.
|
|
24
|
-
|
|
25
|
-
## 1. What the ancestors do (surveyed 2026-07-06, pinned oracle venv)
|
|
26
|
-
|
|
27
|
-
### mlx-lm 0.31.3 — nothing, and actively strips
|
|
28
|
-
|
|
29
|
-
- `models/gemma3n.py:602` and `models/gemma4.py:55` `sanitize()` pop
|
|
30
|
-
`audio_tower`, `embed_audio` (and the vision keys) from the weights at
|
|
31
|
-
load. The upstream capability is deliberately discarded.
|
|
32
|
-
- `server.py:118–150` `process_message_content()` raises
|
|
33
|
-
`ValueError("Only 'text' content type is supported.")` for any non-text
|
|
34
|
-
content part — `input_audio` requests hard-fail.
|
|
35
|
-
- No mel/spectrogram/feature code anywhere in the package; no mlx-vlm /
|
|
36
|
-
mlx-audio / mlx-whisper installed in the oracle venv.
|
|
37
|
-
|
|
38
|
-
**Parity-tree consequence:** there is no mlx-lm arm for audio. Like the
|
|
39
|
-
vision port, correctness gates come from optiq's internals; anything no
|
|
40
|
-
ancestor does (e.g. ever batching audio requests) is novel territory →
|
|
41
|
-
KL + quality gates, not bit-parity (see three-tier doctrine in PLAN.md).
|
|
42
|
-
|
|
43
|
-
### mlx-optiq — complete machinery, unexposed at the serve layer
|
|
44
|
-
|
|
45
|
-
All under `optiq/vlm/_mlxvlm/models/gemma4/` in the oracle venv:
|
|
46
|
-
|
|
47
|
-
- **Feature extraction** (`audio_feature_extractor.py`,
|
|
48
|
-
`Gemma4AudioFeatureExtractor`) — USM pipeline: 16 kHz mono input,
|
|
49
|
-
frame 20 ms / hop 10 ms, magnitude STFT, 128 HTK-scale mel bins over
|
|
50
|
-
0–8 kHz, `log(mel + 1e-3)` floor, optional per-bin mean/stddev
|
|
51
|
-
normalization; `preemphasis=0.0`, `fft_overdrive=False`, `dither=0.0`
|
|
52
|
-
by default. Runs CPU-side (numpy). Output
|
|
53
|
-
`input_features [B,T,128]` + validity mask.
|
|
54
|
-
- **Tower** (`audio.py`, `AudioEncoder`) —
|
|
55
|
-
`SubSampleConvProjection`: two Conv2d stages (channels `(128, 32)`,
|
|
56
|
-
each 2× time stride) then linear to `hidden_size=1024`; then
|
|
57
|
-
**12 Conformer blocks**: FF (residual_weight 0.5) → chunked local
|
|
58
|
-
attention (chunk 12, left context 13 chunks, right 0, logit softcap
|
|
59
|
-
50.0, invalid logits −1e9) → depthwise light Conv1d (kernel 5) → FF →
|
|
60
|
-
clamp + RMSNorm; then output projection to `output_proj_dims=1536`.
|
|
61
|
-
`use_clipped_linears=True`: linears clamp activations to recorded
|
|
62
|
-
per-tensor `input_min/max`/`output_min/max` ranges (those stats ship in
|
|
63
|
-
the sidecar — confirmed present in our local e4b sidecar).
|
|
64
|
-
- **Embedder** (`merge.py`, `MultimodalEmbedder`) — RMSNormNoScale +
|
|
65
|
-
bias-free Linear into text hidden size; embeddings scattered into the
|
|
66
|
-
input sequence at `audio_token_id` positions via `masked_scatter`
|
|
67
|
-
(`gemma4.py get_input_embeddings`).
|
|
68
|
-
- **Tokens & splicing** (`processing_gemma4.py:264–299`) —
|
|
69
|
-
`<|audio|>` expands to `boa + audio_token×n + eoa` with
|
|
70
|
-
`n = min(ceil(duration_ms / 40), 750)` (40 ms/token, ≤30 s ≙ 750 soft
|
|
71
|
-
tokens). Ids (confirmed in our local e4b config.json):
|
|
72
|
-
`boa=256000`, `audio=258881`, `eoa=258883`.
|
|
73
|
-
- **Request parsing** (`processing_gemma4.py:690`) — accepts OpenAI-style
|
|
74
|
-
parts `{"audio", "input_audio", "audio_url"}`.
|
|
75
|
-
- **Sidecar & quant policy** — `vlm/sidecar.py` extracts
|
|
76
|
-
`audio_tower.*`/`embed_audio.*` into the same `optiq_vision.safetensors`
|
|
77
|
-
as vision, kept **bf16**; `backends/mlx_backend.py:491` skips
|
|
78
|
-
`audio_tower.` in the quantization predicate. Calibration recipe (and a
|
|
79
|
-
worked example of driving the audio path programmatically):
|
|
80
|
-
`calibration/datasets.py load_audio_calibration` (LibriSpeech clean).
|
|
81
|
-
- **The gap:** `vlm/gemma4/frontend.py` only wires **vision** into optiq
|
|
82
|
-
serve; audio works only through the internal model class. Golden
|
|
83
|
-
generation therefore scripts the internal model directly (the
|
|
84
|
-
calibration loader shows exactly how) — same move as the vision port.
|
|
85
|
-
|
|
86
|
-
## 2. What we already have (verified on this machine, 2026-07-06)
|
|
87
|
-
|
|
88
|
-
- **e4b OptiQ-4bit** (snapshot `fcdb12…`): sidecar contains **752 audio
|
|
89
|
-
tensors** (`audio_tower.*` + `embed_audio.*`, incl. clipped-linear
|
|
90
|
-
min/max stats); `config.json` has `audio_config`
|
|
91
|
-
(`model_type=gemma4_audio`, 12 layers, hidden 1024, heads 8, conv
|
|
92
|
-
kernel 5, subsampling channels (128,32), logit cap 50, residual 0.5,
|
|
93
|
-
`output_proj_dims=1536`, `use_clipped_linears=true`) plus
|
|
94
|
-
`audio_token_id/boa_token_id/eoa_token_id`; `tokenizer_config.json` has
|
|
95
|
-
`audio_token: "<|audio|>"`. **No download needed — audio-ready today.**
|
|
96
|
-
- **12B OptiQ-4bit**: `audio_config` present but the local sidecar holds
|
|
97
|
-
only **1** audio tensor → needs a sidecar rebuild via optiq's
|
|
98
|
-
`build_vision_sidecar` (its selective-download path pulls only the
|
|
99
|
-
audio shards, not the full base model).
|
|
100
|
-
- **26B-A4B, DiffusionGemma, bf16 assistants**: no `audio_config` — no
|
|
101
|
-
audio for these, ever (architecture, not a porting gap).
|
|
102
|
-
- **Vision pipeline is the template** — every seam already exists:
|
|
103
|
-
content-part detection `src/server.ts:2234`, extraction + splice + merge
|
|
104
|
-
`src/vision/prompt.ts`, lazy tower `src/server.ts:326–350`, sidecar
|
|
105
|
-
detection `src/registry.ts:487` / `src/config.ts:287`, embeddings
|
|
106
|
-
prefill `src/generate.ts:468` → `forwardEmbeddings`
|
|
107
|
-
`src/model/gemma4.ts:876–896` (per-layer-input id zeroing + bidir mask).
|
|
108
|
-
- **FFI gaps**: `mlx_conv1d` is bound (`src/mlx/ffi.ts:173`, Qwen3.5
|
|
109
|
-
DeltaNet, depthwise) but there is **no conv2d and no FFT** binding.
|
|
110
|
-
SSCP needs conv2d; mel extraction needs an FFT (resolved TS-side, §3.1).
|
|
111
|
-
|
|
112
|
-
## 3. Design
|
|
113
|
-
|
|
114
|
-
### 3.1 New files (mirror of `src/vision/`)
|
|
115
|
-
|
|
116
|
-
- **`src/audio/decode.ts`** — WAV parser (PCM16/24/32/float32) → mono
|
|
117
|
-
mix-down → resample to 16 kHz (windowed-sinc or linear; gate vs oracle
|
|
118
|
-
resampler on the fixture). Non-WAV formats (mp3/m4a/flac/ogg): shell out
|
|
119
|
-
to macOS `afconvert` (built into darwin, our only platform) to produce
|
|
120
|
-
WAV — zero new dependencies. **Duration (and thus soft-token count) is
|
|
121
|
-
computed from decoded samples**, so format never affects splicing.
|
|
122
|
-
- **`src/audio/features.ts`** — USM mel extractor, verbatim-semantics port
|
|
123
|
-
of `audio_feature_extractor.py` (megakernel copy-verbatim methodology:
|
|
124
|
-
match first, optimize never — this is ~100×128 floats, not a perf
|
|
125
|
-
path). STFT frame 320 samples / hop 160 / FFT 512
|
|
126
|
-
(`fft_overdrive=False`), 128 HTK mel bins 0–8 kHz, `log(x + 1e-3)`,
|
|
127
|
-
per-bin normalization from shipped stats (open Q3). Implemented as a
|
|
128
|
-
small radix-2 real FFT in TS, f64 accumulate → f32 out, CPU-side —
|
|
129
|
-
exactly where optiq does it (numpy), keeping the mlx graph clean.
|
|
130
|
-
*Considered and rejected for v1*: binding `mlx_fft_rfft` and doing it
|
|
131
|
-
on-device — new binding surface for no perf need.
|
|
132
|
-
- **`src/audio/conformer.ts`** — the tower, bf16 mlx graph:
|
|
133
|
-
- **needs `mlx_conv2d` binding** — read the full mlx.h signature first
|
|
134
|
-
(trailing-optional-param → shifted stream arg hazard, CLAUDE.md).
|
|
135
|
-
- SSCP: Conv2d(1→128) → Conv2d(128→32), each 2× time stride → linear
|
|
136
|
-
to 1024 (exact shapes read from the sidecar weights).
|
|
137
|
-
- 12 × ConformerBlock as in §1; chunked local attention implemented as
|
|
138
|
-
an explicit dense additive mask (≤750 frames pre-subsample, ~188
|
|
139
|
-
post — dense is trivially cheap at this size) with logit softcap 50
|
|
140
|
-
and −1e9 invalid fill.
|
|
141
|
-
- Clipped linears: clamp to shipped `input_min/max`/`output_min/max` —
|
|
142
|
-
parity depends on this, port exactly (toggle test in A2).
|
|
143
|
-
- Output proj → 1536, then `embed_audio` (RMSNormNoScale + Linear →
|
|
144
|
-
text hidden), **pre-divided by embed_scale** — same convention as
|
|
145
|
-
vision towers (`forwardEmbeddings` re-multiplies).
|
|
146
|
-
- **`src/audio/prompt.ts` folded into a shared multimodal prompt
|
|
147
|
-
builder** — recommendation: generalize `src/vision/prompt.ts`
|
|
148
|
-
(`buildVisionPrompt` → `buildMultimodalPrompt`) rather than add a
|
|
149
|
-
parallel audio-only path, because one message can legally carry images
|
|
150
|
-
AND audio and both must splice in document order. Vision-only and
|
|
151
|
-
audio-only fall out as special cases; the vision goldens gate the
|
|
152
|
-
refactor (spliced ids must stay byte-identical).
|
|
153
|
-
|
|
154
|
-
### 3.2 Server surface
|
|
155
|
-
|
|
156
|
-
- Accept OpenAI content parts:
|
|
157
|
-
`{"type":"input_audio","input_audio":{"data":"<b64>","format":"wav"|"mp3"}}`
|
|
158
|
-
(OpenAI canonical) plus optiq's `{"type":"audio"}` / `{"type":"audio_url"}`
|
|
159
|
-
aliases. `hasAudio` detection lands next to `hasImages`
|
|
160
|
-
(`src/server.ts:2234`).
|
|
161
|
-
- `getAudioTower(ctx)` lazy-loads next to `getVisionTower`
|
|
162
|
-
(`src/server.ts:326–350`) — same sidecar file, separate tower object;
|
|
163
|
-
text-only sessions never pay for it. Auto-enable on
|
|
164
|
-
`audio_config` + sidecar audio tensors present, mirroring vision —
|
|
165
|
-
**no new flags** (target surface: zero CLI delta).
|
|
166
|
-
- Routing: audio requests take the **serial lane**, same rule as vision —
|
|
167
|
-
embeddings-prefill doesn't batch, and `promptEmbeddings` already
|
|
168
|
-
excludes the pre-warmed prompt cache (`src/generate.ts:468`). Batching
|
|
169
|
-
is a mode, not a fallback; batched audio has no oracle → if we ever
|
|
170
|
-
want it, it goes through KL + quality gates as new territory.
|
|
171
|
-
- Anthropic-protocol endpoint: the Anthropic messages API has no audio
|
|
172
|
-
input block type → clean 400 with a pointer to the OpenAI endpoint;
|
|
173
|
-
documented.
|
|
174
|
-
- **Docs land in the SAME commit** (standing rule):
|
|
175
|
-
`docs/reference/server-api.md` (content-part schema, ≤30 s / 750
|
|
176
|
-
soft-token cap, 16 kHz mono internal format),
|
|
177
|
-
`docs/reference/features-matrix.md` (audio row incl. serial-lane
|
|
178
|
-
note), README capability line, `cli.md` only if a flag appears
|
|
179
|
-
(target: none).
|
|
180
|
-
|
|
181
|
-
### 3.3 Open questions — RESOLVED against the oracle sources (2026-07-07)
|
|
182
|
-
|
|
183
|
-
1. **LM attention semantics for audio tokens: strictly CAUSAL.**
|
|
184
|
-
`language.py:484–545 _make_masks`: the blockwise bidirectional overlay
|
|
185
|
-
keys off `is_vision = (mm_token_type_ids == 1) | (== 2)` only — audio
|
|
186
|
-
(type 3) never enters a block. Stronger: `use_bidirectional_vision`
|
|
187
|
-
requires `not has_audio_tokens`, so **any audio token in the prompt
|
|
188
|
-
disables the vision overlay entirely** (oracle comment: "Audio spans
|
|
189
|
-
are sequential; keep mixed image+audio prompts causal"). mlx-bun rule:
|
|
190
|
-
audio runs get NO bidir mask, and a mixed image+audio request drops
|
|
191
|
-
the image bidir mask too — pass no bidir mask at all in that case.
|
|
192
|
-
2. **Per-layer-input zeroing: yes, audio included.** `gemma4.py:92–99`
|
|
193
|
-
zeroes per-layer ids for the union mask
|
|
194
|
-
`(ids==image_token) | (ids==audio_token) | (ids==video_token)`.
|
|
195
|
-
Extend the existing image-mask zeroing in
|
|
196
|
-
`src/model/gemma4.ts:876–896` to the combined multimodal mask.
|
|
197
|
-
3. **Per-bin mel stats: constructor defaults, no normalization.**
|
|
198
|
-
`processing_gemma4.py:919–934`: standard HF checkpoints ship no
|
|
199
|
-
`feature_extractor` key (our e4b snapshot has no
|
|
200
|
-
processor_config.json at all) → `Gemma4AudioFeatureExtractor()` with
|
|
201
|
-
defaults; "the USM parameters are fixed for all Gemma 4 models".
|
|
202
|
-
`per_bin_mean/stddev = None` → that branch is dead for us. Also
|
|
203
|
-
pinned there: `audio_seq_length` default 750, `audio_ms_per_token`
|
|
204
|
-
default 40.
|
|
205
|
-
4. **boa/eoa are splice-side.** e4b `chat_template.jinja:301,334` emits
|
|
206
|
-
bare `<|audio|>` for audio parts (both content shapes); the
|
|
207
|
-
boa + audio×n + eoa expansion is processor-side — same ownership as
|
|
208
|
-
vision's boi/eoi. Splice in our prompt builder, not the template.
|
|
209
|
-
|
|
210
|
-
### 3.4 Parity strategy (tree doctrine)
|
|
211
|
-
|
|
212
|
-
Oracle = optiq internal gemma4 model in the pinned venv, driven by
|
|
213
|
-
`regen-audio-goldens.py (deleted; git history)` (modeled on their calibration loader;
|
|
214
|
-
remember `enable_thinking` pinning for any templated prompt). Tiers follow
|
|
215
|
-
the e4b vision precedent exactly:
|
|
216
|
-
|
|
217
|
-
- **T0 model-free** (CI, no weights): WAV decode + mel features vs
|
|
218
|
-
oracle-dumped golden (f32 tolerance ~1e-5 — DSP is deterministic);
|
|
219
|
-
spliced ids **exact**; soft-token count **exact**.
|
|
220
|
-
- **T1 golden tower**: `audio_tower`+`embed_audio` output vs oracle,
|
|
221
|
-
rel-RMSE gate (expect vision-like ~1% from bf16 composition; calibrate
|
|
222
|
-
the threshold from the first honest run, don't invent it).
|
|
223
|
-
- **T2 e2e greedy** (`tests/e4b-audio.test.ts`): first-N greedy prefix
|
|
224
|
-
match vs oracle + grounded-output check (speech fixture → transcript
|
|
225
|
-
keyword present; chirp fixture → tone/beep mentioned).
|
|
226
|
-
- **T3 serve**: curl e2e with base64 `input_audio` against a running
|
|
227
|
-
server (manual/gated; Josh runs servers).
|
|
228
|
-
|
|
229
|
-
Fixtures (tracked in `fixtures/`, tiny): (a) 1.6 s synthesized chirp WAV
|
|
230
|
-
(~50 KB, generated by a checked-in deterministic script), (b) ~2 s public
|
|
231
|
-
domain speech clip (LibriSpeech clean sample, ~64 KB). Goldens:
|
|
232
|
-
`goldens/e4b-audio.json` manifest tracked, `.bin` blobs regenerable and
|
|
233
|
-
untracked (goldens/README.md convention).
|
|
234
|
-
|
|
235
|
-
### 3.5 Perf & memory
|
|
236
|
-
|
|
237
|
-
Expectation (to be *measured*, not asserted): the tower is tiny —
|
|
238
|
-
≤750 mel frames → ~≤188 post-subsample positions × 12 layers × hidden
|
|
239
|
-
1024 bf16 — so added TTFT should be dominated by CPU feature extraction
|
|
240
|
-
plus one extra graph eval; sidecar RSS delta is the 752 bf16 tensors.
|
|
241
|
-
Every number that gets quoted comes from preflight-gated `scripts/bench-serve.ts all`
|
|
242
|
-
cells (tower ms, TTFT delta vs text-only, peak RSS delta) and lands in
|
|
243
|
-
`benchmarks/RESULTS.md`.
|
|
244
|
-
|
|
245
|
-
## 4. Work plan
|
|
246
|
-
|
|
247
|
-
**Phase A0 — groundwork**
|
|
248
|
-
- [ ] Bind `mlx_conv2d` (full header signature; CPU/GPU sanity test vs
|
|
249
|
-
oracle conv output)
|
|
250
|
-
- [ ] `regen-audio-goldens.py (deleted; git history)` + fixtures; dump mel golden,
|
|
251
|
-
tower-output golden, spliced ids, greedy ids
|
|
252
|
-
- [ ] Resolve open questions §3.3 (write the answers into this doc)
|
|
253
|
-
- Exit: goldens on disk; masking/zeroing semantics documented.
|
|
254
|
-
|
|
255
|
-
**Phase A1 — decode + features**
|
|
256
|
-
- [ ] `src/audio/decode.ts` (WAV + mono + resample; `afconvert` fallback)
|
|
257
|
-
- [ ] `src/audio/features.ts` USM mel port
|
|
258
|
-
- Exit: T0 green (mel within tolerance; token counts + spliced ids exact).
|
|
259
|
-
|
|
260
|
-
**Phase A2 — tower**
|
|
261
|
-
- [x] `src/audio/conformer.ts` loads `audio_tower.*`/`embed_audio.*` from
|
|
262
|
-
`optiq_vision.safetensors`; forward matches golden — rel-RMSE **2.4e-8**
|
|
263
|
-
(bit-exact: the tower runs f32 activations over bf16 weights because
|
|
264
|
-
the oracle feeds f32 mel and mlx promotes; the residual is 1 f32 ulp
|
|
265
|
-
from the test's /embed_scale·embed_scale roundtrip). Sidecar conv
|
|
266
|
-
weights are ALREADY MLX layout [C_out,kH,kW,C_in] — no transpose.
|
|
267
|
-
Golden reference point: embed_audio output BEFORE the /embed_scale
|
|
268
|
-
pre-division; features() returns pre-divided (vision convention).
|
|
269
|
-
- [x] Clipped-linear toggle test (off → 90% rel-RMSE divergence, on → gate;
|
|
270
|
-
in tests/e4b-audio-tower.test.ts)
|
|
271
|
-
- Exit: T1 rel-RMSE gate green. ✅ (gate 1e-6, ~40× margin)
|
|
272
|
-
|
|
273
|
-
**Phase A3 — prompt + LM integration**
|
|
274
|
-
- [x] Generalize prompt builder (images + audio, document order):
|
|
275
|
-
`buildMultimodalPrompt` in src/vision/prompt.ts; `<|audio|>` →
|
|
276
|
-
`boa + audio×n + eoa`; `buildVisionPrompt` kept as a byte-identical
|
|
277
|
-
wrapper (vision goldens green, e4b-vision 3/3).
|
|
278
|
-
- [x] Merged embeddings + masks; per-layer id zeroing per Q2 decoupled from
|
|
279
|
-
the bidir overlay (`forwardEmbeddings` gained an optional `multimodal`
|
|
280
|
-
zeroing mask; generate() `multimodalMask` option). Merge numerics are
|
|
281
|
-
oracle-exact: the divide happens AFTER the bf16 cast with a weak
|
|
282
|
-
(bf16) embed_scale scalar — `AudioTower.features(preDivide=false)` +
|
|
283
|
-
astype + div, mirroring `features.astype(bf16) / embed_scale` (mlx
|
|
284
|
-
weak scalars take the array dtype; divide-in-f32-then-cast is up to a
|
|
285
|
-
bf16 ulp off and fails the exact gate).
|
|
286
|
-
- Exit: T2 green — and stronger than planned: the FULL greedy stream +
|
|
287
|
-
decoded text match the oracle EXACTLY for both fixtures (the tower is
|
|
288
|
-
bit-exact, so no prefix allowance was needed; generate()'s
|
|
289
|
-
promptEmbeddings path prefills in one forward exactly like the golden
|
|
290
|
-
script — no tail-split gap). `tests/e4b-audio.test.ts`.
|
|
291
|
-
|
|
292
|
-
**Phase A4 — serve + docs**
|
|
293
|
-
- [x] `src/server.ts` audio branch, lazy tower, serial-lane routing,
|
|
294
|
-
mixed image+audio request handled. `hasAudio` detection over the
|
|
295
|
-
three part shapes; `makeAudioLoader`/`getAudioTower` mirror vision
|
|
296
|
-
(same sidecar, zero flags, auto-enable on `audio_config` +
|
|
297
|
-
sidecar) — but a request WITH audio on a towerless model is an
|
|
298
|
-
explicit 400 naming the model, never a silent text-only degrade.
|
|
299
|
-
The gateway's `Vision` payload generalized to
|
|
300
|
-
`{embeddings, imageMask?, multimodalMask?}` (bidirMask stays null
|
|
301
|
-
whenever audio is present, §3.3 Q1); `shape.hasVision = !!payload`
|
|
302
|
-
routes every media request serial and skips the prompt cache —
|
|
303
|
-
verified live: `/stats` batch.submitted_rows stays 0 for audio
|
|
304
|
-
while a concurrent text request advances it (batch default 8).
|
|
305
|
-
Non-WAV containers (mp3/m4a/flac/ogg/aiff) transcode via
|
|
306
|
-
`afconvert` (src/audio/transcode.ts, RIFF-sniffed content-based
|
|
307
|
-
passthrough, temp files under os.tmpdir(), clear 400 on failure);
|
|
308
|
-
>30 s clips truncate at 480 000 samples in decodeAudio — the
|
|
309
|
-
oracle feature extractor's own default (truncation=True,
|
|
310
|
-
max_length=480_000) verified in audio_feature_extractor.py:302.
|
|
311
|
-
/v1/messages (Anthropic) rejects smuggled audio blocks with a 400
|
|
312
|
-
pointing to the OpenAI endpoint (protocol has no audio block).
|
|
313
|
-
- [x] server-api.md (schema + curl + caps + 400s + lane note) /
|
|
314
|
-
features-matrix.md (audio row + footnote: mlx-lm strips it, optiq
|
|
315
|
-
never serves it — we expose it) / README capability line, same
|
|
316
|
-
change set; Anthropic endpoint 400 documented.
|
|
317
|
-
- [x] capability discovery (post-merge CodeRabbit follow-up, 2026-07-07):
|
|
318
|
-
`audio` flag mirrors `vision` on every surface — /v1/models served
|
|
319
|
-
row, /library rows (`audioCapable` in src/registry.ts:
|
|
320
|
-
`has_audio_config AND has_audio_tower`, header-only sidecar scan),
|
|
321
|
-
and the pi ws `ready` frame. The predicate checks TENSORS, not just
|
|
322
|
-
config: the 12B stub sidecar (audio_config + embed_audio-only) reads
|
|
323
|
-
audio=false, and `makeAudioLoader` header-checks the sidecar so the
|
|
324
|
-
runtime flag can't lie either. Discovery-only in pi land — pi's
|
|
325
|
-
`Model.input` type has no "audio" modality to declare.
|
|
326
|
-
- Exit: T3 green — `tests/e4b-audio-serve.test.ts`
|
|
327
|
-
(MLX_BUN_TEST_AUDIO_SERVE=1): base64 WAV over
|
|
328
|
-
/v1/chat/completions returns the EXACT golden transcription
|
|
329
|
-
("The quick brown fox jumps over the lazy dog.", 83 prompt /
|
|
330
|
-
11 completion tokens); m4a transcode path transcribes; malformed
|
|
331
|
-
part, undecodable bytes, and Anthropic audio block all 400.
|
|
332
|
-
docs-map hygiene green. ✅ 2026-07-07
|
|
333
|
-
|
|
334
|
-
**Phase A5 — bench + coverage**
|
|
335
|
-
- [ ] scripts/bench-serve.ts all cells → RESULTS.md (tower ms, TTFT delta, RSS delta)
|
|
336
|
-
- [ ] 12B audio cell: rebuild its sidecar via optiq `build_vision_sidecar`
|
|
337
|
-
(selective download), own goldens — per-model doctrine, every
|
|
338
|
-
(model, quant) cell gets its own validation or an explicit deferral
|
|
339
|
-
- [ ] features-matrix: audio×batching = serial documented
|
|
340
|
-
- Exit: numbers curated; e4b cell validated; 12B validated or deferred
|
|
341
|
-
with reason.
|
|
342
|
-
|
|
343
|
-
Sizing: A0–A4 ≈ 3–4 focused sessions (the tower is the only genuinely new
|
|
344
|
-
model code; everything else is seam reuse); A5 ≈ 1.
|
|
345
|
-
|
|
346
|
-
## 5. Non-goals (v1)
|
|
347
|
-
|
|
348
|
-
- TTS, STS, and `/v1/audio/transcriptions`-style endpoints — a
|
|
349
|
-
transcription shim over this same path is a cheap follow-up, noted, not
|
|
350
|
-
committed.
|
|
351
|
-
- Streaming/real-time audio input.
|
|
352
|
-
- >30 s audio: cap at 750 soft tokens exactly as the oracle does.
|
|
353
|
-
- Video (`mm_token_type_ids=2`) — same seams, explicitly later.
|
|
354
|
-
- Audio for 26B-A4B / DiffusionGemma / bf16 assistants (no
|
|
355
|
-
`audio_config` in those snapshots — architectural, not deferred work).
|
|
356
|
-
- Batched audio prefill (novel territory; serial lane only in v1).
|
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
# Fine-tuning experiment: chunking task (2026-06-16)
|
|
2
|
-
|
|
3
|
-
Goal (from Josh): test mlx-bun's fine-tuning end-to-end on lucien's conversation-
|
|
4
|
-
chunking task — baseline → LoRA fine-tune → re-measure the quality delta.
|
|
5
|
-
|
|
6
|
-
## Headline result
|
|
7
|
-
|
|
8
|
-
A LoRA fine-tune of **MiniCPM5-1B** on the chunk task, trained and served entirely
|
|
9
|
-
by mlx-bun, on the 25-case frozen holdout (`lucien/benchmark/dataset/chunk.json`),
|
|
10
|
-
scored with lucien's exact `scoreChunk` metric:
|
|
11
|
-
|
|
12
|
-
| Metric | Baseline (stock) | Fine-tuned | Δ |
|
|
13
|
-
|---|---|---|---|
|
|
14
|
-
| **Mean score / 100** | **11.89** | **91.70** | **+79.8 (6.7×)** |
|
|
15
|
-
| Valid JSON | 12% (3/25) | 100% (25/25) | +88 |
|
|
16
|
-
| schema | 100% | 100% | — |
|
|
17
|
-
| anchors | 97% | 78% | −19 |
|
|
18
|
-
| labels | 100% | 96% | −4 |
|
|
19
|
-
| nonempty | 100% | 100% | — |
|
|
20
|
-
|
|
21
|
-
The baseline failure was pure **format**: the stock 1B model rambled past the token
|
|
22
|
-
limit without emitting parseable JSON on 88% of cases. After fine-tuning, every case
|
|
23
|
-
emits valid, well-formed chunk JSON and **stops** (68–456 generated tokens vs the
|
|
24
|
-
baseline hitting the 1536 cap). This validates the full mlx-bun pipeline:
|
|
25
|
-
**train (ops.sdpa) → save adapter (hot-swap format) → `AdapterManager.mount` → generate.**
|
|
26
|
-
|
|
27
|
-
## Why not e4b (the original target)
|
|
28
|
-
|
|
29
|
-
The original plan targeted `gemma-4-e4b-it-OptiQ-4bit`. The chunk data is long
|
|
30
|
-
(median 4092 tokens, 0% ≤2048, 98% ≤8192), so it needs 4–8K training context. On
|
|
31
|
-
this **32 GB M1 Max**, neither mlx-bun NOR the optiq reference can train a 7.4B-param
|
|
32
|
-
model at that length: I ran optiq's own `train_lora` on e4b and it completed only at
|
|
33
|
-
seq 512 (peak 18.24 GB, degenerate — 0 response tokens survive truncation) and
|
|
34
|
-
**crashed at 2048/4096/8192** with `[METAL] Command buffer execution failed: Impacting
|
|
35
|
-
Interactivity` — a memory-pressure GPU stall. It's a hardware ceiling, not a code gap.
|
|
36
|
-
Pivoted to **MiniCPM5-1B** (24 layers, head_dim 128, full attention), which fits 4–8K
|
|
37
|
-
training comfortably. See [[e4b-lora-training-seqlen-ceiling]].
|
|
38
|
-
|
|
39
|
-
## Correctness correction: ops.sdpa vs flash
|
|
40
|
-
|
|
41
|
-
Earlier in the session I concluded mlx-bun's `ops.sdpa` had a wrong dK gradient and
|
|
42
|
-
built/routed a flash kernel as the "correct" training attention. **That was backwards.**
|
|
43
|
-
A clean check (`scripts/sdpa-vs-manual.ts`) against **mlx-autograd of a plain
|
|
44
|
-
matmul/softmax forward** (the unimpeachable ground truth) shows:
|
|
45
|
-
|
|
46
|
-
```
|
|
47
|
-
dQ: sdpa-vs-manual= 0.00% flash-vs-manual= 0.06%
|
|
48
|
-
dK: sdpa-vs-manual= 0.00% flash-vs-manual= 106.01% ← flash is the broken one
|
|
49
|
-
dV: sdpa-vs-manual= 0.00% flash-vs-manual= 0.02%
|
|
50
|
-
```
|
|
51
|
-
|
|
52
|
-
`ops.sdpa` is correct (and fast — one fused kernel). My flash dK kernel is the buggy
|
|
53
|
-
one; the earlier triangulation was fooled by a hand-derived FA-2 backward reference that
|
|
54
|
-
shares the dK formula with the flash kernel. The trainer now defaults to `ops.sdpa`
|
|
55
|
-
(flash opt-in via `MLX_BUN_TRAIN_ATTN=flash`). ops.sdpa's only downside is O(seq²)
|
|
56
|
-
backward memory — fine at ≤4096 for a 1B model (crashes ~8192 on long examples).
|
|
57
|
-
|
|
58
|
-
## Caveats (honest)
|
|
59
|
-
|
|
60
|
-
- **The benchmark metric is intrinsic** (JSON validity / schema / anchor resolution /
|
|
61
|
-
label quality), not segmentation-F1 vs gold boundaries. The +79.8 reflects "produces
|
|
62
|
-
valid, well-formed output," which is exactly what was broken.
|
|
63
|
-
- **anchors 97%→78%**: the fine-tuned model occasionally emits an anchor UUID that needs
|
|
64
|
-
prefix-repair; one 47K-token case failed to resolve (score 50).
|
|
65
|
-
- **Under-segmentation**: the fine-tuned model emits 1 chunk on most conversations. The
|
|
66
|
-
training data was filtered to ≤4000 tokens (730/1375 examples) for speed, biasing
|
|
67
|
-
toward shorter single-topic conversations. Training on the full data at 8192 (or with
|
|
68
|
-
the flash dK fixed for O(L) memory) would likely improve multi-chunk segmentation.
|
|
69
|
-
|
|
70
|
-
## Reproduce
|
|
71
|
-
|
|
72
|
-
```bash
|
|
73
|
-
# baseline
|
|
74
|
-
bun scripts/chunk-eval.ts # 11.89/100
|
|
75
|
-
# filter data, fine-tune, re-measure
|
|
76
|
-
MAXTOK=4000 bun scripts/chunk-filter.ts
|
|
77
|
-
DATA=~/.cache/mlx-bun-finetunes/chunk-data-le4000 SEQ=4096 ITERS=300 \
|
|
78
|
-
ADAPTER=~/.cache/mlx-bun-finetunes/minicpm5-chunk-final bun scripts/chunk-finetune.ts
|
|
79
|
-
ADAPTER=~/.cache/mlx-bun-finetunes/minicpm5-chunk-final bun scripts/chunk-eval.ts # 91.70/100
|
|
80
|
-
```
|
|
81
|
-
|
|
82
|
-
Training: 300 iters, seq 4096, rank 16, lr 2e-4, ops.sdpa, ~26 min, peak 25.47 GB, val
|
|
83
|
-
loss flat ~0.19 (no overfit). Scripts: `chunk-eval.ts`, `chunk-filter.ts`,
|
|
84
|
-
`chunk-finetune.ts`, `sdpa-vs-manual.ts`.
|