Decode throughput on a pair of Radeon cards; checked between an offline probe and the campaign harness, across cold starts, and across thirty days of drift
Two harnesses in this repository produce decode figures: an offline probe and the campaign harness. Charts that pool their results need the difference to be measured rather than assumed. On a warm machine, that difference is 0.44 %. Finding that out required four identical runs, because the first read 31 % low.
The campaign harness queries an OpenAI-compatible server with streaming, sampling at temperature 0.8 over a 512-token generation. The probe harness runs LLM.generate offline with greedy decoding, differencing a 64-token run against an 8-token run. At matched context depths, the two agree to 0.44 %, 0.01 % and 0.07 %. Matching the generation span changes nothing of consequence. They record the same measurement.
Reaching that conclusion required discovering that a single run is not a measurement on this box. Four identical runs back to back read −30.7 %, −5.1 %, and then converge. The penalty falls heaviest where the machine is fastest, which initially disguised a warm-up effect as a harness discrepancy.
Two rules follow and are recorded in the ledger rather than left to whoever plots the charts. Every point records runs and range_pct. patches is a list rather than a boolean, because a result requiring an unmerged pull request is not the same claim as one obtained from a release.
The range is reported rather than a standard deviation, and one cell demonstrates why. Adding a third and fourth run to a bimodal 8K point widened its range from 15.79 % to 16.79 %, even as its standard deviation fell from 4.87 to 3.61. One statistic warned that the measurement was less stable; the other suggested it had improved.
The calibration model is chosen specifically to isolate harness differences from every other variable in the stack:
Engine knobs follow the campaign configuration. Context depths use the campaign's reported
prompt_tokens rather than nominal targets, ensuring both harnesses measure at identical sequence lengths rather than merely near them.
The initial comparison in Figure 1 showed the probe 31 % below the campaign at the shortest depth and 9 % below at the longest. Because the two harnesses differ in token span, sampling strategy, and transport, that gap invited plausible explanations. It was none of them.
Two campaigns ran thirty days apart, under different kernels and different patches. Six configurations were measured in both. Those six controls are the sole evidence determining whether a number from July and a number from August can share a single chart.
The ledger projects raw measurement files into a single uniform row format, recomputed and verified rather than edited by hand. Two metadata fields accompany every point; delegating them to chart rendering is how a benchmark repository promises more certainty than it measured.
One afternoon provides the clearest illustration of why this metadata must accompany the data. The
2026-08-29 campaign evaluated eight ladders on a single machine across eleven shared rungs, running two rounds per
cell in one continuous session. The three non-speculative arms placed zero of their 33 rungs above the
cut, recording a worst range of 0.59 %. By contrast, the five speculative arms placed 28 of 55 rungs above the threshold. That is not a
statement about speculation as such: gemma-4-31B's speculative arm is graded at every
rung, worst range 2.68 %. Instead, all 28 outliers belong to Qwen3.8-27B — on both attention backends,
patched and unpatched alike. Reporting a simple mean would have presented those 28 volatile cells as placidly as the other 60,
concealing the instability in every downstream plot.
Almost every cell in this benchmark contains two runs. With two samples, the sample standard deviation is merely the range divided by the square root of two — the same metric masquerading as an unearned distribution. At four samples, the statistic begins to carry independent meaning. That is where the choice becomes concrete, because one measured cell has four runs.
The obvious way to verify that a kernel change is harmless is to compare generated tokens before and after the modification. On this hardware, however, that test measures platform nondeterminism rather than the change.
Numerical claims in this repository are evaluated against an fp32 reference on fixed inputs. End-to-end changes are argued from throughput rates and internal execution routing logged by the workers. Comparing token IDs is reserved exclusively for platforms known to be deterministic — a property confirmed by measurement on the A100, but absent on this machine.
The slowdown is measured, but the mechanism is not. It outlasts a warm-up generation, is not confined to the first depth, and clears by the third run. Whether the cause is the host, the driver, the container or something else was not isolated.
Calibration uses one model to isolate variables. Agreement is clean but narrow: models on other kernel paths could diverge between harnesses for reasons unaddressed here.
Two of six configurations shifted about 0.8 % between campaigns. One remains under investigation after ruling out several candidates without finding the cause. Cross-campaign pooling is therefore bounded by a band, not asserted as equivalence.
Varying outputs are not claimed to be wrong, only non-reproducible. TP=1 is untested; variance originates above the kernel but is not further localised.
build_ledger.py justified its 6 % threshold by describing the spread distribution as it
stood when the rule was written. That distribution moved: the 0.27 rows landed and the bimodal cell
gained two runs, so the tail was then 2.6, 3.4, 3.5, 4.1, 5.1 and then 16.8, and the cut excluded
one point rather than two. The comment was rewritten to describe it and the verifier pins its tail,
so it cannot go stale unnoticed.
benchmarks/README.md counts 30 of 142 cells above 1 %. The
sentence is now scoped to the cells it is about. Separately, the two campaigns are
thirty days apart, 2026-07-25 to 2026-08-24, not five weeks; the heading, the
paragraph and figure 3's title all said five. And the Chinese rendered "stated with a band" as
带宽陈述, which is bandwidth; it now reads 区间.
RDNA3W4A16LinearKernel and forcing TRITON_ATTN on the two
unstable models left both unstable, against zero varying cells for the two the earlier reading
called stable; the backend is not the axis, and the quantisation kernel is the remaining named
candidate, not established
(gfx1100-greedy-attn-ab/).
Run it yourself. All data and verification scripts live in the repository: probe runs in
benchmarks/harness-calibration/;
the ledger pipeline in
ledger.jsonl
and
build_ledger.py,
which fails if the committed projection no longer matches its sources; and raw nondeterminism logs in
gfx1100-greedy-nondeterminism.json.
Every figure is recomputed from these sources by
verify_doc_figures.py.
The nondeterminism was posted upstream in vllm#50603, which reports identical Triton fallback behaviour but finds that a warm-up call fixes it. Because every measurement here already included a warm-up generation and still varied, either that remedy does not generalise or this platform encounters a distinct defect.