Review of the K3.25 analysis (2026-10-27)

A separate adversarial review of the K3.25 analysis, done after the runs by a reviewer who did not run the measurements: it re-ran the scorers and checked the claims against the receipts, read-only and on CPU only. It covered the precision and speed blocks and the vLLM fork's long output; it was made before CuteAFD's long output, the drift repeats and the follow-up results existed, and it does not cover K4 or the needle pilot. It found the instruments sound and the precision difference robust, traced the vLLM fork's run-to-run variation to multi-chunk prefill (which led to pairing CuteAFD against several vLLM runs), showed that the 8-16K bucket is long code reading, and confirmed the scheduling explanation of the speed results.

The review as published, with suggested follow-up work and local items omitted. Cited files link to this repository or to the engines' public sources at the versions tested; files that are not published are marked. Line numbers refer to the files as reviewed; published copies with placeholders may differ by a few lines.

Reviewer: a separate reviewer who did not run the measurements; read-only. CPU only: no GPU, no requests to :8001, no docker exec. Recomputations ran in docker run --rm --network none containers of local images (v0.9.2 image for numpy; CuteAFD image for tokenizers). The recomputation scripts are not published. Bootstraps I ran are window-cluster percentile bootstraps (5,000 draws, numpy RNG), so their limits differ from the scorer's SplitMix64 ones in the last digit.


1. Summary

The instruments are sound. The scorer port, the capture plumbing, the T driver and the summary script reproduce. The precision difference holds: C1 is further from the reference than vLLM on P-B generated rows, it survives the multiplicity and leave-one-out checks below, and C1's NLL is higher at every context bucket.

Four statements in the write-up go further than the data:

  1. Why vLLM varies run to run (cause misattributed). It is not batching or speculation. The data show the variation starts at the second prefill chunk. At 8-16K, vLLM's run-to-run divergence is about two thirds of the cross-engine divergence. The headline magnitudes therefore depend on which vLLM run is used as the baseline.
  2. "Located at 8-16K / grows with context" cannot be separated from content. The 8-16K bucket is block B (long code reading). Within block A, the only block present at every length, the KL gap is flat.
  3. The FP8 mechanism story leaves out several real differences between the engines' arithmetic. F1a also changes the KDA split path as well as KDA precision.
  4. Q2's sub-results rest on 3 clusters and one outlier window.

In Block T, the scheduling explanation holds and can be quantified. Streams that decode without prefill interleaving decode at the same speed on both engines. At 32K/128K the aggregate figure is mostly a prefill measurement.

In Block L, the "terminal loop" flags on code come from the detector counting the answer re-stating code drafted in the reasoning; they are not loops.


2. Findings, ranked

Corrections (a stated result, explanation or number did not match the data)

I1. vLLM's run-to-run variation was attributed to another cause, and its size was understated.

Prefill stepsWindowsGen rows bit-equal between V1 and V1rMean |ΔKL| per gen row
120100%0
21446%0.011
4120%0.008
8120%0.024
1060%0.022

Inside 2-step windows, rows of the first 2,045-token chunk are 100% bit-equal and rows of the second chunk are 2-67% bit-equal (a04, d01, d04, c03). This matches an earlier investigation (local-inference-evals, LEDGER.md (not published)): identical solo prefills diverge from the layer-3 indexer top-k at token 2,051, the first position where sparse selection applies.

BucketKL(V1‖C1)KL(V1‖V1r)vLLM self-divergence as share of cross-engine
2-8K0.01460.008055%
8-16K0.02450.016065%

"±0.0006" is the shift of a mean, not the size of the run-to-run noise.

P-B gen rowsC1 − V1 (reported)C1 − V1rC1 − mean(V1, V1r)
8-16K KL+0.0044 [+0.0017, +0.0069]+0.0057 [+0.0037, +0.0082]+0.0050 [+0.0031, +0.0071]
8-16K top-1−1.04 pts−0.70 [−1.14, −0.32]−0.87 [−1.20, −0.54]
2-8K top-1+0.39 [+0.03, +0.76]+0.14 [−0.29, +0.48]+0.27 [−0.05, +0.52]
overall KL+0.0027+0.0033+0.0030 [+0.0014, +0.0047]
overall top-1−0.51−0.42−0.47 [−0.74, −0.20]

The 2-8K top-1 "CuteAFD better" interval (RESULTS-Q.md:30) excludes zero only because of which vLLM run was picked.

I2. The claim of identical inputs does not hold for two Block T details.

Narrowed (a statement went beyond the evidence)

U1. "The gap is located at 8-16K and grows with context" is confounded with content (block B).

Block A, bucketKLTop-1NLL
0-2K+0.0029 [−0.0013, +0.0083]
2-8K+0.0017 [−0.0005, +0.0033]
8-16K+0.0028 [−0.0003, +0.0055]−1.05 pts+0.0137 [+0.0043, +0.0221]

Difference-in-differences for KL (8-16K minus <8K): +0.0006 [−0.0030, +0.0044]. So "consistent with a gap that grows with context" (RESULTS-Q.md:51-53) is not supported for KL. A context trend is suggested only in block A's NLL and top-1, on 6 windows.

U2. The mechanism inference ("FP8 projections, head and KDA") omits several known differences, and F1a is not a clean ablation.

RowsEntropy C1Entropy V1Entropy V1rTeacher (lower bound)Windows with C1 > V1
8-16K0.5800.5230.52218 of 18
block B0.6160.5550.527
2-8K14 of 16

The teacher bound is top-1024 plus the tail as one bucket. Excess entropy over the teacher is +17% for C1 and +5% for V1. This explains why the P-B NLL gap (+0.0168) is about 6x the KL gap: the panel text was generated greedily (windows.json recipe.temperature = 0), so NLL rewards sharpness. It also explains why C1 has the lower NLL on surprising tokens (trailing rows, Q2 c2-064k). Systematic flattening points more toward a scale or bias effect (head, norms, softmax inputs) than toward zero-mean rounding noise. This is inferred, not tested.

U3. Q2: "no NLL difference at 32K-128K" is acceptable only as a bounded statement; the prose/code sub-claims are not supported.

Meant-interval
Overall (5 df)−0.0005[−0.0046, +0.0035]
Prose (2 df)+0.0019[−0.0013, +0.0050]
Code (2 df)−0.0029[−0.0135, +0.0077]

Neither sub-claim excludes zero.

U4. Trailing context rows: "a property of the panel's context rows" is right; the implied reference-side cause is not.

U5. Block L: the code "terminal loop" flags count restated code, not loops (6 of 8 L3 and 1 of 1 L3s).

Added checks (checks or confounds not covered at first)

M1. No drift control or in-run telemetry for Block T.

M2. The single-stream speed advantage is plausibly draft policy, and the "code" and "json" labels are misleading.

M3. "As shipped" has undocumented deltas; the full list of launch differences follows.

SettingvLLM v0.9.2CuteAFD v3.0.1
DrafterDFlash2, 3 fixed tokens, BF16DFlash2, adaptive, FP8 / W8A8
Attention placementMLA layer ownership split:25token split context
DSA index KFP8 kpoolBF16 keys
KV recordfp8_ds_mla NOPE, 528 BFP8 latent, own records
Prefill schedulingchunked 2,048 per step, interleaved with decode4,096-row lanes, prefill first
Prefix cachealign mode, 0 hits at 8K20 entries, hit
LogitsBF16F32
Special tokens in user textparsedliteral
GPU memory utilisation0.95pool auto

M4. Results are not read against the panel's own paired bar.

BaselineTop-1 upper95KL upper95
V10.00800.0043
V1r0.00670.0048

M5. The panel's text provenance is not stated.

M6. Only prefill-shaped scoring was done.


3. What holds up (with how I checked)

Scorer and capture

Numbers in RESULTS-Q.md

The precision gap exists

Seeds and determinism

Freeze

The thinking-off confound is real

Block T arithmetic and the scheduling explanation

CellvLLM clean stream (tok/s)CuteAFD clean stream (tok/s)
32K code c1645.045.6
32K prose c850.449.7
128K code c495.490.5
128K prose c472.676.6

So the 1.5-4x is prefill-first vs interleaved scheduling. It trades against vLLM's earlier first tokens, which is why vLLM's TTFT median is lower at c ≥ 4.

Block L harness

GPU time used by this audit: none.