Repository navigation
Accumulate tiled MLP weight grads once per backward - #1083
Conversation
|
Hi @kashif, thanks for your interest in contributing! This project requires that pull request authors are vouched, and you are not in the list of vouched users. This PR will be closed automatically. See https://github.com/huggingface/kernels-community/blob/main/CONTRIBUTING.md for more details. |
|
/kernel-bot build liger-kernels |
|
Build request processed. Command: Dispatched (1):
|
|
/kernel-bot build-and-merge liger-kernels |
|
Invalid command. Use |
|
/kernel-bot merge-and-upload liger-kernels |
|
Build request processed. Command: Merge result: PR is already merged. Continuing with build/upload. Dispatched (1):
Hub uploads: |
Related issue
Closes #1081
What does this PR do?
Makes the tiled MLP backward accumulate each weight gradient once per pass instead of once per shard, so DDP no longer fails with
Expected to mark a variable ready only once.Motivation
The backward drives each shard with its own
torch.autograd.backward, sogate_proj.weight,up_proj.weightanddown_proj.weighteach reach theirAccumulateGradnodenum_shardstimes in a single pass. DDP registers one hook per parameter and marks it ready on every firing, which is one-shot per pass, so any model with more than one tiled MLP dies in backward.ds_grad_is_ready(#1000) defers DeepSpeed's reduction to the last shard, but the accumulations themselves still happen once per shard, so it does not help DDP.Tiling is a memory optimization and should not change how gradients reach the parameters.
Changes
LigerTiledMLPFunction.applyas explicit tensor inputs and return their gradients frombackward, so autograd accumulates each one once, at the end of the pass.torch.autograd.gradinstead oftorch.autograd.backwardon that path, summing the per-shard gradients locally. NoAccumulateGradnode fires inside the loop, so DDP's per-parameter hook is untouched.hasattr(param, "ds_id"). Partitioned weights are 0-sized placeholders outside their owning module's forward, so autograd would record(0,)as the expected gradient shape and the recompute would fail. Those still defer the reduction viads_grad_is_ready.Testing
Ran the reporter's repro from #1081, reduced to 2 gloo/CPU ranks and a 2-layer
LlamaConfigso it needs no GPU. Before this change both ranks raiseExpected to mark a variable ready only once; after it, backward completes.Also checked against an untiled reference in float64, single process, max abs gradient error:
[2, 256, 64], 4 shardsnum_shardsout_features != in_featuresx.requires_grad=Falseds_id) pathAnd confirmed the accumulation count directly with a
register_post_accumulate_grad_hookon each weight: one firing per weight per backward with 8 shards on the default path,num_shardsfirings on the ZeRO-3 path as intended.liger-kernelshas no test directory here, so the regression tests land upstream in linkedin/Liger-Kernel#1276 alongside the same fix.Checklist