Dump what the router thought of the experts that lost, not only the winners - #45
Conversation
…inners
WASTE_DUMP_ROUTE records the top-K ids and their weights, which answers
every question about the ranking the router actually made. It answers none
about a ranking it did not.
That gap is load-bearing. A residency prior promotes an expert the real
router left just outside the top-K; a dynamic-k rule needs to know how far
the k+1th sat behind the kth; a pruning criterion needs the scores of the
experts it is proposing to delete. All three are questions about the
losers, and a trace of the chosen cannot say which one, or by how much.
So WASTE_DUMP_SCORES=path appends the whole vector:
pos L v0 v1 .. v(E-1)
`score[e] + bias[e]`, the quantity the selection loop ranks on -- not
`w[j]`, which is the weight applied afterwards and takes `score[best]`
without the bias. Getting that distinction wrong would make every offline
re-ranking experiment quietly disagree with the engine.
The reasoning is the one already written above WASTE_DUMP_ROUTE -- "is the
signal there", and cheaper from a trace than from a build -- and so are the
economics: one fprintf against a rebuild plus a sweep. It is the same shape
of instrument, one field wider.
Unset it costs a null check per layer and writes nothing. `make check` is
44 passed / 0 failed / 13 skipped, unchanged.
Verified on Kimi-Linear: 3 tokens x 26 MoE layers wrote 78 lines of 258
fields (pos, layer, 256 experts).
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01B5eVMiauR4Lkt8Dhc67MNb
|
Merged. Exercised here rather than taken on the description, since the value of The detail you flagged for review is the one that matters, and it is right. The argument for the shape is also the one this project already accepts: the Offering it separately from the experiment it was built for was the right |
Almost none of this is the engine. It is Windows, real containers, and the four feasibility gates that were still open, and most of it was found by people running hardware this project does not own. GATES.md has no open gate for the first time, and two of the three that closed this cycle closed against the change they were proposing. No ABI move: src/waste.h changed only in a comment this cycle, unlike 0.6.8. waste_kernels gained vq_rows_p6 but that lives in src/waste_backend.h and is not public. Added: the VQ4P apply behind a dispatch slot with an AVX-512 VBMI kernel beside it (#41), bit-identical on ARM against a real index_bits 6 container and still never executed on any machine here; WASTE_DUMP_SCORES (#45) and WASTE_CCR_LAMBDA (#46); the working set printed by `waste plan`, which was quoted by the line below it and never shown; and a test for the fp8 block-scale mapping whose only stub had replaced it with the identity (#40). Fixed: the five gaps of #36 and the two that survived the first attempt — VirtualLock bounded by the minimum working set rather than the maximum, so WASTE_MLOCK wired nothing on Windows twice over; diskbench truncating its offset through a 32-bit off_t at its own default file size, where the quiet half read the wrong place successfully and kept the working set inside an SSD's SLC cache; container JSON through Python text mode, which made the same conversion produce byte-different containers on Windows; a missing cmp reporting `expert cache changes results` on a clean checkout (#42); plus #35, #30, and the CLI help that said one thread per core when it is one per logical CPU (#44). Recorded as measured and not adopted, which is the half of this file that is easy to drop: the budget resolver's quantum stands after Gate 7 (§63); cache-conditional routing stays a knob because it clears README's KL bar and not its continuation bar; the thread default did not move despite 16 threads measuring 1.6x below the plateau; no budget policy fixes two K3 opens on 64 GB (§64, #31 closed, #49 opened for the residue); and VQ4P is not a throughput upgrade over VQ3R on a GB10 despite complete and exact CUDA coverage (§62). 53 passed, 0 failed, 6 skipped against Kimi-Linear and K3.
WASTE_DUMP_ROUTErecords the top-K ids and their weights. That answers every question about the ranking the router made, and none about a ranking it did not.That gap turns out to be load-bearing. A residency prior promotes an expert the real router left just outside the top-K. A dynamic-k rule needs to know how far the k+1th sat behind the kth. A pruning criterion needs the scores of the experts it proposes to delete. All three are questions about the losers, and a trace of the chosen cannot say which one, or by how much.
So
WASTE_DUMP_SCORES=pathappends the whole vector, one line per (token, layer):Evidence
Same container, same prompt, same flags; before is the merge-base built in a sibling worktree.
3 generated tokens × 26 MoE layers → 78 lines of 258 fields (pos, layer, 256 experts).
The one detail worth checking in review
It dumps
score[e] + bias[e]— the quantity the selection loop ranks on — and notw[j], which takesscore[best]without the bias and is applied after the choice is made.Those differ, and getting it backwards would make every offline re-ranking experiment quietly disagree with the engine while looking correct. It is the sort of thing that produces a confident wrong answer rather than an obvious one, so it seemed worth saying out loud in the comment as well as here.
Cost
Unset: one null check per layer, nothing written.
make checkis 44 passed / 0 failed / 13 skipped, unchanged from the merge-base on this machine (Windows 11 / Ryzen 7 3700X / MSYS2 UCRT64 / gcc 16.2.0).Set: one
fprintfper (token, layer), same shape as theWASTE_DUMP_ROUTEblock it sits beside. 200 tokens × 26 layers × 256 experts came to about 7.8 MB.Why this shape
The reasoning is the one already written above
WASTE_DUMP_ROUTE— "Both questions are 'is the signal there', and both are cheaper to answer from a trace than from a build" — and so are the economics: onefprintfagainst a rebuild plus a sweep. This is the same instrument, one field wider.I wanted it for a specific question (does preferring cache-resident experts buy anything the router lookahead has not already collected — arXiv:2412.00099), but the dump is not specific to that, which is why it is offered on its own rather than bundled with the experiment. The experiment may not survive;
docs/LEARNED.md§54's "what routing buys is not which experts exist … it is the per-token exclusion" is a strong prior against anything that edits the selection, and I have not yet cleared the continuation bar the README holdsnum_experts_per_tokento. The trace was worth having either way, and would be worth having to anyone testing a dynamic-k or a pruning criterion.Context
From standing up a native Windows x86 measurement box for #37/#38 work. Companions on the same machine: #42, #43, #44.
🤖 Generated with Claude Code
https://claude.ai/code/session_01B5eVMiauR4Lkt8Dhc67MNb