Files
wehub-resource-sync 2aaeece67c
Codestyle Check / Lint (push) Has been cancelled
Codestyle Check / Check bypass (push) Has been cancelled
Pipelines-Test / Pipelines-Test (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 13:37:14 +08:00

895 lines
36 KiB
Python

# Copyright (c) 2023 Technology Innovation Institute (TII) and PaddlePaddle Authors. All Rights Reserved.
#
# 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.
import math
import warnings
from typing import List, Optional, Tuple, Union
import paddle
from paddle import Tensor, nn
from ...utils.converter import StateDictNameMapping, init_name_mappings
from .. import PretrainedModel
from ..model_outputs import (
BaseModelOutputWithPastAndCrossAttentions,
CausalLMOutputWithCrossAttentions,
)
from .configuration import RW_PRETRAINED_INIT_CONFIGURATION, RWConfig
# rotary pos emb helpers (paddle.jit.script does not seem to support staticmethod...)
def rotate_half(x):
x1, x2 = x[..., : x.shape[-1] // 2], x[..., x.shape[-1] // 2 :]
return paddle.concat((-x2, x1), axis=x1.ndim - 1) # dim=-1 triggers a bug in paddle < 1.8.0
class RotaryEmbedding(paddle.nn.Layer):
"""Implementation of RotaryEmbedding from GPT-NeoX.
This implementation is design to operate on queries and keys that are compatible with
[batch_size, n_heads_per_partition, seq_len, head_dim] (e.g. MinGPTAttention format).
"""
def __init__(
self,
head_dim: int,
base=10000,
):
super().__init__()
# head_dim must be an even number
inv_freq = 1.0 / (base ** (paddle.arange(0, head_dim, 2).astype("float32") / head_dim))
self.register_buffer("inv_freq", inv_freq, persistable=False)
self.head_dim = head_dim
self.seq_len_cached = None
self.batch_size_cached = None
self.cos_cached: Tensor | None = None
self.sin_cached: Tensor | None = None
def cos_sin(
self,
seq_len: int,
dtype=paddle.bfloat16,
) -> Tensor:
if seq_len != self.seq_len_cached:
self.seq_len_cached = seq_len
t = paddle.arange(seq_len, dtype=self.inv_freq.dtype)
freqs = paddle.einsum("i,j->ij", t, self.inv_freq)
emb = paddle.concat((freqs, freqs), axis=-1)
if dtype in [paddle.float16, paddle.bfloat16]:
emb = paddle.cast(emb, dtype)
self.cos_cached = emb.cos()[None, :, :]
self.sin_cached = emb.sin()[None, :, :]
self.cos_cached = paddle.cast(self.cos_cached, dtype)
self.sin_cached = paddle.cast(self.sin_cached, dtype)
return self.cos_cached, self.sin_cached
def forward(self, q, k):
batch, seq_len, head_dim = q.shape
cos, sin = self.cos_sin(seq_len, q.dtype)
return (q * cos) + (rotate_half(q) * sin), (k * cos) + (rotate_half(k) * sin)
def _make_causal_mask(input_ids_shape: paddle.shape, past_key_values_length: int):
batch_size, target_length = input_ids_shape
mask = paddle.empty((target_length, target_length + past_key_values_length), dtype=paddle.bool)
# ONNX doesn't support `Tensor.triu` properly, thus we use this workaround
seq_ids = paddle.arange(target_length)
mask[:, past_key_values_length:] = seq_ids[:, None] < seq_ids[None, :]
if past_key_values_length > 0:
mask[:, :past_key_values_length] = False
expanded_mask = mask[None, None, :, :].expand(
shape=(batch_size, 1, target_length, target_length + past_key_values_length)
)
return expanded_mask
def _expand_mask(mask: Tensor, tgt_length: int):
batch_size, src_length = mask.shape
tgt_length = tgt_length if tgt_length is not None else src_length
expanded_mask = ~(paddle.cast(mask[:, None, None, :], "bool"))
return expanded_mask.expand(shape=(batch_size, 1, tgt_length, src_length))
def build_alibi_tensor(attention_mask: Tensor, num_heads: int, dtype: paddle.dtype) -> Tensor:
batch_size, seq_length = attention_mask.shape
closest_power_of_2 = 2 ** math.floor(math.log2(num_heads))
base = paddle.to_tensor(2 ** (-(2 ** -(math.log2(closest_power_of_2) - 3))), dtype=paddle.float32)
powers = paddle.arange(1, 1 + closest_power_of_2, dtype=paddle.float32)
slopes = paddle.pow(base, powers)
if closest_power_of_2 != num_heads:
extra_base = Tensor(2 ** (-(2 ** -(math.log2(2 * closest_power_of_2) - 3))), dtype=paddle.float32)
num_remaining_heads = min(closest_power_of_2, num_heads - closest_power_of_2)
extra_powers = paddle.arange(1, 1 + 2 * num_remaining_heads, 2, dtype=paddle.int32)
slopes = paddle.concat([slopes, paddle.pow(extra_base, extra_powers)], axis=0)
arange_tensor = ((attention_mask.cumsum(axis=-1) - 1) * attention_mask)[:, None, :]
alibi = paddle.cast(slopes[..., None], "bfloat16") * arange_tensor
return paddle.cast(alibi.reshape([batch_size * num_heads, 1, seq_length]), dtype)
def dropout_add(x: Tensor, residual: Tensor, prob: float, training: bool) -> Tensor:
out = nn.functional.dropout(x, p=prob, training=training)
out = residual + out
return out
class Attention(nn.Layer):
def __init__(self, config: RWConfig):
super().__init__()
self.hidden_size = config.hidden_size
self.num_heads = config.n_head
self.head_dim = self.hidden_size // self.num_heads
self.split_size = self.hidden_size
self.hidden_dropout = config.hidden_dropout
if self.head_dim * self.num_heads != self.hidden_size:
raise ValueError(
f"`hidden_size` must be divisible by num_heads (got `hidden_size`: {self.hidden_size} and `num_heads`:"
f" {self.num_heads})."
)
self.maybe_rotary = RotaryEmbedding(config.head_dim) if config.rotary else lambda q, k: (q, k)
# Layer-wise attention scaling
self.inv_norm_factor = 1.0 / math.sqrt(self.head_dim)
self.beta = self.inv_norm_factor
self.query_key_value = nn.Linear(
self.hidden_size,
3 * self.hidden_size if not config.multi_query else (self.hidden_size + 2 * self.head_dim),
bias_attr=config.bias,
)
self.multi_query = config.multi_query
self.dense = nn.Linear(self.hidden_size, self.hidden_size, bias_attr=config.bias)
self.attention_dropout = nn.Dropout(config.attention_dropout)
self.num_kv = config.n_head if not self.multi_query else 1
def _split_heads(self, fused_qkv: Tensor) -> Tuple[Tensor, Tensor, Tensor]:
"""
Split the last dimension into (num_heads, head_dim) without making any copies, results share same memory
storage as `fused_qkv`
Args:
fused_qkv (`Tensor`, *required*): [batch_size, seq_length, num_heads * 3 * head_dim]
Returns:
query: [batch_size, seq_length, num_heads, head_dim] key: [batch_size, seq_length, num_heads, head_dim]
value: [batch_size, seq_length, num_heads, head_dim]
"""
if not self.multi_query:
batch_size, seq_length, three_times_hidden_size = fused_qkv.shape
fused_qkv = fused_qkv.reshape([batch_size, seq_length, self.num_heads, 3, self.head_dim])
return fused_qkv[..., 0, :], fused_qkv[..., 1, :], fused_qkv[..., 2, :]
else:
batch_size, seq_length, three_times_hidden_size = fused_qkv.shape
fused_qkv = fused_qkv.reshape([batch_size, seq_length, self.num_heads + 2, self.head_dim])
return fused_qkv[..., :-2, :], fused_qkv[..., -2, :].unsqueeze(-2), fused_qkv[..., -1, :].unsqueeze(-2)
def _merge_heads(self, x: Tensor) -> Tensor:
"""
Merge heads together over the last dimension
Args:
x: (`Tensor`, *required*): [batch_size * num_heads, seq_length, head_dim]
Returns:
Tensor: [batch_size, seq_length, num_heads * head_dim]
"""
# What we want to achieve is:
# batch_size * num_heads, seq_length, head_dim -> batch_size, seq_length, num_heads * head_dim
batch_size_and_num_heads, seq_length, _ = x.shape
batch_size = batch_size_and_num_heads // self.num_heads
# First reshape to decompose the batch size
# batch_size * num_heads, seq_length, head_dim -> batch_size, num_heads, seq_length, head_dim
x = x.reshape([batch_size, self.num_heads, seq_length, self.head_dim])
# batch_size, num_heads, seq_length, head_dim -> batch_size, seq_length, num_heads, head_dim
x = x.transpose([0, 2, 1, 3])
# batch_size, seq_length, num_heads, head_dim -> batch_size, seq_length, num_heads * head_dim
return x.reshape([batch_size, seq_length, self.num_heads * self.head_dim])
def forward(
self,
hidden_states: Tensor,
alibi: Tensor,
attention_mask: Tensor,
layer_past: Optional[Tuple[Tensor, Tensor]] = None,
head_mask: Optional[Tensor] = None,
use_cache: bool = False,
output_attentions: bool = False,
i: int = 0,
):
fused_qkv = self.query_key_value(hidden_states) # [batch_size, seq_length, 3 x hidden_size]
# 3 x [batch_size, seq_length, num_heads, head_dim]
(query_layer, key_layer, value_layer) = self._split_heads(fused_qkv)
batch_size, q_length, _, _ = query_layer.shape
# [batch_size, seq_length, num_heads, head_dim]
query_layer = query_layer.transpose([0, 2, 1, 3]).reshape(
[batch_size * self.num_heads, q_length, self.head_dim]
)
key_layer = key_layer.transpose([0, 2, 1, 3]).reshape(
[
batch_size * self.num_kv,
q_length,
self.head_dim,
]
)
value_layer = value_layer.transpose([0, 2, 1, 3]).reshape([batch_size * self.num_kv, q_length, self.head_dim])
query_layer, key_layer = self.maybe_rotary(query_layer, key_layer)
if layer_past is not None:
past_key, past_value = layer_past
# concatenate along seq_length dimension:
# - key: [batch_size * self.num_heads, head_dim, kv_length]
# - value: [batch_size * self.num_heads, kv_length, head_dim]
key_layer = paddle.concat((past_key, key_layer), axis=1)
value_layer = paddle.concat((past_value, value_layer), axis=1)
# if use layer_past, kv_length != q_length
_, kv_length, _ = key_layer.shape
if use_cache is True:
present = (key_layer, value_layer)
else:
present = None
if alibi is None:
query_layer_ = query_layer.reshape([batch_size, self.num_heads, q_length, self.head_dim])
key_layer_ = key_layer.reshape([batch_size, self.num_kv, kv_length, self.head_dim])
value_layer_ = value_layer.reshape([batch_size, self.num_kv, kv_length, self.head_dim])
attn_output = query_layer_ @ key_layer_.transpose([0, 1, 3, 2])
attention_scores = attn_output.reshape([batch_size, self.num_heads, q_length, kv_length])
# cast attention scores to fp32, compute scaled softmax and cast back to initial dtype - [batch_size, num_heads, q_length, kv_length]
input_dtype = attention_scores.dtype
# `float16` has a minimum value of -65504.0, whereas `bfloat16` and `float32` have a minimum value of `-3.4e+38`
if input_dtype == paddle.float16 or input_dtype == paddle.bfloat16:
attention_scores = paddle.cast(attention_scores, paddle.float32)
attention_scores = paddle.where(
attention_mask > 0,
paddle.full_like(attention_scores, paddle.finfo(attention_scores.dtype).min),
attention_scores,
)
attention_probs = nn.functional.softmax(
attention_scores * self.inv_norm_factor,
axis=-1,
dtype=hidden_states.dtype,
)
# [batch_size, num_heads, q_length, kv_length]
attention_probs = self.attention_dropout(attention_probs)
if head_mask is not None:
attention_probs = attention_probs * head_mask
# matmul: [batch_size, num_heads, q_length, head_dim]
context_layer = attention_probs @ value_layer_
# change reshape [batch_size , q_length, num_heads * head_dim]
context_layer = context_layer.transpose([0, 2, 1, 3])
context_layer = context_layer.reshape([batch_size, q_length, -1])
output_tensor = self.dense(context_layer)
outputs = (output_tensor, present)
if output_attentions:
outputs += (attention_probs,)
return outputs
else:
query_layer_ = query_layer.reshape([batch_size, self.num_heads, q_length, self.head_dim])
key_layer_ = key_layer.reshape([batch_size, self.num_kv, kv_length, self.head_dim])
value_layer_ = value_layer.reshape([batch_size, self.num_kv, kv_length, self.head_dim])
alibi = alibi.reshape([batch_size, self.num_heads, 1, -1])
attention_scores = query_layer_ @ key_layer_.transpose([0, 1, 3, 2])
attention_mask_float = paddle.zeros_like(attention_mask, dtype=attention_scores.dtype)
attention_mask_float = paddle.where(
attention_mask > 0,
paddle.full_like(attention_scores, paddle.finfo(attention_scores.dtype).min),
attention_mask_float,
)
# cast attention scores to fp32, compute scaled softmax and cast back to initial dtype - [batch_size, num_heads, q_length, kv_length]
input_dtype = attention_scores.dtype
# `float16` has a minimum value of -65504.0, whereas `bfloat16` and `float32` have a minimum value of `-3.4e+38`
if input_dtype == paddle.float16 or input_dtype == paddle.bfloat16:
attention_scores = paddle.cast(attention_scores, paddle.float32)
# attn_weights = paddle.masked_fill(attention_scores, attention_mask, paddle.finfo(attention_scores.dtype).min)
attention_probs = nn.functional.softmax(
(attention_scores + alibi) * self.inv_norm_factor + attention_mask_float,
axis=-1,
dtype=hidden_states.dtype,
)
# [batch_size, num_heads, q_length, kv_length]
attention_probs = self.attention_dropout(attention_probs)
if head_mask is not None:
attention_probs = attention_probs * head_mask
# matmul: [batch_size, num_heads, q_length, kv_length] * [batch_size, num_kv, kv_length, head_dim]
context_layer = attention_probs @ value_layer_
# change reshape [batch_size x num_heads, q_length, head_dim]
context_layer = context_layer.reshape([batch_size * self.num_heads, q_length, self.head_dim])
# change reshape [batch_size, num_heads, q_length, head_dim]
context_layer = self._merge_heads(context_layer)
output_tensor = self.dense(context_layer)
outputs = (output_tensor, present)
if output_attentions:
outputs += (attention_probs,)
return outputs
class MLP(nn.Layer):
def __init__(self, config: RWConfig):
super().__init__()
hidden_size = config.hidden_size
self.dense_h_to_4h = nn.Linear(hidden_size, 4 * hidden_size, bias_attr=config.bias)
self.act = nn.GELU()
self.dense_4h_to_h = nn.Linear(4 * hidden_size, hidden_size, bias_attr=config.bias)
self.hidden_dropout = config.hidden_dropout
def forward(self, x: Tensor) -> Tensor:
x = self.act(self.dense_h_to_4h(x))
x = self.dense_4h_to_h(x)
return x
class DecoderLayer(nn.Layer):
def __init__(self, config: RWConfig):
super().__init__()
hidden_size = config.hidden_size
self.input_layernorm = nn.LayerNorm(hidden_size, epsilon=config.layer_norm_epsilon)
self.num_heads = config.n_head
self.self_attention = Attention(config)
if not config.parallel_attn:
# unused if parallel attn
self.post_attention_layernorm = nn.LayerNorm(hidden_size, epsilon=config.layer_norm_epsilon)
self.mlp = MLP(config)
self.apply_residual_connection_post_layernorm = config.apply_residual_connection_post_layernorm
self.hidden_dropout = config.hidden_dropout
self.config = config
def forward(
self,
hidden_states: Tensor = None,
alibi: Tensor = None,
attention_mask: Tensor = None,
layer_past: Optional[Tuple[Tensor, Tensor]] = None,
head_mask: Optional[Tensor] = None,
use_cache: bool = False,
output_attentions: bool = False,
i: int = 0,
):
layernorm_output = self.input_layernorm(hidden_states)
residual = hidden_states
# Self attention.
attn_outputs = self.self_attention(
layernorm_output,
layer_past=layer_past,
attention_mask=attention_mask,
alibi=alibi,
head_mask=head_mask,
use_cache=use_cache,
output_attentions=output_attentions,
i=i,
)
attention_output = attn_outputs[0]
if not self.config.parallel_attn:
residual = dropout_add(attention_output, residual, self.config.attention_dropout, training=self.training)
layernorm_output = self.post_attention_layernorm(residual)
outputs = attn_outputs[1:]
# MLP.
mlp_output = self.mlp(layernorm_output)
if self.config.parallel_attn:
mlp_output += attention_output
output = dropout_add(mlp_output, residual, self.config.hidden_dropout, training=self.training)
if use_cache:
outputs = (output,) + outputs
else:
outputs = (output,) + outputs[1:]
return outputs # hidden_states, present, attentions
class RWPreTrainedModel(PretrainedModel):
"""
An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained
models.
"""
config_class = RWConfig
base_model_prefix = "transformer"
pretrained_init_configuration = RW_PRETRAINED_INIT_CONFIGURATION
@classmethod
def _get_name_mappings(cls, config: RWConfig) -> List[StateDictNameMapping]:
mappings = [
"word_embeddings.weight",
"ln_f.weight",
"ln_f.bias",
]
for layer_index in range(config.num_hidden_layers):
layer_mappings = [
[
f"h.{layer_index}.input_layernorm.weight",
f"h.{layer_index}.input_layernorm.weight",
],
[
f"h.{layer_index}.input_layernorm.bias",
f"h.{layer_index}.input_layernorm.bias",
],
[
f"h.{layer_index}.self_attention.query_key_value.weight",
f"h.{layer_index}.self_attention.query_key_value.weight",
"transpose",
],
[
f"h.{layer_index}.self_attention.query_key_value.bias",
f"h.{layer_index}.self_attention.query_key_value.bias",
],
[
f"h.{layer_index}.self_attention.dense.weight",
f"h.{layer_index}.self_attention.dense.weight",
"transpose",
],
[
f"h.{layer_index}.self_attention.dense.bias",
f"h.{layer_index}.self_attention.dense.bias",
],
[
f"h.{layer_index}.mlp.dense_h_to_4h.weight",
f"h.{layer_index}.mlp.dense_h_to_4h.weight",
"transpose",
],
[
f"h.{layer_index}.mlp.dense_h_to_4h.bias",
f"h.{layer_index}.mlp.dense_h_to_4h.bias",
],
[
f"h.{layer_index}.mlp.dense_4h_to_h.weight",
f"h.{layer_index}.mlp.dense_4h_to_h.weight",
"transpose",
],
[
f"h.{layer_index}.mlp.dense_4h_to_h.bias",
f"h.{layer_index}.mlp.dense_4h_to_h.bias",
],
]
mappings.extend(layer_mappings)
init_name_mappings(mappings)
# Other than RWModel, other architectures will prepend model prefix
if config.architectures is not None and "RWModel" not in config.architectures:
for mapping in mappings:
mapping[0] = "transformer." + mapping[0]
if len(mapping) > 1 and mapping[1] is not None:
mapping[1] = "transformer." + mapping[1]
if config.architectures is not None:
if "RWForCausalLM" in config.architectures:
mappings.extend(
[
"lm_head.weight",
"lm_head.bias",
]
)
init_name_mappings(mappings)
return [StateDictNameMapping(*mapping) for mapping in mappings]
def __init__(self, *inputs, **kwargs):
super().__init__(*inputs, **kwargs)
def _init_weights(self, layer: nn.Layer):
"""Initialize the weights."""
if isinstance(layer, (nn.Linear, nn.Embedding)):
layer.weight.set_value(
paddle.tensor.normal(mean=0.0, std=self.config.initializer_range, shape=layer.weight.shape)
)
if getattr(layer, "bias", None) is not None:
layer.weight.set_value(paddle.zeros(shape=layer.weight.shape, dtype=paddle.get_default_dtype()))
def _set_gradient_checkpointing(self, module: nn.Layer, value: bool = False):
if isinstance(module, RWModel):
module.gradient_checkpointing = value
@staticmethod
def _convert_to_standard_cache(
past_key_value: Tuple[Tuple[Tensor, Tensor]], batch_size: int
) -> Tuple[Tuple[Tensor, Tensor]]:
"""
Standardizes the format of the cache so as to match most implementations, i.e. to tuple(tuple([batch_size,
num_heads, ...]))
"""
batch_size_times_num_heads, head_dim, seq_length = past_key_value[0][0].shape
num_heads = batch_size_times_num_heads // batch_size
# key: [batch_size * num_heads, head_dim, seq_length] -> [batch_size, num_heads, head_dim, seq_length]
# value: [batch_size * num_heads, seq_length, head_dim] -> [batch_size, num_heads, seq_length, head_dim]
return tuple(
(
layer_past[0].reshape([batch_size, num_heads, head_dim, seq_length]),
layer_past[1].reshape([batch_size, num_heads, seq_length, head_dim]),
)
for layer_past in past_key_value
)
@staticmethod
def _convert_to_rw_cache(past_key_value: Tuple[Tuple[Tensor, Tensor]]) -> Tuple[Tuple[Tensor, Tensor]]:
batch_size, num_heads, head_dim, seq_length = past_key_value[0][0].shape
batch_size_times_num_heads = batch_size * num_heads
# key: [batch_size, num_heads, head_dim, seq_length] -> [batch_size * num_heads, head_dim, seq_length]
# value: [batch_size, num_heads, seq_length, head_dim] -> [batch_size * num_heads, seq_length, head_dim]
return tuple(
(
layer_past[0].reshape([batch_size_times_num_heads, head_dim, seq_length]),
layer_past[1].reshape([batch_size_times_num_heads, seq_length, head_dim]),
)
for layer_past in past_key_value
)
class RWModel(RWPreTrainedModel):
def __init__(self, config: RWConfig):
super().__init__(config)
self.embed_dim = config.hidden_size
self.num_heads = config.n_head
self.alibi = config.alibi
# Embedding + LN Embedding
self.word_embeddings = nn.Embedding(config.vocab_size, self.embed_dim)
# Transformer blocks
self.h = nn.LayerList([DecoderLayer(config) for _ in range(config.num_hidden_layers)])
# Final Layer Norm
self.ln_f = nn.LayerNorm(self.embed_dim, epsilon=config.layer_norm_epsilon)
self.gradient_checkpointing = False
def get_input_embeddings(self):
return self.word_embeddings
def _prepare_attn_mask(self, attention_mask: Tensor, input_shape: Tuple[int, int], past_key_values_length: int):
# create causal mask
# [batch_size, seq_length] -> [batch_size, 1, tgt_length, src_length]
combined_attention_mask = None
# device = attention_mask.device
_, src_length = input_shape
if src_length > 1:
combined_attention_mask = _make_causal_mask(input_shape, past_key_values_length=past_key_values_length)
# [batch_size, seq_length] -> [batch_size, 1, tgt_length, src_length]
expanded_attn_mask = _expand_mask(attention_mask, tgt_length=src_length)
combined_attention_mask = (
expanded_attn_mask if combined_attention_mask is None else expanded_attn_mask | combined_attention_mask
)
return combined_attention_mask
def set_input_embeddings(self, new_embeddings: Tensor):
self.word_embeddings = new_embeddings
def _convert_head_mask_to_5d(self, head_mask, num_hidden_layers):
"""-> [num_hidden_layers x batch x num_heads x seq_length x seq_length]"""
if head_mask.dim() == 1:
axis = paddle.to_tensor([0, 1, 3, 4])
head_mask = paddle.unsqueeze(head_mask, axis=axis)
head_mask = head_mask.expand(shape=(num_hidden_layers, -1, -1, -1, -1))
elif head_mask.dim() == 2:
axis = paddle.to_tensor([1, 3, 4])
head_mask = paddle.unsqueeze(head_mask, axis=axis)
assert head_mask.dim() == 5, f"head_mask.dim != 5, instead {head_mask.dim()}"
head_mask = paddle.cast(head_mask, dtype=self.config.dtype)
return head_mask
def get_head_mask(
self, head_mask: Optional[Tensor], num_hidden_layers: int, is_attention_chunked: bool = False
) -> Tensor:
"""
Prepare the head mask if needed.
Args:
head_mask (`paddle.Tensor` with shape `[num_heads]` or `[num_hidden_layers x num_heads]`, *optional*):
The mask indicating if we should keep the heads or not (1.0 for keep, 0.0 for discard).
num_hidden_layers (`int`):
The number of hidden layers in the model.
is_attention_chunked: (`bool`, *optional*, defaults to `False`):
Whether or not the attentions scores are computed by chunks or not.
Returns:
`paddle.Tensor` with shape `[num_hidden_layers x batch x num_heads x seq_length x seq_length]` or list with
`[None]` for each layer.
"""
if head_mask is not None:
head_mask = self._convert_head_mask_to_5d(head_mask, num_hidden_layers)
if is_attention_chunked is True:
head_mask = head_mask.unsqueeze(-1)
else:
head_mask = [None] * num_hidden_layers
return head_mask
def forward(
self,
input_ids=None,
past_key_values=None,
attention_mask=None,
head_mask=None,
inputs_embeds=None,
use_cache=None,
output_attentions=None,
output_hidden_states=None,
return_dict=None,
**deprecated_arguments,
) -> Union[Tuple[Tensor, ...], BaseModelOutputWithPastAndCrossAttentions]:
if deprecated_arguments.pop("position_ids", False) is not False:
# `position_ids` could have been `Tensor` or `None` so defaulting pop to `False` allows to detect if users were passing explicitly `None`
warnings.warn(
"`position_ids` have no functionality in BLOOM and will be removed in v5.0.0. You can safely ignore"
" passing `position_ids`.",
FutureWarning,
)
if len(deprecated_arguments) > 0:
raise ValueError(f"Got unexpected arguments: {deprecated_arguments}")
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
)
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
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:
batch_size, seq_length = input_ids.shape
elif inputs_embeds is not None:
batch_size, seq_length, _ = inputs_embeds.shape
else:
raise ValueError("You have to specify either input_ids or inputs_embeds")
if past_key_values is None:
past_key_values = tuple([None] * len(self.h))
# Prepare head mask if needed
# 1.0 in head_mask indicate we keep the head
# attention_probs has shape batch_size x num_heads x N x N
# head_mask has shape n_layer x batch x num_heads x N x N
head_mask = self.get_head_mask(head_mask, self.config.n_layer)
if inputs_embeds is None:
inputs_embeds = self.word_embeddings(input_ids)
hidden_states = inputs_embeds
presents = () if use_cache else None
all_self_attentions = () if output_attentions else None
all_hidden_states = () if output_hidden_states else None
# Compute alibi tensor: check build_alibi_tensor documentation
seq_length_with_past = seq_length
past_key_values_length = 0
if past_key_values[0] is not None:
past_key_values_length = past_key_values[0][0].shape[2]
seq_length_with_past = seq_length_with_past + past_key_values_length
if attention_mask is None:
attention_mask = paddle.ones((batch_size, seq_length_with_past))
if self.alibi:
alibi = build_alibi_tensor(attention_mask, self.num_heads, dtype=hidden_states.dtype)
else:
alibi = None
causal_mask = self._prepare_attn_mask(
attention_mask,
input_shape=(batch_size, seq_length),
past_key_values_length=past_key_values_length,
)
for i, (block, layer_past) in enumerate(zip(self.h, past_key_values)):
if output_hidden_states:
all_hidden_states = all_hidden_states + (hidden_states,)
outputs = block(
hidden_states,
layer_past=layer_past,
attention_mask=causal_mask,
head_mask=head_mask[i],
use_cache=use_cache,
output_attentions=output_attentions,
alibi=alibi,
i=i,
)
hidden_states = outputs[0]
if use_cache is True:
presents = presents + (outputs[1],)
if output_attentions:
all_self_attentions = all_self_attentions + (outputs[2 if use_cache else 1],)
# Add last hidden state
hidden_states = self.ln_f(hidden_states)
if output_hidden_states:
all_hidden_states = all_hidden_states + (hidden_states,)
if not return_dict:
return tuple(v for v in [hidden_states, presents, all_hidden_states, all_self_attentions] if v is not None)
return BaseModelOutputWithPastAndCrossAttentions(
last_hidden_state=hidden_states,
past_key_values=presents,
hidden_states=all_hidden_states,
attentions=all_self_attentions,
)
class CausalLMHead(nn.Linear):
def forward(self, input: Tensor) -> Tensor:
ret = input @ self.weight.T
return ret
class RWForCausalLM(RWPreTrainedModel):
_keys_to_ignore_on_load_missing = [r"lm_head.weight"]
def __init__(self, config: RWConfig):
super().__init__(config)
self.transformer = RWModel(config)
self.lm_head = CausalLMHead(config.vocab_size, config.hidden_size, bias_attr=False)
def get_output_embeddings(self):
return self.lm_head
def set_output_embeddings(self, new_embeddings: Tensor):
self.lm_head = new_embeddings
def prepare_attention_mask_for_generation(self, input_ids, pad_token_id, eos_token_id):
is_pad_token_in_inputs_ids = (pad_token_id is not None) and paddle.any(input_ids == pad_token_id).item()
is_pad_token_not_equal_to_eos_token_id = (eos_token_id is None) or (
(eos_token_id is not None) and (pad_token_id != eos_token_id)
)
if is_pad_token_in_inputs_ids and is_pad_token_not_equal_to_eos_token_id:
attention_mask = (input_ids != pad_token_id).astype("int64")
else:
attention_mask = paddle.ones_like(input_ids, dtype="int64")
return attention_mask
def prepare_inputs_for_generation(
self,
input_ids,
past: Optional[Tensor] = None,
attention_mask: Optional[Tensor] = None,
**kwargs,
) -> dict:
# only last token for input_ids if past is not None
if past:
input_ids = input_ids[:, -1].unsqueeze(-1)
# the cache may be in the standard format (e.g. in contrastive search), convert to our's format if needed
if past[0][0].shape[0] == input_ids.shape[0]:
past = self._convert_to_rw_cache(past)
return {
"input_ids": input_ids,
"past_key_values": past,
"use_cache": kwargs.get("use_cache"),
"attention_mask": attention_mask,
}
def forward(
self,
input_ids=None,
past_key_values: Optional[Tuple[Tuple[Tensor, Tensor], ...]] = None,
attention_mask: Optional[Tensor] = None,
head_mask: Optional[Tensor] = None,
inputs_embeds: Optional[Tensor] = None,
labels: Optional[Tensor] = None,
use_cache: Optional[bool] = None,
output_attentions: Optional[bool] = None,
output_hidden_states: Optional[bool] = None,
return_dict: Optional[bool] = None,
**deprecated_arguments,
) -> Union[Tuple[Tensor], CausalLMOutputWithCrossAttentions]:
r"""
labels (`paddle.LongTensor` of shape `(batch_size, sequence_length)`, *optional*):
Labels for language modeling. Note that the labels **are shifted** inside the model, i.e. you can set
`labels = input_ids` Indices are selected in `[-100, 0, ..., config.vocab_size]` All labels set to `-100`
are ignored (masked), the loss is only computed for labels in `[0, ..., config.vocab_size]`
"""
return_dict = return_dict if return_dict is not None else self.config.use_return_dict
transformer_outputs = self.transformer(
input_ids,
past_key_values=past_key_values,
attention_mask=attention_mask,
head_mask=head_mask,
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]
lm_logits = self.lm_head(hidden_states)
loss = None
if labels is not None:
loss = nn.functional.cross_entropy(lm_logits, labels)
if not return_dict:
output = (lm_logits,) + transformer_outputs[1:]
return ((loss,) + output) if loss is not None else output
return CausalLMOutputWithCrossAttentions(
loss=loss,
logits=lm_logits,
past_key_values=transformer_outputs.past_key_values,
hidden_states=transformer_outputs.hidden_states,
attentions=transformer_outputs.attentions,
)
@staticmethod
def _reorder_cache(past: Tuple[Tuple[Tensor]], beam_idx: Tensor) -> Tuple[Tuple[Tensor]]:
"""
This function is used to re-order the `past_key_values` cache if [`~PreTrainedModel.beam_search`] or
[`~PreTrainedModel.beam_sample`] is called. This is required to match `past_key_values` with the correct
beam_idx at every generation step.
"""
return tuple(tuple(past_state.index_select(0, beam_idx) for past_state in layer_past) for layer_past in past)