Merge pull request #859 from basil-k-aji-dev/fix/moe-router-gradient-topk1

[fix] keep the MoE router trainable at num_experts_per_tok=1
pull/860/head
jingyaogong 2026-09-18 15:03:36 +08:00 committed by GitHub
commit 1aae25911b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 8 additions and 1 deletions

View File

@ -158,7 +158,14 @@ class MOEFeedForward(nn.Module):
x_flat = x.view(-1, hidden_dim)
scores = F.softmax(self.gate(x_flat), dim=-1)
topk_weight, topk_idx = torch.topk(scores, k=self.config.num_experts_per_tok, dim=-1, sorted=False)
if self.config.norm_topk_prob: topk_weight = topk_weight / (topk_weight.sum(dim=-1, keepdim=True) + 1e-20)
# Normalising a single top-k weight by its own sum yields 1.0 for every
# token, so the gate drops out of the graph: topk_idx is discrete and the
# weight is now a constant, leaving the LM loss no path to the router. It
# then trains on aux_loss alone, whose optimum is a uniform distribution,
# and the experts never specialise. Only normalise when there is more than
# one weight to normalise.
if self.config.norm_topk_prob and self.config.num_experts_per_tok > 1:
topk_weight = topk_weight / (topk_weight.sum(dim=-1, keepdim=True) + 1e-20)
y = torch.zeros_like(x_flat)
for i, expert in enumerate(self.experts):
mask = (topk_idx == i)