Skip to content
Closed
99 changes: 99 additions & 0 deletions .agents/benchmark-record.md
Original file line number Diff line number Diff line change
Expand Up @@ -22960,3 +22960,102 @@ for CUDA runtime version`. The Jetson 540.4.0 driver cannot run a CUDA 13 runtim
untried route is a CUDA 12.x toolkit for that driver; it was not pursued, because the
dgx gate had already answered the question orin was there to support. No lease held;
`orin:gpu0` returned to ready.

## ENG-EXPERT-STREAM-DEVICE W0e/W0f — `--device cuda` decodes a 369.97 GiB checkpoint on a 119.631 GiB GB10, and the token gate fails on a near-tie (2026-08-19, `row/ENG-EXPERT-STREAM-DEVICE-W0F`, source `9c783a8be`, #1299)

**Setup.** One `rc hold` on `dgx:gpu0` (GB10, `sm_121a`, CUDA 13.0.1 in
`vllmcpp-build:gb10`, driver 580.173.02). `Qwen3.8-2.4T-A95B UD-Q1_0`
(369.97 GiB, 10 shards) from the host at `/home/mudler/ckpt/qwen3.8-q1_0`.
Streaming ON, 4000 slots (9.28 GiB arena), greedy, 32 tokens, prompt ids
`760,6511,314,9338,369`. Both arms on the SAME binary and the SAME lease, page
cache dropped between them. Harness `w0e_gen`, logs under
`/home/mudler/work/es-w0e/logs` on `dgx.casa`.

**Two VOID runs first, and why they were void.** The first two CUDA attempts
reproduced #1299 exactly (guard trip, zero decode steps) and looked like a W0f
result. They were not: the build ran `cmake --build build --target vllm`, which
is the STATIC library, while the harness links `build/libvllm.so`. That file was
still the previous day's pre-W0f build, `LIB_EXIT=0` all the same. W0e's own
`build.sh` had it right with `--target vllm-cli`. The corrected script records
the shared object's mtime and sha256 before and after and greps the built binary
for a string that exists only in the new code: `87c58eec` to `cf771cec`, marker
count 0 to 1. A build that does not relink is now reported as STALE rather than
as a pass.

**G0-LIVE: PASS.**

| Observable | CUDA | CPU |
|---|---|---|
| load | 266.330 s | 253.504 s |
| RSS after load | 61.20 GiB | 62.45 GiB |
| decode steps | 32 | 32 |
| `exhausted` at step 1 / step 32 | 6077 / 6077 | 6074 / 6074 |
| decode-phase `exhausted` delta | **0** | **0** |
| peak RSS | 97.75 GiB | 92.19 GiB |
| swap used at peak | 0 | 0 |
| container exit | `W0E_DOCKER_RC=0` | `W0E_DOCKER_RC=0` |

**What W0f moved, counted rather than inferred.** An RSS curve cannot separate
"the branch declined and staged", "the branch re-homed and the pages did not come
back" and "something else allocated", so `MakeHostBytesDeviceAliasable` reports
its outcome per weight and `ResidentWeight` prints the split every 4 GiB on
`VT_LOAD_STATS`. First-forward totals, at the point re-homing plateaus (call
1361):

| Outcome | Bytes |
|---|---|
| re-homed into an aligned host block, then aliased | **60.793 GiB** |
| declined, misaligned GGUF borrow, still staged | ~9.2 GiB |
| aliased in place (already 256-aligned) | 0.02 GiB at that point |

On the CPU arm the same counter reads **0 calls**, which is the live control that
the branch is platform-gated rather than an argument that it is.

**G0-CORRECT: FAIL, on a measured near-tie.**

```
CPU 11751,13,11751,369,264,3177,7172,303,279,17631,919,314,9338,11,383,279,...
CUDA 11751,13,11751,369,264,3177, 303,9338, 13, 9338,369,264,3046,303,4357,13,...
^ first divergence, step 7
```

The CPU arm on this binary reproduces its four-times-recorded ids byte for byte,
so the divergence is between the arms and not W0f. An instrumented CPU run
printing the top-2 logits per step gives the reason:

| step | top-1 | logit | top-2 | logit | margin |
|---|---|---|---|---|---|
| 5 | 264 | 18.954491 | 279 | 18.668240 | 0.286251 |
| 6 | 3177 | 19.375208 | 6037 | 18.425795 | 0.949413 |
| **7** | **7172** | **18.779411** | **303** | **18.514702** | **0.264709** |
| 8 | 303 | 20.953234 | 383 | 18.930481 | 2.022753 |
| **9** | 279 | 19.850554 | 9338 | 19.827751 | **0.022802** |

At the divergent step the CPU arm's own runner-up IS the token CUDA emitted,
1.4 % behind; one step later the margin is 0.1 %. The two arms rank the same
candidates and disagree about a coin flip. The declared gate still fails and the
wave still stops.

**G0-SPEED: VOID and NOT claimed**, because a speed number behind a failing
correctness gate is the #912 F1 shape. Taken for the record only, over the 31
DECODE steps of each arm (step 1 is prefill and is excluded), interleaved on one
lease:

| arm | n | min | median | max |
|---|---|---|---|---|
| CUDA | 31 | 3.012 | **4.598** | 126.456 |
| CPU | 31 | 7.857 | **9.055** | 23.174 |

The medians are the figures; the maxima are the first decode step after prefill,
when the slot cache is cold, and quoting either end of the range would be
quoting the least representative number in it. The implied ratio is 1.97x and it
is NOT a result: the correctness gate that would license it fails. Note also
that this CPU arm is FASTER than the 11.05 s/token previously recorded for the
CPU arm at 4000 slots, so the same-lease interleaved denominator here and that
earlier figure are not the same measurement and should not be mixed.

**Owed from this run.** The CUDA arm's own top-2 margin: the scratch instrument
that reads `logits` in the completion callback SIGSEGVs on that arm
(`SCRIPT_EXIT=139`), almost certainly because the pointer is not host memory
there. And a ratified gate for a two-arm comparison whose greedy path is this
finely balanced, which `AGENTS.md` reserves as an explicit operator decision.
2 changes: 2 additions & 0 deletions .agents/issue-index.md
Original file line number Diff line number Diff line change
Expand Up @@ -377,3 +377,5 @@ rather than merged. `scripts/check-agent-record.py` gates both.
| [#1226](https://github.com/mudler/vllm.cpp/issues/1226) | `ENG-CUDAGRAPH-DEDUP` | The owed device A/B for #1162 RAN on `dgx:gpu0` 2026-08-18 (GB10, driver 580.173.02, nvcc 13.0.88, `rc` job f88d484b, gated commit `72de552c8`, whose four dedup sources are byte-identical to the merged `2a976eb9f`) and it SPLIT. CORRECTNESS PASSED and closes [#1184](https://github.com/mudler/vllm.cpp/issues/1184): 12/12 cells exit 0, zero `invalid device function` and zero `engine-fatal` where the pre-fix head `e4ce5571a` died after exactly one replay, ON replays as often as OFF (60=60, 33=33, 43=43), and `--output-token-ids` is IDENTICAL over 10/10 comparisons with the three OFF/OFF controls passing FIRST and three workloads hashing to three DIFFERENT values. THE BENEFIT IS REFUTED for the case the row was filed for: `N == M` in every `VT_CUDA_GRAPH_DEDUP=1` cell — 3 graphs to 3 execs on sizes [24 16 8], 2 to 2 on [16 8], 2 to 2 on [32 24] — with the registry count CLIMBING 1→1, 2→2, 3→3, so more than one capture reached it and the 1:1 is a measurement rather than the single-capture artefact of the first attempt. The cause is structural and was pre-registered before the run: `AppendKernelPayload` hashes (`func`, `gridDim.{x,y,z}`, `blockDim.{x,y,z}`, `sharedMemBytes`) at `src/vt/graph_dedup_runtime.h:121-128` and the memcpy payload hashes the copy extent, so the padded batch dimension is IN THE KEY, no candidate group forms and `cudaGraphExecUpdate` is never attempted. That contradicts the row's own premise, and SGLang keys the same fields (`cuda_graph_dedup_mixin.py:105-114`), so whatever folds upstream is not decode buckets either. NO throughput or memory number is recorded — clocks unpinned AND the ON arm allocated exactly as many executables as OFF. `VT_CUDA_GRAPH_DEDUP` therefore stays OFF and the default flip is NOT JUSTIFIED on this evidence. THE OPEN HYPOTHESIS this issue owns, deliberately not decided by the record that filed it: a COARSER key keeping the function addresses and topology but dropping the launch dimensions and memcpy extents would let two padded buckets form a candidate group at all, and the probe-before-fold design means a wrong grouping costs one wasted `cudaGraphExecUpdate` probe and a private executable rather than a wrong replay, so it is a cost question needing its own spec, a red-first discrimination test and a device probe-refusal rate. Also owed here: whether ANY other capture site or two models sharing the process-singleton registry can fold (only the Qwen3 dense decode driver was exercised), and a supporting `orin:gpu0` leg, BLOCKED because the Jetson 540.4.0 driver cannot run a CUDA 13 runtime (`cudaGetDeviceCount err=35`; a CUDA 12.x toolkit is the untried route). Honest gaps carried into the record: per-shape replay counts are unavailable, so B's ~30-per-shape is arithmetic over a printed TOTAL; the driver's "N captured size(s)" counts SLOTS not captures; the container's own cuBLASLt was never re-tested at CUDA 13.0. Full evidence [`benchmark-record.md`](benchmark-record.md) entry `ENG-CUDAGRAPH-DEDUP W4`; spec [`eng-cudagraph-dedup.md`](specs/eng-cudagraph-dedup.md) `## Outcome` | perf |
| [#1229](https://github.com/mudler/vllm.cpp/issues/1229) | `ENG-CUDAGRAPH-DEDUP` | `origin/main` went RED at `fe24a3029` because `tests/scripts/test_check_gate_commands.py:670` pinned the literal string `Device byte-identity A/B (owed` inside `.agents/specs/eng-cudagraph-dedup.md`, and that commit legitimately rewrote the sentence from recording the device A/B as owed to recording that it RAN and what it found. The record edit is correct and the assertion described a state the record left, so every branch that merged `origin/main` inherited the failure. The protected property is stated by the assertion's own comment: the row is credited in `RUNNABLE_BASELINE` for `ctest -R test_graph_dedup` and `./scripts/agent-preflight.sh`, both CPU-tier, while gate item 6 of the spec contributes NO runnable command, so the credit covers the CPU tier and the record must not go silent about the leg it does not cover. That property is STATE-INDEPENDENT: `owed` was the leg's value on the day, not the property, and silence is the defect whether the leg was never run or the line was deleted after it ran. Asserting the NEW wording would only move the pin from `(owed` to `RAN 2026-08-18, PASS`, and the rerun this row already owes under [#1226](https://github.com/mudler/vllm.cpp/issues/1226) against a coarser signature key would red it again. FIXED by keying on structure: `gate_items`, `item_lead` and `gate_disposition` land in `scripts/check-gate-commands.py`, and the test now asserts that exactly one gate item names the device byte-identity A/B as its SUBJECT, that `runnable_commands` extracts nothing from it, and that its bold lead declares a disposition from a closed vocabulary. Lead-scoping is measured rather than assumed: a whole-item search credits item 5 with a disposition it does not declare, because its body contains `fail` in the phrase "proving the instrument can fail". Both historical wordings of item 6 are pinned as fixtures, which is what proves the new assertion is state-independent rather than re-pinned to today's sentence. The rule is NOT swept over every gate item and the reason is measured, not assumed: items 1 and 5 yield no command and declare no disposition, so a sweep is red on arrival, and widening the vocabulary until they pass would make it match ordinary English. That general rule is carried under `## Owed`. Also established and NOT a defect: `ERROR: these baseline rows left the gated population: ROW-THAT-IS-NOT-THERE` on the same run is the expected negative-path output of `test_check_mode_is_never_silently_swallowed_by_json`, confirmed by running that fixture alone. Spec [`fix-gate-commands-prose-pin.md`](specs/fix-gate-commands-prose-pin.md) | bug |
| [#1240](https://github.com/mudler/vllm.cpp/issues/1240) | `MODEL-FP8-BLOCK-WEIGHT` | `test_qwen27_dense_forward` and `test_qwen27_dense_forward_glue_fuse_off` are RED on `origin/main` at `aba8d5ffb`. Both throw the block-wise-FP8 refusal `09597106e` (#1228, issue #1189) added at `src/vllm/model_executor/models/qwen3_5_dense_weights.cpp:428`: `'layer.linear_attn.in_proj_qkv.weight_scale_inv' is present ... but the checkpoint's quantization_config declares no weight_block_size`. ATTRIBUTED by measurement, not inference: `git log -1` on that file is `09597106e`, and `git show --stat 09597106e` changes it (+219) while touching neither test — the producer moved and its consumer did not. It hides behind the doctest thrown-case shape: the run reports 563 assertions with NONE failed beside 9 cases with ONE failed, because a case that THROWS records no failed assertion, so the assertions line reads clean and only `Status: FAILURE!` and the exit code tell the truth. NOT fixed in flow, deliberately: the refusal is correct in its own terms (guessing 128x128 is exactly what #1166 asked not to happen), so whether the synthetic fixture is wrong to emit `weight_scale_inv` without `weight_block_size`, or the refusal is too broad for a checkpoint that is not block-wise FP8 at all, is a semantics choice belonging to the owning row with its own red-first evidence — not a fixture edit that makes the message go away. Found by `ENG-EXPERT-STREAM-DEVICE` W0 running the full ctest suite after merging `origin/main` (523 of 525 passed; these two the only failures, and W0 touches neither file) | bug |
| [#1299](https://github.com/mudler/vllm.cpp/issues/1299) | `ENG-EXPERT-STREAM-DEVICE` | With W0's lane on, `Qwen3.8-2.4T-A95B UD-Q1_0` (369.97 GiB) LOADS on `--device cuda` on a 119.631 GiB GB10 — 61.20 GiB resident, ~265 s, the [#1123](https://github.com/mudler/vllm.cpp/issues/1123) refusal correctly silent — and then exhausts the machine inside its FIRST forward, **zero decode steps across seven attempts**. Diagnosed by the measurements rather than by reading: a **0.15 GiB** slot arena died exactly where an 18.55 GiB one did, so the arena is not the cost; a 1-token prompt (protected set 2,790 slices, no in-place fallback) behaved identically to a 5-token one, so prefill protection is not either; growth was ANONYMOUS (`RssAnon` 8.1 -> 61.4 GB) while file-backed stayed flat, refuting "the GPU pins the mapping"; and host anon + swap ~65 GB against system `used` ~119 GB leaves ~42 GB of device memory unified memory does not charge to RSS. So **the non-expert weights are resident twice** — once as the host `OwnedTensor`, once as the `ResidentWeight` device staging copy — and on a part where device memory IS host memory the second copy buys nothing. About 39 GiB of the 61.20 is `attn_qkv` + `ssm_out`, which the GDN V-head reorder makes `kTransformedWeight` and therefore expands to bf16 in OWNED host buffers. FIXED as W0f: where `Platform::host_memory_is_device_addressable()` — the same probed predicate W0c already serves every expert slice on — `ResidentWeight` returns a tensor over `w.bytes.data()` instead of allocating and copying. Safety is by ALIGNMENT rather than by enumerating kernels: `MakeHostBytesDeviceAliasable` guarantees the aliased pointer meets `kDeviceAliasAlignment = 256`, which is what `cudaMalloc` returns, so no consumer can distinguish the two pointers; an OWNED buffer below that (glibc gives 16) is re-homed once into an aligned block, and a BORROW below it declines and stages, because copying a clean file-backed mapping into anonymous memory would ADD the residency this change removes. A DISCRETE device answers the predicate false and is byte-identical to before, asserted by its own case. Red-first and mutation-proven in `tests/vllm/model_executor/test_resident_weight_host_addressable.cpp` | bug |
| [#1320](https://github.com/mudler/vllm.cpp/issues/1320) | `ENG-EXPERT-STREAM-DEVICE` | `VT_CPU_QUANT_REPACK` rewrites a Q8_0 weight into the `block_q8_0x4` i8mm interleave at load, and only the CPU `MatmulBTKernel` understands that layout — the CUDA quant dot reads plain `block_q8_0` and never consults `Tensor::repacked`, so a repacked weight uploaded to a device produces WRONG TOKENS rather than a crash. Its sibling `elem_kn_repack` has BOTH a CPU-platform gate in the loader policy (`gguf_keep_quant.cpp`, `CurrentPlatform().device_type() == kCPU`) and a refusal in `ResidentWeight`; `quant_repack` had NEITHER, because it rides `vt::cpu::QuantRepackActive()`, a HOST-CPU Arm i8mm probe that says nothing about where the weight will execute. An aarch64 box doing `--device cuda` — which is exactly `dgx:gpu0`, a Grace-Blackwell GB10 — satisfies it. Currently silent rather than firing, and that is measured: eligibility is Q8_0 with `n % 4 == 0 && k % 32 == 0`, `Qwen3.8-2.4T-A95B UD-Q1_0` has exactly one Q8_0 tensor at 0.01% of parameters, and the instrumented load of that checkpoint recorded `quant_repack = 0`. Found while implementing W0f ([#1299](https://github.com/mudler/vllm.cpp/issues/1299)), which changes the same function and whose G0-CORRECT gate compares CUDA tokens against CPU tokens — precisely the instrument that would have reported this as a W0f defect. FIXED IN FLOW as the tripwire its sibling already has, placed beside it so it covers the staging branch AND W0f's aliasing branch (where the bytes live was never the question; the kernel that reads them is), gated red-first on both arms and mutation-proven. `VT_CPU_QUANT_REPACK=0` is the operator's way past it. NOT fixed here, deliberately: adding the missing CPU-platform gate to `p.quant_repack` itself is a loader-policy semantics change owned by `QUANT-GGUF-KEEPQ-LOADER`, carried under `## Owed` in [`expert-stream-device-slots.md`](specs/expert-stream-device-slots.md) | bug |
Loading
Loading