feat(megatron): add manual CPU offload as an alternative to torch_mem…#66
Open
yeqinghe609 wants to merge 2 commits into
Open
feat(megatron): add manual CPU offload as an alternative to torch_mem…#66yeqinghe609 wants to merge 2 commits into
yeqinghe609 wants to merge 2 commits into
Conversation
yeqinghe609
force-pushed
the
main
branch
2 times, most recently
from
July 16, 2026 08:03
0b8a727 to
9e45df2
Compare
…ory_saver Colocate training offloads the train actor to CPU on every sleep/wake. The only path was torch_memory_saver (TMS) VMM pause()/resume(), which is semantically blind (backs up the whole runtime pool) and unsafe on backends without expandable_segments (e.g. Kunlunxin P800). This adds an explicit, application-level selective offload and lets it be selected per job. Behavior: - Default stays TMS. - New --manual-offload switches to selective offload: only live train state (param flat buffers + optimizer master/Adam state) is copied to CPU; grads and recomputable buffers are just released, then empty_cache() returns the freed pages to the driver. Changes: - weight_update/train_offload.py (new): MegatronTrainStateOffloader facade delegating to _TmsOffloadStrategy / _ManualOffloadStrategy behind an _OffloadStrategy Protocol. Owns TMS margin init and strategy selection (TMS when LD_PRELOAD'ed, else manual; --manual-offload forces manual). - backends/megatron/actor.py: sleep()/wake_up()/update_weights() delegate to the offloader; drop the inline _torch_memory_saver_enabled block and the torch_memory_saver / nullcontext imports. - weight_update/common.py: _maybe_get_cpu_backup() reads from the offloader's _relax_cpu_offload_data when a param's GPU storage was freed, and only takes the TMS get_cpu_backup() branch when the hook is actually LD_PRELOAD'ed. - distributed/ray/actor_group.py: skip LD_PRELOAD + TMS_INIT env vars under --manual-offload so TMS is not the active mechanism. - utils/arguments.py: add --manual-offload. - scripts/training/text/run-qwen35-8xklx.sh: pass --manual-offload for P800. No behavior change for existing TMS/CUDA users (default path untouched).
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.
…ory_saver
Colocate training offloads the train actor to CPU on every sleep/wake. The only path was torch_memory_saver (TMS) VMM pause()/resume(), which is semantically blind (backs up the whole runtime pool) and unsafe on backends without expandable_segments (e.g. Kunlunxin P800). This adds an explicit, application-level selective offload and lets it be selected per job.
Behavior:
Use TMS (default) when
torch_memory_saver hook LD_PRELOAD'ed (the launcher does this automatically for offload_train + megatron).
The allocator supports it (notably expandable_segments), so pause()/resume() can unmap/remap physical pages cleanly.
You want the simplest, well-tested path and don't mind that TMS backs up the entire runtime memory pool (it can't tell live optimizer state from dead activation/cache blocks).
Use --manual-offload when
You want selective offload: only the live train state (param flat buffers + optimizer master/Adam state) is copied to CPU; gradients and recomputable buffers are just released and empty_cache() returns the freed pages to the driver. This avoids blindly copying the ~70% dead data that whole-pool TMS backup moves, cutting sleep+wake time significantly on large/MoE/long-sequence models.
You need a hardware-neutral path that relies only on plain PyTorch storage ops (no .so / VMM), consistent across NVIDIA/Others.
Changes:
No behavior change for existing TMS/CUDA users (default path untouched).
Testing
Qwen3.6-35B
performance
Memory
3G vs 9G(tms offload vs manual offload)
tms offload
manual offload
pre-commit run --all-filespassespytest tests/)Type of Change
Screenshots / Logs