moe#
HuggingFace-coupled MoE expert-parallel (EP) helpers.
Finding a model’s routed experts, choosing the EP degree they are sharded over, the DP=EP
all-to-all expert transport (torch_a2a). The expert-parallel model loader is
load_and_prepare_ep().
The all-to-all transport is plain torch.distributed.all_to_all_single (NCCL) wrapped around
transformers’ quantizable _grouped_linear. register_torch_a2a() registers
it into transformers’ ExpertsInterface (lazily, from load_and_prepare_ep’s a2a path – never at
import time, so importing this module has no transformers-ExpertsInterface side effect).
Functions
Route one MoE layer's expert stage by plain torch.distributed.all_to_all_single (NCCL). |
|
Pick |
|
The mesh |
|
Return the MoE expert count from an HF config (0 if the model is not MoE). |
|
Register everything the torch_a2a path needs into stock transformers (idempotent). |
|
Fail loudly if the installed transformers is older than |
|
All-to-all expert-parallel forward for PTQ calibration (DP=EP). |
- a2a_moe(group, hidden_states, topk_idx, topk_weights, num_local_experts, expert_fn)#
Route one MoE layer’s expert stage by plain torch.distributed.all_to_all_single (NCCL).
Works cross-node at any rank count, with explicit token permute/unpermute.
Flow: expand (token, expert) pairs -> route each to dest_rank = global_expert // num_local -> all_to_all the tokens (+ local-expert id) -> local grouped_mm (quantizable) -> all_to_all back -> weight by the routing weights and sum each token’s top_k results.
Tokens travel and the result returns in
hidden_states’ dtype – the model’s, so its residual stream keeps one dtype. The routing weights never travel: the rank that holds a token weights its experts’ results in the weights’ own dtype and sums them as transformers’ grouped_mm forward does.
- choose_ep_dp_degrees(world_size, num_experts)#
Pick
(expert_parallel, expert_data_parallel)degrees withEP * EDP == world_size.EP must divide both
num_experts(whole experts per rank) andworld_size(a valid mesh factorization); we take the largest such EP, and each expert shard is then replicated over the remainingEDP = world_size // EPranks. Falls back to(1, world_size)when the model is not MoE or no valid EP degree exists. Heuristic – callers may override.- Parameters:
world_size (int)
num_experts (int)
- Return type:
tuple[int, int]
- expert_parallel_mesh(model)#
The mesh
model’s routed experts are sharded over, orNoneif its plan shards none.load_and_prepare_ep()loads the model over its expert-parallel submesh, which transformers keeps on the model as_device_mesh. Calibration takes the mesh to re-install the all-to-all forwards (distributed_forward_loop()).- Parameters:
model (Module)
- num_experts_from_config(hf_config)#
Return the MoE expert count from an HF config (0 if the model is not MoE).
Recurses into
.text_config/.llm_configso VLMs whose nested text submodel is the MoE (Kimi-K2.7, Llama-4 multimodal, NemotronH-Omni, …) report the LM’s expert count.- Return type:
int
- register_torch_a2a()#
Register everything the torch_a2a path needs into stock transformers (idempotent).
Done lazily from
load_and_prepare_ep, not at import time, so importing this module has no transformers side effect:the
torch_a2aexperts forward intoExpertsInterface(ALL_EXPERTS_FUNCTIONS);two EP parallel styles into
ALL_PARALLEL_STYLES:torch_a2a_router– emit global, unmasked expert ids (skipRouterParallel’s per-EP-rank masking) so the a2a dispatch can route each (token, expert) to its owning rank;torch_a2a_experts– inject the EPprocess_groupinto the experts forward (4th arg) and skip the all-reduce (the a2a combine does the reduction).
These two styles are functionally transformers’
megamoe_router/megamoe_experts(added in 5.10.4 for DeepGEMM Mega-MoE), reimplemented here so the transport works below 5.10.4 too. The base classes (RouterParallel,TensorParallelLayer) are stock wherever the EP infra exists (transformers >= 5.6, the framework floor enforced inload_and_prepare_ep), so this works on any such version;grouped_gemm(expert weight sharding) is stock too.
- require_transformers(min_version, feature)#
Fail loudly if the installed transformers is older than
min_version(the floor forfeature).Callers enforce the version where the needed APIs first exist, so a too-old transformers errors clearly instead of silently mis-behaving (e.g. transformers 5.5 silently shards nothing for EP). See each call site for the empirically-determined floor.
- Parameters:
min_version (str)
feature (str)
- Return type:
None
- torch_a2a_experts_forward(self, hidden_states, top_k_index, top_k_weights, process_group=None)#
All-to-all expert-parallel forward for PTQ calibration (DP=EP).
Registered as the “torch_a2a” experts implementation on transformers’ ExpertsInterface.
Dense+router run data-parallel; experts are EP-sharded; tokens are routed to the expert-owning rank by the NCCL all-to-all above. Local experts run through the ModelOpt-quantizable _grouped_linear so per-expert weight + shared input quantizers attach over the dispatched (global) token pool. process_group (the EP group) is injected by the torch_a2a_experts TP style’s _prepare_input_fn; the router must emit GLOBAL ids unmasked (torch_a2a_router).
self.num_expertsis this rank’s share of the experts: the expert-parallel loader loads them through transformers’ expert-parallel sharding (thegrouped_gemm/ packed styles), which slices the experts’ weights along dim 0 and setsnum_expertsto the per-rank count.