Repository navigation
Conversation
…ecay dspark.yaml and domino.yaml set dflash_loss_decay_factor: 7.0 without an objective. DSpark and Domino ignore dflash_loss_objective today and always decay; once they honor it, the default 'dpace' would switch both recipes to D-PACE and drop the decay factor they were tuned with. Pin dflash_loss_objective: decay in both, and list it among the knobs the Qwen3-8B Domino launcher repeats for visibility, as the LiLiCorr launcher does. The DSpark launchers (Kimi-K2.6, MiniMax-M3) inherit the pin from dspark.yaml. No behavior change at this commit. Verified that both recipes load through ModelOptDFlashRecipe with objective 'decay' and decay factor 7.0; pre-commit's recipe and launcher-reference validators pass. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: h-guo18 <67671475+h-guo18@users.noreply.github.com>
…objective DSpark and Domino overrode the shared forward's _position_weighting hook to return "decay", so dflash_loss_objective, whose default is "dpace", had no effect on them, and DFlashModel.modify's warning that the decay factor is ignored under D-PACE was false for both. They now follow the objective like the rest of the family, from their first predicted block position, 0. D-PACE reads the draft's confidence off the served (final) logits, and that one set of weights reduces every term of the step: DSpark's CE, TVD and confidence BCE, and both of Domino's objectives, final and backbone. With no override left, the hook goes and _loss_context reads dflash_loss_objective directly. The new test pins, for both variants and both objectives, the weights handed to the loss to _block_position_weights from position 0 on the final logits, and the reported CE (DSpark) and backbone CE (Domino) to their reduction under those weights. It fails on the parent for D-PACE, and it fails when the confidence is read off the backbone, when the first position is 1, and when Domino's backbone CE gets its own D-PACE weights. Verified against the parent with one training and one generation step per case, in fp32 and bf16. The 23 existing cases (every variant, offline and online, decay and D-PACE, zero-loss steps included) are bitwise equal in loss, gradients, metrics and generated tokens. The five new DSpark/Domino D-PACE training cases change loss and gradients, as intended, generate the same tokens, and equal bitwise the parent with the two overrides deleted at runtime; their two zero-loss cases are unchanged. The DFlash-family plugin tests and the recipe loader tests pass on transformers 5.5 and 5.18 (806, the 4 new cases included), the GPU plugin tests pass, and the FSDP2 DFlash probes pass on both ranks. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: h-guo18 <67671475+h-guo18@users.noreply.github.com>
…ective Users of a released DSpark or Domino who leave dflash_loss_objective unset move from the static decay to D-PACE, so the changelog lists it under backward breaking changes with the one-line way back. That way back does not reach a run resumed across the upgrade: its checkpoint stores the default 'dpace' the old code ignored, and main.py's HF-format resume restores it without re-reading the recipe, so the run continues with D-PACE. The entry says to finish such runs on the version that started them, and the DSpark and Domino skill sheets key the case on the warning the restore logs. The sheets also list the pinned static decay among the recipes' deltas from DFlash. Verified with pre-commit (rst, markdownlint, skill symlink sync), and by resuming DSpark and Domino checkpoints through main.py's HF-format loader: saved from the branch base's shipped recipes, they restore 'dpace' and weight the next step with the static decay on that base but with D-PACE here; saved from the pinned recipes, they restore 'decay' and keep it. 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 24, 2026
Draft
This branch has not been deployed
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.
What does this PR do?
Type of change: New feature. It changes the default weighting for DSpark and Domino configs that leave
dflash_loss_objectiveunset, and for runs resumed from checkpoints saved before it.This PR is stacked on #2990 [2/2] (branch
haoguo/dflash-shared-forward, which gives the DFlash family one training forward), whose branch is its base; review and merge it after that one. The stack below is #2757 → #2762 → #2989 [1/2] → #2990 [2/2]. Three other PRs also sit on #2990 and are independent of this one: loggingdraft_metricsin the trainer (#2992), loss terms in config (#2993), and the shared AR-decode helper (#2994).Since they were added in 0.46.0, DSpark and Domino have ignored
dflash_loss_objective. They always weighted block positions with the staticdflash_loss_decay_factordecay, while DFlash, DFlash2 and LiLiCorr follow the objective, whose default isdpace. On the shared forward this came down to one override per variant:_position_weightingreturning"decay". MeanwhileDFlashModel.modifywarned that the decay factor is ignored under D-PACE, which was false for these two._position_weightinghook, since nothing else overrode it;_loss_contextnow readsdflash_loss_objectivedirectly.1 - _label_shift).dspark.yamlanddomino.yamlsetdflash_loss_decay_factor: 7.0without an objective, so they would have switched to D-PACE.dflash_loss_objective: decay. That commit lands first, so every commit trains them the same.dspark.yaml.Behavior change:
dflash_loss_objectiveunset now trains with D-PACE and ignoresdflash_loss_decay_factor, as the existing warning says.dpacenow gets it.decay.modelopt_stateholds the defaultdpace, which the old code ignored.main.pyresumes an HF-format checkpoint, the format DDP writes and the shipped DSpark and Domino recipes use, by restoring that saved config. It never re-reads the recipe, so the new pin does not reach the run.dflash_loss_decay_factor=7.0is ignored" warning, which these recipes already printed, wrongly, before this change.Usage
On top of the shipped recipes:
dflash.dflash_loss_objective=dpace.Testing
New test.
test_next_token_variants_weight_positions_by_the_objective[dspark|domino-dpace|decay]runs the real training forward and checks, bitwise:_block_position_weights(mask, objective, 0, ...)computed from the final logits' cross-entropy;loss_ceand Domino'sloss_backboneequal their cross-entropy reduced under those weights.It fails on the base for both D-PACE cases, which got decay weights. In scratch runs it also fails when the confidence is read off the backbone, when the first weighted position is 1, and when Domino's backbone objective gets D-PACE weights of its own. Each case takes at most 0.13 s on 4 CPUs (
taskset -c 0-3).Unit tests. The test files this PR changes or exercises, on CPU:
test_hf_dflash.py,test_hf_dflash2.py,test_hf_dspark.py,test_hf_domino.py,test_hf_lilicorr.pyandtest_hf_dflash_offline.pyundertests/unit/torch/speculative/plugins, andtests/unit/recipe/test_loader.py. 806 passed on each of transformers 5.5.4 and 5.18.0, CI'stf_minandtf_latestpins (802 on the base; the other 4 are the new test's cases).GPU tests.
tests/gpu/torch/speculative/pluginson 1 GPU: 20 passed, 1 skipped (that test needs 2 GPUs), as on the base.Bitwise A/B against the base. One training step per case, plus generation at
steps0, 2 and 4 for the online cases, in fp32 and bf16. Compared: loss, every gradient,train_acc, everydraft_metricsvalue and the generated tokens.decayobjective are among them.loss_ce,loss_tvdandconfidence_losschange, as do Domino'sloss_finalandloss_backbone. The generated tokens are identical.Resume across the change, on transformers 5.5.4 and 5.18.0. Tiny DSpark and Domino models were converted from each tree's shipped recipe and saved with
save_pretrained. Each was then loaded the waymain.pyresumes an HF-format checkpoint (load_vlm_or_llmunderpatch_transformers5_params_loading, thenrestore_draft_precision) and run for one training step.dflash_loss_objective: dpacewith decay factor 7.0. Resumed on the base, the step's position weights equal the static decay. Resumed here, they equal the D-PACE weights, and the restore logs the decay-factor warning.decay, and the step uses the static decay.FSDP2 probe (2 gloo ranks, the draft as its own
fully_shardunit, one rank on the zero-loss branch).Recipes and pre-commit. Both recipes load through
ModelOptDFlashRecipewith objectivedecayand decay factor 7.0. The launcher's example-resolution tests pass (75).pre-commit run --files <changed files>is clean.Before your PR is "Ready for review"
Make sure you read and follow Contributor guidelines and your commits are signed (
git commit -s -S).Make sure you read and follow the Security Best Practices (e.g. avoiding hardcoded
trust_remote_code=True,torch.load(..., weights_only=False),pickle, etc.).dflash_loss_objectiveunset now train with D-PACE. Setdflash_loss_objective: decayto keep the previous weighting, as the shipped recipes now do. A run resumed from a checkpoint saved before this change restores that checkpoint's objective (dpaceunless it was set) instead of the recipe's, so it switches to D-PACE; finish such runs on the version that started them. Checkpoints still load, and export and generation are unaffected.CONTRIBUTING.md: N/AAdditional Information
draft_metrics, feat(speculative): DFlash-family loss terms in config; one teacher with an opt-in softcap #2993 loss terms in config, refactor(speculative): draft DSpark and Domino through one AR-validation loop #2994 the shared AR-decode helper) do not depend on this one.CHANGELOG.rst,hf_dflash.py,hf_dspark.py,hf_domino.py,dspark.yamlanddomino.yaml. Whichever merges second has to be rebased on the other. It merges cleanly with thedraft_metricslogging PR (feat(speculative): log the DFlash family's draft_metrics from the example trainer #2992) and the AR-decode helper (refactor(speculative): draft DSpark and Domino through one AR-validation loop #2994).decaywould need to know which checkpoints predate this change, and nothing marks them reliably:dpacefrom a chosen one;dflash_loss_objective: dpaceand no decay factor. Until now it trained with uniform position weights. It now trains with D-PACE, as it states, and a run of it resumed across the change switches too. That switch logs no warning, since the recipe sets no decay factor. The recipe is left unpinned because it names an objective. Pindecaythere if its fine-tune should keep the old weighting.🤖 Generated with Claude Code