Yuan3.0-Flash / modeling_yuanlm2.py
root
update code
4e18cb4
# coding=utf-8
# Copyright 2022 YuanLabAI and the HuggingFace Inc. team. All rights reserved.
#
# This code is based on EleutherAI's GPT-NeoX library and the GPT-NeoX
# and OPT implementations in this library. It has been modified from its
# original forms to accommodate minor architectural differences compared
# to GPT-NeoX and OPT used by the Meta AI team that trained the model.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
""" PyTorch Yuan model."""
import math
from typing import List, Optional, Tuple, Union
import torch.nn.functional as F
import torch
import torch.utils.checkpoint
from torch import einsum, nn
from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss
from transformers.activations import ACT2FN
from transformers.modeling_outputs import BaseModelOutputWithPast, CausalLMOutputWithPast, SequenceClassifierOutputWithPast
from transformers.modeling_utils import PreTrainedModel
from transformers.utils import add_start_docstrings, add_start_docstrings_to_model_forward, logging, replace_return_docstrings
from configuration_yuan import YuanConfig
from einops import rearrange
# from flash_attn import flash_attn_varlen_func as flash_attn_unpadded_func
#from apex.normalization import MixedFusedRMSNorm as RMSNorm
#from flash_attn import flash_attn_func
from transformer_engine.pytorch import RMSNorm
import copy
try:
import grouped_gemm as gg
except ImportError:
gg = None
try:
from flash_attn import flash_attn_varlen_func as flash_attn_unpadded_func
from flash_attn import flash_attn_func
except ImportError:
flash_attn_unpadded_func = None
logger = logging.get_logger(__name__)
_CONFIG_FOR_DOC = "YuanConfig"
class YuanRotaryEmbedding(nn.Module):
def __init__(self, dim, base=10000, dtype=torch.float32, rotary_interleaved=False, seq_len_interpolation_factor=None):
super().__init__()
self.base = base
self.dim = dim
self.rotary_interleaved = rotary_interleaved
self.seq_len_interpolation_factor = seq_len_interpolation_factor
def get_rotary_seq_len(
self,
inference_param=None,
transformer_input: torch.Tensor=None,
transformer_config=None,
):
if inference_param is not None:
rotary_seq_len = inference_param.max_sequence_length
else:
rotary_seq_len = transformer_input.size[0]
if transformer_config.sequence_parallel:
rotary_seq_len *= transformer_config.tensor_model_parallel_size
return rotary_seq_len
def forward(self, max_seq_len, offset=0):
"""Forward pass of RoPE embedding.
Args:
max_seq_len (int): Maximum size of sequence
offset (int, optional): _description_. Defaults to 0.
Returns:
Tensor: Embeddings after applying RoPE.
"""
inv_freq = (1.0 / ( self.base**(torch.arange(0, self.dim, 2, dtype=torch.float32, device=torch.cuda.current_device()) / self.dim))).to(torch.float32)
#max_seq_len_int = max_seq_len.item() if max_seq_len.numel() == 1 else max_seq_len.max().item()
seq = (
torch.arange(max_seq_len, device=inv_freq.device, dtype=inv_freq.dtype)
+ offset
)
if self.seq_len_interpolation_factor is not None:
seq *= 1 / self.seq_len_interpolation_factor
freqs = torch.outer(seq, inv_freq)
# first part even vector components, second part odd vector components,
# 2 * dim in dimension size
if not self.rotary_interleaved:
emb = torch.cat((freqs, freqs), dim=-1)
else:
emb = torch.stack((freqs.view(-1, 1), freqs.view(-1, 1)), dim=-1).view(
freqs.shape[0], -1
)
# emb [seq_length, .., dim]
emb = emb[:, None, None, :]
return emb
def _rotate_half(x, rotary_interleaved):
if not rotary_interleaved:
x1, x2 = torch.chunk(x, 2, dim=-1)
return torch.cat((-x2, x1), dim=-1)
else:
x1 = x[:, :, :, ::2]
x2 = x[:, :, :, 1::2]
x_new = torch.stack((-x2, x1), dim=-1)
return x_new.view(x_new.shape[0], x_new.shape[1], x_new.shape[2], -1)
def apply_rotary_pos_emb(t, freqs, position_ids, rotary_interleaved=False):
rot_dim = freqs.shape[-1]
#if position_ids.shape[1] > 1:
freqs = freqs[position_ids]
freqs = freqs.view(t.shape[1],freqs.shape[1],freqs.shape[2],freqs.shape[4]).transpose(0,1)
# ideally t_pass is empty so rotary pos embedding is applied to all tensor t
t, t_pass = t[..., :rot_dim], t[..., rot_dim:]
# first part is cosine component
# second part is sine component, need to change signs with _rotate_half method
t_type = t.dtype
cos_ = torch.cos(freqs).to(t.dtype)
sin_ = torch.sin(freqs).to(t.dtype)
t = (t * cos_) + (_rotate_half(t, rotary_interleaved) * sin_)
return torch.cat((t, t_pass), dim=-1)
return torch.cat((t, t_pass), dim=-1)
class LocalizedFiltering(torch.nn.Module):
"""
Mega's Exponential Moving Average layer, largely left unmodified from the original repo with the exception of
variable names and moving away from the stateful representation of incremental decoding state. See
"https://arxiv.org/abs/2209.10655" for more details.
"""
def __init__(self, hidden_size, lf_conv2d_group, lf_conv2d_num_pad):
super().__init__()
self.embed_dim = hidden_size
self.lf_conv2d_group = lf_conv2d_group
self.lf_conv2d_num_pad = lf_conv2d_num_pad
if self.lf_conv2d_num_pad == 1:
self.training = True
self.conv1 = torch.nn.Conv2d(self.embed_dim, self.embed_dim // 2, (2, 1), stride=(1, 1), padding=(self.lf_conv2d_num_pad, 0), groups=self.lf_conv2d_group)
self.conv2 = torch.nn.Conv2d(self.embed_dim // 2, self.embed_dim, (2, 1), stride=(1, 1), padding=(self.lf_conv2d_num_pad, 0), groups=self.lf_conv2d_group)
self.output_layernorm = RMSNorm(self.embed_dim, eps=1e-6)
def _train_forward(self, inputs):
inputs = inputs.transpose(0,1)
seq_len, bsz, embed_dim = inputs.size()
if embed_dim != self.embed_dim:
raise ValueError(
f"Unexpected embedding dimension received: input is {embed_dim}, model expects {self.embed_dim}"
)
residual = inputs
inputs = inputs.view(seq_len, 1, bsz, embed_dim).permute(2, 3, 0, 1)
output1 = self.conv1(inputs)
output1 = output1[:, :, :seq_len, :]
output2 = self.conv2(output1)
output2 = output2[:, :, :seq_len, :].permute(2, 3, 0, 1).contiguous()
output2 = output2.view(seq_len, bsz, embed_dim)
assert output2.shape == residual.shape
torch.cuda.set_device(output2.device)
lf_output = self.output_layernorm(output2 + residual)
lf_output = lf_output.transpose(0,1)
return lf_output
def _inference_forward(self, inputs, before_hidden_states):
if before_hidden_states is None:
residual = inputs
seq_len, bsz, embed_dim = inputs.size()
inputs = inputs.view(seq_len, 1, bsz, embed_dim).permute(2, 3, 0, 1)
pad_zero1 = torch.zeros(bsz, embed_dim, 1, 1).to(inputs)
inputs = torch.cat((pad_zero1, inputs), dim=2).contiguous()
output1 = self.conv1(inputs)
pad_zero2 = torch.zeros(bsz, embed_dim // 2, 1, 1).to(output1)
output1 = torch.cat((pad_zero2, output1), dim=2).contiguous()
output2 = self.conv2(output1)
output2 = output2.permute(2, 3, 0, 1).contiguous()
output2 = output2.view(seq_len, bsz, embed_dim)
assert output2.shape == residual.shape
lf_output = self.output_layernorm(output2 + residual)
else:
residual = inputs
seq_len, bsz, embed_dim = inputs.size()
seq_len_before, _, _ = before_hidden_states.size()
assert seq_len == 1 and seq_len_before == 2
inputs = torch.cat((before_hidden_states, inputs), dim=0)
inputs = inputs.view(3, 1, bsz, embed_dim).permute(2, 3, 0, 1)
output1 = self.conv1(inputs)
output2 = self.conv2(output1)
output2 = output2.view(1, bsz, embed_dim)
assert output2.shape == residual.shape
lf_output = self.output_layernorm(output2 + residual)
return lf_output
def forward(
self,
inputs,
before_hidden_states = None,
) -> torch.Tensor:
# assert self.lf_conv2d_num_pad == 1
if self.training:
lf_output = self._train_forward(inputs)
else:
lf_output = self._inference_forward(inputs, before_hidden_states)
return lf_output
# Copied from transformers.models.bart.modeling_bart._make_causal_mask
def _make_causal_mask(
input_ids_shape: torch.Size, dtype: torch.dtype, device: torch.device, past_key_values_length: int = 0
):
"""
Make causal mask used for bi-directional self-attention.
"""
bsz, tgt_len = input_ids_shape
mask = torch.full((tgt_len, tgt_len), torch.tensor(torch.finfo(dtype).min, device=device), device=device)
mask_cond = torch.arange(mask.size(-1), device=device)
mask.masked_fill_(mask_cond < (mask_cond + 1).view(mask.size(-1), 1), 0)
mask = mask.to(dtype)
if past_key_values_length > 0:
mask = torch.cat([torch.zeros(tgt_len, past_key_values_length, dtype=dtype, device=device), mask], dim=-1)
return mask[None, None, :, :].expand(bsz, 1, tgt_len, tgt_len + past_key_values_length)
# Copied from transformers.models.bart.modeling_bart._expand_mask
def _expand_mask(mask: torch.Tensor, dtype: torch.dtype, tgt_len: Optional[int] = None):
"""
Expands attention_mask from `[bsz, seq_len]` to `[bsz, 1, tgt_seq_len, src_seq_len]`.
"""
bsz, src_len = mask.size()
tgt_len = tgt_len if tgt_len is not None else src_len
expanded_mask = mask[:, None, None, :].expand(bsz, 1, tgt_len, src_len).to(dtype)
inverted_mask = 1.0 - expanded_mask
return inverted_mask.masked_fill(inverted_mask.to(torch.bool), torch.finfo(dtype).min)
class YuanRMSNorm(nn.Module):
def __init__(self, hidden_size, eps=1e-6):
"""
YuanRMSNorm is equivalent to LlamaRMSNorm
"""
super().__init__()
self.weight = nn.Parameter(torch.ones(hidden_size))
self.variance_epsilon = eps
def forward(self, hidden_states):
input_dtype = hidden_states.dtype
hidden_states = hidden_states.to(torch.float32)
variance = hidden_states.pow(2).mean(-1, keepdim=True)
hidden_states = hidden_states * torch.rsqrt(variance + self.variance_epsilon)
return self.weight * hidden_states.to(input_dtype)
# flash attn
class FlashSelfAttention(torch.nn.Module):
"""Implement the scaled dot product attention with softmax.
Arguments
---------
softmax_scale: The temperature to use for the softmax attention.
(default: 1/sqrt(d_keys) where d_keys is computed at
runtime)
attention_dropout: The dropout rate to apply to the attention
(default: 0.0)
"""
def __init__(self, causal=False, softmax_scale=None, attention_dropout=0.0,
device=None, dtype=None):
super().__init__()
assert flash_attn_unpadded_func is not None, ('Please install FlashAttention first, '
'e.g., with pip install flash-attn')
assert rearrange is not None, 'Please install einops first, e.g., with pip install einops'
self.causal = causal
self.softmax_scale = softmax_scale
self.dropout_p = attention_dropout
def forward(self, q, k, v):
"""Implements the multihead softmax attention.
Arguments
---------
q, k, v: The tensor containing the query, key, and value. (B, S, H, D)
"""
assert all((i.dtype in [torch.float16, torch.bfloat16] for i in (q,k,v)))
assert all((i.is_cuda for i in (q,k,v)))
batch_size, seqlen_q = q.shape[1], q.shape[0]
seqlen_k = k.shape[0]
q, k, v = [rearrange(x, 'b s ... -> (b s) ...') for x in [q, k, v]]
cu_seqlens_q = torch.arange(0, (batch_size + 1) * seqlen_q, step=seqlen_q, dtype=torch.int32, device=q.device)
if self.training:
# during training q,k,v always have same seqlen
assert seqlen_k == seqlen_q
is_causal = self.causal
cu_seqlens_k = cu_seqlens_q
dropout_p = self.dropout_p
else:
# turn off FA causal mask after first inference autoregressive iteration
# only on first autoregressive step q,k,v have same seqlen
is_causal = seqlen_q == seqlen_k
cu_seqlens_k = torch.arange(0, (batch_size + 1) * seqlen_k, step=seqlen_k, dtype=torch.int32, device=q.device)
dropout_p = 0
output = flash_attn_unpadded_func(q, k, v, cu_seqlens_q, cu_seqlens_k, seqlen_q, seqlen_k, dropout_p, softmax_scale=self.softmax_scale, causal=is_causal)
output = rearrange(output, '(b s) ... -> b s ...', b=batch_size)
return output
class ParallelAttention_router(nn.Module):
def __init__(self, config):
super(ParallelAttention_router, self).__init__()
layer_number=0
self.layer_number = max(1, layer_number)
self.hidden_size = config.hidden_size
self.projection_size = config.moe_config['moe_num_experts']
self.num_attention_router_heads = config.moe_config['num_attention_router_heads']
self.hidden_size_per_attention_head = config.max_position_embeddings // self.num_attention_router_heads
self.query_key_value = nn.Linear(self.hidden_size, self.projection_size*3, bias=False)
def forward(self, hidden_states, attention_mask=None, enc_position_ids=None,
encoder_output=None, inference_params=None,
rotary_pos_emb=None):
is_first_step = False
before_hidden_states = None
#mixed_x_layer = torch.matmul(hidden_states, self.query_key_value)
mixed_x_layer = self.query_key_value(hidden_states)
(query_layer, key_layer, value_layer) = torch.split(mixed_x_layer, self.projection_size, -1)
b, s, z = query_layer.shape
# use fp32 router
query_layer = query_layer.float().view(b,s,z,1)
key_layer = key_layer.float().view(b,s,z,1)
value_layer = value_layer.float().view(b,s,z,1)
attn_weights = torch.matmul(query_layer, key_layer.transpose(2, 3))
attn_weights = nn.functional.softmax(attn_weights, dim=-1)
attn_output = torch.matmul(attn_weights, value_layer)
router_output = attn_output.view(-1, z)
return router_output
class YuanExpertMLP(nn.Module):
def __init__(self, config):
super(YuanExpertMLP, self).__init__()
self.gated_linear_unit = config.moe_config['gated_linear_unit']
#self.ffn_hidden_size = config.moe_config['ffn_hidden_size']
self.ffn_hidden_size = config.ffn_hidden_size
if self.gated_linear_unit:
self.w1 = nn.Linear(config.hidden_size, self.ffn_hidden_size*2, bias=False)
else:
self.w1 = nn.Linear(config.hidden_size, self.ffn_hidden_size, bias=False)
self.act_fn = ACT2FN[config.hidden_act]
self.w2 = nn.Linear(self.ffn_hidden_size, config.hidden_size, bias=False)
def forward(self, x):
x = self.w1(x)
if self.gated_linear_unit:
x = torch.chunk(x, 2, dim=-1)
x = self.act_fn(x[0]) * x[1]
else:
x = self.act_fn(x)
x = self.w2(x)
return x
class YuanMLP(nn.Module):
def __init__(
self,
hidden_size: int,
intermediate_size: int,
hidden_act: str
):
super().__init__()
self.up_proj = nn.Linear(hidden_size, intermediate_size, bias=False)
self.gate_proj = nn.Linear(hidden_size, intermediate_size, bias=False)
self.down_proj = nn.Linear(intermediate_size, hidden_size, bias=False)
self.act_fn = ACT2FN[hidden_act]
def forward(self, x):
return self.down_proj(self.gate_proj(x) * self.act_fn(self.up_proj(x)))
class YuanAttention(nn.Module):
"""Localized Filtering-based Attention 'YUAN 2.0: A Large Language Model with Localized Filtering-based Attention' paper"""
def __init__(self, config: YuanConfig):
super().__init__()
self.config = config
self.hidden_size = config.hidden_size
self.num_heads = config.num_attention_heads
self.lf_conv2d_group = config.lf_conv2d_group
self.lf_conv2d_num_pad = config.lf_conv2d_num_pad
try:
self.attention_projection_size = config.attention_projection_size
except:
self.attention_projection_size = None
if self.attention_projection_size is None:
self.head_dim = self.hidden_size // self.num_heads
else:
self.head_dim = self.attention_projection_size // self.num_heads
self.max_position_embeddings = config.max_position_embeddings
self.causal_mask = config.causal_mask
self.attn_mask_type = config.attn_mask_type
self.softmax_scale = 1.0 / math.sqrt(self.head_dim)
self.use_flash_attention = config.use_flash_attention
try:
self.use_shareqk = config.use_shareqk
except Exception as e:
self.use_shareqk=False
self.dropout = 0.0
self.attention_projection_size = config.attention_projection_size
self.v_proj = nn.Linear(self.hidden_size, self.num_heads * self.head_dim, bias=False)
self.o_proj = nn.Linear(self.num_heads * self.head_dim, self.hidden_size, bias=False)
if self.use_shareqk:
self.qk_proj = nn.Linear(self.hidden_size, self.num_heads * self.head_dim, bias=False)
self.qk_weight = nn.Parameter(torch.Tensor(2, self.hidden_size))
self.qk_bias = nn.Parameter(torch.Tensor(2, self.hidden_size))
else:
self.lf_gate = LocalizedFiltering(self.hidden_size, self.lf_conv2d_group, self.lf_conv2d_num_pad)
self.get_query_key = nn.Linear(self.hidden_size, 2 * self.attention_projection_size, bias=False)
self.core_attention = FlashSelfAttention(causal=True, attention_dropout=config.attn_dropout, softmax_scale=self.softmax_scale)
def _shape(self, tensor: torch.Tensor, seq_len: int, bsz: int):
return tensor.view(bsz, seq_len, self.num_heads, self.head_dim).transpose(1, 2).contiguous()
def forward(
self,
hidden_states: torch.Tensor,
attention_mask: Optional[torch.Tensor] = None,
position_ids: Optional[torch.LongTensor] = None,
position_ids_k: Optional[torch.LongTensor] = None,
past_key_value: Optional[Tuple[torch.Tensor]] = None,
rotary_pos_emb: Optional[Tuple[torch.Tensor]] = None,
output_attentions: bool = False,
use_cache: bool = False,
) -> Tuple[torch.Tensor, Optional[torch.Tensor], Optional[Tuple[torch.Tensor]]]:
q_len, bsz, _ = hidden_states.size()
hidden_states = hidden_states#.to('cuda:1')
is_first_step = False
if use_cache:
if past_key_value is None:
before_hidden_states = None
is_first_step = True
if q_len > 1:
inference_hidden_states_memory = hidden_states[-2:, :, :]
else:
inference_hidden_states_memory = torch.cat((torch.zeros_like(hidden_states), hidden_states), dim=0)
else:
before_hidden_states = past_key_value[2]
inference_hidden_states_memory = torch.cat((before_hidden_states[-1:, :, :], hidden_states), dim=0)
value_states = self.v_proj(hidden_states).view(q_len, bsz, self.num_heads, self.head_dim)
if self.use_shareqk:
qk_states = self.qk_proj(hidden_states).view(q_len, bsz, self.num_heads*self.head_dim)
query_key = qk_states.unsqueeze(2) * self.qk_weight + self.qk_bias
query_states, key_states = torch.unbind(query_key, dim=2)
query_states = query_states.view(q_len, bsz, self.num_heads, self.head_dim).transpose(1, 2)
key_states = key_states.view(q_len, bsz, self.num_heads, self.head_dim).transpose(1, 2)
else:
hidden_states = self.lf_gate(hidden_states, before_hidden_states)
mixed_qk_layer = self.get_query_key(hidden_states)
new_tensor_shape = mixed_qk_layer.size()[:-1] + (self.num_heads, 2 * self.head_dim)
mixed_qk_layer = mixed_qk_layer.view(*new_tensor_shape)
(query_states, key_states) = torch.split(mixed_qk_layer, self.head_dim, dim=-1)
kv_seq_len = key_states.shape[1]
if past_key_value is not None:
kv_seq_len += past_key_value[0].shape[1]
# duplicate the pos_emb for self attention
if rotary_pos_emb is not None:
if position_ids.shape[1] == 1:
q_seq_start = position_ids[0,-1]
q_seq_end = q_seq_start + 1
k_seq_end = q_seq_end
else:
q_seq_start = 0
q_seq_end = q_seq_start+key_states.shape[0]
k_seq_end = q_seq_end
rotary_pos_shape = rotary_pos_emb.shape
if isinstance(rotary_pos_emb, tuple):
rotary_pos_emb = rotary_pos_emb
else:
rotary_pos_emb = ((rotary_pos_emb,) * 2)
q_pos_emb, k_pos_emb = rotary_pos_emb
if past_key_value is not None:
# reuse k, v, self_attention
key_states = torch.cat([past_key_value[0], key_states], dim=0)
value_states = torch.cat([past_key_value[1], value_states], dim=0)
past_key_value = (key_states, value_states, inference_hidden_states_memory) if use_cache else None
query_states = apply_rotary_pos_emb(query_states, q_pos_emb, position_ids)
key_states = apply_rotary_pos_emb(key_states, k_pos_emb, position_ids_k)
attn_weights = None
attn_output = self.core_attention(query_states, key_states, value_states)
q_len, bsz, _, _ = attn_output.shape
attn_output = attn_output.reshape(q_len, bsz, -1)
attn_output = self.o_proj(attn_output)
return attn_output, attn_weights, past_key_value
class MoEDroplessTokenDispatcher:
def __init__(self, num_experts: int, config: YuanConfig) -> None:
self.num_experts = num_experts
assert self.num_experts > 0, "Expected at least one expert"
self.router_topk = config.moe_config['moe_top_k']
def token_permutation(
self, hidden_states: torch.Tensor, max_prob: torch.Tensor, max_ind: torch.Tensor
):
self.hidden_shape = hidden_states.shape
hidden_states = hidden_states.view(-1, self.hidden_shape[-1])
if self.router_topk > 1:
global_local_map = torch.ones_like(max_ind).bool()
local_indices = max_ind.masked_select(global_local_map)
local_probs = max_prob.masked_select(global_local_map)
global_local_map = global_local_map.nonzero()[:, 0]
global_local_map = global_local_map.view(-1, 1).expand(-1, hidden_states.shape[-1])
local_hidden_states = torch.gather(hidden_states, 0, global_local_map)
indices = torch.argsort(local_indices, dim=0)
tokens_per_expert = torch.histc(
local_indices,
bins=self.num_experts,
min=0,
max=self.num_experts - 1,
)
tokens_per_expert = tokens_per_expert.cpu().to(torch.long)
indices = indices.view(-1, 1).expand(-1, hidden_states.shape[-1])
permuted_local_hidden_states = torch.gather(local_hidden_states, 0, indices)
return (permuted_local_hidden_states, tokens_per_expert, local_probs, indices, global_local_map)
def token_unpermutation(
self,
hidden_states: torch.Tensor,
scores: torch.Tensor,
indices: torch.Tensor,
global_local_map: torch.Tensor = None,
):
scores = scores.to(dtype=hidden_states.dtype)
unpermuted_local_hidden = torch.zeros_like(hidden_states)
assert indices.shape == hidden_states.shape, f'{indices.shape}, {hidden_states.shape}'
unpermuted_local_hidden = unpermuted_local_hidden.scatter(0, indices, hidden_states)
if self.router_topk > 1:
unpermuted_local_hidden = unpermuted_local_hidden * scores.view(-1, 1)
unpermuted_local_bias = None
output_total = unpermuted_local_hidden
output_bias_total = unpermuted_local_bias
if self.router_topk > 1:
global_num_tokens = self.hidden_shape[0] * self.hidden_shape[1]
global_hidden_shape = [global_num_tokens, hidden_states.shape[-1]]
unpermuted_global_hidden = torch.zeros(
global_hidden_shape,
dtype=hidden_states.dtype,
device=hidden_states.device,
)
output_total = unpermuted_global_hidden.scatter_add(
0, global_local_map, unpermuted_local_hidden
)
output_total = output_total.view(self.hidden_shape)
return output_total
class GroupedMLP(nn.Module):
"""An efficient implementation of the Experts layer using CUTLASS GroupedGEMM.
This class is designed to execute multiple experts in parallel, thereby maximizing computational efficiency.
"""
def __init__(self, num_experts: int, config: YuanConfig):
super().__init__()
self.num_experts = num_experts
self.config = config
def glu(x):
x = torch.chunk(x, 2, dim=-1)
return torch.nn.functional.silu(x[0]) * x[1]
self.activation_func = glu
self.ffn_hidden_size = config.ffn_hidden_size
fc1_output_size_per_partition = self.ffn_hidden_size * 2
fc2_input_size = self.ffn_hidden_size
self.w1 = nn.ModuleList([nn.Linear(self.config.hidden_size, self.ffn_hidden_size * 2, bias=False) for _ in range(num_experts)])
self.w2 = nn.ModuleList([nn.Linear(self.ffn_hidden_size, self.config.hidden_size, bias=False) for _ in range(num_experts)])
def forward(self, permuted_hidden_states, tokens_per_expert):
torch.cuda.set_device(permuted_hidden_states.device)
permuted_hidden_states = permuted_hidden_states#.to('cuda:0')
fc2_outputs = []
start_idx = 0
for i in range(self.num_experts):
if tokens_per_expert[i] == 0:
continue
end_idx = start_idx + tokens_per_expert[i]
# Use custom attributes for each expert's Linear layers
fc1_output = self.w1[i](permuted_hidden_states[start_idx:end_idx])
intermediate_parallel = self.activation_func(fc1_output)
fc2_output = self.w2[i](intermediate_parallel)
fc2_outputs.append(fc2_output)
start_idx = end_idx
fc2_output = torch.cat(fc2_outputs, dim=0)
return fc2_output#.to('cuda:1')
class YuanMoeLayer(nn.Module):
def __init__(self, config:YuanConfig):
super().__init__()
self.config = config
self.num_experts = config.moe_config['moe_num_experts']
self.top_k = config.moe_config['moe_top_k']
self.norm_topk_prob = config.moe_config['norm_topk_prob']
self.hidden_size = config.hidden_size
expert_indices_offset = (0)
self.router = ParallelAttention_router(config)
self.token_dispatcher = MoEDroplessTokenDispatcher(self.num_experts, config=self.config)
self.experts = GroupedMLP(self.num_experts, self.config)
def routing(self, logits: torch.Tensor) -> torch.Tensor:
top_logits, indices = torch.topk(logits, k=self.top_k, dim=1)
scores = torch.softmax(top_logits, dim=-1, dtype=torch.float32).type_as(logits)
return scores, indices
def forward(self, hidden_states: torch.Tensor) -> torch.Tensor:
batch_size, sequence_length, hidden_dim = hidden_states.shape
logits = self.router(hidden_states)
scores, indices = self.routing(logits)
scores = scores.to(hidden_states.dtype)
(dispatched_input, tokens_per_expert, scores, indices, global_local_map, ) = self.token_dispatcher.token_permutation(hidden_states, scores, indices)
expert_output = self.experts(dispatched_input, tokens_per_expert)
output = self.token_dispatcher.token_unpermutation(expert_output, scores, indices, global_local_map)
return output
class YuanDecoderLayer(nn.Module):
def __init__(self, config: YuanConfig, num_layer):
super().__init__()
self.hidden_size = config.hidden_size
self.self_attn = YuanAttention(config=config)
self.num_layer = num_layer
if config.moe_config['moe_num_experts'] > 0:
self.mlp = YuanMoeLayer(config)
else:
self.mlp = YuanMLP(
hidden_size=self.hidden_size,
intermediate_size=config.intermediate_size,
hidden_act=config.hidden_act,
)
self.input_layernorm = RMSNorm(config.hidden_size, eps=config.rms_norm_eps)
self.post_attention_layernorm = RMSNorm(config.hidden_size, eps=config.rms_norm_eps)
def forward(
self,
hidden_states: torch.Tensor,
attention_mask: Optional[torch.Tensor] = None,
position_ids: Optional[torch.LongTensor] = None,
position_ids_k: Optional[torch.LongTensor] = None,
past_key_value: Optional[Tuple[torch.Tensor]] = None,
rotary_pos_emb: Optional[Tuple[torch.Tensor]] = None,
output_attentions: Optional[bool] = False,
use_cache: Optional[bool] = False,
) -> Tuple[torch.FloatTensor, Optional[Tuple[torch.FloatTensor, torch.FloatTensor]]]:
"""
Args:
hidden_states (`torch.FloatTensor`): input to the layer of shape `(batch, seq_len, embed_dim)`
attention_mask (`torch.FloatTensor`, *optional*): attention mask of size
`(batch, 1, tgt_len, src_len)` where padding elements are indicated by very large negative values.
output_attentions (`bool`, *optional*):
Whether or not to return the attentions tensors of all attention layers. See `attentions` under
returned tensors for more detail.
use_cache (`bool`, *optional*):
If set to `True`, `past_key_values` key value states are returned and can be used to speed up decoding
(see `past_key_values`).
past_key_value (`Tuple(torch.FloatTensor)`, *optional*): cached past key and value projection states
"""
residual = hidden_states#.to('cuda:1')
torch.cuda.set_device(hidden_states.device)
hidden_states = self.input_layernorm(hidden_states) #.to('cuda:0')).to('cuda:1')
# Self Attention
hidden_states, self_attn_weights, present_key_value = self.self_attn(
hidden_states=hidden_states,
attention_mask=attention_mask,
position_ids=position_ids,
position_ids_k=position_ids_k,
past_key_value=past_key_value,
rotary_pos_emb=rotary_pos_emb,
output_attentions=output_attentions,
use_cache=use_cache,
)
hidden_states = residual + hidden_states.permute(1, 0, 2)
# Fully Connected
residual = hidden_states#.to('cuda:1')
torch.cuda.set_device(hidden_states.device)
hidden_states = self.post_attention_layernorm(hidden_states) #.to('cuda:0')).to('cuda:1')
hidden_states = self.mlp(hidden_states)# .to('cuda:1')
hidden_states = residual + hidden_states
outputs = (hidden_states,)
if output_attentions:
outputs += (self_attn_weights,)
if use_cache:
outputs += (present_key_value,)
return outputs
YUAN_START_DOCSTRING = r"""
This model inherits from [`PreTrainedModel`]. Check the superclass documentation for the generic methods the
library implements for all its model (such as downloading or saving, resizing the input embeddings, pruning heads
etc.)
This model is also a PyTorch [torch.nn.Module](https://pytorch.org/docs/stable/nn.html#torch.nn.Module) subclass.
Use it as a regular PyTorch Module and refer to the PyTorch documentation for all matter related to general usage
and behavior.
Parameters:
config ([`YuanConfig`]):
Model configuration class with all the parameters of the model. Initializing with a config file does not
load the weights associated with the model, only the configuration. Check out the
[`~PreTrainedModel.from_pretrained`] method to load the model weights.
"""
@add_start_docstrings(
"The bare Yuan Model outputting raw hidden-states without any specific head on top.",
YUAN_START_DOCSTRING,
)
class YuanPreTrainedModel(PreTrainedModel):
config_class = YuanConfig
base_model_prefix = "model"
supports_gradient_checkpointing = True
_no_split_modules = ["YuanDecoderLayer"]
_skip_keys_device_placement = "past_key_values"
_keys_to_ignore_on_load_unexpected = [r"decoder\.version"]
def _init_weights(self, module):
std = self.config.initializer_range
if isinstance(module, nn.Linear):
module.weight.data.normal_(mean=0.0, std=std)
if module.bias is not None:
module.bias.data.zero_()
elif isinstance(module, nn.Embedding):
module.weight.data.normal_(mean=0.0, std=std)
if module.padding_idx is not None:
module.weight.data[module.padding_idx].zero_()
def _set_gradient_checkpointing(self, module, value=False):
if isinstance(module, YuanModel):
module.gradient_checkpointing = value
YUAN_INPUTS_DOCSTRING = r"""
Args:
input_ids (`torch.LongTensor` of shape `(batch_size, sequence_length)`):
Indices of input sequence tokens in the vocabulary. Padding will be ignored by default should you provide
it.
Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and
[`PreTrainedTokenizer.__call__`] for details.
[What are input IDs?](../glossary#input-ids)
attention_mask (`torch.Tensor` of shape `(batch_size, sequence_length)`, *optional*):
Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`:
- 1 for tokens that are **not masked**,
- 0 for tokens that are **masked**.
[What are attention masks?](../glossary#attention-mask)
Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and
[`PreTrainedTokenizer.__call__`] for details.
If `past_key_values` is used, optionally only the last `decoder_input_ids` have to be input (see
`past_key_values`).
If you want to change padding behavior, you should read [`modeling_opt._prepare_decoder_attention_mask`]
and modify to your needs. See diagram 1 in [the paper](https://arxiv.org/abs/1910.13461) for more
information on the default strategy.
- 1 indicates the head is **not masked**,
- 0 indicates the head is **masked**.
position_ids (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*):
Indices of positions of each input sequence tokens in the position embeddings. Selected in the range `[0,
config.n_positions - 1]`.
[What are position IDs?](../glossary#position-ids)
past_key_values (`tuple(tuple(torch.FloatTensor))`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`):
Tuple of `tuple(torch.FloatTensor)` of length `config.n_layers`, with each tuple having 2 tensors of shape
`(batch_size, num_heads, sequence_length, embed_size_per_head)`) and 2 additional tensors of shape
`(batch_size, num_heads, encoder_sequence_length, embed_size_per_head)`.
Contains pre-computed hidden-states (key and values in the self-attention blocks and in the cross-attention
blocks) that can be used (see `past_key_values` input) to speed up sequential decoding.
If `past_key_values` are used, the user can optionally input only the last `decoder_input_ids` (those that
don't have their past key value states given to this model) of shape `(batch_size, 1)` instead of all
`decoder_input_ids` of shape `(batch_size, sequence_length)`.
inputs_embeds (`torch.FloatTensor` of shape `(batch_size, sequence_length, hidden_size)`, *optional*):
Optionally, instead of passing `input_ids` you can choose to directly pass an embedded representation. This
is useful if you want more control over how to convert `input_ids` indices into associated vectors than the
model's internal embedding lookup matrix.
use_cache (`bool`, *optional*):
If set to `True`, `past_key_values` key value states are returned and can be used to speed up decoding (see
`past_key_values`).
output_attentions (`bool`, *optional*):
Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned
tensors for more detail.
output_hidden_states (`bool`, *optional*):
Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for
more detail.
return_dict (`bool`, *optional*):
Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple.
"""
@add_start_docstrings(
"The bare Yuan Model outputting raw hidden-states without any specific head on top.",
YUAN_START_DOCSTRING,
)
class YuanModel(YuanPreTrainedModel):
"""
Transformer decoder consisting of *config.num_hidden_layers* layers. Each layer is a [`YuanDecoderLayer`]
Args:
config: YuanConfig
"""
def __init__(self, config: YuanConfig):
super().__init__(config)
self.padding_idx = config.pad_token_id
self.vocab_size = config.vocab_size
#TODO: control it by config
self.eod_token = config.eod_token
self.reset_attention_mask = config.reset_attention_mask
self.reset_position_ids = config.reset_position_ids
self.max_position_embeddings = config.max_position_embeddings
self.embed_tokens = nn.Embedding(config.vocab_size, config.hidden_size, self.padding_idx)
self.layers = nn.ModuleList([YuanDecoderLayer(config, i) for i in range(config.num_hidden_layers)])
self.norm = RMSNorm(config.hidden_size, eps=config.rms_norm_eps)
self.gradient_checkpointing = False
# Initialize weights and apply final processing
self.post_init()
self.seq_length = config.max_position_embeddings
rotary_dim = config.hidden_size // config.num_attention_heads
if config.rotary_percent < 1.0:
rotary_dim = int(rotary_dim * config.rotary_percent)
self.rotary_pos_emb = YuanRotaryEmbedding(rotary_dim, base=config.rotary_base, dtype=config.torch_dtype)
def get_input_embeddings(self, input_ids: torch.Tensor) -> torch.Tensor:
return self.embed_tokens(input_ids)
def set_input_embeddings(self, value):
self.embed_tokens = value
# Copied from transformers.models.bart.modeling_bart.BartDecoder._prepare_decoder_attention_mask
def _prepare_decoder_attention_mask(self, attention_mask, input_shape, inputs_embeds, past_key_values_length):
# create causal mask
# [bsz, seq_len] -> [bsz, 1, tgt_seq_len, src_seq_len]
combined_attention_mask = None
if input_shape[-1] > 1:
combined_attention_mask = _make_causal_mask(
input_shape,
inputs_embeds.dtype,
device=inputs_embeds.device,
past_key_values_length=past_key_values_length,
)
if attention_mask is not None:
# [bsz, seq_len] -> [bsz, 1, tgt_seq_len, src_seq_len]
expanded_attn_mask = _expand_mask(attention_mask, inputs_embeds.dtype, tgt_len=input_shape[-1]).to(
inputs_embeds.device
)
combined_attention_mask = (
expanded_attn_mask if combined_attention_mask is None else expanded_attn_mask + combined_attention_mask
)
return combined_attention_mask
def _prepare_decoder_attention_mask_training(self, input_id, inputs_embeds, eod_token, reset_mask_flag ,reset_attention_mask=True, reset_position_ids=True):
micro_batch_size, seq_length = input_id.size()
attention_mask = torch.tril(torch.ones(
(micro_batch_size, seq_length, seq_length), device=inputs_embeds.device)).view(
micro_batch_size, 1, seq_length, seq_length)
position_ids = torch.arange(seq_length, dtype=torch.long,
device=inputs_embeds.device)
position_ids = position_ids.unsqueeze(0).expand_as(input_id)
if reset_position_ids:
position_ids = position_ids.clone()
if reset_position_ids or reset_attention_mask:
# Loop through the batches:
for b in range(micro_batch_size):
# Find indecies where EOD token is.
eod_index = position_ids[b, input_id[b] == eod_token]
# Detach indecies from positions if going to modify positions.
if reset_position_ids:
eod_index = eod_index.clone()
# Loop through EOD indecies:
prev_index = 0
for j in range(eod_index.size()[0]):
i = eod_index[j]
# Mask attention loss.
if reset_attention_mask:
attention_mask[b, 0, (i + 1):, :(i + 1)] = 0
# Reset positions.
if reset_position_ids:
position_ids[b, (i + 1):] -= (i + 1 - prev_index)
prev_index = i + 1
inverted_mask = 1 - attention_mask
output_attn_mask = inverted_mask.masked_fill(inverted_mask.to(torch.bool), torch.finfo(inputs_embeds.dtype).min)
if reset_mask_flag:
output_attn_mask = output_attn_mask[:,:,-1:,:]
return output_attn_mask, position_ids
@add_start_docstrings_to_model_forward(YUAN_INPUTS_DOCSTRING)
def forward(
self,
input_ids: torch.LongTensor = None,
attention_mask: Optional[torch.Tensor] = None,
position_ids: Optional[torch.LongTensor] = None,
past_key_values: Optional[List[torch.FloatTensor]] = None,
inputs_embeds: Optional[torch.FloatTensor] = None,
use_cache: Optional[bool] = None,
output_attentions: Optional[bool] = None,
output_hidden_states: Optional[bool] = None,
output_router_logits: Optional[bool] = None,
return_dict: Optional[bool] = None,
) -> Union[Tuple, BaseModelOutputWithPast, torch.Tensor]:
output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions
output_router_logits = (
output_router_logits if output_router_logits is not None else self.config.output_router_logits
)
output_hidden_states = (
output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states
)
use_cache = use_cache if use_cache is not None else self.config.use_cache
return_dict = return_dict if return_dict is not None else self.config.use_return_dict
input_ids1 = copy.deepcopy(input_ids)
reset_mask_flag = False
if past_key_values:
input_ids = input_ids
input_ids = input_ids[:,-1:]
if use_cache:
reset_mask_flag = True
# retrieve input_ids and inputs_embeds
if input_ids is not None and inputs_embeds is not None:
raise ValueError("You cannot specify both decoder_input_ids and decoder_inputs_embeds at the same time")
elif input_ids is not None:
input_ids = input_ids
batch_size, seq_length = input_ids.shape
elif inputs_embeds is not None:
inputs_embeds = inputs_embeds.transpose(0,1)
batch_size, seq_length, _ = inputs_embeds.shape
else:
raise ValueError("You have to specify either decoder_input_ids or decoder_inputs_embeds")
seq_length_with_past = seq_length
past_key_values_length = 0
if past_key_values is not None:
past_key_values_length = past_key_values[0][0].shape[0]
seq_length_with_past = seq_length_with_past + past_key_values_length
# modify to reset position ids
if past_key_values is not None:
pos_start = position_ids[:,-1]+1
pos_end = pos_start+past_key_values[0][0].shape[0]-position_ids.shape[1]+1
position_ids_k = torch.arange(pos_start.item(), pos_end.item()).to(position_ids.device)
position_ids_k = position_ids_k.unsqueeze(0)
position_ids_k = torch.cat((position_ids, position_ids_k), dim=1)
position_ids = position_ids[:,-1]+past_key_values[0][0].shape[0]-position_ids.shape[1]+1
position_ids = position_ids.unsqueeze(0)
else:
position_ids_k = position_ids
if position_ids is None:
device = input_ids.device if input_ids is not None else inputs_embeds.device
position_ids = torch.arange(
past_key_values_length, seq_length + past_key_values_length, dtype=torch.long, device=device
)
position_ids = position_ids.unsqueeze(0).view(-1, seq_length)
else:
#position_ids = position_ids.view(-1, seq_length).long()
pass
if inputs_embeds is None:
inputs_embeds = self.embed_tokens(input_ids).transpose(0,1)
if self.training or self.reset_position_ids:
attention_mask, _ = self._prepare_decoder_attention_mask_training(input_ids1, inputs_embeds, self.eod_token, reset_mask_flag, self.reset_attention_mask, self.reset_position_ids)
else:
if attention_mask is None:
attention_mask = torch.ones(
(batch_size, seq_length_with_past), dtype=torch.bool, device=inputs_embeds.device
)
attention_mask = self._prepare_decoder_attention_mask(
attention_mask, (batch_size, seq_length), inputs_embeds, past_key_values_length
)
#rotary_pos_emb = self.rotary_pos_emb(self.max_position_embeddings)
# Rotary positional embeddings (embedding is None for PP intermediate devices)
rotary_pos_emb = None
'''
rotary_seq_len = self.rotary_pos_emb.get_rotary_seq_len(
transformer_input=inputs_embeds
)
'''
rotary_pos_emb = self.rotary_pos_emb(self.max_position_embeddings)
hidden_states = inputs_embeds
if self.gradient_checkpointing and self.training:
if use_cache:
logger.warning_once(
"`use_cache=True` is incompatible with gradient checkpointing. Setting `use_cache=False`..."
)
use_cache = False
# decoder layers
all_hidden_states = () if output_hidden_states else None
all_self_attns = () if output_attentions else None
next_decoder_cache = () if use_cache else None
position_ids = position_ids.cpu()
position_ids_k = position_ids_k.cpu()
for idx, decoder_layer in enumerate(self.layers):
if output_hidden_states:
all_hidden_states += (hidden_states,)
past_key_value = past_key_values[idx] if past_key_values is not None else None
if self.gradient_checkpointing and self.training:
def create_custom_forward(module):
def custom_forward(*inputs):
# None for past_key_value
return module(*inputs, output_attentions, None)
return custom_forward
layer_outputs = torch.utils.checkpoint.checkpoint(
create_custom_forward(decoder_layer),
hidden_states,
attention_mask,
position_ids,
None,
)
else:
layer_outputs = decoder_layer(
hidden_states,
attention_mask=attention_mask,
position_ids=position_ids,
position_ids_k=position_ids_k,
past_key_value=past_key_value,
rotary_pos_emb=rotary_pos_emb,
output_attentions=output_attentions,
use_cache=use_cache,
)
hidden_states = layer_outputs[0]
if use_cache:
next_decoder_cache += (layer_outputs[2 if output_attentions else 1],)
if output_attentions:
all_self_attns += (layer_outputs[1],)
hidden_states = hidden_states#.to('cuda:0')
torch.cuda.set_device(hidden_states.device)
hidden_states = self.norm(hidden_states)
# add hidden states from the last decoder layer
if output_hidden_states:
all_hidden_states += (hidden_states,)
next_cache = next_decoder_cache if use_cache else None
if not return_dict:
return tuple(v for v in [hidden_states, next_cache, all_hidden_states, all_self_attns] if v is not None)
return BaseModelOutputWithPast(
last_hidden_state=hidden_states,
past_key_values=next_cache,
hidden_states=all_hidden_states,
attentions=all_self_attns,
)
class YuanForCausalLM(YuanPreTrainedModel):
def __init__(self, config):
super().__init__(config)
self.lm_head = nn.Linear(config.hidden_size, config.vocab_size, bias=False)
self.model = YuanModel(config)
self.post_init()
def get_input_embeddings(self):
return self.model.embed_tokens
def set_input_embeddings(self, value):
self.model.embed_tokens = value
def get_output_embeddings(self):
return self.lm_head
def set_output_embeddings(self, new_embeddings):
self.lm_head = new_embeddings
def set_decoder(self, decoder):
self.model = decoder
def get_decoder(self):
return self.model
def get_loss_mask(self, input_ids, labels, eod_token, sep_token):
micro_batch_size, seq_length = input_ids.size()
loss_mask = torch.ones(input_ids.size(), dtype=torch.float, device=input_ids.device)
position_ids = torch.arange(seq_length, dtype=torch.long, device=input_ids.device)
position_ids = position_ids.unsqueeze(0).expand_as(input_ids)
"""modify loss_mask to only calculate the loss of the answer (separated with [SEP])"""
for b in range(micro_batch_size):
eod_indexs = position_ids[b, input_ids[b] == eod_token]
sep_indexs = position_ids[b, input_ids[b] == sep_token]
if len(eod_indexs) == 0 or len(sep_indexs) == 0:
loss_mask[b] = 1.0
else:
if eod_indexs[0] > sep_indexs[0]:
loss_mask[b, 0:sep_indexs[0]] = 0
if len(eod_indexs) == len(sep_indexs):
for ii, eod_index in enumerate(eod_indexs):
start_index = eod_index
if ii == (len(sep_indexs) - 1):
stop_index = seq_length
else:
stop_index = sep_indexs[ii + 1]
loss_mask[b, start_index:stop_index] = 0.0
else:
if len(eod_indexs) > len(sep_indexs):
loss_mask[b,:] = 1.0
else:
for ii, eod_index in enumerate(eod_indexs):
start_index = eod_index
stop_index = sep_indexs[ii + 1]
loss_mask[b, start_index:stop_index] = 0.0
elif eod_indexs[0] < sep_indexs[0]:
if len(eod_indexs) == len(sep_indexs):
for ii, eod_index in enumerate(eod_indexs):
start_index = eod_index
stop_index = sep_indexs[ii]
loss_mask[b, start_index:stop_index] = 0.0
else:
if len(eod_indexs) < len(sep_indexs):
loss_mask[b,:] = 1.0
else:
for ii, eod_index in enumerate(eod_indexs):
start_index = eod_index
if ii >= len(sep_indexs):
stop_index = seq_length
else:
stop_index = sep_indexs[ii]
loss_mask[b, start_index:stop_index] = 0.0
loss_mask[input_ids == eod_token] = 1.0
return loss_mask
@add_start_docstrings_to_model_forward(YUAN_INPUTS_DOCSTRING)
@replace_return_docstrings(output_type=CausalLMOutputWithPast, config_class=_CONFIG_FOR_DOC)
def forward(
self,
input_ids: torch.LongTensor = None,
attention_mask: Optional[torch.Tensor] = None,
position_ids: Optional[torch.LongTensor] = None,
past_key_values: Optional[List[torch.FloatTensor]] = None,
inputs_embeds: Optional[torch.FloatTensor] = None,
labels: Optional[torch.LongTensor] = None,
use_cache: Optional[bool] = None,
output_attentions: Optional[bool] = None,
output_hidden_states: Optional[bool] = None,
return_dict: Optional[bool] = None,
) -> Union[Tuple, CausalLMOutputWithPast]:
"""
## modify delete routers
Args:
labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*):
Labels for computing the masked language modeling loss. Indices should either be in `[0, ...,
config.vocab_size]` or -100 (see `input_ids` docstring). Tokens with indices set to `-100` are ignored
(masked), the loss is only computed for the tokens with labels in `[0, ..., config.vocab_size]`.
Returns:
Example:
```python
>>> from transformers import AutoTokenizer, YuanForCausalLM
>>> model = YuanForCausalLM.from_pretrained(PATH_TO_CONVERTED_WEIGHTS)
>>> tokenizer = AutoTokenizer.from_pretrained(PATH_TO_CONVERTED_TOKENIZER)
>>> prompt = "Hey, are you consciours? Can you talk to me?"
>>> inputs = tokenizer(prompt, return_tensors="pt")
>>> # Generate
>>> generate_ids = model.generate(inputs.input_ids, max_length=30)
>>> tokenizer.batch_decode(generate_ids, skip_special_tokens=True, clean_up_tokenization_spaces=False)[0]
"Hey, are you consciours? Can you talk to me?\nI'm not consciours, but I can talk to you."
```"""
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
outputs = self.model(
input_ids=input_ids,
attention_mask=attention_mask,
position_ids=position_ids,
past_key_values=past_key_values,
inputs_embeds=inputs_embeds,
use_cache=use_cache,
output_attentions=output_attentions,
output_hidden_states=output_hidden_states,
return_dict=return_dict,
)
hidden_states = outputs[0].transpose(0,1)
logits = self.lm_head(hidden_states)
loss = None
if labels is not None:
if self.use_loss_mask:
loss_mask = self.get_loss_mask(input_ids, labels, self.eod_token, self.sep_token)
# Shift so that tokens < n predict n
shift_logits = logits[..., :-1, :].contiguous()
shift_labels = labels[..., 1:].contiguous()
# Flatten the tokens
if self.use_loss_mask:
loss_fct = CrossEntropyLoss(reduction='none')
shift_logits = shift_logits.view(-1, self.config.vocab_size)
shift_labels = shift_labels.view(-1)
# Enable model parallelism
shift_labels = shift_labels.to(shift_logits.device)
loss = loss_fct(shift_logits, shift_labels)
loss = torch.sum(loss * loss_mask) / loss_mask.sum()
else:
loss_fct = CrossEntropyLoss()
shift_logits = shift_logits.view(-1, self.config.vocab_size)
shift_labels = shift_labels.view(-1)
# Enable model parallelism
shift_labels = shift_labels.to(shift_logits.device)
loss = loss_fct(shift_logits, shift_labels)
if not return_dict:
output = (logits,) + outputs[1:]
return (loss,) + output if loss is not None else output
return CausalLMOutputWithPast(
loss=loss,
logits=logits,
past_key_values=outputs.past_key_values,
hidden_states=hidden_states,
attentions=outputs.attentions,
)
def prepare_inputs_for_generation(
self, input_ids, past_key_values=None, attention_mask=None, inputs_embeds=None, **kwargs
):
position_ids = kwargs.get("position_ids", None)
if attention_mask is not None and position_ids is None:
# create position_ids on the fly for batch generation
position_ids = attention_mask.long().cumsum(-1) - 1
position_ids.masked_fill_(attention_mask == 0, 1)
if past_key_values:
position_ids = position_ids[:, -1].unsqueeze(-1)
# if `inputs_embeds` are passed, we only want to use them in the 1st generation step
if inputs_embeds is not None and past_key_values is None:
model_inputs = {"inputs_embeds": inputs_embeds}
else:
model_inputs = {"input_ids": input_ids}
model_inputs.update(
{
"position_ids": position_ids,
"past_key_values": past_key_values,
"use_cache": kwargs.get("use_cache"),
"attention_mask": attention_mask,
}
)
return model_inputs
@staticmethod
def _reorder_cache(past_key_values, beam_idx):
reordered_past = ()
for layer_past in past_key_values:
reordered_past += (tuple(past_state.index_select(0, beam_idx) for past_state in layer_past),)
return reordered_past
@add_start_docstrings(
"""
The Yuan Model transformer with a sequence classification head on top (linear layer).
[`YuanForSequenceClassification`] uses the last token in order to do the classification, as other causal models
(e.g. GPT-2) do.
Since it does classification on the last token, it requires to know the position of the last token. If a
`pad_token_id` is defined in the configuration, it finds the last token that is not a padding token in each row. If
no `pad_token_id` is defined, it simply takes the last value in each row of the batch. Since it cannot guess the
padding tokens when `inputs_embeds` are passed instead of `input_ids`, it does the same (take the last value in
each row of the batch).
""",
YUAN_START_DOCSTRING,
)
class YuanForSequenceClassification(YuanPreTrainedModel):
#_keys_to_ignore_on_load_missing = [r"lm_head.weight"]
def __init__(self, config):
super().__init__(config)
self.num_labels = config.num_labels
self.model = YuanModel(config)
self.score = nn.Linear(config.hidden_size, self.num_labels, bias=False)
# Initialize weights and apply final processing
self.post_init()
def get_input_embeddings(self):
return self.model.embed_tokens
def set_input_embeddings(self, value):
self.model.embed_tokens = value
@add_start_docstrings_to_model_forward(YUAN_INPUTS_DOCSTRING)
def forward(
self,
input_ids: torch.LongTensor = None,
attention_mask: Optional[torch.Tensor] = None,
position_ids: Optional[torch.LongTensor] = None,
past_key_values: Optional[List[torch.FloatTensor]] = None,
inputs_embeds: Optional[torch.FloatTensor] = None,
labels: Optional[torch.LongTensor] = None,
use_cache: Optional[bool] = None,
output_attentions: Optional[bool] = None,
output_hidden_states: Optional[bool] = None,
return_dict: Optional[bool] = None,
) -> Union[Tuple, SequenceClassifierOutputWithPast]:
r"""
labels (`torch.LongTensor` of shape `(batch_size,)`, *optional*):
Labels for computing the sequence classification/regression loss. Indices should be in `[0, ...,
config.num_labels - 1]`. If `config.num_labels == 1` a regression loss is computed (Mean-Square loss), If
`config.num_labels > 1` a classification loss is computed (Cross-Entropy).
"""
return_dict = return_dict if return_dict is not None else self.config.use_return_dict
transformer_outputs = self.model(
input_ids,
attention_mask=attention_mask,
position_ids=position_ids,
past_key_values=past_key_values,
inputs_embeds=inputs_embeds,
use_cache=use_cache,
output_attentions=output_attentions,
output_hidden_states=output_hidden_states,
return_dict=return_dict,
)
hidden_states = transformer_outputs[0]
logits = self.score(hidden_states)
if input_ids is not None:
batch_size = input_ids.shape[0]
else:
batch_size = inputs_embeds.shape[0]
if self.config.pad_token_id is None and batch_size != 1:
raise ValueError("Cannot handle batch sizes > 1 if no padding token is defined.")
if self.config.pad_token_id is None:
sequence_lengths = -1
else:
if input_ids is not None:
sequence_lengths = (torch.ne(input_ids, self.config.pad_token_id).sum(-1) - 1).to(logits.device)
else:
sequence_lengths = -1
pooled_logits = logits[torch.arange(batch_size, device=logits.device), sequence_lengths]
loss = None
if labels is not None:
labels = labels.to(logits.device)
if self.config.problem_type is None:
if self.num_labels == 1:
self.config.problem_type = "regression"
elif self.num_labels > 1 and (labels.dtype == torch.long or labels.dtype == torch.int):
self.config.problem_type = "single_label_classification"
else:
self.config.problem_type = "multi_label_classification"
if self.config.problem_type == "regression":
loss_fct = MSELoss()
if self.num_labels == 1:
loss = loss_fct(pooled_logits.squeeze(), labels.squeeze())
else:
loss = loss_fct(pooled_logits, labels)
elif self.config.problem_type == "single_label_classification":
loss_fct = CrossEntropyLoss()
loss = loss_fct(pooled_logits.view(-1, self.num_labels), labels.view(-1))
elif self.config.problem_type == "multi_label_classification":
loss_fct = BCEWithLogitsLoss()
loss = loss_fct(pooled_logits, labels)
if not return_dict:
output = (pooled_logits,) + transformer_outputs[1:]
return ((loss,) + output) if loss is not None else output
return SequenceClassifierOutputWithPast(
loss=loss,
logits=pooled_logits,
past_key_values=transformer_outputs.past_key_values,
hidden_states=transformer_outputs.hidden_states,
attentions=transformer_outputs.attentions,
)