Skip to content

🚨 Separate EP logic into its own file - #49679

Merged
ArthurZucker merged 6 commits into
mainfrom
cleanup-ep
Oct 27, 2026
Merged

ArthurZucker merged 6 commits into
mainfrom
cleanup-ep

Conversation

@3outeille

@3outeille 3outeille commented Oct 16, 2026 •

Copy link
Copy Markdown
Member

🤗 Transformers CI

Only moving, no behaviour change.
Referencing #49429 as it needs it

What changed

  • New distributed/expert_parallel.py: all MoE/EP styles (moe_tp_experts, moe_identity_expert, grouped_gemm, ep_router, ep_dispatch_experts, megamoe_router, megamoe_experts) and apply_expert_parallelism. The EP styles get an ExpertParallelLayer base class with the same hooks as TensorParallelLayer.
  • New distributed/parallel_utils.py: the DTensor helpers shared by both files.
  • tensor_parallel.py keeps only the dense styles. Still one registry, ALL_PARALLEL_STYLES; expert_parallel.py registers its styles into it.
  • New tests/test_expert_parallel_mixin.py: ExpertParallelTesterMixin with the test_ep_* tests and its own model allowlist, moved out of the TP mixin.

Breaking changes 🚨

  • EP styles subclass ExpertParallelLayer, not TensorParallelLayer / MoeExpertsParallel. Hooks are unchanged.
  • _use_local_dtensor_params, _AllReduceForward, _AllReduceBackward moved to parallel_utils.py (private, no shim).
  • TensorParallelTesterMixin no longer carries the EP tests; add ExpertParallelTesterMixin to get them.

Old imports from transformers.distributed.tensor_parallel keep working with a FutureWarning until v5.23.

@3outeille
3outeille added this pull request to stack #49680 October 16, 2026 17:55
@3outeille 3outeille changed the title Merge branch 'main' into cleanup-ep (on top of unify-resolve-plan) 🚨 Separate EP logic into its own file Oct 16, 2026
@3outeille
3outeille force-pushed the cleanup-ep branch 2 times, most recently from cbb8a4d to 2948f5d Compare October 16, 2026 19:56
@HuggingFaceDocBuilderDev

Copy link
Copy Markdown

The docs for this PR live here. All of your documentation changes will be reflected on that endpoint. The docs are available until 30 days after the last update.

@3outeille
3outeille force-pushed the cleanup-ep branch 2 times, most recently from 4193ff1 to 4481fe3 Compare October 16, 2026 21:49
@3outeille
3outeille marked this pull request as ready for review October 16, 2026 23:22
@3outeille
3outeille requested review from ArthurZucker, IlyasMoutawwakil and vasqu and removed request for ArthurZucker, IlyasMoutawwakil and vasqu October 16, 2026 23:22
)


def __getattr__(name: str):

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

not so sure about this one. Wdyt ? @ArthurZucker @vasqu

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

dang yea kind of a wear workaround but its for cases where you import from the file right? Imo ok to keep as its for BC but we should add a small comment to explain this!

@IlyasMoutawwakil IlyasMoutawwakil left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks ! very much needed ! left a couple comments, my one concern is the double file dependency which is preferably avoidable imo, it'd be much better if we draw clear lines between the diff parallelisms in terms of integration as well, the registery can be somewhere central

Comment on lines +37 to +51
# Set to None to run distributed EP tests for every model with a plan.
# Representative MoE model types covered by distributed EP tests.
EP_DISTRIBUTED_TEST_MODEL_TYPES = {
"qwen4_exp_text",
"qwen3_moe",
"glm_moe_dsa",
"deepseek_v4",
"glm4_moe_lite",
"glm4_moe",
"olmoe",
"qwen2_moe",
"cohere2_moe",
# VLM
"glm4v_moe",
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

in general these allow lists keeps a lot of problems under the radar, i'd much more prefer making the tests cheaper an enabling them on all MoEs, and VLMs, simple lm decoders are generally fine having one representative, but moes/vlms/alms/omnis can implement some things very differently (ernie text/vision experts, DSAs, attn sinks, ..)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

they are already tiny models running. I once enabled them for a lot of models but @ydshieh was complaining that it was still taking a lot of time. Maybe I can distribute it on more machines ?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

OR, we can keep it this way and wait for my transformer training CI dashboard coming up next. I am planning to run small training through HF jobs to check bitwise correctness on all models. Will post internally about the idea soon

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

yeh i was also surprised when i ran them all locally they weren't that slow but collectively they might be, the biggest slowdown might be in the multi-process spawning, i wonder if we can use threads to simulate a multi-proc setup for example, wdyt ?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

or cache it once you are on a single machine and config does not change

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I still dont see why we cant run all for nightly at least? Its fine to have a small list for the fast CI but nightly should run all no?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

yes yes i agree, a once per day nightly is better ! same as we do for export.
but we need a way to @slow all models except a list of models that continue to run in fast ci

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

agree but this belongs to another PR tho

Comment thread docs/source/en/perf_infer_gpu_multi.md Resolved
return output


if is_torch_distributed_available():

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

no need for guarding ig, both ALL_PARALLEL_STYLES and the layers are defined

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

maybe we should move ALL_PARALLEL_STYLES to something more general and let tp / ep define their own list => update the ALL_PARALLEL_STYLES based on both of theirs

atm it's still very tp focused and needs a more centralized point imo

@ArthurZucker ArthurZucker left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Yep let's be careful with BC but otherwise full gassss

parallelism=6,
)

expert_parallel_ci_job = CircleCIJob(

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

not sure that needs to be separated!

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

imo better to separate, it was already weird enough imo that tp and ep were used in the same context of tests

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

yeah I prefer separating as well

@vasqu vasqu left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Some smaller comments but overall much needed

parallelism=6,
)

expert_parallel_ci_job = CircleCIJob(

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

imo better to separate, it was already weird enough imo that tp and ep were used in the same context of tests

Comment thread docs/source/en/perf_infer_gpu_multi.md Resolved
)


def __getattr__(name: str):

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

dang yea kind of a wear workaround but its for cases where you import from the file right? Imo ok to keep as its for BC but we should add a small comment to explain this!

return output


if is_torch_distributed_available():

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

maybe we should move ALL_PARALLEL_STYLES to something more general and let tp / ep define their own list => update the ALL_PARALLEL_STYLES based on both of theirs

atm it's still very tp focused and needs a more centralized point imo

Comment thread tests/test_expert_parallel_mixin.py Resolved
Comment on lines +37 to +51
# Set to None to run distributed EP tests for every model with a plan.
# Representative MoE model types covered by distributed EP tests.
EP_DISTRIBUTED_TEST_MODEL_TYPES = {
"qwen4_exp_text",
"qwen3_moe",
"glm_moe_dsa",
"deepseek_v4",
"glm4_moe_lite",
"glm4_moe",
"olmoe",
"qwen2_moe",
"cohere2_moe",
# VLM
"glm4v_moe",
}

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I still dont see why we cant run all for nightly at least? Its fine to have a small list for the fast CI but nightly should run all no?

IlyasMoutawwakil added a commit that referenced this pull request Oct 21, 2026
The rename of `_hf_quantized_needs_local_tp` had no user here and collides with #49679. Scalar replication
goes back from `resolve_parallel_plans` into `HfQuantizer.update_parallel_plan`, as Arthur asked on #49015,
so every quantizer gets it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@3outeille
3outeille removed this pull request from stack #49680 October 23, 2026 00:00
@3outeille
3outeille changed the base branch from unify-resolve-plan to main October 23, 2026 00:00
- Consolidated the registration of parallel styles into the `ParallelInterface` class for better organization.
- Updated the `expert_parallel.py` and `tensor_parallel.py` files to streamline the registration process of expert parallel strategies.
- Enhanced documentation for clarity regarding the usage of tensor parallel strategies and their registration.
- Removed redundant code related to `MoeExpertsParallel` and `MoeIdentityParallel` classes, which are now properly registered in the new structure.
ALL_PARALLEL_STYLES.register("moe_tp_experts", MoeExpertsParallel())
ALL_PARALLEL_STYLES.register("moe_identity_expert", MoeIdentityParallel())
# Every rank keeps the full param, e.g. a per-tensor quantization scale
ALL_PARALLEL_STYLES.register("replicate", TensorParallelLayer())

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

why do we need this one @IlyasMoutawwakil ?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

for non shardable scales f850c82
not ep specific tho

@3outeille
3outeille added this pull request to the merge queue Oct 27, 2026
@3outeille
3outeille removed this pull request from the merge queue due to a manual request Oct 27, 2026
@github-actions

Copy link
Copy Markdown
Contributor

[For maintainers] Suggested jobs to run (before merge)

run-slow: deepseek_v3, diffusion_gemma, glm4v_moe, granitemoehybrid, jamba, nemotron_h, olmoe, openai_privacy_filter, qwen3_omni_moe

@3outeille
3outeille enabled auto-merge October 27, 2026 01:36
@ArthurZucker
ArthurZucker disabled auto-merge October 27, 2026 08:14
@ArthurZucker
ArthurZucker merged commit 575b59f into main Oct 27, 2026
447 of 455 checks passed
@ArthurZucker
ArthurZucker deleted the cleanup-ep branch October 27, 2026 08:15
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.

5 participants