mlx-bun 0.3.0 → 0.5.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 +57 -32
- package/docs/README.md +58 -42
- package/docs/archive/investigations/benchmark-ledger-through-v0.4.0.md +3617 -0
- package/docs/archive/investigations/openjarvis-fit.md +198 -0
- package/docs/archive/investigations/qwen38-27b-campaign-log.md +1092 -0
- package/docs/archive/planning/release-notes-v0.4.0.md +45 -0
- package/docs/archive/planning/release-notes-v0.5.0.md +37 -0
- package/docs/design/batching.md +1535 -50
- package/docs/design/decode-speed-program.md +394 -1171
- package/docs/design/generic-model-support.md +195 -3
- package/docs/design/kv-cache.md +538 -225
- package/docs/design/speculative-decoding.md +552 -50
- package/docs/design/turboquant.md +140 -17
- package/docs/design/unified-engine-frontier-plan.md +259 -150
- package/docs/planning/PRODUCT_ROADMAP.md +21 -6
- package/docs/planning/public-readiness-handoff.md +244 -0
- package/docs/planning/public-readiness.md +149 -0
- package/docs/reference/benchmarks.md +3537 -1112
- package/docs/reference/cli.md +102 -2
- package/docs/reference/distribution.md +45 -13
- package/docs/reference/environment.md +159 -13
- package/docs/reference/library-api.md +18 -4
- package/docs/reference/memory.md +1 -1
- package/docs/reference/models.md +28 -7
- package/docs/reference/server-api.md +257 -33
- package/docs/reference/server-config.md +372 -151
- package/docs/reference/troubleshooting.md +13 -21
- package/package.json +2 -2
- package/src/audio/audiotoolbox.ts +112 -0
- package/src/audio/conformer.ts +8 -0
- package/src/audio/mic-capture.ts +98 -0
- package/src/audio/silero-vad.ts +379 -0
- package/src/audio/whisper-decode.ts +774 -0
- package/src/audio/whisper-fast.ts +732 -0
- package/src/audio/whisper-format.ts +73 -0
- package/src/audio/whisper-mel.ts +185 -0
- package/src/audio/whisper-timing.ts +274 -0
- package/src/audio/whisper-tokenizer.ts +239 -0
- package/src/audio/whisper-transcribe.ts +410 -0
- package/src/backends/mlx/assistant-target.ts +46 -0
- package/src/backends/mlx/autoregressive-draft-rows.ts +120 -0
- package/src/backends/mlx/autoregressive.ts +22 -1
- package/src/backends/mlx/batch-group.ts +464 -236
- package/src/backends/mlx/cache-attachment.ts +67 -0
- package/src/backends/mlx/cache-layout.ts +31 -0
- package/src/backends/mlx/checkpoint-state.ts +53 -0
- package/src/backends/mlx/continuation-persistence.ts +107 -0
- package/src/backends/mlx/continuation-request.ts +43 -0
- package/src/backends/mlx/continuation.ts +77 -0
- package/src/backends/mlx/draft-target.ts +7 -22
- package/src/backends/mlx/encoder-cache.ts +25 -0
- package/src/backends/mlx/fill-append.ts +21 -8
- package/src/backends/mlx/fill-group.ts +497 -0
- package/src/backends/mlx/full-kv-row-append.ts +32 -0
- package/src/backends/mlx/full-kv-row-donor.ts +54 -0
- package/src/backends/mlx/full-transitioning-kv-rows.ts +65 -0
- package/src/backends/mlx/gateway-binding.ts +122 -19
- package/src/backends/mlx/kv-codec.ts +9 -0
- package/src/backends/mlx/kv-maintenance.ts +161 -0
- package/src/backends/mlx/kv-tensor-rows.ts +212 -0
- package/src/backends/mlx/mixed-iteration.ts +62 -0
- package/src/backends/mlx/model-prompt.ts +46 -32
- package/src/backends/mlx/model-serving.ts +5 -4
- package/src/backends/mlx/paged-cache-codec.ts +27 -0
- package/src/backends/mlx/prefill-cohort.ts +100 -0
- package/src/backends/mlx/prefill-policy.ts +26 -0
- package/src/backends/mlx/prefill-rows.ts +244 -0
- package/src/backends/mlx/prefill.ts +1 -1
- package/src/backends/mlx/projected-context-rows.ts +72 -0
- package/src/backends/mlx/prompt-input.ts +29 -0
- package/src/backends/mlx/qwen-prompt-input.ts +40 -0
- package/src/backends/mlx/request-state-policy.ts +54 -0
- package/src/backends/mlx/rollback.ts +45 -4
- package/src/backends/mlx/row-sampling.ts +49 -0
- package/src/backends/mlx/serial-executor.ts +51 -73
- package/src/backends/mlx/speculative-group.ts +438 -0
- package/src/backends/mlx/speculative-round.ts +161 -0
- package/src/backends/mlx/speculative.ts +24 -7
- package/src/backends/mlx/state-rows.ts +104 -0
- package/src/backends/mlx/state-views.ts +21 -1
- package/src/backends/mlx/target-layout-capability.ts +35 -0
- package/src/backends/mlx/transitioning-kv-rows.ts +173 -0
- package/src/cli.ts +333 -36
- package/src/contracts/execution.ts +21 -0
- package/src/contracts/object-cache.ts +8 -0
- package/src/contracts/pi-provider.ts +1 -1
- package/src/contracts/pi.ts +3 -1
- package/src/contracts/prefix-cache.ts +33 -0
- package/src/contracts/resources.ts +7 -0
- package/src/contracts/sampling.ts +23 -0
- package/src/contracts/scheduling.ts +27 -0
- package/src/engine/execution-plan.ts +38 -25
- package/src/engine/execution-tasks.ts +44 -0
- package/src/engine/namespaced-cache.ts +13 -0
- package/src/engine/resources.ts +12 -1
- package/src/engine/scheduler.ts +32 -7
- package/src/fill/fill-session.ts +14 -3
- package/src/fit.ts +29 -15
- package/src/generate.ts +105 -195
- package/src/grammar.ts +13 -0
- package/src/inference/draft-acceptance.ts +41 -0
- package/src/inference/draft-output.ts +49 -0
- package/src/inference/prefill.ts +6 -0
- package/src/inference/rollback.ts +2 -2
- package/src/kv-scheme.ts +92 -12
- package/src/kv-store.ts +183 -93
- package/src/lab/README.md +5 -1
- package/src/lab/paged-kv/paged-attention.ts +117 -0
- package/src/lab/paged-kv/paged-kv-rows.ts +111 -0
- package/src/lab/paged-kv/paged-kv.ts +126 -46
- package/src/md-modules.d.ts +5 -0
- package/src/mlx/array.ts +39 -1
- package/src/mlx/ffi.ts +19 -0
- package/src/mlx/normalized-argmax.ts +116 -0
- package/src/mlx/ops.ts +97 -10
- package/src/model/artifact-identity.ts +73 -0
- package/src/model/batched-kv.ts +235 -0
- package/src/model/batched-mask.ts +12 -4
- package/src/model/batched-quant.ts +8 -2
- package/src/model/batched-quantized-kv.ts +144 -0
- package/src/model/batched-rotating-quant.ts +76 -15
- package/src/model/batched-rotating-state.ts +76 -0
- package/src/model/batched-rotating.ts +64 -22
- package/src/model/batched-row-storage.ts +52 -0
- package/src/model/batched-ssm.ts +52 -0
- package/src/model/batched-turboquant-kv.ts +94 -0
- package/src/model/compiled-decode.ts +7 -1
- package/src/model/decoded-kv-donor.ts +12 -0
- package/src/model/delayed-quantized-kv.ts +72 -0
- package/src/model/delayed-rotating-quantized-kv.ts +93 -0
- package/src/model/delayed-turboquant-kv.ts +57 -0
- package/src/model/factory.ts +26 -0
- package/src/model/fingerprint.ts +12 -0
- package/src/model/full-prefill-padding.ts +56 -0
- package/src/model/full-prefill-row.ts +105 -0
- package/src/model/gemma4-base.ts +183 -82
- package/src/model/gemma4.ts +116 -28
- package/src/model/generated/gemma4-12b.ts +4 -1
- package/src/model/generated/gemma4-26b.ts +4 -1
- package/src/model/generated/gemma4-e4b.ts +4 -1
- package/src/model/glm52-cache.ts +80 -4
- package/src/model/glm52-mla.ts +12 -6
- package/src/model/glm52.ts +19 -40
- package/src/model/kv-attention-view.ts +70 -0
- package/src/model/minicpm5.ts +11 -7
- package/src/model/profile.ts +29 -4
- package/src/model/quantized-append-attention.ts +31 -0
- package/src/model/qwen3-delta-state.ts +74 -0
- package/src/model/qwen3-delta.ts +59 -36
- package/src/model/qwen3-mrope.ts +7 -9
- package/src/model/qwen3_5.ts +177 -75
- package/src/model/rotating-kv-donor.ts +35 -0
- package/src/model/rotating-kv-layout.ts +262 -0
- package/src/model/rotating-row-transaction.ts +35 -0
- package/src/model/speculative-rotating-kv.ts +101 -0
- package/src/model/ssm-prefill-padding.ts +39 -0
- package/src/model/support.ts +8 -0
- package/src/model/token-groups.ts +66 -0
- package/src/model/trellis-linear.ts +4 -4
- package/src/model/turboquant-codec.ts +89 -0
- package/src/model/universal/dense.ts +14 -13
- package/src/model/whisper.ts +435 -0
- package/src/native/mic_capture.swift +92 -0
- package/src/native-pack.ts +6 -5
- package/src/pi-web.ts +9 -1
- package/src/preflight.ts +31 -15
- package/src/prompt-cache.ts +306 -86
- package/src/runtime-config.ts +1 -5
- package/src/safetensors.ts +9 -2
- package/src/sampler.ts +37 -25
- package/src/serve/audio-routes.ts +323 -0
- package/src/serve/chat-request.ts +2 -0
- package/src/serve/chat-stage.ts +19 -14
- package/src/serve/completion-executor.ts +9 -1
- package/src/serve/discovery-routes.ts +17 -1
- package/src/serve/generated-token-history.ts +57 -0
- package/src/serve/generation-gateway.ts +88 -38
- package/src/serve/model-binding.ts +7 -1
- package/src/serve/model-host.ts +3 -4
- package/src/serve/preparation.ts +3 -3
- package/src/serve/prompt-response-trace.ts +14 -0
- package/src/serve/request-plan.ts +6 -3
- package/src/serve/request-prep.ts +40 -25
- package/src/serve/text-completion-stage.ts +2 -2
- package/src/serve/transcription-server.ts +64 -0
- package/src/serve/transcription-service.ts +502 -0
- package/src/server.ts +185 -261
- package/src/spec/assistant-rows.ts +93 -0
- package/src/spec/assistant-source.ts +28 -18
- package/src/spec/cache-identity.ts +22 -0
- package/src/spec/deepspec-rows.ts +29 -0
- package/src/spec/deepspec-source.ts +12 -10
- package/src/spec/dflash-source.ts +28 -4
- package/src/spec/drafter.ts +153 -142
- package/src/spec/dspark/deepspec-module.ts +95 -120
- package/src/spec/dspark/module-dflash.ts +126 -170
- package/src/spec/glm52-mtp-graph.ts +29 -0
- package/src/spec/glm52-mtp-rows.ts +132 -0
- package/src/spec/glm52-mtp-source.ts +54 -136
- package/src/spec/glm52-mtp-state.ts +33 -0
- package/src/spec/ngram-source.ts +115 -21
- package/src/spec/projected-draft-rows.ts +73 -0
- package/src/spec/qwen-mtp-module.ts +171 -0
- package/src/spec/qwen-mtp-rows.ts +230 -0
- package/src/spec/qwen-mtp-source.ts +84 -226
- package/src/spec/qwen-mtp-state.ts +30 -0
- package/src/spec/serve-loop.ts +73 -69
- package/src/spec/source.ts +93 -15
- package/src/spec/two-model-rows.ts +62 -0
- package/src/spec/two-model.ts +45 -103
- package/src/ssd-cache.ts +107 -36
- package/src/ssd-durability.ts +29 -27
- package/src/storage/host-buffer.ts +24 -0
- package/src/storage/kv-writer.ts +83 -0
- package/src/storage/kv-writer.worker.js +264 -0
- package/src/storage/retention-policy.ts +37 -0
- package/src/tiered-prompt-cache.ts +45 -0
- package/src/vision/embedder.ts +8 -0
- package/src/vision/prompt.ts +101 -65
- package/src/vision/qwen3vl-prompt.ts +101 -64
- package/src/vision/qwen3vl-tower.ts +11 -0
- package/src/vision/siglip.ts +8 -0
- package/src/web/app.html +12 -0
- package/src/web/app.js +217 -57
- package/src/web/src/chat.ts +4 -1
- package/src/web/src/composer.ts +3 -0
- package/src/web/src/voice.ts +141 -0
- package/src/web/sw.js +1 -1
- package/src/backends/mlx/memory-guard.ts +0 -40
- package/src/spec/prefix-state.ts +0 -45
- /package/docs/{planning → archive/planning}/release-notes-v0.3.0.md +0 -0
package/docs/reference/cli.md
CHANGED
|
@@ -29,6 +29,8 @@ each verb).
|
|
|
29
29
|
| `harness pi` | connect your own pi install to the local server | — |
|
|
30
30
|
| `generate` (`gen`) | one-shot generation, no server | `mlx_lm.generate` |
|
|
31
31
|
| `embed` | text embeddings, no server | — |
|
|
32
|
+
| `transcribe` | speech-to-text from an audio file, no server | — (`mlx_whisper` CLI is the nearest) |
|
|
33
|
+
| `dictate` | push-to-talk microphone dictation → print / clipboard / typed keystrokes | — |
|
|
32
34
|
| `get` | download a model (resumable, verified) | `mlx_lm.manage` (partial) |
|
|
33
35
|
| `scan` | re-index the Hugging Face cache | `mlx_lm.manage --scan` |
|
|
34
36
|
| `ls` | list downloaded models | `mlx_lm.manage --scan` |
|
|
@@ -64,6 +66,24 @@ mlx-bun serve GLM-5.2 --context-length 4096
|
|
|
64
66
|
semantics, and which combinations compose live in
|
|
65
67
|
**[server-config.md](server-config.md)** — this page only names them.
|
|
66
68
|
|
|
69
|
+
Library requests support delayed uniform or per-layer affine conversion with
|
|
70
|
+
qualified shared drafting providers, including rotating caches. CLI affine
|
|
71
|
+
quantization starts at zero.
|
|
72
|
+
|
|
73
|
+
The shared executor supports qualified Qwen MTP and start-zero
|
|
74
|
+
TurboQuant at one or several active rows; `--batch 1` still selects the
|
|
75
|
+
legacy serial control. No new CLI flag is required for the shared interfaces.
|
|
76
|
+
Full-attention and rotating targets, including Llama, MiniCPM and Gemma, use shared bf16, uniform KV4/KV8, per-layer affine KV or TurboQuant
|
|
77
|
+
prompt lookup and standalone drafting, including generated RAM/SSD state.
|
|
78
|
+
Gemma assistant drafting also shares these target layouts and caches its last true target
|
|
79
|
+
hidden alongside target KV through the same RAM/SSD interfaces.
|
|
80
|
+
DeepSpec and DSpark use the same executor and persist their projected context through those
|
|
81
|
+
interfaces. DeepSpec accepts bf16 or affine-quantized weights; DSpark retains
|
|
82
|
+
its Markov/RNN head and checkpoint confidence policy.
|
|
83
|
+
|
|
84
|
+
Shared Qwen MTP retains completed decode state through the existing
|
|
85
|
+
`--prompt-cache` and `--ssd-cache` settings.
|
|
86
|
+
|
|
67
87
|
| Group | Flags |
|
|
68
88
|
|---|---|
|
|
69
89
|
| Network | `--host`, `--port`, `--no-open`, `--allow-private-media` |
|
|
@@ -71,13 +91,17 @@ semantics, and which combinations compose live in
|
|
|
71
91
|
| Process model | `--isolate`, `--model-pool`, `--unix` (internal — the engine half of `--isolate`) |
|
|
72
92
|
| Scheduling | `--batch` (`--decode-concurrency` accepted as the mlx_lm.server alias) |
|
|
73
93
|
| KV cache | `--kv-quant`, `--paged-kv`, `--paged-kv-block-size` |
|
|
74
|
-
| Adapters | `--adapter` (`--adapter-path` alias) |
|
|
75
|
-
| Speculative decoding | `--draft-model`, `--draft-kind`, `--num-draft-tokens`, `--ngram-max`, `--ngram-min` |
|
|
94
|
+
| Adapters (compatible sets can batch) | `--adapter` (`--adapter-path` alias) |
|
|
95
|
+
| Speculative decoding (Qwen methods and full-attention/rotating lookup/standalone and Gemma assistant/DeepSpec/DSpark drafting share execution) | `--draft-model`, `--draft-kind`, `--num-draft-tokens`, `--ngram-max`, `--ngram-min` |
|
|
76
96
|
| GLM-5.2 | `--mtp`, `--context-length` |
|
|
77
97
|
| Sampling defaults | `--temperature` (`--temp` alias), `--top-p`, `--top-k`, `--max-tokens`, `--thinking`, `--hlg-sampling`, `--hlg-width`, `--hlg-shoulder`, `--hlg-toe`, `--hlg-pivot-offset` |
|
|
78
98
|
| Parity tier | `--l1`, `--l2` (`--l3` errors — removed) |
|
|
79
99
|
| Kill switches | `--compiled-decode`, `--compiled-activations`, `--fused-sdpa`, `--force-wire`, `--expert-offload` |
|
|
80
100
|
|
|
101
|
+
Serving treats memory estimates as advisory by default and attempts the request.
|
|
102
|
+
`--memory-budget` opts into estimated admission limits; `--kv-budget` opts
|
|
103
|
+
into aggregate KV limits. `--max-tokens` supplies an explicit output cap.
|
|
104
|
+
|
|
81
105
|
Endpoints: `/v1/chat/completions`, `/v1/completions`, `/v1/messages`,
|
|
82
106
|
`/v1/responses`, `/v1/embeddings`, `/v1/models`, `/v1/adapters`, `/health`,
|
|
83
107
|
`/stats`, `/fit`, `/library`, `/downloads`; the web app at `/` (`/chat`,
|
|
@@ -191,6 +215,65 @@ mlx-bun embed --instruct "Retrieve passages that answer the question" --text "wh
|
|
|
191
215
|
| `[query]` / `--query <q>` | embedding model; omitted = the first downloaded embedding model (errors with a `get` suggestion when none) |
|
|
192
216
|
| `--text "…"` | text to embed (omit to read one text per stdin line) |
|
|
193
217
|
| `--instruct "…"` | Qwen3-Embedding query instruction; omit for plain document embeddings |
|
|
218
|
+
|
|
219
|
+
### `transcribe` — speech-to-text
|
|
220
|
+
|
|
221
|
+
Whisper transcription of one audio file with a local `mlx-community/whisper-*`
|
|
222
|
+
checkpoint, no server. WAV decodes natively; other containers CoreAudio can
|
|
223
|
+
read (mp3/m4a/aac/flac/ogg/aiff, mp4/mov audio…) decode in-process through
|
|
224
|
+
AudioToolbox. Model support
|
|
225
|
+
and the oracle contract: [models.md](models.md#supported-models).
|
|
226
|
+
|
|
227
|
+
```sh
|
|
228
|
+
mlx-bun transcribe meeting.m4a # first downloaded Whisper, language auto-detected
|
|
229
|
+
mlx-bun transcribe talk.wav --language en --format srt > talk.srt
|
|
230
|
+
mlx-bun transcribe note.wav --beam-size 5 --prompt "Sotto, SwiftUI, Metal" --verbose
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
| Flag | Meaning |
|
|
234
|
+
|---|---|
|
|
235
|
+
| `<audio-file>` | required positional |
|
|
236
|
+
| `[query]` / `--model <path\|query>` | Whisper model; omitted = the first downloaded `whisper` checkpoint (errors with a `get` suggestion when none) |
|
|
237
|
+
| `--language <code\|name>` | `en`, `japanese`, …; `auto` or omitted detects from the first 30 s |
|
|
238
|
+
| `--task translate` | translate to English |
|
|
239
|
+
| `--beam-size <n>` | beam search (default greedy) |
|
|
240
|
+
| `--temperature <t>` | one temperature; default is mlx-whisper's `(0, 0.2, …, 1.0)` fallback ladder gated by compression-ratio / log-prob thresholds |
|
|
241
|
+
| `--no-fallback` | temperature 0 only |
|
|
242
|
+
| `--prompt "…"` | initial prompt (vocabulary hints, up to 223 tokens are kept) |
|
|
243
|
+
| `--no-timestamps` | text-only decoding |
|
|
244
|
+
| `--no-condition` | do not feed the previous window's text as the next prompt |
|
|
245
|
+
| `--vad`, `--vad-threshold <t>`, `--vad-model <path>` | Silero VAD gate: no detected speech → empty output, Whisper never runs. Weights: `ggml-org/whisper-vad` in the HF cache (885 KB) or an explicit ggml path |
|
|
246
|
+
| `--word-timestamps` | word-level timing in `verbose_json` (`words` per segment) |
|
|
247
|
+
| `--faithful` | oracle-parity graph instead of the fast path (fused attention, compiled decoder step) |
|
|
248
|
+
| `--audio-ctx <n>` | Lab: encode only n of the 1500 encoder positions (whisper.cpp `-ac`); degrades below ~1024 |
|
|
249
|
+
| `--format <f>` | `text` (default) · `json` · `verbose_json` · `srt` · `vtt` |
|
|
250
|
+
| `--verbose` | per-segment time ranges and a realtime-factor summary on stderr |
|
|
251
|
+
|
|
252
|
+
### `dictate` — push-to-talk from the microphone
|
|
253
|
+
|
|
254
|
+
Streams the mic (AVAudioEngine sidecar `mlx-bun-mic-capture`, built from
|
|
255
|
+
`src/native/mic_capture.swift` on first use with swiftc, or shipped beside
|
|
256
|
+
the binary) into a transcription session while you speak, so every
|
|
257
|
+
finished 30 s window is transcribed during capture and the result lands
|
|
258
|
+
about one window after you stop. Silence never runs Whisper (Silero VAD).
|
|
259
|
+
macOS prompts for Microphone permission; `--hotkey` needs Input Monitoring
|
|
260
|
+
and `--type` needs Accessibility for your terminal app.
|
|
261
|
+
|
|
262
|
+
```sh
|
|
263
|
+
mlx-bun dictate # Enter starts/stops a take; prints the text
|
|
264
|
+
mlx-bun dictate --hotkey --copy # hold Right Option, transcript → clipboard
|
|
265
|
+
mlx-bun dictate --hotkey --type # …typed into the frontmost app
|
|
266
|
+
mlx-bun dictate --server http://localhost:8090 --vocabulary "Sotto,SwiftUI,Metal"
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
| Flag | Meaning |
|
|
270
|
+
|---|---|
|
|
271
|
+
| `[query]` / `--model <path\|query>` | Whisper model for in-process transcription (default: first downloaded `whisper` checkpoint) |
|
|
272
|
+
| `--server <url>` | use a running server's `/v1/audio/sessions` instead |
|
|
273
|
+
| `--hotkey [keycode]` | hold-to-talk on a macOS virtual keycode (default 61, Right Option) instead of Enter toggling |
|
|
274
|
+
| `--language`, `--beam-size`, `--prompt`, `--vocabulary "a,b"`, `--no-vad` | decoding, as for `transcribe` |
|
|
275
|
+
| `--idle-unload <s>` / `--resident` | release the weights after idle seconds (0 = after every take; default 30) or keep them loaded |
|
|
276
|
+
| `--copy` / `--type` / `--type-delay <s>` | clipboard / System Events keystrokes into the frontmost app (delay defaults to 1 s in Enter mode so you can Cmd-Tab, 0 with `--hotkey`) |
|
|
194
277
|
| `--json` | one OpenAI-style `{object:"list",data:[…]}` object instead of bare arrays |
|
|
195
278
|
|
|
196
279
|
Server equivalent: `mlx-bun serve <embedding-model>` then
|
|
@@ -469,6 +552,11 @@ and optiq reference servers and writes a dated report:
|
|
|
469
552
|
```sh
|
|
470
553
|
bun scripts/bench-serve.ts all
|
|
471
554
|
bun scripts/bench-serve.ts all --models cpm5,e4b --arms mlx-bun,mlx-lm --out report.md
|
|
555
|
+
bun scripts/bench-serve.ts all --models qwen27b --arms mlx-bun-serial,mlx-bun --logprobs --top-logprobs 3
|
|
556
|
+
# Same KV settings on both executors
|
|
557
|
+
bun scripts/bench-serve.ts all --models qwen27b --arms mlx-bun-serial,mlx-bun --kv-quant 4
|
|
558
|
+
# Same adapter settings on both execution arms:
|
|
559
|
+
bun scripts/bench-serve.ts all --models e4b --arms mlx-bun-serial,mlx-bun --adapter fixtures/adapters/upper
|
|
472
560
|
```
|
|
473
561
|
|
|
474
562
|
Curated results: [benchmarks.md](benchmarks.md).
|
|
@@ -544,3 +632,15 @@ behind each "not covered" row is in
|
|
|
544
632
|
Native verbs with no mlx-lm counterpart — `pi`, `harness pi`, `embed`,
|
|
545
633
|
`fit`, `train-watch`, `memory`, `evals` — are the surface that makes mlx-bun
|
|
546
634
|
more than a drop-in.
|
|
635
|
+
|
|
636
|
+
|
|
637
|
+
`--kv-quant turbo` composes with grouped lookup, standalone, Gemma assistant,
|
|
638
|
+
DeepSpec and DSpark drafting on supported targets. Sliding layers stay bf16.
|
|
639
|
+
See [batching design](../design/batching.md) for composition evidence and limits.
|
|
640
|
+
|
|
641
|
+
Paged KV retains the configured `--batch` size. Gemma4 bf16 requests use the shared executor and bypass the prompt cache; quantized KV and draft combinations remain unavailable. See [server configuration](server-config.md).
|
|
642
|
+
|
|
643
|
+
`--generation-checkpoint N` requires `--ssd-cache` and queues owned snapshots
|
|
644
|
+
for eligible ordinary requests. Shared continuation supports eligible Qwen, Llama, MiniCPM and Gemma4 requests with or without adapters, excluding media, grammar, fill, paging, logprobs or speculation.
|
|
645
|
+
Repeat the identical request to replay and resume; flush before shutdown for
|
|
646
|
+
eventual queued snapshots to become durable.
|
|
@@ -15,9 +15,33 @@ Three install channels ship from one release:
|
|
|
15
15
|
| Direct download (`curl -fsSL https://mlx-bun.dev/install.sh \| sh`) | the same bundle, into `~/.mlx-bun` | one tarball, via curl |
|
|
16
16
|
| npm / bunx (`bunx mlx-bun`, `bun install -g mlx-bun`) | a launcher + the TypeScript source, run under the user's Bun | the package, then the native runtime pack on first run |
|
|
17
17
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
18
|
+
The same bundle can run as a local worker inside a desktop application.
|
|
19
|
+
See [Embedding in a desktop application](#embedding-in-a-desktop-application).
|
|
20
|
+
|
|
21
|
+
## Embedding in a desktop application
|
|
22
|
+
|
|
23
|
+
Include the complete release bundle in the application's resources and launch
|
|
24
|
+
its executable by absolute path. Keep the native libraries, Metal library,
|
|
25
|
+
helpers, and Pi assets together as listed below. Copying only the executable
|
|
26
|
+
does not produce a self-contained installation.
|
|
27
|
+
|
|
28
|
+
For a Bun host, the [library API](library-api.md) documents `openIsolatedHost`
|
|
29
|
+
and its explicit executable command. A desktop host in another runtime can
|
|
30
|
+
manage the worker process and use the [HTTP API](server-api.md). Keep transport
|
|
31
|
+
and worker lifecycle in the application; request scheduling belongs to the
|
|
32
|
+
engine. Stop the worker when the application no longer owns it.
|
|
33
|
+
|
|
34
|
+
The model weights are separate from the executable bundle. Select an existing
|
|
35
|
+
artifact or use the [model download commands](models.md) before starting the
|
|
36
|
+
worker with that model. Follow the documented cache-location settings when
|
|
37
|
+
the application manages its own storage.
|
|
38
|
+
|
|
39
|
+
Repackaging within an application requires that application's signing and
|
|
40
|
+
notarization workflow. The executable's hardened-runtime entitlements and
|
|
41
|
+
native signing requirements are documented below. Include the third-party
|
|
42
|
+
attributions with the distributed application. Test the installed application
|
|
43
|
+
bundle, including worker launch and runtime assets, rather than relying only
|
|
44
|
+
on a source-checkout run.
|
|
21
45
|
|
|
22
46
|
## What ships in the bundle
|
|
23
47
|
|
|
@@ -32,6 +56,7 @@ dir), ~80 MB compressed; `mlx.metallib` is the bulk of the installed size.
|
|
|
32
56
|
| `libmlx.dylib`, `libjaccl.dylib`, `mlx.metallib` | MLX core, its distributed-comm dependency, the Metal kernels (libmlx loads the metallib from its own directory) | `/opt/homebrew/opt/mlx/lib` (override `MLX_LIB_DIR`) |
|
|
33
57
|
| `libmlx_bun_expert_io.dylib` | bounded streamed-expert I/O for GLM-5.2 MoE serving | [scripts/build-expert-io.sh](../../scripts/build-expert-io.sh) |
|
|
34
58
|
| `mlx-bun-frame-extract` | AVFoundation frame-extraction helper for video input (a Mach-O *executable*, not a dylib) | [scripts/build-frame-extract.sh](../../scripts/build-frame-extract.sh) → `swiftc -O src/native/frame_extract.swift` |
|
|
59
|
+
| `mlx-bun-mic-capture` | AVAudioEngine microphone capture + CGEvent hold-key helper for `mlx-bun dictate` (Mach-O executable; the only native piece of the Whisper work — the web composer uses the browser mic) | [scripts/build-mic-capture.sh](../../scripts/build-mic-capture.sh) → `swiftc -O src/native/mic_capture.swift` |
|
|
35
60
|
| `photon_rs_bg.wasm` | pi's image codec, resolved next to the executable by the web chat's `read`-on-image path (best-effort; pi degrades to a text note without it) | `node_modules/@silvia-odwyer/photon-node` (override `PHOTON_WASM`) |
|
|
36
61
|
| `theme/*.json`, `assets/*.png`, `export-html/`, `package.json`, `CHANGELOG.md`, `native/darwin/prebuilds/<arch>/darwin-modifiers.node` | assets the embedded pi **terminal** (`mlx-bun pi`) resolves by path: themes, startup art, `/export` template, version banner + changelog, native modifier-key helper (degrades if absent) | `node_modules/@earendil-works/pi-coding-agent/dist`, `pi-tui` |
|
|
37
62
|
|
|
@@ -133,7 +158,7 @@ does, in order. Steps 1–3 are yours; the rest is the scripts.
|
|
|
133
158
|
(`BUILD_DIR` overrides `dist`). Release builds are arm64-only; the script
|
|
134
159
|
exits on any other host arch.
|
|
135
160
|
5. **Sign nested code first** — every `*.dylib`, `*.node`, and the
|
|
136
|
-
`mlx-bun-frame-extract`
|
|
161
|
+
`mlx-bun-frame-extract` / `mlx-bun-mic-capture` helpers, matched by name under the build dir, get
|
|
137
162
|
`codesign --force --timestamp --options runtime -s "<identity>"`.
|
|
138
163
|
Nested-before-container is required. The metallib, wasm, JSON, and PNG
|
|
139
164
|
assets are data, not code, and are skipped.
|
|
@@ -186,6 +211,13 @@ npm if the version is live. Env overrides: `MLX_BUN_SIGN_IDENTITY`,
|
|
|
186
211
|
`NOTARY_PROFILE`, `BUILD_DIR`, `OUT_DIR` (release); `OUT_DIR`, `REPO`,
|
|
187
212
|
`TAP_REPO` (publish).
|
|
188
213
|
|
|
214
|
+
For an SSH-driven release, a local keychain unlock may still leave
|
|
215
|
+
`notarytool` reporting `keychainLocked` in the SSH session. The v0.3.0
|
|
216
|
+
release succeeded by running `release-binary.sh` in the M1 Max's local
|
|
217
|
+
Terminal, then `publish-release.sh` over SSH. Both steps used the same clean
|
|
218
|
+
merged source and `OUT_DIR`. Check `npm whoami` from the actual release
|
|
219
|
+
checkout too: a project `.npmrc` can override the user's configuration.
|
|
220
|
+
|
|
189
221
|
### The notarization lesson (v0.2.0, 2026-08-24)
|
|
190
222
|
|
|
191
223
|
The first v0.2.0 submission came back **Invalid**. The release added
|
|
@@ -311,7 +343,7 @@ sh scripts/build-native-pack.sh <ver> dist-native
|
|
|
311
343
|
gh release create native-v<ver> \
|
|
312
344
|
dist-native/mlx-bun-native-v<ver>-arm64.tar.gz \
|
|
313
345
|
dist-native/mlx-bun-native-v<ver>-arm64.tar.gz.sha256 \
|
|
314
|
-
--title "mlx-bun native runtime v<ver>" --notes "<what changed>"
|
|
346
|
+
--latest=false --title "mlx-bun native runtime v<ver>" --notes "<what changed>"
|
|
315
347
|
```
|
|
316
348
|
|
|
317
349
|
`build-native-pack.sh` stages the same six files with the same
|
|
@@ -323,13 +355,13 @@ package. Pre-publish smoke: a fresh-cache extraction plus a real MLX
|
|
|
323
355
|
`dlopen` (and, when the helpers changed, an expert read or a video decode).
|
|
324
356
|
The pack is ad-hoc signed only — `build-native-pack.sh` never touches a
|
|
325
357
|
Developer ID and nothing notarizes it; it is `dlopen`ed by the user's own Bun
|
|
326
|
-
process, not by our signed executable.
|
|
327
|
-
|
|
358
|
+
process, not by our signed executable. Use `--latest=false` so a native pack
|
|
359
|
+
does not replace the application release behind the direct installer's URL.
|
|
328
360
|
|
|
329
|
-
|
|
330
|
-
`c74db5307cc8ce122f48d97ef951b30578674e7f`. Its six-file macOS 14
|
|
331
|
-
|
|
332
|
-
|
|
361
|
+
Native pack 0.4.0 was published on 2026-09-08 with MLX 0.32.2 and MLX-C
|
|
362
|
+
`c74db5307cc8ce122f48d97ef951b30578674e7f`. Its six-file macOS 14 archive
|
|
363
|
+
was uploaded from the M1 Max and downloaded again; its checksum matches the
|
|
364
|
+
package manifest. It was published before mlx-bun v0.3.0. Runtime bindings
|
|
333
365
|
match this one C API, and startup checks the linked core version. The old
|
|
334
366
|
runtime and source controls remain separate for benchmark comparisons.
|
|
335
367
|
|
|
@@ -338,8 +370,8 @@ CI builds that pinned C wrapper with
|
|
|
338
370
|
`MLX_BUN_LIBMLXC` to its `lib/libmlxc.dylib`. The script verifies the official
|
|
339
371
|
macOS 14 MLX-Metal archive hash and checks out the exact MLX-C commit. It
|
|
340
372
|
extracts native libraries and headers without running Python or compiling
|
|
341
|
-
Metal sources. This also reproduces
|
|
342
|
-
|
|
373
|
+
Metal sources. This also reproduces the native-pack build inputs;
|
|
374
|
+
Homebrew's C wrapper is not the CI runtime.
|
|
343
375
|
|
|
344
376
|
Managed jobs in the compiled binary re-exec that binary through a private job
|
|
345
377
|
entry, with the database/log paths passed in the environment. They do not depend
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
# Reference environment and platform facts
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
it — when you change the code, update the paragraph.
|
|
3
|
+
Oracle configuration, native-runtime compatibility, and machine conditions
|
|
4
|
+
for reproducing numerical and performance checks. Historical environment
|
|
5
|
+
records below identify the versions used for their original comparisons.
|
|
7
6
|
|
|
8
7
|
User-facing symptoms live in [troubleshooting.md](./troubleshooting.md).
|
|
9
8
|
|
|
@@ -21,8 +20,8 @@ Before asserting anything about RAM, OOM, or bandwidth, run
|
|
|
21
20
|
reference `serve.sh` (below) hard-codes a 28 GB wired limit "of 32 GB", so it
|
|
22
21
|
is written for the M1 Max.
|
|
23
22
|
|
|
24
|
-
|
|
25
|
-
|
|
23
|
+
The M4 Pro optimization measurements use internal SSD storage for active
|
|
24
|
+
models. The external SSD stores artifacts to copy when
|
|
26
25
|
needed; external-drive loading performance is outside normal acceptance for
|
|
27
26
|
the 12–17 GB models. Stage each needed artifact under `~/models/`, verify
|
|
28
27
|
every file against its archive, and record that path in both benchmark arms.
|
|
@@ -34,10 +33,24 @@ user-local eval DB (`~/.cache/mlx-bun/evals.sqlite`) and promoted to
|
|
|
34
33
|
`docs/reference/benchmarks.md` deliberately. `bun scripts/bench-serve.ts all`
|
|
35
34
|
is the benchmark harness; it writes Markdown and raw JSON under `reports/`
|
|
36
35
|
as gitignored outputs. Numbers on a loaded machine are
|
|
37
|
-
|
|
36
|
+
diagnostic; run-to-run spread is the stability signal, and the harness retries
|
|
38
37
|
unstable cells (`scripts/bench-serve.ts`; `benchmarks.md`, "Running the
|
|
39
38
|
benchmark").
|
|
40
39
|
|
|
40
|
+
A performance decision must account for concurrent work during the timed
|
|
41
|
+
comparison. For unstable pairs, capture process activity, GPU utilization and
|
|
42
|
+
VM/page-in changes before and during the repeat; keep timestamps that align
|
|
43
|
+
those observations with each measured request or forward. A preflight snapshot
|
|
44
|
+
alone cannot identify interference during a run. CPU usage or retained swap
|
|
45
|
+
alone does not establish GPU contention or active paging. Preserve all original
|
|
46
|
+
samples and label unresolved comparisons inconclusive rather than attributing
|
|
47
|
+
an outlier to the candidate. GPU-wide counters and the last submitting PID are
|
|
48
|
+
observations, not complete per-process GPU attribution. The serving decode
|
|
49
|
+
samples use different nonce-bearing prompts; speculative acceptance and target
|
|
50
|
+
call counts can therefore vary within an arm. Compare matching request hashes
|
|
51
|
+
and work counters across arms before interpreting their TPS spread as temporal
|
|
52
|
+
instability.
|
|
53
|
+
|
|
41
54
|
## External storage loading
|
|
42
55
|
|
|
43
56
|
On the M4 Pro with MLX 0.32.2, two RTN4 first-request warmups from
|
|
@@ -66,6 +79,65 @@ deferred under the active-storage policy above. Evidence under `reports/qwen38-r
|
|
|
66
79
|
`fill-append-http-final-partial-review.json`, `rtn4-storage-control-manifest.json`,
|
|
67
80
|
`fill-append-storage-control-review.json` and `weights-loading-http.json`.
|
|
68
81
|
|
|
82
|
+
## Reproduce the MiniCPM5 logit comparison
|
|
83
|
+
|
|
84
|
+
From an Apple Silicon Mac running macOS 14 or later, install Bun 1.4.2 or
|
|
85
|
+
newer and [uv](https://docs.astral.sh/uv/getting-started/installation/), then
|
|
86
|
+
run these commands from a checkout of this repository:
|
|
87
|
+
|
|
88
|
+
```sh
|
|
89
|
+
bun install --frozen-lockfile && \
|
|
90
|
+
oracle_env="$(bash scripts/oracle/setup.sh)" && \
|
|
91
|
+
eval "$oracle_env" && \
|
|
92
|
+
bash scripts/oracle/compare-minicpm5.sh --download
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
The setup script creates an external Python 3.13.5 environment, installs the
|
|
96
|
+
complete [reference lock](../../scripts/oracle/requirements.lock), checks its
|
|
97
|
+
dependencies, and prints the `MLX_BUN_ORACLE_VENV` export. Its default location
|
|
98
|
+
is `~/.cache/mlx-bun/oracle-mlx-0.32.2-py3.13.5`. Pass a directory to `setup.sh`
|
|
99
|
+
to choose another location. Re-running it synchronizes that environment to
|
|
100
|
+
the lock, removing packages outside the pinned set. It does not install model
|
|
101
|
+
weights or run inference.
|
|
102
|
+
|
|
103
|
+
The lock pins MLX 0.32.2, mlx-lm 0.31.3, mlx-optiq 0.2.7 and their installed
|
|
104
|
+
dependencies. MLX-Metal uses the explicit macOS 14 wheel and SHA-256 from
|
|
105
|
+
[the upstream release](https://pypi.org/project/mlx-metal/0.32.2/#files),
|
|
106
|
+
matching native pack 0.4.0. Selecting only a package version could install a
|
|
107
|
+
different Metal build on newer macOS releases.
|
|
108
|
+
|
|
109
|
+
The comparison script downloads `mlx-community/MiniCPM5-1B-OptiQ-4bit` at
|
|
110
|
+
revision `664aabaed233c653f82716d8dc822234d0091f78` when `--download` is supplied.
|
|
111
|
+
Omit the flag to require a cached snapshot. Hugging Face cache environment
|
|
112
|
+
settings are respected. Set `MLX_BUN_TEST_MINICPM5` to use an existing model
|
|
113
|
+
directory instead; its config and weight hashes are recorded in the output.
|
|
114
|
+
|
|
115
|
+
Each run creates a fresh fixture directory under
|
|
116
|
+
`~/.cache/mlx-bun/comparisons/`, invokes the Python oracle through
|
|
117
|
+
`scripts/regen/minicpm5.ts`, then runs
|
|
118
|
+
`bun test tests/parity/minicpm5-parity.test.ts`. `MLX_BUN_GOLDEN_DIR` selects
|
|
119
|
+
that directory for both generation and comparison, with no fallback to older
|
|
120
|
+
fixtures. The manifest records the prompt, token IDs, Python/MLX/Metal/mlx-lm
|
|
121
|
+
versions, device, model hashes, lock hash and per-vector hashes. The command
|
|
122
|
+
prints the output directory and elapsed comparison time. Missing inputs,
|
|
123
|
+
failed generation or mismatched logits produce a nonzero exit; skipped tests
|
|
124
|
+
are not the acceptance result.
|
|
125
|
+
|
|
126
|
+
This test compares the complete vocabulary logit vector before sampling at
|
|
127
|
+
100 steps, plus all 100 greedy token IDs. It uses bf16 KV, one short prompt
|
|
128
|
+
and single-row model forwards. It does not establish sampling-policy parity,
|
|
129
|
+
batched scheduling correctness, mixed-KV parity or server performance. The
|
|
130
|
+
[benchmark reference](benchmarks.md) links the separate
|
|
131
|
+
coverage for those configurations.
|
|
132
|
+
|
|
133
|
+
Fixtures must be generated on the comparison machine. The usual golden
|
|
134
|
+
resolver selects `goldens/<machine-key>/` overrides; the reference machine
|
|
135
|
+
uses the root `goldens/` directory. Metal kernels can differ across GPU
|
|
136
|
+
families and runtime builds. In particular, the fast-SDPA dispatch boundary
|
|
137
|
+
at sequence length L ≥ 16 can change floating-point operation order. This
|
|
138
|
+
short-prompt recipe does not test that prefill boundary. Longer-prefill and
|
|
139
|
+
batched comparisons need their corresponding same-machine oracle cases.
|
|
140
|
+
|
|
69
141
|
## The Python oracle
|
|
70
142
|
|
|
71
143
|
Logit parity with mlx-lm is the correctness oracle; mixed-precision KV and the
|
|
@@ -85,6 +157,30 @@ bumped from 0.2.4 to 0.2.15 on 2026-07-06 and the mixed-KV goldens stayed
|
|
|
85
157
|
byte-identical across the bump. The venv directory holds no project source —
|
|
86
158
|
just the venv and `serve.sh`.
|
|
87
159
|
|
|
160
|
+
**Whisper oracle.** mlx-whisper 0.4.3 lives in its own venv,
|
|
161
|
+
`~/Code/mlx-whisper-oracle/.venv` (Python 3.12 via uv; `mlx==0.32.2` to match
|
|
162
|
+
`MLX_CORE_VERSION`, plus torch and numba, which must never enter the pinned
|
|
163
|
+
mlx-lm venv). Override with `MLX_BUN_WHISPER_ORACLE_VENV`. Regenerate with
|
|
164
|
+
`bun scripts/regen.ts whisper`; the parity test compares against
|
|
165
|
+
`goldens/whisper.json` and its untracked blobs. The mlx-community Whisper
|
|
166
|
+
checkpoint ships no tokenizer: `openai/whisper-large-v3-turbo`'s
|
|
167
|
+
`tokenizer.json` + `tokenizer_config.json` must be in the HF cache
|
|
168
|
+
(`hf_hub_download` of those two files; ~2.5 MB). whisper.cpp comparisons use
|
|
169
|
+
sotto's vendored v1.9.3 helper (`~/Code/sotto/build/server/helpers/sotto-engine`)
|
|
170
|
+
with `ggml-large-v3-turbo.bin` — same weights, different runtime.
|
|
171
|
+
|
|
172
|
+
Silero VAD parity uses the `silero-vad` 6.2.1 pip package (torch JIT model)
|
|
173
|
+
in the same venv (`scripts/oracle/gen-silero-golden.py` → tracked
|
|
174
|
+
`goldens/silero-vad.json`); the engine's weights are `ggml-org/whisper-vad`'s
|
|
175
|
+
`ggml-silero-v6.2.0.bin` in the HF cache (byte-identical to sotto's copy,
|
|
176
|
+
SHA-256 `2aa269b7…`). `coremltools` is installed there too for the Core ML
|
|
177
|
+
encoder experiment (benchmarks.md).
|
|
178
|
+
|
|
179
|
+
The repo's untracked `.env` may pin `MLX_BUN_ORACLE_VENV` to a directory that
|
|
180
|
+
no longer exists (it pointed at `~/Code/mlx-lm-example/.venv` on the M1 Max
|
|
181
|
+
on 2026-09-15); every parity test importing `tests/support/paths.ts` then
|
|
182
|
+
throws at import. Fix the path or run with `bun --env-file=/dev/null test …`.
|
|
183
|
+
|
|
88
184
|
The Qwen MTP compatibility test accepts explicit local artifact paths through
|
|
89
185
|
`MLX_BUN_TEST_MTP_TARGET` and `MLX_BUN_TEST_MTP_DRAFT`, alongside
|
|
90
186
|
`MLX_BUN_TEST_QWEN38_MTP=1`. It compares speculative and ordinary greedy
|
|
@@ -101,7 +197,7 @@ Qwen artifacts are also present under
|
|
|
101
197
|
`/Volumes/MLX-Models/models/{Qwen,mjriii}/`; header-only inventories under
|
|
102
198
|
`reports/qwen38-rd/` are machine-local and do not load the GPU.
|
|
103
199
|
|
|
104
|
-
**
|
|
200
|
+
**M4 Pro runtime update, staged 2026-09-07:** MLX 0.32.2 with
|
|
105
201
|
MLX-C `c74db5307cc8ce122f48d97ef951b30578674e7f` is built under
|
|
106
202
|
`reports/qwen38-rd/mlx-upgrade-0.32.2/install/lib/`. Explicit
|
|
107
203
|
`MLX_BUN_LIBMLXC=<that-directory>/libmlxc.dylib` selects it per process.
|
|
@@ -134,10 +230,10 @@ eleven skips on the old core. The local native-pack
|
|
|
134
230
|
candidate under `native-pack-candidate/` extracts into `native-pack-extracted/`;
|
|
135
231
|
all five Mach-O files target 14.0, have valid ad-hoc signatures and load their
|
|
136
232
|
non-system dependencies from siblings. These checks ran on macOS 27, not an
|
|
137
|
-
actual macOS 14 host.
|
|
138
|
-
|
|
139
|
-
`/Users/joshrossi/Library/Caches/mlx-bun/native-v0.4.0-arm64`.
|
|
140
|
-
|
|
233
|
+
actual macOS 14 host. This build is published as native pack 0.4.0 and the
|
|
234
|
+
verified local cache is
|
|
235
|
+
`/Users/joshrossi/Library/Caches/mlx-bun/native-v0.4.0-arm64`. Publication
|
|
236
|
+
details are in distribution.md. The consolidated source passes 52 complete Qwen
|
|
141
237
|
forward/state/continuation cases and six Trellis generations, with fixed
|
|
142
238
|
source/runtime/reference hashes and clean worker exits. The consolidated
|
|
143
239
|
model-free suite passes 1,875 tests with ten skips; all typechecks pass.
|
|
@@ -179,6 +275,40 @@ against an M4 Pro output fixture. The test still requires exact output and
|
|
|
179
275
|
state hashes; Python runs only the external reference. Trellis variant
|
|
180
276
|
matrix tests allow 30 seconds for first-use kernel compilation on CI.
|
|
181
277
|
|
|
278
|
+
The M1 Max override was replayed on 2026-09-08 with the same inputs using
|
|
279
|
+
`/Users/joshrossi/Code/mlx-lm/.venv-mlx-0.32.2-macos14` (MLX/MLX-Metal
|
|
280
|
+
0.32.2, MLX-LM 0.31.3). Bun matches its outputs and recurrent-state hashes
|
|
281
|
+
exactly. The review file is
|
|
282
|
+
`reports/qwen38-closeout/qwen-delta-m1-review.json`.
|
|
283
|
+
|
|
284
|
+
Qwen3-Embedding tests also resolve `goldenPath("qwen3-embed")`, including
|
|
285
|
+
machine overrides, and skip when their required binary blobs are absent.
|
|
286
|
+
Regenerate with the matching Python and
|
|
287
|
+
`scripts/oracle/gen-qwen3-embed-golden.py <artifact> --replay goldens/qwen3-embed/meta.json`;
|
|
288
|
+
`--output-dir` selects a review directory. Replay preserves the text and token
|
|
289
|
+
IDs and checks the tokenizer against them. Metadata records the device,
|
|
290
|
+
runtime, artifact config, original metadata and output hashes. The M1 Max
|
|
291
|
+
replay matches hidden states and pooled embeddings exactly. Cosine uses both
|
|
292
|
+
vector norms: bf16 normalization does not guarantee a unit norm when the
|
|
293
|
+
result is subsequently read as float32.
|
|
294
|
+
|
|
295
|
+
The same M1 validation found June MiniCPM logit blobs without runtime
|
|
296
|
+
provenance. Explicit `bun scripts/regen.ts minicpm5` with the matching venv
|
|
297
|
+
preserves the artifact, prompt IDs and greedy trajectory; the regenerated
|
|
298
|
+
logits match Bun exactly. The generator now records runtime/device/config
|
|
299
|
+
provenance and all blob hashes. The old files and reviewed differences remain
|
|
300
|
+
under `reports/qwen38-closeout/minicpm5-golden-before/` and
|
|
301
|
+
`minicpm5-golden-review.json`.
|
|
302
|
+
|
|
303
|
+
The Gemma bf16 and mixed-KV M1 replays also pass with unchanged prompt IDs
|
|
304
|
+
on MLX 0.32.2. This current M1 venv contains **mlx-optiq 0.2.7** by installed
|
|
305
|
+
distribution metadata, matching the documented M4 installation; it is not
|
|
306
|
+
the historical 0.2.15 environment. OptiQ's module `__version__` incorrectly
|
|
307
|
+
reports 0.2.5 there, so regeneration records distribution metadata. Old
|
|
308
|
+
fixtures remain under `reports/qwen38-closeout/{parity,mixed-kv}-golden-before/`.
|
|
309
|
+
These are current-stack parity checks, not a runtime-only A/B against the
|
|
310
|
+
older mixed-KV fixture's 0.31.2/0.2.15 combination.
|
|
311
|
+
|
|
182
312
|
Readable oracle source, in that `site-packages/`: `mlx_lm/models/gemma3.py`
|
|
183
313
|
and `mlx_lm/server.py` for the port targets; `mlx_lm/models/cache.py` for the
|
|
184
314
|
cache classes; `mlx_lm/tokenizer_utils.py` for prompt rendering;
|
|
@@ -250,7 +380,19 @@ servers DO validate: the Bearer token must start with `sk-optiq-`
|
|
|
250
380
|
|
|
251
381
|
## Bun and FFI facts
|
|
252
382
|
|
|
253
|
-
**Bun
|
|
383
|
+
**Development and CI: Bun 1.4.2.** Build the committed frontend bundle with
|
|
384
|
+
that version so its byte-for-byte freshness check uses the same compiler.
|
|
385
|
+
Performance comparisons record the runtime and use the same version in both
|
|
386
|
+
arms; historical results retain their original version.
|
|
387
|
+
|
|
388
|
+
Non-login SSH on the M4 Pro can omit `/Users/joshrossi/.bun/bin` from `PATH`.
|
|
389
|
+
Put that directory on the remote command's PATH when running the test suite:
|
|
390
|
+
launching the parent Bun by absolute path alone does not let subprocess tests
|
|
391
|
+
find `bun`. The quantized-row validation's initial seven command-entry/job
|
|
392
|
+
failures disappear with that invocation corrected; no product code change was
|
|
393
|
+
needed for those failures.
|
|
394
|
+
|
|
395
|
+
**Runtime minimum: Bun ≥ 1.4.0.** `package.json` `engines.bun` is `>=1.4.0`. `Bun.Image`
|
|
254
396
|
(native OS codecs via ImageIO, EXIF auto-orient, off-thread) is the vision
|
|
255
397
|
decode path (`src/vision/preprocess.ts`); `Bun.Image.resize` is deliberately
|
|
256
398
|
not used. The FFI ABI fix below is the other reason for the pin.
|
|
@@ -346,3 +488,7 @@ holds self-contained reproductions for upstream bug reports (the two Bun
|
|
|
346
488
|
issues above, plus `optiq-mixed-kv-inert` and `vllm-metal-turboquant`); they
|
|
347
489
|
are not part of the build. Committed absolute paths (the venv, the weights
|
|
348
490
|
snapshot, `serve.sh`) are machine-specific on purpose — do not "correct" them.
|
|
491
|
+
|
|
492
|
+
The quantized-KV golden producer (`bun scripts/regen.ts kvq`) passes an absolute output directory to Python, since the child runs from `scripts/`. This preserves the selected machine directory and existing prompt IDs. Missing M4 blobs were regenerated from the pinned oracle into the isolated `delayed-affine-m4-oracle` override; numerical expectations were not produced by the inference implementation. Evidence: `reports/qwen38-closeout/composition-baseline/oracle-generator-path/`.
|
|
493
|
+
|
|
494
|
+
The M1 rotating-KV reference still identified MLX 0.31.2 and disagreed with both unchanged control and candidate on the KV8 greedy prefix. Regeneration with pinned MLX 0.32.2 retains the prompt IDs and passes exact logits plus both continuation checks. The matching M1 override and M4 reference caches are refreshed; previous manifests/blobs and provenance are retained with the generator-path evidence.
|
|
@@ -14,10 +14,13 @@ everything else under `src/` is internal and may change without notice.
|
|
|
14
14
|
Every export is documented below, grouped the way `src/index.ts` groups
|
|
15
15
|
them.
|
|
16
16
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
17
|
+
The server uses continuous batching by default for eligible requests.
|
|
18
|
+
Its scheduler coordinates work on shared model resources, including a single
|
|
19
|
+
active request. Direct callers of `generate` must coordinate access to the
|
|
20
|
+
same model and mutable state; launching independent generators does not
|
|
21
|
+
automatically create a batch. Use the serving integration for its scheduling
|
|
22
|
+
and request preparation, or compose the engine with explicit execution ports.
|
|
23
|
+
See [server configuration](server-config.md) for supported combinations.
|
|
21
24
|
|
|
22
25
|
## Export map
|
|
23
26
|
|
|
@@ -672,3 +675,14 @@ When embedding the high-level library in your own compiled application, pass
|
|
|
672
675
|
`command: ["/path/to/mlx-bun"]` to `openIsolatedHost`. Source/package consumers
|
|
673
676
|
use the installed CLI source automatically; compiled callers supply the worker
|
|
674
677
|
executable explicitly because their own executable is not the mlx-bun CLI.
|
|
678
|
+
|
|
679
|
+
### Cache session affinity
|
|
680
|
+
|
|
681
|
+
`GenerateOptions.cacheSessionId` carries application cache affinity through
|
|
682
|
+
serving execution. The `PrefixCache` contract accepts the optional session ID
|
|
683
|
+
on `take`, `prefetch` and `put`, and exposes optional `closeSession(id)`. The
|
|
684
|
+
cache owns the association and both storage tiers; the ID does not change the
|
|
685
|
+
numerical namespace or replace the request's full token history. Standalone
|
|
686
|
+
`generate()` calls that supply their own cache retain caller-owned state; an
|
|
687
|
+
ID alone does not create a process-wide cache. HTTP fields and lifecycle are
|
|
688
|
+
documented in [server-api.md](server-api.md#cache-session-affinity).
|
package/docs/reference/memory.md
CHANGED
|
@@ -254,7 +254,7 @@ routes never touch the agent-tool surface above.
|
|
|
254
254
|
|
|
255
255
|
## Related
|
|
256
256
|
|
|
257
|
-
- [cli.md](cli.md#memory--the-personal-wiki) — the `memory` command in the full CLI reference.
|
|
257
|
+
- [cli.md](cli.md#memory-alias-setup--the-personal-wiki) — the `memory` command in the full CLI reference.
|
|
258
258
|
- [server-api.md](server-api.md#get-apimemory--post-apimemoryinit) — `/api/memory/*` wire format.
|
|
259
259
|
- [dreaming-nightly-pipeline.md](../design/dreaming-nightly-pipeline.md) — the canonical pipeline design.
|
|
260
260
|
- [docs/design/dreaming-nightly-pipeline.md](../design/dreaming-nightly-pipeline.md), [docs/design/dreaming-nightly-pipeline.md](../design/dreaming-nightly-pipeline.md) — synthesis internals and the local inference path.
|
package/docs/reference/models.md
CHANGED
|
@@ -4,6 +4,14 @@ The one supported-model list, plus how mlx-bun downloads, indexes, lists,
|
|
|
4
4
|
and reclaims models. The store is the standard Hugging Face hub cache —
|
|
5
5
|
nothing proprietary; `hf` and mlx-lm read/write the same tree.
|
|
6
6
|
|
|
7
|
+
## Automatic model selection
|
|
8
|
+
|
|
9
|
+
On a fresh install with no supported downloaded model, `serve` downloads and
|
|
10
|
+
starts MiniCPM5-1B, then can download the device-recommended model in the
|
|
11
|
+
background. Gemma e4b is the preferred general model once available and within
|
|
12
|
+
the selection budget. `DEFAULT_REPO_ID` names that preference, not the
|
|
13
|
+
first-download artifact. Explicit model selection bypasses this starter flow.
|
|
14
|
+
|
|
7
15
|
## Supported models
|
|
8
16
|
|
|
9
17
|
The source of truth is code, not this table: `src/model/profile.ts`
|
|
@@ -16,25 +24,29 @@ is the bug.
|
|
|
16
24
|
|
|
17
25
|
Scope is deliberate: a few families held to explicit oracle contracts
|
|
18
26
|
(L1 = bit-exact vs mlx-lm, L2 = bit-exact vs mlx-optiq, L3 = measured, no
|
|
19
|
-
oracle), plus a declared Tier-0 generic surface.
|
|
27
|
+
oracle), plus a declared Tier-0 generic surface. These are comparison
|
|
28
|
+
contracts, not interchangeable claims about every artifact. The
|
|
29
|
+
[coverage map](benchmarks.md#coverage-beyond-the-four-model-summary) identifies
|
|
30
|
+
the test and remaining evidence limits for each roster row. There is no alias table —
|
|
20
31
|
the "query" column is a substring that `resolve()` matches against
|
|
21
32
|
already-downloaded repos (it must match exactly one repo; see
|
|
22
33
|
[Query resolution rules](#query-resolution-rules-per-verb)).
|
|
23
34
|
|
|
24
35
|
| `serve` query | Validated artifact (HF repo) | Family · load path · tier | Modalities | Draft sources | KV schemes | Notes |
|
|
25
36
|
| --- | --- | --- | --- | --- | --- | --- |
|
|
26
|
-
| `e4b` | `mlx-community/gemma-4-e4b-it-OptiQ-4bit` | Gemma 4 (`gemma4*`) · dedicated `gemma4` graph with a **generated** specialization keyed on the config fingerprint · L1 | text · **image** (SigLIP tower in the bf16 `optiq_vision.safetensors` sidecar) · **audio** (Conformer tower in the same sidecar) | two-model · Gemma `-assistant` (L2) · locally-trained DSpark (`dspark.json`) · ngram | bf16 · uniform 4/8 · `config` (kv_config.json, batches) · turbo · `--paged-kv` | **
|
|
37
|
+
| `e4b` | `mlx-community/gemma-4-e4b-it-OptiQ-4bit` | Gemma 4 (`gemma4*`) · dedicated `gemma4` graph with a **generated** specialization keyed on the config fingerprint · L1 | text · **image** (SigLIP tower in the bf16 `optiq_vision.safetensors` sidecar) · **audio** (Conformer tower in the same sidecar) | two-model · Gemma `-assistant` (L2) · locally-trained DSpark (`dspark.json`) · ngram | bf16 · uniform 4/8 · `config` (kv_config.json, batches) · turbo · `--paged-kv` | **Preferred model after download**; fresh installs first serve MiniCPM5. See [automatic selection](#automatic-model-selection). The only audio-capable artifact. ~7.0 GB on disk (benchmarks.md legend, 2026-06-15). Trains (LoRA / ORPO / SFT). |
|
|
27
38
|
| `12B` | `mlx-community/gemma-4-12B-it-OptiQ-4bit` | Gemma 4 · generated specialization · L1 | text · **image** (encoder-free `gemma4_unified_vision` declared in config.json — no sidecar needed). No audio: the snapshot's sidecar is an audio **stub** (`embed_audio` only, no `audio_tower.*`) | two-model · `-assistant` · DSpark local · **DeepSpec released** (`deepseek-ai/dspark_gemma4_12b_block7`) · ngram | bf16 · uniform · `config` · turbo · `--paged-kv` | ~8.4 GB (2026-06-15). `largestRecommendedRepoId` pick for ≥ 24 GB RAM (src/fit.ts). Trains. |
|
|
28
39
|
| `26B` | `mlx-community/gemma-4-26B-A4B-it-OptiQ-4bit` | Gemma 4 MoE · generated specialization · L1 | text · image **only if** the snapshot ships the SigLIP sidecar (registry `has_vision_sidecar`; the tower is `gemma4_vision`). No `audio_config` → no audio | two-model · `-assistant` · ngram | bf16 · uniform · `config` · turbo · `--paged-kv` | ~18 GB (2026-06-15). `largestRecommendedRepoId` pick for ≥ 48 GB RAM. |
|
|
29
|
-
| any other `gemma4*` config (1B, e2b, 31B, …) | — | Gemma 4 · the `Gemma4Model` monolith (no generated specialization) ·
|
|
40
|
+
| any other `gemma4*` config (1B, e2b, 31B, …) | — | Gemma 4 · the `Gemma4Model` monolith (no generated specialization) · family support, artifact unvalidated | per the registry's vision/audio flags | same as the family | same as the family | Loads by `model_type`; **no artifact is pinned in tests/support/goldens for these**, so treat as family-supported, artifact-unvalidated. |
|
|
30
41
|
| `MiniCPM5` | `mlx-community/MiniCPM5-1B-OptiQ-4bit` | MiniCPM5 · `model_type: llama` matched by exact shape (`isMiniCPM5Config`) → dedicated `minicpm5` graph · L1 / L2 | text | two-model · ngram | bf16 · uniform · `config` (batches — Phase 3.1) · turbo (quality curve measured 2026-07-06, benchmarks.md §3) | Sub-GB starter (benchmarks.md legend). Trains (segmented backward). Tool calling (XML). |
|
|
31
42
|
| `Qwen3.5-4B` | `mlx-community/Qwen3.5-4B-OptiQ-4bit` | Qwen3.5 (`qwen3_5` / `qwen3_5_text`, dense hybrid gated-DeltaNet) · dedicated `qwen3.5` graph · L1 | text (image/video only when the artifact ships vision weights — see Qwen3.8) | two-model · ngram · `mtp` if a `qwen3_5_mtp` companion exists | bf16 (L1) · `config` (KV-ON parity passed 2026-06-15, PLAN 14e) | Thinking + tool calling. Batches on the SSM path (`MLX_BUN_BATCH_SSM=0` reverts). The MoE variant `qwen3_5_moe` is **not** supported. |
|
|
32
43
|
| `Qwen3.8` | `mlx-community/Qwen3.8-27B-OptiQ-4bit` @ `b04599de95d7a9bfbd7f208d347c0f10d9432a42` | Qwen3.5 family · **exact artifact profile** `qwen3.8-27b-optiq-4bit` (safetensors + `qwen3.5` graph) · L1 | text · **image** · **video** (`image_url` / `video_url` parts; Qwen3-VL tower + mRoPE; video decodes via the AVFoundation sidecar `mlx-bun-frame-extract`, 2 fps, ≤ 768 frames). Video never combines with audio; no audio | **native MTP head** (`mlx-community/Qwen3.8-27B-MTP-bf16`, auto-detected `qwen3_5_mtp`; `--draft-kind mtp` with no `--draft-model` uses a bundled `mtp/` subfolder) · two-model · ngram | bf16 (L1) · `config` is **Lab** — policy copied from the same-topology Qwen3.6 artifact, no model-specific oracle (benchmarks.md, 2026-08-22) | `reasoning_effort` (xhigh/medium/low) + `preserve_thinking` + tool calling. `/v1/models` advertises vision. Shipped in v0.2.0. |
|
|
33
44
|
| `Qwen3-Embedding` | `mlx-community/Qwen3-Embedding-4B-4bit-DWQ` | plain `qwen3` · dedicated `qwen3` graph · L1 | text | — | — | **Embeddings only**: `/v1/embeddings` + `mlx-bun embed`. Auto-picked by `embed` when no query is given; never the chat default. |
|
|
34
45
|
| `Qwen3-30B` | `mlx-community/Qwen3-30B-A3B-Thinking-2507-4bit` | Qwen3-MoE (`qwen3_moe`) · dedicated `qwen3-moe` graph · L1 (opt-in slow parity test, `MLX_BUN_TEST_QWEN3_MOE=1`) | text | two-model · ngram | bf16 (the artifact ships no kv_config.json) | Sparse top-k SwitchGLU experts. |
|
|
35
46
|
| `diffusiongemma` | `mlx-community/diffusiongemma-26B-A4B-it-OptiQ-4bit` | DiffusionGemma (`diffusion_gemma`) · dedicated graph + **denoising loop** (non-autoregressive) · L2 (optiq) | text · **image** (single image; its own inline-quantized SigLIP tower). No video / audio | — (no AR verify loop) | — (canvas model; the `--kv-quant` axis does not apply) | Serial lane always. Diffusion-native LoRA trains. |
|
|
47
|
+
| `whisper` | `mlx-community/whisper-large-v3-turbo` (fp16, 1.6 GB, `weights.safetensors`) | Whisper (`whisper`) · dedicated encoder-decoder graph + transcription loop · **L1 vs mlx-whisper 0.4.3** (mel, encoder output and per-step decoder logits bit-exact; `tests/parity/whisper.test.ts`) | **audio in → text out** only: `/v1/audio/transcriptions`, `/v1/audio/translations`, `mlx-bun transcribe`. Never the chat model. | — | — | Tokenizer files are not in the mlx-community repo; the loader resolves `openai/whisper-large-v3-turbo`'s `tokenizer.json` from the HF cache (2.4 MB, `mlx-bun get` it once). Beam search (`beam_size`) is ours — mlx-whisper has none; checked against whisper.cpp's beam-5 transcripts. Word timestamps not yet. Serves as a companion beside any chat model or alone (transcription-only server). Any `mlx-community/whisper-*` fp16 checkpoint loads (80-mel v1/v2 vocab resolves `openai/whisper-large-v2`). |
|
|
36
48
|
| `GLM-5.2-colibri` | `mateogrgic/GLM-5.2-colibri-int4-with-int8-mtp` @ `3cc8db99b1b13fc79325d987ba3c1c430766b3b8` | GLM-5.2 (`glm_moe_dsa`) · **Colibri container loader** + dedicated `glm5.2` graph (streamed experts) · **exact artifact profile**, L3 | text | **checkpoint-native MTP** (`--mtp on`, the default; mutually exclusive with `--draft-model`) | checkpoint-native compressed **MLA/DSA** cache (its own scheme; SSD tier v3 persists it) | Fixed-context admission: `--context-length` (4096) and `--max-tokens` (128) are reserved by the header-only resource equation before weights open; `--memory-budget` defaults to min(25 GiB, RAM). `--mtp off` enables ordinary batching. Embeddings, vision/audio, adapters, and training are unsupported. See [below](#direct-container-artifacts-glm-5x). |
|
|
37
|
-
| Tier-0 generic | validated manifest (`tests/support/universal-manifest.ts`): `Llama-3.2-1B-Instruct-4bit`, `Qwen2.5-0.5B-Instruct-4bit`, `Qwen3-0.6B-4bit`, `quantized-gemma-2b-it`, `gemma-2-2b-it-4bit`, `Phi-3.5-mini-instruct-4bit`, `GLM-4-9B-0414-4bit`, `granite-3.3-2b-instruct-4bit`, `starcoder2-3b-4bit`, `SmolLM3-3B-4bit` (all `mlx-community/`) and `ekryski/OLMo-2-0425-1B-Instruct-4bit` | 11 `model_type`s: `llama`, `smollm3`, `qwen2`, `qwen3`, `gemma`, `gemma2`, `phi3`, `olmo2`, `glm4`, `granite`, `starcoder2` (+ mlx-lm remaps `mistral`, `iquestcoder` → `llama`) · `universal-dense` graph · L1 | text | two-model · ngram | bf16
|
|
49
|
+
| Tier-0 generic | validated manifest (`tests/support/universal-manifest.ts`): `Llama-3.2-1B-Instruct-4bit`, `Qwen2.5-0.5B-Instruct-4bit`, `Qwen3-0.6B-4bit`, `quantized-gemma-2b-it`, `gemma-2-2b-it-4bit`, `Phi-3.5-mini-instruct-4bit`, `GLM-4-9B-0414-4bit`, `granite-3.3-2b-instruct-4bit`, `starcoder2-3b-4bit`, `SmolLM3-3B-4bit` (all `mlx-community/`) and `ekryski/OLMo-2-0425-1B-Instruct-4bit` | 11 `model_type`s: `llama`, `smollm3`, `qwen2`, `qwen3`, `gemma`, `gemma2`, `phi3`, `olmo2`, `glm4`, `granite`, `starcoder2` (+ mlx-lm remaps `mistral`, `iquestcoder` → `llama`) · `universal-dense` graph · L1 | text | two-model · ngram | bf16; Llama full-attention uniform KV4/KV8 | `ls` labels these `supported (generic)`. Shared full-attention execution is qualified on Llama-3.2-3B at B1/B4, including speculative KV4/KV8 and generated RAM/SSD state; gemma2-family / sliding-window archs run serial. No compiled specialization. A `model_type` absent from the table refuses to load. |
|
|
38
50
|
|
|
39
51
|
Rules that apply across rows (all enforced in `src/server.ts`):
|
|
40
52
|
|
|
@@ -45,8 +57,11 @@ Rules that apply across rows (all enforced in `src/server.ts`):
|
|
|
45
57
|
MTP is its own row. Qwen MTP companions may store dense or affine-quantized
|
|
46
58
|
projections; the loader uses each module's quantization metadata. Target
|
|
47
59
|
verification is unchanged, while draft acceptance and speed depend on the
|
|
48
|
-
companion.
|
|
49
|
-
|
|
60
|
+
companion. In the shared executor, qualified plain, uniform,
|
|
61
|
+
per-layer affine and TurboQuant layouts compose with drafting through the
|
|
62
|
+
target/provider interfaces. Positive affine conversion thresholds are also
|
|
63
|
+
supported by library requests. The loaded model and provider determine
|
|
64
|
+
which combinations can execute.
|
|
50
65
|
- **Qwen3.5-family checkpoint generations.** Both ship the same graph and both
|
|
51
66
|
load: the mlx-lm-converted naming (`language_model.model.*`,
|
|
52
67
|
`language_model.lm_head`, `vision_tower.*`) and the transformers-5.8 export
|
|
@@ -60,7 +75,9 @@ Rules that apply across rows (all enforced in `src/server.ts`):
|
|
|
60
75
|
- **KV schemes.** `--kv-quant 4|8` (uniform, L1) and `config` (per-layer
|
|
61
76
|
`kv_config.json`, L2) apply to the autoregressive families that ship the
|
|
62
77
|
file; `turbo` additionally requires a full-attention `head_dim` in
|
|
63
|
-
{64, 128, 256, 512} (refused at startup otherwise)
|
|
78
|
+
{64, 128, 256, 512} (refused at startup otherwise). Qualified TurboQuant
|
|
79
|
+
targets support shared ordinary and speculative execution; sliding layers
|
|
80
|
+
remain bf16;
|
|
64
81
|
`--paged-kv` is Gemma 4 only, bf16, serial. Flag detail:
|
|
65
82
|
[server-config.md](server-config.md).
|
|
66
83
|
- **Modalities.** Image requests reach a Gemma 4 model only when
|
|
@@ -323,3 +340,7 @@ Safety rails:
|
|
|
323
340
|
|
|
324
341
|
After a real deletion, gc re-scans so the registry drops the reaped
|
|
325
342
|
rows immediately.
|
|
343
|
+
|
|
344
|
+
|
|
345
|
+
Non-Qwen grouped TurboQuant drafting, including assistant donor attention, uses
|
|
346
|
+
the shared cache interfaces. See [composition coverage](../design/batching.md#turboquant-donor-attention-and-grouped-draft-composition).
|