Repository navigation
bench(decode): root-cause prompt-lookup non-losslessness (M=K verify near-tie fp noise) + verify_logits_probe - #935
Merged
Conversation
Root-causes PR #932 finding 2 (M=K verify argmax != M=1 greedy argmax) as near-tie floating-point noise in the eager M=K verify's in-block attention/KV numerics -- not a bug, not a systematic offset. Adds a bench-only diagnostic bin (no engine change) that replays greedy M=1 decode on the native CUDA captured path, then re-runs the same greedy continuation as an M=K draft through decode_verify so each verify row has mathematically identical causal inputs to the M=1 forward. Any logit delta is therefore pure kernel numerics. Findings (qwen2.5-0.5b-int4, CUDA, GPU6): - K=1 verify is argmax-identical to M=1 (0 flips). Eager-vs-captured dispatch is not the cause. - Flips occur only at in-block rows >=1 (first flip = last row of the block), count scales ~linearly with K, and only at near-ties (greedy top1-top2 gap <= ~0.17, min 0.014). mean|delta| ~0.07, top-5 sets essentially identical. - Localized to in-block draft K/V computed inside the batched M=K GEMM vs the same positions read from persistent KV in the sequential M=1 path (fp non-associativity). Implication: exact/lossless prompt-lookup is not achievable with a distinct M=K kernel; either accept approximate output or add a near-tie guard (re-decode low-gap positions via M=1). Same limitation applies to EAGLE-3/MTP verify. Full analysis: .squad/decisions/inbox/deckard-verify-rootcause.md Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #935 +/- ##
==========================================
- Coverage 78.51% 77.81% -0.71%
==========================================
Files 352 354 +2
Lines 145983 148153 +2170
Branches 145983 148153 +2170
==========================================
+ Hits 114622 115287 +665
- Misses 26873 28372 +1499
- Partials 4488 4494 +6
Flags with carried forward coverage won't be shown. Click here to find out more. 🚀 New features to boost your workflow:
|
🔴 Benchmark Regression DetectedComparison of criterion micro-benchmarks: PR head vs merge-base, measured on the same runner in the same job (base first → PR second).
Visual flags: Host infoWhat this cannot catch
|
justinchuby
added a commit
that referenced
this pull request
Aug 14, 2026
…re-stable verify (B) first (#938) Design-only feasibility scoping (mirrors the TP feasibility doc #933) of the two remaining multi-week decode levers, after the three cheap ones were closed this week (#928 kernel +2.7% capped, #933 TP NO-GO for speed, #932/#935/spec-14b eager-M=K speculative KILL). **Recommendation: build Lever B (capture-stable padded M=K verify graph) first**, gated on a cheap Phase-0 capture-stability probe. B attacks the actual dispatch binding and — because a captured M=K replay reads weights once (weight-DRAM is per-token, not per-M) — amortizes both dispatch and weight-read over K tokens (floor ~1.0x, ceiling ~2-3x), reuses existing frozen-bucket capture machinery, and unlocks prompt-lookup + EAGLE-3/MTP from one build. Lever A (Marlin int4 relayout) is the unconditional ~1.3-1.6x Amdahl-capped fallback. Docs + decision drop only; no code. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Root-causes PR #932 finding 2 (M=K verify argmax ≠ M=1 greedy argmax). Verdict: near-tie floating-point noise in the eager M=K verify's in-block attention/KV numerics — not a bug, not a systematic offset. Adds a reusable bench-only diagnostic bin (
verify_logits_probe); no engine change.GPU:
CUDA_VISIBLE_DEVICES=6(verified idle). Model:qwen2.5-0.5b-int4.Method (controlled)
Replay greedy M=1 decode on the native CUDA captured hot path, recording per-position logits; then re-run the same greedy continuation as the M=K draft through
decode_verify, so each verify row has mathematically identical causal inputs to the corresponding M=1 forward. Any logit delta is therefore pure kernel numerics.Evidence
First divergence (prose), output index 27, K-block P=24 row 3:
Discriminating K-sweep (prose, 64 tokens):
Classification: (1) near-tie fp noise
run_cuda_eager_rows.Implication
Byte-lossless prompt-lookup is not achievable with a distinct M=K kernel: every committed position
> baseis decided by an in-block M=K row that isn't bit-exact. Routing just the last position through M=1 does not suffice (any row ≥1 can diverge; the bonus token also comes from an M=K row). Options:Not a one-line fix → no fix in this PR (design decision for the speculative owner). This PR lands only the diagnostic tool + analysis.
EAGLE-3 / MTP
They reuse the same eager M=K
decode_verify, so they inherit the identical near-tie in-block divergence. Not a correctness bug for them (approximate by nature), but any "exact/lossless" guarantee would not hold, and the same near-tie guard would be needed for byte-exactness.Notes / validation
verify_logits_probeis bench-only (new[[bin]],required-features=["bench-native"]).NativeDecodeSession::load_with_resolved_ioneedsONNX_GENAI_CUDA_KV_MAX_LENfor model dirs withgenai_config.jsonbut noinference_metadata.yaml(else "full CUDA mask reservation size overflow").cargo fmt --all -- --checkclean;cargo clippy -p onnx-genai-bench --features bench-native,cuda --bin verify_logits_probeclean.Full analysis:
.squad/decisions/inbox/deckard-verify-rootcause.md.Co-authored-by: Copilot 223556219+Copilot@users.noreply.github.com