Skip to content

Efficient Expert Weight Fusion for Moe deepseek v3#39150

Open
VassilyLombard wants to merge 2 commits into
huggingface:mainfrom
VassilyLombard:moe_DeepseekV3MoE
Open

Efficient Expert Weight Fusion for Moe deepseek v3#39150
VassilyLombard wants to merge 2 commits into
huggingface:mainfrom
VassilyLombard:moe_DeepseekV3MoE

Conversation

@VassilyLombard

Copy link
Copy Markdown

What does this PR do?

This PR answers a call for contribution. It introduces a fully vectorized, efficient Mixture-of-Experts (MoE) implementation for the DeepseekV3 model, specifically in the class DeepseekV3Moe. The new approach eliminates the loop over experts, improving inference and training speed, especially for large numbers of experts (256 here!).

Key Changes

  • Efficient MoE Forward Pass:
    Instead of iterating over experts, all expert weights are stacked into tensors, and expert selection is performed using indexing and batched matrix multiplications.
  • Expert Routing:
    For each token, the top-k expert indices and routing weights are computed by the router. Inputs are repeated and routed to the selected experts in a single batched operation.
  • Batched Expert Computation:
    All expert computations (linear projections and activations) are performed in parallel for all tokens and their assigned experts.
  • Aggregation:
    The outputs from all routed experts are weighted and summed back to the original token positions, producing the final MoE output without explicit loop.
  • Compatibility:
    The implementation assumes all experts are instances of the same class and have the same architecture, enabling parameter stacking and efficient computation.

No additional dependencies are required. @ArthurZucker

@VassilyLombard

Copy link
Copy Markdown
Author

Hi! First-time contributor here, happy to make any changes. I intended to do the second commit only, sorry for the confusion. Please let me know if you need anything else from me!

Comment on lines +181 to +183
w1 = torch.stack([e.gate_proj.weight for e in self.experts], dim=0)
w2 = torch.stack([e.down_proj.weight for e in self.experts], dim=0)
w3 = torch.stack([e.up_proj.weight for e in self.experts], dim=0)

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.

there is no way this is not super costly no? Also have you ran this with TP? we need to make sure both pathes work!

expert_mask = torch.nn.functional.one_hot(topk_indices, num_classes=len(self.experts))
expert_mask = expert_mask.permute(2, 0, 1)

for expert_idx in range(len(self.experts)):

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.

we don't have to go through all the export tho! we should only go through the ones that are hit!

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