|
|
|
|
|
|
|
|
|
|
|
from typing import Optional, Tuple |
|
|
|
|
|
import numpy as np |
|
|
import pickle |
|
|
import torch |
|
|
import torch.nn as nn |
|
|
import torch.nn.functional as F |
|
|
from torch.nn import CrossEntropyLoss, MSELoss |
|
|
|
|
|
from torch import Tensor |
|
|
|
|
|
import copy |
|
|
|
|
|
from dataclasses import dataclass |
|
|
from transformers.activations import ACT2FN |
|
|
from transformers.file_utils import ModelOutput |
|
|
|
|
|
from transformers.models.bert.modeling_bert import ( |
|
|
BertAttention, |
|
|
BertEmbeddings, |
|
|
BertEncoder, |
|
|
BertIntermediate, |
|
|
BertLayer, |
|
|
BertModel, |
|
|
BertOutput, |
|
|
BertPooler, |
|
|
BertPreTrainedModel, |
|
|
) |
|
|
|
|
|
import logging |
|
|
logger = logging.getLogger(__name__) |
|
|
|
|
|
|
|
|
def use_experts(layer_idx): |
|
|
return True |
|
|
|
|
|
|
|
|
def process_ffn(model): |
|
|
if model.config.model_type == "bert": |
|
|
inner_model = model.bert |
|
|
else: |
|
|
raise ValueError("Model type not recognized.") |
|
|
|
|
|
for i in range(model.config.num_hidden_layers): |
|
|
model_layer = inner_model.encoder.layer[i] |
|
|
|
|
|
|
|
|
class FeedForward(nn.Module): |
|
|
def __init__(self, config, intermediate_size, dropout): |
|
|
nn.Module.__init__(self) |
|
|
|
|
|
|
|
|
self.fc1 = nn.Linear(config.hidden_size, intermediate_size) |
|
|
if isinstance(config.hidden_act, str): |
|
|
self.intermediate_act_fn = ACT2FN[config.hidden_act] |
|
|
else: |
|
|
self.intermediate_act_fn = config.hidden_act |
|
|
|
|
|
|
|
|
self.fc2 = nn.Linear(intermediate_size, config.hidden_size) |
|
|
self.LayerNorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) |
|
|
self.dropout = nn.Dropout(dropout) |
|
|
|
|
|
def forward(self, hidden_states: Tensor): |
|
|
input_tensor = hidden_states |
|
|
hidden_states = self.fc1(hidden_states) |
|
|
hidden_states = self.intermediate_act_fn(hidden_states) |
|
|
hidden_states = self.fc2(hidden_states) |
|
|
hidden_states = self.dropout(hidden_states) |
|
|
hidden_states = self.LayerNorm(hidden_states + input_tensor) |
|
|
return hidden_states |
|
|
|
|
|
|
|
|
@dataclass |
|
|
class MoEModelOutput(ModelOutput): |
|
|
last_hidden_state: torch.FloatTensor = None |
|
|
past_key_values: Optional[Tuple[Tuple[torch.FloatTensor]]] = None |
|
|
hidden_states: Optional[Tuple[torch.FloatTensor]] = None |
|
|
attentions: Optional[Tuple[torch.FloatTensor]] = None |
|
|
cross_attentions: Optional[Tuple[torch.FloatTensor]] = None |
|
|
gate_loss: torch.FloatTensor = None |
|
|
|
|
|
|
|
|
@dataclass |
|
|
class MoEModelOutputWithPooling(ModelOutput): |
|
|
last_hidden_state: torch.FloatTensor = None |
|
|
pooler_output: torch.FloatTensor = None |
|
|
hidden_states: Optional[Tuple[torch.FloatTensor]] = None |
|
|
past_key_values: Optional[Tuple[Tuple[torch.FloatTensor]]] = None |
|
|
attentions: Optional[Tuple[torch.FloatTensor]] = None |
|
|
cross_attentions: Optional[Tuple[torch.FloatTensor]] = None |
|
|
gate_loss: torch.FloatTensor = None |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class MoELayer(nn.Module): |
|
|
def __init__(self, hidden_size, num_experts, expert, route_method, vocab_size, hash_list): |
|
|
nn.Module.__init__(self) |
|
|
self.num_experts = num_experts |
|
|
self.experts = nn.ModuleList([copy.deepcopy(expert) for i in range(num_experts)]) |
|
|
self.route_method = route_method |
|
|
if route_method in ["gate-token", "gate-sentence"]: |
|
|
self.gate = nn.Linear(hidden_size, num_experts, bias=False).float() |
|
|
elif route_method == "hash-random": |
|
|
self.hash_list = self._random_hash_list(vocab_size) |
|
|
elif route_method == "hash-balance": |
|
|
self.hash_list = self._balance_hash_list(hash_list) |
|
|
else: |
|
|
raise KeyError("Routing method not supported.") |
|
|
|
|
|
def _random_hash_list(self, vocab_size): |
|
|
hash_list = torch.randint(low=0, high=self.num_experts, size=(vocab_size,)) |
|
|
return hash_list |
|
|
|
|
|
def _balance_hash_list(self, hash_list): |
|
|
with open(hash_list, "rb") as file: |
|
|
result = pickle.load(file) |
|
|
result = torch.tensor(result, dtype=torch.int64) |
|
|
return result |
|
|
|
|
|
def _forward_gate_token(self, x): |
|
|
bsz, seq_len, dim = x.size() |
|
|
|
|
|
x = x.view(-1, dim) |
|
|
logits_gate = self.gate(x) |
|
|
prob_gate = F.softmax(logits_gate, dim=-1) |
|
|
gate = torch.argmax(prob_gate, dim=-1) |
|
|
|
|
|
order = gate.argsort(0) |
|
|
num_tokens = F.one_hot(gate, self.num_experts).gt(0).sum(0) |
|
|
gate_load = num_tokens.clone() |
|
|
x = x[order] |
|
|
x = x.split(num_tokens.tolist(), dim=0) |
|
|
|
|
|
|
|
|
P = prob_gate.mean(0) |
|
|
temp = num_tokens.float() |
|
|
f = temp / temp.sum(0, keepdim=True) |
|
|
balance_loss = self.num_experts * torch.sum(P * f) |
|
|
|
|
|
prob_gate = prob_gate.gather(dim=1, index=gate.unsqueeze(1)) |
|
|
prob_gate = prob_gate[order] |
|
|
prob_gate = prob_gate.split(num_tokens.tolist(), dim=0) |
|
|
|
|
|
def forward_expert(input_x, prob_x, expert_idx): |
|
|
input_x = self.experts[expert_idx].forward(input_x) |
|
|
input_x = input_x * prob_x |
|
|
return input_x |
|
|
|
|
|
x = [forward_expert(x[i], prob_gate[i], i) for i in range(self.num_experts)] |
|
|
x = torch.vstack(x) |
|
|
x = x[order.argsort(0)] |
|
|
x = x.view(bsz, seq_len, dim) |
|
|
|
|
|
return x, balance_loss, gate_load |
|
|
|
|
|
def _forward_gate_sentence(self, x, attention_mask): |
|
|
x_masked = x * attention_mask.unsqueeze(-1) |
|
|
x_average = x_masked.sum(1) / attention_mask.unsqueeze(-1).sum(1) |
|
|
logits_gate = self.gate(x_average) |
|
|
prob_gate = F.softmax(logits_gate, dim=-1) |
|
|
gate = torch.argmax(prob_gate, dim=-1) |
|
|
|
|
|
order = gate.argsort(0) |
|
|
num_sentences = F.one_hot(gate, self.num_experts).gt(0).sum(0) |
|
|
gate_load = num_sentences.clone() |
|
|
x = x[order] |
|
|
x = x.split(num_sentences.tolist(), dim=0) |
|
|
|
|
|
|
|
|
P = prob_gate.mean(0) |
|
|
temp = num_sentences.float() |
|
|
f = temp / temp.sum(0, keepdim=True) |
|
|
balance_loss = self.num_experts * torch.sum(P * f) |
|
|
|
|
|
prob_gate = prob_gate.gather(dim=1, index=gate.unsqueeze(1)) |
|
|
prob_gate = prob_gate[order] |
|
|
prob_gate = prob_gate.split(num_sentences.tolist(), dim=0) |
|
|
|
|
|
def forward_expert(input_x, prob_x, expert_idx): |
|
|
input_x = self.experts[expert_idx].forward(input_x) |
|
|
input_x = input_x * prob_x.unsqueeze(-1) |
|
|
return input_x |
|
|
|
|
|
result = [] |
|
|
for i in range(self.num_experts): |
|
|
if x[i].size(0) > 0: |
|
|
result.append(forward_expert(x[i], prob_gate[i], i)) |
|
|
result = torch.vstack(result) |
|
|
result = result[order.argsort(0)] |
|
|
|
|
|
return result, balance_loss, gate_load |
|
|
|
|
|
def _forward_sentence_single_expert(self, x, attention_mask): |
|
|
x_masked = x * attention_mask.unsqueeze(-1) |
|
|
x_average = x_masked.sum(1) / attention_mask.unsqueeze(-1).sum(1) |
|
|
logits_gate = self.gate(x_average) |
|
|
prob_gate = F.softmax(logits_gate, dim=-1) |
|
|
gate = torch.argmax(prob_gate, dim=-1) |
|
|
|
|
|
gate_load = F.one_hot(gate, self.num_experts).gt(0).sum(0) |
|
|
x = self.experts[gate.cpu().item()].forward(x) |
|
|
return x, 0.0, gate_load |
|
|
|
|
|
def _forward_hash(self, x, input_ids): |
|
|
bsz, seq_len, dim = x.size() |
|
|
|
|
|
x = x.view(-1, dim) |
|
|
self.hash_list = self.hash_list.to(x.device) |
|
|
gate = self.hash_list[input_ids.view(-1)] |
|
|
|
|
|
order = gate.argsort(0) |
|
|
num_tokens = F.one_hot(gate, self.num_experts).gt(0).sum(0) |
|
|
gate_load = num_tokens.clone() |
|
|
x = x[order] |
|
|
x = x.split(num_tokens.tolist(), dim=0) |
|
|
|
|
|
x = [self.experts[i].forward(x[i]) for i in range(self.num_experts)] |
|
|
x = torch.vstack(x) |
|
|
x = x[order.argsort(0)] |
|
|
x = x.view(bsz, seq_len, dim) |
|
|
|
|
|
return x, 0.0, gate_load |
|
|
|
|
|
def forward(self, x, input_ids, attention_mask): |
|
|
if self.route_method == "gate-token": |
|
|
x, balance_loss, gate_load = self._forward_gate_token(x) |
|
|
elif self.route_method == "gate-sentence": |
|
|
if x.size(0) == 1: |
|
|
x, balance_loss, gate_load = self._forward_sentence_single_expert(x, attention_mask) |
|
|
else: |
|
|
x, balance_loss, gate_load = self._forward_gate_sentence(x, attention_mask) |
|
|
elif self.route_method in ["hash-random", "hash-balance"]: |
|
|
x, balance_loss, gate_load = self._forward_hash(x, input_ids) |
|
|
else: |
|
|
raise KeyError("Routing method not supported.") |
|
|
|
|
|
return x, balance_loss, gate_load |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def symmetric_KL_loss(p, q): |
|
|
""" symmetric KL-divergence 1/2*(KL(p||q)+KL(q||p)) """ |
|
|
p, q = p.float(), q.float() |
|
|
loss = (p - q) * (torch.log(p) - torch.log(q)) |
|
|
return 0.5 * loss.sum() |
|
|
|
|
|
|
|
|
def softmax(x): |
|
|
return F.softmax(x, dim=-1, dtype=torch.float32) |
|
|
|
|
|
|
|
|
class MoEBertLayer(BertLayer): |
|
|
def __init__(self, config, layer_idx=-100): |
|
|
nn.Module.__init__(self) |
|
|
self.chunk_size_feed_forward = config.chunk_size_feed_forward |
|
|
self.seq_len_dim = 1 |
|
|
self.attention = BertAttention(config) |
|
|
self.is_decoder = config.is_decoder |
|
|
self.add_cross_attention = config.add_cross_attention |
|
|
if self.add_cross_attention: |
|
|
assert self.is_decoder, f"{self} should be used as a decoder model if cross attention is added" |
|
|
self.crossattention = BertAttention(config) |
|
|
self.intermediate = BertIntermediate(config) |
|
|
self.output = BertOutput(config) |
|
|
|
|
|
|
|
|
self.use_experts = use_experts(layer_idx) |
|
|
dropout = config.moebert_expert_dropout if self.use_experts else config.hidden_dropout_prob |
|
|
if self.use_experts: |
|
|
ffn = FeedForward(config, config.moebert_expert_dim, dropout) |
|
|
self.experts = MoELayer( |
|
|
hidden_size=config.hidden_size, |
|
|
expert=ffn, |
|
|
num_experts=config.moebert_expert_num, |
|
|
route_method=config.moebert_route_method, |
|
|
vocab_size=config.vocab_size, |
|
|
hash_list=config.moebert_route_hash_list, |
|
|
) |
|
|
else: |
|
|
self.experts = FeedForward(config, config.intermediate_size, dropout) |
|
|
|
|
|
def forward( |
|
|
self, |
|
|
hidden_states, |
|
|
attention_mask=None, |
|
|
head_mask=None, |
|
|
encoder_hidden_states=None, |
|
|
encoder_attention_mask=None, |
|
|
past_key_value=None, |
|
|
output_attentions=False, |
|
|
expert_input_ids=None, |
|
|
expert_attention_mask=None, |
|
|
): |
|
|
|
|
|
self_attn_past_key_value = past_key_value[:2] if past_key_value is not None else None |
|
|
self_attention_outputs = self.attention( |
|
|
hidden_states, |
|
|
attention_mask, |
|
|
head_mask, |
|
|
output_attentions=output_attentions, |
|
|
past_key_value=self_attn_past_key_value, |
|
|
) |
|
|
attention_output = self_attention_outputs[0] |
|
|
|
|
|
|
|
|
if self.is_decoder: |
|
|
outputs = self_attention_outputs[1:-1] |
|
|
present_key_value = self_attention_outputs[-1] |
|
|
else: |
|
|
outputs = self_attention_outputs[1:] |
|
|
|
|
|
cross_attn_present_key_value = None |
|
|
if self.is_decoder and encoder_hidden_states is not None: |
|
|
assert hasattr( |
|
|
self, "crossattention" |
|
|
), f"If `encoder_hidden_states` are passed, {self} has to be instantiated with cross-attention layers by setting `config.add_cross_attention=True`" |
|
|
|
|
|
|
|
|
cross_attn_past_key_value = past_key_value[-2:] if past_key_value is not None else None |
|
|
cross_attention_outputs = self.crossattention( |
|
|
attention_output, |
|
|
attention_mask, |
|
|
head_mask, |
|
|
encoder_hidden_states, |
|
|
encoder_attention_mask, |
|
|
cross_attn_past_key_value, |
|
|
output_attentions, |
|
|
) |
|
|
attention_output = cross_attention_outputs[0] |
|
|
outputs = outputs + cross_attention_outputs[1:-1] |
|
|
|
|
|
|
|
|
cross_attn_present_key_value = cross_attention_outputs[-1] |
|
|
present_key_value = present_key_value + cross_attn_present_key_value |
|
|
|
|
|
layer_output = self.feed_forward(attention_output, expert_input_ids, expert_attention_mask) |
|
|
outputs = (layer_output,) + outputs |
|
|
|
|
|
|
|
|
if self.is_decoder: |
|
|
outputs = outputs + (present_key_value,) |
|
|
|
|
|
return outputs |
|
|
|
|
|
def feed_forward(self, attention_output, expert_input_ids, expert_attention_mask): |
|
|
if not self.use_experts: |
|
|
layer_output = self.experts(attention_output) |
|
|
return layer_output, 0.0 |
|
|
|
|
|
layer_output, gate_loss, gate_load = self.experts( |
|
|
attention_output, expert_input_ids, expert_attention_mask |
|
|
) |
|
|
return layer_output, gate_loss |
|
|
|
|
|
|
|
|
class MoEBertEncoder(BertEncoder): |
|
|
def __init__(self, config): |
|
|
nn.Module.__init__(self) |
|
|
self.config = config |
|
|
self.layer = nn.ModuleList([MoEBertLayer(config, i) for i in range(config.num_hidden_layers)]) |
|
|
|
|
|
def forward( |
|
|
self, |
|
|
hidden_states, |
|
|
attention_mask=None, |
|
|
head_mask=None, |
|
|
encoder_hidden_states=None, |
|
|
encoder_attention_mask=None, |
|
|
past_key_values=None, |
|
|
use_cache=None, |
|
|
output_attentions=False, |
|
|
output_hidden_states=False, |
|
|
return_dict=True, |
|
|
expert_input_ids=None, |
|
|
expert_attention_mask=None, |
|
|
): |
|
|
all_hidden_states = () if output_hidden_states else None |
|
|
all_self_attentions = () if output_attentions else None |
|
|
all_cross_attentions = () if output_attentions and self.config.add_cross_attention else None |
|
|
|
|
|
next_decoder_cache = () if use_cache else None |
|
|
gate_loss = 0.0 |
|
|
for i, layer_module in enumerate(self.layer): |
|
|
if output_hidden_states: |
|
|
all_hidden_states = all_hidden_states + (hidden_states,) |
|
|
|
|
|
layer_head_mask = head_mask[i] if head_mask is not None else None |
|
|
past_key_value = past_key_values[i] if past_key_values is not None else None |
|
|
|
|
|
if getattr(self.config, "gradient_checkpointing", False) and self.training: |
|
|
|
|
|
if use_cache: |
|
|
logger.warn( |
|
|
"`use_cache=True` is incompatible with `config.gradient_checkpointing=True`. Setting " |
|
|
"`use_cache=False`..." |
|
|
) |
|
|
use_cache = False |
|
|
|
|
|
def create_custom_forward(module): |
|
|
def custom_forward(*inputs): |
|
|
return module(*inputs, past_key_value, output_attentions) |
|
|
|
|
|
return custom_forward |
|
|
|
|
|
layer_outputs = torch.utils.checkpoint.checkpoint( |
|
|
create_custom_forward(layer_module), |
|
|
hidden_states, |
|
|
attention_mask, |
|
|
layer_head_mask, |
|
|
encoder_hidden_states, |
|
|
encoder_attention_mask, |
|
|
) |
|
|
else: |
|
|
layer_outputs = layer_module( |
|
|
hidden_states, |
|
|
attention_mask, |
|
|
layer_head_mask, |
|
|
encoder_hidden_states, |
|
|
encoder_attention_mask, |
|
|
past_key_value, |
|
|
output_attentions, |
|
|
expert_input_ids, |
|
|
expert_attention_mask, |
|
|
) |
|
|
|
|
|
hidden_states = layer_outputs[0][0] |
|
|
gate_loss = gate_loss + layer_outputs[0][1] |
|
|
if use_cache: |
|
|
next_decoder_cache += (layer_outputs[-1],) |
|
|
if output_attentions: |
|
|
all_self_attentions = all_self_attentions + (layer_outputs[1],) |
|
|
if self.config.add_cross_attention: |
|
|
all_cross_attentions = all_cross_attentions + (layer_outputs[2],) |
|
|
|
|
|
if output_hidden_states: |
|
|
all_hidden_states = all_hidden_states + (hidden_states,) |
|
|
|
|
|
if not return_dict: |
|
|
return tuple( |
|
|
v |
|
|
for v in [ |
|
|
hidden_states, |
|
|
next_decoder_cache, |
|
|
all_hidden_states, |
|
|
all_self_attentions, |
|
|
all_cross_attentions, |
|
|
] |
|
|
if v is not None |
|
|
) |
|
|
return MoEModelOutput( |
|
|
last_hidden_state=hidden_states, |
|
|
past_key_values=next_decoder_cache, |
|
|
hidden_states=all_hidden_states, |
|
|
attentions=all_self_attentions, |
|
|
cross_attentions=all_cross_attentions, |
|
|
gate_loss=gate_loss, |
|
|
) |
|
|
|
|
|
|
|
|
class MoEBertModel(BertModel): |
|
|
def __init__(self, config, add_pooling_layer=True): |
|
|
BertModel.__init__(self, config) |
|
|
self.config = config |
|
|
|
|
|
self.embeddings = BertEmbeddings(config) |
|
|
self.encoder = MoEBertEncoder(config) |
|
|
|
|
|
self.pooler = BertPooler(config) if add_pooling_layer else None |
|
|
|
|
|
self.init_weights() |
|
|
|
|
|
def forward( |
|
|
self, |
|
|
input_ids=None, |
|
|
attention_mask=None, |
|
|
token_type_ids=None, |
|
|
position_ids=None, |
|
|
head_mask=None, |
|
|
inputs_embeds=None, |
|
|
encoder_hidden_states=None, |
|
|
encoder_attention_mask=None, |
|
|
past_key_values=None, |
|
|
use_cache=None, |
|
|
output_attentions=None, |
|
|
output_hidden_states=None, |
|
|
return_dict=None, |
|
|
expert_input_ids=None, |
|
|
expert_attention_mask=None, |
|
|
): |
|
|
output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions |
|
|
output_hidden_states = ( |
|
|
output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states |
|
|
) |
|
|
return_dict = return_dict if return_dict is not None else self.config.use_return_dict |
|
|
|
|
|
if self.config.is_decoder: |
|
|
use_cache = use_cache if use_cache is not None else self.config.use_cache |
|
|
else: |
|
|
use_cache = False |
|
|
|
|
|
if input_ids is not None and inputs_embeds is not None: |
|
|
raise ValueError("You cannot specify both input_ids and inputs_embeds at the same time") |
|
|
elif input_ids is not None: |
|
|
input_shape = input_ids.size() |
|
|
batch_size, seq_length = input_shape |
|
|
elif inputs_embeds is not None: |
|
|
input_shape = inputs_embeds.size()[:-1] |
|
|
batch_size, seq_length = input_shape |
|
|
else: |
|
|
raise ValueError("You have to specify either input_ids or inputs_embeds") |
|
|
|
|
|
device = input_ids.device if input_ids is not None else inputs_embeds.device |
|
|
|
|
|
|
|
|
past_key_values_length = past_key_values[0][0].shape[2] if past_key_values is not None else 0 |
|
|
|
|
|
if attention_mask is None: |
|
|
attention_mask = torch.ones(((batch_size, seq_length + past_key_values_length)), device=device) |
|
|
if token_type_ids is None: |
|
|
token_type_ids = torch.zeros(input_shape, dtype=torch.long, device=device) |
|
|
|
|
|
|
|
|
|
|
|
extended_attention_mask: torch.Tensor = self.get_extended_attention_mask(attention_mask, input_shape, device) |
|
|
|
|
|
|
|
|
|
|
|
if self.config.is_decoder and encoder_hidden_states is not None: |
|
|
encoder_batch_size, encoder_sequence_length, _ = encoder_hidden_states.size() |
|
|
encoder_hidden_shape = (encoder_batch_size, encoder_sequence_length) |
|
|
if encoder_attention_mask is None: |
|
|
encoder_attention_mask = torch.ones(encoder_hidden_shape, device=device) |
|
|
encoder_extended_attention_mask = self.invert_attention_mask(encoder_attention_mask) |
|
|
else: |
|
|
encoder_extended_attention_mask = None |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
head_mask = self.get_head_mask(head_mask, self.config.num_hidden_layers) |
|
|
|
|
|
embedding_output = self.embeddings( |
|
|
input_ids=input_ids, |
|
|
position_ids=position_ids, |
|
|
token_type_ids=token_type_ids, |
|
|
inputs_embeds=inputs_embeds, |
|
|
past_key_values_length=past_key_values_length, |
|
|
) |
|
|
encoder_outputs = self.encoder( |
|
|
embedding_output, |
|
|
attention_mask=extended_attention_mask, |
|
|
head_mask=head_mask, |
|
|
encoder_hidden_states=encoder_hidden_states, |
|
|
encoder_attention_mask=encoder_extended_attention_mask, |
|
|
past_key_values=past_key_values, |
|
|
use_cache=use_cache, |
|
|
output_attentions=output_attentions, |
|
|
output_hidden_states=output_hidden_states, |
|
|
return_dict=return_dict, |
|
|
expert_input_ids=expert_input_ids, |
|
|
expert_attention_mask=expert_attention_mask, |
|
|
) |
|
|
sequence_output = encoder_outputs[0] |
|
|
pooled_output = self.pooler(sequence_output) if self.pooler is not None else None |
|
|
|
|
|
if not return_dict: |
|
|
return (sequence_output, pooled_output) + encoder_outputs[1:] |
|
|
|
|
|
return MoEModelOutputWithPooling( |
|
|
last_hidden_state=sequence_output, |
|
|
pooler_output=pooled_output, |
|
|
past_key_values=encoder_outputs.past_key_values, |
|
|
hidden_states=encoder_outputs.hidden_states, |
|
|
attentions=encoder_outputs.attentions, |
|
|
cross_attentions=encoder_outputs.cross_attentions, |
|
|
gate_loss=encoder_outputs.gate_loss, |
|
|
) |
|
|
|