System Info
transformers version 4.36.0
Who can help?
@ArthurZucker and @younesbelkada
Information
Tasks
Reproduction
I think load_balancing_loss_func in modeling_mixtral creates router_prob_per_group_and_expert incorrectly
https://github.com/huggingface/transformers/blob/v4.36.0/src/transformers/models/mixtral/modeling_mixtral.py#L120
Trying to multiply something batch_size * num_hidden_layers, num_experts by batch_size * num_hidden_layers, topk, 1
torch.mean(tokens_per_group_and_expert * router_prob_per_group_and_expert.unsqueeze(-1)) * (num_experts**2)
Correct creation of routing_weights should likely be from gate_logits, which ensures it is the correct size
routing_weights = gate_logits.softamx(dim=-1)
The unsqueeze(-1) is necessary with this. Also router_prob_per_group_and_expert should average over axis=-2
router_prob_per_group_and_expert = torch.mean(routing_weights, axis=-2)
This follows the previous implementation in modeling_switch_transformers
https://github.com/huggingface/transformers/blob/v4.36.0/src/transformers/models/switch_transformers/modeling_switch_transformers.py#L91
Expected behavior
Something like this would fix it
def router_loss_func_test(gate_logits: torch.Tensor, top_k=2) -> float:
if gate_logits is None:
return 0
if isinstance(gate_logits, tuple):
# cat along the layers?
gate_logits = torch.cat(gate_logits, dim=0) # batch_size * num_hidden_layers, sequence_length, num_experts
num_experts = gate_logits.shape[-1]
_, expert_indicies = torch.topk(gate_logits, top_k, dim=-1) # this is done so you don't need to pass expert_indicies
routing_probs = gate_logits.softmax(dim=-1) # routing probs
if expert_indicies.dtype != torch.int64: # cast the expert indices to int64, otherwise one-hot encoding will fail
expert_indicies = expert_indicies.to(torch.int64)
if len(expert_indicies.shape) == 2:
expert_indicies = expert_indicies.unsqueeze(2)
expert_mask = torch.nn.functional.one_hot(expert_indicies, num_experts)
# For a given token, determine if it was routed to a given expert.
expert_mask = torch.max(expert_mask, axis=-2).values
expert_mask = expert_mask.to(torch.float32) # cast to float32 otherwise mean will fail
tokens_per_group_and_expert = torch.mean(expert_mask, axis=-2)
router_prob_per_group_and_expert = torch.mean(routing_probs, axis=-2)
loss = torch.mean(tokens_per_group_and_expert * router_prob_per_group_and_expert) * (num_experts**2)
return loss
System Info
transformers version 4.36.0
Who can help?
@ArthurZucker and @younesbelkada
Information
Tasks
examplesfolder (such as GLUE/SQuAD, ...)Reproduction
I think load_balancing_loss_func in modeling_mixtral creates router_prob_per_group_and_expert incorrectly
https://github.com/huggingface/transformers/blob/v4.36.0/src/transformers/models/mixtral/modeling_mixtral.py#L120
Trying to multiply something batch_size * num_hidden_layers, num_experts by batch_size * num_hidden_layers, topk, 1
torch.mean(tokens_per_group_and_expert * router_prob_per_group_and_expert.unsqueeze(-1)) * (num_experts**2)Correct creation of routing_weights should likely be from gate_logits, which ensures it is the correct size
routing_weights = gate_logits.softamx(dim=-1)The unsqueeze(-1) is necessary with this. Also router_prob_per_group_and_expert should average over axis=-2
router_prob_per_group_and_expert = torch.mean(routing_weights, axis=-2)This follows the previous implementation in modeling_switch_transformers
https://github.com/huggingface/transformers/blob/v4.36.0/src/transformers/models/switch_transformers/modeling_switch_transformers.py#L91
Expected behavior
Something like this would fix it