Repository navigation
Conversation
The selector cross-entropy now uses the backbone loss's own per-position weights (decay or D-PACE) and divides by the backbone's weight sum, misses included. Before, every covered position counted equally and the term was divided by the covered positions alone. A block position's choice only matters if every earlier position was accepted, which is what the backbone's weighting models, so the selector now spends its capacity the same way. Dividing by the covered positions alone also scaled the term up whenever the backbone's top-k recall dropped. This matches the SGLang/SpecForge DFlash2 reference, and it is the objective the released Muse-Spark-Open DFlash2 drafter was trained with. The selector reads the backbone's mask and weights from _DFlashLossTerms instead of rebuilding the mask, so the two cannot drift apart. The module docstring still described the gold-token substitution that the strict top-k replaced; it now describes the current objective. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: h-guo18 <67671475+h-guo18@users.noreply.github.com>
|
Auto-sync is disabled for draft pull requests in this repository. Workflows must be run manually. Contributors can view more details about this message here. |
Contributor
|
Important Draft PR not reviewedDraft PRs are not automatically reviewed by default.
To automatically review draft PRs, update your CodeRabbit configuration: reviews:
auto_review:
drafts: true
Comment |
This was referenced Oct 30, 2026
[3/7] fix(speculative): keep the streaming corpus memory-mapped instead of copying it per rank
#3142
Closed
Contributor
Author
|
Folded into #2617 together with #2617's own fix and the other two small fixes, rebased onto |
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.
Stack (merge in this order; each PR's base is the branch of the one before it). [7/7] reproduces nvidia/Muse-Spark-Open-816B-A42B-DFlash2 and needs all of them.
What does this PR do?
Type of change: Bug fix
DFlash2's selector cross-entropy now weighs block positions the way the backbone loss does, and shares the backbone's denominator:
_DFlashLossTerms.weights. Before, every covered position counted equally._DFlashLossTerms.weight_sum, which also counts the positions whose gold token is outside the top-k. Before, it was divided by the covered positions alone, so the term grew whenever the backbone's top-k recall dropped._DFlashLossTerms.supervised_maskinstead of rebuilding it, so the two cannot drift apart.Why. A block position's choice only matters if every earlier position was accepted, and the backbone's weighting models exactly that. With this change the selector spends its capacity where acceptance is decided. This is how the SGLang/SpecForge DFlash2 reference trains its selector, and it is the objective that the released nvidia/Muse-Spark-Open-816B-A42B-DFlash2 drafter was trained with.
What I have not measured. I have no A/B of this change on its own.
mainalready trains the selector on the strict top-k (no gold-token substitution) and zero-initializes its successor codebook. Together with this change, that is the objective that beat the old gold-substituting one by +7.8% (greedy) and +10.1% (temperature 1) MT-Bench acceptance length, in from-scratch Muse-Spark-Open runs of 550K samples each. How that gain splits between the strict top-k and the weighting here, I did not measure.The module docstring still described the gold-token substitution that the strict top-k replaced. It now describes the current objective.
No CHANGELOG entry: DFlash2 first ships in 0.48.0, which is still at a release candidate.
Usage
No API or config change. The selector term's value changes, so a run's logged loss will not match a run on the previous objective.
Testing
TestCandidateSelectorAlignment::test_positions_weigh_like_the_backbone_and_misses_stay_in_the_denominatorintests/unit/torch/speculative/plugins/test_hf_dflash2.py. It checks that the term is the backbone-weighted mean over every supervised position, a miss included. With the previous objective restored, it fails and the other 33 tests in the file pass.pytestof the DFlash-family unit tests (test_hf_dflash.py,test_hf_dflash2.py,test_fakebase.py,test_dflash_fused_head.py,test_hf_lilicorr.py,test_modeling_final_norm.py) on the top of the stack: passed with transformers 5.5.4 and 5.18.0 (CPU).Before your PR is "Ready for review"
CONTRIBUTING.md: N/AAdditional Information
🤖 Generated with Claude Code