fix(optimizer): clip by global grad norm across FSDP ranks in BF16Optimizer#663
Open
jessiewei7 wants to merge 1 commit into
Open
fix(optimizer): clip by global grad norm across FSDP ranks in BF16Optimizer#663jessiewei7 wants to merge 1 commit into
jessiewei7 wants to merge 1 commit into
Conversation
Contributor
|
Warning You have reached your daily quota limit. Please wait up to 24 hours and I will start processing your requests again! |
Collaborator
|
Great findings! We have fixed the bugs in branch. |
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.
fix(optimizer): clip by global grad norm across FSDP ranks in BF16Optimizer
Summary
BF16Optimizer.step()clips with plaintorch.nn.utils.clip_grad_norm_overits fp32 master copies. All callers (
train_dflash.py,train_domino.py,train_eagle3.py,train_peagle.py, the dataflow runtime, the disaggexample) wrap the model in FSDP with
SHARD_GRAD_OP, so after backward eachrank's
.grads are its reduce-scattered shard — the clip sees arank-local norm, roughly
1/sqrt(world_size)of the true norm. Twoconsequences:
scales with world size), and
clipped global gradient no longer points in the original direction.
specforge/runtime/training/backend.pyalready acknowledges this — itsstep()all-reduces the norm — but it does so afteroptimizer.step()has clipped, so only the logged norm was corrected, not the clipping
itself.
Fix
BF16Optimizer._clip_grad_norm(): accumulate the squared norm, all-reduceit across ranks (when
distis initialized), and scale every shard by thesingle global clip coefficient. Non-distributed behavior is unchanged
(verified against
torch.nn.utils.clip_grad_norm_in the test). Thereturned/logged norm is now the true global norm.
FSDPTrainingBackend.step(): drop the post-hoc all-reduce — with the fixit would reduce twice and inflate the logged norm by ~
sqrt(world_size).Why not
FSDP.clip_grad_norm_: it clips the module's bf16 shard gradients,while
BF16Optimizer's whole design is clipping its fp32 master copies —this keeps that numerics path, applying the same cross-rank reduction that
API does internally. An FSDP2 migration would make this class of bug
impossible (DTensor grads reduce cross-rank automatically) — #242 did that
for the old offline script, but the current dataflow backend is back on
FSDP1 — so the FSDP1 paths need the reduction done explicitly, as here.
Note on behavior:
max_grad_norm=0.5was copied from EAGLE's DeepSpeedds_config.json, and DeepSpeed clips by the global norm — so this restoresparity with the reference implementation the constant came from. At scale
the true norm is ~
sqrt(world_size)× the previously-compared local norm, soclipping engages more often; existing multi-GPU loss curves will not
reproduce exactly.
Test plan
tests/test_optimizer/test_bf16_optimizer_clip_grad_norm.py(CUDA-free):torch.nn.utils.clip_grad_norm_exactly(norm and clipped gradients);
gloorun with different per-rank gradient shards: both rankscompute the same global norm and apply the same clip coefficient.