Repository navigation
mtp: the draft route's DEFAULT tau=0.6 is measured — 78.8 % hit rate on a 1.83 tokens/pass chain - #1300
Conversation
…on a 1.83 tokens/pass chain `Options::tau` defaults to 0.6 (npu/mtp/draft.h:162), so that is what a serve driving `mtp::run()` gets without asking, and every published acceptance row was at `tau = 0`. This lands the missing window: 8 prompts x 64 tokens, k=4, tau=0.6, `--live --match`, one prompt per npu-hold ticket (16:42-18:06 AST, array exclusive, amdxdna errors 0 in every arm), greedy text byte-identical to plain decode on 8 of 8 prompts with 0 stream mismatches, and prompt 0 measured twice (31/35 both times) as the determinism control. Measured, all-chains view, 277 chains / 292 drafts offered: hit rate 78.77 % (230/292) vs 46.69 % at tau=0 depth 1 acceptance 78.34 % (217/277) vs 75.14 % depth 2 acceptance 3.97 % (11/277) vs 47.51 % depth 3 acceptance 0.72 % (2/277) vs 34.81 % depth 4 never offered vs 29.28 % tokens per pass 1.83 (live) / 2.05 (offline, same positions) vs 2.87 So the gate does what it was asked and still loses: the drafts it keeps are far better (78.8 % hit rate, depth 1 identical to the offline protocol at +0.00 pp), but it almost never chains -- ~1.05 drafts per chain against 4.0 -- so the chain collapses from 2.87 to 1.83 tokens/pass, below the measured 3.2-4.1 break-even. At the default the draft route is a slowdown: 0.81x on the prompt-0 pair (plain 0.849 s/token, draft 1.049 s/token). The conditional per-depth comparison reads +27 and +47 pp at depths 2-3 on 13 and 2 live chains, which is why the all-chains view is the one published and depth 1 is the only comparable cell. Contents: eight fixtures (tests/fixtures/mtp_tau06, extracted verbatim with the same grep the mtp_clause55 README documents), six leaderboard records generated from the pool tool's own output rather than typed, the guard extended with the tau=0.6 window, and docs/npu.md carrying the table above plus the reason the per-depth clause is a depth-1 clause at this tau. Verified: `tools/mtp_depth_pool.py` over the fixtures reproduces the run to the count (277 chains, 292/230, 78.34/3.97/0.72, 78.77 %, 1.83/2.05); `tests/mtp_depth_pool_test.py` -> all checks passed, including `tau=0.6 (the default)... all 6 records equal what its tickets derive: []`; red arm: hit rate set to 78.78 -> `record says 78.78 %, the fixtures derive 78.77`, 1 CHECK(S) FAILED, restored green; `npu_leaderboard.py --check` 27 valid and regeneration byte-identical on a second run; `ctest -R 'mtp_draft|mtp_depth_pool|npu_leaderboard'` 3/3; copyright rc 0. refs #805.
…so the next window does not need a code edit
The tau=0.6 window's eight ticket fixtures reddened CI's `Copyright notice on every file` step:
no comment style known (add one to LINE_STYLES/BLOCK_STYLES or EXEMPT): tests/fixtures/mtp_tau06/p0.txt
... p1..p7 ...
##[error]Process completed with exit code 1.
Cause: EXEMPT carried the clause-55 window's own path (`tests/fixtures/mtp_clause55/*.txt`, engine#1146) rather than
the kind of file it is. An acceptance ticket is data a parser reads byte-verbatim, so a notice comment would make the
fixture no longer the log it claims to be -- true of every such window, not of one directory. The exemption is now
`tests/fixtures/*/*.txt`, and each fixture directory's README still carries the notice (it is `.md` and unaffected).
Why this got past my own pre-push check, measured rather than guessed: `tools/copyright.py --check` enumerates
TRACKED files, so it reports success on files that are not yet added.
untracked probe file, no notice: python3 tools/copyright.py --check -> rc 0
the same file after `git add -A`: python3 tools/copyright.py --check -> rc 1
"missing copyright notice: tools/zzz_untracked_probe.py"
That is the "a check that passes on data it cannot see" family this repo keeps closing (engine#1146, #1184, #1213).
The pre-flight for this lane is now: `git add -A` FIRST, then `copyright.py --check`.
Verified after the change, with the tree fully staged (the way CI sees it): `tools/copyright.py --check` rc 0;
`python3 tests/mtp_depth_pool_test.py` -> all checks passed; `ctest -R 'mtp_draft|mtp_depth_pool|npu_leaderboard'`
3/3; `tools/npu_leaderboard.py --check` 27 record(s) valid.
refs #805.
|
#1300 ready for review at 6fc93fa
Worth recording how it got past my own pre-push check, measured rather than guessed: i.e. another check that reports success on data it cannot see. New pre-flight for this lane: |
bong-water-water-bong
left a comment
There was a problem hiding this comment.
VERDICT: READY at 6fc93fa0.
Every number in the table re-derives from the counts you cite, which is the part a reader would otherwise take on trust:
tau=0.6 230/292 = 78.77 % 217/277 = 78.34 % 11/277 = 3.97 % 2/277 = 0.72 %
tau=0 338/724 = 46.69 % 136/181 = 75.14 % 86/181 = 47.51 % 63/181 = 34.81 % 53/181 = 29.28 %
derived 292/277 = 1.054 drafts per chain 0.849/1.049 = 0.809x (= the 0.81x you publish)
The guards are real, and they re-derive your records rather than trusting them:
tests/mtp_depth_pool_test.py all checks passed (the tau=0.6 window is covered, and "the record comparison
bites" fires: 27b-mtp-tau06-depth1 +0.01 is reported)
npu_leaderboard.py --check 27 record(s) valid (21 + your six)
regenerate vs committed page BYTE-IDENTICAL
copyright --check rc 0 (your last commit)
The fixtures carry their own provenance — == ticket 'tau06 p0 try1' 20261106-164254 hold=9min … --tau 0.6 — so the
window claim (16:42–18:06 AST) is checkable against the evidence rather than asserted, and each ticket states the identity
line the pool tool reads.
What I want to say about the finding itself: publishing a row that says the shipped default is a slowdown is the
right kind of PR, and the doc says it without softening — 1.83 tokens/pass against the measured 3.2–4.1 break-even, the chain
collapsing because ~1.05 drafts are offered per chain instead of 4.0, and the depth-2/3 "+27/+47 pp" called out as 13-and-2
live chains, i.e. noise. That is the difference between a benchmark and an advertisement.
One thing to surface rather than bury, since npu/ has no diff here: this PR measures the tau=0.6 default, it does not
change it, so the engine currently ships a default that this evidence says is 0.81x on the prompt-0 pair. Whether the default
becomes tau=0 (or a lower gate) is an owner decision, not a lane one — TISSUES-ALL rule 6 shape, and the natural next
line on #805. refs #805 is the right reference for a roadmap issue, and the "what remains" note on the issue should say
this row is now measured and the default is the open question.
Device rows stay yours: the window is seven npu-hold tickets with amdxdna errors 0, which I cannot re-run tonight (the
lock is still pinned by another lane's idle host-GEMM serve), and the fixtures are what make that acceptable — the CI guard
re-derives every record from them on each run.
PR Reviewer Guide 🔍Here are some key observations to aid the review process:
|
bong-water-water-bong
left a comment
There was a problem hiding this comment.
VERDICT: READY at f091af3ef408847d87f455b765e618b14531f478. The tau=0.6 measurement for #805 checks out end to end, from the raw ticket logs to the fixtures, the records and the guard. One nit, on the width of the copyright exemption.
Provenance, re-derived here
- The fixtures are the logs. Re-running the README's
grep -E "$pat"over the eight ticket logs in~/wt/mtp-window/(ticket-tau06-p{0..7}-try1-20261106-{164254,165612,170407,172013,172718,173228,174605,175540}.log) reproducestests/fixtures/mtp_tau06/p0..p7.txtbyte-identically, 8/8 (cmp). - Text identity: all 8 logs say
TEXT IDENTICAL, 64 tokens … 0 mismatch. The determinism control holds: p0 at 16:29 and 16:42 both readaccepted 31/35, passes/token 1.016, with depth 187.50 % (28/32)both times. - "amdxdna errors 0 in every arm" holds. Each log's header carries the boot-cumulative counter, which steps 105 → 114 between p2 (17:04) and p3 (17:20).
journalctl -kputs those 9 at 17:12:43-44, after p2's run ended and before p3's ticket. All 8 logs report[array] amdxdna ERROR lines during the run: 0 (during the queue wait, NOT ours: 0).
The numbers
tools/mtp_depth_pool.py tests/fixtures/mtp_tau06/*.txtreproduces the body exactly: 277 iterations, 292 offered, 230 accepted. Depth 1 is 78.34 % (217/277), depth 2 3.97 % (11/277), depth 3 0.72 % (2/277), depth 4 never offered. Hit rate 78.77 %, tokens/pass live 1.83 (1 + 230/277) and offline 2.05 (1 + 291/277).- They are internally consistent: 217+11+2 = 230, and 277+13+2 = 292. The 0.81× slowdown is 0.849/1.049.
tests/mtp_depth_pool_test.py→all checks passed. Red arm, mine: the hit-rate record edited to 78.78 →1 CHECK(S) FAILED; restored → green. So the six records are tied to the fixtures, not typed in.tools/npu_leaderboard.py --check→27 record(s) valid. Regenerating the docs leaves the tree clean.copyright.py --checkrc 0.
Nit, not blocking: EXEMPT widens from tests/fixtures/mtp_clause55/*.txt to tests/fixtures/*/*.txt, and fnmatch's * also crosses /. Today it newly exempts exactly the 8 tau06 tickets (fflm/ has no .txt). But any future hand-written .txt under tests/fixtures/ will skip the notice check silently. A name convention for extracted tickets would keep the "by kind" intent without the blanket glob, for example tests/fixtures/mtp_*/p*.txt, or a *.ticket.txt suffix.
refs #805 and not Fixes is right: leaf fill and the P5 Hexagon rows remain, as the body says.
The last unmeasured row of #805 (plan P6):
Options::taudefaults to 0.6 (npu/mtp/draft.h:162), so that is what a serve drivingmtp::run()gets without asking — and every acceptance row published before this one was attau = 0.The window
8 prompts × 64 tokens,
k = 4,tau = 0.6,--live --match, one prompt pernpu-holdticket (2026-11-06 16:42–18:06 AST, array exclusive,amdxdnaerrors 0 in every arm). Greedy text was byte-identical to plain decode on 8 of 8 prompts with 0 stream mismatches, and prompt 0 was measured twice (16:29 and 16:42, both31/35) as the determinism control.Measured — all chains, 277 chain iterations, 292 drafts offered
tau = 0tau = 0.6(default)The gate does what it was asked to do and still loses. The drafts it keeps are far better (78.8 % against 46.7 % hit rate; depth 1 is identical to the offline protocol at the same positions, +0.00 pp), but it almost never chains — ~1.05 drafts per chain against 4.0 — so the chain collapses from 2.87 to 1.83 tokens/pass, below the measured 3.2–4.1 break-even. At the default the draft route is a slowdown: 0.81× on the prompt-0 pair (plain 0.849 s/token, draft 1.049 s/token). The conditional per-depth comparison reads +27 and +47 pp at depths 2–3 on 13 and 2 live chains — sampling noise, which is why the all-chains view is published and depth 1 is the only comparable cell at this tau.
Contents
tests/fixtures/mtp_tau06/— the eight tickets, extracted verbatim with the samegrepthemtp_clause55README documents (which re-extracts those three fixtures byte-identically), each carrying its own== 8 prompts x 64 tokens, k=4 tau=0.60, hidden=post-normidentity line.bench/npu-leaderboard/27b-mtp-tau06-*.json— six records, generated from the pool tool's own output rather than typed (depth 1/2/3 all-chains acceptance, hit rate, live and offline tokens per pass).tests/mtp_depth_pool_test.py— the records guard gains the tau=0.6 window, so these six rows are re-derived from the fixtures on every CI run.docs/npu.md— the table above, the break-even consequence, and why the 2 pp per-depth clause is a depth-1 clause at this tau.Verified
refs #805 — the protocol's measurable gate rows are now all published at both taus; what remains on that issue is leaf fill (needs per-row positions/attention in the forward, i.e. a kernel-side change on top of P4) and the Hexagon target rows (P5, #804).