Skip to content

Unmanaged gradient accumulation: ZeRO offload support - #8225

Open
sfc-gh-truwase wants to merge 5 commits into
masterfrom
sfc-gh-truwase/gas_mgmt_offload
Open

Unmanaged gradient accumulation: ZeRO offload support#8225
sfc-gh-truwase wants to merge 5 commits into
masterfrom
sfc-gh-truwase/gas_mgmt_offload

Conversation

@sfc-gh-truwase

Copy link
Copy Markdown
Collaborator

Summary

  • Extends unmanaged gradient accumulation (managed_gradient_accumulation=false) to ZeRO optimizer-state and parameter offload (CPU/NVMe). Follow-up to Unmanaged gradient accumulation: ZeRO stage 3 support #8217 (ZeRO stage 3, now merged).
  • Stage 2/3: grads still reduce/partition every backward(); step() finalizes deferred offload boundary work (grad norms + FP32/NVMe copy) via finalize_gradient_accumulation_boundary().
  • Stage 1: continues to reduce at step() via allreduce_gradients(), which already performs offload boundary finalization when the boundary flag is true.
  • Pipeline parallelism, DeepCompile, Apex AMP, and stage-0/1 overlap_comm remain unsupported.

Test plan

Validated on a 2-GPU node:

  • Full -k Unmanaged suite (31 passed), including:
    • test_unmanaged_matches_managed_optimizer_offload[1|2|3]
    • test_unmanaged_matches_managed_param_offload (stage 3)
    • existing non-offload unmanaged equivalence / varying-GAS / rejection tests
  • Docs updated (config-json.md, training.rst); previewable on rtd-staging

Made with Cursor

Allow managed_gradient_accumulation=False with ZeRO optimizer-state and
parameter offload (CPU/NVMe). Stage 2/3 defer boundary norm and FP32/NVMe
gradient copy into finalize_gradient_accumulation_boundary(); stage 1
continues to finalize via allreduce_gradients() at step(). Docs and
equivalence tests cover stages 1-3 optimizer offload and stage-3 param
offload.

Validated on a 2-GPU node (full -k Unmanaged suite, 31 passed) incl.
optimizer offload [1,2,3] and param+optimizer offload stage 3.

Signed-off-by: Olatunji Ruwase <tunji.ruwase@snowflake.com>
Co-authored-by: Cursor <cursoragent@cursor.com>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d3dcf9ad4e

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread docs/_pages/config-json.md
Comment thread deepspeed/runtime/zero/stage_1_and_2.py Outdated
Comment thread deepspeed/runtime/zero/stage3.py
@sfc-gh-truwase
sfc-gh-truwase requested review from delock and stas00 August 6, 2026 16:11
sfc-gh-truwase and others added 3 commits August 7, 2026 01:31
Track params reduced in the current accumulation window and only finalize
those at step(), matching managed offload (which only copies grads that
flow through the boundary backward). Prevents inactive ZeRO-2/3 params
from being updated from leftover CPU/partition buffers. Adds a regression
test that alternates active heads across windows.

Signed-off-by: Olatunji Ruwase <tunji.ruwase@snowflake.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Cover optimizer NVMe and param+optimizer NVMe paths against managed mode,
skipping when async-io is unavailable. Shared helper drives CPU and NVMe
offload cases; NVMe uses a large enough model to exercise swap_out_gradients.

Signed-off-by: Olatunji Ruwase <tunji.ruwase@snowflake.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Resolve stage3.py conflict with async grad offload (#8207): keep
unmanaged boundary helper and retain non_blocking FP32 grad copy.

Signed-off-by: Olatunji Ruwase <tunji.ruwase@snowflake.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Comment thread deepspeed/runtime/zero/stage3.py Outdated
Comment thread deepspeed/runtime/zero/stage3.py
@delock

delock commented Aug 8, 2026

Copy link
Copy Markdown
Collaborator

Hi @sfc-gh-truwase , I have left my comments. One impression is self.is_gradient_accumulation_boundary might need some refactor. Its a flag variable that could be injected from engine, and no longer used in stage 2/3 unmanaged code. Proper comments and set/get interface would be better than expose as variable.

Comment thread deepspeed/runtime/zero/stage_1_and_2.py Outdated
Move optimizer is_gradient_accumulation_boundary behind
ZeROOptimizer get/set methods so the engine mirrors boundary
state through an explicit API, with comments clarifying managed
vs unmanaged use.

Signed-off-by: Olatunji Ruwase <tunji.ruwase@snowflake.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
@sfc-gh-truwase

Copy link
Copy Markdown
Collaborator Author

@delock, thanks for catching the issues with self.is_gradient_accumulation_boundary. It is replaced with getter/setter.

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.

2 participants