Found while landing SPEC-DFLASH2 W11 (#1890), by mutation rather than by reading.
tests/vllm/v1/spec_decode/dflash2_runner_fixture.h drives the production DFlash2 runner and RunAndCollectDrafts returns the drafted blocks off the VT_SPEC_TRACE line. Every one of the eight steps drafts the same three tokens:
threw=[] n=8
[0] 19 19 19
[1] 19 19 19
[2] 19 19 19
[3] 19 19 19
[4] 19 19 19
[5] 19 19 19
[6] 19 19 19
[7] 19 19 19
Measured on main @ 1724be38e + the W11 branch, Release, CPU, with a one-off probe that printed what DraftedBlocks returns.
Consequence. Any case that compares two arms by these strings compares one constant against another, so it cannot see a numerics change in the draft forward. Three mutations of the W11 draft-block attention, each a genuinely WRONG attention, left the comparison green:
| mutation |
what it breaks |
drafted-token comparison |
| force the layer mask causal when the layer is non-causal |
the whole block mask |
green |
| neutralise the paged K/V write before the read |
the draft attends over unwritten pool slots |
green |
hand the read the store's seq_lens instead of the extended bound |
every block row silently dropped |
green |
The byte-for-byte op-level gate W11 added (test_qwen3_dflash_block_route) reds on all of them, which is how the degeneracy was located.
This is not only a W11 concern. dflash2 runner (W8): the paged lane and the materialized lane draft identically compares the same constants, so its stated guarantee — that two attention lanes agree — is not measured by it either. The W9/W10 cases assert counters and trace presence rather than token values and are unaffected.
Not the D9-scalars case. dflash2 runner: D9's SCALARS move the drafted tokens, in production DOES observe a difference, so the fixture is not degenerate under every perturbation — only under changes that move the block logits by less than whatever separates token 19 from its runner-up.
What a fix looks like: make the synthetic draft weights produce a non-constant argmax across the block (a wider draft vocab, or weights whose per-position logits actually separate), and then re-state the W8 and W11 comparisons as the numerics gates they are meant to be. It has to be done without disturbing the W3/W4/W9/W10 cases that read the same fixture.
NOT FIXED IN FLOW: changing the fixture's weights moves five landed cases at once and needs its own red-before evidence, which is a different unit of work from #1890. Owned by row SPEC-DFLASH2 and listed under ## Owed in dflash2-draft-block-fa2.md.
Found while landing SPEC-DFLASH2 W11 (#1890), by mutation rather than by reading.
tests/vllm/v1/spec_decode/dflash2_runner_fixture.hdrives the production DFlash2 runner andRunAndCollectDraftsreturns the drafted blocks off theVT_SPEC_TRACEline. Every one of the eight steps drafts the same three tokens:Measured on
main@1724be38e+ the W11 branch, Release, CPU, with a one-off probe that printed whatDraftedBlocksreturns.Consequence. Any case that compares two arms by these strings compares one constant against another, so it cannot see a numerics change in the draft forward. Three mutations of the W11 draft-block attention, each a genuinely WRONG attention, left the comparison green:
seq_lensinstead of the extended boundThe byte-for-byte op-level gate W11 added (
test_qwen3_dflash_block_route) reds on all of them, which is how the degeneracy was located.This is not only a W11 concern.
dflash2 runner (W8): the paged lane and the materialized lane draft identicallycompares the same constants, so its stated guarantee — that two attention lanes agree — is not measured by it either. The W9/W10 cases assert counters and trace presence rather than token values and are unaffected.Not the D9-scalars case.
dflash2 runner: D9's SCALARS move the drafted tokens, in productionDOES observe a difference, so the fixture is not degenerate under every perturbation — only under changes that move the block logits by less than whatever separates token 19 from its runner-up.What a fix looks like: make the synthetic draft weights produce a non-constant argmax across the block (a wider draft vocab, or weights whose per-position logits actually separate), and then re-state the W8 and W11 comparisons as the numerics gates they are meant to be. It has to be done without disturbing the W3/W4/W9/W10 cases that read the same fixture.
NOT FIXED IN FLOW: changing the fixture's weights moves five landed cases at once and needs its own red-before evidence, which is a different unit of work from #1890. Owned by row
SPEC-DFLASH2and listed under## Owedindflash2-draft-block-fa2.md.