mlx-bun 0.3.0 → 0.4.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/docs/README.md +4 -1
- package/docs/archive/investigations/openjarvis-fit.md +198 -0
- package/docs/archive/investigations/qwen38-27b-campaign-log.md +1092 -0
- package/docs/design/batching.md +1321 -49
- package/docs/design/decode-speed-program.md +331 -1163
- package/docs/design/generic-model-support.md +79 -3
- package/docs/design/kv-cache.md +198 -54
- package/docs/design/speculative-decoding.md +387 -24
- package/docs/design/turboquant.md +123 -13
- package/docs/design/unified-engine-frontier-plan.md +144 -142
- package/docs/planning/PRODUCT_ROADMAP.md +16 -0
- package/docs/planning/release-notes-v0.4.0.md +45 -0
- package/docs/reference/benchmarks.md +2457 -6
- package/docs/reference/cli.md +41 -2
- package/docs/reference/distribution.md +16 -9
- package/docs/reference/environment.md +55 -5
- package/docs/reference/models.md +13 -4
- package/docs/reference/server-api.md +79 -25
- package/docs/reference/server-config.md +178 -84
- package/docs/reference/troubleshooting.md +13 -21
- package/package.json +1 -1
- package/src/backends/mlx/assistant-target.ts +46 -0
- package/src/backends/mlx/autoregressive-draft-rows.ts +120 -0
- package/src/backends/mlx/batch-group.ts +368 -224
- 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 +106 -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/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 +77 -18
- package/src/backends/mlx/kv-codec.ts +9 -0
- package/src/backends/mlx/kv-maintenance.ts +133 -0
- package/src/backends/mlx/kv-tensor-rows.ts +212 -0
- package/src/backends/mlx/model-serving.ts +1 -1
- package/src/backends/mlx/prefill-cohort.ts +89 -0
- package/src/backends/mlx/prefill-rows.ts +200 -0
- package/src/backends/mlx/prefill.ts +1 -1
- package/src/backends/mlx/projected-context-rows.ts +72 -0
- package/src/backends/mlx/request-state-policy.ts +41 -0
- package/src/backends/mlx/rollback.ts +41 -3
- package/src/backends/mlx/row-sampling.ts +49 -0
- package/src/backends/mlx/serial-executor.ts +35 -66
- package/src/backends/mlx/speculative-group.ts +359 -0
- package/src/backends/mlx/speculative-round.ts +161 -0
- 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 +165 -0
- package/src/cli.ts +11 -36
- package/src/contracts/execution.ts +11 -0
- package/src/contracts/prefix-cache.ts +23 -0
- package/src/contracts/resources.ts +7 -0
- package/src/contracts/sampling.ts +23 -0
- package/src/contracts/scheduling.ts +18 -0
- package/src/engine/execution-plan.ts +18 -16
- package/src/engine/resources.ts +12 -1
- package/src/engine/scheduler.ts +10 -5
- package/src/fit.ts +29 -15
- package/src/generate.ts +77 -173
- package/src/inference/draft-acceptance.ts +41 -0
- package/src/inference/draft-output.ts +49 -0
- package/src/inference/rollback.ts +2 -2
- package/src/kv-scheme.ts +70 -12
- package/src/kv-store.ts +70 -16
- package/src/lab/paged-kv/paged-kv-rows.ts +83 -0
- package/src/lab/paged-kv/paged-kv.ts +25 -11
- package/src/mlx/array.ts +2 -1
- 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 +93 -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 +55 -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 +162 -80
- package/src/model/gemma4.ts +34 -26
- 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 +67 -0
- package/src/model/minicpm5.ts +11 -7
- package/src/model/qwen3-delta-state.ts +74 -0
- package/src/model/qwen3-delta.ts +59 -36
- package/src/model/qwen3_5.ts +82 -42
- 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/trellis-linear.ts +2 -2
- package/src/model/turboquant-codec.ts +83 -0
- package/src/model/universal/dense.ts +14 -13
- package/src/preflight.ts +31 -15
- package/src/prompt-cache.ts +42 -44
- package/src/sampler.ts +36 -25
- package/src/serve/chat-stage.ts +2 -2
- package/src/serve/generation-gateway.ts +39 -30
- package/src/serve/model-host.ts +3 -4
- package/src/serve/request-plan.ts +4 -3
- package/src/serve/request-prep.ts +2 -4
- package/src/serve/text-completion-stage.ts +2 -2
- package/src/server.ts +64 -108
- package/src/spec/assistant-rows.ts +92 -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 +53 -136
- package/src/spec/glm52-mtp-state.ts +33 -0
- package/src/spec/ngram-source.ts +92 -20
- 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 +219 -0
- package/src/spec/qwen-mtp-source.ts +81 -226
- package/src/spec/qwen-mtp-state.ts +30 -0
- package/src/spec/serve-loop.ts +70 -68
- package/src/spec/source.ts +80 -15
- package/src/spec/two-model-rows.ts +61 -0
- package/src/spec/two-model.ts +43 -101
- package/src/ssd-cache.ts +33 -21
- package/src/ssd-durability.ts +11 -7
- package/src/web/app.js +57 -57
- 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
|
@@ -6,11 +6,983 @@ structured backing record is the user-local eval DB
|
|
|
6
6
|
(`~/.cache/mlx-bun/evals.sqlite`). Promote a run into this file
|
|
7
7
|
deliberately when it becomes the new reference.
|
|
8
8
|
|
|
9
|
+
New raw request records also retain the server's final `usage` object,
|
|
10
|
+
including execution lane and speculative counters when supplied. The reader
|
|
11
|
+
captures these already-parsed fields after timing finishes; older reports may
|
|
12
|
+
lack them. This lets settings comparisons verify which method actually ran.
|
|
13
|
+
|
|
9
14
|
The optional `mlx-bun-isolated` arm runs the same CLI/model/request cells through
|
|
10
15
|
`--isolate`; select it alongside `mlx-bun` to compare transport cost. Its RSS
|
|
11
16
|
column sums the parent and descendant processes. This is aggregate process RSS,
|
|
12
17
|
not deduplicated physical memory; shared runtime pages may appear in both.
|
|
13
18
|
|
|
19
|
+
The current closeout candidate follows Josh's advisory-memory policy: requests
|
|
20
|
+
are attempted without fit-based refusal or completion clamping by default.
|
|
21
|
+
Earlier reservation variants remain diagnostics, including successful trials;
|
|
22
|
+
they are not the product policy. Explicit budgets/context caps still apply.
|
|
23
|
+
No speed default has been promoted by these memory experiments.
|
|
24
|
+
|
|
25
|
+
The advisory candidate's M4 Pro replay (`m4-advisory-short.md.json`) retains
|
|
26
|
+
all 23 comparable successful request outputs and usage/cache counts from
|
|
27
|
+
the earlier R0 run. Five-sample decode medians are 14.812 tok/s serial and
|
|
28
|
+
14.677 tok/s continuous; this is one diagnostic run, not a paired speed win.
|
|
29
|
+
Both lanes complete decode and cold/warm 1K prefill. The aggregate retained
|
|
30
|
+
history hits actual Metal insufficient-memory errors: serial recovers on the
|
|
31
|
+
harness retry; continuous fails both attempts. These are runtime failures,
|
|
32
|
+
not predictive refusals. Local regression tests deliberately give the live
|
|
33
|
+
model an impossible accounting estimate and verify both lanes still execute.
|
|
34
|
+
Review: `reports/qwen38-closeout/m4-advisory-short-review.json`.
|
|
35
|
+
|
|
36
|
+
## Rotating target speculation through shared execution
|
|
37
|
+
|
|
38
|
+
M4 Pro 24 GB, Bun 1.4.2, MLX 0.32.2. Gemma 4 12B OptiQ, prompt lookup
|
|
39
|
+
at its default depth ten, bf16 KV, 2 GiB RAM cache plus temporary SSD,
|
|
40
|
+
192 decode tokens, four concurrent requests and default capacity eight.
|
|
41
|
+
Production `bench-serve.ts all`, context sweep skipped, seed `rotating-spec-0`,
|
|
42
|
+
diagnostic mode under Josh's machine policy. Final comparison order is
|
|
43
|
+
control-1, candidate-2, control-2, candidate-3; an earlier candidate-1 predates
|
|
44
|
+
the final singleton boundary correction and is excluded from these means.
|
|
45
|
+
|
|
46
|
+
| Metric (mean of two arms) | Previous serial placement | Shared rotating placement | Change |
|
|
47
|
+
|---|---:|---:|---:|
|
|
48
|
+
| Single-request decode | 16.928 tok/s | 16.894 tok/s | −0.2% |
|
|
49
|
+
| Four-request throughput | 17.269 tok/s | 22.130 tok/s | +28.1% |
|
|
50
|
+
| Four-request wall time | 29,648.128 ms | 23,139.278 ms | −22.0% |
|
|
51
|
+
| Repeated-prompt TTFT | 2,505.201 ms | 199.600 ms | −92.0% |
|
|
52
|
+
| Cold prefill TTFT | 2,515.753 ms | 2,524.302 ms | +0.3% |
|
|
53
|
+
| Launch to first output | 1,571.428 ms | 1,631.817 ms | +3.8% |
|
|
54
|
+
|
|
55
|
+
All 60 recorded requests complete with matching bodies and token budgets.
|
|
56
|
+
Single-request text and raw completion/chat probes match. All four concurrent
|
|
57
|
+
responses differ across implementations, while each implementation's repeats
|
|
58
|
+
are exact. This measures fixed output budgets with different concurrent
|
|
59
|
+
trajectories. The shared cache reuses 671 tokens versus zero in the control.
|
|
60
|
+
Startup spans roughly 1.1–2.2 seconds in both arms; its mean does not establish
|
|
61
|
+
strict dominance. This closes the bf16 rotating transaction implementation,
|
|
62
|
+
not all speculative compositions or strict serial-removal acceptance.
|
|
63
|
+
|
|
64
|
+
Control source: `20c21f2f62383b9878966f8ea1bf74c98d58942d33351430042ff7801cb929c4`.
|
|
65
|
+
Final candidate: `c8213540beb87f438fbafad7115b49f494e92526c28acca930f134883d5cfdcf`.
|
|
66
|
+
The change is integrated in the unreleased tree. Evidence:
|
|
67
|
+
`reports/qwen38-closeout/composition-baseline/rotating-speculation/`, including
|
|
68
|
+
`benchmark-comparison.json` and all raw M4 reports.
|
|
69
|
+
|
|
70
|
+
## Full-attention speculation through shared execution
|
|
71
|
+
|
|
72
|
+
M4 Pro 24 GB, Bun 1.4.2, MLX 0.32.2. Llama 3.2 3B target and 1B
|
|
73
|
+
standalone drafter (4-bit weights), draft depth two, bf16 KV, 2 GiB RAM
|
|
74
|
+
plus temporary SSD. Production `bench-serve.ts all`, 192 decode tokens,
|
|
75
|
+
four concurrent requests, default capacity eight, seed `full-kv-spec-0`,
|
|
76
|
+
context sweep skipped, diagnostic mode under Josh's machine policy.
|
|
77
|
+
The same draft engine runs in both arms; target placement and paired cache
|
|
78
|
+
reuse change. Order: control, candidate, candidate, control.
|
|
79
|
+
|
|
80
|
+
| Metric (mean of two arms) | Previous serial placement | Shared placement | Change |
|
|
81
|
+
|---|---:|---:|---:|
|
|
82
|
+
| Single-request decode | 120.890 tok/s | 129.319 tok/s | +7.0% |
|
|
83
|
+
| Four-request throughput | 108.167 tok/s | 162.331 tok/s | +50.1% |
|
|
84
|
+
| Four-request wall time | 4,733.455 ms | 3,154.056 ms | −33.4% |
|
|
85
|
+
| Repeated-prompt TTFT | 891.394 ms | 44.685 ms | −95.0% |
|
|
86
|
+
| Cold prefill TTFT | 893.065 ms | 919.492 ms | +3.0% |
|
|
87
|
+
| Launch to first output | 1,070.260 ms | 978.795 ms | −8.5% |
|
|
88
|
+
|
|
89
|
+
All 60 requests complete, with identical request bodies and token counts.
|
|
90
|
+
Single-request text and raw completion/chat probes match. One of four
|
|
91
|
+
concurrent responses changes across implementations; each implementation's
|
|
92
|
+
repeats are exact. Usage differs by execution lane, repeated-prefix reuse
|
|
93
|
+
(752 tokens versus zero), and the changed response's speculative counters.
|
|
94
|
+
Thus aggregate timing holds token budgets fixed, with one changed trajectory.
|
|
95
|
+
The control launch times span 970–1,171 ms; this is not strict startup
|
|
96
|
+
acceptance. Cold-prefill latency still regresses. The change is integrated
|
|
97
|
+
in the unreleased tree; defaults remain unchanged.
|
|
98
|
+
|
|
99
|
+
Control source: `3a420497bf8a8c6be5896050b45773d541515a22e737d8775522d742221a8d41`.
|
|
100
|
+
Candidate source: `20c21f2f62383b9878966f8ea1bf74c98d58942d33351430042ff7801cb929c4`.
|
|
101
|
+
Evidence: `reports/qwen38-closeout/composition-baseline/full-kv-speculation/`,
|
|
102
|
+
including four raw M4 reports and `benchmark-comparison.json`.
|
|
103
|
+
|
|
104
|
+
## Standalone drafting: first shared-executor comparison
|
|
105
|
+
|
|
106
|
+
M4 Pro 24 GB, Bun 1.4.2, MLX 0.32.2. Qwen3.8 packed 27B target plus
|
|
107
|
+
Qwen3.5 0.8B OptiQ standalone drafter, depth two, KV4 from token zero,
|
|
108
|
+
4 GiB RAM cache plus temporary SSD, 192 decode tokens and four concurrent
|
|
109
|
+
requests. Production `bench-serve.ts all`, seed `standalone-serving-0`,
|
|
110
|
+
context sweep skipped; advisory diagnostic mode under Josh's machine policy.
|
|
111
|
+
|
|
112
|
+
| First run | Single-request decode | Repeated-prompt TTFT | Reused tokens | Four-request throughput |
|
|
113
|
+
|---|---:|---:|---:|---:|
|
|
114
|
+
| Previous standalone provider | 8.936 tok/s | 5,987.688 ms | 0 | 8.617 tok/s |
|
|
115
|
+
| Shared standalone candidate | 13.945 tok/s | 122.100 ms | 756 | GPU allocation failure |
|
|
116
|
+
|
|
117
|
+
The initial candidate's aggregate phase failed both attempts with native Metal
|
|
118
|
+
insufficient-memory errors. A complete-sequence profile reproduces the failure
|
|
119
|
+
with 4,005 MiB of accounted cache entries and an observed 17,987 MiB peak;
|
|
120
|
+
a fresh aggregate completes. Retained RAM entries consume batch headroom.
|
|
121
|
+
|
|
122
|
+
A second matched comparison uses **2 GiB RAM plus SSD in both arms**, in
|
|
123
|
+
candidate/control/control/candidate order. Other settings are unchanged;
|
|
124
|
+
default capacity is eight, with four concurrent requests. All 60 recorded
|
|
125
|
+
requests complete without failures. Means of the per-arm measurements:
|
|
126
|
+
|
|
127
|
+
| Metric | Previous standalone provider | Shared standalone provider | Change |
|
|
128
|
+
|---|---:|---:|---:|
|
|
129
|
+
| Single-request decode | 8.882 tok/s | 13.970 tok/s | +57.3% |
|
|
130
|
+
| Four-request throughput | 8.614 tok/s | 9.343 tok/s | +8.5% |
|
|
131
|
+
| Four-request wall time | 59.437 s | 54.807 s | −7.8% |
|
|
132
|
+
| Repeated-prompt TTFT | 5,989.823 ms | 122.527 ms | −98.0% |
|
|
133
|
+
| Cold prefill TTFT | 5,993.083 ms | 6,153.492 ms | +2.7% |
|
|
134
|
+
| Launch to first output | 4,332.735 ms | 4,537.720 ms | +4.7% |
|
|
135
|
+
|
|
136
|
+
All request bodies, token counts and single-request text match; raw completion
|
|
137
|
+
and chat probes also match. Candidate repeats preserve single-request text and
|
|
138
|
+
usage. Concurrent text and acceptance counters differ both across implementations
|
|
139
|
+
and between candidate repeats as admission geometry changes; throughput is a
|
|
140
|
+
fixed-token-budget serving measurement, not identical generated content.
|
|
141
|
+
The new provider retains recurrent draft history after rejection; the old
|
|
142
|
+
provider discarded that history. It also retains paired cache state, with
|
|
143
|
+
756 tokens reused on the repeated prompt versus zero in the control.
|
|
144
|
+
|
|
145
|
+
The provider is integrated in the unreleased working tree. The cold/startup
|
|
146
|
+
cost and the 4 GiB failure remain; this does not close strict serial dominance
|
|
147
|
+
or select application defaults. MTP comparisons use a different drafter and
|
|
148
|
+
must remain separate. Control source is
|
|
149
|
+
`0a7e65986e57b493e7ab30a2e328a1eb591b03b029f59e342fd8a01471538613`;
|
|
150
|
+
candidate source
|
|
151
|
+
`3a420497bf8a8c6be5896050b45773d541515a22e737d8775522d742221a8d41`.
|
|
152
|
+
Evidence: `reports/qwen38-closeout/composition-baseline/two-model-batch/`,
|
|
153
|
+
including `ram2/benchmark-comparison.json` and raw request records.
|
|
154
|
+
|
|
155
|
+
## Current serial versus shared execution: staggered Gemma requests
|
|
156
|
+
|
|
157
|
+
M4 Pro 24 GB, Bun 1.4.2, MLX 0.32.2/native pack 0.4.0, unreleased source
|
|
158
|
+
`0a7e65986e57b493e7ab30a2e328a1eb591b03b029f59e342fd8a01471538613`.
|
|
159
|
+
Gemma 4 12B OptiQ, ordinary KV4, 4 GiB RAM prompt cache and temporary SSD.
|
|
160
|
+
`bench-serve.ts all` uses 192 decode tokens, skipped context sweep,
|
|
161
|
+
`--aggregate-context 2048 --aggregate-stagger-ms 25`, seed `prefill-long-0`.
|
|
162
|
+
The serial arm pins `--batch 1`; the shared arm uses the default capacity eight. The four aggregate prompts contain 1,289/1,281/1,287/1,287
|
|
163
|
+
tokens with 13/12/14/12 cached, and each emits 128 tokens. Diagnostic mode
|
|
164
|
+
follows Josh's retained-swap policy; no competing GPU job runs during timing.
|
|
165
|
+
|
|
166
|
+
| run order | median decode tok/s | cached first-token ms | aggregate tok/s | aggregate wall ms | first request TTFT ms | mean TTFT ms |
|
|
167
|
+
|---|---:|---:|---:|---:|---:|---:|
|
|
168
|
+
| serial 0 | 26.3177 | 155.205 | 11.4938 | 44545.58 | 10037.72 | 24644.60 |
|
|
169
|
+
| shared 0 | 26.0648 | 155.797 | 19.7660 | 25903.03 | 9287.39 | 16360.50 |
|
|
170
|
+
| shared 1 | 26.2129 | 154.351 | 20.1601 | 25396.75 | 9031.62 | 15985.86 |
|
|
171
|
+
| serial 1 | 25.9724 | 156.207 | 13.0064 | 39365.23 | 4776.07 | 19477.02 |
|
|
172
|
+
|
|
173
|
+
Mean aggregate throughput increases **62.96%**, total aggregate time falls
|
|
174
|
+
**38.86%**, and mean first-token latency falls **26.69%**. Single-request
|
|
175
|
+
decode is effectively equal, −0.024% in throughput or +0.056% in summed
|
|
176
|
+
request time; cached latency falls 0.406%. First-request latency does not
|
|
177
|
+
dominate: the second serial sample starts in 4.78 s versus shared samples
|
|
178
|
+
near 9.1 s. Startup also has an initial serial outlier, so it is not a settled
|
|
179
|
+
comparison. These limits keep strict serial deletion acceptance open.
|
|
180
|
+
|
|
181
|
+
All 60 requests complete without failure. Request bodies, usage excluding
|
|
182
|
+
the expected lane label, token/cache counts and finish markers match. All
|
|
183
|
+
single-request texts match; all four concurrent texts differ between serial
|
|
184
|
+
and shared. Repeated runs of each arm produce identical text. This measures
|
|
185
|
+
throughput for the same submitted workload and output-token budgets, not
|
|
186
|
+
identical generated content. Same-B model oracle checks remain separate.
|
|
187
|
+
Source hashes stay fixed throughout both blocks. Raw reports and comparison:
|
|
188
|
+
`reports/qwen38-closeout/composition-baseline/current-serial-dominance/`.
|
|
189
|
+
|
|
190
|
+
## Delayed full-attention padding: M4 comparison
|
|
191
|
+
|
|
192
|
+
The unreleased cache implementation now supports padded prefill while full
|
|
193
|
+
attention rows transition independently from BF16 to affine or TurboQuant.
|
|
194
|
+
Shared row positions and codec ownership replace separate padding logic.
|
|
195
|
+
The existing uniform KV4 decode still uses the same packed attention code.
|
|
196
|
+
|
|
197
|
+
M4 Pro 24 GB, Bun 1.4.2, MLX 0.32.2/native pack 0.4.0. Qwen3.8-27B packed
|
|
198
|
+
interleave2 target and folded RTN4 MTP companion, depth 2, KV4 from token zero,
|
|
199
|
+
4 GiB RAM prompt cache, temporary SSD cache, configured batch capacity 8,
|
|
200
|
+
four concurrent requests. Production `bench-serve.ts all`, 192 decode tokens,
|
|
201
|
+
`--skip-context`, workload seed `mtp-serving-block-0`, async expansion off and
|
|
202
|
+
fused TQ decode enabled. Diagnostic mode follows Josh's retained-swap policy;
|
|
203
|
+
free memory starts at 90–93%, retained swap at 1.6–2.8 GiB. No other GPU job
|
|
204
|
+
runs during timing. The audio-daemon allowance is explicit.
|
|
205
|
+
|
|
206
|
+
| arm, in order | median decode tok/s | aggregate tok/s | cached first-token ms | ready ms | cold start ms |
|
|
207
|
+
|---|---:|---:|---:|---:|---:|
|
|
208
|
+
| control 1 | 19.2267 | 16.4810 | 98.186 | 610.78 | 4085.57 |
|
|
209
|
+
| candidate 1 | 19.1023 | 16.4524 | 98.070 | 821.10 | 4167.10 |
|
|
210
|
+
| candidate 2 | 19.1224 | 16.4746 | 99.601 | 614.60 | 4009.12 |
|
|
211
|
+
| control 2 | 19.3181 | 16.5351 | 99.174 | 621.53 | 3982.93 |
|
|
212
|
+
|
|
213
|
+
Candidate/control means change decode throughput by −0.831%, aggregate
|
|
214
|
+
throughput by −0.270%, cached latency by +0.157%, and cold start by +1.335%.
|
|
215
|
+
One candidate readiness sample is about 200 ms higher; the other overlaps
|
|
216
|
+
controls. These measurements establish no speed improvement or strict serial
|
|
217
|
+
performance dominance. The feature is integrated with these limits recorded;
|
|
218
|
+
long-prefill and B1 performance acceptance remain open.
|
|
219
|
+
|
|
220
|
+
All 60 request bodies, responses, usage/speculation counters, token counts,
|
|
221
|
+
finish reasons and completion markers match. No requests fail. Each source
|
|
222
|
+
snapshot stays fixed: control `7f06df944eb062703711f29b086879718868803c00367dd992b3a5bb8d0fac8e`,
|
|
223
|
+
candidate `0a7e65986e57b493e7ab30a2e328a1eb591b03b029f59e342fd8a01471538613`.
|
|
224
|
+
Both-machine cache/model and seeded delayed-conversion gates accompany this
|
|
225
|
+
comparison. Evidence: `reports/qwen38-closeout/composition-baseline/full-delayed-prefill/`,
|
|
226
|
+
including `benchmark-comparison.json`, `manifest.json`, and `m4/` raw reports.
|
|
227
|
+
|
|
228
|
+
## Shared MTP prefill: M4 comparison and scheduling attribution
|
|
229
|
+
|
|
230
|
+
Apple M4 Pro, 24 GB; Bun 1.4.2, MLX 0.32.2. Packed interleave2
|
|
231
|
+
Qwen3.8-27B, affine KV4, folded MTP2, four concurrent requests (configured
|
|
232
|
+
maximum batch 8), 4 GiB prompt cache,
|
|
233
|
+
192 output tokens per decode request, five decode samples, context sweep off.
|
|
234
|
+
`bench-serve.ts all` uses workload seed `mtp-serving-block-0`, fused TQ enabled
|
|
235
|
+
and async Trellis expansion disabled. Four balanced runs use
|
|
236
|
+
control/candidate/candidate/control order. The first control started with zero
|
|
237
|
+
swap; subsequent runs used `--diagnostic` after swap returned. All runs finished
|
|
238
|
+
without request failures and retained stable source hashes within each run.
|
|
239
|
+
|
|
240
|
+
| Preparation policy | Runs | Mean decode median tok/s | Mean concurrent tok/s |
|
|
241
|
+
|---|---:|---:|---:|
|
|
242
|
+
| Control: existing MTP preparation | 2 | 19.331 | 15.194 |
|
|
243
|
+
| Common driver, shared prefill | 2 | 19.069 | 14.076 |
|
|
244
|
+
| Common driver, individual preparation | 2 | 19.158 | 15.508 |
|
|
245
|
+
| Common driver, finish resumed final step first | 1 | 19.3 | 14.099 |
|
|
246
|
+
|
|
247
|
+
Shared prefill loses **1.35%** single-request decode rate and **7.36%** concurrent
|
|
248
|
+
throughput relative to the balanced control means. Mean concurrent wall time
|
|
249
|
+
rises from 33.718 to 36.374 seconds. Cached first-output latency is 98.23 versus
|
|
250
|
+
99.85 ms; cold 1K first-output latency is 5844.61 versus 5997.68 ms.
|
|
251
|
+
|
|
252
|
+
All 60 requests in the balanced comparison preserve request hashes,
|
|
253
|
+
prompt/output/cache counts, finish reasons and completion markers. Single-request
|
|
254
|
+
text and usage are exact. Three of four concurrent responses change between
|
|
255
|
+
control and candidate; each arm reproduces its own text and full usage exactly.
|
|
256
|
+
Thus this is a serving comparison with changed concurrent numerical trajectories,
|
|
257
|
+
not an identical-work kernel timing. Total concurrent speculative rounds fall
|
|
258
|
+
from 234 to 232, so an increase in round count does not explain the slowdown.
|
|
259
|
+
|
|
260
|
+
The individual-preparation control changes only the scheduler admission budget
|
|
261
|
+
from 2048 to zero and retains B4 decode and the same common driver. Both runs
|
|
262
|
+
reproduce every control response and full usage record. The clean repeat
|
|
263
|
+
confirmed that this is the only source difference. Finishing resumed final
|
|
264
|
+
steps first instead leaves concurrent responses/usage identical to shared
|
|
265
|
+
prefill and does not recover its throughput. None of these isolated candidates
|
|
266
|
+
is adopted. The next investigation is preparation-to-decode cache state and
|
|
267
|
+
actual work per round.
|
|
268
|
+
|
|
269
|
+
Two instrumented follow-ups locate the sustained cost in target verification.
|
|
270
|
+
Across 53 B4 rounds per arm, median complete-round time is 540.64 ms with
|
|
271
|
+
shared preparation versus 459.01 ms with individual preparation. The target
|
|
272
|
+
forward interval is 510.50 versus 430.34 ms; draft generation is 12.11 versus
|
|
273
|
+
12.15 ms. These are lazy-execution phase timings, so the target interval includes
|
|
274
|
+
any work it forces; layer-level attribution is still needed. Independent saved
|
|
275
|
+
SSE timestamps reproduce the uninstrumented gap (about 542 versus 459 ms
|
|
276
|
+
between output bursts during seconds 10–25).
|
|
277
|
+
|
|
278
|
+
Further probes run three B4 rounds with layer synchronization. Both arms use
|
|
279
|
+
128 packed gate/up calls and 64 expanded down-projection calls, with identical
|
|
280
|
+
M=12 and bf16 geometry. The down-projection evaluation interval, which also
|
|
281
|
+
forces the preceding lazy packed gate/up work, is 412.68 versus 355.75 ms.
|
|
282
|
+
This narrows the cost to MLP evaluation but does not distinguish its packed
|
|
283
|
+
kernels from weight expansion/native matmul. Phase/layer probes preserve their
|
|
284
|
+
respective control responses and usage. A separate candidate evaluates target
|
|
285
|
+
state and clears the temporary buffer pool after preparation; it completes
|
|
286
|
+
without failures at 14.3 concurrent tok/s, still below individual preparation.
|
|
287
|
+
It is not adopted. Profiles: `mtp-cohort-layer-profile.json` and
|
|
288
|
+
`mtp-cohort-trellis-profile.json`; drain result: `mtp-cohort-drain-manifest.json`.
|
|
289
|
+
|
|
290
|
+
A subsequent split probe evaluates inputs, packed projections, expanded weights
|
|
291
|
+
and matrix products separately. Across three instrumented B4 rounds, median
|
|
292
|
+
expansion time is 157.92 ms after shared preparation versus 85.55 ms after
|
|
293
|
+
individual preparation. Packed gate/up evaluation is 232.03 versus 229.83 ms;
|
|
294
|
+
expanded-weight matrix multiplication is 88.75 versus 84.07 ms. These inserted
|
|
295
|
+
synchronization points change absolute latency and serve only to locate work.
|
|
296
|
+
The separate input-evaluation candidate passes M1 native MTP serving but reaches
|
|
297
|
+
13.8 concurrent tok/s on the M4, so it is not adopted. Evidence:
|
|
298
|
+
`mtp-cohort-split-profile.json`, `split-profile-*.md.json`, `input-eval-1.md.json`.
|
|
299
|
+
|
|
300
|
+
Smaller vector expansion tiles (32, 64 and untiled) reach 14.15–14.22
|
|
301
|
+
concurrent tok/s; variant 12 reaches 13.30; a residency refresh reaches 14.00.
|
|
302
|
+
All preserve their shared-prefill reference responses and usage, and none is
|
|
303
|
+
adopted. Memory instrumentation observes 16.823 GiB active after shared
|
|
304
|
+
preparation versus 16.534 GiB after individual preparation. A native ownership
|
|
305
|
+
probe confirms that a deferred compact row copy retains its larger parent
|
|
306
|
+
allocation until evaluated.
|
|
307
|
+
|
|
308
|
+
Evaluating target snapshots before RAM retention recovers concurrent throughput
|
|
309
|
+
in two M4 runs: **16.268 and 16.299 tok/s**, averaging 16.283, versus 14.076
|
|
310
|
+
for the original shared-preparation pair (**+15.68%**) and 15.508 for the two
|
|
311
|
+
individual-preparation controls (**+5.00%**). Concurrent wall time falls to
|
|
312
|
+
31.473 and 31.414 seconds. Single-request decode medians are 19.277 and 19.108
|
|
313
|
+
tok/s; cached first output is 100.66 and 100.76 ms. All 30 requests preserve
|
|
314
|
+
request hashes, output text and full usage exactly against shared preparation.
|
|
315
|
+
Source is stable in both runs. The M1 native serving test passes 229 assertions.
|
|
316
|
+
The final implementation below moves this behavior from method-local capture
|
|
317
|
+
to the common cache ownership boundary for every producer.
|
|
318
|
+
Evidence: `mtp-cohort-snapshot-eval-review.json`,
|
|
319
|
+
`mtp-cohort-expansion-screen-review.json`, `mtp-cohort-memory-profile.json`.
|
|
320
|
+
|
|
321
|
+
Moving materialization into the shared RAM cache, including companion tensors,
|
|
322
|
+
preserves all 30 responses and usage records in two further M4 runs. Concurrent
|
|
323
|
+
throughput is **16.477 and 16.384 tok/s**; single-request decode is 19.127 and
|
|
324
|
+
19.205 tok/s; cached first output is 97.62 and 98.79 ms. The common implementation
|
|
325
|
+
passes 2,150 M1 tests (14 skipped), all typechecks, and the generated TurboQuant
|
|
326
|
+
RAM/SSD continuation test at MTP3/B4. M1 native lookup passes 228 assertions and the ordinary 4096-token TQ prefix
|
|
327
|
+
ownership test passes 40. A fresh current-tree control reaches 19.245 decode
|
|
328
|
+
and 15.539 concurrent tok/s, with 99.02 ms cached first output. Against that
|
|
329
|
+
control, the common-cache pair averages **5.74% higher concurrent throughput**,
|
|
330
|
+
0.41% lower single-request decode and 0.83% lower cached first-output latency.
|
|
331
|
+
This is a two-candidate/one-control comparison; the older balanced control
|
|
332
|
+
pair remains above. The M4 suite passes 2,154 tests (10 skipped), both-machine typechecks pass, and
|
|
333
|
+
M4 native TQ MTP serving passes 229 assertions. The shared driver and common
|
|
334
|
+
cache fix are adopted in the unreleased working tree; main integration
|
|
335
|
+
suite, typechecks and hygiene pass. Strict serial dominance remains open. Review:
|
|
336
|
+
`mtp-cohort-cache-boundary-review.json`; source/validation:
|
|
337
|
+
`mtp-cohort-cache-boundary-manifest.json`.
|
|
338
|
+
|
|
339
|
+
The final memory profile differs from the original shared-preparation profile
|
|
340
|
+
only in the two cache implementation files. Active GPU allocation falls from
|
|
341
|
+
16.823 to **16.458 GiB**, releasing **373.37 MiB**. Median weight-expansion time
|
|
342
|
+
falls from **147.57 to 86.17 ms** across three instrumented B4 rounds, matching
|
|
343
|
+
the individual-preparation profile's 87.99 ms. Routes, geometry and call counts
|
|
344
|
+
are unchanged; all 15 responses and full usage remain exact. The retained-memory
|
|
345
|
+
regression passes with materialization and fails when it is disabled. Profile
|
|
346
|
+
latencies locate the cost; the uninstrumented runs above measure serving speed.
|
|
347
|
+
Evidence: `mtp-cohort-memory-profile.json` and
|
|
348
|
+
`memory-profile-cache-boundary.md.json`.
|
|
349
|
+
|
|
350
|
+
Evidence: `reports/qwen38-closeout/composition-baseline/prefill-cohort/`:
|
|
351
|
+
`mtp-cohort-benchmark-comparison.json`, `mtp-cohort-admission-comparison.json`,
|
|
352
|
+
source manifests/patches, seven comparison runs and instrumented follow-ups in
|
|
353
|
+
`mtp-cohort-m4/*.md.json`; phase timing is in `mtp-cohort-phase-profile.json`.
|
|
354
|
+
|
|
355
|
+
## Delayed affine row composition: fixed-settings M4 regression
|
|
356
|
+
|
|
357
|
+
Apple M4 Pro, 24 GB, macOS 27.0.0, Bun 1.4.2, MLX 0.32.2/native pack
|
|
358
|
+
0.4.0. The existing `bench-serve.ts all` suite ran control/candidate/candidate/control
|
|
359
|
+
on the packed interleave2 Qwen3.8-27B artifact with KV4, MTP2, 192 output tokens,
|
|
360
|
+
five decode requests, prompt cache 4 and context sweep disabled. Workload seed
|
|
361
|
+
`mtp-serving-block-0`; fused TQ enabled, async Trellis expansion disabled.
|
|
362
|
+
All preflights passed with Josh's audio-daemon allowance. Source stayed fixed:
|
|
363
|
+
control `88da0dca100cdb012cbd4330638cc43b727dbb853a5b1ef6aded60bc6fe1eb0d`,
|
|
364
|
+
candidate `eacbb8c7d9e1a2f06c4235f71dc7db51f29b8bd27a9940a5e802a056220ff336`.
|
|
365
|
+
Remote checkout HEAD was `0c355f4`; source hashes include the unreleased changes.
|
|
366
|
+
|
|
367
|
+
| Arm | Five decode requests, total ms | Cached TTFT ms | Concurrent aggregate tok/s |
|
|
368
|
+
|---|---:|---:|---:|
|
|
369
|
+
| Control 1 | 55,730.95 | 97.33 | 15.9259 |
|
|
370
|
+
| Candidate 1 | 55,585.20 | 97.57 | 15.8891 |
|
|
371
|
+
| Candidate 2 | 55,678.22 | 99.36 | 15.7890 |
|
|
372
|
+
| Control 2 | 55,682.47 | 99.41 | 15.7812 |
|
|
373
|
+
|
|
374
|
+
All 60 request records retain identical request hashes, response text, complete
|
|
375
|
+
usage, token counts and finish reasons. Combined candidate/control changes are
|
|
376
|
+
−0.135% decode wall time, +0.099% cached latency and −0.091% aggregate throughput.
|
|
377
|
+
Peak RSS is effectively unchanged. Startup was less stable: the initial control
|
|
378
|
+
reached readiness in 608 ms versus about 800 ms in the later arms, and its cold
|
|
379
|
+
start was 3,443 ms versus about 4,200–4,300 ms afterward. The candidate overlaps
|
|
380
|
+
the final control, but this screen does not establish startup equivalence.
|
|
381
|
+
The decode and cached-latency changes overlap the observed
|
|
382
|
+
control variation: the existing default path is effectively flat. This is a
|
|
383
|
+
regression check for integrating delayed-affine support and the shared transition
|
|
384
|
+
lifecycle, not a measurement of delayed conversion speed or serial dominance.
|
|
385
|
+
Both-machine native/serving/SSD correctness gates qualify the new composition.
|
|
386
|
+
Raw records and comparison: `reports/qwen38-closeout/composition-baseline/delayed-affine/`.
|
|
387
|
+
|
|
388
|
+
## Captured attention views: M4 regression
|
|
389
|
+
|
|
390
|
+
Same M4 Pro 24 GB/toolchain, packed Qwen artifact and 192-token KV4/MTP2
|
|
391
|
+
protocol as the delayed-affine comparison above. Order is again
|
|
392
|
+
control/candidate/candidate/control, with unchanged requests and initial cache
|
|
393
|
+
settings. Control source is
|
|
394
|
+
`eacbb8c7d9e1a2f06c4235f71dc7db51f29b8bd27a9940a5e802a056220ff336`;
|
|
395
|
+
candidate source is
|
|
396
|
+
`f94a8212be222056a0d1cdc70c45c3d7f2e50a937eb89560a719ee4bf21c61f7`.
|
|
397
|
+
Both sources remain fixed throughout their runs.
|
|
398
|
+
|
|
399
|
+
| Arm | Five decode requests, total ms | Cached TTFT ms | Concurrent aggregate tok/s |
|
|
400
|
+
|---|---:|---:|---:|
|
|
401
|
+
| Control 1 | 55,784.51 | 97.57 | 15.8553 |
|
|
402
|
+
| Candidate 1 | 55,656.05 | 97.18 | 15.9355 |
|
|
403
|
+
| Candidate 2 | 55,687.98 | 97.26 | 15.9648 |
|
|
404
|
+
| Control 2 | 55,680.16 | 97.45 | 15.9668 |
|
|
405
|
+
|
|
406
|
+
All 60 request records match in input hash, output text, complete usage, token
|
|
407
|
+
counts and finish reason. Combined decode wall time changes −0.108%, cached
|
|
408
|
+
latency −0.298%, and aggregate throughput +0.246%; peak RSS is unchanged.
|
|
409
|
+
These are effectively flat regression results, not a general speedup or serial
|
|
410
|
+
dominance result. Initial-control startup was faster than every subsequent
|
|
411
|
+
arm: readiness 607 ms versus 817–818 ms; cold start 3,487 ms versus 4,210–4,254 ms.
|
|
412
|
+
Startup equivalence remains unproven.
|
|
413
|
+
|
|
414
|
+
All start checks pass with the audio-daemon allowance. The final control's raw
|
|
415
|
+
end check flags `/usr/libexec/mobileassetd` at 84% CPU and 23 MB RSS, while free
|
|
416
|
+
memory remains 92%. That flag remains in the raw result. Under Josh's policy
|
|
417
|
+
allowing isolated background CPU activity, the stable paired decode/cached
|
|
418
|
+
measurements support feature integration; this is not an entirely unflagged
|
|
419
|
+
four-arm run. The initial wrapper's separate oracle-path error occurred before
|
|
420
|
+
inference and is retained as a failed launch, not a timing sample.
|
|
421
|
+
|
|
422
|
+
The changed attention-view operations are qualified by both-machine full-model
|
|
423
|
+
Gemma/MiniCPM state/logit checks, Qwen rollback/MTP/lookup checks and exact SSD
|
|
424
|
+
continuations. This default-settings screen does not measure delayed conversion
|
|
425
|
+
speed. Evidence: `reports/qwen38-closeout/composition-baseline/kv-attention-view/`.
|
|
426
|
+
|
|
427
|
+
## Delayed rotating affine composition: M4 regression
|
|
428
|
+
|
|
429
|
+
Same M4 Pro 24 GB, Bun 1.4.2, MLX 0.32.2/native pack 0.4.0 and packed
|
|
430
|
+
Qwen KV4/MTP2 protocol as the preceding comparisons: 192 output tokens,
|
|
431
|
+
five decode requests, prompt cache 4, workload seed `mtp-serving-block-0`,
|
|
432
|
+
context sweep disabled, fused TQ enabled and async expansion disabled.
|
|
433
|
+
The four arms ran control/candidate/candidate/control with stable sources:
|
|
434
|
+
control `1b1ededa649088e8338a2930b4ae152e66edf7e4048e2dc8d0b7a3859691800c`,
|
|
435
|
+
candidate `c7d58f7ec867015eff7bbc9a7f02d13baea28173dd312bd504e9b880659278eb`.
|
|
436
|
+
Every start/end preflight passed with the recorded audio-daemon allowance;
|
|
437
|
+
there were no request or phase failures.
|
|
438
|
+
|
|
439
|
+
| Arm | Five decode requests, total ms | Cached TTFT ms | Concurrent aggregate tok/s |
|
|
440
|
+
|---|---:|---:|---:|
|
|
441
|
+
| Control 1 | 55,775.68 | 97.24 | 15.9569 |
|
|
442
|
+
| Candidate 1 | 55,608.34 | 97.49 | 16.0176 |
|
|
443
|
+
| Candidate 2 | 55,692.19 | 97.55 | 15.8421 |
|
|
444
|
+
| Control 2 | 55,661.04 | 99.17 | 15.8041 |
|
|
445
|
+
|
|
446
|
+
All 60 records match in request hash, response text, complete usage including
|
|
447
|
+
speculation counters, token counts and finish reason. These HTTP records do
|
|
448
|
+
not contain emitted token IDs; native tests provide the numerical evidence.
|
|
449
|
+
Candidate versus control means change decode wall time by −0.122%, cached
|
|
450
|
+
latency by −0.696% and aggregate throughput by +0.311%. Peak RSS spans
|
|
451
|
+
12,208–12,224 MB. These are effectively flat regression results. The first
|
|
452
|
+
control reaches readiness in 609 ms and cold start in 3,610 ms; the remaining
|
|
453
|
+
arms take 817–818 ms and 4,235–4,288 ms. Startup equivalence remains unproven.
|
|
454
|
+
|
|
455
|
+
This checks the shared lifecycle on the existing default Qwen path. It does
|
|
456
|
+
not measure positive-threshold Gemma conversion speed or establish serial
|
|
457
|
+
dominance. Both-machine Gemma KV4/KV8 and per-layer native state/logit,
|
|
458
|
+
RAM/SSD continuation and seeded serving tests cover the new composition;
|
|
459
|
+
fresh-process Gemma and long-pressure acceptance remain open.
|
|
460
|
+
Evidence: `reports/qwen38-closeout/composition-baseline/delayed-rotating/`.
|
|
461
|
+
|
|
462
|
+
## Singleton admission attribution on M4 Pro
|
|
463
|
+
|
|
464
|
+
A synthetic Qwen-shaped MLX 0.32.2 probe compares singleton `copyOf` with
|
|
465
|
+
`contiguous`, using evaluated donors: 48 recurrent states, 16 KV4 layers at
|
|
466
|
+
757 logical tokens with 768-token capacity, and their combination. Each arm
|
|
467
|
+
has four warmups and twenty samples; order is control/candidate/candidate/control.
|
|
468
|
+
The combined logical storage is 168,099,840 bytes. Both implementations add
|
|
469
|
+
**zero live GPU allocation** during admission. Combined median admission times
|
|
470
|
+
are 0.1463/0.1435/0.1470/0.1464 ms in execution order. There is no demonstrated
|
|
471
|
+
physical-copy saving; `copyOf` already shares storage in this runtime.
|
|
472
|
+
These synthetic measurements do not establish complete-request speed. The
|
|
473
|
+
initial probe launch omitted the required stream argument to `synchronize`;
|
|
474
|
+
its failure is retained separately and supplied no timing sample.
|
|
475
|
+
|
|
476
|
+
The completed four-arm `bench-serve.ts all` comparison uses the same M4
|
|
477
|
+
Qwen KV4/MTP2, 192-token protocol as above. Control source is
|
|
478
|
+
`c7d58f7ec867015eff7bbc9a7f02d13baea28173dd312bd504e9b880659278eb`;
|
|
479
|
+
candidate is `b7361d962c70f0efbb5c55c32f06996103015477095833c98d83928cc23ddd52`.
|
|
480
|
+
All source snapshots and start/end preflights pass. All 60 request hashes,
|
|
481
|
+
response texts, complete usage/speculation counters, token counts and finish
|
|
482
|
+
reasons match, with no request or phase failures.
|
|
483
|
+
|
|
484
|
+
| Arm | Five decode requests, total ms | Cached TTFT ms | Concurrent aggregate tok/s |
|
|
485
|
+
|---|---:|---:|---:|
|
|
486
|
+
| Control 1 | 56,033.78 | 99.64 | 15.8719 |
|
|
487
|
+
| Candidate 1 | 55,590.06 | 97.28 | 15.9511 |
|
|
488
|
+
| Candidate 2 | 55,682.16 | 97.35 | 15.9217 |
|
|
489
|
+
| Control 2 | 55,725.68 | 99.44 | 15.9324 |
|
|
490
|
+
|
|
491
|
+
Candidate/control means change decode wall time −0.436%, cached latency
|
|
492
|
+
−2.230% and aggregate throughput +0.216%. Both candidate cached samples are
|
|
493
|
+
lower than both controls, although the physical-copy hypothesis is disproven
|
|
494
|
+
and MTP group admission follows its first published token. The latency result
|
|
495
|
+
needs attribution/repetition before treating this replacement as an accepted
|
|
496
|
+
optimization. Controls report readiness at 608 ms and candidates at 816 ms;
|
|
497
|
+
the readiness probe polls every 200 ms, so these observations have coarse
|
|
498
|
+
resolution. Cold starts are 3,414/4,114/4,224/4,017 ms in execution order.
|
|
499
|
+
Startup equivalence and direct serial dominance remain unproven. Both-machine
|
|
500
|
+
native, serving, full-suite and typecheck checks pass; the candidate is isolated.
|
|
501
|
+
Evidence: `reports/qwen38-closeout/composition-baseline/singleton-state/`.
|
|
502
|
+
|
|
503
|
+
## Recurrent row retention diagnostic on M1 Max
|
|
504
|
+
|
|
505
|
+
Apple M1 Max 32 GB, Bun 1.4.2, MLX 0.32.2/native pack 0.4.0. A synthetic
|
|
506
|
+
Qwen-shaped recurrent layer contains 3,207,168 logical bytes per row. After
|
|
507
|
+
extracting one row and disposing its source, the existing implementation keeps
|
|
508
|
+
3,211,264 / 6,422,528 / 12,828,672 / 25,657,344 live allocator bytes for source
|
|
509
|
+
B=1/2/4/8. A proper-subset compact copy retains 3,211,264 bytes in every case,
|
|
510
|
+
including allocator rounding. B1 continues to share its whole allocation.
|
|
511
|
+
This measures one layer, not full-model RSS or request time. The allocation
|
|
512
|
+
regression fails against unchanged source and passes with exact values on the
|
|
513
|
+
isolated fix. Both-machine MTP and bf16/KV4/TQ generated RAM/SSD continuation,
|
|
514
|
+
complete-suite and typecheck checks pass. The allocation regression also passes
|
|
515
|
+
on M4. The reviewed extraction fix is adopted in the unreleased working tree.
|
|
516
|
+
|
|
517
|
+
The M4 Pro 24 GB `bench-serve.ts all` check uses the same packed Qwen KV4/MTP2,
|
|
518
|
+
192-token protocol above, in control/candidate/candidate/control order. Sources
|
|
519
|
+
remain fixed: control
|
|
520
|
+
`c7d58f7ec867015eff7bbc9a7f02d13baea28173dd312bd504e9b880659278eb`, candidate
|
|
521
|
+
`bdc1241596526f42d68ba0988fc63cd90dce73ce8d048b45d9bfa1cc0c5872c7`.
|
|
522
|
+
All start/end preflights pass; all 60 request hashes, response texts, full usage
|
|
523
|
+
and speculation counters, token counts and finish reasons match. No failures.
|
|
524
|
+
|
|
525
|
+
| Arm | Five decode requests, total ms | Cached TTFT ms | Concurrent aggregate tok/s |
|
|
526
|
+
|---|---:|---:|---:|
|
|
527
|
+
| Control 1 | 56,548.78 | 99.48 | 15.7814 |
|
|
528
|
+
| Candidate 1 | 55,608.23 | 99.02 | 15.9869 |
|
|
529
|
+
| Candidate 2 | 55,785.82 | 97.41 | 15.8657 |
|
|
530
|
+
| Control 2 | 55,636.97 | 99.47 | 15.9106 |
|
|
531
|
+
|
|
532
|
+
Candidate/control means change decode wall time −0.706%, cached latency
|
|
533
|
+
−1.264% and aggregate throughput +0.507%. The initial control is slower than
|
|
534
|
+
the remaining arms; candidate throughput overlaps the control range, and the
|
|
535
|
+
second candidate decode total is slightly above the second control. Treat
|
|
536
|
+
these as a regression check for the storage fix, not a broad speedup or serial
|
|
537
|
+
dominance result. Peak RSS spans 12,208–12,240 MB. Startup remains unresolved:
|
|
538
|
+
readiness is 608/816/816/817 ms and cold start 3,704/4,177/4,240/4,181 ms.
|
|
539
|
+
The short workload does not establish long-context pressure acceptance.
|
|
540
|
+
Evidence: `reports/qwen38-closeout/composition-baseline/ssm-extraction/`.
|
|
541
|
+
|
|
542
|
+
## Batched prefill cohorts: M4 regression before projection correction
|
|
543
|
+
|
|
544
|
+
Unreleased isolated candidate against the previously validated delayed-padding
|
|
545
|
+
checkout. Apple M4 Pro, 24 GB; Bun 1.4.2, MLX 0.32.2/native pack 0.4.0.
|
|
546
|
+
Gemma 4 12B OptiQ, ordinary generation, KV4, RAM prompt cache 4 GB, default
|
|
547
|
+
batch capacity 4. Both checkouts have HEAD `0c355f4` plus frozen source changes.
|
|
548
|
+
Control source SHA-256 `89d209400c1f683143ee9afea30e8a440ee00159fe96ba8e1c3bbe5893c744ac`;
|
|
549
|
+
candidate `2431d0395ad7e752991bc47817cf8c6f54a6d74fb6e0f6fc08598e314ce6d937`.
|
|
550
|
+
|
|
551
|
+
Protocol: `bun scripts/bench-serve.ts all --model-path <Gemma-12B-OptiQ>
|
|
552
|
+
--arms mlx-bun --tokens 192 --skip-context --kv-quant 4 --prompt-cache 4
|
|
553
|
+
--workload-seed delayed-padding-0 --allow-cpu-process /usr/libexec/audiomxd`.
|
|
554
|
+
Run order is control, candidate, candidate, control. All preflights and saved
|
|
555
|
+
machine checks pass, with 217 MB swap and the explicitly allowed audio daemon.
|
|
556
|
+
Source hashes remain fixed throughout all four arms; no request failures.
|
|
557
|
+
|
|
558
|
+
| arm | five decode requests, total ms ↓ | cached first-token ms ↓ | B4 aggregate tok/s ↑ | ready ms | cold-start ms | peak RSS MiB |
|
|
559
|
+
|---|---:|---:|---:|---:|---:|---:|
|
|
560
|
+
| control 1 | 38,010.26 | 154.517 | 72.966 | 609.34 | 2,150.35 | 8,985.45 |
|
|
561
|
+
| candidate 1 | 38,063.00 | 154.884 | 72.965 | 608.25 | 1,026.27 | 8,990.06 |
|
|
562
|
+
| candidate 2 | 37,950.08 | 154.601 | 73.024 | 608.52 | 1,024.44 | 8,985.66 |
|
|
563
|
+
| control 2 | 37,906.38 | 154.930 | 73.032 | 609.03 | 1,029.51 | 8,967.28 |
|
|
564
|
+
|
|
565
|
+
Candidate means: decode wall **+0.127%**, cached latency **+0.012%**, aggregate
|
|
566
|
+
throughput **−0.006%**. These results establish no speed win or strict serial
|
|
567
|
+
dominance. The first control's cold-start outlier does not establish a startup
|
|
568
|
+
improvement. This short-prompt workload does not measure long-prefill scaling.
|
|
569
|
+
|
|
570
|
+
All request bodies, token counts, usage, finish reasons and completion markers
|
|
571
|
+
match. Both candidates change the text of concurrent rows 1–3; candidate repeats
|
|
572
|
+
are identical to each other, as are control repeats. Other responses and parity
|
|
573
|
+
probes match. This is not an all-responses-identical regression result. Same-B
|
|
574
|
+
model checks pass on Qwen 27B and Gemma 12B on both Macs, and an admission-only diagnostic restores all
|
|
575
|
+
baseline responses, tying the text changes to shared prefill. An added M4 token-zero check subsequently
|
|
576
|
+
found a sampler-logit mismatch when finished rows project separately. A follow-up
|
|
577
|
+
candidate projects the batch before selecting sampler rows; these timing numbers
|
|
578
|
+
do not measure that fix. The corrected projection passes the M4 model/sampler
|
|
579
|
+
checks. Its fresh comparison is recorded below; the earlier measured candidate is not adopted.
|
|
580
|
+
|
|
581
|
+
Raw evidence: `reports/qwen38-closeout/composition-baseline/prefill-cohort/`,
|
|
582
|
+
including source manifest/patch, native checks and the four complete reports.
|
|
583
|
+
|
|
584
|
+
## Batched prefill cohorts: corrected M4 comparison
|
|
585
|
+
|
|
586
|
+
The benchmark now also accepts `--aggregate-context <approximate tokens>` and
|
|
587
|
+
`--aggregate-stagger-ms <milliseconds>` for long, staggered HTTP requests.
|
|
588
|
+
Zero preserves the original short-prompt/simultaneous workload. Reports record
|
|
589
|
+
these settings, actual submission offsets, prompt/cache counts, first-token
|
|
590
|
+
latencies and total aggregate wall time. These workload changes must match
|
|
591
|
+
between comparison arms; the historical short-prompt numbers below use zeros.
|
|
592
|
+
|
|
593
|
+
The corrected candidate projects the forward batch before selecting each
|
|
594
|
+
sampler's logits. It is adopted in the unreleased working tree. Same machine,
|
|
595
|
+
model, protocol, settings and control as the preceding comparison, with fresh
|
|
596
|
+
control/candidate/candidate/control runs. Candidate source SHA-256
|
|
597
|
+
`84abd86ac44155298ec14cc59eeb0b51a0f1862d45e199b3597ef8a22d24a31f`.
|
|
598
|
+
All source hashes remain fixed, all preflight/save checks pass, and every arm
|
|
599
|
+
reports zero failures. Retained swap is 215 MB; the audio daemon allowance is
|
|
600
|
+
explicit, as in the preceding run.
|
|
601
|
+
|
|
602
|
+
| arm | five decode requests, total ms ↓ | cached first-token ms ↓ | B4 aggregate tok/s ↑ | ready ms | cold-start ms | peak RSS MiB |
|
|
603
|
+
|---|---:|---:|---:|---:|---:|---:|
|
|
604
|
+
| control 1 | 37,975.15 | 155.060 | 73.009 | 608.52 | 1,033.49 | 8,977.16 |
|
|
605
|
+
| candidate 1 | 37,989.93 | 154.810 | 73.042 | 608.63 | 1,029.35 | 8,980.83 |
|
|
606
|
+
| candidate 2 | 37,971.84 | 154.802 | 73.071 | 608.51 | 1,030.21 | 8,974.33 |
|
|
607
|
+
| control 2 | 37,974.80 | 154.991 | 73.003 | 609.87 | 1,027.01 | 8,954.62 |
|
|
608
|
+
|
|
609
|
+
Candidate means: decode wall **+0.016%**, cached latency **−0.142%**, aggregate
|
|
610
|
+
throughput **+0.069%**. Ready time changes by −0.102%, cold-start time by
|
|
611
|
+
−0.045%, and peak RSS by +0.130%. This is effectively flat performance for the
|
|
612
|
+
short-prompt workload, with no established speed win or strict serial dominance.
|
|
613
|
+
Long-prefill scaling remains unmeasured by this workload.
|
|
614
|
+
|
|
615
|
+
All 60 requests complete. Request bodies, token counts, usage, finish reasons
|
|
616
|
+
and completion markers match the baseline. The two candidate repeats produce
|
|
617
|
+
identical responses; the two controls do too. Three concurrent responses differ
|
|
618
|
+
between candidate and control, as in the earlier admission-only attribution.
|
|
619
|
+
Other responses match. These cross-shape text differences do not establish
|
|
620
|
+
an engine-only coding-task speedup or an all-responses-identical result.
|
|
621
|
+
The corrected same-B Qwen 27B and Gemma 12B checks include full logits,
|
|
622
|
+
token-zero sampler logits and restored continuation on both Macs.
|
|
623
|
+
|
|
624
|
+
Raw evidence: `reports/qwen38-closeout/composition-baseline/prefill-cohort/`,
|
|
625
|
+
particularly `projection-m4/`, `projection-benchmark-comparison.json`, and
|
|
626
|
+
`projection-manifest.json`. Main integration results are recorded in the manifest.
|
|
627
|
+
|
|
628
|
+
## Staggered long prefill: M4 regression
|
|
629
|
+
|
|
630
|
+
Gemma 4 12B OptiQ, M4 Pro 24 GB, Bun 1.4.2, MLX 0.32.2/native pack 0.4.0.
|
|
631
|
+
Same ordinary KV4/cache settings as the preceding corrected comparison.
|
|
632
|
+
The benchmark adds `--aggregate-context 2048 --aggregate-stagger-ms 25` and
|
|
633
|
+
uses `--workload-seed prefill-long-0`. Actual aggregate prompt counts are
|
|
634
|
+
1,289/1,281/1,287/1,287, with matching cache hits of 13/12/14/12 across all arms.
|
|
635
|
+
The target length is a character-based estimate, not a measured token count.
|
|
636
|
+
Client submission offsets are approximately 0/26/51/76 ms. Each request
|
|
637
|
+
produces 128 completion tokens. The existing prefill chunk default is 2,048.
|
|
638
|
+
|
|
639
|
+
Control source SHA-256
|
|
640
|
+
`4ab50112e6464d0d778f80398d8f61e3740c9a6dd5c3c9725f34b255c26b7711`;
|
|
641
|
+
candidate `003827c79e0bcefd65c33fe7366faa28ca60d7fd428063f6c3a159efd7a60991`.
|
|
642
|
+
Both include the same benchmark extension; inference code matches the preceding
|
|
643
|
+
control/corrected candidate respectively. All source hashes stay fixed, all
|
|
644
|
+
preflight/save checks pass, and all requests complete without failure. The
|
|
645
|
+
explicit audio allowance applies; retained swap remains 215 MB.
|
|
646
|
+
|
|
647
|
+
| arm | aggregate wall ms ↓ | aggregate tok/s ↑ | first request TTFT ms ↓ | mean request TTFT ms ↓ | peak RSS MiB |
|
|
648
|
+
|---|---:|---:|---:|---:|---:|
|
|
649
|
+
| control 1 | 25,278.61 | 20.254 | 9,007.88 | 15,911.29 | 8,947.95 |
|
|
650
|
+
| candidate 1 | 26,328.98 | 19.446 | 18,696.52 | 19,042.67 | 8,997.20 |
|
|
651
|
+
| candidate 2 | 26,543.42 | 19.289 | 18,849.50 | 19,193.88 | 9,013.50 |
|
|
652
|
+
| control 2 | 26,388.15 | 19.403 | 9,493.52 | 16,771.75 | 8,949.66 |
|
|
653
|
+
|
|
654
|
+
Candidate means show **2.333% longer aggregate wall time**, **2.324% lower
|
|
655
|
+
throughput**, **102.936% higher first-request TTFT**, and **16.992% higher mean
|
|
656
|
+
TTFT**. The controls' aggregate wall times differ by 4.4%, so the exact small
|
|
657
|
+
throughput penalty is not stable enough to generalize. The large first-request
|
|
658
|
+
latency penalty repeats clearly. Short decode request wall time changes by
|
|
659
|
+
−0.066%, and cached TTFT by −0.036%. Shared prefill has not passed long-request
|
|
660
|
+
performance acceptance. No serial deletion or default promotion follows.
|
|
661
|
+
|
|
662
|
+
Requests, usage, counts, finish reasons and completion markers match. Concurrent
|
|
663
|
+
rows 1–3 change text; other responses match, and each pair of repeated arms is
|
|
664
|
+
internally identical. This remains a comparison of identical submitted work,
|
|
665
|
+
not an all-responses-identical result or a coding-task quality assessment.
|
|
666
|
+
|
|
667
|
+
An M1 diagnostic with `MLX_BUN_P2R_TRACE=1` records the first request's internal
|
|
668
|
+
token-zero completion at about 6.25 s, but its first response write at 25.94 s.
|
|
669
|
+
The following B3 prefill chunk spans 18.25 s. This points to long preparation
|
|
670
|
+
work delaying active output, rather than admission waiting alone. It is
|
|
671
|
+
instrumented M1 attribution, not an M4 performance claim. A bounded M4 screen
|
|
672
|
+
with prefill chunks of 256 completes at 26,526.13 ms aggregate wall time and
|
|
673
|
+
19.302 tok/s, with first-request TTFT 13,235.29 ms. It improves first output
|
|
674
|
+
relative to the candidate's 2,048-token chunks but still trails the earlier
|
|
675
|
+
control. The matching 256-token control completes at 26,011.10 ms and
|
|
676
|
+
19.684 tok/s, with first-request TTFT 7,232.19 ms. The candidate therefore
|
|
677
|
+
still has 1.980% longer wall time and 83.005% higher first-request TTFT at
|
|
678
|
+
matching chunk size. Source/preflight/save checks pass with no failures.
|
|
679
|
+
Requests, usage/counts and completion markers match, but all four concurrent
|
|
680
|
+
texts differ. This one-pair screen does not qualify a default. Smaller chunks
|
|
681
|
+
change KV conversion boundaries and do not resolve the admission/work-unit
|
|
682
|
+
performance problem. Raw comparison: `long-chunk256-comparison.json` in the
|
|
683
|
+
evidence directory below.
|
|
684
|
+
|
|
685
|
+
Evidence: `reports/qwen38-closeout/composition-baseline/prefill-cohort/`,
|
|
686
|
+
including `long-m4/`, `long-benchmark-comparison.json`, and
|
|
687
|
+
`long-m1-prefill-traces.json`.
|
|
688
|
+
|
|
689
|
+
## Prefill admission work budget: M4 comparison
|
|
690
|
+
|
|
691
|
+
The isolated scheduler candidate limits admission to an existing prefill cohort
|
|
692
|
+
using initial uncached token work. Its internal budget is 2,048 tokens; a larger
|
|
693
|
+
request still enters alone and runs through the same preparation method. An
|
|
694
|
+
earlier shrinking-weight screen restored first TTFT to 9,538.63 ms but completed
|
|
695
|
+
the group in 26,797.77 ms, versus 9,012.73/25,295.58 ms in the first control,
|
|
696
|
+
and still changed three responses. The fixed-weight candidate below avoids
|
|
697
|
+
attaching another long prompt to a nearly completed request.
|
|
698
|
+
|
|
699
|
+
M4 Pro 24 GB, Gemma 4 12B OptiQ, Bun 1.4.2, MLX 0.32.2/native pack 0.4.0.
|
|
700
|
+
Same protocol and exact inputs as the preceding staggered-long comparison,
|
|
701
|
+
including KV4, prompt cache 4 GB, chunk default 2,048, 25 ms arrival spacing,
|
|
702
|
+
and `prefill-long-0`. Actual prompt/cache/output counts match. Control source
|
|
703
|
+
SHA-256 `4ab50112e6464d0d778f80398d8f61e3740c9a6dd5c3c9725f34b255c26b7711`;
|
|
704
|
+
fixed candidate `2dcee8a99708c66facd8aa296fe8b990de92eca5031453888947e9f9f35dfd72`.
|
|
705
|
+
Run order was control 1, the earlier shrinking-weight screen, fixed candidate 1,
|
|
706
|
+
fixed candidate 2, control 2. All source hashes remain fixed within their runs;
|
|
707
|
+
all preflight/save checks pass under the explicit audio-daemon allowance, with
|
|
708
|
+
215 MB retained swap and no failed requests.
|
|
709
|
+
|
|
710
|
+
| arm | aggregate wall ms ↓ | aggregate tok/s ↑ | first request TTFT ms ↓ | mean TTFT ms ↓ | five decode requests, total ms ↓ | cached TTFT ms ↓ |
|
|
711
|
+
|---|---:|---:|---:|---:|---:|---:|
|
|
712
|
+
| control 1 | 25,295.58 | 20.241 | 9,012.73 | 15,955.67 | 37,922.95 | 154.872 |
|
|
713
|
+
| candidate 1 | 25,550.88 | 20.038 | 9,031.34 | 16,089.03 | 37,960.58 | 154.755 |
|
|
714
|
+
| candidate 2 | 26,390.25 | 19.401 | 9,526.85 | 16,783.75 | 38,091.45 | 155.456 |
|
|
715
|
+
| control 2 | 26,122.33 | 19.600 | 9,289.83 | 16,519.82 | 37,973.20 | 155.051 |
|
|
716
|
+
|
|
717
|
+
All 60 responses in the four fixed-candidate/control arms match exactly, including
|
|
718
|
+
request bodies, usage/counts, finish reasons and completion markers. Candidate
|
|
719
|
+
means are +1.018% aggregate wall time, −1.007% throughput, +1.397% first-request
|
|
720
|
+
TTFT, +1.223% mean TTFT, +0.205% short decode wall and +0.093% cached TTFT.
|
|
721
|
+
This restores the large latency regression from unrestricted cohorts, but does
|
|
722
|
+
not establish strict performance dominance. Aggregate timings vary by about
|
|
723
|
+
3.3% within both candidate and control pairs. No default-speed win is claimed.
|
|
724
|
+
|
|
725
|
+
The policy is adopted in the unreleased working tree. Complete suites/types
|
|
726
|
+
and long-prefix Qwen/TurboQuant and Gemma/KV4 ownership checks pass on both
|
|
727
|
+
Macs. Main integration suite/typecheck pass.
|
|
728
|
+
A separate lifetime review found that the new loop retains unused hidden output
|
|
729
|
+
through cache maintenance, unlike the existing shared prefill primitive. Its
|
|
730
|
+
release-order screen is complete and is not adopted, as recorded below.
|
|
731
|
+
|
|
732
|
+
Evidence: `reports/qwen38-closeout/composition-baseline/prefill-cohort/`,
|
|
733
|
+
including `budget-m4/`, `budget-fixed-benchmark-comparison.json`, the earlier
|
|
734
|
+
`budget-remaining.patch`, and `budget-fixed-manifest.json`.
|
|
735
|
+
|
|
736
|
+
## Prefill early-release lifetime screen: no measured win
|
|
737
|
+
|
|
738
|
+
The candidate disposes input IDs immediately after prefill forward and unused
|
|
739
|
+
hidden output before cache maintenance. Its control is the adopted fixed-work
|
|
740
|
+
admission policy above. Same M4 Pro 24 GB, Gemma 4 12B OptiQ snapshot, Bun 1.4.2,
|
|
741
|
+
MLX 0.32.2/native pack 0.4.0 and production `bench-serve.ts all` protocol:
|
|
742
|
+
KV4, prompt cache 4 GB, 192 decode tokens, skipped context sweep,
|
|
743
|
+
`prefill-long-0`, aggregate context target 2,048 and stagger 25 ms.
|
|
744
|
+
Actual aggregate prompts/cache hits remain 1,289/13, 1,281/12, 1,287/14,
|
|
745
|
+
1,287/12, with 128 output tokens each. Control source SHA-256
|
|
746
|
+
`2dcee8a99708c66facd8aa296fe8b990de92eca5031453888947e9f9f35dfd72`;
|
|
747
|
+
candidate `46b351c3a4f4ed1442c946de388638b01611419fcc5a060c407f7a9da9584a80`.
|
|
748
|
+
|
|
749
|
+
| arm, in run order | aggregate wall ms ↓ | aggregate tok/s ↑ | first request TTFT ms ↓ | five decode requests, total ms ↓ | cached TTFT ms ↓ |
|
|
750
|
+
|---|---:|---:|---:|---:|---:|
|
|
751
|
+
| control 1 | 25,394.38 | 20.162 | 9,020.58 | 38,018.88 | 154.911 |
|
|
752
|
+
| candidate 1 | 25,537.82 | 20.049 | 9,033.96 | 37,966.96 | 154.710 |
|
|
753
|
+
| candidate 2 | 26,290.25 | 19.475 | 9,402.95 | 38,027.90 | 154.732 |
|
|
754
|
+
| control 2 | 25,888.99 | 19.777 | 9,164.43 | 38,000.93 | 154.781 |
|
|
755
|
+
|
|
756
|
+
All 60 responses, request bodies, usage/counts, finish reasons and completion
|
|
757
|
+
markers match exactly. All source/preflight/save checks pass; retained swap
|
|
758
|
+
stays at 208.25 MB under the explicit audio-daemon CPU allowance. No requests
|
|
759
|
+
fail. Candidate means are +1.062% aggregate wall time, −1.039% throughput,
|
|
760
|
+
+1.385% first TTFT, +1.366% mean TTFT, −0.033% short decode wall and
|
|
761
|
+
−0.081% cached TTFT. Aggregate run spread is 1.95% in controls and 2.95% in
|
|
762
|
+
candidates, so these small differences do not establish a causal slowdown.
|
|
763
|
+
Mean peak RSS differs by only −1.95 MB, or −0.022%, with no pressure test.
|
|
764
|
+
Cold start has a 2,132 ms first-control outlier versus roughly 1,095–1,100 ms
|
|
765
|
+
in the other three arms; its mean ratio is not evidence of a startup gain.
|
|
766
|
+
|
|
767
|
+
No speed or material measured-memory benefit is established. The candidate
|
|
768
|
+
remains isolated and is not adopted. M1 full suite/typecheck and Qwen 27B
|
|
769
|
+
same-B model/sampler/continuation checks on both Macs pass; M4 full suite and
|
|
770
|
+
typecheck were not run for this unadopted screen.
|
|
771
|
+
Evidence: `reports/qwen38-closeout/composition-baseline/prefill-cohort/`,
|
|
772
|
+
including `drain-m4/`, `drain-benchmark-comparison.json` and `drain-manifest.json`.
|
|
773
|
+
|
|
774
|
+
## MTP preparation port and compiled activation: M4 comparison
|
|
775
|
+
|
|
776
|
+
This seven-file change adds provider-owned draft prefill using the existing
|
|
777
|
+
Qwen row state and replaces the companion's unfused MLP activation with the
|
|
778
|
+
compiled SwiGLU already used by the target. The new prefill port is not yet
|
|
779
|
+
connected to shared target preparation. This HTTP comparison therefore covers
|
|
780
|
+
the activation and row-lifecycle changes, not batched MTP prefill performance.
|
|
781
|
+
The same-B pinned companion check found 11 differing bf16 output values out of
|
|
782
|
+
10,240 in one decoder continuation with the old activation, maximum absolute
|
|
783
|
+
difference 0.0078125; KV already matched. The shared compiled activation passes
|
|
784
|
+
all tested KV/full-decoder continuations at B1/B2/B3/B4 on both Macs, including
|
|
785
|
+
a 2,051-token prefix and cold/restored joins.
|
|
786
|
+
|
|
787
|
+
M4 Pro 24 GB, packed Qwen 27B Trellis interleave2 artifact and folded RTN4/g64
|
|
788
|
+
MTP companion, Bun 1.4.2, MLX 0.32.2/native pack 0.4.0. Production
|
|
789
|
+
`bench-serve.ts all`, explicit `mlx-bun` arm, MTP2, KV4, prompt cache 4 GB,
|
|
790
|
+
192 decode tokens, five decode requests, context sweep disabled, original
|
|
791
|
+
short aggregate prompts at concurrency four, seed `mtp-serving-block-0`.
|
|
792
|
+
`MLX_BUN_TURBOQUANT_FUSED_DECODE=1` and
|
|
793
|
+
`MLX_BUN_TRELLIS_ASYNC_EXPAND=0` match the preceding MTP controls.
|
|
794
|
+
Control source SHA-256
|
|
795
|
+
`2dcee8a99708c66facd8aa296fe8b990de92eca5031453888947e9f9f35dfd72`;
|
|
796
|
+
candidate `69f3f37388ca0fdda2dd836786a20cb588c947fdc476b6206d617d7312d366fa`.
|
|
797
|
+
|
|
798
|
+
| arm, in run order | five decode requests, total ms ↓ | concurrent aggregate tok/s ↑ | cached TTFT ms ↓ |
|
|
799
|
+
|---|---:|---:|---:|
|
|
800
|
+
| control 1 | 55,546.48 | 15.7645 | 99.415 |
|
|
801
|
+
| candidate 1 | 55,705.24 | 15.6455 | 99.348 |
|
|
802
|
+
| candidate 2 | 55,931.24 | 15.7543 | 96.942 |
|
|
803
|
+
| control 2 | 55,905.67 | 15.7074 | 97.644 |
|
|
804
|
+
|
|
805
|
+
All 60 request bodies, response texts, prompt/output/cache token counts,
|
|
806
|
+
finish reasons and completion markers match. Five records per candidate arm
|
|
807
|
+
have different speculation statistics; candidate repeats agree exactly, as do
|
|
808
|
+
the controls. Four of the five decode requests have changed acceptance traces,
|
|
809
|
+
and one concurrent response has changed draft/acceptance counts. This follows
|
|
810
|
+
the corrected draft arithmetic and is not identical internal work. The targets
|
|
811
|
+
still return the same text and token counts.
|
|
812
|
+
|
|
813
|
+
Descriptive candidate/control means change decode wall by +0.165%, aggregate
|
|
814
|
+
throughput by −0.229%, aggregate wall by +0.230% and cached TTFT by −0.390%.
|
|
815
|
+
Readiness and cold-start means change by +0.059% and +0.051%. Mean peak RSS is
|
|
816
|
+
14.82 MB lower, without a pressure test. All source/preflight/save checks pass
|
|
817
|
+
under the audio-daemon allowance, with no request or phase failures. Retained
|
|
818
|
+
swap grows across the runs, from 200.25 MB before the first control to 297.88 MB
|
|
819
|
+
after the final control; the environment is not a fixed zero-swap control.
|
|
820
|
+
|
|
821
|
+
No speed win, identical-work ratio or serial dominance is established. The
|
|
822
|
+
provider port and numerical correction are adopted in the unreleased working
|
|
823
|
+
tree after both-machine companion-oracle, native MTP, full-suite and typecheck
|
|
824
|
+
checks. Main integration suite/typecheck pass. Shared target/MTP prefill integration,
|
|
825
|
+
its serving/caching gates and a combined performance comparison remain open.
|
|
826
|
+
Evidence: `reports/qwen38-closeout/composition-baseline/prefill-cohort/`, including
|
|
827
|
+
`mtp-prefill-m4/`, `mtp-prefill-benchmark-comparison.json`,
|
|
828
|
+
`mtp-prefill-manifest.json`, and `mtp-prefill.patch`.
|
|
829
|
+
|
|
830
|
+
## Delayed rotating prefill: M4 regression
|
|
831
|
+
|
|
832
|
+
Gemma 4 12B OptiQ 4-bit, snapshot
|
|
833
|
+
`5b1101065d2094c8f12aa87fee80e0afa5b292b7`, on the **M4 Pro / 24 GB**.
|
|
834
|
+
Bun 1.4.2, MLX 0.32.2, native pack 0.4.0. The control is
|
|
835
|
+
`padded-partial-validation`; the candidate is `delayed-padding-validation`.
|
|
836
|
+
Both use remote HEAD `0c355f4` plus their recorded working-tree changes.
|
|
837
|
+
The production snapshots are respectively
|
|
838
|
+
`27b65281f031a4ffc4f7db057a264f32aa8bbfab70bf4c2acb357176148f38b2` and
|
|
839
|
+
`89d209400c1f683143ee9afea30e8a440ee00159fe96ba8e1c3bbe5893c744ac`.
|
|
840
|
+
|
|
841
|
+
Four alternating runs use `bun scripts/bench-serve.ts all`, the exact artifact
|
|
842
|
+
above, `--arms mlx-bun --tokens 192 --skip-context --kv-quant 4 --prompt-cache 4
|
|
843
|
+
--workload-seed delayed-padding-0 --allow-cpu-process /usr/libexec/audiomxd`.
|
|
844
|
+
All preflights pass under the authorized audio-daemon CPU allowance, with fixed
|
|
845
|
+
source in each arm and identical workload/runtime settings. All 60 request
|
|
846
|
+
bodies, response texts, usage records, token counts and finish reasons match;
|
|
847
|
+
the separate parity probes also match. No request or phase failed.
|
|
848
|
+
|
|
849
|
+
| Arm | Five decode requests, total wall ms | Cached TTFT ms | B4 aggregate tok/s | Ready ms | Cold start ms | Peak RSS MiB |
|
|
850
|
+
|---|---:|---:|---:|---:|---:|---:|
|
|
851
|
+
| Control 1 | 37,952.57 | 154.73 | 72.98 | 608.63 | 1,022.52 | 8,992.91 |
|
|
852
|
+
| Candidate 1 | 37,969.02 | 155.03 | 72.85 | 607.89 | 1,024.32 | 8,971.34 |
|
|
853
|
+
| Candidate 2 | 38,284.21 | 155.46 | 72.54 | 608.21 | 1,021.92 | 8,982.78 |
|
|
854
|
+
| Control 2 | 38,207.34 | 155.07 | 72.90 | 608.12 | 1,023.51 | 8,990.95 |
|
|
855
|
+
|
|
856
|
+
Candidate means are **0.123% higher decode wall time**, **0.222% higher cached
|
|
857
|
+
TTFT** and **0.339% lower aggregate throughput**. Both candidate aggregate
|
|
858
|
+
observations are below both controls. These are small unfavorable differences,
|
|
859
|
+
not evidence of a speed win. Readiness is in the same 200 ms polling interval;
|
|
860
|
+
this Gemma block does not resolve the separate Qwen startup/cached-latency debt.
|
|
861
|
+
|
|
862
|
+
The change adds delayed rotating-cache preparation and is retained as feature
|
|
863
|
+
work. This benchmark exercises current serving, which still prefills requests
|
|
864
|
+
separately; it does not measure the future batched-prefill path or establish
|
|
865
|
+
serial dominance. Native preparation tests cover mixed-format attention and
|
|
866
|
+
encoded state through B8, with the numerical scope documented in batching.md.
|
|
867
|
+
Raw records and comparison: `reports/qwen38-closeout/composition-baseline/delayed-padding/`.
|
|
868
|
+
|
|
869
|
+
## Recurrent padded prefill: M4 regression
|
|
870
|
+
|
|
871
|
+
Joshs-MBP-2025.local, Apple M4 Pro 24 GB, Bun 1.4.2, MLX 0.32.2/native
|
|
872
|
+
pack 0.4.0. Four alternating `bench-serve.ts all` arms use the same packed
|
|
873
|
+
Qwen KV4/MTP2, 192-token protocol above. The control includes the adopted
|
|
874
|
+
full/rotating KV padding interfaces. Sources remain fixed: control
|
|
875
|
+
`5431fdd0f20225e0493b12fb251db0b773f93d6ca92a2a5d09d64882a1161d04`,
|
|
876
|
+
candidate `98f5fb5038e3b63f3d1e28a3084f5d1da0a475aa28307761defd26f681e4eb82`.
|
|
877
|
+
Every start/end preflight passes with the audio-daemon allowance. All 60
|
|
878
|
+
requests match in request hash/body, text, complete usage/speculation counters,
|
|
879
|
+
token counts and finish reason. The separate parity probes also match. There
|
|
880
|
+
are no request or phase failures.
|
|
881
|
+
|
|
882
|
+
| Arm | Five decode requests, total ms | Cached TTFT ms | Concurrent aggregate tok/s |
|
|
883
|
+
|---|---:|---:|---:|
|
|
884
|
+
| Control 1 | 55,951.11 | 97.49 | 15.7960 |
|
|
885
|
+
| Candidate 1 | 55,713.07 | 97.38 | 15.8332 |
|
|
886
|
+
| Candidate 2 | 55,628.97 | 97.20 | 15.9066 |
|
|
887
|
+
| Control 2 | 55,639.46 | 98.99 | 15.9824 |
|
|
888
|
+
|
|
889
|
+
Candidate/control means change decode wall time by −0.223%, cached latency
|
|
890
|
+
by −0.964% and aggregate throughput by −0.122%. Candidate aggregate throughput
|
|
891
|
+
falls within the control range; cached latency is lower in both candidate arms.
|
|
892
|
+
This supports integration as a feature addition with
|
|
893
|
+
roughly flat decode/request performance, not a speedup or serial-dominance
|
|
894
|
+
claim. Peak RSS ranges from 12,161 to 12,227 MB. Readiness is
|
|
895
|
+
608/817/813/612 ms; both candidate observations fall one 200-ms polling
|
|
896
|
+
interval later. Cold start is 3,726/4,207/4,200/4,006 ms. Startup equivalence
|
|
897
|
+
remains unproven and is not covered by the flat decode conclusion.
|
|
898
|
+
|
|
899
|
+
This checks existing unpadded serving behavior. Actual padded behavior passes
|
|
900
|
+
same-B 27B logit and convolution/recurrent-state oracles on both machines,
|
|
901
|
+
including B1 and uniform/unequal B3. MTP, TurboQuant, generated RAM/SSD reuse,
|
|
902
|
+
complete suites and typechecks also pass on both Macs. True batched serving
|
|
903
|
+
prefill, delayed-codec preparation and long-pressure acceptance remain open.
|
|
904
|
+
The recurrent-padding change is adopted in the unreleased working tree.
|
|
905
|
+
Evidence: `reports/qwen38-closeout/composition-baseline/padded-ssm/`.
|
|
906
|
+
|
|
907
|
+
## Packed Qwen serial closeout on M4 Pro
|
|
908
|
+
|
|
909
|
+
Six balanced v6/v13 pairs on **Joshs-MBP-2025.local, Apple M4 Pro 24 GB**
|
|
910
|
+
complete with **114 matching paired requests and no failures**. This uses
|
|
911
|
+
Bun 1.4.0, MLX 0.32.2 and the advisory-memory candidate on `0c355f4` plus
|
|
912
|
+
its recorded patch. Source snapshot
|
|
913
|
+
`e0ebcb3fd1be6024623ffb4db08cdb5b7322a823d43df7ef1e803d11b37131b7`
|
|
914
|
+
is unchanged across all twelve runs. The packed interleaved artifact's
|
|
915
|
+
20-file manifest hashes to
|
|
916
|
+
`24c56033e1ae4c816747f763b76a7420b6327236a3736c2a89462a22e4e512ce`.
|
|
917
|
+
Preflight passes under Josh's explicit `/usr/libexec/audiomxd` CPU allowance;
|
|
918
|
+
all blocks retain their memory, swap and thermal observations.
|
|
919
|
+
|
|
920
|
+
| Metric | v6 → v13 or paired factor | 95% block interval |
|
|
921
|
+
|---|---|---|
|
|
922
|
+
| Decode request wall time | 20.507 → 17.826 seconds pooled median; **1.1504×**, or **13.08% less time** | 1.1493–1.1514× |
|
|
923
|
+
| Decode SSE-window rate | 10.026 → 11.593 tok/s pooled median; 1.1562× | 1.1557–1.1568× |
|
|
924
|
+
| Cold 1K TTFT | 1.0145× | 0.9997–1.0292×; inconclusive |
|
|
925
|
+
| Warm 1K TTFT | 1.0889× | 1.0710–1.1083× |
|
|
926
|
+
| Long-prompt TTFT | 1.0039× | 0.9995–1.0083×; inconclusive |
|
|
927
|
+
| Four queued requests, aggregate rate | 1.1464× | 1.1457–1.1470× |
|
|
928
|
+
| Peak process RSS, inverse ratio | 0.9948× | 0.9755–1.0107×; no demonstrated reduction |
|
|
929
|
+
|
|
930
|
+
Factors above one favor v13. Intervals resample the six block log-ratios of
|
|
931
|
+
within-run summaries, not the individual requests. These describe this
|
|
932
|
+
controlled session, not variation across days or p99 latency. Each run has
|
|
933
|
+
five 192-token decode requests, cold/warm prefix requests, restart restoration
|
|
934
|
+
and the four-request aggregate leg. Actual long prompts contain
|
|
935
|
+
10,397–10,399 tokens despite the synthetic `--context 16384` target. Both arms
|
|
936
|
+
use serial serving and bf16 KV; output hashes, prompt/output/reused-token
|
|
937
|
+
counts and finish reasons match throughout. The aggregate leg is queued
|
|
938
|
+
serial throughput, not evidence of simultaneous batch execution.
|
|
939
|
+
|
|
940
|
+
Final-source native checks also preserve full logits, cache state and
|
|
941
|
+
continuation at eight input lengths. Paired MTP-prefix restoration passes with
|
|
942
|
+
both bf16 and KV4 storage. Continuous and combined paired results follow below;
|
|
943
|
+
broader composed/pressure acceptance remains open; **no default is promoted by this serial result alone**.
|
|
944
|
+
Raw bundle: `reports/qwen38-closeout/m4-v6-v13-b{0..5}-v{6,13}.md.json`;
|
|
945
|
+
review and offline HTML: `m4-v6-v13-review.json`,
|
|
946
|
+
`m4-v6-v13-comparison.html`. Native evidence: `m4-final-native-runner.json`
|
|
947
|
+
and `m4-final-v13-*.log` in the same directory.
|
|
948
|
+
|
|
949
|
+
Six balanced longer-context continuous-serving pairs now pass on the same
|
|
950
|
+
M4 Pro, artifact, Bun/MLX versions and CPU allowance above. All 114 paired
|
|
951
|
+
requests match with no failures. Each run uses 256-token decode requests and
|
|
952
|
+
actual long prompts of about 20,717 tokens. The frozen source snapshot is
|
|
953
|
+
`363f74acc1e432677bfe333eec001c9111a1fb2c10128603409568f86dad58bb`.
|
|
954
|
+
The paired decode request-time factor is 1.15235×, or 13.22% less time,
|
|
955
|
+
with a 95% block interval of 1.15164–1.15316×. Four-request aggregate
|
|
956
|
+
throughput improves 2.37742×, with a 95% block interval of 2.37615–2.37856×.
|
|
957
|
+
These are same-session intervals, not across-day or sustained-load results.
|
|
958
|
+
Raw reports and review are
|
|
959
|
+
`reports/qwen38-closeout/m4-final-continuous-b{0..5}-v{6,13}.md.json`
|
|
960
|
+
and `m4-final-continuous-review.json`.
|
|
961
|
+
|
|
962
|
+
All six serial KV4 plus two-token MTP pairs with paired RAM prefixes now
|
|
963
|
+
pass, with all 114 paired requests matching and no failures. Source, host,
|
|
964
|
+
artifact and qualification match the longer-context continuous series above.
|
|
965
|
+
The paired decode request-time factor is 2.15832×, or 53.67% less time,
|
|
966
|
+
with a 95% block interval of 2.15467–2.16129×. Aggregate queued throughput
|
|
967
|
+
improves 2.07990×, with a 95% block interval of 2.07838–2.08162×. At long
|
|
968
|
+
context, decode SSE-window throughput improves 2.03668× and first-token time
|
|
969
|
+
improves 1.03885×. These compare kernel variant 13 with variant 6 while keeping
|
|
970
|
+
KV4 and MTP enabled in both arms; they do not isolate the benefit of MTP or
|
|
971
|
+
compare KV formats. All twelve restart requests reuse zero tokens: paired MTP
|
|
972
|
+
prefixes are RAM-only, so this is fresh-prefill restart measurement, not SSD
|
|
973
|
+
restoration. Raw reports and review are
|
|
974
|
+
`reports/qwen38-closeout/m4-final-kv4-mtp-b{0..5}-v{6,13}.md.json`
|
|
975
|
+
and `m4-final-kv4-mtp-review.json`. These measured settings are now selected in
|
|
976
|
+
the unreleased candidate source as documented in server-config.md; changing
|
|
977
|
+
default selection does not complete output-cache or execution consolidation.
|
|
978
|
+
|
|
979
|
+
The saved Kanban first-turn audit finds 50,479 reasoning tokens shared with
|
|
980
|
+
the next request beyond the original 2,550-token prompt. The following prompt
|
|
981
|
+
has 53,175 tokens. This is an offline tokenizer/template comparison, not a
|
|
982
|
+
performance measurement: no generated-state checkpoint has yet been accepted
|
|
983
|
+
for this saved long turn, and no saved time is claimed for it. Evidence:
|
|
984
|
+
`reports/qwen38-closeout/r17-first-tool-prefix-opportunity.json`.
|
|
985
|
+
|
|
14
986
|
## Running the benchmark
|
|
15
987
|
|
|
16
988
|
`bun scripts/bench-serve.ts all` is THE benchmark — one pass, real servers,
|
|
@@ -53,6 +1025,10 @@ bun scripts/bench/model-inventory.ts /path/to/affine /path/to/packed > reports/m
|
|
|
53
1025
|
|
|
54
1026
|
`--workload-seed <block-id>` generates identical nonce-prefixed prompts for
|
|
55
1027
|
every engine and artifact in that block, with distinct nonces for retries.
|
|
1028
|
+
`--logprobs` and `--top-logprobs N` apply capture settings to every timed
|
|
1029
|
+
request, including concurrent requests, and record them in the workload and
|
|
1030
|
+
request hashes. SSE timing measures capture cost; wire-level logprob values
|
|
1031
|
+
are checked separately by the native/HTTP composition tests.
|
|
56
1032
|
Thinking is pinned on for all chat measurements. Long-context filler uses a
|
|
57
1033
|
fixed character estimate so token-count drift cannot silently change the
|
|
58
1034
|
input on one engine. Record actual token counts and compare raw request hashes.
|
|
@@ -61,9 +1037,10 @@ repeat; request hashes alone do not identify cache state.
|
|
|
61
1037
|
For paired trials, alternate `--arms mlx-bun-serial,mlx-lm` and the reversed
|
|
62
1038
|
order across blocks; give every block its own seed and `--out` path.
|
|
63
1039
|
|
|
64
|
-
Configured
|
|
65
|
-
`--num-draft-tokens`, `--kv-quant` and `--
|
|
66
|
-
`--arms mlx-bun-serial
|
|
1040
|
+
Configured engine experiments accept `--draft-model`, `--draft-kind`,
|
|
1041
|
+
`--num-draft-tokens`, `--kv-quant`, `--prompt-cache` and `--adapter`. These options
|
|
1042
|
+
require explicit `--arms mlx-bun-serial,mlx-bun` (or either engine arm); run
|
|
1043
|
+
oracle controls separately. Both selected engine arms receive identical overrides.
|
|
67
1044
|
The dry-run, raw JSON and Markdown report retain the settings and relevant
|
|
68
1045
|
runtime overrides. No script under `reports/` is required to launch them.
|
|
69
1046
|
For the current packed Qwen artifact on the M4 Pro, run this after closing
|
|
@@ -81,9 +1058,90 @@ bun scripts/bench-serve.ts all \
|
|
|
81
1058
|
```
|
|
82
1059
|
|
|
83
1060
|
Append `--dry-run` to inspect the command first. This serving suite is separate
|
|
84
|
-
from the Luke Kanban task and does not establish its task-time speedup.
|
|
85
|
-
|
|
86
|
-
|
|
1061
|
+
from the Luke Kanban task and does not establish its task-time speedup. This
|
|
1062
|
+
entry point writes Markdown plus the `<report>.md.json` companion; the offline
|
|
1063
|
+
HTML comparison report renders from saved companions:
|
|
1064
|
+
|
|
1065
|
+
```sh
|
|
1066
|
+
bun scripts/bench/report.ts reports/a.md.json reports/b.md.json --out reports/compare.html
|
|
1067
|
+
bun scripts/bench/report.ts reports/a.md.json reports/native-bun.json --out reports/compare.html --baseline mlx-bun-serial
|
|
1068
|
+
```
|
|
1069
|
+
|
|
1070
|
+
Use `--baseline mlx-bun-serial --baseline-env MLX_BUN_TRELLIS_VARIANT=6`
|
|
1071
|
+
to compare environment-selected variants of that same arm. The selected
|
|
1072
|
+
setting stays visible in both serving tables; the usual identity and workload
|
|
1073
|
+
requirements still apply.
|
|
1074
|
+
|
|
1075
|
+
Inputs are auto-detected: bench-serve schema-4 `<report>.md.json` files and
|
|
1076
|
+
`scripts/bench/native.ts` `native-inference-diagnostic` JSON. Rendering reads
|
|
1077
|
+
the saved JSON only — no weights, server, GPU, Python or network. The single
|
|
1078
|
+
self-contained file shows a provenance panel per input (file sha256, machine
|
|
1079
|
+
string, commit, Bun, runtime overrides, source snapshot hashes, server
|
|
1080
|
+
commands, workload seed, thinking mode), a per-machine serving matrix with a
|
|
1081
|
+
status on every cell (measured, recovered on retry, failed with the phase
|
|
1082
|
+
error, not-measured, or unsupported with the reason), correctness flags beside
|
|
1083
|
+
the timings (finish-reason mix, actual vs requested output counts, early EOS,
|
|
1084
|
+
warm/restart cached-token counts, durability, request errors, retries, parity
|
|
1085
|
+
verdicts), ratios only against a baseline arm on the same machine key,
|
|
1086
|
+
artifact and workload (`--baseline mlx-lm|mlx-bun-serial|mlx-bun`; default
|
|
1087
|
+
mlx-lm when present), per-machine comparison columns, decode-sample strips,
|
|
1088
|
+
an RSS-versus-decode plot, a native token-identity table, and the retained
|
|
1089
|
+
failures, stderr tails and raw request table. "decode" stays the SSE-window
|
|
1090
|
+
rate and "actual output / wall" the completion-token rate; RSS is process
|
|
1091
|
+
RSS from `ps`. The paired uncertainty table groups fixed-source trials across
|
|
1092
|
+
workload seeds and gives a 95% percentile-bootstrap interval for the geometric
|
|
1093
|
+
mean of block ratios. It resamples block log-ratios, requires at least five
|
|
1094
|
+
distinct seeds and ignores duplicate seeds. Its baseline is fixed when the
|
|
1095
|
+
report is generated. Quality-versus-size renders "not measured" until a quality
|
|
1096
|
+
input exists.
|
|
1097
|
+
|
|
1098
|
+
Request-derived speed ratios require matching request hashes, attempts, full
|
|
1099
|
+
output hashes, prompt/output and reused-token counts, and finish reasons. A mismatch keeps the
|
|
1100
|
+
absolute timings visible and suppresses the ratio. Full output hashes survive
|
|
1101
|
+
fixture trimming. Retry summaries use the final attempt; earlier samples and
|
|
1102
|
+
failures remain in the raw table. Diagnostic, nonquiet and changing-source
|
|
1103
|
+
runs cannot earn speed ratios. Cross-file comparisons require a recorded
|
|
1104
|
+
hostname, matching artifact path/config and the complete workload definition;
|
|
1105
|
+
matching config files alone do not establish matching weights. New serving
|
|
1106
|
+
companions record hostname and OS. Old files with no hostname compare only
|
|
1107
|
+
within their own file. Displayed ratios are ratios of medians, not paired
|
|
1108
|
+
confidence intervals or default-promotion evidence.
|
|
1109
|
+
|
|
1110
|
+
The bounded M1 Max smoke of this path uses MiniCPM, 16 requested decode
|
|
1111
|
+
tokens, `--skip-context`, and the unsplit reference. Both real-server arms
|
|
1112
|
+
complete without failed phases on fixed source. Warmup, the parity chat,
|
|
1113
|
+
five decode requests and the cold/warm 1K requests match full output hashes
|
|
1114
|
+
and reused-token counts. Concurrent four-request outputs still differ.
|
|
1115
|
+
Short decode timings are unstable; the run is explicitly diagnostic and
|
|
1116
|
+
cannot supply speed ratios or M4 acceptance. Raw data and review:
|
|
1117
|
+
`reports/qwen38-closeout/serve-smoke.md.json` and `serve-smoke-review.json`.
|
|
1118
|
+
The offline `comparison.html` includes this run beside both machines' saved
|
|
1119
|
+
evidence. Automated rendering/escaping checks pass; browser URL policy
|
|
1120
|
+
blocked visual inspection of the local HTML file.
|
|
1121
|
+
|
|
1122
|
+
`--reference-prefill server` keeps stock MLX-LM system/thinking segmentation
|
|
1123
|
+
and is the default. `--reference-prefill unsplit` selects an explicit Python
|
|
1124
|
+
reference control that passes one whole-prompt segment to BatchGenerator,
|
|
1125
|
+
which still reserves the final token. Tokenization, model operations,
|
|
1126
|
+
sampling and HTTP handling remain in the pinned reference. This changes
|
|
1127
|
+
prefill and cache policy and is recorded in commands, workload identity and
|
|
1128
|
+
the Markdown report. It applies to the `mlx-lm` arm, including models that
|
|
1129
|
+
need OptiQ registration. Use it only where it matches the Bun request's
|
|
1130
|
+
boundaries; it does not promise matching arbitrary multi-turn snapshots.
|
|
1131
|
+
|
|
1132
|
+
```sh
|
|
1133
|
+
bun scripts/bench-serve.ts all --models cpm5,qwen27b --arms mlx-bun,mlx-bun-serial,mlx-lm --reference-prefill unsplit --out reports/matched-prefill.md
|
|
1134
|
+
```
|
|
1135
|
+
|
|
1136
|
+
For an exclusively allocated GPU, `--allow-cpu-process /absolute/command`
|
|
1137
|
+
permits one explicitly reviewed background command to exceed the CPU
|
|
1138
|
+
threshold. The exact command and observed activity remain in the raw
|
|
1139
|
+
preflight snapshots and the report names the allowance. RSS, swap, thermal
|
|
1140
|
+
and overall-load checks still apply. This is not proof of an idle GPU or
|
|
1141
|
+
stable timing: verify GPU ownership and compare alternating repeated runs.
|
|
1142
|
+
Josh authorized this policy for `/usr/libexec/audiomxd` on the M4 Pro;
|
|
1143
|
+
CPU activity alone no longer blocks this campaign. Earlier diagnostic
|
|
1144
|
+
runs keep their original classification.
|
|
87
1145
|
|
|
88
1146
|
`--diagnostic` explicitly permits a loaded-machine serving run. It records
|
|
89
1147
|
the preflight snapshot and writes `*-serve-diagnostic` DB rows, which cannot
|
|
@@ -331,6 +1389,946 @@ this follow-up does not resolve their separate cross-oracle output differences.
|
|
|
331
1389
|
Evidence: `reports/qwen38-rd/pr47-ssd-followup.md.json` and
|
|
332
1390
|
`reports/qwen38-rd/pr47-ssd-followup-mixed.md.json`.
|
|
333
1391
|
|
|
1392
|
+
The subsequent boundary investigation identifies the timed-output difference
|
|
1393
|
+
on MiniCPM and Qwen. For each model's first saved request, Bun and Python match all 192
|
|
1394
|
+
complete native logit vectors. Stock Python HTTP instead splits at the
|
|
1395
|
+
thinking marker: MiniCPM uses prefill lengths 29, 1, 1 instead of 30, 1;
|
|
1396
|
+
Qwen uses 75, 1, 1 instead of 76, 1. Those segmented native Python runs
|
|
1397
|
+
reproduce the original reference responses after HTTP thinking-tag removal.
|
|
1398
|
+
The explicit unsplit reference control then reproduces all ten saved Bun
|
|
1399
|
+
decode responses, with identical output counts and finish reasons. Request
|
|
1400
|
+
hashes match. The first MiniCPM replay reuses zero tokens versus four in the
|
|
1401
|
+
original run; the other nine cache counts match. These are M4 Pro correctness
|
|
1402
|
+
diagnostics, not a replacement timing cohort or a speed claim. Qwen's Metal
|
|
1403
|
+
prefill failures and quiet paired timing acceptance remain open. Evidence:
|
|
1404
|
+
`reports/qwen38-closeout/prefill-segmentation-review.json` and its hashed
|
|
1405
|
+
native/HTTP companions. The initial invalid-model-ID replay is retained on
|
|
1406
|
+
the M4 Pro as `cpm5-replay-invalid-model-id.json`.
|
|
1407
|
+
|
|
1408
|
+
The Qwen memory follow-up on the same M4 Pro distinguishes a fresh-process
|
|
1409
|
+
control from the suite's retained state. The saved “1K” request actually has
|
|
1410
|
+
757 prompt tokens and succeeds after a fresh warmup. Replaying the preceding
|
|
1411
|
+
warmup, completion/chat parity probes and five decode requests with SSD cache
|
|
1412
|
+
enabled reproduces the Metal OOM on the original source. An isolated
|
|
1413
|
+
per-layer prefill-evaluation prototype passes the fresh control; its full
|
|
1414
|
+
history replay completes warmup and the raw completion probe, then times
|
|
1415
|
+
out before the parity chat finishes. SSH subsequently became unavailable
|
|
1416
|
+
and recovered without a reboot. The timeout has no resolved cause, and the
|
|
1417
|
+
prototype is not integrated. Raising the fit estimate alone does not resolve
|
|
1418
|
+
the observed OOM. Local fresh controls and recovered history trials are
|
|
1419
|
+
`reports/qwen38-closeout/qwen27b-memory-{server,barrier}-{fresh,history}.json`;
|
|
1420
|
+
the M4 keeps the history trials under the unsuffixed names. Preflight still
|
|
1421
|
+
rejects retained swap. No speed or memory improvement is accepted from
|
|
1422
|
+
these trials.
|
|
1423
|
+
|
|
1424
|
+
After the M4 reboot and unlock, the frozen candidate still fails the 1K
|
|
1425
|
+
prefill phase on both attempts. Layer evaluation gets all four cold/warm 1K
|
|
1426
|
+
requests through with the seven preceding outputs and usage unchanged, but
|
|
1427
|
+
four-request serving then fails with a Metal OOM. Reserving successor state
|
|
1428
|
+
for all batch rows gets all 15 requests through. Both changes are now in the
|
|
1429
|
+
working candidate. Twelve same-version oracle cases (prefix lengths 0/64,
|
|
1430
|
+
forward lengths 1/4/8/16/128/757) preserve complete logits, recurrent state
|
|
1431
|
+
and continuation exactly. A longer replay completes 38 requests across
|
|
1432
|
+
continuous and serial serving, including a 2,679-token context and SSD
|
|
1433
|
+
restart restoring 2,678 tokens. All 15 individually issued requests match
|
|
1434
|
+
across lanes in output and usage; the four concurrent responses differ and
|
|
1435
|
+
are excluded from cross-lane speed comparisons.
|
|
1436
|
+
|
|
1437
|
+
These remain correctness diagnostics under their original run policy.
|
|
1438
|
+
A subsequent control removes per-token memory polling from continuous
|
|
1439
|
+
decode and reserves at batch joins. It completes 19 requests with a
|
|
1440
|
+
5,239-token context and restores 5,238 tokens from SSD. The integrated
|
|
1441
|
+
reservation also accounts for cache growth to the requested output caps;
|
|
1442
|
+
its repeat preserves all 19 request identities, outputs and usage counts.
|
|
1443
|
+
Josh then clarified that the isolated audio CPU load is acceptable with
|
|
1444
|
+
memory and GPU availability; new acceptance runs record the explicit
|
|
1445
|
+
allowance described above. Earlier diagnostics are not relabeled.
|
|
1446
|
+
Evidence under `reports/qwen38-closeout/`:
|
|
1447
|
+
`m4-{candidate,layer-eval,layer-batch}-memory.md.json`,
|
|
1448
|
+
`m4-memory-review.json`, `m4-layer-state-{bun,reference,review}.json`,
|
|
1449
|
+
`m4-memory-context{.md,-review}.json`,
|
|
1450
|
+
`m4-{join-only,reserved-growth}-memory.md.json` and
|
|
1451
|
+
`m4-join-reservation-review.json`; artifact hashes are in
|
|
1452
|
+
`m4-candidate-preparation.json`. No speed default is promoted.
|
|
1453
|
+
|
|
1454
|
+
The first CPU-allowance R0 block (same M4 Pro, candidate on `0c355f4`,
|
|
1455
|
+
Bun 1.4.0, MLX 0.32.2, stock GPU ceiling, explicit unsplit reference)
|
|
1456
|
+
passes preflight before and after on fixed source. All five decode requests
|
|
1457
|
+
match across continuous Bun, serial Bun and Python in complete output,
|
|
1458
|
+
prompt/generated/reused tokens and finish reason. Within-arm decode spread
|
|
1459
|
+
is 0.49%, 1.05% and 0.78%, respectively; this is one block, not a paired
|
|
1460
|
+
speed verdict. Continuous serving completes all phases. Without the earlier
|
|
1461
|
+
context leg's server restart, serial serving fails the fourth queued request
|
|
1462
|
+
with Metal OOM. Python's 1K timeout and final aggregate failure also contain
|
|
1463
|
+
Metal OOM tracebacks, at prompt-state evaluation and pipelined decode.
|
|
1464
|
+
The earlier longer replay therefore does not close retained-history pressure.
|
|
1465
|
+
A focused allocation trace reproduces the fourth-request failure with
|
|
1466
|
+
18,783,888,604 active bytes, a four-byte allocator pool, 2,485,518,336 bytes
|
|
1467
|
+
of RAM prefixes and a 199,133,984-byte reservation against the
|
|
1468
|
+
19,069,665,280-byte GPU ceiling. The pool is not the missing memory; the
|
|
1469
|
+
remaining 86,642,692 bytes do not establish room for overlapping asynchronous
|
|
1470
|
+
state updates. A two-successor boundary reservation then completes all 30
|
|
1471
|
+
requests across both Bun lanes without failures. The 29 successful requests
|
|
1472
|
+
from R0 match output and usage; the formerly failed serial request matches
|
|
1473
|
+
the earlier context/restart control. Full-output reservation and longer
|
|
1474
|
+
generation are the next gates. Evidence:
|
|
1475
|
+
`m4-serial-allocation-probe.md.json`, `m4-serial-allocation-review.json`,
|
|
1476
|
+
`m4-two-state-memory.md.json` and `m4-two-state-memory-review.json` in
|
|
1477
|
+
`reports/qwen38-closeout/`.
|
|
1478
|
+
Raw: `reports/qwen38-closeout/m4-r0-audio-allowed-01.md.json` and
|
|
1479
|
+
`m4-r0-audio-allowed-01-review.json`.
|
|
1480
|
+
|
|
1481
|
+
### Fresh Kanban candidate generation — M4 Pro (2026-09-09)
|
|
1482
|
+
|
|
1483
|
+
The frozen optimized candidate completed the pinned Luke Kanban prompt on
|
|
1484
|
+
Joshs-MBP-2025.local (M4 Pro 24 GB, Bun 1.4.0, MLX 0.32.2, Pi 0.85.1)
|
|
1485
|
+
in **5,085.387 seconds (1h 24m 45.387s)** from prompt submission to completion.
|
|
1486
|
+
It generated 68,958 output tokens across 15 requests, with zero Pi retries,
|
|
1487
|
+
compactions or tool errors. Pi and the server exited zero; the outcome parser
|
|
1488
|
+
confirmed completion, profile requests were valid, and source hashes stayed fixed.
|
|
1489
|
+
The run used packed interleave2, variant 13, KV4, MTP depth 2 and paired RAM
|
|
1490
|
+
prefixes, with the authorized audio CPU allowance. R17 generated-history
|
|
1491
|
+
checkpointing was not implemented in this candidate.
|
|
1492
|
+
|
|
1493
|
+
The untouched generated app passes all 18 required browser acceptance categories,
|
|
1494
|
+
including native card/column dragging, combined filters, archive/restore,
|
|
1495
|
+
keyboard operation and persistence in both themes. Source hashes are unchanged. The earlier successful task generated a different number of tokens
|
|
1496
|
+
and tool turns, so this duration does not establish an engine-only speedup.
|
|
1497
|
+
The first/new runs used 75/21 tool calls, 7/0 tool errors and 1/0 compactions.
|
|
1498
|
+
Summed pre-first-output time is 3,399.895/814.988 seconds. New task time is
|
|
1499
|
+
60.2% lower and output count 47.2% lower, without an engine-only attribution.
|
|
1500
|
+
The sole initial-request difference is Pi's working-directory suffix:
|
|
1501
|
+
`kanban-final-workspace` versus `kanban-closeout-candidate-r1-workspace`,
|
|
1502
|
+
verified as five additional tokens by the model tokenizer. Both used batch 1
|
|
1503
|
+
and MTP depth 2. Detailed acceptance and comparison:
|
|
1504
|
+
`reports/qwen38-closeout/kanban-run-comparison.md`; raw evidence:
|
|
1505
|
+
`reports/qwen38-closeout/kanban-final-candidate-r1/`.
|
|
1506
|
+
|
|
1507
|
+
### Direct scheduler B=1 versus serial — both machines (2026-09-08)
|
|
1508
|
+
|
|
1509
|
+
Josh's September 8 standard suites include both default scheduling and strict
|
|
1510
|
+
serial controls. M1 Max 32 GB used clean commit `1ac8f61`; M4 Pro 24 GB used
|
|
1511
|
+
clean commit `86738ac`. Both used Bun 1.4.0, no runtime overrides, and passed
|
|
1512
|
+
quiet preflight. Compare arms within each machine; the machines have different
|
|
1513
|
+
source commits. These are single ordered suites, not alternating repeat blocks.
|
|
1514
|
+
|
|
1515
|
+
Median short-decode SSE rates from five 192-token requests per arm:
|
|
1516
|
+
|
|
1517
|
+
| Model | M1 default / serial tok/s | M4 default / serial tok/s |
|
|
1518
|
+
|---|---:|---:|
|
|
1519
|
+
| MiniCPM5-1B | 268.79 / 267.81 | 278.65 / 275.86 |
|
|
1520
|
+
| Gemma4-e4b | 63.85 / 64.01 | 57.86 / 59.03 |
|
|
1521
|
+
| Gemma4-12B | 30.33 / 30.33 | 26.14 / 26.44 |
|
|
1522
|
+
| Qwen3.8-27B 4/8-bit winner | 18.58 / 18.56 | 14.75 / 14.66 |
|
|
1523
|
+
|
|
1524
|
+
All 40 paired timed responses match between default and serial in request hash,
|
|
1525
|
+
output text, prompt/cached/generated token counts, finish reason and DONE status.
|
|
1526
|
+
Completion and chat parity probes also match for all eight model/machine cells.
|
|
1527
|
+
This comparison is between our two executors; it does not erase the separate
|
|
1528
|
+
Python-reference differences recorded in the M4 section above. Default B=1
|
|
1529
|
+
short-decode rates are within 0.4% of serial on M1 and within 2.0% on M4.
|
|
1530
|
+
The M1 suite has no phase failures. The M4 suite retains its recorded SSD retry
|
|
1531
|
+
and Qwen prefill OOM failures; short-decode agreement is not whole-suite acceptance.
|
|
1532
|
+
|
|
1533
|
+
The M1 four-request aggregate rates, default versus serial, are 408.12/243.14
|
|
1534
|
+
(MiniCPM), 101.60/60.91 (e4b), 41.32/27.95 (12B), and 20.08/15.72 (Qwen),
|
|
1535
|
+
in tok/s. These measure aggregate throughput, not single-request latency.
|
|
1536
|
+
The results support sharing a scheduler with a B=1 case; they do not establish
|
|
1537
|
+
feature completeness for replacing the dedicated executor, including MTP.
|
|
1538
|
+
Raw reports: `reports/benchmarks-serve-2026-09-08-Joshs-MacBook-Pro.md.json`
|
|
1539
|
+
and the M4's `reports/benchmarks-serve-2026-09-08-Joshs-MBP-2025.md.json`
|
|
1540
|
+
(local preserved copy: `reports/qwen38-closeout/m4-standard-20260908-original.json`).
|
|
1541
|
+
|
|
1542
|
+
### Batched logprob composition — M4 Pro, acceptance open (2026-09-09)
|
|
1543
|
+
|
|
1544
|
+
Two ordered/reversed `bench-serve.ts all` blocks use the packed interleave2
|
|
1545
|
+
Qwen artifact on Joshs-MBP-2025.local, M4 Pro 24 GB, Bun 1.4.0 and MLX
|
|
1546
|
+
0.32.2. Both pass preflight with the authorized audio CPU allowance. The
|
|
1547
|
+
frozen sampler candidate uses selected logprobs plus top-3 capture, unchanged
|
|
1548
|
+
kernels, five 192-token decode requests and the short-context suite with SSD
|
|
1549
|
+
caching. Its source predates the subsequent explicit-seed placement change;
|
|
1550
|
+
these benchmark requests have no explicit seed. Neither block has a failure.
|
|
1551
|
+
|
|
1552
|
+
| Block/order | Median decode request ms, serial / batch B=1 | Cached TTFT ms, serial / batch B=1 | Cached request ms, serial / batch B=1 |
|
|
1553
|
+
|---|---:|---:|---:|
|
|
1554
|
+
| 0, serial then batch | 17,833.47 / 17,785.57 | 261.16 / 307.45 | 800.68 / 846.69 |
|
|
1555
|
+
| 1, batch then serial | 17,840.70 / 17,771.87 | 272.90 / 319.81 | 812.66 / 858.99 |
|
|
1556
|
+
|
|
1557
|
+
All 22 single-request pairs match request/output hashes, token counts, finish
|
|
1558
|
+
reason and DONE status. Only three of eight concurrent pairs match complete
|
|
1559
|
+
outputs across serial and batch execution, so their timing does not establish
|
|
1560
|
+
an identical-work speedup. The cached response regression keeps performance
|
|
1561
|
+
acceptance open. Existing ordinary-execution M1/M4 baselines above remain valid.
|
|
1562
|
+
|
|
1563
|
+
Raw reports and review: `reports/qwen38-closeout/composition-baseline/`
|
|
1564
|
+
`logprobs-composition-{0,1}.md.json` and `logprobs-performance-review.json`.
|
|
1565
|
+
A third block enables `MLX_BUN_EARLY_FIRST_TOKEN=1` in both arms using
|
|
1566
|
+
block 0's requests. Source hashes remain fixed and no phase fails. Serial /
|
|
1567
|
+
batch B=1 median decode request time is 17,847.38 / 17,782.37 ms, cached
|
|
1568
|
+
TTFT 194.87 / 242.19 ms, and cached request time 809.63 / 860.77 ms. All
|
|
1569
|
+
15 within-block response pairs match, including the four concurrent requests.
|
|
1570
|
+
All 11 single-request outputs also match block 0; two concurrent batch outputs
|
|
1571
|
+
change with the different admission timing. Early output improves delivery in
|
|
1572
|
+
both arms but leaves the cached-request regression open. It is not a default
|
|
1573
|
+
promotion. Raw: `logprobs-early-composition-0.md.json` and
|
|
1574
|
+
`logprobs-early-performance-review.json` in the same directory.
|
|
1575
|
+
|
|
1576
|
+
Bounded P2R diagnostics there separate recurrent-boundary SSD persistence
|
|
1577
|
+
from output-delivery delay. Traced timings are diagnostic only.
|
|
1578
|
+
|
|
1579
|
+
### Shared uniform KV4 composition — M4 Pro, acceptance open (2026-09-09)
|
|
1580
|
+
|
|
1581
|
+
One ordered serial/default block uses the packed interleave2 artifact with
|
|
1582
|
+
uniform KV4, selected logprobs and top-3 capture on M4 Pro 24 GB, Bun 1.4.0,
|
|
1583
|
+
MLX 0.32.2. Both commands receive identical KV options. Preflight passes with
|
|
1584
|
+
the authorized audio allowance, source hashes stay fixed, and no phase fails.
|
|
1585
|
+
Serial / shared B=1 median decode request time is 17,866.95 / 17,814.16 ms;
|
|
1586
|
+
median SSE decode rate is 11.5556 / 11.5569 tok/s. Cached TTFT is 271.67 /
|
|
1587
|
+
292.97 ms and cached request time 813.85 / 834.49 ms. The cached latency gap
|
|
1588
|
+
keeps acceptance open; this single ordered block cannot establish stability.
|
|
1589
|
+
All 11 single-request pairs match complete responses. Only one of four
|
|
1590
|
+
concurrent pairs matches, so the aggregate timings do not establish an
|
|
1591
|
+
identical-work speedup. The frozen candidate includes the shared KV conversion
|
|
1592
|
+
and uniform placement change; later removal of an obsolete startup warning is
|
|
1593
|
+
not part of this source snapshot.
|
|
1594
|
+
|
|
1595
|
+
Raw: `reports/qwen38-closeout/composition-baseline/`
|
|
1596
|
+
`uniform-kv4-composition-0.md.json` and `uniform-kv4-performance-review.json`.
|
|
1597
|
+
|
|
1598
|
+
### Immutable RAM prefix prototype — M4 Pro (2026-09-09)
|
|
1599
|
+
|
|
1600
|
+
The first borrowed-prefix prototype uses the same packed artifact, selected
|
|
1601
|
+
logprobs/top-3, SSD cache and workload as logprob block 0 above. On M4 Pro
|
|
1602
|
+
24 GB, Bun 1.4.0, MLX 0.32.2, preflight passes with the authorized audio CPU
|
|
1603
|
+
allowance. Source hashes remain fixed and no phase fails. Serial / shared
|
|
1604
|
+
B=1 median decode request time is 17,874.77 / 17,758.63 ms, cached TTFT
|
|
1605
|
+
256.93 / 168.77 ms and cached request time 796.78 / 707.51 ms.
|
|
1606
|
+
|
|
1607
|
+
All 11 single-request pairs match. Every output within each arm also matches
|
|
1608
|
+
that arm in original logprob block 0. Two of four concurrent pairs match
|
|
1609
|
+
across arms; aggregate timings do not establish identical-work performance.
|
|
1610
|
+
This prototype still makes serial requests flush durability before generation.
|
|
1611
|
+
The later removal of that flush must be measured in both arms before claiming
|
|
1612
|
+
that shared B=1 dominates the best serial implementation.
|
|
1613
|
+
|
|
1614
|
+
Raw: `reports/qwen38-closeout/composition-baseline/`
|
|
1615
|
+
`borrowed-prefix-composition-0.md.json` and
|
|
1616
|
+
`borrowed-prefix-performance-review.json`.
|
|
1617
|
+
|
|
1618
|
+
### Eventual SSD persistence — M4 Pro, acceptance open (2026-09-09)
|
|
1619
|
+
|
|
1620
|
+
The next frozen candidate retains immutable RAM prefixes and removes the
|
|
1621
|
+
serial request-time durability flush. It uses the same machine, toolchain,
|
|
1622
|
+
artifact, capture settings and block-0 workload as the prototype above.
|
|
1623
|
+
Preflight passes with the audio allowance, source hashes remain fixed and
|
|
1624
|
+
there are no failures. Serial / shared B=1 median decode request time is
|
|
1625
|
+
17,768.44 / 17,787.02 ms, cached TTFT 163.57 / 168.03 ms and cached request
|
|
1626
|
+
time 703.55 / 706.67 ms. All 11 single-request pairs match, and every output
|
|
1627
|
+
within each arm matches original logprob block 0. Two of four concurrent
|
|
1628
|
+
pairs match across arms.
|
|
1629
|
+
|
|
1630
|
+
This removes the large cached-request regression in the earlier logprob
|
|
1631
|
+
comparisons. One ordered block does not establish that the remaining small
|
|
1632
|
+
difference is stable or that shared B=1 dominates serial. A subsequent change
|
|
1633
|
+
makes background writes acquire idle ownership without requesting a batch
|
|
1634
|
+
drain; its balanced serving comparisons are separate acceptance work.
|
|
1635
|
+
|
|
1636
|
+
Raw: `reports/qwen38-closeout/composition-baseline/`
|
|
1637
|
+
`eventual-cache-composition-0.md.json` and
|
|
1638
|
+
`eventual-cache-performance-review.json`.
|
|
1639
|
+
|
|
1640
|
+
### Idle persistence queue on Bun 1.4.2 — M4 Pro (2026-09-09)
|
|
1641
|
+
|
|
1642
|
+
Two ordered/reversed blocks measure immutable RAM reuse, removal of the
|
|
1643
|
+
request-time flush, and background writes that acquire the engine only when
|
|
1644
|
+
idle. Both use the packed Qwen artifact, bf16 KV, selected logprobs/top-3,
|
|
1645
|
+
SSD caching and the same block-0 requests. M4 Pro 24 GB, Bun 1.4.2, MLX
|
|
1646
|
+
0.32.2; preflight passes under the audio allowance. The source hash is identical
|
|
1647
|
+
across both blocks and remains fixed; neither block has a failure.
|
|
1648
|
+
|
|
1649
|
+
| Order | Median decode request ms, serial / shared B=1 | Cached TTFT ms, serial / shared B=1 | Cached request ms, serial / shared B=1 |
|
|
1650
|
+
|---|---:|---:|---:|
|
|
1651
|
+
| Serial then batch | 17,772.00 / 17,750.51 | 163.13 / 167.44 | 703.25 / 706.08 |
|
|
1652
|
+
| Batch then serial | 17,746.81 / 17,757.96 | 162.87 / 167.51 | 701.86 / 706.03 |
|
|
1653
|
+
|
|
1654
|
+
All 22 single-request pairs match complete response identity. Every output
|
|
1655
|
+
within each arm also matches original logprob block 0. Four of eight concurrent
|
|
1656
|
+
pairs match across arms, so aggregate timing does not establish identical-work
|
|
1657
|
+
performance. Decode request time differs by less than 0.13%, while shared B=1
|
|
1658
|
+
retains a consistent 4.3–4.6 ms cached first-output gap. Strict dominance is
|
|
1659
|
+
still unproven. The later correction to the batch's reported first-token
|
|
1660
|
+
clock is not included; these numbers come from client-observed timings.
|
|
1661
|
+
|
|
1662
|
+
Raw: `reports/qwen38-closeout/composition-baseline/`
|
|
1663
|
+
`idle-persistence-bun142-composition-{0,1}.md.json` and
|
|
1664
|
+
`idle-persistence-bun142-performance-review.json`.
|
|
1665
|
+
|
|
1666
|
+
### First-admission device pipeline — M4 Pro (2026-09-09)
|
|
1667
|
+
|
|
1668
|
+
The first ordinary row now enters the existing pending GPU-token register,
|
|
1669
|
+
allowing the next forward to overlap its first readback. This also includes
|
|
1670
|
+
the corrected first-token metric timestamp. The frozen candidate was measured
|
|
1671
|
+
in both arm orders on M4 Pro 24 GB, Bun 1.4.2 and MLX 0.32.2, using the same
|
|
1672
|
+
packed artifact, bf16 KV, logprobs/top-3, SSD and block-0 requests as the
|
|
1673
|
+
idle-persistence comparison. Both preflights pass with the audio allowance,
|
|
1674
|
+
source stays fixed across both blocks and no phase fails.
|
|
1675
|
+
|
|
1676
|
+
| Arm order | Decode request median ms, serial / shared B=1 | Cached TTFT ms, serial / shared B=1 | Cached request ms, serial / shared B=1 |
|
|
1677
|
+
|---|---:|---:|---:|
|
|
1678
|
+
| Serial first | 17,759.74 / 17,745.59 | 163.25 / 163.38 | 703.29 / 701.71 |
|
|
1679
|
+
| Shared first | 17,754.03 / 17,746.97 | 162.61 / 163.53 | 701.91 / 702.64 |
|
|
1680
|
+
|
|
1681
|
+
All 22 single-request pairs match, and every output within each arm matches
|
|
1682
|
+
the idle-persistence baseline. Four of eight concurrent pairs match across
|
|
1683
|
+
arms; these do not support an identical-work aggregate speed claim. The
|
|
1684
|
+
change reduces the prior cached-TTFT gap to 0.12–0.91 ms and is adopted in
|
|
1685
|
+
the working tree. Shared B=1 does not strictly dominate every measured
|
|
1686
|
+
latency, and this composition does not close the full feature matrix.
|
|
1687
|
+
|
|
1688
|
+
Raw: `reports/qwen38-closeout/composition-baseline/`
|
|
1689
|
+
`first-row-pipeline-composition-{0,1}.md.json` and corresponding
|
|
1690
|
+
`first-row-pipeline-composition-{0,1}-review.json`. Both blocks identify source
|
|
1691
|
+
`5cd1cb0668b743303cd6b05ba8779fd9075280d97585b008ac2da9d03f462c7f`.
|
|
1692
|
+
|
|
1693
|
+
### Batched sliding-window correctness — M1 Max and M4 Pro (2026-09-09)
|
|
1694
|
+
|
|
1695
|
+
The shared executor passes the live, pinned same-B MLX-LM oracle on Gemma
|
|
1696
|
+
12B and e4b on both M1 Max 32 GB and M4 Pro 24 GB, with Bun 1.4.2 and
|
|
1697
|
+
MLX 0.32.2. Each cell compares 48 complete float32 logit vectors exactly.
|
|
1698
|
+
Three unequal prompt lengths straddle the configured sliding window: two
|
|
1699
|
+
cross it during decode and one starts beyond it. The two arrival schedules
|
|
1700
|
+
include staggered retirement and a late join. This closes Phase 18's ordinary
|
|
1701
|
+
Gemma ring-wrap gate; it does not qualify quantized layouts or other methods.
|
|
1702
|
+
|
|
1703
|
+
Raw: `reports/qwen38-closeout/composition-baseline/`
|
|
1704
|
+
`m1-gemma12b-batch-ring-wrap.log`,
|
|
1705
|
+
`m4-gemma12b-batch-ring-wrap-complete-inputs.log`,
|
|
1706
|
+
`m1-gemmae4b-batch-ring-wrap.log`, and
|
|
1707
|
+
`m4-gemmae4b-batch-ring-wrap.log`. The first M4 launch failed before model
|
|
1708
|
+
loading because its scratch checkout lacked test support files; the complete
|
|
1709
|
+
input rerun is the accepted result. No performance conclusion uses test time.
|
|
1710
|
+
|
|
1711
|
+
### Compatible adapter groups — M4 Pro (2026-09-09)
|
|
1712
|
+
|
|
1713
|
+
Gemma e4b OptiQ snapshot `98d7dc6`, `fixtures/adapters/upper`, bf16 KV and
|
|
1714
|
+
SSD cache, on M4 Pro 24 GB with Bun 1.4.2 and MLX 0.32.2. The configured
|
|
1715
|
+
adapter and block-0 requests are identical across the serial and shared arms.
|
|
1716
|
+
Both arm orders pass preflight with the recorded audio allowance, retain a
|
|
1717
|
+
fixed source, and finish every phase.
|
|
1718
|
+
|
|
1719
|
+
| Arm order | Decode request median ms, serial / shared B=1 | Cached TTFT ms, serial / shared B=1 | Cached request ms, serial / shared B=1 | Observed four-request throughput tok/s, serial / shared |
|
|
1720
|
+
|---|---:|---:|---:|---:|
|
|
1721
|
+
| Serial first | 3,654.29 / 3,671.12 | 36.88 / 37.66 | 162.18 / 161.73 | 51.76 / 161.42 |
|
|
1722
|
+
| Shared first | 3,678.68 / 3,675.22 | 37.58 / 37.96 | 162.13 / 161.98 | 51.82 / 161.27 |
|
|
1723
|
+
|
|
1724
|
+
All 22 single-request output/usage pairs match. Six of eight concurrent
|
|
1725
|
+
pairs match across arms; every output is stable within its own arm across
|
|
1726
|
+
orders. The concurrent throughput figures therefore are observed workload
|
|
1727
|
+
results, not an identical-output speedup. Single-request decode changes winner
|
|
1728
|
+
with order; cached first output remains slightly slower on the shared path.
|
|
1729
|
+
Strict serial-dominance acceptance remains open.
|
|
1730
|
+
|
|
1731
|
+
Native adapter B=1 control, compatible B=2, mixed queues, callback failure,
|
|
1732
|
+
separate prefix reuse and queued adapter replacement pass on M1/M4. Both
|
|
1733
|
+
machines match 48 full logit vectors against the pinned same-B adapter oracle.
|
|
1734
|
+
KV4 plus logprobs also passes the native composition checks on both machines;
|
|
1735
|
+
this is not an external quantized-batch oracle claim.
|
|
1736
|
+
|
|
1737
|
+
Raw: `reports/qwen38-closeout/composition-baseline/`
|
|
1738
|
+
`adapter-composition-{0,1}.md.json` and
|
|
1739
|
+
`adapter-composition-performance-review.json`. Frozen source:
|
|
1740
|
+
`e92487827cbb4755f5bd0cb4880999b2aa1d1aba64a86b7bfc6042b0b458723c`.
|
|
1741
|
+
Native logs: `m1-batch-adapters-replacement.log`,
|
|
1742
|
+
`m1-batch-adapter-oracle.log`, `m4-batch-adapters-oracle.log`, and
|
|
1743
|
+
`{m1,m4}-batch-adapters-kv4-logprobs.log`.
|
|
1744
|
+
|
|
1745
|
+
|
|
1746
|
+
### State-only recurrent replay experiment — M4 Pro (2026-09-09)
|
|
1747
|
+
|
|
1748
|
+
Packed Qwen 27B with its folded RTN4 MTP companion, depth four and KV4,
|
|
1749
|
+
Bun 1.4.2 and MLX 0.32.2 on the M4 Pro 24 GB. Both versions use the same
|
|
1750
|
+
serial serving control and shared prefill cache. Only recurrent prefix replay
|
|
1751
|
+
changes. The existing serving suite ran reference/candidate, then
|
|
1752
|
+
candidate/reference, with matched requests within each block. Preflight passed
|
|
1753
|
+
under Josh's audio-daemon CPU allowance; raw reports retain `canonical:false`.
|
|
1754
|
+
|
|
1755
|
+
| Block/order | Five decode requests, reference → candidate | Sum of four queued request times, reference → candidate | Cached TTFT, reference → candidate |
|
|
1756
|
+
|---|---:|---:|---:|
|
|
1757
|
+
| 0, reference/candidate | 135,674.99 → 135,614.72 ms | 176,655.25 → 176,192.41 ms | 94.03 → 94.10 ms |
|
|
1758
|
+
| 1, candidate/reference | 130,083.45 → 129,893.97 ms | 189,279.10 → 189,066.15 ms | 93.98 → 93.78 ms |
|
|
1759
|
+
|
|
1760
|
+
All 30 recorded responses match in text, counts, cached coverage and finish
|
|
1761
|
+
reason; both completion/chat probes match and no phase failed. The five-request
|
|
1762
|
+
decode totals improve by only 0.044% and 0.146%. Warmup complete time regresses
|
|
1763
|
+
in both blocks, by 8.41% and 0.32%. This is **inconclusive for default promotion**.
|
|
1764
|
+
The independently required batched recurrence can use its row-length-aware
|
|
1765
|
+
kernel; uniform replay retains its existing kernel pending a demonstrated win.
|
|
1766
|
+
|
|
1767
|
+
Raw files: `reports/qwen38-closeout/composition-baseline/`
|
|
1768
|
+
`state-replay-{reference,candidate}-{0,1}.md.json` and
|
|
1769
|
+
`state-replay-performance-review.json`. Both sources stay fixed across blocks:
|
|
1770
|
+
reference `a01bee0b7e1962c8211f1ffd845d95f7923d6c04bddb18cf06f07483cab9e7e8`,
|
|
1771
|
+
candidate `9ea170f63a70b143a978fd2f8519c265a363760fcc5921ab7fe7c51f6ff2a173`.
|
|
1772
|
+
These reports measure the isolated replay experiment, not the subsequent
|
|
1773
|
+
attention-cache and draft-interface work.
|
|
1774
|
+
|
|
1775
|
+
|
|
1776
|
+
### Shared MTP drafting candidate — M4 Pro (2026-09-09)
|
|
1777
|
+
|
|
1778
|
+
Packed Qwen 27B, folded RTN4 companion, MTP depth two, KV4, Bun 1.4.2 and
|
|
1779
|
+
MLX 0.32.2 on the M4 Pro 24 GB. The candidate replaces the request-local
|
|
1780
|
+
draft/commit loop with the shared row method at B=1. Both use the existing
|
|
1781
|
+
serving control and shared prefill cache. The official serving suite ran in
|
|
1782
|
+
both orders with 192-token decode requests. Preflight passed under Josh's
|
|
1783
|
+
audio-daemon CPU allowance; reports retain `canonical:false`.
|
|
1784
|
+
|
|
1785
|
+
| Block/order | Five decode requests, reference → candidate | Sum of four queued request times, reference → candidate |
|
|
1786
|
+
|---|---:|---:|
|
|
1787
|
+
| 0, reference/candidate | 53,764.24 → 53,884.42 ms | 80,319.89 → 81,191.39 ms |
|
|
1788
|
+
| 1, candidate/reference | 56,025.69 → 56,363.44 ms | 78,935.80 → 81,001.15 ms |
|
|
1789
|
+
|
|
1790
|
+
All 30 recorded request hashes, response hashes, token counts, cached coverage
|
|
1791
|
+
and finish reasons match, with no failures and unchanged source snapshots.
|
|
1792
|
+
Decode complete time regresses by 0.22% and 0.60%; summed queued-request time
|
|
1793
|
+
regresses by 1.09% and 2.62%. The four-request 1k-context phase also regresses,
|
|
1794
|
+
by 2.09% and 3.04%. This candidate has not established equal-or-better serving
|
|
1795
|
+
performance and is not adopted. Native before/after prefix continuations match
|
|
1796
|
+
on both Macs; those correctness results do not close the timing gate.
|
|
1797
|
+
|
|
1798
|
+
Raw: `reports/qwen38-closeout/composition-baseline/`
|
|
1799
|
+
`mtp-row-{reference,candidate}-{0,1}.md.json` and
|
|
1800
|
+
`mtp-shared-draft-performance-review.json`. Frozen source hashes:
|
|
1801
|
+
reference `a0f66ee4bbf357cdd7ace981e31c4f21d8e1705b7f052e5bd6ce0b8bccf68ab5`,
|
|
1802
|
+
candidate `dcaf122ce30b38e60847af6c0fd4df59232ccb2552ec7fb98019d231e1757b75`.
|
|
1803
|
+
Four queued requests here still execute one at a time; this is not B=4 MTP
|
|
1804
|
+
serving acceptance.
|
|
1805
|
+
|
|
1806
|
+
The subsequent candidate replaces the B=1 hidden gather with a slice of the
|
|
1807
|
+
same verification context. On the same machine/toolchain and settings, two
|
|
1808
|
+
new matched blocks preserve all 30 responses, counts, cached coverage and
|
|
1809
|
+
finish reasons, plus both parity probes, with no failures or source changes.
|
|
1810
|
+
|
|
1811
|
+
| Block/order | Five decode requests, reference → slice candidate | Sum of four queued request times, reference → slice candidate | Cached TTFT, reference → slice candidate |
|
|
1812
|
+
|---|---:|---:|---:|
|
|
1813
|
+
| 0, candidate/reference | 56,802.25 → 56,806.30 ms | 83,579.51 → 82,931.12 ms | 93.85 → 93.78 ms |
|
|
1814
|
+
| 1, reference/candidate | 55,672.47 → 56,315.67 ms | 80,785.87 → 82,545.85 ms | 93.54 → 94.80 ms |
|
|
1815
|
+
|
|
1816
|
+
The first block's decode time is essentially flat; the reverse-order block
|
|
1817
|
+
regresses by 1.16%. Queued-request gains also reverse, and the 1k-context phase
|
|
1818
|
+
changes by -0.57% then +2.34%. This does not close the performance gate. The
|
|
1819
|
+
source replacement and slice specialization remain isolated. Do not attribute
|
|
1820
|
+
the full variation to the gather or claim a speedup from the first block.
|
|
1821
|
+
|
|
1822
|
+
Raw: `mtp-slice-{reference,candidate}-{0,1}.md.json` and
|
|
1823
|
+
`mtp-slice-performance-review.json` in the same report directory. Reference
|
|
1824
|
+
hash is unchanged; slice candidate hash is
|
|
1825
|
+
`665acf5432f5cde64207a475edff0f999215f2fb9df014fce8db295e6cc20bd9`.
|
|
1826
|
+
|
|
1827
|
+
### Concurrent MTP serving candidate — M4 Pro (2026-09-09)
|
|
1828
|
+
|
|
1829
|
+
Packed Qwen 27B, folded RTN4 companion, MTP depth two and KV4, Bun 1.4.2
|
|
1830
|
+
and MLX 0.32.2 on the M4 Pro 24 GB. The existing serving suite compares
|
|
1831
|
+
strict serial with shared execution in both arm orders. Each block uses
|
|
1832
|
+
matched requests and a fixed source, with 192-token decode requests and no
|
|
1833
|
+
long-context leg. Preflight passes under the recorded audio CPU allowance.
|
|
1834
|
+
|
|
1835
|
+
| Arm order | Five decode requests, serial / shared | Cached TTFT, serial / shared | Observed four-request throughput, serial / shared |
|
|
1836
|
+
|---|---:|---:|---:|
|
|
1837
|
+
| Serial first | 56,130.19 / 55,549.00 ms | 93.58 / 214.00 ms | 15.88 / 16.18 tok/s |
|
|
1838
|
+
| Shared first | 54,137.25 / 53,914.05 ms | 93.63 / 218.90 ms | 16.08 / 16.41 tok/s |
|
|
1839
|
+
|
|
1840
|
+
All 22 single-request output/usage pairs and both parity probes match, with
|
|
1841
|
+
no phase failures. Single-request decode totals improve by 1.04% and 0.41%,
|
|
1842
|
+
but cached first output regresses in both orders. This does not meet serial
|
|
1843
|
+
dominance and is not adopted. Seven of eight concurrent outputs differ across
|
|
1844
|
+
arms, so aggregate throughput is an observed result, not an identical-output
|
|
1845
|
+
speed ratio. The separate native/HTTP gate confirms real B=4 MTP verification.
|
|
1846
|
+
|
|
1847
|
+
The next revision exposes preparation output through the shared scheduling
|
|
1848
|
+
readiness interface. Scheduling yields after admission completes, before the
|
|
1849
|
+
next graph. The same two arm orders give:
|
|
1850
|
+
|
|
1851
|
+
| Arm order | Five decode requests, serial / shared | Cached TTFT, serial / shared | Observed four-request throughput, serial / shared |
|
|
1852
|
+
|---|---:|---:|---:|
|
|
1853
|
+
| Serial first | 56,583.61 / 55,563.91 ms | 93.64 / 98.28 ms | 15.52 / 16.21 tok/s |
|
|
1854
|
+
| Shared first | 54,175.23 / 53,514.51 ms | 93.48 / 99.70 ms | 16.09 / 16.19 tok/s |
|
|
1855
|
+
|
|
1856
|
+
All 22 single-request pairs match, with no phase failures. Decode totals
|
|
1857
|
+
improve by 1.80% and 1.22%. The remaining cached TTFT gap is 4.64 and 6.22 ms,
|
|
1858
|
+
so strict serial dominance remains open. Seven of eight concurrent outputs
|
|
1859
|
+
again differ, preventing an identical-output aggregate speed claim.
|
|
1860
|
+
Moving publication ahead of the remaining state admission gives these results:
|
|
1861
|
+
|
|
1862
|
+
| Arm order | Five decode requests, serial / shared | Cached TTFT, serial / shared | Observed four-request throughput, serial / shared |
|
|
1863
|
+
|---|---:|---:|---:|
|
|
1864
|
+
| Serial first | 56,139.21 / 55,564.02 ms | 93.64 / 97.75 ms | 15.76 / 16.24 tok/s |
|
|
1865
|
+
| Shared first | 54,122.55 / 54,352.40 ms | 93.60 / 100.76 ms | 16.09 / 15.89 tok/s |
|
|
1866
|
+
|
|
1867
|
+
All 22 single-request pairs still match, with no failures. Decode totals change
|
|
1868
|
+
by -1.02% and +0.42%; the cached first-output gap remains. Seven concurrent
|
|
1869
|
+
outputs differ. This revision also does not establish dominance. The next
|
|
1870
|
+
candidate removes allocator cache clearing from shared output delivery while
|
|
1871
|
+
preserving the methods' own maintenance. It also fixes cleanup after state
|
|
1872
|
+
admission. Its two arm orders produce:
|
|
1873
|
+
|
|
1874
|
+
| Arm order | Five decode requests, serial / shared | Cached TTFT, serial / shared | Observed four-request throughput, serial / shared |
|
|
1875
|
+
|---|---:|---:|---:|
|
|
1876
|
+
| Serial first | 56,857.65 / 55,535.73 ms | 94.48 / 99.33 ms | 15.50 / 16.24 tok/s |
|
|
1877
|
+
| Shared first | 54,107.37 / 53,587.76 ms | 93.70 / 98.99 ms | 16.09 / 16.16 tok/s |
|
|
1878
|
+
|
|
1879
|
+
All 22 single-request pairs and parity probes match, with no failures. Decode
|
|
1880
|
+
totals improve by 2.32% and 0.96%, but cached TTFT trails serial by 4.85 and
|
|
1881
|
+
5.28 ms. Seven concurrent outputs differ. Allocator maintenance separation
|
|
1882
|
+
therefore does not resolve the latency gap or qualify serial removal.
|
|
1883
|
+
|
|
1884
|
+
Raw reports and reviews in
|
|
1885
|
+
`reports/qwen38-closeout/composition-baseline/`:
|
|
1886
|
+
`mtp-serving-serial-shared-0.md.json`, `mtp-serving-shared-serial-1.md.json`,
|
|
1887
|
+
`mtp-serving-performance-review.json`, `mtp-serving-output-yield-0.md.json`,
|
|
1888
|
+
`mtp-serving-output-yield-1.md.json` and
|
|
1889
|
+
`mtp-serving-output-yield-performance-review.json`, `mtp-serving-staged-0.md.json`,
|
|
1890
|
+
`mtp-serving-staged-1.md.json`, `mtp-serving-staged-performance-review.json`,
|
|
1891
|
+
`mtp-serving-method-maintenance-0.md.json`, `mtp-serving-method-maintenance-1.md.json`
|
|
1892
|
+
and `mtp-serving-method-maintenance-performance-review.json`.
|
|
1893
|
+
Initial frozen source:
|
|
1894
|
+
`4799c307be193a2cd53c91d95940c40e7294f41b13a07693ab4a45097be60d25`.
|
|
1895
|
+
First readiness revision:
|
|
1896
|
+
`e7d6955ea0ae8133b6445a5180fd68a784c8913072a13579f08392896cff8904`.
|
|
1897
|
+
Staged admission revision:
|
|
1898
|
+
`309d671bdcdd4830765d6af2341fe3b68a04c2eb9795929f9d6bcfb12f55e04d`.
|
|
1899
|
+
Method-owned maintenance revision:
|
|
1900
|
+
`311043d3a1add4bebffffc820a96f83dc415ad3ac6d6a17133e75540909ff273`.
|
|
1901
|
+
|
|
1902
|
+
The subsequent combined source includes the TurboQuant codec/row components.
|
|
1903
|
+
The first matched block keeps KV4/MTP2, so it measures overhead in the existing
|
|
1904
|
+
workload rather than TurboQuant serving. Compared directly with the previous
|
|
1905
|
+
method-maintenance block on the same M4:
|
|
1906
|
+
|
|
1907
|
+
| Metric | Previous shared | Combined shared |
|
|
1908
|
+
|---|---:|---:|
|
|
1909
|
+
| Five decode requests, complete time | 55,535.73 ms | 55,560.29 ms |
|
|
1910
|
+
| Median decode | 19.211 tok/s | 19.196 tok/s |
|
|
1911
|
+
| Cached TTFT | 99.33 ms | 99.55 ms |
|
|
1912
|
+
| Four concurrent requests | 16.238 tok/s | 16.241 tok/s |
|
|
1913
|
+
|
|
1914
|
+
All 15 shared request/output/usage pairs match, as do all 15 serial-control
|
|
1915
|
+
pairs. Shared decode time changes by +0.044%; this is effectively unchanged,
|
|
1916
|
+
not a demonstrated speed gain. The serial control changes by -0.94%. No phase
|
|
1917
|
+
fails and the combined source stays fixed. This is one arm-order block;
|
|
1918
|
+
the reverse-order repeat remains open. The first settings sweep follows.
|
|
1919
|
+
Raw report: `decode-composition-combined-0.md.json`; review:
|
|
1920
|
+
`decode-composition-previous-run-review.json`, in the same reports directory.
|
|
1921
|
+
Combined source:
|
|
1922
|
+
`2b7b258c983729be4dc723493ad6a14eea853c0166df9f2a36a4a3b27344f51c`.
|
|
1923
|
+
|
|
1924
|
+
The first settings sweep uses that same frozen source, the same block-0
|
|
1925
|
+
requests and the shared server. Each row includes five 192-token decode
|
|
1926
|
+
requests, short cold/cached prompts and four concurrent requests. Long-context
|
|
1927
|
+
and restart benchmark legs are excluded. Every report has zero failed phases
|
|
1928
|
+
and a stable source snapshot; the audio CPU allowance remains recorded.
|
|
1929
|
+
|
|
1930
|
+
| KV / draft depth | Five decode requests | Median decode | Cached TTFT | Four concurrent requests |
|
|
1931
|
+
|---|---:|---:|---:|---:|
|
|
1932
|
+
| Affine 4 / MTP2 | 55.560 s | 19.196 tok/s | 99.55 ms | 16.241 tok/s |
|
|
1933
|
+
| Affine 8 / MTP2 | 55.067 s | 19.442 tok/s | 98.96 ms | 16.329 tok/s |
|
|
1934
|
+
| Affine 4 / MTP4 | 136.714 s | 7.493 tok/s | 97.23 ms | 14.522 tok/s |
|
|
1935
|
+
| Affine 8 / MTP4 | 131.855 s | 7.683 tok/s | 97.48 ms | 15.170 tok/s |
|
|
1936
|
+
|
|
1937
|
+
MTP2 leads this first sweep. Changing precision or draft depth can change the
|
|
1938
|
+
continuation; these are observed configuration rates, not identical-output
|
|
1939
|
+
engine speedup ratios. The small KV8/MTP2 lead needs repetition. The expanded
|
|
1940
|
+
screen below adds async weight expansion, no-MTP controls and TurboQuant
|
|
1941
|
+
serving. No default changes are justified by this single block. Raw settings reports are
|
|
1942
|
+
`decode-settings-{kv8-mtp2,kv4-mtp4,kv8-mtp4}-0.md.json`; the summary is
|
|
1943
|
+
`decode-settings-first-sweep-review.json` in the same reports directory.
|
|
1944
|
+
|
|
1945
|
+
### Integrated settings screen and context repeat — M4 Pro (2026-09-09)
|
|
1946
|
+
|
|
1947
|
+
The isolated shared-serving candidate now includes TurboQuant ordinary/MTP
|
|
1948
|
+
groups. All 20 reports below use stable source
|
|
1949
|
+
`6e293a0efeb2f22e2557bf0e39373774545dc0737496c07e7bbe8cfbf6cd3939`,
|
|
1950
|
+
the same packed Qwen artifact and folded RTN4 companion, Bun 1.4.2,
|
|
1951
|
+
MLX 0.32.2 and the M4 Pro 24 GB. Preflight passes with Josh's audio-CPU
|
|
1952
|
+
allowance. The server's batch capacity is eight; the aggregate leg submits
|
|
1953
|
+
four requests. Separate native serving gates establish actual four-row MTP
|
|
1954
|
+
verification. These reports retain `canonical:false`.
|
|
1955
|
+
|
|
1956
|
+
Short-context block 0 uses matching requests and five 192-token decode
|
|
1957
|
+
samples. Fused TurboQuant decode is enabled; async Trellis expansion is off
|
|
1958
|
+
unless labeled. No report has a failed phase.
|
|
1959
|
+
|
|
1960
|
+
| KV / method | Five requests, complete ms | Median decode tok/s | Cached TTFT ms | Aggregate ×4 tok/s |
|
|
1961
|
+
|---|---:|---:|---:|---:|
|
|
1962
|
+
| bf16 / ordinary | 88,763.10 | 11.593 | 163.76 | 25.776 |
|
|
1963
|
+
| bf16 / MTP2 | 54,064.81 | 19.793 | 96.49 | 16.822 |
|
|
1964
|
+
| bf16 / MTP3 | 53,904.19 | 20.089 | 98.79 | 16.952 |
|
|
1965
|
+
| Affine 4 / ordinary | 89,551.02 | 11.521 | 164.78 | 25.689 |
|
|
1966
|
+
| Affine 4 / MTP1 | 61,737.80 | 17.170 | 96.91 | 15.695 |
|
|
1967
|
+
| Affine 4 / MTP2 | 55,544.22 | 19.200 | 99.49 | 16.247 |
|
|
1968
|
+
| Affine 4 / MTP3 | 61,344.01 | 17.198 | 98.07 | 16.208 |
|
|
1969
|
+
| Affine 4 / MTP2, async | 55,282.33 | 19.167 | 99.02 | 16.243 |
|
|
1970
|
+
| Affine 4 / MTP4, async | 136,386.37 | 7.487 | 97.26 | 14.559 |
|
|
1971
|
+
| Affine 8 / ordinary | 88,955.50 | 11.571 | 167.18 | 25.679 |
|
|
1972
|
+
| Affine 8 / MTP1 | 62,207.00 | 17.003 | 97.45 | 15.510 |
|
|
1973
|
+
| Affine 8 / MTP3 | 56,289.15 | 18.991 | 99.90 | 16.664 |
|
|
1974
|
+
| TQ K8V3 / ordinary | 90,881.00 | 11.403 | 174.53 | 25.308 |
|
|
1975
|
+
| TQ K8V3 / MTP2 | 56,578.08 | 19.242 | 102.53 | 16.429 |
|
|
1976
|
+
| TQ K8V3 / MTP3 | 56,923.87 | 19.065 | 102.78 | 16.046 |
|
|
1977
|
+
| TQ K8V3 / MTP4 | 131,849.48 | 7.593 | 101.34 | 14.481 |
|
|
1978
|
+
|
|
1979
|
+
The affine-4/MTP2 integration control preserves all 15 request/output pairs
|
|
1980
|
+
against the preceding `2b7b…` source; complete decode time changes by -0.029%,
|
|
1981
|
+
effectively unchanged. Its async arm also preserves all 15 outputs, with
|
|
1982
|
+
complete time -0.47% in this one block. Async expansion does not remove the
|
|
1983
|
+
MTP4 decode cliff. MTP3 uses its third proposal: affine-4 accepts 109 of 386
|
|
1984
|
+
third-position drafts, affine-8 accepts 114 of 373. Acceptance alone does not
|
|
1985
|
+
make the extra work profitable.
|
|
1986
|
+
|
|
1987
|
+
The four leading comparison profiles then run full `bench-serve all` with
|
|
1988
|
+
block-1 inputs and `--context 16384`. The rendered prompt actually contains
|
|
1989
|
+
**10,398 tokens**. Each context leg has a cold request and two RAM-cached
|
|
1990
|
+
repeats, followed by an explicit durable flush and SSD restart.
|
|
1991
|
+
|
|
1992
|
+
| KV / method | Five short requests, complete ms | Short decode tok/s | Context decode tok/s | Cold context TTFT ms | SSD restart TTFT ms |
|
|
1993
|
+
|---|---:|---:|---:|---:|---:|
|
|
1994
|
+
| bf16 / MTP3 | 56,107.03 | 19.179 | 23.130 | 80,060.42 | 2,026.44 |
|
|
1995
|
+
| TQ K8V3 / MTP3 | 58,195.34 | 18.350 | 19.580 | 79,777.84 | 1,936.05 |
|
|
1996
|
+
| Affine 4 / MTP2 | 53,548.41 | 20.133 | 22.184 | 79,860.36 | 1,919.74 |
|
|
1997
|
+
| Affine 4 / MTP3 | 56,923.65 | 18.999 | 22.826 | 79,912.94 | 1,930.17 |
|
|
1998
|
+
|
|
1999
|
+
Within each profile the three context responses match exactly. Every restart
|
|
2000
|
+
restores 10,397 cached tokens, with zero pending, dropped or failed spills
|
|
2001
|
+
after flush. Across settings, continuations can differ; these rates do not
|
|
2002
|
+
establish an identical-output engine speedup. MTP2 leads affine-4 short
|
|
2003
|
+
requests, while MTP3 has a small context-decode lead. Ordinary batching has
|
|
2004
|
+
the strongest aggregate throughput in the short screen. The choice of one
|
|
2005
|
+
default for typical single-user multi-turn/tool use remains open pending
|
|
2006
|
+
late-task context measurements and balanced repeats; user overrides remain.
|
|
2007
|
+
|
|
2008
|
+
Raw files in `reports/qwen38-closeout/composition-baseline/`:
|
|
2009
|
+
`decode-integrated-*-0.md.json`, `decode-default-*-context-1.md.json` and
|
|
2010
|
+
`decode-integrated-settings-review.json`. Source archives remain frozen on
|
|
2011
|
+
the M4; no candidate default has been promoted.
|
|
2012
|
+
|
|
2013
|
+
The subsequent late-context control uses the same frozen source and
|
|
2014
|
+
`--context 125000`. KV4/MTP2 fails the context phase, including its retry,
|
|
2015
|
+
with Metal command-buffer out-of-memory at the default 2,048-token prefill
|
|
2016
|
+
chunk. It supplies no context decode or restart result. Preflight passed
|
|
2017
|
+
with 96 MB retained swap and 93% free memory; swap remained 96 MB afterward.
|
|
2018
|
+
Raw: `decode-default-kv4-mtp2-late-context-0.md.json` in the same directory.
|
|
2019
|
+
The next depth-3 attempt was stopped before the context leg to avoid repeating
|
|
2020
|
+
the same oversized configuration. A separate depth-2/3/1 comparison uses
|
|
2021
|
+
`MLX_BUN_RD_PREFILL_CHUNK=256`, matching the published Kanban prefill profile;
|
|
2022
|
+
depth 2 now completes at **78,678 actual prompt tokens**. Cold first-output time
|
|
2023
|
+
is 884.14 seconds, context decode median is 12.828 tok/s, cached repeat
|
|
2024
|
+
first-output time is 237.45 ms and fresh-process SSD restart first-output time
|
|
2025
|
+
is 2,229.68 ms with 78,677 cached tokens. All three context outputs match;
|
|
2026
|
+
the eight-token restart output matches their beginning. Flush is durable with
|
|
2027
|
+
zero pending, dropped or failed writes, and the source hash remains unchanged.
|
|
2028
|
+
Depth 3 also completes on unchanged source. Its cold first-output time is
|
|
2029
|
+
884.68 seconds, context decode median 11.718 tok/s, cached first-output time
|
|
2030
|
+
187.75 ms and SSD restart first-output time 2,235.34 ms with 78,677 tokens
|
|
2031
|
+
restored. Its three context outputs match each other, but differ from depth 2;
|
|
2032
|
+
these are settings comparisons, not identical-output engine comparisons.
|
|
2033
|
+
Durability also passes with no pending, dropped or failed writes. Depth 1
|
|
2034
|
+
completes at 10.582 tok/s context decode, with 884.59 seconds cold first-output
|
|
2035
|
+
time, 189.69 ms cached first-output time and 2,243.35 ms after SSD restart.
|
|
2036
|
+
It restores 78,677 tokens; all three context outputs match depth 2. Source
|
|
2037
|
+
hashes are stable, both preflights pass and there are no phase failures or
|
|
2038
|
+
pending, dropped or failed writes. These single profiles do not select a
|
|
2039
|
+
default. Raw: `decode-default-kv4-mtp{1,2,3}-late-context-chunk256-0.md.json`.
|
|
2040
|
+
Ordinary shared prefill in the frozen benchmark source does not read that
|
|
2041
|
+
control. The adopted policy fix makes ordinary and speculative prefill use the group's
|
|
2042
|
+
captured default and preserves the library request override. Its M1 seeded
|
|
2043
|
+
native and MTP RAM/SSD gates, complete model-free suite and typecheck pass; a matched M4
|
|
2044
|
+
ordinary late-context arm remains open.
|
|
2045
|
+
|
|
2046
|
+
The composed ownership/prefill-policy short control is complete on the M4
|
|
2047
|
+
Pro, with source `04f518534d568d10cd570e3ecd671a69ccbe97513f803d3a29ac250269416a0d`.
|
|
2048
|
+
It uses the same block-0 requests, KV4/MTP2, default prefill chunk and runtime
|
|
2049
|
+
settings as the frozen `6e293a0...` arm. All 14 measured request hashes,
|
|
2050
|
+
response texts, generated counts and cached counts match. Five decode requests
|
|
2051
|
+
take 55,619.41 ms versus 55,544.22 ms, a 0.14% increase; median decode is
|
|
2052
|
+
19.195 versus 19.200 tok/s. Cached first-output time is 97.56 versus 99.49 ms,
|
|
2053
|
+
and four-request aggregate throughput is 16.203 versus 16.247 tok/s. This
|
|
2054
|
+
single comparison is effectively unchanged, with no performance win claimed.
|
|
2055
|
+
There are no phase failures and source hashes remain stable. The arm includes
|
|
2056
|
+
the Gemma ownership fix and captured prefill policy, but not generated-output
|
|
2057
|
+
publication. Raw: `composition-baseline/decode-prefill-policy-kv4-mtp2-short-0.md.json`
|
|
2058
|
+
under `reports/qwen38-closeout/`.
|
|
2059
|
+
|
|
2060
|
+
The same composed source also completes the 78,678-token KV4/MTP2 context
|
|
2061
|
+
control with 256-token chunks. All 19 request hashes, response texts,
|
|
2062
|
+
generated counts and cached counts match the frozen arm. Cold first-output
|
|
2063
|
+
time is 884.12 versus 884.14 seconds; context decode median is 12.918 versus
|
|
2064
|
+
12.828 tok/s. Cached first-output time is 188.35 versus 237.45 ms and restart
|
|
2065
|
+
time is 2,230.56 versus 2,229.68 ms, with 78,677 tokens restored. Durability
|
|
2066
|
+
has no pending, dropped or failed writes; source hashes and both preflights
|
|
2067
|
+
pass. This single comparison does not establish a latency or throughput win.
|
|
2068
|
+
Raw: `composition-baseline/decode-prefill-policy-kv4-mtp2-late-context-chunk256-0.md.json`.
|
|
2069
|
+
The wrapper failed before launching the ordinary arm because macOS Bash 3
|
|
2070
|
+
rejects its empty-array expansion under `set -u`. That arm was resumed alone;
|
|
2071
|
+
the completed MTP report was preserved.
|
|
2072
|
+
|
|
2073
|
+
|
|
2074
|
+
The subsequent ordinary KV4 late-context arm on the same M4 Pro source did
|
|
2075
|
+
**not** pass clean acceptance. Its first 78,678-token cold request completed
|
|
2076
|
+
with 881,941 ms to first output, but the cached repeat failed with Metal
|
|
2077
|
+
`kIOGPUCommandBufferCallbackErrorOutOfMemory`. The benchmark's built-in retry
|
|
2078
|
+
restarted the phase with a different request hash and 78,677 prompt tokens.
|
|
2079
|
+
That retry completed at 7.319 tok/s median context decode, 292.54 ms cached
|
|
2080
|
+
first output and 2,262.76 ms after SSD restart, reusing 78,676 tokens. These
|
|
2081
|
+
are recovery diagnostics, not a matched successful ordinary/MTP comparison.
|
|
2082
|
+
Both machine checks passed and source stayed fixed; final swap was 294.69 MB.
|
|
2083
|
+
The final flush retained 17 entries with no pending, dropped or failed spills.
|
|
2084
|
+
The initial failure and both attempts remain in
|
|
2085
|
+
`reports/qwen38-closeout/composition-baseline/decode-prefill-policy-kv4-plain-late-context-chunk256-0.md.json`.
|
|
2086
|
+
The cached-repeat allocation failure needs investigation before repeating
|
|
2087
|
+
ordinary late-context acceptance. Independent output-cache/prefill correctness
|
|
2088
|
+
resumed without rerunning or reclassifying this failed benchmark.
|
|
2089
|
+
|
|
2090
|
+
|
|
2091
|
+
The final generated-output/prefill composition also passes M4 native and
|
|
2092
|
+
HTTP bf16/KV4/fused-TQ cache continuation, parser/template replay, full-suite
|
|
2093
|
+
and typecheck gates. Its short KV4/MTP2 block-0 benchmark uses source
|
|
2094
|
+
`af91e6a64649df5af9eb73e4a35739109f6799a5c8ba7ddc47c3543876cb19c0`.
|
|
2095
|
+
All 14 measured requests plus warmup match the prefill-policy control's
|
|
2096
|
+
request hashes, response text, prompt/generated counts and cached counts.
|
|
2097
|
+
Five decode requests take 55,636.28 versus 55,619.41 ms, a 0.03% increase;
|
|
2098
|
+
median decode is 19.171 versus 19.195 tok/s. Cached first output is 99.06
|
|
2099
|
+
versus 97.56 ms, and aggregate throughput is 15.859 versus 16.203 tok/s.
|
|
2100
|
+
Source and preflights are stable with no failures. This is one matched
|
|
2101
|
+
composition check with flat decode; it establishes no overall speed win or
|
|
2102
|
+
strict serial-domination result. Long Kanban and pressure acceptance remain.
|
|
2103
|
+
Raw: `composition-baseline/decode-output-prefill-kv4-mtp2-short-0.md.json`.
|
|
2104
|
+
|
|
2105
|
+
|
|
2106
|
+
The isolated variable-proposal verifier passes M4 uniform/variable bf16/KV4
|
|
2107
|
+
native controls, the full suite and typecheck. Its first short KV4/MTP2
|
|
2108
|
+
block-0 comparison is slower: five decode requests take 58,907.66 versus
|
|
2109
|
+
55,636.28 ms, a 5.88% increase; median decode is 17.936 versus 19.171 tok/s.
|
|
2110
|
+
Cached first output is 97.51 versus 99.06 ms and aggregate throughput is
|
|
2111
|
+
15.911 versus 15.859 tok/s. All measured requests plus warmup preserve
|
|
2112
|
+
request hashes, responses, prompt/generated/cache counts and speculation
|
|
2113
|
+
statistics. Source `885f542f07ea48e119a6bdaf533b4e2605ff293c3d7eb373ac202410032e24dd`
|
|
2114
|
+
and both preflights are stable, with no failures. This single ordered
|
|
2115
|
+
comparison does not distinguish a code regression from machine drift.
|
|
2116
|
+
Alternating frozen control/candidate repeats below test whether that slowdown
|
|
2117
|
+
follows the source.
|
|
2118
|
+
Raw: `composition-baseline/decode-variable-proposals-kv4-mtp2-short-0.md.json`.
|
|
2119
|
+
|
|
2120
|
+
The subsequent M4 Pro 24 GB A/B/B/A repeats use the same two frozen sources,
|
|
2121
|
+
KV4, MTP2, 192-token limit, block-0 workload and runtime environment. All 15
|
|
2122
|
+
requests per arm, including warmup, match request/output hashes, token counts,
|
|
2123
|
+
finish reasons and complete usage/speculation records. Both preflights pass
|
|
2124
|
+
and each source remains unchanged, with no request or phase failures.
|
|
2125
|
+
|
|
2126
|
+
| Arm | Five decode requests, total ms | Median decode tok/s | Cached first output ms | Aggregate tok/s |
|
|
2127
|
+
|---|---:|---:|---:|---:|
|
|
2128
|
+
| Control 1 | 55,559.96 | 19.154 | 98.90 | 15.853 |
|
|
2129
|
+
| Candidate 1 | 55,618.37 | 19.152 | 97.29 | 15.674 |
|
|
2130
|
+
| Candidate 2 | 55,566.01 | 19.189 | 97.23 | 15.880 |
|
|
2131
|
+
| Control 2 | 55,604.33 | 19.166 | 99.06 | 15.917 |
|
|
2132
|
+
|
|
2133
|
+
Combined candidate decode wall time is **0.018% higher**. The initial 5.88%
|
|
2134
|
+
slowdown does not reproduce; this screen supports preserving fixed-MTP decode
|
|
2135
|
+
performance while adding variable proposals. Aggregate throughput varies and
|
|
2136
|
+
establishes no gain. This does not qualify actual prompt-lookup performance,
|
|
2137
|
+
long contexts or serial deletion. The verifier patch is adopted in the working
|
|
2138
|
+
tree after the both-machine correctness gates; the main suite and typecheck pass.
|
|
2139
|
+
Raw reports and derived identity/timing comparison:
|
|
2140
|
+
`composition-baseline/variable-proposals/decode-variable-alternating-*.md.json`
|
|
2141
|
+
and `composition-baseline/variable-proposals/alternating-comparison.json`.
|
|
2142
|
+
|
|
2143
|
+
The prompt-lookup integration's fixed-MTP regression screen uses the same M4
|
|
2144
|
+
Pro 24 GB, KV4/MTP2, block-0 requests and runtime settings. Frozen source
|
|
2145
|
+
`3df52152aac2289b9ed860c2789141acb5e8d6ce7a6170899f34bd9ef1ac9a39`
|
|
2146
|
+
retains all 15 request/output hashes and complete usage/speculation records
|
|
2147
|
+
against variable-verifier candidate2 above. Five decode requests take
|
|
2148
|
+
55,620.03 versus 55,566.01 ms, a 0.097% increase; median decode is 19.176
|
|
2149
|
+
versus 19.189 tok/s, cached first output 97.56 versus 97.23 ms, and aggregate
|
|
2150
|
+
throughput 15.778 versus 15.880 tok/s. Source/preflights are stable with no
|
|
2151
|
+
request or phase failures. This one short screen establishes no speedup;
|
|
2152
|
+
actual prompt-lookup serial/shared comparisons remain separate.
|
|
2153
|
+
Raw and comparison: `composition-baseline/ngram-group/decode-ngram-group-kv4-mtp2-short-0.md.json`
|
|
2154
|
+
and `composition-baseline/ngram-group/fixed-mtp-comparison.json`.
|
|
2155
|
+
|
|
2156
|
+
The subsequent delayed-TQ/method composition passes M4 fused/unfused native,
|
|
2157
|
+
SSD, complete-suite, typecheck and hygiene checks. Its short fixed-KV4/MTP2
|
|
2158
|
+
screen, source `88da0dca100cdb012cbd4330638cc43b727dbb853a5b1ef6aded60bc6fe1eb0d`,
|
|
2159
|
+
preserves all 15 request/output hashes and complete usage/speculation records
|
|
2160
|
+
against the frozen lookup base. Five decode requests take 55,812.61 versus
|
|
2161
|
+
55,620.03 ms, a 0.35% increase. Median decode is 19.123 versus 19.176 tok/s,
|
|
2162
|
+
cached first output 98.72 versus 97.56 ms, and aggregate throughput 15.724
|
|
2163
|
+
versus 15.778 tok/s. Source/preflights pass with no failures. This single
|
|
2164
|
+
short composition screen establishes no gain and does not measure delayed
|
|
2165
|
+
TurboQuant performance, since the workload uses KV4.
|
|
2166
|
+
Raw: `composition-baseline/method-composed/decode-tq-method-composed-kv4-mtp2-short-0.md.json`
|
|
2167
|
+
and `composition-baseline/method-composed/fixed-mtp-comparison.json`.
|
|
2168
|
+
|
|
2169
|
+
Two M4 Pro 24 GB prompt-lookup comparisons use KV4, draft depth 3,
|
|
2170
|
+
192-token decode requests, and reversed arm order on two workload seeds.
|
|
2171
|
+
Source is the same frozen lookup candidate above; both preflights and source
|
|
2172
|
+
checks pass with no request or phase failures. All single-request response
|
|
2173
|
+
pairs match, including their generated counts and finish reasons.
|
|
2174
|
+
|
|
2175
|
+
| Arm order | Five decode requests, serial / shared ms | Cached first output, serial / shared ms | Observed aggregate tok/s, serial / shared |
|
|
2176
|
+
|---|---:|---:|---:|
|
|
2177
|
+
| Serial first | 92,140.46 / 91,472.96 | 5,843.26 / 126.77 | 10.213 / 9.430 |
|
|
2178
|
+
| Shared first | 89,953.79 / 89,279.30 | 5,863.21 / 126.66 | 10.798 / 9.608 |
|
|
2179
|
+
|
|
2180
|
+
Single-request decode totals improve by 0.72% and 0.75%. Shared prompt lookup
|
|
2181
|
+
restores 758 and 757 tokens on the cached repetitions; serial restores zero.
|
|
2182
|
+
That is an actual new cache benefit, with different prefill work. All eight
|
|
2183
|
+
concurrent output pairs differ, and observed shared throughput is lower in
|
|
2184
|
+
both orders. An identical-output aggregate comparison and shared-execution
|
|
2185
|
+
dominance remain unproven. Wider verification cost and acceptance need further
|
|
2186
|
+
measurement; the result does not qualify deleting serial. Default-depth-10
|
|
2187
|
+
KV4 serving correctness subsequently passes 219 assertions on each Mac, with
|
|
2188
|
+
all ten proposal positions exercised; this is not depth-10 timing acceptance.
|
|
2189
|
+
Raw: `composition-baseline/ngram-group/decode-ngram-group-kv4-serial-shared-{0,1}.md.json`
|
|
2190
|
+
and `composition-baseline/ngram-group/lookup-paired-comparison.json`.
|
|
2191
|
+
|
|
2192
|
+
A separate M1 Max first-output diagnostic uses a 758-token prompt, KV4/MTP2
|
|
2193
|
+
and eight generated tokens through direct serial/shared execution. All eight
|
|
2194
|
+
outputs match and warm requests restore 757 tokens. Draft seeding accounts
|
|
2195
|
+
for roughly 93 ms on the warm traces; cache lookup is about 0.3–0.6 ms.
|
|
2196
|
+
Instrumenting the native allocator cleanup then identifies 0–6.8 ms inside
|
|
2197
|
+
`clearCache()` after the one-token target forward, on both execution paths.
|
|
2198
|
+
The shared path does not consistently trail serial in this loaded diagnostic;
|
|
2199
|
+
it does not explain the M4 gap by itself. A bounded candidate will skip this
|
|
2200
|
+
cleanup for one-token prefill work while retaining larger-chunk cleanup, with
|
|
2201
|
+
numerical, allocation and M4 request-time checks before adoption. Raw traces:
|
|
2202
|
+
`composition-baseline/mtp-first-output-diagnostic-m1.jsonl` and
|
|
2203
|
+
`composition-baseline/mtp-clear-diagnostic-m1.jsonl`.
|
|
2204
|
+
|
|
2205
|
+
The one-token maintenance candidate also completes a separate-process M1 Max
|
|
2206
|
+
allocation comparison at 8,195 prompt tokens, MTP2/KV4, chunk256, eight output
|
|
2207
|
+
tokens and a 4 GiB RAM cache without SSD. All three paired outputs, cache counts
|
|
2208
|
+
and speculation records match. Both warm repeats restore 8,194 tokens.
|
|
2209
|
+
Warm peak live allocation above the starting live state is 544.717 MiB for
|
|
2210
|
+
control and 544.732 MiB for candidate, a 16,208-byte increase. Final live
|
|
2211
|
+
allocation is effectively unchanged; the candidate's final allocator pool is
|
|
2212
|
+
845.54 versus 709.29 MiB, so it retains about 136 MiB more unused capacity in
|
|
2213
|
+
this run. This loaded M1 diagnostic establishes no speedup and does not replace
|
|
2214
|
+
M4 long-context/SSD pressure coverage. Raw and derived records:
|
|
2215
|
+
`composition-baseline/single-token-maintenance/m1-allocation-{control,candidate}.jsonl`
|
|
2216
|
+
and `composition-baseline/single-token-maintenance/m1-allocation-comparison.json`.
|
|
2217
|
+
|
|
2218
|
+
Four alternating M4 Pro 24 GB fixed-MTP2/KV4 short runs compare the one-token
|
|
2219
|
+
maintenance candidate against the composed source above. Bun is 1.4.2,
|
|
2220
|
+
MLX is 0.32.2, fused TQ decode is enabled and asynchronous Trellis expansion
|
|
2221
|
+
is disabled. Both arms use seed `mtp-serving-block-0`, 192 output tokens,
|
|
2222
|
+
a 4 GiB prompt cache and the same packed target/RTN4 companion. Control source
|
|
2223
|
+
is `88da0dca100cdb012cbd4330638cc43b727dbb853a5b1ef6aded60bc6fe1eb0d`;
|
|
2224
|
+
candidate is `c12b60c1c7f39bf4ccdeaa7cdd16795a04d6ca2246eeb7609ec97cb9eee65315`.
|
|
2225
|
+
All four source snapshots and preflights pass under the recorded audio-CPU
|
|
2226
|
+
allowance. All 60 requests preserve request hashes, output text, complete
|
|
2227
|
+
usage/acceptance records and finish reasons, with no failures.
|
|
2228
|
+
|
|
2229
|
+
| Order | Five decode requests, total ms | Cached first output, ms | Median decode, tok/s | Aggregate tok/s |
|
|
2230
|
+
|---|---:|---:|---:|---:|
|
|
2231
|
+
| Control 1 | 56,424.69 | 98.097 | 18.722 | 15.591 |
|
|
2232
|
+
| Candidate 1 | 55,595.29 | 96.483 | 19.198 | 15.799 |
|
|
2233
|
+
| Candidate 2 | 55,588.63 | 96.517 | 19.171 | 15.916 |
|
|
2234
|
+
| Control 2 | 55,581.64 | 98.214 | 19.174 | 15.959 |
|
|
2235
|
+
|
|
2236
|
+
Cached latency averages 98.156 versus 96.500 ms, a 1.69% reduction. The
|
|
2237
|
+
first control also has slower cold prefill and decode; both candidate decode
|
|
2238
|
+
totals are effectively flat against the second control. This screen supports
|
|
2239
|
+
the narrow cached-latency improvement, not a general throughput gain or
|
|
2240
|
+
serial/shared dominance. The candidate remains isolated pending the direct
|
|
2241
|
+
serial/shared comparison and pressure review. Raw and derived records:
|
|
2242
|
+
`composition-baseline/single-token-maintenance/decode-single-token-maintenance-{control1,candidate1,candidate2,control2}.md.json`
|
|
2243
|
+
and `composition-baseline/single-token-maintenance/alternating-comparison.json`.
|
|
2244
|
+
|
|
2245
|
+
The direct M4 Pro serial/shared follow-up uses that same candidate source,
|
|
2246
|
+
MTP2/KV4 and two seeds with reversed arm order. All 22 single-request pairs
|
|
2247
|
+
preserve output, usage except the lane label, and cache coverage; all request
|
|
2248
|
+
hashes and generated budgets match. Source/preflights pass with no failures.
|
|
2249
|
+
|
|
2250
|
+
| Arm order | Five decode requests, serial / shared ms | Cached first output, serial / shared ms | Observed aggregate tok/s, serial / shared |
|
|
2251
|
+
|---|---:|---:|---:|
|
|
2252
|
+
| Serial first | 56,220.90 / 55,568.01 | 93.761 / 96.858 | 15.734 / 16.003 |
|
|
2253
|
+
| Shared first | 54,119.93 / 54,093.31 | 93.782 / 95.060 | 16.111 / 15.925 |
|
|
2254
|
+
|
|
2255
|
+
The allocator change does not remove the B1 cached-latency regression. Seven
|
|
2256
|
+
of eight concurrent output pairs differ, and observed aggregate throughput
|
|
2257
|
+
moves in opposite directions across the two orders. These results do not
|
|
2258
|
+
qualify shared dominance or serial deletion. The cleanup candidate remains
|
|
2259
|
+
isolated; its narrow improvement against the prior shared implementation is
|
|
2260
|
+
recorded separately above. Raw and derived records:
|
|
2261
|
+
`composition-baseline/single-token-maintenance/decode-maintenance-serial-shared-{0,1}.md.json`
|
|
2262
|
+
and `composition-baseline/single-token-maintenance/serial-shared-comparison.json`.
|
|
2263
|
+
|
|
2264
|
+
Four alternating M4 Pro 24 GB prompt-lookup runs compare wider packed
|
|
2265
|
+
down-projection eligibility against the unchanged operation. Settings are
|
|
2266
|
+
KV4, lookup depth3, 192 output tokens, seed `ngram-serving-block-0`, Bun 1.4.2
|
|
2267
|
+
and MLX 0.32.2. Control source is
|
|
2268
|
+
`88da0dca100cdb012cbd4330638cc43b727dbb853a5b1ef6aded60bc6fe1eb0d`;
|
|
2269
|
+
candidate is `c399a3e7fa4d8e61d720476a53a3abb5055944dccfd32684a99157373a288343`.
|
|
2270
|
+
All 60 requests preserve request hashes, response text, complete usage and
|
|
2271
|
+
finish reasons. Source/preflights pass under the audio-CPU allowance, with no
|
|
2272
|
+
failures. Both-machine projection and full-model B1/B2/B4/B8 state checks pass,
|
|
2273
|
+
including every new projection width and the artifact's three bit widths.
|
|
2274
|
+
|
|
2275
|
+
| Order | Five decode requests, total ms | Cached first output, ms | Aggregate tok/s |
|
|
2276
|
+
|---|---:|---:|---:|
|
|
2277
|
+
| Control 1 | 91,973.51 | 126.671 | 9.456 |
|
|
2278
|
+
| Candidate 1 | 92,261.32 | 129.677 | 9.305 |
|
|
2279
|
+
| Candidate 2 | 91,413.34 | 126.650 | 9.324 |
|
|
2280
|
+
| Control 2 | 91,750.52 | 126.872 | 9.473 |
|
|
2281
|
+
|
|
2282
|
+
Combined single-request time is effectively unchanged, decreasing 0.027%,
|
|
2283
|
+
while aggregate throughput decreases 1.58%. Both candidate aggregate results
|
|
2284
|
+
trail both controls. The wider eligibility is not adopted: exact arithmetic
|
|
2285
|
+
and avoiding dense weight expansion do not establish a serving benefit.
|
|
2286
|
+
Any further kernel tuning needs workload dispatch/cost attribution first.
|
|
2287
|
+
Raw and comparison:
|
|
2288
|
+
`composition-baseline/trellis-batch-width/decode-trellis-width-ngram-{control1,candidate1,candidate2,control2}.md.json`
|
|
2289
|
+
and `composition-baseline/trellis-batch-width/alternating-comparison.json`.
|
|
2290
|
+
|
|
2291
|
+
A bounded M1 Max allocation diagnostic follows the ordinary M4 cached-repeat
|
|
2292
|
+
OOM. At 8,195 prompt tokens, KV4, 12 generated tokens and a 4 GiB RAM cache
|
|
2293
|
+
without SSD, normal pipelining, early first output and disabled pipelining
|
|
2294
|
+
all retain two entries and add the same 375.28 MiB peak allocator demand
|
|
2295
|
+
above the pre-request live allocation on warm repeats. All nine outputs
|
|
2296
|
+
match. This loaded-machine native probe is not a speed benchmark, does not
|
|
2297
|
+
reproduce the 78k failure, and supplies no evidence that pipeline overlap is
|
|
2298
|
+
its allocation cause. Large-context retention and concurrent SSD persistence
|
|
2299
|
+
remain untested by this probe.
|
|
2300
|
+
Raw: `composition-baseline/ordinary-cached-allocation-m1.jsonl`.
|
|
2301
|
+
|
|
2302
|
+
### Current MTP depth two versus four — M4 Pro (2026-09-09)
|
|
2303
|
+
|
|
2304
|
+
Same packed artifact, RTN4 companion, KV4, Bun 1.4.2, MLX 0.32.2 and frozen
|
|
2305
|
+
reference source as the replay experiment above. The source hash is
|
|
2306
|
+
`a01bee0b7e1962c8211f1ffd845d95f7923d6c04bddb18cf06f07483cab9e7e8`.
|
|
2307
|
+
Only the draft depth changes. Each block uses matching request hashes and
|
|
2308
|
+
192 output tokens. Both depth-four blocks precede both depth-two blocks, so
|
|
2309
|
+
this depth comparison is not balanced in execution order. Preflight passes
|
|
2310
|
+
with the recorded audio-CPU allowance; reports retain `canonical:false`.
|
|
2311
|
+
|
|
2312
|
+
| Block | Depth two median decode | Depth four median decode | Five-request complete time, depth two / four | Matching responses |
|
|
2313
|
+
|---|---:|---:|---:|---:|
|
|
2314
|
+
| 0 | 19.33 tok/s | 7.36 tok/s | 56,275.71 / 135,674.99 ms | 6 / 15 |
|
|
2315
|
+
| 1 | 18.31 tok/s | 7.60 tok/s | 57,859.37 / 130,083.45 ms | 6 / 15 |
|
|
2316
|
+
|
|
2317
|
+
Counts, cached coverage and finish reasons match for every request. All five
|
|
2318
|
+
decode and four queued-concurrency responses differ in each block; no phase
|
|
2319
|
+
fails. These are observed results from different continuations, not an
|
|
2320
|
+
identical-output speed ratio or a depth-four acceptance. Depth two remains the
|
|
2321
|
+
current choice. A depth-four verify processes five tokens including the pending
|
|
2322
|
+
token, crossing the existing four-row packed-kernel boundary. R7 already records
|
|
2323
|
+
that boundary's cost and arithmetic difference; the current runs do not isolate
|
|
2324
|
+
its contribution from the changed continuation/acceptance trajectory.
|
|
2325
|
+
|
|
2326
|
+
Raw: `reports/qwen38-closeout/composition-baseline/mtp-depth2-{0,1}.md.json`,
|
|
2327
|
+
`state-replay-reference-{0,1}.md.json` and `mtp-depth-performance-review.json`.
|
|
2328
|
+
All requests here use the one-active-request control; four queued requests do
|
|
2329
|
+
not establish actual batched MTP. Compare fixed-input verification at both
|
|
2330
|
+
window sizes before changing the dispatch policy or promoting depth four.
|
|
2331
|
+
|
|
334
2332
|
### Current standard serve matrix — M1 Max 32 GB (2026-08-22)
|
|
335
2333
|
|
|
336
2334
|
Real-server HTTP matrix on commit `4103ae1`, with the canonical preflight
|
|
@@ -1125,6 +3123,44 @@ contains `result.json`, `measurement-audit.json`, `quality.json`, referenced
|
|
|
1125
3123
|
browser evidence, `memory-summary.json`, the untouched app and saved sources.
|
|
1126
3124
|
The derived HTML report is `reports/qwen38-rd/kanban-final/comparison.html`.
|
|
1127
3125
|
|
|
3126
|
+
Offline analysis of this successful trace reconciles all 62 terminal usage
|
|
3127
|
+
records to 130,494 output tokens, including the 1,404-token compaction. The
|
|
3128
|
+
server reports 3,980,688 cumulative prompt tokens and 3,701,542 cached tokens
|
|
3129
|
+
through the enabled paired target/draft RAM prefix cache; these are repeated
|
|
3130
|
+
request counts, not unique text or a measured time-saving percentage. An
|
|
3131
|
+
exact-substring analysis of 593,994 Unicode characters from 380 original
|
|
3132
|
+
input/output segments finds 2,830 maximal repeats of at least 32 characters
|
|
3133
|
+
(after excluding separator noise). The longest is 10,304 characters, a file
|
|
3134
|
+
write followed by a read. Replayed history and duplicated log events are
|
|
3135
|
+
excluded; nested/overlapping repeat families remain, so counts do not imply
|
|
3136
|
+
removable work. Local derived evidence and methodology:
|
|
3137
|
+
`~/.cache/mlx-bun/analysis/kanban-success/{analysis,duplicates}/report.md`,
|
|
3138
|
+
with the hashed source snapshot, per-request counts and repeat locations.
|
|
3139
|
+
Token-ID analysis of those same independently retokenized segments contains
|
|
3140
|
+
160,352 tokens and 2,756 maximal repeats of at least eight tokens after the
|
|
3141
|
+
same noise filter; the longest is 2,732 tokens, occurring twice. This is
|
|
3142
|
+
reconstructed-text tokenization, not the sampled-token stream. Methodology,
|
|
3143
|
+
source/tokenizer hashes, all matches and histogram are retained alongside
|
|
3144
|
+
that evidence under `kanban-success/token-duplicates/`.
|
|
3145
|
+
Counting only later generated positions matching earlier generated content,
|
|
3146
|
+
with first occurrences retained and overlapping intervals merged, gives
|
|
3147
|
+
48,932 duplicated retokenized positions at the eight-token cutoff, including
|
|
3148
|
+
26,965 tool-argument positions matching prior reasoning. At a 32-token cutoff
|
|
3149
|
+
the total is 26,602. These are approximate 37.50%/20.39% shares of the 130,494
|
|
3150
|
+
reported output tokens: the normalized generated corpus has 127,905 tokens
|
|
3151
|
+
and excludes wire framing/escaping. They are not measured time savings.
|
|
3152
|
+
Method and interval evidence: `generated-duplicate-report.md` and its JSON
|
|
3153
|
+
companions in the same token-analysis directory.
|
|
3154
|
+
|
|
3155
|
+
A narrative reconstruction with an embedded source browser is saved at
|
|
3156
|
+
`~/.cache/mlx-bun/analysis/kanban-success/timeline/kanban-story.html`.
|
|
3157
|
+
Its clock uses cumulative completion tokens and places external actions at
|
|
3158
|
+
completed assistant-response boundaries: the first tool action follows
|
|
3159
|
+
50,533 generated tokens. The account distinguishes code drafted in reasoning, file writes,
|
|
3160
|
+
repairs to the synthetic DOM test harness, and concrete application fixes.
|
|
3161
|
+
The trace identifies candidates for shortening the run; it does not establish
|
|
3162
|
+
which reasoning could be removed while preserving the successful outcome.
|
|
3163
|
+
|
|
1128
3164
|
### Speculative decoding — "should spec be on?" (decision pending Phase 0/1 runs)
|
|
1129
3165
|
|
|
1130
3166
|
Decision rule: spec defaults ON for a (target, drafter) pair iff
|
|
@@ -1160,3 +3196,418 @@ slower per step at long context; no speed claim made). The KL-vs-bpw
|
|
|
1160
3196
|
curve above is the quality evidence. NOTE: any turbo perf/RSS impression
|
|
1161
3197
|
formed before 2026-07-07 is invalid — the pre-fix build leaked
|
|
1162
3198
|
window-scale buffers per decode step (PLAN Phase 13 post-merge fix).
|
|
3199
|
+
|
|
3200
|
+
|
|
3201
|
+
### Shared Gemma assistant drafting, M4 Pro 24 GB, 2026-09-10
|
|
3202
|
+
|
|
3203
|
+
Four `bench-serve.ts all` arms in control/candidate/candidate/control order,
|
|
3204
|
+
Bun 1.4.2, MLX 0.32.2. Gemma4 12B OptiQ4 target with its bf16 assistant,
|
|
3205
|
+
draft depth 2, bf16 target KV, 2 GiB RAM cache plus temporary SSD, 192 decode
|
|
3206
|
+
tokens, four concurrent requests and default capacity eight. Workload seed
|
|
3207
|
+
`assistant-spec-0`; diagnostic mode under Josh's CPU/swap policy. Source snapshots
|
|
3208
|
+
`c8213540beb87f438fbafad7115b49f494e92526c28acca930f134883d5cfdcf`
|
|
3209
|
+
→ `db38e64dbc3421ba5750485d8d6328afad63b64883bae8b945ff76e0ae6f1f21`.
|
|
3210
|
+
The candidate includes the shared assistant graph/provider, hidden companions,
|
|
3211
|
+
donor validity ports and the oracle-aligned strided weight views.
|
|
3212
|
+
|
|
3213
|
+
| Metric, mean of two arms | Previous implementation | Shared assistant | Change |
|
|
3214
|
+
|---|---:|---:|---:|
|
|
3215
|
+
| Median single-request decode, tok/s | 25.637 | 26.583 | +3.69% |
|
|
3216
|
+
| Four-request aggregate, tok/s | 24.815 | 34.129 | +37.53% |
|
|
3217
|
+
| Four-request wall time, ms | 20,632.8 | 15,002.1 | −27.29% |
|
|
3218
|
+
| Cached prefill, ms | 2,573.4 | 116.7 | −95.47% |
|
|
3219
|
+
| Cold prefill, ms | 2,581.1 | 2,527.6 | −2.08% |
|
|
3220
|
+
| Server readiness, ms | 723.5 | 1,016.1 | +40.45% |
|
|
3221
|
+
| Cold start, ms | 2,244.1 | 2,094.7 | −6.66% |
|
|
3222
|
+
| Peak RSS, MiB | 9,744.6 | 10,042.8 | +3.06% |
|
|
3223
|
+
|
|
3224
|
+
All 60 requests complete without failures with matching request bodies and token
|
|
3225
|
+
budgets. Single-request text and raw completion/chat probes match. Three of four
|
|
3226
|
+
concurrent responses differ across implementations; each implementation repeats
|
|
3227
|
+
exactly, including usage. Shared cached requests reuse 668 tokens, versus zero.
|
|
3228
|
+
Mean cold-start improvement is within substantial variation: candidate arms are
|
|
3229
|
+
1.712 and 2.478 seconds. Readiness regresses by 293 ms; strict startup dominance
|
|
3230
|
+
remains open. These numbers compare implementations with the same assistant,
|
|
3231
|
+
not assistant speculation versus ordinary decoding. Defaults are unchanged.
|
|
3232
|
+
|
|
3233
|
+
Both-machine e4b/12B graph and serving/cache tests pass; e4b matches unmodified
|
|
3234
|
+
optiq `spec_generate` end to end. The pinned 12B loader lacks tensor-presence head
|
|
3235
|
+
detection, so its numerical test explicitly binds the artifact's tied embedding
|
|
3236
|
+
head while retaining upstream layers. Both-machine Qwen MTP/TQ regressions, full
|
|
3237
|
+
suites and all typechecks pass. Evidence:
|
|
3238
|
+
`reports/qwen38-closeout/composition-baseline/assistant-batch/`.
|
|
3239
|
+
|
|
3240
|
+
|
|
3241
|
+
### Shared DeepSpec drafting, M4 Pro 24 GB, 2026-09-10
|
|
3242
|
+
|
|
3243
|
+
Four `bench-serve.ts all` arms in control/candidate/candidate/control order,
|
|
3244
|
+
Bun 1.4.2, MLX 0.32.2. Gemma4 12B OptiQ4 target with the DeepSpec affine-q4-g64
|
|
3245
|
+
drafter, trained depth seven, bf16 target KV, 2 GiB RAM cache plus temporary SSD,
|
|
3246
|
+
192 decode tokens, four concurrent requests and default capacity eight. Seed
|
|
3247
|
+
`deepspec-spec-0`; diagnostic mode under Josh's CPU/swap policy. Frozen sources
|
|
3248
|
+
`db38e64dbc3421ba5750485d8d6328afad63b64883bae8b945ff76e0ae6f1f21`
|
|
3249
|
+
→ `39b289a30244e8f37bc8457c7e8f4e36deae428340157cd90c3a4c2287610dda`.
|
|
3250
|
+
The candidate adds shared context projections, batched proposals and persisted
|
|
3251
|
+
method companions. Both arms use the same target, drafter and settings.
|
|
3252
|
+
|
|
3253
|
+
| Metric, mean of two arms | Previous implementation | Shared DeepSpec | Change |
|
|
3254
|
+
|---|---:|---:|---:|
|
|
3255
|
+
| Median single-request decode, tok/s | 25.288 | 25.950 | +2.62% |
|
|
3256
|
+
| Four-request aggregate, tok/s | 25.191 | 53.187 | +111.14% |
|
|
3257
|
+
| Four-request wall time, ms | 20,326.0 | 9,626.5 | −52.64% |
|
|
3258
|
+
| Cached prefill, ms | 2,724.6 | 345.1 | −87.33% |
|
|
3259
|
+
| Cold prefill, ms | 2,715.1 | 2,737.0 | +0.81% |
|
|
3260
|
+
| Server readiness, ms | 612.5 | 1,319.1 | +115.37% |
|
|
3261
|
+
| Cold start, ms | 2,509.8 | 2,918.0 | +16.26% |
|
|
3262
|
+
| Peak RSS, MiB | 10,772.8 | 11,057.6 | +2.64% |
|
|
3263
|
+
|
|
3264
|
+
All 60 requests complete without failures and use matching request bodies and
|
|
3265
|
+
budgets. Single-request text and raw completion/chat probes match. One of four
|
|
3266
|
+
concurrent responses differs; both implementations repeat exactly, including
|
|
3267
|
+
usage. Cached requests reuse 671 tokens versus zero. Decode samples within each
|
|
3268
|
+
arm span roughly 15–16%, although the repeated medians agree. The small B1 gain
|
|
3269
|
+
should be read with that variation. Readiness regresses by 707 ms and cold start
|
|
3270
|
+
by 408 ms on average; strict startup dominance remains open. Defaults are unchanged.
|
|
3271
|
+
|
|
3272
|
+
Both-machine bf16/4-bit graph controls, depth-seven serving/generated RAM/SSD,
|
|
3273
|
+
regression suites and all typechecks pass. The graph comparisons preserve the
|
|
3274
|
+
frozen implementation; they are not a new external DeepSpec oracle. Real-window
|
|
3275
|
+
checks confirm active shared speculation across wrap. Evidence:
|
|
3276
|
+
`reports/qwen38-closeout/composition-baseline/deepspec-batch/`.
|
|
3277
|
+
|
|
3278
|
+
|
|
3279
|
+
### Shared projected-context extraction, M4 Pro 24 GB, 2026-09-10
|
|
3280
|
+
|
|
3281
|
+
Four `bench-serve.ts all` arms, control/candidate/candidate/control, use the same
|
|
3282
|
+
Gemma4 12B OptiQ4 target, trained DeepSpec q4-g64 drafter, depth seven, bf16 target
|
|
3283
|
+
KV, 2 GiB RAM plus temporary SSD, 192 decode tokens, four concurrent requests,
|
|
3284
|
+
default capacity eight and seed `deepspec-spec-0`. Bun 1.4.2, MLX 0.32.2,
|
|
3285
|
+
diagnostic mode under Josh's CPU/swap policy. Frozen sources
|
|
3286
|
+
`39b289a30244e8f37bc8457c7e8f4e36deae428340157cd90c3a4c2287610dda`
|
|
3287
|
+
→ `9f8484fa9dca140b31ad685a2701563ed5a1e0a2638d27f48e31d1df4160f4ab`.
|
|
3288
|
+
The candidate extracts context ownership for reuse by DSpark/DFlash and DeepSpec.
|
|
3289
|
+
This measures the extraction with a trained DeepSpec drafter; no trained DSpark
|
|
3290
|
+
checkpoint was available for its own performance comparison.
|
|
3291
|
+
|
|
3292
|
+
| Metric, mean of two arms | DeepSpec-specific owner | Shared context owner | Change |
|
|
3293
|
+
|---|---:|---:|---:|
|
|
3294
|
+
| Median single-request decode, tok/s | 25.800 | 25.695 | −0.41% |
|
|
3295
|
+
| Four-request aggregate, tok/s | 53.597 | 52.229 | −2.55% |
|
|
3296
|
+
| Four-request wall time, ms | 9,552.8 | 9,805.0 | +2.64% |
|
|
3297
|
+
| Cached prefill, ms | 342.2 | 348.3 | +1.79% |
|
|
3298
|
+
| Cold prefill, ms | 2,722.4 | 2,778.2 | +2.05% |
|
|
3299
|
+
| Server readiness, ms | 1,318.4 | 1,421.7 | +7.84% |
|
|
3300
|
+
| Cold start, ms | 2,943.2 | 3,321.3 | +12.85% |
|
|
3301
|
+
| Peak RSS, MiB | 11,070.5 | 11,068.2 | −0.02% |
|
|
3302
|
+
|
|
3303
|
+
All 60 requests complete without failures; every request body, response and usage
|
|
3304
|
+
record matches across all four arms. Cached requests reuse 671 tokens in both.
|
|
3305
|
+
The first control cold start is 2.615 seconds; the other three arms range from
|
|
3306
|
+
3.272 to 3.337 seconds. Candidate aggregate arms are 52.99 and 51.47 tok/s versus
|
|
3307
|
+
53.75 and 53.44 controls. The measured cost is retained; this is not a speed win
|
|
3308
|
+
or strict dominance. Defaults are unchanged. Both-machine pinned Markov/RNN and
|
|
3309
|
+
independent confidence/sampling tests, seeded real-Gemma serving/generated RAM/SSD,
|
|
3310
|
+
trained DeepSpec regressions, full suites and typechecks pass. Evidence:
|
|
3311
|
+
`reports/qwen38-closeout/composition-baseline/dflash-batch/`.
|
|
3312
|
+
|
|
3313
|
+
|
|
3314
|
+
### Reused artifact identity, M4 Pro 24 GB, 2026-09-10
|
|
3315
|
+
|
|
3316
|
+
Four `bench-serve.ts all` arms, control/candidate/candidate/control, use Gemma4 12B
|
|
3317
|
+
OptiQ4, trained DeepSpec q4-g64, depth seven, bf16 target KV, 2 GiB RAM plus temporary
|
|
3318
|
+
SSD, 192 decode tokens, four concurrent requests, default capacity eight and seed
|
|
3319
|
+
`deepspec-spec-0`. Bun 1.4.2, MLX 0.32.2, diagnostic mode under Josh's CPU/swap
|
|
3320
|
+
policy. Frozen sources `9f8484fa9dca140b31ad685a2701563ed5a1e0a2638d27f48e31d1df4160f4ab`
|
|
3321
|
+
→ `e17613b8496e5820bb8f4a193e735a4d9129b5333c851886bb22cbd0c9c41bed`.
|
|
3322
|
+
The candidate resolves the same full configuration/name/byte SHA-256 through a
|
|
3323
|
+
shared artifact-identity store. Its unchanged-file memo was populated during
|
|
3324
|
+
native validation. These fresh server starts hit the identity memo; first-ever
|
|
3325
|
+
identity calculation still reads all shard bytes. Memo writes are queued.
|
|
3326
|
+
|
|
3327
|
+
| Metric, mean of two arms | Rehash each load | Reuse unchanged identity | Change |
|
|
3328
|
+
|---|---:|---:|---:|
|
|
3329
|
+
| Median single-request decode, tok/s | 25.881 | 25.975 | +0.37% |
|
|
3330
|
+
| Four-request aggregate, tok/s | 52.449 | 52.831 | +0.73% |
|
|
3331
|
+
| Four-request wall time, ms | 9,761.8 | 9,691.3 | −0.72% |
|
|
3332
|
+
| Cached prefill, ms | 350.0 | 346.1 | −1.12% |
|
|
3333
|
+
| Cold prefill, ms | 2,783.3 | 2,763.5 | −0.71% |
|
|
3334
|
+
| Server readiness, ms | 1,422.2 | 713.1 | −49.86% |
|
|
3335
|
+
| Cold start, ms | 3,332.1 | 2,709.7 | −18.68% |
|
|
3336
|
+
| Peak RSS, MiB | 11,072.1 | 10,784.0 | −2.60% |
|
|
3337
|
+
|
|
3338
|
+
All 60 requests complete without failures; every request body, response and usage
|
|
3339
|
+
record matches across all four arms. Cached requests reuse 671 tokens in both.
|
|
3340
|
+
Candidate readiness is 610/816 ms versus 1,422/1,422 ms; cold start is 2,590/2,829 ms
|
|
3341
|
+
versus 3,345/3,319 ms. Peak RSS decreases by 288.1 MiB on average. Throughput changes
|
|
3342
|
+
are small; the material gain is repeat loading. Sampling, draft-depth and KV
|
|
3343
|
+
defaults are unchanged. Both-machine Qwen MTP/TurboQuant and DeepSpec serving and
|
|
3344
|
+
generated RAM/SSD, complete suites and typechecks pass. Identity tests cover the
|
|
3345
|
+
previous digest, zero weight reads on memo hits, file/config/symlink mutation and
|
|
3346
|
+
failed persistence. Existing KV namespaces remain compatible. Evidence:
|
|
3347
|
+
`reports/qwen38-closeout/composition-baseline/artifact-identity/`.
|
|
3348
|
+
|
|
3349
|
+
|
|
3350
|
+
### Affine rotating speculation, M4 Pro 24 GB, 2026-09-11
|
|
3351
|
+
|
|
3352
|
+
Six `bench-serve.ts all` arms run control/candidate/KV4/KV4/candidate/control.
|
|
3353
|
+
All use Gemma4 12B OptiQ4 weights, trained DeepSpec q4-g64 at depth seven,
|
|
3354
|
+
2 GiB RAM plus temporary SSD, 192 decode tokens, four concurrent requests,
|
|
3355
|
+
default capacity eight and seed `deepspec-spec-0`. Bun 1.4.2 and MLX 0.32.2;
|
|
3356
|
+
diagnostic mode follows Josh's background-CPU/swap policy. Control and candidate
|
|
3357
|
+
use bf16 target KV; KV4 changes only that setting on the candidate source.
|
|
3358
|
+
Frozen source hashes are
|
|
3359
|
+
`e17613b8496e5820bb8f4a193e735a4d9129b5333c851886bb22cbd0c9c41bed`
|
|
3360
|
+
and `9f8819cce7c759eab2e86f5ba35e20d99e436491fd46c39966c59048ab44e60d`.
|
|
3361
|
+
Every arm retains its source hash through completion.
|
|
3362
|
+
|
|
3363
|
+
| Metric, mean of two arms | Control bf16 | Candidate bf16 | Candidate KV4 |
|
|
3364
|
+
|---|---:|---:|---:|
|
|
3365
|
+
| Median single-request decode, tok/s | 25.778 | 25.895 | 25.880 |
|
|
3366
|
+
| Four-request aggregate, tok/s | 52.947 | 52.995 | 55.398 |
|
|
3367
|
+
| Four-request wall time, ms | 9,671.7 | 9,661.4 | 9,242.3 |
|
|
3368
|
+
| Cached prefill, ms | 345.7 | 346.5 | 352.9 |
|
|
3369
|
+
| Cold prefill, ms | 2,749.7 | 2,748.8 | 2,814.0 |
|
|
3370
|
+
| Server readiness, ms | 611.5 | 611.7 | 612.1 |
|
|
3371
|
+
| Cold start, ms | 2,600.5 | 2,427.5 | 2,424.3 |
|
|
3372
|
+
| Peak RSS, MiB | 10,775.3 | 10,767.2 | 10,802.8 |
|
|
3373
|
+
|
|
3374
|
+
The source-only comparison is effectively flat: decode +0.45%, aggregate +0.09%,
|
|
3375
|
+
cached prefill +0.22%, cold prefill −0.03%. All 60 bf16 requests have identical
|
|
3376
|
+
request bodies, responses and usage records. Each setting repeats exactly.
|
|
3377
|
+
All 90 requests complete without benchmark failures and reuse 671 cached tokens.
|
|
3378
|
+
|
|
3379
|
+
KV4 reaches +4.63% aggregate throughput versus the bf16 control, with +2.07%
|
|
3380
|
+
cached and +2.34% cold prefill time. Ten of fifteen responses per KV4 arm differ
|
|
3381
|
+
from bf16, and accepted draft tokens total 1,042 versus 1,032. This is a measured
|
|
3382
|
+
precision/configuration tradeoff, not an isolated engine speed gain. Short-run
|
|
3383
|
+
RSS does not establish a memory saving; startup varies within the candidate
|
|
3384
|
+
arms. Defaults remain unchanged. Context/pressure and strict serial-dominance
|
|
3385
|
+
acceptance are not covered by this short comparison. Native tests separately
|
|
3386
|
+
cover generated RAM/SSD restoration, real-window rollback and KV4/KV8 provider
|
|
3387
|
+
composition on both Macs. Evidence:
|
|
3388
|
+
`reports/qwen38-closeout/composition-baseline/rotating-spec-quant/`.
|
|
3389
|
+
|
|
3390
|
+
|
|
3391
|
+
### TurboQuant provider composition and centroid correction, M4 Pro 24 GB, 2026-09-11
|
|
3392
|
+
|
|
3393
|
+
Two six-arm `bench-serve.ts all` comparisons use
|
|
3394
|
+
control/candidate/TQ/TQ/candidate/control. Both use Bun 1.4.2, MLX 0.32.2,
|
|
3395
|
+
192 decode tokens, four concurrent requests, capacity eight, 2 GiB RAM plus
|
|
3396
|
+
temporary SSD and fused TQ decoding enabled. Control/candidate target KV is
|
|
3397
|
+
bf16; the TQ arms select K8/V3 on the candidate. The CLI keeps start zero;
|
|
3398
|
+
sliding layers remain bf16. Diagnostic mode follows Josh's CPU/swap policy.
|
|
3399
|
+
Sources stay fixed through every arm:
|
|
3400
|
+
`9f8819cce7c759eab2e86f5ba35e20d99e436491fd46c39966c59048ab44e60d`
|
|
3401
|
+
→ `f4c9fe17c9f0a691907ded7777e7814cc5eaed7811ac9941b4d1528ad75070bd`.
|
|
3402
|
+
|
|
3403
|
+
The candidate adds owned TQ donor attention and capability-based grouped draft
|
|
3404
|
+
selection, captures immutable numerical options and distinct per-layer cache
|
|
3405
|
+
identities, and corrects the small assistant's centroid head to the pinned
|
|
3406
|
+
bf16 multiply/sum arithmetic and lowest-token-ID tie rule. The independent M1
|
|
3407
|
+
oracle exposed the previous matmul shortcut; its decoded KV and hidden state
|
|
3408
|
+
were exact but its selected token differed. This correction applies at every B.
|
|
3409
|
+
|
|
3410
|
+
#### Gemma4 12B + trained DeepSpec
|
|
3411
|
+
|
|
3412
|
+
OptiQ4 target weights, q4-g64 DeepSpec block7, draft depth seven and seed `deepspec-spec-0`.
|
|
3413
|
+
|
|
3414
|
+
| Metric, mean of two arms | Control bf16 | Candidate bf16 | Candidate K8/V3 |
|
|
3415
|
+
|---|---:|---:|---:|
|
|
3416
|
+
| Median single-request decode, tok/s | 25.912 | 25.428 | 26.749 |
|
|
3417
|
+
| Four-request aggregate, tok/s | 53.635 | 51.962 | 54.258 |
|
|
3418
|
+
| Four-request wall time, ms | 9,546.956 | 9,854.496 | 9,436.373 |
|
|
3419
|
+
| Cached prefill, ms | 341.823 | 343.041 | 352.446 |
|
|
3420
|
+
| Cold prefill, ms | 2,688.505 | 2,758.072 | 2,772.306 |
|
|
3421
|
+
| Server readiness, ms | 616.147 | 616.509 | 610.971 |
|
|
3422
|
+
| Cold start, ms | 2,604.734 | 2,604.987 | 2,612.562 |
|
|
3423
|
+
| Peak RSS, MiB | 10,784.125 | 10,762.719 | 10,780.617 |
|
|
3424
|
+
|
|
3425
|
+
Source-only bf16 decode decreases 1.87% and aggregate throughput decreases
|
|
3426
|
+
3.12%; cached prefill is +0.36%, cold prefill +2.59%. All 60 bf16 requests have
|
|
3427
|
+
identical bodies, responses and usage. The cost remains recorded and is under
|
|
3428
|
+
separate attribution testing. It is not a refactor speed win.
|
|
3429
|
+
|
|
3430
|
+
K8/V3 increases decode 3.23% and aggregate throughput 1.16% versus the old bf16
|
|
3431
|
+
control, with cached and cold prefill each about 3.1% slower. Nine of fifteen
|
|
3432
|
+
responses per TQ arm differ from bf16. Accepted draft tokens total 1,044 versus
|
|
3433
|
+
1,032. Each TQ repeat matches its own responses and usage exactly.
|
|
3434
|
+
|
|
3435
|
+
#### Gemma4 e4b + assistant
|
|
3436
|
+
|
|
3437
|
+
OptiQ4 target weights, bf16 assistant, draft depth three and seed `assistant-spec-0`.
|
|
3438
|
+
|
|
3439
|
+
| Metric, mean of two arms | Control bf16 | Candidate bf16 | Candidate K8/V3 |
|
|
3440
|
+
|---|---:|---:|---:|
|
|
3441
|
+
| Median single-request decode, tok/s | 55.374 | 55.106 | 57.532 |
|
|
3442
|
+
| Four-request aggregate, tok/s | 94.152 | 93.340 | 91.267 |
|
|
3443
|
+
| Four-request wall time, ms | 5,438.005 | 5,485.344 | 5,609.896 |
|
|
3444
|
+
| Cached prefill, ms | 88.692 | 89.947 | 92.351 |
|
|
3445
|
+
| Cold prefill, ms | 962.402 | 960.880 | 967.007 |
|
|
3446
|
+
| Server readiness, ms | 621.475 | 610.243 | 611.252 |
|
|
3447
|
+
| Cold start, ms | 1,309.033 | 894.498 | 906.810 |
|
|
3448
|
+
| Peak RSS, MiB | 6,880.625 | 6,889.672 | 6,929.180 |
|
|
3449
|
+
|
|
3450
|
+
The centroid correction and interface changes decrease bf16 decode 0.49%
|
|
3451
|
+
and aggregate throughput 0.86%. All bf16 response text is unchanged, while
|
|
3452
|
+
draft-acceptance usage changes: 530 accepted tokens per candidate arm versus
|
|
3453
|
+
532 in each control. Each arm repeats its own response and usage exactly.
|
|
3454
|
+
The first control cold start is 1,726 ms; all later arms are 888–914 ms, so
|
|
3455
|
+
the mean startup difference is not attributed to this change.
|
|
3456
|
+
|
|
3457
|
+
K8/V3 increases decode 3.90% versus the old bf16 control but decreases aggregate
|
|
3458
|
+
throughput 3.06%; cached prefill is +4.13%, cold prefill +0.48%. Nine of fifteen
|
|
3459
|
+
responses per TQ arm differ from bf16, and draft acceptance totals 557.
|
|
3460
|
+
The TQ arms repeat exactly. This setting benefits single-request decode on
|
|
3461
|
+
this workload and loses concurrent throughput.
|
|
3462
|
+
|
|
3463
|
+
All 180 requests complete without benchmark failures. Cached requests retain
|
|
3464
|
+
671 tokens for 12B and 668 for e4b. These are short configuration tradeoffs, not
|
|
3465
|
+
long-context memory or pressure acceptance. Defaults remain unchanged and strict
|
|
3466
|
+
serial dominance stays open. Both-machine native coverage includes assistant,
|
|
3467
|
+
DeepSpec, standalone and lookup serving/generated RAM/SSD, delayed conversion,
|
|
3468
|
+
independent assistant codec/graph controls, seeded DSpark heads and Qwen MTP
|
|
3469
|
+
regressions; the final suites and typechecks pass. Evidence and source manifests:
|
|
3470
|
+
`reports/qwen38-closeout/composition-baseline/turboquant-donor/`.
|
|
3471
|
+
|
|
3472
|
+
### TurboQuant option-capture attribution (M4 Pro, 2026-09-11)
|
|
3473
|
+
|
|
3474
|
+
Same Gemma4-12B/DeepSpec7 workload and settings as the TurboQuant composition comparison above, all using bf16 KV. The sequence isolates request-option capture from numerical kernels. Frozen integrated source `f4c9fe17…` is unchanged; the key-restored variant is `cb063841…`, and the shallow-clone/conditional-assignment variant is `09e02ca6…`.
|
|
3475
|
+
|
|
3476
|
+
| Arm, in execution order | Decode median tok/s | Aggregate tok/s | Cached TTFT ms | Cold TTFT ms |
|
|
3477
|
+
|---|---:|---:|---:|---:|
|
|
3478
|
+
| deep-key-ablation-1 | 25.898 | 53.222 | 343.92 | 2728.18 |
|
|
3479
|
+
| deep-candidate-attribution-1 | 25.899 | 52.984 | 346.27 | 2748.01 |
|
|
3480
|
+
| deep-options-capture-1 | 25.910 | 53.942 | 339.04 | 2640.71 |
|
|
3481
|
+
| deep-candidate-attribution-2 | 25.897 | 53.063 | 346.38 | 2752.70 |
|
|
3482
|
+
| deep-options-capture-2 | 25.895 | 52.690 | 350.81 | 2769.67 |
|
|
3483
|
+
|
|
3484
|
+
The unchanged integrated build recovered the original decode rate on both repeats. Neither key restoration nor the option-copy variant establishes a repeatable speed benefit; retain the integrated implementation. The earlier measured source-only costs remain recorded, but attributing them to a code regression is not supported by these repeats. All five arms retain five distinct decode samples (reported within-arm spread about 1.15–1.16); these medians are comparisons of that fixed workload, not five identical requests. Raw requests, source identities and comparison: `reports/qwen38-closeout/composition-baseline/turboquant-donor/{m4,performance-attribution.json}`.
|
|
3485
|
+
|
|
3486
|
+
### Delayed/per-layer affine rotating speculation (M4 Pro, 2026-09-11)
|
|
3487
|
+
|
|
3488
|
+
Gemma4-12B OptiQ-4bit with the q4 DeepSpec block-7 drafter, depth seven, Bun 1.4.2/MLX 0.32.2, 192 decode tokens, four concurrent requests, scheduler capacity eight, 2 GiB RAM prompt cache plus temporary SSD. Same `deepspec-spec-0` workload as the previous composition comparison. Order: control bf16, candidate bf16, candidate per-layer, candidate per-layer, candidate bf16, control bf16. The control source is `f4c9fe17…`; candidate `072bf3ca…`. All six source snapshots remain fixed through completion.
|
|
3489
|
+
|
|
3490
|
+
| Setting (mean of two arms) | Decode tok/s | Aggregate tok/s | Aggregate wall ms | Cached TTFT ms | Cold TTFT ms | Ready ms | Startup ms | Peak RSS MiB |
|
|
3491
|
+
|---|---:|---:|---:|---:|---:|---:|---:|---:|
|
|
3492
|
+
| control | 25.898 | 53.455 | 9579.865 | 344.315 | 2696.925 | 616.786 | 2603.127 | 10795.445 |
|
|
3493
|
+
| candidate | 25.713 | 53.643 | 9545.352 | 339.185 | 2680.571 | 614.743 | 2544.107 | 10775.914 |
|
|
3494
|
+
| per-layer | 27.430 | 52.456 | 9760.580 | 353.531 | 2655.698 | 616.945 | 2544.832 | 10816.516 |
|
|
3495
|
+
|
|
3496
|
+
Source-only bf16 comparison: decode −0.716%, aggregate +0.353%, cached TTFT −1.490%, cold TTFT −0.606%. Every bf16 request, response and usage record matches. The first candidate decode median is lower than its second repeat; the small source-only cost remains recorded and does not satisfy strict B1 dominance.
|
|
3497
|
+
|
|
3498
|
+
Model-defined mixed per-layer affine KV versus control bf16: decode +5.916%, aggregate −1.868%, cached TTFT +2.677%, cold TTFT −1.529%. Ten of fifteen responses differ from bf16; each configuration repeats exactly, including usage. All ninety requests complete with no phase failures. Precision changes affect the numerical trajectory and draft acceptance, so this setting comparison is not an engine-only same-output speedup. Defaults remain unchanged.
|
|
3499
|
+
|
|
3500
|
+
Both-machine native serving/generated RAM/SSD, delayed transition and real-window hidden/logit controls pass for the qualified providers. Seeded DSpark fixtures establish Markov/RNN execution and state contracts, not trained quality or acceptance. Raw arms and exact pair comparisons: `reports/qwen38-closeout/composition-baseline/delayed-rotating-spec/{m4,benchmark-comparison.json}`.
|
|
3501
|
+
|
|
3502
|
+
|
|
3503
|
+
### Paged storage in the shared executor (M4 Pro, 2026-09-11)
|
|
3504
|
+
|
|
3505
|
+
Gemma4-12B OptiQ-4bit, bf16 KV, Bun 1.4.2/MLX 0.32.2, 192 decode tokens, four concurrent requests, 2 GiB RAM cache plus temporary SSD, workload `paged-compose-0`. Paged storage uses 256-token blocks and bypasses both cache tiers. The ordinary source comparison keeps continuous scheduling on both sides. The paged comparison uses the old serial executor versus the candidate shared executor (capacity eight). Frozen source: control `db451918…`, candidate `a9fe941c…`; both include identical benchmark argument plumbing. Each configuration runs twice, with reversed control/candidate order. All source snapshots remain fixed.
|
|
3506
|
+
|
|
3507
|
+
| Configuration (mean of two arms) | Decode tok/s | Aggregate tok/s | Aggregate wall ms | Repeated-prompt TTFT ms | Cold TTFT ms | Ready ms | Startup ms | Peak RSS MiB |
|
|
3508
|
+
|---|---:|---:|---:|---:|---:|---:|---:|---:|
|
|
3509
|
+
| Ordinary control | 26.455 | 72.894 | 7023.933 | 153.036 | 2436.522 | 616.814 | 1452.364 | 8936.141 |
|
|
3510
|
+
| Ordinary candidate | 26.480 | 72.913 | 7022.101 | 154.218 | 2437.542 | 613.202 | 1588.357 | 8946.594 |
|
|
3511
|
+
| Paged serial control | 26.310 | 24.832 | 20618.569 | 2462.690 | 2443.653 | 613.156 | 1425.283 | 8915.117 |
|
|
3512
|
+
| Paged shared candidate | 26.289 | 70.240 | 7289.413 | 2490.439 | 2479.725 | 611.401 | 1218.411 | 8940.664 |
|
|
3513
|
+
|
|
3514
|
+
Ordinary source cost is effectively flat: decode +0.094%, aggregate +0.026%, cold TTFT +0.042% and cached TTFT +0.772%. Every paired response and usage record is identical. Startup varies more (+9.36% in the two-arm mean); this short comparison does not establish startup dominance.
|
|
3515
|
+
|
|
3516
|
+
Shared paged execution increases four-request throughput **182.86% (2.83×)** and reduces task wall time **64.65%**. Single-request decode changes −0.081%; cold TTFT increases 1.48% and repeated-prompt TTFT 1.13%. The first concurrent request reaches output in 365.84 versus 365.86 ms. Peak RSS increases 25.55 MiB. Two concurrent responses differ from serial in each pair; all single-request responses and token counts match. Every configuration repeats its own text and usage exactly. The repeated paged prompt restores zero tokens, as expected; ordinary restores 669. This is concurrent execution scaling, not a single-request decode-kernel speedup.
|
|
3517
|
+
|
|
3518
|
+
Eight successful arms complete 120 requests without phase failures. Four earlier paged setup attempts failed before readiness because the harness enables SSD while `--prompt-cache 0` disables its required RAM tier; those reports remain in the evidence, and both paged sides were rerun with the same 2 GiB setting. The machine retained about 1.65 GiB swap with 91% free memory and no competing GPU job; diagnostic mode follows Josh's campaign policy.
|
|
3519
|
+
|
|
3520
|
+
The long native comparison initially allowed ordinary cache snapshots to change prefill cohort/query boundaries while paging bypassed them. Holding arrivals alone did not equalize that graph. The corrected storage comparison holds arrivals and disables snapshot splitting on both sides; it checks full logits and tokens beyond the default block boundary. Separate HTTP coverage checks sampling, logprobs and grammar. Raw arms, source manifest, setup failures and exact request comparisons: `reports/qwen38-closeout/composition-baseline/paged-rows/`. Direct paged attention, block sharing and composed quantized/speculative paging remain open; defaults are unchanged.
|
|
3521
|
+
|
|
3522
|
+
|
|
3523
|
+
### Adapter-qualified prompt lookup (M4 Pro, 2026-09-11)
|
|
3524
|
+
|
|
3525
|
+
Gemma4 e4b OptiQ-4bit with the existing `upper` LoRA adapter (weights SHA-256 `94f83569ba85df9e05557238809101cd19f9eabd0149c7931904e2a58774a05b`), bf16 KV, Bun 1.4.2/MLX 0.32.2, scheduler capacity eight, 192 decode tokens, four concurrent requests, 2 GiB RAM cache plus temporary SSD. Same `adapter-lookup-0` request bodies in every arm. Frozen control `a9fe941c…` and candidate `cce6e1e6…`; two repetitions per configuration in reversed control/candidate order.
|
|
3526
|
+
|
|
3527
|
+
The ordinary arms omit draft flags and isolate source cost. The lookup arms request ngram depth three: the old control disables speculation for adapters, while the candidate honors it through the grouped provider capability. This second comparison therefore measures newly enabled behavior.
|
|
3528
|
+
|
|
3529
|
+
| Configuration (mean of two arms) | Decode tok/s | Aggregate tok/s | Aggregate wall ms | Cached TTFT ms | Cold TTFT ms | Ready ms | Startup ms | Peak RSS MiB |
|
|
3530
|
+
|---|---:|---:|---:|---:|---:|---:|---:|---:|
|
|
3531
|
+
| ordinary-control | 53.888 | 159.078 | 3218.551 | 38.040 | 526.635 | 610.894 | 893.690 | 6751.648 |
|
|
3532
|
+
| ordinary-candidate | 53.800 | 158.943 | 3221.290 | 38.246 | 523.882 | 610.938 | 893.021 | 6763.688 |
|
|
3533
|
+
| lookup-control | 53.746 | 159.064 | 3218.837 | 38.244 | 524.087 | 611.516 | 951.899 | 6731.523 |
|
|
3534
|
+
| lookup-candidate | 53.136 | 78.537 | 6519.231 | 30.925 | 518.250 | 611.589 | 945.210 | 6766.641 |
|
|
3535
|
+
|
|
3536
|
+
Ordinary source cost is effectively flat: decode −0.163%, aggregate −0.085%, cold TTFT −0.523% and cached TTFT +0.543%. Every ordinary response and usage record matches across source versions.
|
|
3537
|
+
|
|
3538
|
+
Enabling lookup decreases single-request decode 1.14% and four-request throughput **50.63%**, increasing aggregate wall time **102.53%**. It lowers cached TTFT 19.14%. Each concurrent block accepts only 26 of 444 proposed tokens (5.86%); repeated rejection makes this configuration a poor throughput choice. Concurrent cached prefixes also change from 11 tokens under ordinary execution to zero under the paired lookup namespace. That small prefill difference does not establish the cause of the decode cost.
|
|
3539
|
+
|
|
3540
|
+
Eight of fifteen responses change with the enabled method, including five single-request decode probes and three concurrent responses; token counts and finish reasons match. Each configuration repeats its own responses and usage exactly. All 120 requests complete without phase failures. This is not a same-output speed gain and does not justify a default change. A stricter ngram-match screen follows separately.
|
|
3541
|
+
|
|
3542
|
+
Native composition checks cover bf16/KV4 and TurboQuant, compatible adapter cohorts, seeded logprobs, namespace replacement, callback failure and generated RAM/SSD restart identity on both Macs. The HTTP fixture explicitly checks token alignment with the generated SSD header: appending an extra newline changes the M4 KV4 boundary, so the original fixture correctly reused an earlier prompt checkpoint. Preserving the generated newline restores the complete generated boundary; no cache assertion was relaxed. Raw arms, source manifest and request comparison: `reports/qwen38-closeout/composition-baseline/adapter-lookup/`.
|
|
3543
|
+
|
|
3544
|
+
|
|
3545
|
+
### Ngram match-length screen with the upper adapter (M4 Pro, 2026-09-11)
|
|
3546
|
+
|
|
3547
|
+
Same e4b/upper-adapter artifact, bf16 KV, depth three, cache settings and `adapter-lookup-0` workload as above. Source `ef832276…` differs only by adding benchmark forwarding for the existing `--ngram-min`/`--ngram-max` flags. Order is 1–3, 2–3, 3–3, 5–5, then the reverse. Each arm retains five decode samples; table values are means of the two arm medians for decode and means for other timings.
|
|
3548
|
+
|
|
3549
|
+
| Minimum–maximum match | Decode tok/s | Aggregate tok/s | Aggregate wall ms | Cached TTFT ms | Cold TTFT ms | Aggregate accepted/proposed, arm A |
|
|
3550
|
+
|---|---:|---:|---:|---:|---:|---:|
|
|
3551
|
+
| min1-max3 | 53.949 | 78.566 | 6516.923 | 30.535 | 529.999 | 39/455 |
|
|
3552
|
+
| min2-max3 | 56.532 | 115.274 | 4442.253 | 47.959 | 537.508 | 26/90 |
|
|
3553
|
+
| min3-max3 | 53.552 | 130.850 | 3913.573 | 47.439 | 533.417 | 17/30 |
|
|
3554
|
+
| min5-max5 | 50.495 | 134.898 | 3796.100 | 47.561 | 525.433 | 20/24 |
|
|
3555
|
+
|
|
3556
|
+
Requiring longer matches avoids many rejected proposals. Minimum two has the highest single-request decode in this screen; minimum five has the highest aggregate throughput. Neither dominates ordinary execution from the adjacent matched campaign (about 53.8 decode and 159 aggregate tok/s). Minimum two improves single-request decode but still gives up concurrent throughput; minimum five lowers both decode and aggregate throughput versus ordinary. Lookup stays opt-in; these results do not establish a global match-length default.
|
|
3557
|
+
|
|
3558
|
+
Three concurrent responses/usage records differ between the minimum-one repeats (39/455 versus 26/444 accepted/proposed); their aggregate timings remain close. The other settings repeat their own responses and usage exactly. Different match thresholds change response trajectories, so the timing differences are configuration results, not same-output engine speedups. All eight arms complete 120 requests without phase failures. Raw commands, request hashes, source identity and comparisons: `reports/qwen38-closeout/composition-baseline/ngram-settings/`.
|
|
3559
|
+
|
|
3560
|
+
|
|
3561
|
+
### Independent greedy sampling across verification positions (M4 Pro, 2026-09-11)
|
|
3562
|
+
|
|
3563
|
+
Apple M4 Pro, 24 GB, Bun 1.4.2, MLX 0.32.2. Twelve matched `bench-serve.ts all` arms compare frozen control `ef832276f7a43d2a203e8d8e4b41c362459bf55d7389803af18ca8e995c83838` with candidate `22d1a38a761ea28c0dcd3ec90374a6a6931bbd9d2965bb7c64a65458aae45398`. Gemma e4b OptiQ with the upper adapter, bf16 KV, scheduler capacity eight, four concurrent requests, 192 decode tokens, 2 GiB prompt cache plus SSD, workload seed `adapter-lookup-0`. Each setting runs control/candidate/candidate/control. Diagnostic mode follows Josh's CPU/swap policy; retained swap and background App Store CPU activity are recorded in raw reports.
|
|
3564
|
+
|
|
3565
|
+
The sampler exposes a stateless operation for compatible greedy rows. Ordinary decode and speculative verification share normalized-score argmax; verification reads its independent token rectangle once. Grammar, processors, stochastic sampling, logprobs and custom sampler functions retain request-local sampling. Tests include rounding-created ties where raw-logit argmax would choose a different token.
|
|
3566
|
+
|
|
3567
|
+
Means of the two arm medians for single-request decode/cold latency; means of the two measured aggregate/cached values:
|
|
3568
|
+
|
|
3569
|
+
| Method | Decode control → candidate, tok/s | Aggregate control → candidate, tok/s | Aggregate change | Cached TTFT control → candidate, ms | Cold TTFT control → candidate, ms |
|
|
3570
|
+
|---|---:|---:|---:|---:|---:|
|
|
3571
|
+
| Ordinary | 54.198 → 54.278 | 162.724 → 162.721 | −0.002% | 38.378 → 37.283 | 530.258 → 522.210 |
|
|
3572
|
+
| Lookup depth 3, min/max 1/3 | 55.101 → 54.898 | 79.716 → 80.779 | +1.334% | 30.760 → 30.517 | 518.664 → 516.427 |
|
|
3573
|
+
| Lookup depth 3, min/max 5/5 | 51.405 → 51.712 | 136.141 → 138.956 | +2.067% | 47.652 → 47.348 | 539.549 → 536.417 |
|
|
3574
|
+
|
|
3575
|
+
Ordinary decode changes +0.148%; lookup 1/3 changes −0.368%, and lookup 5/5 changes +0.598%. Aggregate wall time changes +0.002%, −1.319% and −2.025%, respectively. Startup changes +0.045%, +10.505% and −7.777%, while ready time stays within 0.3%; the small source change does not establish startup dominance. Peak RSS changes −0.321%, −0.248% and +0.413%.
|
|
3576
|
+
|
|
3577
|
+
All 180 requests succeed and every arm retains its source hash. The first paired comparisons preserve every response and usage record. Ordinary and 5/5 repeats are exact, as are both candidate 1/3 runs. The 1/3 control repeat changes three concurrent responses and speculation usage; it is not an exact repeated trajectory. The stricter lookup setting still loses aggregate throughput to ordinary decoding, so no lookup default changes. Both-machine numerical, full-suite/typecheck and adapter native/generated RAM/SSD checks pass. Raw commands, source inventories, results and response comparisons are under `reports/qwen38-closeout/composition-baseline/independent-sampling/`.
|
|
3578
|
+
|
|
3579
|
+
|
|
3580
|
+
### Shared ordinary checkpoints and queued persistence (M4 Pro, 2026-09-11)
|
|
3581
|
+
|
|
3582
|
+
Apple M4 Pro, 24 GB, Bun 1.4.2, MLX 0.32.2. Ten matched `bench-serve.ts all` arms compare frozen control `6ab45ad7bda4adf9760eb69312bbf1dacdb8fe17592df9bc8f5699e7c8b692a9` with candidate `4dcf90668b7a319538ba648de196b72d81a8a26aa1bcef7d45ba5ce4f393c6e8`. Gemma e4b OptiQ, bf16 KV, no adapter, 192 decode tokens, four concurrent requests, 2 GiB prompt cache plus SSD, workload seed `ordinary-continuation-0`. Shared scheduler capacity is eight. Ordinary arms run control/candidate/candidate/control; checkpoint interval 64 runs old serial/new serial/new shared/new shared/new serial/old serial. Diagnostic mode follows Josh's CPU/swap policy; retained swap and background App Store CPU activity are recorded.
|
|
3583
|
+
|
|
3584
|
+
The candidate shares ordinary restore/capture through a checkpoint-policy interface and queues owned SSD snapshots through the existing idle gate. Completion invalidates the checkpoint immediately and queues ordered disk cleanup. Means of the two arm medians for decode/cold latency; means of aggregate/cached measurements:
|
|
3585
|
+
|
|
3586
|
+
| Execution | Decode tok/s | Aggregate tok/s | Aggregate wall ms | Cached TTFT ms | Cold TTFT ms |
|
|
3587
|
+
|---|---:|---:|---:|---:|---:|
|
|
3588
|
+
| Ordinary control | 59.401 | 169.043 | 3028.808 | 67.649 | 551.692 |
|
|
3589
|
+
| Ordinary candidate | 59.258 | 168.873 | 3031.856 | 67.720 | 553.158 |
|
|
3590
|
+
| Checkpoint, old serial | 58.702 | 57.265 | 8940.938 | 67.800 | 559.996 |
|
|
3591
|
+
| Checkpoint, queued serial | 59.011 | 57.458 | 8910.919 | 67.758 | 565.658 |
|
|
3592
|
+
| Checkpoint, queued shared | 58.905 | 168.159 | 3044.730 | 67.975 | 566.320 |
|
|
3593
|
+
|
|
3594
|
+
The ordinary source comparison changes decode −0.241%, aggregate throughput −0.101%, cached TTFT +0.105%, cold TTFT +0.266%, startup +0.480% and peak RSS +0.084%. Queuing serial persistence changes decode +0.526%, aggregate +0.337%, cold TTFT +1.011% and peak RSS −1.141% versus old serial. Moving checkpoint-enabled requests from queued serial to shared execution raises aggregate throughput **192.667% (2.927×)** and reduces aggregate wall time **65.831%**; single-request decode changes −0.179%, cached TTFT +0.321%, cold TTFT +0.117%, startup +0.648% and peak RSS +0.239%. This establishes concurrent throughput improvement on this workload, with the small single-request costs recorded.
|
|
3595
|
+
|
|
3596
|
+
All 150 requests succeed, source hashes stay fixed, and each arm repeats its own response/usage records exactly. Ordinary source and queued-serial comparisons preserve all responses and usage. Shared versus queued serial changes one concurrent response; all 15 usage records report the different execution lane and three concurrent requests reuse 11 rather than 13 prompt tokens. Other usage fields match. These timed requests complete normally; separate both-machine native and HTTP interruption/flush/fresh-server checks establish exact checkpoint restoration at matching batch geometry, including compiled and mixed-grammar bf16 controls. Those checks found a resumed shared cached-token counter could include replayed output; its clamp is under validation in the subsequent quantized candidate and is not part of this frozen timing source. This is not a process-crash durability or full Kanban acceptance result. Raw commands, source inventory and comparisons: `reports/qwen38-closeout/composition-baseline/ordinary-continuation-composition/`.
|
|
3597
|
+
|
|
3598
|
+
### Shared ordinary continuation composition (M4 Pro, 2026-09-11)
|
|
3599
|
+
|
|
3600
|
+
Eight completed `bench-serve.ts all` arms on the Apple M4 Pro, 24 GB, Bun 1.4.2 and MLX 0.32.2. Gemma e4b OptiQ, no adapter, 192 decode tokens, four concurrent requests, scheduler capacity eight, 2 GiB RAM cache plus temporary SSD, checkpoint interval 64 and workload seed `ordinary-continuation-0`. Diagnostic mode follows Josh's campaign policy. Frozen control `4dcf90668b7a319538ba648de196b72d81a8a26aa1bcef7d45ba5ce4f393c6e8` and candidate `c918d6e76e702f86d66f17095f33f0aa00d912e8c7f4a469e9992dfbe90a03a0` run control/candidate/KV4/TurboQuant, then the reverse. Context sweeps are omitted in this short comparison.
|
|
3601
|
+
|
|
3602
|
+
The candidate composes ordinary continuation with shared cache layouts, fixes resumed cached-token accounting and the pending-token dtype, and materializes Gemma's model constants before compiler capture. Separate native/HTTP tests cover actual interruption and restoration; the timed requests complete normally. Decode and cold latency are means of arm medians; other columns are means of the two arms.
|
|
3603
|
+
|
|
3604
|
+
| Shared checkpoint configuration | Decode tok/s | Aggregate tok/s | Aggregate wall ms | Cached TTFT ms | Cold TTFT ms | Startup ms | Peak RSS MiB |
|
|
3605
|
+
|---|---:|---:|---:|---:|---:|---:|---:|
|
|
3606
|
+
| Control, bf16 KV | 59.186 | 168.196 | 3044.070 | 67.724 | 556.523 | 904.388 | 6751.820 |
|
|
3607
|
+
| Candidate, bf16 KV | 59.034 | 168.304 | 3042.116 | 67.836 | 558.943 | 908.403 | 6738.312 |
|
|
3608
|
+
| Candidate, affine KV4 | 58.286 | 164.636 | 3109.894 | 70.515 | 564.785 | 916.674 | 6768.227 |
|
|
3609
|
+
| Candidate, TurboQuant k8v3 | 57.197 | 165.002 | 3102.993 | 71.260 | 559.206 | 899.109 | 6744.930 |
|
|
3610
|
+
|
|
3611
|
+
At unchanged bf16 settings, decode changes −0.256%, aggregate throughput +0.064%, cached TTFT +0.166% and cold TTFT +0.435%. This is effectively flat performance. All source-comparison responses and usage records match. All four configurations repeat their own responses and usage exactly, all 120 requests succeed without phase failures, and every source hash remains fixed.
|
|
3612
|
+
|
|
3613
|
+
Compared with candidate bf16, KV4 changes decode −1.267% and aggregate throughput −2.179%; TurboQuant changes decode −3.112% and aggregate throughput −1.962%. KV4 changes ten response texts and TurboQuant nine, with unchanged usage records. These short-context settings do not improve speed or establish a memory advantage from peak RSS. They remain configuration tradeoffs rather than new defaults. Raw arms and derived response/timing comparisons: `reports/qwen38-closeout/composition-baseline/ordinary-continuation-final/`.
|