Repository navigation
Conversation
The TP/DP groups in deepspeed.utils.groups are process-wide and the first engine creates them. _init_tp_mesh_device returned early when they were set, so a second engine with another autotp_size silently ran on the first engine's groups. An engine without AutoTP and without its own mpu took the earlier AutoTP engine's data parallel group and failed later in initialize. Check the requested sizes against the existing groups and raise a clear error in both cases. Engines with the same layout keep sharing the groups. This is stage 1 of deepspeedai#9081. Signed-off-by: Jin, Youzhi <youzhi.jin@intel.com>
This branch has not been deployed
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.
Stage 1 of #9081: the guard (option 3), which @LiRunGuo and @Achyuthan-S agreed should come first.
Problem
The TP/DP groups in
deepspeed.utils.groupsare process-wide, and the first engine creates them. When a second engine is built in the same process:autotp_size:_init_tp_mesh_devicereturns early because_TENSOR_MODEL_PARALLEL_GROUPis already set. An engine that asks for TP4 after a TP2 engine silently becomes a TP2 model (reproducer in [RFC] Cleanup: move process-wide parallel-group globals to per-engine groups — follow-up to #8241 / #8851 #9081).mpu(pointed out by @Achyuthan-S on [RFC] Cleanup: move process-wide parallel-group globals to per-engine groups — follow-up to #8241 / #8851 #9081): this engine never reaches_init_tp_mesh_device. The earlier AutoTP engine leftgroups.mpu = groups, so the new engine takes the TP2 engine's data parallel group, which covers only part of the ranks. On master it then fails in_configure_distributed_modelwithAttributeError: 'NoneType' object has no attribute 'get_model_parallel_rank'.Change
groups._check_existing_tp_groups()compares the requested TP size, and the DP size when one is given, with the existing groups. It raises aRuntimeErrorthat names both layouts and points to [RFC] Cleanup: move process-wide parallel-group globals to per-engine groups — follow-up to #8241 / #8851 #9081._init_tp_mesh_devicecalls it before its early return. This covers the engine path,tp_model_init(init_utils.py) andTpTrainingManager(tp_manager.py).DeepSpeedEngine.__init__calls it with size 1 for an engine without AutoTP that passes neithermpunormesh_param, when TP groups already exist.Not covered
These are left for stage 2 of #9081, as the RFC lays out:
mpureplacesgroups.mpu. Every later reader ofgroupsthen sees the newest engine's groups. [rollout] In-memory relayout between sharded layouts (two-stage relay, pipelined execution) and ZeRO-3 training-state move #9074 relies on this: it passes anmputo every engine. Making this an error would break that approach, and it is not a misconfiguration of the new engine.mpuafter one with a usermpu(the DP case @LiRunGuo reported on [RFC] Cleanup: move process-wide parallel-group globals to per-engine groups — follow-up to #8241 / #8851 #9081). The second engine takes the first one's DP group. Megatron-style code may rely on passing thempuonce ("For subsequent use, just query groups"), so a check here would be a behavior change. I would rather fix it with per-engine groups than turn it into an error.initialize. The new engine then builds its own groups, so the check does not fire.Duplicate check
I ran
gh pr list --search "9081 in:body", and searched for_init_tp_mesh_deviceand AutoTP guard PRs. The only related open PR, #8801, changes thebwc.pyfallbacks and is unrelated. On #9081 nobody else has taken the guard. @Achyuthan-S plans to move thestage3.pyuniversal-checkpoint reader in a later stage.Tests
Hardware: 4× Intel Arc Pro B70 (XPU, oneCCL), torch 2.14.0.dev20260804+xpu, on upstream master 5dc44e8.
skip_on_device()on XPU, plus H100-only tests.TestGroupCacheTeardown::test_nonmember_destroy_preserves_cached_groups: a worker was killed by signal 6 during teardown. That test does not reach the changed code. It passed when rerun alone, three times on this branch and once on master.TestAutoTPEnginesShareProcessGroups, 4 ranks):AttributeErrorabove.Compatibility matrix: ZeRO stage 0, bf16 off, AutoTP 1/2/4, no offload, on XPU. Not run on CUDA. The check runs only at
initializeand does not touch training steps, so there is no effect on numerics, throughput or memory.This PR was prepared with AI assistance; the tests above were run on the hardware listed.