已合并
fix: use deterministic placeholder initialization for DeepSeek4 hash layers #4898
fix: use deterministic placeholder initialization for DeepSeek4 hash layers #4898
已合并
丁子叉创建于 28 天前
1 个文件变更+115-95
@@ -14,7 +14,6 @@
14# limitations under the License.14# limitations under the License.
15 15 
丁子叉16 天前

修改hash layer参数随机初始化逻辑与开源保持一致,并说明其局限性

likedislike
16from functools import wraps16from functools import wraps
17-from functools import partial
18 17 
19import torch18import torch
20import torch.nn.functional as F19import torch.nn.functional as F
@@ -36,11 +35,9 @@ from mindspeed_llm.core.transformer.moe.moe_utils import topk_softmax_with_capac
36def group_limited_greedy_topKgating(self, logits: torch.Tensor):35def group_limited_greedy_topKgating(self, logits: torch.Tensor):
37 args = get_args()36 args = get_args()
38 seq_length = logits.shape[0]37 seq_length = logits.shape[0]
39- 38+ 
40 scores = F.softmax(logits, dim=1)39 scores = F.softmax(logits, dim=1)
41- group_scores = (40+ group_scores = scores.view(args.micro_batch_size * seq_length, self.n_group, -1).max(dim=-1).values # [n, EP]
42- scores.view(args.micro_batch_size * seq_length, self.n_group, -1).max(dim=-1).values
43- ) # [n, EP]
44 41 
45 group_idx = torch.topk(group_scores, k=self.topk_group, dim=-1, sorted=False)[1] # [n, top_k_group]42 group_idx = torch.topk(group_scores, k=self.topk_group, dim=-1, sorted=False)[1] # [n, top_k_group]
46 43 
@@ -48,17 +45,13 @@ def group_limited_greedy_topKgating(self, logits: torch.Tensor):
48 group_mask.scatter_(1, group_idx, 1) # [n, EP]45 group_mask.scatter_(1, group_idx, 1) # [n, EP]
49 score_mask = (46 score_mask = (
50 group_mask.unsqueeze(-1)47 group_mask.unsqueeze(-1)
51- .expand(48+ .expand(args.micro_batch_size * seq_length, self.n_group, args.num_experts // self.n_group)
52- args.micro_batch_size * seq_length, self.n_group, args.num_experts // self.n_group
53- )
54 .reshape(args.micro_batch_size * seq_length, -1)49 .reshape(args.micro_batch_size * seq_length, -1)
55 ) # [n, e]50 ) # [n, e]
56 51 
57 tmp_scores = scores.masked_fill(~score_mask.bool(), 0.0) # [n, e]52 tmp_scores = scores.masked_fill(~score_mask.bool(), 0.0) # [n, e]
58 53 
59- topk_weight, topk_idx = torch.topk(54+ topk_weight, topk_idx = torch.topk(tmp_scores, k=args.moe_router_topk, dim=-1, sorted=False)
60- tmp_scores, k=args.moe_router_topk, dim=-1, sorted=False
61- )
62 55 
63 ### norm gate to sum 156 ### norm gate to sum 1
64 if args.moe_router_topk > 1 and args.norm_topk_prob:57 if args.moe_router_topk > 1 and args.norm_topk_prob:
@@ -77,7 +70,6 @@ def group_limited_greedy_topKgating(self, logits: torch.Tensor):
77 70 
78 scores_for_aux = scores # [s*b, n_global_experts]71 scores_for_aux = scores # [s*b, n_global_experts]
79 topk_idx_for_aux_loss = topk_idx.view(args.micro_batch_size, -1) # [b, s*top_k]72 topk_idx_for_aux_loss = topk_idx.view(args.micro_batch_size, -1) # [b, s*top_k]
80- topk_group_idx_for_aux_loss = group_idx.view(args.micro_batch_size, -1) # [b, s*topk_group]
81 fi, Pi, l_aux = None, None, 073 fi, Pi, l_aux = None, None, 0
82 74 
83 #########################################################75 #########################################################
@@ -89,9 +81,7 @@ def group_limited_greedy_topKgating(self, logits: torch.Tensor):
89 if args.seq_aux:81 if args.seq_aux:
90 scores_for_seq_aux = scores_for_aux.view(args.micro_batch_size, seq_length, -1)82 scores_for_seq_aux = scores_for_aux.view(args.micro_batch_size, seq_length, -1)
91 # [b, s, n_global_experts]83 # [b, s, n_global_experts]
92- ce = torch.zeros(84+ ce = torch.zeros(args.micro_batch_size, args.num_experts, device=logits.device) # [b, n_global_experts]
93- args.micro_batch_size, args.num_experts, device=logits.device
94- ) # [b, n_global_experts]
95 ce.scatter_add_(85 ce.scatter_add_(
96 1,86 1,
97 topk_idx_for_aux_loss,87 topk_idx_for_aux_loss,
@@ -105,13 +95,13 @@ def group_limited_greedy_topKgating(self, logits: torch.Tensor):
105 torch.distributed.all_reduce(ce, group=sequence_partition_group)95 torch.distributed.all_reduce(ce, group=sequence_partition_group)
106 96 
107 num_tokens = seq_length * num_sub_sequence97 num_tokens = seq_length * num_sub_sequence
108- fi = ce.div(num_sub_sequence * num_tokens * args.moe_router_topk / args.num_experts) # [b, n_global_experts]98+ fi = ce.div(
99+ num_sub_sequence * num_tokens * args.moe_router_topk / args.num_experts
100+ ) # [b, n_global_experts]
109 Pi = scores_for_seq_aux.mean(dim=1) # [b, n_global_experts]101 Pi = scores_for_seq_aux.mean(dim=1) # [b, n_global_experts]
110 l_expert_aux = (Pi * fi).sum(dim=1).mean() * self.config.moe_aux_loss_coeff102 l_expert_aux = (Pi * fi).sum(dim=1).mean() * self.config.moe_aux_loss_coeff
111 else:103 else:
112- mask_ce = F.one_hot(104+ mask_ce = F.one_hot(topk_idx_for_aux_loss.view(-1), num_classes=args.num_experts)
113- topk_idx_for_aux_loss.view(-1), num_classes=args.num_experts
114- )
115 ce = mask_ce.to(logits.dtype).mean(0)105 ce = mask_ce.to(logits.dtype).mean(0)
116 Pi = scores_for_aux.mean(0)106 Pi = scores_for_aux.mean(0)
117 fi = ce * args.num_experts107 fi = ce * args.num_experts
@@ -130,9 +120,7 @@ def group_limited_greedy_topKgating(self, logits: torch.Tensor):
130 if fi is None:120 if fi is None:
131 scores_for_seq_aux = scores_for_aux.view(args.micro_batch_size, seq_length, -1)121 scores_for_seq_aux = scores_for_aux.view(args.micro_batch_size, seq_length, -1)
132 122 
133- ce = torch.zeros(123+ ce = torch.zeros(args.micro_batch_size, args.num_experts, device=logits.device) # [b, n_global_experts]
134- args.micro_batch_size, args.num_experts, device=logits.device
135- ) # [b, n_global_experts]
136 ce.scatter_add_(124 ce.scatter_add_(
137 1,125 1,
138 topk_idx_for_aux_loss,126 topk_idx_for_aux_loss,
@@ -147,9 +135,7 @@ def group_limited_greedy_topKgating(self, logits: torch.Tensor):
147 135 
148 else:136 else:
149 if fi is None:137 if fi is None:
150- mask_ce = F.one_hot(138+ mask_ce = F.one_hot(topk_idx_for_aux_loss.view(-1), num_classes=args.num_experts)
151- topk_idx_for_aux_loss.view(-1), num_classes=args.num_experts
152- )
153 ce = mask_ce.to(logits.dtype).mean(0)139 ce = mask_ce.to(logits.dtype).mean(0)
154 Pi = scores_for_aux.mean(0)140 Pi = scores_for_aux.mean(0)
155 fi = ce * args.num_experts141 fi = ce * args.num_experts
@@ -222,20 +208,20 @@ def group_limited_greedy_topKgating(self, logits: torch.Tensor):
222class custom_multiplier(torch.autograd.Function):208class custom_multiplier(torch.autograd.Function):
223 @staticmethod209 @staticmethod
224 def forward(210 def forward(
225- ctx,211+ ctx,
226- scores: torch.Tensor,212+ scores: torch.Tensor,
227- multiplier: torch.Tensor,213+ multiplier: torch.Tensor,
228- selected_experts: torch.Tensor,214+ selected_experts: torch.Tensor,
229- masked_gates: torch.Tensor,215+ masked_gates: torch.Tensor,
230- mask_for_one: torch.Tensor,216+ mask_for_one: torch.Tensor,
231 ):217 ):
232 ctx.save_for_backward(multiplier, selected_experts, masked_gates)218 ctx.save_for_backward(multiplier, selected_experts, masked_gates)
233 return multiplier * mask_for_one219 return multiplier * mask_for_one
234 220 
235 @staticmethod221 @staticmethod
236 def backward(222 def backward(
237- ctx,223+ ctx,
238- grad_at_output: torch.Tensor,224+ grad_at_output: torch.Tensor,
239 ):225 ):
240 multiplier, selected_experts, masked_gates = ctx.saved_tensors226 multiplier, selected_experts, masked_gates = ctx.saved_tensors
241 227 
@@ -272,9 +258,14 @@ def sparsemixer_top2(self, scores, jitter_eps=0.01):
272 masked_gates = scores.masked_fill(mask_logits_threshold, float('-inf'))258 masked_gates = scores.masked_fill(mask_logits_threshold, float('-inf'))
273 if self.training:259 if self.training:
274 # gumbel sampling, more robust than than the multinomial method260 # gumbel sampling, more robust than than the multinomial method
275- selected_experts = (masked_gates - torch.empty_like(261+ selected_experts = (
276- masked_gates, memory_format=torch.legacy_contiguous_format262+ (
277- ).exponential_().log()).max(dim=-1)[1].unsqueeze(-1)263+ masked_gates
264+ - torch.empty_like(masked_gates, memory_format=torch.legacy_contiguous_format).exponential_().log()
265+ )
266+ .max(dim=-1)[1]
267+ .unsqueeze(-1)
268+ )
278 else:269 else:
279 selected_experts = max_ind270 selected_experts = max_ind
280 271 
@@ -287,7 +278,7 @@ def sparsemixer_top2(self, scores, jitter_eps=0.01):
287 max_scores, max_ind = masked_gates.max(dim=-1, keepdim=True)278 max_scores, max_ind = masked_gates.max(dim=-1, keepdim=True)
288 mask_for_one = torch.logical_or(279 mask_for_one = torch.logical_or(
289 selected_experts == max_ind,280 selected_experts == max_ind,
290- torch.rand_like(max_scores) > 0.75 # Heun's third-order method: f(x) - f(0) = .25 f'(x) + .75 f'(x/3.)281+ torch.rand_like(max_scores) > 0.75, # Heun's third-order method: f(x) - f(0) = .25 f'(x) + .75 f'(x/3.)
291 ).int()282 ).int()
292 # 1 -> 1.0 & 0 -> 1./3: lambda x: (x + 0.5) / 1.5283 # 1 -> 1.0 & 0 -> 1./3: lambda x: (x + 0.5) / 1.5
293 mask_for_one = torch.add(0.3333, mask_for_one, alpha=0.6667).type_as(masked_gates)284 mask_for_one = torch.add(0.3333, mask_for_one, alpha=0.6667).type_as(masked_gates)
@@ -318,10 +309,14 @@ def sparsemixer_top2(self, scores, jitter_eps=0.01):
318 # apply mask309 # apply mask
319 masked_gates_top2 = masked_scores.masked_fill(mask_logits_threshold, float('-inf'))310 masked_gates_top2 = masked_scores.masked_fill(mask_logits_threshold, float('-inf'))
320 if self.training:311 if self.training:
321- selected_experts_top2 = (masked_gates_top2 - torch.empty_like(312+ selected_experts_top2 = (
322- masked_gates_top2, memory_format=torch.legacy_contiguous_format313+ (
323- ).exponential_().log()314+ masked_gates_top2
324- ).max(dim=-1)[1].unsqueeze(-1) # gumbel sampling, more robust than than the multinomial method315+ - torch.empty_like(masked_gates_top2, memory_format=torch.legacy_contiguous_format).exponential_().log()
316+ )
317+ .max(dim=-1)[1]
318+ .unsqueeze(-1)
319+ ) # gumbel sampling, more robust than than the multinomial method
325 else:320 else:
326 selected_experts_top2 = max_ind321 selected_experts_top2 = max_ind
327 # compute scores for gradients322 # compute scores for gradients
@@ -333,7 +328,7 @@ def sparsemixer_top2(self, scores, jitter_eps=0.01):
333 max_scores, max_ind = masked_gates_top2.max(dim=-1, keepdim=True)328 max_scores, max_ind = masked_gates_top2.max(dim=-1, keepdim=True)
334 mask_for_one_top2 = torch.logical_or(329 mask_for_one_top2 = torch.logical_or(
335 selected_experts_top2 == max_ind,330 selected_experts_top2 == max_ind,
336- torch.rand_like(max_scores).uniform_() > 0.75331+ torch.rand_like(max_scores).uniform_() > 0.75,
337 # Heun's third-order method: f(x) - f(0) = .25 f'(x) + .75 f'(x/3.)332 # Heun's third-order method: f(x) - f(0) = .25 f'(x) + .75 f'(x/3.)
338 ).int()333 ).int()
339 # 1 -> 1.0 & 0 -> 1./3: lambda x: (x + 0.5) / 1.5334 # 1 -> 1.0 & 0 -> 1./3: lambda x: (x + 0.5) / 1.5
@@ -366,11 +361,16 @@ def topk_router_build_hash_module(self):
366 361 
367 self.hash = self.layer_number <= mg_args.n_hash_layers362 self.hash = self.layer_number <= mg_args.n_hash_layers
368 if self.hash:363 if self.hash:
369- # self.tid2eid hash [vocab_size, top_k]364+ # DSv4-Pro provides a pre-trained tid2eid table in its inference checkpoint, but no
370- self.tid2eid = torch.nn.Parameter(365+ # public initialization recipe is available. This round-robin initialization is only
371- torch.stack([torch.randperm(mg_args.moe_router_topk) for _ in range(mg_args.padded_vocab_size)]),366+ # a placeholder to make hash layers runnable from scratch and is not suitable for
372- requires_grad=False367+ # real-world training.
368+ token_ids = torch.arange(mg_args.padded_vocab_size)
369+ tid2eid = torch.stack(
370+ [(token_ids + offset) % mg_args.num_experts for offset in range(mg_args.moe_router_topk)],
371+ dim=1,
373 )372 )
373+ self.tid2eid = torch.nn.Parameter(tid2eid, requires_grad=False)
374 self.expert_bias = None374 self.expert_bias = None
375 375 
376 376 
@@ -396,15 +396,16 @@ def topk_router_init_wrapper(function):
396 torch.zeros(self.num_experts, dtype=torch.float32),396 torch.zeros(self.num_experts, dtype=torch.float32),
397 persistent=False,397 persistent=False,
398 )398 )
399- self.register_buffer(399+ self.register_buffer('expert_bias', torch.zeros(self.num_experts, dtype=torch.float32))
400- 'expert_bias', torch.zeros(self.num_experts, dtype=torch.float32)
401- )
402 else:400 else:
403 self.local_tokens_per_expert = None401 self.local_tokens_per_expert = None
404 self.expert_bias = None402 self.expert_bias = None
405 403 
406- self.n_group = mg_args.moe_router_num_groups if mg_args.moe_router_num_groups is not None else (404+ self.n_group = (
407- mg_args.expert_model_parallel_size)405+ mg_args.moe_router_num_groups
406+ if mg_args.moe_router_num_groups is not None
407+ else (mg_args.expert_model_parallel_size)
408+ )
408 self.topk_group = mg_args.moe_router_group_topk409 self.topk_group = mg_args.moe_router_group_topk
409 self.norm_topk_prob = mg_args.norm_topk_prob410 self.norm_topk_prob = mg_args.norm_topk_prob
410 setattr(self.__class__, 'build_hash_module', topk_router_build_hash_module)411 setattr(self.__class__, 'build_hash_module', topk_router_build_hash_module)
@@ -412,28 +413,30 @@ def topk_router_init_wrapper(function):
412 return topk_router_init413 return topk_router_init
413 414 
414 415 
415-def topk_router_forward_patch(self, input: torch.Tensor, input_ids: torch.Tensor = None):416+def topk_router_forward_patch( # pylint: disable=redefined-builtin
416- """417+ self, input: torch.Tensor, input_ids: torch.Tensor = None
417- patch for TopKRouter forward418+):
419+ """
420+ patch for TopKRouter forward
418 421 
419- Args:422+ Args:
420- input (torch.Tensor): Input tensor.423+ input (torch.Tensor): Input tensor.
421- input_ids (torch.Tensor): Input ids.424+ input_ids (torch.Tensor): Input ids.
422- """425+ """
423- self._maintain_float32_expert_bias()426+ self._maintain_float32_expert_bias()
424 427 
425- # Apply input jitter428+ # Apply input jitter
426- input = self.apply_input_jitter(input)429+ input = self.apply_input_jitter(input)
427- logits = self.gating(input)430+ logits = self.gating(input)
428 431 
429- scores, routing_map = self.routing(logits, input_ids)432+ scores, routing_map = self.routing(logits, input_ids)
430 433 
431- return scores, routing_map434+ return scores, routing_map
432 435 
433 436 
434def apply_seq_aux_loss(self, activation, logits, topk_idx):437def apply_seq_aux_loss(self, activation, logits, topk_idx):
435 """438 """
436- Apply complementary sequence-wise auxiliary loss439+ Apply complementary sequence-wise auxiliary loss
437 """440 """
438 441 
439 args = get_args()442 args = get_args()
@@ -450,7 +453,7 @@ def apply_seq_aux_loss(self, activation, logits, topk_idx):
450 if self.expert_bias is not None:453 if self.expert_bias is not None:
451 scores = scores + self.expert_bias454 scores = scores + self.expert_bias
452 scores = scores / (scores.sum(dim=-1, keepdim=True) + 1e-20)455 scores = scores / (scores.sum(dim=-1, keepdim=True) + 1e-20)
453- elif self.score_function == "sqrtsoftplus": 456+ elif self.score_function == "sqrtsoftplus":
454 scores = F.softplus(logits).sqrt()457 scores = F.softplus(logits).sqrt()
455 if self.expert_bias is not None:458 if self.expert_bias is not None:
456 scores = scores + self.expert_bias459 scores = scores + self.expert_bias
@@ -461,8 +464,12 @@ def apply_seq_aux_loss(self, activation, logits, topk_idx):
461 scores_for_aux = scores # [s*b, n_global_experts]464 scores_for_aux = scores # [s*b, n_global_experts]
462 topk_idx_for_aux_loss = topk_idx.view(args.micro_batch_size, -1) # [b, s*top_k]465 topk_idx_for_aux_loss = topk_idx.view(args.micro_batch_size, -1) # [b, s*top_k]
463 scores_for_seq_aux = scores_for_aux.view(args.micro_batch_size, seq_length, -1)466 scores_for_seq_aux = scores_for_aux.view(args.micro_batch_size, seq_length, -1)
464- ce = torch.stack([torch.histc(x.to(torch.int32), bins=args.num_experts, min=0, max=args.num_experts) for x in467+ ce = torch.stack(
465- topk_idx_for_aux_loss])468+ [
469+ torch.histc(x.to(torch.int32), bins=args.num_experts, min=0, max=args.num_experts)
470+ for x in topk_idx_for_aux_loss
471+ ]
472+ )
466 473 
467 num_sub_sequence = 1474 num_sub_sequence = 1
468 sequence_partition_group = parallel_state.get_context_parallel_group()475 sequence_partition_group = parallel_state.get_context_parallel_group()
@@ -487,7 +494,7 @@ def apply_seq_aux_loss(self, activation, logits, topk_idx):
487 return activation494 return activation
488 495 
489 496 
490-def topk_router_gating_func(self, input: torch.Tensor):497+def topk_router_gating_func(self, input: torch.Tensor): # pylint: disable=redefined-builtin
491 _args = get_args()498 _args = get_args()
492 499 
493 if _args.router_gating_in_fp32:500 if _args.router_gating_in_fp32:
@@ -495,6 +502,7 @@ def topk_router_gating_func(self, input: torch.Tensor):
495 # if weight is not requires_grad like lora finetune, can not autograd for weight in checkpoint_manager502 # if weight is not requires_grad like lora finetune, can not autograd for weight in checkpoint_manager
496 logits = F.linear(input.type(torch.float32), self.weight.type(torch.float32))503 logits = F.linear(input.type(torch.float32), self.weight.type(torch.float32))
497 else:504 else:
505+ 
498 def to_fp32(_input, weight):506 def to_fp32(_input, weight):
499 return _input.type(torch.float32), weight.type(torch.float32)507 return _input.type(torch.float32), weight.type(torch.float32)
500 508 
@@ -507,6 +515,7 @@ def topk_router_gating_func(self, input: torch.Tensor):
507 else:515 else:
508 if self.config.moe_router_dtype == 'fp8':516 if self.config.moe_router_dtype == 'fp8':
509 from mindspeed.te.pytorch.fp8.recipes import matmul_fp8517 from mindspeed.te.pytorch.fp8.recipes import matmul_fp8
518+ 
510 logits = matmul_fp8(input, self.weight)519 logits = matmul_fp8(input, self.weight)
511 else:520 else:
512 if self.config.moe_router_dtype == 'fp32':521 if self.config.moe_router_dtype == 'fp32':
@@ -539,10 +548,8 @@ def topk_router_routing(self, logits: torch.Tensor, input_ids: torch.Tensor = No
539 logits = self.apply_z_loss(logits)548 logits = self.apply_z_loss(logits)
540 549 
541 args = get_args()550 args = get_args()
542- if (551+ dispatcher_type = self.config.moe_token_dispatcher_type
543- self.config.tensor_model_parallel_size > 1552+ if self.config.tensor_model_parallel_size > 1 and dispatcher_type == "alltoall_seq":
544- and self.config.moe_token_dispatcher_type == "alltoall_seq"
545- ):
546 # Gather the logits from the TP region553 # Gather the logits from the TP region
547 logits = gather_from_sequence_parallel_region(logits)554 logits = gather_from_sequence_parallel_region(logits)
548 555 
@@ -562,7 +569,7 @@ def topk_router_routing(self, logits: torch.Tensor, input_ids: torch.Tensor = No
562 logits_ = torch.softmax(logits, dim=-1, dtype=torch.float32)569 logits_ = torch.softmax(logits, dim=-1, dtype=torch.float32)
563 else:570 else:
564 logits_ = torch.softmax(logits, dim=-1, dtype=torch.float32).type_as(logits)571 logits_ = torch.softmax(logits, dim=-1, dtype=torch.float32).type_as(logits)
565- 572+ 
566 if self.expert_bias is not None:573 if self.expert_bias is not None:
567 logits_for_routing = logits_ + self.expert_bias574 logits_for_routing = logits_ + self.expert_bias
568 _, indices = torch.topk(logits_for_routing, k=self.topk, dim=1)575 _, indices = torch.topk(logits_for_routing, k=self.topk, dim=1)
@@ -618,11 +625,12 @@ def topk_router_routing(self, logits: torch.Tensor, input_ids: torch.Tensor = No
618 )625 )
619 args = get_args()626 args = get_args()
620 if self.training and args.seq_aux:627 if self.training and args.seq_aux:
621- scores = apply_seq_aux_loss(self,628+ scores = apply_seq_aux_loss(
622- activation=scores,629+ self,
623- logits=logits,630+ activation=scores,
624- topk_idx=routing_map,631+ logits=logits,
625- )632+ topk_idx=routing_map,
633+ )
626 else:634 else:
627 raise ValueError(f"Unsupported MoE routing type: {self.routing_type}")635 raise ValueError(f"Unsupported MoE routing type: {self.routing_type}")
628 if args.moe_tp_extend_ep:636 if args.moe_tp_extend_ep:
@@ -635,9 +643,14 @@ def topk_router_routing(self, logits: torch.Tensor, input_ids: torch.Tensor = No
635 643 
636 # fix router if needed644 # fix router if needed
637 if args.fix_router:645 if args.fix_router:
646+ 
638 def fix_indices(index_tensor, logits_shape, router_topk):647 def fix_indices(index_tensor, logits_shape, router_topk):
639- expert_select = torch.arange(index_tensor.shape[0] * router_topk, device=index_tensor.device,648+ expert_select = (
640- dtype=torch.int64).view(index_tensor.shape[0], router_topk) % logits_shape[-1]649+ torch.arange(index_tensor.shape[0] * router_topk, device=index_tensor.device, dtype=torch.int64).view(
650+ index_tensor.shape[0], router_topk
651+ )
652+ % logits_shape[-1]
653+ )
641 routing_map = torch.zeros(index_tensor.shape, device=index_tensor.device, dtype=torch.bool)654 routing_map = torch.zeros(index_tensor.shape, device=index_tensor.device, dtype=torch.bool)
642 routing_map.scatter_(1, expert_select, True)655 routing_map.scatter_(1, expert_select, True)
643 return routing_map656 return routing_map
@@ -692,7 +705,9 @@ def global_aux_loss_load_balancing(self, logits: torch.Tensor):
692 return probs, routing_map705 return probs, routing_map
693 706 
694 707 
695-def global_aux_loss_topk_router_forward(self, input: torch.Tensor):708+def global_aux_loss_topk_router_forward( # pylint: disable=redefined-builtin
709+ self, input: torch.Tensor
710+):
696 """711 """
697 Forward pass of the router.712 Forward pass of the router.
698 713 
@@ -709,6 +724,7 @@ def global_aux_loss_topk_router_forward(self, input: torch.Tensor):
709 724 
710 return scores, routing_map, logits.detach()725 return scores, routing_map, logits.detach()
711 726 
727+ 
712def global_load_balancing_loss_func(router_logits, attention_mask, config):728def global_load_balancing_loss_func(router_logits, attention_mask, config):
713 """729 """
714 Computes auxiliary load balancing loss as in Switch Transformer - implemented in Pytorch.730 Computes auxiliary load balancing loss as in Switch Transformer - implemented in Pytorch.
@@ -729,16 +745,18 @@ def global_load_balancing_loss_func(router_logits, attention_mask, config):
729 Returns:745 Returns:
730 The auxiliary loss.746 The auxiliary loss.
731 """747 """
732- 
733 if router_logits is None or not isinstance(router_logits, tuple):748 if router_logits is None or not isinstance(router_logits, tuple):
734 return 0749 return 0
735 750 
736- if isinstance(router_logits, tuple):751+ compute_device = router_logits[0].device
737- compute_device = router_logits[0].device752+ concatenated_gate_logits = torch.cat(
738- concatenated_gate_logits = torch.cat(753+ [
739- [layer_gate.to(compute_device).transpose(0, 1).reshape(-1, layer_gate.shape[2]) 754+ layer_gate.to(compute_device).transpose(0, 1).reshape(-1, layer_gate.shape[2])
740- for layer_gate in router_logits], dim=0)755+ for layer_gate in router_logits
741- 756+ ],
757+ dim=0,
758+ )
759+ 
742 top_k = config.moe_router_topk760 top_k = config.moe_router_topk
743 num_experts = concatenated_gate_logits.shape[1]761 num_experts = concatenated_gate_logits.shape[1]
744 762 
@@ -788,9 +806,10 @@ def global_load_balancing_loss_func(router_logits, attention_mask, config):
788 806 
789 return overall_loss * num_experts807 return overall_loss * num_experts
790 808 
791-# TODO remove it when megatron support sqrtsoftplus809+ 
792-def transformer_config_post_init_wrapper(fn): 810+# Remove this wrapper when Megatron supports sqrtsoftplus.
793- @wraps(fn) 811+def transformer_config_post_init_wrapper(fn):
812+ @wraps(fn)
794 def wrapper(self): #813 def wrapper(self): #
795 allowed_score_function = {"softmax", "sigmoid", "sqrtsoftplus"}814 allowed_score_function = {"softmax", "sigmoid", "sqrtsoftplus"}
796 bypass_flag = (815 bypass_flag = (
@@ -799,13 +818,14 @@ def transformer_config_post_init_wrapper(fn):
799 and getattr(self, "moe_router_score_function", None) != "sigmoid"818 and getattr(self, "moe_router_score_function", None) != "sigmoid"
800 )819 )
801 if not bypass_flag:820 if not bypass_flag:
802- return fn(self) 821+ return fn(self)
803 old_score_fn = self.moe_router_score_function822 old_score_fn = self.moe_router_score_function
804 try:823 try:
805 # bypass megatron's check824 # bypass megatron's check
806 self.moe_router_score_function = "sigmoid"825 self.moe_router_score_function = "sigmoid"
807- return fn(self) 826+ return fn(self)
808 finally:827 finally:
809 # restore user's config828 # restore user's config
810 self.moe_router_score_function = old_score_fn829 self.moe_router_score_function = old_score_fn
811- return wrapper 830+ 
831+ return wrapper