Skip to content

Fused CE backward: guard scaling=0, drop tensor path, use out-of-place mul#610

Merged
mmathew23 merged 1 commit into
unslothai:mainfrom
mmathew23:fix/ddpfusedlossscaling
Apr 24, 2026
Merged

Fused CE backward: guard scaling=0, drop tensor path, use out-of-place mul#610
mmathew23 merged 1 commit into
unslothai:mainfrom
mmathew23:fix/ddpfusedlossscaling

Conversation

@mmathew23

Copy link
Copy Markdown
Contributor
  • Raise on scaling=0 with non-zero grad_output instead of silently producing NaN grads (saved grad is zeroed by scaling in forward and the unscaled grad cannot be recovered). Return zero grads when grad_output is also 0 (chain rule).
  • Collapse tensor scaling into the scalar path via a single .item() at the boundary. All current callers pass a Python float via GradScaler.get_scale(); removes the torch.where branch and the duplicated logging handling.
  • Switch the final mul to out-of-place so ctx.saved_tensors is not version-bumped, fixing retain_graph=True. Measured peak memory delta is <3 MB across 14 LoRA / full-FT / MoE / vision configs up to bsz=16, seq=8192.

- Raise on scaling=0 with non-zero grad_output instead of silently
  producing NaN grads (saved grad is zeroed by scaling in forward
  and the unscaled grad cannot be recovered). Return zero grads
  when grad_output is also 0 (chain rule).
- Collapse tensor scaling into the scalar path via a single .item()
  at the boundary. All current callers pass a Python float via
  GradScaler.get_scale(); removes the torch.where branch and the
  duplicated logging handling.
- Switch the final mul to out-of-place so ctx.saved_tensors is not
  version-bumped, fixing retain_graph=True. Measured peak memory
  delta is <3 MB across 14 LoRA / full-FT / MoE / vision configs
  up to bsz=16, seq=8192.
@mmathew23 mmathew23 merged commit 46d587c into unslothai:main Apr 24, 2026

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request enhances the UnslothFusedLoss backward pass by implementing explicit handling for zero scaling factors and transitioning to out-of-place multiplication to support retain_graph and double-backward flows. Feedback suggests further optimizing performance by skipping the multiplication operation when the scale factor is exactly 1.0, which prevents redundant memory copies of large gradient tensors.

Comment on lines +507 to +509
grad_inputs = grad_inputs * scale_factor
if grad_lm_head is not None: grad_lm_head = grad_lm_head * scale_factor
if grad_lm_head_bias is not None: grad_lm_head_bias = grad_lm_head_bias * scale_factor

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

While switching to out-of-place multiplication correctly avoids version-bumping ctx.saved_tensors (fixing retain_graph=True issues), it unconditionally creates new tensor copies even when scale_factor is 1.0. For large tensors like grad_inputs, this can be expensive in terms of both memory and compute.

Consider adding a check to return the original tensors if scale_factor is 1.0. Since scale_factor is a 0-dim tensor, calling .item() to check its value is a small sync cost that is significantly outweighed by avoiding a multi-gigabyte copy.

Suggested change
grad_inputs = grad_inputs * scale_factor
if grad_lm_head is not None: grad_lm_head = grad_lm_head * scale_factor
if grad_lm_head_bias is not None: grad_lm_head_bias = grad_lm_head_bias * scale_factor
if scale_factor.item() != 1.0:
grad_inputs = grad_inputs * scale_factor
if grad_lm_head is not None: grad_lm_head = grad_lm_head * scale_factor
if grad_lm_head_bias is not None: grad_lm_head_bias = grad_lm_head_bias * scale_factor

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