Skip to content

[Loss] Split logging loss from backward loss#1962

Closed
HAOCHENYE wants to merge 1 commit into
reduce-sum-01-fsdp-helperfrom
reduce-sum-02-split-logging
Closed

[Loss] Split logging loss from backward loss#1962
HAOCHENYE wants to merge 1 commit into
reduce-sum-01-fsdp-helperfrom
reduce-sum-02-split-logging

Conversation

@HAOCHENYE

Copy link
Copy Markdown
Collaborator

This PR (2/5) — behavior-neutral. Routes displayed/logged losses through detached per-rank local components reduced by cross-rank SUM; the backward loss is still globally reduced. Isolates the display pipeline so the next PR flips gradients without touching logging.

Full stack (merge bottom-up, under #1959):

  1. reduce-sum-01-fsdp-helper — [FSDP] Add reduce-sum gradient reduction helper
  2. reduce-sum-02-split-logging — [Loss] Split logging loss from backward loss
  3. reduce-sum-03-switch-sum — [FSDP][Loss] Switch gradient reduction to SUM
  4. reduce-sum-04-remove-world-size — [Refactor] Remove unused world_size plumbing
  5. reduce-sum-05-drop-nonglobal — [Refactor] Drop non-global aux-loss averaging mode

Restore every displayed loss scalar from a detached per-rank LOCAL component
reduced across ranks with a SUM all_reduce, instead of mean-reducing the
(globally reduced) backward loss tensors. Because each term's cross-rank SUM
equals the global loss, the logged curves are unchanged while backward still
uses the current global autograd path; this decouples display from backward so
the reduce-sum switch can make backward per-rank-local without touching logs.

- BalancingLossContext.finalize / ZLossContext now also produce a detached local
  component (z-loss's without the x world_size factor); MoE forward records them
  on extra_info as local_*loss (CE already exposes local_base_loss, MTP mirrored).
- BaseModel.post_micro_batch_forward and train_step total_loss reduce these local
  components with detached SUM; train_step total_loss is now the global value.

Behavior-neutral: EP=2, balancing+z on, grad-acc=2, symmetric data reproduces
C1's total_loss / reduced_llm_loss / reduced_balancing_loss / reduced_z_loss
bit-for-bit.
@HAOCHENYE
HAOCHENYE force-pushed the reduce-sum-01-fsdp-helper branch from c216448 to 184b6ca Compare July 17, 2026 08:11
@HAOCHENYE
HAOCHENYE force-pushed the reduce-sum-02-split-logging branch from a13bca8 to 316b1cc Compare July 17, 2026 08:11
loss = self._get_total_loss(output)
loss.backward()
total_loss += loss.detach()
local_display_loss += self.model.local_display_loss(output)

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

loss reduction, otherwise still do it in post_micro_batch_forward?

local_z_loss = z_locals[0] if len(z_locals) == 1 else torch.stack(z_locals).sum(dim=0)

return balancing_loss, z_loss, tokens_per_expert_global
return balancing_loss, z_loss, tokens_per_expert_global, local_balancing_loss, local_z_loss

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Return a TypedDict, as the tuple return type is not convenient for extension

Comment on lines +250 to +251
if dist.is_initialized():
dist.all_reduce(local_display_loss, op=dist.ReduceOp.SUM)

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

This part of the logic is placed in post_micro_batch_forward, and I hope each rank can display its own loss without performing an all_reduce sum. Could you try multiplying this coefficient back instead of doing a global sum?

Comment on lines +182 to +184
loss = loss_vec.sum() * alpha / self._batch_size
local_loss = local_vec.sum() * alpha / self._batch_size
return loss, local_loss.detach()

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Why return two losses? If a subsequent module needs to record it, just detach it there. Why implement it this way? The interfaces between modules are all very strange now

non_pad_token=non_pad_token,
)
balancing_loss, z_loss, tokens_per_expert_global = split_aux_output
balancing_loss, z_loss, tokens_per_expert_global, local_balancing_loss, local_z_loss = split_aux_output

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

If local_loss can be omitted, please simplify the interface

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

I don't see the need to make so many changes just for printing loss

@HAOCHENYE

Copy link
Copy Markdown
Collaborator Author

Superseded by the consolidated 2-PR stack #1968 (core) + #1969 (drop non-global). Closing this fragmented stack.

@HAOCHENYE HAOCHENYE closed this Jul 20, 2026
@HAOCHENYE
HAOCHENYE deleted the reduce-sum-02-split-logging branch July 20, 2026 16:35
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