Skip to content

Commit c20e0e7

Browse files
debug(mlx): full root-cause chain — batch>1 decode bug is MLX core quantized/rope kernel at L=1 B>1 (ruled out rotation/cache/shared-kv/embed/mask/SDPA); not Python-patchable, upstream MLX
Co-authored-by: FluffyAIcode <FluffyAIcode@users.noreply.github.com>
1 parent e04f579 commit c20e0e7

2 files changed

Lines changed: 47 additions & 0 deletions

File tree

docs/adr/0014-agent-connection-capacity-and-cross-host-topology-tests.md

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,35 @@ present on CUDA (HF transformers batched decode is correct → §3.5/§3.7's 8.0
289289
custom batched gemma decode kernel) — tracked as a follow-up; CUDA is the
290290
recall-safe batched path today.
291291

292+
**Deep localization (per-layer logits + ablations).** A per-layer hidden-diff
293+
instrument (`mlx_batched_layer_diff_diag.py`) + targeted ablations narrowed the
294+
batch>1 decode bug to a single op class. At decode step 1, batched **row 0 is
295+
bit-exact** vs serialized while **row 1+ diverge starting at layer 0**, with
296+
**layer-0 input identical** (embedding/per-layer-input correct). Every
297+
Python-level cause was **ruled out** with evidence:
298+
299+
| candidate | test | result |
300+
| --- | --- | --- |
301+
| sliding-window rotation | short prompt (no rotation) | still diverges |
302+
| in-place cache write | concat `SinkWindowKVCache` | still diverges |
303+
| KV-shared layers | model has **0** shared layers (`first_kv_shared_idx=30`) | N/A |
304+
| embedding / per-layer-input | layer-0 **input** diff = 0 for all rows | ruled out |
305+
| attention mask | decode mask is `None` at this offset | ruled out |
306+
| `mx.fast.scaled_dot_product_attention` | manual matmul-softmax SDPA | still diverges |
307+
308+
With identical layer-0 input + concat cache + manual SDPA, row 1 *still* breaks,
309+
and **prefill (L=327) is correct while decode (L=1) breaks** → the residual is
310+
an **MLX core-kernel bug for 4-bit-quantized *batched single-token* decode**
311+
(`mx.quantized_matmul` / `mx.fast.rope` at `B>1, L=1`) — below the Python layer,
312+
**not patchable in this repo**. (CUDA is unaffected: HF transformers, no MLX
313+
quantized kernels — §3.5/§3.7 keep recall 1.0.)
314+
315+
**Outcome:** the Mac batched path is **blocked upstream in MLX**, now precisely
316+
characterized for an upstream report. Recall-safe Mac multi-tenant remains
317+
**serialized**; a Python workaround (e.g. L≥2 padded decode, or de-quantized
318+
projections) is a possible future probe. Evidence:
319+
`results/research/k3_mlx_batched_manual_sdpa_mac.json` + the layer-diff logs.
320+
292321
## 4. Case 2 — cross-host proposer/verifier (FEASIBILITY VERDICT)
293322

294323
### 4.1 Verdict: the requested topology is not implementable today, and is architecturally bounded out
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
{
2+
"kind": "mlx_batched_multitenant",
3+
"config": {
4+
"sessions": 8,
5+
"modal_prompt_len": 1149,
6+
"max_new_tokens": 24,
7+
"verifier_path": "/Users/fluffy314/kakeya-models/gemma-4-26B-A4B-it-mlx-4bit"
8+
},
9+
"serialized": {
10+
"aggregate_tps": 16.115,
11+
"recall": 1.0
12+
},
13+
"batched": {
14+
"aggregate_tps": 0.955,
15+
"recall": 0.125
16+
},
17+
"batched_speedup_vs_serialized": 0.06
18+
}

0 commit comments

Comments
 (0)