Skip to content

[DFlash/DSpark] Optional direct-acceptance (LK) loss#58

Open
zhangwenhe1007 wants to merge 1 commit into
deepseek-ai:mainfrom
zhangwenhe1007:dflash-direct-acceptance-loss
Open

[DFlash/DSpark] Optional direct-acceptance (LK) loss#58
zhangwenhe1007 wants to merge 1 commit into
deepseek-ai:mainfrom
zhangwenhe1007:dflash-direct-acceptance-loss

Conversation

@zhangwenhe1007

@zhangwenhe1007 zhangwenhe1007 commented Jul 8, 2026

Copy link
Copy Markdown

Current drafters train on per-token cross-entropy, but the quantity that actually determines the speedup is the acceptance length. The repo already computes the expected acceptance length (E[tau] = 1 + sum_k prod_{j<=k} alpha_j) and logs it as the tau_probabilistic metric, but it sits under torch.no_grad() so it's never optimized. This PR makes it an optional loss, such that you can train the drafter to maximize acceptance directly instead of only through the CE proxy.

It's gated behind accept_loss_alpha (default 0.0), so existing configs are untouched. The term is just the negative expected accepted length, differentiable through the per-position acceptance rate, and it needs aligned_target_logits (same as the L1 and confidence terms).

Files:

  • deepspec/modeling/dspark/loss.py: the accept_loss term
  • deepspec/trainer/dspark_trainer.py: read accept_loss_alpha from the config (getattr default 0.0)
  • config/dflash/dflash_qwen3_8b.py: the knob, documented
  • scripts/test_accept_loss.py: a small CPU test

The test runs on CPU with no model and verifies three things: accept_loss_alpha=0 gives the exact same loss as before, the term is differentiable (gradient reaches the draft logits), and it rewards a draft that matches the target (the loss goes to -4.0 when all four block positions accept with probability 1).

In my own DFlash runs, a direct acceptance loss like the one in this PR improved position-1 acceptance by about 6% over CE at matched data.

Adds a differentiable direct-acceptance objective that trains the drafter to
maximise expected accepted length E[tau]=sum_k prod_{j<=k} alpha_j directly,
instead of only the per-token cross-entropy proxy. It makes the acceptance
quantity already logged as the tau_probabilistic metric trainable.

- deepspec/modeling/dspark/loss.py: accept_loss term (gated on accept_loss_alpha>0)
- deepspec/trainer/dspark_trainer.py: wire accept_loss_alpha (getattr default 0.0)
- config/dflash/dflash_qwen3_8b.py: documented accept_loss_alpha knob (default 0.0)
- scripts/test_accept_loss.py: CPU unit test (zero-regression, differentiable, rewards matching)

Implementation prepared with AI assistance.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant