192 lines
7.7 KiB
Python
192 lines
7.7 KiB
Python
# Copyright (c) 2023 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.
|
|
|
|
from __future__ import annotations
|
|
|
|
from typing import Any, Optional
|
|
|
|
import paddle
|
|
from paddle import nn
|
|
from paddle.distributed.fleet.utils.sequence_parallel_utils import GatherOp
|
|
|
|
from ...transformers import PretrainedConfig, PretrainedModel
|
|
from ...transformers.auto import AutoModel
|
|
from .score_model_utils import ScoreModelMixin, ScoreModelOutput
|
|
|
|
|
|
class AutoModelForScore(ScoreModelMixin, PretrainedModel):
|
|
_keys_to_ignore_on_load_missing = ["lm_head.weight"]
|
|
|
|
def __init__(self, config: PretrainedConfig, **kwargs: Any) -> None:
|
|
"""
|
|
Initializes a `AutoModelForScore` model.
|
|
|
|
Args:
|
|
config (PretrainedConfig): Model configuration class with all the parameters of the model.
|
|
kwargs (Any, optional): Additional keyword arguments passed along to the `__init__` of the parent class.
|
|
This is necessary because of how `transformers.AutoModelWithHead` is designed. Defaults to `None`.
|
|
|
|
Raises:
|
|
TypeError: If the config is not an instance of `PretrainedConfig`.
|
|
"""
|
|
super().__init__(config)
|
|
|
|
@classmethod
|
|
def from_pretrained(cls, pretrained_model_name_or_path: str, *model_args, **kwargs):
|
|
config = kwargs.pop("config", None)
|
|
model = cls(config, **kwargs)
|
|
model.config = config
|
|
model.model = AutoModel.from_pretrained(pretrained_model_name_or_path, config=config)
|
|
model.init_score_head(config, hidden_size=config.hidden_size, **kwargs)
|
|
model.head_init_weights()
|
|
return model
|
|
|
|
def head_init_weights(self):
|
|
self.score_head.weight.set_value(
|
|
paddle.tensor.normal(
|
|
mean=0.0,
|
|
std=self.config.initializer_range,
|
|
shape=self.score_head.weight.shape,
|
|
)
|
|
)
|
|
if hasattr(self.score_head, "bias") and isinstance(self.score_head.bias, paddle.Tensor):
|
|
self.score_head.bias.set_value(paddle.zeros_like(self.score_head.bias))
|
|
|
|
@classmethod
|
|
def from_config(cls, config, **kwargs):
|
|
model = cls(config, **kwargs)
|
|
model.model = AutoModel.from_config(config)
|
|
model.config = config
|
|
model.init_score_head(config, hidden_size=config.hidden_size, **kwargs)
|
|
return model
|
|
|
|
def get_input_embeddings(self) -> Optional[nn.Embedding]:
|
|
"""
|
|
Returns the nn.Embedding object for input embeddings, which converts input sequences into embedding vectors.
|
|
If the model does not use embeddings, it returns None.
|
|
|
|
Returns:
|
|
Optional[nn.Embedding]: The nn.Embedding object for input embeddings, or None if embeddings are not used.
|
|
"""
|
|
return self.model.embed_tokens
|
|
|
|
def set_input_embeddings(self, value: nn.Embedding) -> None:
|
|
"""
|
|
Set the input embeddings to be used for the model.
|
|
|
|
Args:
|
|
value (nn.Embedding): The embedding layer to use.
|
|
|
|
Returns:
|
|
NoneType: No return value is returned. Instead, the input embeddings are updated in-place.
|
|
"""
|
|
self.model.embed_tokens = value
|
|
|
|
def get_decoder(self) -> PretrainedModel:
|
|
"""
|
|
Retrieve the decoder model.
|
|
|
|
Returns:
|
|
PretrainedModel: The decoder model, which is an instance of PaddlePaddle's PretrainedModel class.
|
|
"""
|
|
return self.model
|
|
|
|
def set_decoder(self, decoder: PretrainedModel) -> None:
|
|
"""
|
|
Sets the decoder for text generation.
|
|
|
|
Args:
|
|
decoder (PretrainedModel): A pre-trained model object that serves as a valid decoder.
|
|
|
|
Returns:
|
|
None: No return value.
|
|
"""
|
|
self.model = decoder
|
|
|
|
def forward(
|
|
self,
|
|
input_ids: paddle.Tensor,
|
|
position_ids: paddle.Tensor | None = None,
|
|
past_key_values: list[paddle.Tensor] | None = None,
|
|
inputs_embeds: paddle.Tensor | None = None,
|
|
use_cache: bool | None = None,
|
|
output_attentions: bool | None = None,
|
|
output_hidden_states: bool | None = None,
|
|
return_dict: bool | None = None,
|
|
attn_mask_startend_row_indices: paddle.Tensor | None = None,
|
|
**kwargs
|
|
) -> tuple[paddle.Tensor, paddle.Tensor] | ScoreModelOutput:
|
|
"""
|
|
Forward pass of the sentence.
|
|
|
|
Args:
|
|
input_ids (paddle.Tensor):
|
|
IDs of the input sequences, with shape (batch_size, sequence_length).
|
|
attention_mask (paddle.Tensor):
|
|
Mask used to distinguish padding and non-padding elements, with shape (batch_size, sequence_length), values are 0 or 1.
|
|
position_ids (paddle.Tensor, optional):
|
|
Position IDs corresponding to input_ids, with shape (batch_size, sequence_length), default is None.
|
|
past_key_values (list[paddle.Tensor], optional):
|
|
Contains all preprocessed keys and values, default is None.
|
|
inputs_embeds (paddle.Tensor, optional):
|
|
Embeddings of the input sequences, with shape (batch_size, sequence_length, embedding_dimension), default is None.
|
|
use_cache (bool, optional):
|
|
Whether to use caching, default is None.
|
|
output_attentions (bool, optional):
|
|
Whether to return attention tensors, default is None.
|
|
output_hidden_states (bool, optional):
|
|
Whether to return hidden states, default is None.
|
|
return_dict (bool, optional):
|
|
Whether to return results in dictionary format, default is None.
|
|
|
|
Returns:
|
|
tuple[paddle.Tensor, paddle.Tensor] or ScoreModelOutput:
|
|
If `return_dict` is True, returns a tuple of ScoreModelOutput type containing two elements: score and additional information; otherwise, returns a tuple containing the score and additional information.
|
|
Raises:
|
|
AssertionError:
|
|
Raised when `attention_mask` is not 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
|
|
|
|
outputs = self.model(
|
|
input_ids=input_ids,
|
|
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,
|
|
attn_mask_startend_row_indices=attn_mask_startend_row_indices,
|
|
return_dict=return_dict,
|
|
)
|
|
critic_hidden_states = outputs[0] # size = (B, L, E)
|
|
|
|
if self.config.sequence_parallel:
|
|
gather_hidden_states = GatherOp.apply(critic_hidden_states)
|
|
|
|
hidden_states = paddle.reshape_(
|
|
gather_hidden_states, [-1, position_ids.shape[1], gather_hidden_states.shape[-1]]
|
|
)
|
|
|
|
return self.get_score(
|
|
hidden_states,
|
|
position_ids=position_ids,
|
|
return_dict=return_dict,
|
|
)
|