Skip to content
Merged
216 changes: 216 additions & 0 deletions .agents/benchmark-record.md
Original file line number Diff line number Diff line change
Expand Up @@ -25349,3 +25349,219 @@ row's process and it was left alone. And the FIRST arm started seconds after the
previous holder's four-hour render released the device, with the one-minute load
average still at 17.5, which is one reason the first 8000-slot run is the
noisiest of the four. Every later arm started from a quiet box.

## ENG-EXPERT-STREAM-DEVICE 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)

**Read the W0e section above first; this one is a different run of the same
harness on a different tree.** W0e measured the CPU arm and found the CUDA arm
loading without generating, at source `95883dcae`, which is W0f's parent. This
section is the re-run WITH W0f, at `9c783a8be`. The CPU figures therefore do not
agree between the two sections and must not be mixed: W0e's **11.05 s/token at
4000 slots** is the standing CPU number, taken on its own lease against a live
cache, and the CPU column below is a same-lease interleaved control for the CUDA
arm rather than a second attempt at that measurement. Where they disagree, W0e's
is the one `docs/BENCHMARKS.md` carries.

**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.
**That does NOT by itself acquit W0f, and an earlier draft of this entry said it
did.** Both of the grounds first offered constrain only the arm W0f cannot reach:
the CPU arm returns at `ResidentWeight`'s `is_cpu()` early return
(the `is_cpu()` branch of `qwen3_5.cpp`'s `ResidentWeight`) roughly ninety lines above the alias branch (the `host_memory_is_device_addressable()` branch of the same function; no line number, because this change moves it), so
`w0f-alias calls = 0` there is true by construction for every possible state of
W0f, correct or corrupt. It shows the branch is platform-gated. It cannot
discriminate "the arms' GEMM arithmetic differs" from "W0f moved a logit". The
experiment that does is recorded under **Algo identity** below. An instrumented
CPU run printing the top-2 logits per step gives the shape of the disagreement:

| 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. **NO RATIO IS WRITTEN HERE, and
the omission is deliberate.** A ratio of these two medians is not a result: the
correctness gate that would license one FAILS, so it may not be published,
quoted, or carried into `docs/BENCHMARKS.md`. An earlier revision of this entry
did write the figure out in digits in order to disown it, which is the shape
this repository has watched turn a disowned number into a measured one -- the
digits survive a copy-paste and the disclaimer does not. Nothing is lost by
removing them, because both medians are in the table above and anyone entitled
to the quotient can do the division; what is removed is the pre-computed string
a later reader can lift without its gate. 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 must not be mixed.

**Algo identity: the discriminating experiment, and it clears W0f.** The grounds
first offered above could not separate "the arms' GEMM arithmetic differs" from
"W0f moved a logit", so the mechanism was measured directly on `thor:gpu0`
(NVIDIA Thor `sm_110`, driver 13020, cudart 13000, cuBLASLt 130101, `rc` job
`c625e836`, 2026-08-19 13:50). Thor answers this branch's own predicate TRUE —
`cudaDevAttrPageableMemoryAccess = 1`, `cudaDevAttrIntegrated = 1` — so it is a
member of the population W0f serves, and a `cudaMalloc` pointer there is a real
device pointer exactly as on GB10.

The probe transcribes both cuBLASLt formulations out of
`src/vt/cuda/cuda_matmul.cu` at this branch — the row-major NN
`MatmulKernelCuda` (weight is operand B) and the column-major TN
`MatmulBTKernelCuda` (weight is operand A) — over six shapes off the
checkpoint's own `embedding_length = 8192` at M = 1, 5 and 32. Twelve
measurements, `PROBE_FAILURES=0`:

| Question | Result |
|---|---|
| Does a repeated heuristic call return the same selection? | **12/12 identical** |
| Is the tree's unset preference the documented 256 default? | **12/12** `default == MIN_ALIGNMENT 256` |
| Does STATING a weaker 16-byte promise move the selection? | **12/12 unchanged** (`256 == 16`) |
| `cublasLtMatmul` with weight from `cudaMalloc` vs a 256-aligned HOST block | **12/12 bit-exact**, 0 differing elements, every status `SUCCESS` |
| ...and from a 16-aligned-only host block | 12/12 bit-exact as well |

The selection is reported in full rather than by id alone. At M=1 N=8192 K=8192,
both layouts: `id=66 tile=573 stages=35 splitK=5 reduction=2 swizzle=0 custom=1
inner=0 ws=163856 waves=0.8000`, identical across all four queries. **The
instrument discriminates:** five DIFFERENT configurations appear across the six
shapes (tiles 393, 537, 573, 576; workspaces 0 through 5,242,896), so a uniform
answer is not a probe that reports one thing regardless.

The structural reason sits in the API and needs no lease:
`cublasLtMatmulAlgoGetHeuristic` takes `(handle, operationDesc, Adesc, Bdesc,
Cdesc, Ddesc, preference, count, results, returned)` and **no operand
pointers**, so the only channel by which alignment can reach the heuristic is
`CUBLASLT_MATMUL_PREF_MIN_ALIGNMENT_*_BYTES`, which this tree never sets.

**Conclusion on Thor: identical algo AND bit-exact output, so W0f cannot move a
logit there.** What that leg could not establish is that it ran on Thor and not
on the GB10 the token gate ran on: same predicate class, not the same silicon.

**The GB10 leg RAN, on the target silicon, and it agrees.** `rc` job
`7c7a05e9-be87-48f4-94ae-1bbe0340f063` on `dgx:gpu0`, worker `rc-worker-4b8lj`,
2026-08-19 17:47 UTC, output `/workspace/w0f-algo-probe/out-rc-worker-4b8lj-20260819T174748.txt`.
The box re-derived inside the job rather than inherited: `NVIDIA GB10 sm_121`,
driver 580.173.02, cudart 13000, driver 13000, cuBLASLt 130101 resolved from
`/usr/local/cuda-13.0/lib64/libcublasLt.so.13.1.1.3`, headers at
`/usr/local/cuda/include`. It answers this branch's predicate TRUE in the job's
own print: `pageableMemoryAccess=1 integrated=1 hostPageTables=1 uva=1`. The same
six shapes crossed with the same two formulations, `PROBE_EXIT=0`,
`PROBE_FAILURES=0`:

| Question | Result on GB10 |
|---|---|
| Does a repeated heuristic call return the same selection? | **12/12 identical** (`VERDICT-A repeat-identical=YES`) |
| Is the tree's unset preference the documented 256 default? | **12/12** (`VERDICT-B default==256:YES`) |
| Does STATING a weaker 16-byte promise move the selection? | **12/12 unchanged** (`256==16:YES`) |
| `cublasLtMatmul` with weight from `cudaMalloc` vs a 256-aligned HOST block | **12/12 bit-exact**, `differing=0`, every status `SUCCESS` |
| ...and from a 16-aligned-only host block | 12/12 bit-exact as well, no sync error |

The pointers are printed per case, so the arms are not assumed to differ: e.g.
`d_w=0x331200000 %256=0 | host256=0xed1243ffd000 %256=0 | host16=0xed123bffa010
%256=16`. The largest case compared `out_elems=262144` with `differing=0`.

**The GB10 instrument discriminates too**, and more finely than Thor's: at least
five distinct selections appear across the twelve measurements — `id=23 tile=21
stages=10 splitK=1 ws=0`, `id=13 tile=0 custom=75 ws=0`, `id=21 tile=11 stages=8
splitK=64 ws=1920`, `id=13 tile=0 custom=96 splitK=16 ws=32784`, `id=21 tile=5
stages=19 splitK=5 ws=5120`, `id=21 tile=5 stages=20 splitK=9 ws=737280` and
`id=67 tile=18 stages=35 custom=28 ws=0` — so a uniform verdict on alignment is
not an instrument that returns one answer regardless. The GB10 selections differ
from Thor's, which is expected of a different architecture and is itself evidence
that the heuristic was re-resolved rather than replayed.

**So the attribution is now measured on the target silicon: W0f cannot move a
logit, and the step-7 divergence is not the alias.** What it does NOT establish
is what the divergence IS. "The two arms' GEMM arithmetic" remains the standing
hypothesis and it is not measured; naming the operation that first differs is
owed. The 16-aligned arm also came back bit-exact on both boxes, which is NOT a
licence to lower `kDeviceAliasAlignment`: twelve shapes is not the enumeration,
and cuBLASLt is still promised 256.

**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`), and **why it faults is UNMEASURED**. An earlier draft wrote
"almost certainly because the pointer is not host memory there", which is a
hypothesis: nothing printed the pointer, nothing called
`cudaPointerGetAttributes` on it, and no fault address was recorded. In a change
whose central risk is handing device kernels host pointers, a segfault whose
cause was guessed at is the finding that must not be dismissed, so it is carried
as unmeasured. The next lease prints `cudaPointerGetAttributes(logits)` in that
callback first. Also owed: a ratified gate for a two-arm comparison whose greedy
path is this finely balanced, which `AGENTS.md` reserves as an explicit operator
decision. And still owed, now that the alias is excluded on the target silicon:
WHAT the step-7 divergence is. Excluding one cause is not identifying another,
and the next traceable hypothesis is a per-operation two-arm comparison of the
step-7 forward, first differing tensor named.
Loading
Loading