Add files using upload-large-folder tool
Browse filesThis view is limited to 50 files because it contains too many changes. See raw diff
- third_party/transformers/src/transformers/models/albert/__init__.py +28 -0
- third_party/transformers/src/transformers/models/albert/configuration_albert.py +78 -0
- third_party/transformers/src/transformers/models/albert/convert_albert_original_tf_checkpoint_to_pytorch.py +61 -0
- third_party/transformers/src/transformers/models/albert/modeling_albert.py +976 -0
- third_party/transformers/src/transformers/models/albert/tokenization_albert.py +176 -0
- third_party/transformers/src/transformers/models/bark/generation_configuration_bark.py +327 -0
- third_party/transformers/src/transformers/models/big_bird/__init__.py +28 -0
- third_party/transformers/src/transformers/models/big_bird/configuration_big_bird.py +84 -0
- third_party/transformers/src/transformers/models/big_bird/convert_bigbird_original_tf_checkpoint_to_pytorch.py +251 -0
- third_party/transformers/src/transformers/models/big_bird/modeling_big_bird.py +0 -0
- third_party/transformers/src/transformers/models/big_bird/tokenization_big_bird.py +151 -0
- third_party/transformers/src/transformers/models/bigbird_pegasus/__init__.py +27 -0
- third_party/transformers/src/transformers/models/bigbird_pegasus/configuration_bigbird_pegasus.py +93 -0
- third_party/transformers/src/transformers/models/bigbird_pegasus/convert_bigbird_pegasus_tf_to_pytorch.py +168 -0
- third_party/transformers/src/transformers/models/bigbird_pegasus/modeling_bigbird_pegasus.py +0 -0
- third_party/transformers/src/transformers/models/bitnet/__init__.py +27 -0
- third_party/transformers/src/transformers/models/bitnet/configuration_bitnet.py +71 -0
- third_party/transformers/src/transformers/models/bitnet/modeling_bitnet.py +501 -0
- third_party/transformers/src/transformers/models/bitnet/modular_bitnet.py +148 -0
- third_party/transformers/src/transformers/models/blip/__init__.py +31 -0
- third_party/transformers/src/transformers/models/blip/configuration_blip.py +174 -0
- third_party/transformers/src/transformers/models/blip/convert_blip_original_pytorch_to_hf.py +192 -0
- third_party/transformers/src/transformers/models/blip/image_processing_blip.py +34 -0
- third_party/transformers/src/transformers/models/blip/image_processing_pil_blip.py +34 -0
- third_party/transformers/src/transformers/models/blip/modeling_blip.py +1302 -0
- third_party/transformers/src/transformers/models/blip/modeling_blip_text.py +801 -0
- third_party/transformers/src/transformers/models/blip/processing_blip.py +84 -0
- third_party/transformers/src/transformers/models/camembert/__init__.py +28 -0
- third_party/transformers/src/transformers/models/camembert/configuration_camembert.py +66 -0
- third_party/transformers/src/transformers/models/camembert/modeling_camembert.py +1272 -0
- third_party/transformers/src/transformers/models/camembert/modular_camembert.py +534 -0
- third_party/transformers/src/transformers/models/camembert/tokenization_camembert.py +166 -0
- third_party/transformers/src/transformers/models/canine/__init__.py +28 -0
- third_party/transformers/src/transformers/models/canine/configuration_canine.py +78 -0
- third_party/transformers/src/transformers/models/canine/convert_canine_original_tf_checkpoint_to_pytorch.py +165 -0
- third_party/transformers/src/transformers/models/canine/modeling_canine.py +1358 -0
- third_party/transformers/src/transformers/models/canine/tokenization_canine.py +156 -0
- third_party/transformers/src/transformers/models/code_llama/__init__.py +26 -0
- third_party/transformers/src/transformers/models/code_llama/tokenization_code_llama.py +358 -0
- third_party/transformers/src/transformers/models/cohere/__init__.py +28 -0
- third_party/transformers/src/transformers/models/cohere/configuration_cohere.py +94 -0
- third_party/transformers/src/transformers/models/cohere/modeling_cohere.py +530 -0
- third_party/transformers/src/transformers/models/cohere/modular_cohere.py +326 -0
- third_party/transformers/src/transformers/models/cohere/tokenization_cohere.py +384 -0
- third_party/transformers/src/transformers/models/cohere2_vision/__init__.py +29 -0
- third_party/transformers/src/transformers/models/cohere2_vision/configuration_cohere2_vision.py +65 -0
- third_party/transformers/src/transformers/models/cohere2_vision/image_processing_cohere2_vision.py +293 -0
- third_party/transformers/src/transformers/models/cohere2_vision/modeling_cohere2_vision.py +388 -0
- third_party/transformers/src/transformers/models/cohere2_vision/modular_cohere2_vision.py +328 -0
- third_party/transformers/src/transformers/models/cohere2_vision/processing_cohere2_vision.py +169 -0
third_party/transformers/src/transformers/models/albert/__init__.py
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright 2020 The HuggingFace Team. All rights reserved.
|
| 2 |
+
#
|
| 3 |
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
| 4 |
+
# you may not use this file except in compliance with the License.
|
| 5 |
+
# You may obtain a copy of the License at
|
| 6 |
+
#
|
| 7 |
+
# http://www.apache.org/licenses/LICENSE-2.0
|
| 8 |
+
#
|
| 9 |
+
# Unless required by applicable law or agreed to in writing, software
|
| 10 |
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
| 11 |
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 12 |
+
# See the License for the specific language governing permissions and
|
| 13 |
+
# limitations under the License.
|
| 14 |
+
from typing import TYPE_CHECKING
|
| 15 |
+
|
| 16 |
+
from ...utils import _LazyModule
|
| 17 |
+
from ...utils.import_utils import define_import_structure
|
| 18 |
+
|
| 19 |
+
|
| 20 |
+
if TYPE_CHECKING:
|
| 21 |
+
from .configuration_albert import *
|
| 22 |
+
from .modeling_albert import *
|
| 23 |
+
from .tokenization_albert import *
|
| 24 |
+
else:
|
| 25 |
+
import sys
|
| 26 |
+
|
| 27 |
+
_file = globals()["__file__"]
|
| 28 |
+
sys.modules[__name__] = _LazyModule(__name__, _file, define_import_structure(_file), module_spec=__spec__)
|
third_party/transformers/src/transformers/models/albert/configuration_albert.py
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright 2018 The Google AI Language Team Authors and The HuggingFace Inc. team.
|
| 2 |
+
# Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved.
|
| 3 |
+
#
|
| 4 |
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
| 5 |
+
# you may not use this file except in compliance with the License.
|
| 6 |
+
# You may obtain a copy of the License at
|
| 7 |
+
#
|
| 8 |
+
# http://www.apache.org/licenses/LICENSE-2.0
|
| 9 |
+
#
|
| 10 |
+
# Unless required by applicable law or agreed to in writing, software
|
| 11 |
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
| 12 |
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 13 |
+
# See the License for the specific language governing permissions and
|
| 14 |
+
# limitations under the License.
|
| 15 |
+
"""ALBERT model configuration"""
|
| 16 |
+
|
| 17 |
+
from huggingface_hub.dataclasses import strict
|
| 18 |
+
|
| 19 |
+
from ...configuration_utils import PreTrainedConfig
|
| 20 |
+
from ...utils import auto_docstring
|
| 21 |
+
|
| 22 |
+
|
| 23 |
+
@auto_docstring(checkpoint="albert/albert-xxlarge-v2")
|
| 24 |
+
@strict
|
| 25 |
+
class AlbertConfig(PreTrainedConfig):
|
| 26 |
+
r"""
|
| 27 |
+
num_hidden_groups (`int`, *optional*, defaults to 1):
|
| 28 |
+
Number of groups for the hidden layers, parameters in the same group are shared.
|
| 29 |
+
inner_group_num (`int`, *optional*, defaults to 1):
|
| 30 |
+
The number of inner repetition of attention and ffn.
|
| 31 |
+
|
| 32 |
+
Examples:
|
| 33 |
+
|
| 34 |
+
```python
|
| 35 |
+
>>> from transformers import AlbertConfig, AlbertModel
|
| 36 |
+
|
| 37 |
+
>>> # Initializing an ALBERT-xxlarge style configuration
|
| 38 |
+
>>> albert_xxlarge_configuration = AlbertConfig()
|
| 39 |
+
|
| 40 |
+
>>> # Initializing an ALBERT-base style configuration
|
| 41 |
+
>>> albert_base_configuration = AlbertConfig(
|
| 42 |
+
... hidden_size=768,
|
| 43 |
+
... num_attention_heads=12,
|
| 44 |
+
... intermediate_size=3072,
|
| 45 |
+
... )
|
| 46 |
+
|
| 47 |
+
>>> # Initializing a model (with random weights) from the ALBERT-base style configuration
|
| 48 |
+
>>> model = AlbertModel(albert_xxlarge_configuration)
|
| 49 |
+
|
| 50 |
+
>>> # Accessing the model configuration
|
| 51 |
+
>>> configuration = model.config
|
| 52 |
+
```"""
|
| 53 |
+
|
| 54 |
+
model_type = "albert"
|
| 55 |
+
|
| 56 |
+
vocab_size: int = 30000
|
| 57 |
+
embedding_size: int = 128
|
| 58 |
+
hidden_size: int = 4096
|
| 59 |
+
num_hidden_layers: int = 12
|
| 60 |
+
num_hidden_groups: int = 1
|
| 61 |
+
num_attention_heads: int = 64
|
| 62 |
+
intermediate_size: int = 16384
|
| 63 |
+
inner_group_num: int = 1
|
| 64 |
+
hidden_act: str = "gelu_new"
|
| 65 |
+
hidden_dropout_prob: int | float = 0.0
|
| 66 |
+
attention_probs_dropout_prob: int | float = 0.0
|
| 67 |
+
max_position_embeddings: int = 512
|
| 68 |
+
type_vocab_size: int = 2
|
| 69 |
+
initializer_range: float = 0.02
|
| 70 |
+
layer_norm_eps: float = 1e-12
|
| 71 |
+
classifier_dropout_prob: int | float = 0.1
|
| 72 |
+
pad_token_id: int | None = 0
|
| 73 |
+
bos_token_id: int | None = 2
|
| 74 |
+
eos_token_id: int | list[int] | None = 3
|
| 75 |
+
tie_word_embeddings: bool = True
|
| 76 |
+
|
| 77 |
+
|
| 78 |
+
__all__ = ["AlbertConfig"]
|
third_party/transformers/src/transformers/models/albert/convert_albert_original_tf_checkpoint_to_pytorch.py
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright 2018 The HuggingFace Inc. team.
|
| 2 |
+
#
|
| 3 |
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
| 4 |
+
# you may not use this file except in compliance with the License.
|
| 5 |
+
# You may obtain a copy of the License at
|
| 6 |
+
#
|
| 7 |
+
# http://www.apache.org/licenses/LICENSE-2.0
|
| 8 |
+
#
|
| 9 |
+
# Unless required by applicable law or agreed to in writing, software
|
| 10 |
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
| 11 |
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 12 |
+
# See the License for the specific language governing permissions and
|
| 13 |
+
# limitations under the License.
|
| 14 |
+
"""Convert ALBERT checkpoint."""
|
| 15 |
+
|
| 16 |
+
import argparse
|
| 17 |
+
|
| 18 |
+
import torch
|
| 19 |
+
|
| 20 |
+
from ...utils import logging
|
| 21 |
+
from . import AlbertConfig, AlbertForPreTraining, load_tf_weights_in_albert
|
| 22 |
+
|
| 23 |
+
|
| 24 |
+
logging.set_verbosity_info()
|
| 25 |
+
|
| 26 |
+
|
| 27 |
+
def convert_tf_checkpoint_to_pytorch(tf_checkpoint_path, albert_config_file, pytorch_dump_path):
|
| 28 |
+
# Initialise PyTorch model
|
| 29 |
+
config = AlbertConfig.from_json_file(albert_config_file)
|
| 30 |
+
print(f"Building PyTorch model from configuration: {config}")
|
| 31 |
+
model = AlbertForPreTraining(config)
|
| 32 |
+
|
| 33 |
+
# Load weights from tf checkpoint
|
| 34 |
+
load_tf_weights_in_albert(model, config, tf_checkpoint_path)
|
| 35 |
+
|
| 36 |
+
# Save pytorch-model
|
| 37 |
+
print(f"Save PyTorch model to {pytorch_dump_path}")
|
| 38 |
+
torch.save(model.state_dict(), pytorch_dump_path)
|
| 39 |
+
|
| 40 |
+
|
| 41 |
+
if __name__ == "__main__":
|
| 42 |
+
parser = argparse.ArgumentParser()
|
| 43 |
+
# Required parameters
|
| 44 |
+
parser.add_argument(
|
| 45 |
+
"--tf_checkpoint_path", default=None, type=str, required=True, help="Path to the TensorFlow checkpoint path."
|
| 46 |
+
)
|
| 47 |
+
parser.add_argument(
|
| 48 |
+
"--albert_config_file",
|
| 49 |
+
default=None,
|
| 50 |
+
type=str,
|
| 51 |
+
required=True,
|
| 52 |
+
help=(
|
| 53 |
+
"The config json file corresponding to the pre-trained ALBERT model. \n"
|
| 54 |
+
"This specifies the model architecture."
|
| 55 |
+
),
|
| 56 |
+
)
|
| 57 |
+
parser.add_argument(
|
| 58 |
+
"--pytorch_dump_path", default=None, type=str, required=True, help="Path to the output PyTorch model."
|
| 59 |
+
)
|
| 60 |
+
args = parser.parse_args()
|
| 61 |
+
convert_tf_checkpoint_to_pytorch(args.tf_checkpoint_path, args.albert_config_file, args.pytorch_dump_path)
|
third_party/transformers/src/transformers/models/albert/modeling_albert.py
ADDED
|
@@ -0,0 +1,976 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright 2018 Google AI, Google Brain and the HuggingFace Inc. team.
|
| 2 |
+
#
|
| 3 |
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
| 4 |
+
# you may not use this file except in compliance with the License.
|
| 5 |
+
# You may obtain a copy of the License at
|
| 6 |
+
#
|
| 7 |
+
# http://www.apache.org/licenses/LICENSE-2.0
|
| 8 |
+
#
|
| 9 |
+
# Unless required by applicable law or agreed to in writing, software
|
| 10 |
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
| 11 |
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 12 |
+
# See the License for the specific language governing permissions and
|
| 13 |
+
# limitations under the License.
|
| 14 |
+
"""PyTorch ALBERT model."""
|
| 15 |
+
|
| 16 |
+
from collections.abc import Callable
|
| 17 |
+
from dataclasses import dataclass
|
| 18 |
+
|
| 19 |
+
import torch
|
| 20 |
+
from torch import nn
|
| 21 |
+
from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss
|
| 22 |
+
|
| 23 |
+
from ... import initialization as init
|
| 24 |
+
from ...activations import ACT2FN
|
| 25 |
+
from ...masking_utils import create_bidirectional_mask
|
| 26 |
+
from ...modeling_outputs import (
|
| 27 |
+
BaseModelOutput,
|
| 28 |
+
BaseModelOutputWithPooling,
|
| 29 |
+
MaskedLMOutput,
|
| 30 |
+
MultipleChoiceModelOutput,
|
| 31 |
+
QuestionAnsweringModelOutput,
|
| 32 |
+
SequenceClassifierOutput,
|
| 33 |
+
TokenClassifierOutput,
|
| 34 |
+
)
|
| 35 |
+
from ...modeling_utils import ALL_ATTENTION_FUNCTIONS, PreTrainedModel
|
| 36 |
+
from ...processing_utils import Unpack
|
| 37 |
+
from ...pytorch_utils import (
|
| 38 |
+
apply_chunking_to_forward,
|
| 39 |
+
)
|
| 40 |
+
from ...utils import ModelOutput, TransformersKwargs, auto_docstring, logging
|
| 41 |
+
from ...utils.generic import can_return_tuple, merge_with_config_defaults
|
| 42 |
+
from ...utils.output_capturing import capture_outputs
|
| 43 |
+
from .configuration_albert import AlbertConfig
|
| 44 |
+
|
| 45 |
+
|
| 46 |
+
logger = logging.get_logger(__name__)
|
| 47 |
+
|
| 48 |
+
|
| 49 |
+
class AlbertEmbeddings(nn.Module):
|
| 50 |
+
"""
|
| 51 |
+
Construct the embeddings from word, position and token_type embeddings.
|
| 52 |
+
"""
|
| 53 |
+
|
| 54 |
+
def __init__(self, config: AlbertConfig):
|
| 55 |
+
super().__init__()
|
| 56 |
+
self.word_embeddings = nn.Embedding(config.vocab_size, config.embedding_size, padding_idx=config.pad_token_id)
|
| 57 |
+
self.position_embeddings = nn.Embedding(config.max_position_embeddings, config.embedding_size)
|
| 58 |
+
self.token_type_embeddings = nn.Embedding(config.type_vocab_size, config.embedding_size)
|
| 59 |
+
|
| 60 |
+
self.LayerNorm = nn.LayerNorm(config.embedding_size, eps=config.layer_norm_eps)
|
| 61 |
+
self.dropout = nn.Dropout(config.hidden_dropout_prob)
|
| 62 |
+
|
| 63 |
+
# position_ids (1, len position emb) is contiguous in memory and exported when serialized
|
| 64 |
+
self.register_buffer(
|
| 65 |
+
"position_ids", torch.arange(config.max_position_embeddings).expand((1, -1)), persistent=False
|
| 66 |
+
)
|
| 67 |
+
self.register_buffer(
|
| 68 |
+
"token_type_ids", torch.zeros(self.position_ids.size(), dtype=torch.long), persistent=False
|
| 69 |
+
)
|
| 70 |
+
|
| 71 |
+
def forward(
|
| 72 |
+
self,
|
| 73 |
+
input_ids: torch.LongTensor | None = None,
|
| 74 |
+
token_type_ids: torch.LongTensor | None = None,
|
| 75 |
+
position_ids: torch.LongTensor | None = None,
|
| 76 |
+
inputs_embeds: torch.FloatTensor | None = None,
|
| 77 |
+
) -> torch.Tensor:
|
| 78 |
+
if input_ids is not None:
|
| 79 |
+
input_shape = input_ids.size()
|
| 80 |
+
else:
|
| 81 |
+
input_shape = inputs_embeds.size()[:-1]
|
| 82 |
+
|
| 83 |
+
batch_size, seq_length = input_shape
|
| 84 |
+
|
| 85 |
+
if position_ids is None:
|
| 86 |
+
position_ids = self.position_ids[:, :seq_length]
|
| 87 |
+
|
| 88 |
+
# Setting the token_type_ids to the registered buffer in constructor where it is all zeros, which usually occurs
|
| 89 |
+
# when its auto-generated, registered buffer helps users when tracing the model without passing token_type_ids, solves
|
| 90 |
+
# issue #5664
|
| 91 |
+
if token_type_ids is None:
|
| 92 |
+
if hasattr(self, "token_type_ids"):
|
| 93 |
+
# NOTE: We assume either pos ids to have bsz == 1 (broadcastable) or bsz == effective bsz (input_shape[0])
|
| 94 |
+
buffered_token_type_ids = self.token_type_ids.expand(position_ids.shape[0], -1)
|
| 95 |
+
buffered_token_type_ids = torch.gather(buffered_token_type_ids, dim=1, index=position_ids)
|
| 96 |
+
token_type_ids = buffered_token_type_ids.expand(batch_size, seq_length)
|
| 97 |
+
else:
|
| 98 |
+
token_type_ids = torch.zeros(input_shape, dtype=torch.long, device=self.position_ids.device)
|
| 99 |
+
|
| 100 |
+
if inputs_embeds is None:
|
| 101 |
+
inputs_embeds = self.word_embeddings(input_ids)
|
| 102 |
+
token_type_embeddings = self.token_type_embeddings(token_type_ids)
|
| 103 |
+
embeddings = inputs_embeds + token_type_embeddings
|
| 104 |
+
|
| 105 |
+
position_embeddings = self.position_embeddings(position_ids)
|
| 106 |
+
embeddings = embeddings + position_embeddings
|
| 107 |
+
|
| 108 |
+
embeddings = self.LayerNorm(embeddings)
|
| 109 |
+
embeddings = self.dropout(embeddings)
|
| 110 |
+
return embeddings
|
| 111 |
+
|
| 112 |
+
|
| 113 |
+
# Copied from transformers.models.bert.modeling_bert.eager_attention_forward
|
| 114 |
+
def eager_attention_forward(
|
| 115 |
+
module: nn.Module,
|
| 116 |
+
query: torch.Tensor,
|
| 117 |
+
key: torch.Tensor,
|
| 118 |
+
value: torch.Tensor,
|
| 119 |
+
attention_mask: torch.Tensor | None,
|
| 120 |
+
scaling: float | None = None,
|
| 121 |
+
dropout: float = 0.0,
|
| 122 |
+
**kwargs: Unpack[TransformersKwargs],
|
| 123 |
+
):
|
| 124 |
+
if scaling is None:
|
| 125 |
+
scaling = query.size(-1) ** -0.5
|
| 126 |
+
|
| 127 |
+
# Take the dot product between "query" and "key" to get the raw attention scores.
|
| 128 |
+
attn_weights = torch.matmul(query, key.transpose(2, 3)) * scaling
|
| 129 |
+
|
| 130 |
+
if attention_mask is not None:
|
| 131 |
+
attn_weights = attn_weights + attention_mask
|
| 132 |
+
|
| 133 |
+
attn_weights = nn.functional.softmax(attn_weights, dim=-1)
|
| 134 |
+
attn_weights = nn.functional.dropout(attn_weights, p=dropout, training=module.training)
|
| 135 |
+
|
| 136 |
+
attn_output = torch.matmul(attn_weights, value)
|
| 137 |
+
attn_output = attn_output.transpose(1, 2).contiguous()
|
| 138 |
+
|
| 139 |
+
return attn_output, attn_weights
|
| 140 |
+
|
| 141 |
+
|
| 142 |
+
class AlbertAttention(nn.Module):
|
| 143 |
+
def __init__(self, config: AlbertConfig):
|
| 144 |
+
super().__init__()
|
| 145 |
+
if config.hidden_size % config.num_attention_heads != 0 and not hasattr(config, "embedding_size"):
|
| 146 |
+
raise ValueError(
|
| 147 |
+
f"The hidden size ({config.hidden_size}) is not a multiple of the number of attention "
|
| 148 |
+
f"heads ({config.num_attention_heads}"
|
| 149 |
+
)
|
| 150 |
+
self.config = config
|
| 151 |
+
|
| 152 |
+
self.num_attention_heads = config.num_attention_heads
|
| 153 |
+
self.hidden_size = config.hidden_size
|
| 154 |
+
self.attention_head_size = config.hidden_size // config.num_attention_heads
|
| 155 |
+
self.all_head_size = self.num_attention_heads * self.attention_head_size
|
| 156 |
+
self.scaling = self.attention_head_size**-0.5
|
| 157 |
+
|
| 158 |
+
self.attention_dropout = nn.Dropout(config.attention_probs_dropout_prob)
|
| 159 |
+
self.output_dropout = nn.Dropout(config.hidden_dropout_prob)
|
| 160 |
+
|
| 161 |
+
self.query = nn.Linear(config.hidden_size, self.all_head_size)
|
| 162 |
+
self.key = nn.Linear(config.hidden_size, self.all_head_size)
|
| 163 |
+
self.value = nn.Linear(config.hidden_size, self.all_head_size)
|
| 164 |
+
self.dense = nn.Linear(config.hidden_size, config.hidden_size)
|
| 165 |
+
|
| 166 |
+
self.LayerNorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps)
|
| 167 |
+
|
| 168 |
+
self.is_causal = False
|
| 169 |
+
|
| 170 |
+
def forward(
|
| 171 |
+
self,
|
| 172 |
+
hidden_states: torch.Tensor,
|
| 173 |
+
attention_mask: torch.FloatTensor | None = None,
|
| 174 |
+
**kwargs: Unpack[TransformersKwargs],
|
| 175 |
+
) -> tuple[torch.Tensor, torch.Tensor]:
|
| 176 |
+
input_shape = hidden_states.shape[:-1]
|
| 177 |
+
hidden_shape = (*input_shape, -1, self.attention_head_size)
|
| 178 |
+
|
| 179 |
+
# get all proj
|
| 180 |
+
query_layer = self.query(hidden_states).view(*hidden_shape).transpose(1, 2)
|
| 181 |
+
key_layer = self.key(hidden_states).view(*hidden_shape).transpose(1, 2)
|
| 182 |
+
value_layer = self.value(hidden_states).view(*hidden_shape).transpose(1, 2)
|
| 183 |
+
|
| 184 |
+
attention_interface: Callable = ALL_ATTENTION_FUNCTIONS.get_interface(
|
| 185 |
+
self.config._attn_implementation, eager_attention_forward
|
| 186 |
+
)
|
| 187 |
+
|
| 188 |
+
attn_output, attn_weights = attention_interface(
|
| 189 |
+
self,
|
| 190 |
+
query_layer,
|
| 191 |
+
key_layer,
|
| 192 |
+
value_layer,
|
| 193 |
+
attention_mask,
|
| 194 |
+
dropout=0.0 if not self.training else self.attention_dropout.p,
|
| 195 |
+
scaling=self.scaling,
|
| 196 |
+
**kwargs,
|
| 197 |
+
)
|
| 198 |
+
attn_output = attn_output.reshape(*input_shape, -1).contiguous()
|
| 199 |
+
|
| 200 |
+
attn_output = self.dense(attn_output)
|
| 201 |
+
attn_output = self.output_dropout(attn_output)
|
| 202 |
+
attn_output = self.LayerNorm(hidden_states + attn_output)
|
| 203 |
+
|
| 204 |
+
return attn_output, attn_weights
|
| 205 |
+
|
| 206 |
+
|
| 207 |
+
class AlbertLayer(nn.Module):
|
| 208 |
+
def __init__(self, config: AlbertConfig):
|
| 209 |
+
super().__init__()
|
| 210 |
+
|
| 211 |
+
self.config = config
|
| 212 |
+
self.chunk_size_feed_forward = config.chunk_size_feed_forward
|
| 213 |
+
self.seq_len_dim = 1
|
| 214 |
+
self.full_layer_layer_norm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps)
|
| 215 |
+
self.attention = AlbertAttention(config)
|
| 216 |
+
self.ffn = nn.Linear(config.hidden_size, config.intermediate_size)
|
| 217 |
+
self.ffn_output = nn.Linear(config.intermediate_size, config.hidden_size)
|
| 218 |
+
self.activation = ACT2FN[config.hidden_act]
|
| 219 |
+
self.dropout = nn.Dropout(config.hidden_dropout_prob)
|
| 220 |
+
|
| 221 |
+
def forward(
|
| 222 |
+
self,
|
| 223 |
+
hidden_states: torch.Tensor,
|
| 224 |
+
attention_mask: torch.FloatTensor | None = None,
|
| 225 |
+
**kwargs: Unpack[TransformersKwargs],
|
| 226 |
+
) -> tuple[torch.Tensor, torch.Tensor]:
|
| 227 |
+
attention_output, _ = self.attention(hidden_states, attention_mask, **kwargs)
|
| 228 |
+
|
| 229 |
+
ffn_output = apply_chunking_to_forward(
|
| 230 |
+
self.ff_chunk,
|
| 231 |
+
self.chunk_size_feed_forward,
|
| 232 |
+
self.seq_len_dim,
|
| 233 |
+
attention_output,
|
| 234 |
+
)
|
| 235 |
+
hidden_states = self.full_layer_layer_norm(ffn_output + attention_output)
|
| 236 |
+
return hidden_states
|
| 237 |
+
|
| 238 |
+
def ff_chunk(self, attention_output: torch.Tensor) -> torch.Tensor:
|
| 239 |
+
ffn_output = self.ffn(attention_output)
|
| 240 |
+
ffn_output = self.activation(ffn_output)
|
| 241 |
+
ffn_output = self.ffn_output(ffn_output)
|
| 242 |
+
return ffn_output
|
| 243 |
+
|
| 244 |
+
|
| 245 |
+
class AlbertLayerGroup(nn.Module):
|
| 246 |
+
def __init__(self, config: AlbertConfig):
|
| 247 |
+
super().__init__()
|
| 248 |
+
|
| 249 |
+
self.albert_layers = nn.ModuleList([AlbertLayer(config) for _ in range(config.inner_group_num)])
|
| 250 |
+
|
| 251 |
+
def forward(
|
| 252 |
+
self,
|
| 253 |
+
hidden_states: torch.Tensor,
|
| 254 |
+
attention_mask: torch.FloatTensor | None = None,
|
| 255 |
+
**kwargs: Unpack[TransformersKwargs],
|
| 256 |
+
) -> tuple[torch.Tensor | tuple[torch.Tensor], ...]:
|
| 257 |
+
for layer_index, albert_layer in enumerate(self.albert_layers):
|
| 258 |
+
hidden_states = albert_layer(hidden_states, attention_mask, **kwargs)
|
| 259 |
+
return hidden_states
|
| 260 |
+
|
| 261 |
+
|
| 262 |
+
class AlbertTransformer(nn.Module):
|
| 263 |
+
def __init__(self, config: AlbertConfig):
|
| 264 |
+
super().__init__()
|
| 265 |
+
|
| 266 |
+
self.config = config
|
| 267 |
+
self.embedding_hidden_mapping_in = nn.Linear(config.embedding_size, config.hidden_size)
|
| 268 |
+
self.albert_layer_groups = nn.ModuleList([AlbertLayerGroup(config) for _ in range(config.num_hidden_groups)])
|
| 269 |
+
|
| 270 |
+
def forward(
|
| 271 |
+
self,
|
| 272 |
+
hidden_states: torch.Tensor,
|
| 273 |
+
attention_mask: torch.FloatTensor | None = None,
|
| 274 |
+
**kwargs: Unpack[TransformersKwargs],
|
| 275 |
+
) -> BaseModelOutput | tuple:
|
| 276 |
+
hidden_states = self.embedding_hidden_mapping_in(hidden_states)
|
| 277 |
+
|
| 278 |
+
for i in range(self.config.num_hidden_layers):
|
| 279 |
+
# Index of the hidden group
|
| 280 |
+
group_idx = int(i / (self.config.num_hidden_layers / self.config.num_hidden_groups))
|
| 281 |
+
|
| 282 |
+
hidden_states = self.albert_layer_groups[group_idx](
|
| 283 |
+
hidden_states,
|
| 284 |
+
attention_mask,
|
| 285 |
+
**kwargs,
|
| 286 |
+
)
|
| 287 |
+
|
| 288 |
+
return BaseModelOutput(last_hidden_state=hidden_states)
|
| 289 |
+
|
| 290 |
+
|
| 291 |
+
@auto_docstring
|
| 292 |
+
class AlbertPreTrainedModel(PreTrainedModel):
|
| 293 |
+
config_class = AlbertConfig
|
| 294 |
+
base_model_prefix = "albert"
|
| 295 |
+
_supports_flash_attn = True
|
| 296 |
+
_supports_sdpa = True
|
| 297 |
+
_supports_flex_attn = True
|
| 298 |
+
_supports_attention_backend = True
|
| 299 |
+
_can_record_outputs = {
|
| 300 |
+
"hidden_states": AlbertLayer,
|
| 301 |
+
"attentions": AlbertAttention,
|
| 302 |
+
}
|
| 303 |
+
|
| 304 |
+
@torch.no_grad()
|
| 305 |
+
def _init_weights(self, module):
|
| 306 |
+
"""Initialize the weights."""
|
| 307 |
+
if isinstance(module, nn.Linear):
|
| 308 |
+
init.normal_(module.weight, mean=0.0, std=self.config.initializer_range)
|
| 309 |
+
if module.bias is not None:
|
| 310 |
+
init.zeros_(module.bias)
|
| 311 |
+
elif isinstance(module, nn.Embedding):
|
| 312 |
+
init.normal_(module.weight, mean=0.0, std=self.config.initializer_range)
|
| 313 |
+
# Here we need the check explicitly, as we slice the weight in the `zeros_` call, so it looses the flag
|
| 314 |
+
if module.padding_idx is not None and not getattr(module.weight, "_is_hf_initialized", False):
|
| 315 |
+
init.zeros_(module.weight[module.padding_idx])
|
| 316 |
+
elif isinstance(module, nn.LayerNorm):
|
| 317 |
+
init.zeros_(module.bias)
|
| 318 |
+
init.ones_(module.weight)
|
| 319 |
+
elif isinstance(module, AlbertMLMHead):
|
| 320 |
+
init.zeros_(module.bias)
|
| 321 |
+
elif isinstance(module, AlbertEmbeddings):
|
| 322 |
+
init.copy_(module.position_ids, torch.arange(module.position_ids.shape[-1]).expand((1, -1)))
|
| 323 |
+
init.zeros_(module.token_type_ids)
|
| 324 |
+
|
| 325 |
+
|
| 326 |
+
@dataclass
|
| 327 |
+
@auto_docstring(
|
| 328 |
+
custom_intro="""
|
| 329 |
+
Output type of [`AlbertForPreTraining`].
|
| 330 |
+
"""
|
| 331 |
+
)
|
| 332 |
+
class AlbertForPreTrainingOutput(ModelOutput):
|
| 333 |
+
r"""
|
| 334 |
+
loss (*optional*, returned when `labels` is provided, `torch.FloatTensor` of shape `(1,)`):
|
| 335 |
+
Total loss as the sum of the masked language modeling loss and the next sequence prediction
|
| 336 |
+
(classification) loss.
|
| 337 |
+
prediction_logits (`torch.FloatTensor` of shape `(batch_size, sequence_length, config.vocab_size)`):
|
| 338 |
+
Prediction scores of the language modeling head (scores for each vocabulary token before SoftMax).
|
| 339 |
+
sop_logits (`torch.FloatTensor` of shape `(batch_size, 2)`):
|
| 340 |
+
Prediction scores of the next sequence prediction (classification) head (scores of True/False continuation
|
| 341 |
+
before SoftMax).
|
| 342 |
+
"""
|
| 343 |
+
|
| 344 |
+
loss: torch.FloatTensor | None = None
|
| 345 |
+
prediction_logits: torch.FloatTensor | None = None
|
| 346 |
+
sop_logits: torch.FloatTensor | None = None
|
| 347 |
+
hidden_states: tuple[torch.FloatTensor] | None = None
|
| 348 |
+
attentions: tuple[torch.FloatTensor] | None = None
|
| 349 |
+
|
| 350 |
+
|
| 351 |
+
@auto_docstring
|
| 352 |
+
class AlbertModel(AlbertPreTrainedModel):
|
| 353 |
+
config_class = AlbertConfig
|
| 354 |
+
base_model_prefix = "albert"
|
| 355 |
+
|
| 356 |
+
def __init__(self, config: AlbertConfig, add_pooling_layer: bool = True):
|
| 357 |
+
r"""
|
| 358 |
+
add_pooling_layer (bool, *optional*, defaults to `True`):
|
| 359 |
+
Whether to add a pooling layer
|
| 360 |
+
"""
|
| 361 |
+
super().__init__(config)
|
| 362 |
+
|
| 363 |
+
self.config = config
|
| 364 |
+
self.embeddings = AlbertEmbeddings(config)
|
| 365 |
+
self.encoder = AlbertTransformer(config)
|
| 366 |
+
if add_pooling_layer:
|
| 367 |
+
self.pooler = nn.Linear(config.hidden_size, config.hidden_size)
|
| 368 |
+
self.pooler_activation = nn.Tanh()
|
| 369 |
+
else:
|
| 370 |
+
self.pooler = None
|
| 371 |
+
self.pooler_activation = None
|
| 372 |
+
|
| 373 |
+
self.attn_implementation = config._attn_implementation
|
| 374 |
+
|
| 375 |
+
# Initialize weights and apply final processing
|
| 376 |
+
self.post_init()
|
| 377 |
+
|
| 378 |
+
def get_input_embeddings(self) -> nn.Embedding:
|
| 379 |
+
return self.embeddings.word_embeddings
|
| 380 |
+
|
| 381 |
+
def set_input_embeddings(self, value: nn.Embedding) -> None:
|
| 382 |
+
self.embeddings.word_embeddings = value
|
| 383 |
+
|
| 384 |
+
@merge_with_config_defaults
|
| 385 |
+
@capture_outputs
|
| 386 |
+
@auto_docstring
|
| 387 |
+
def forward(
|
| 388 |
+
self,
|
| 389 |
+
input_ids: torch.LongTensor | None = None,
|
| 390 |
+
attention_mask: torch.FloatTensor | None = None,
|
| 391 |
+
token_type_ids: torch.LongTensor | None = None,
|
| 392 |
+
position_ids: torch.LongTensor | None = None,
|
| 393 |
+
inputs_embeds: torch.FloatTensor | None = None,
|
| 394 |
+
**kwargs: Unpack[TransformersKwargs],
|
| 395 |
+
) -> BaseModelOutputWithPooling | tuple:
|
| 396 |
+
if (input_ids is None) ^ (inputs_embeds is not None):
|
| 397 |
+
raise ValueError("You must specify exactly one of input_ids or inputs_embeds")
|
| 398 |
+
|
| 399 |
+
embedding_output = self.embeddings(
|
| 400 |
+
input_ids, position_ids=position_ids, token_type_ids=token_type_ids, inputs_embeds=inputs_embeds
|
| 401 |
+
)
|
| 402 |
+
|
| 403 |
+
attention_mask = create_bidirectional_mask(
|
| 404 |
+
config=self.config,
|
| 405 |
+
inputs_embeds=embedding_output,
|
| 406 |
+
attention_mask=attention_mask,
|
| 407 |
+
)
|
| 408 |
+
|
| 409 |
+
encoder_outputs = self.encoder(
|
| 410 |
+
embedding_output,
|
| 411 |
+
attention_mask,
|
| 412 |
+
position_ids=position_ids,
|
| 413 |
+
**kwargs,
|
| 414 |
+
)
|
| 415 |
+
|
| 416 |
+
sequence_output = encoder_outputs[0]
|
| 417 |
+
|
| 418 |
+
pooled_output = self.pooler_activation(self.pooler(sequence_output[:, 0])) if self.pooler is not None else None
|
| 419 |
+
|
| 420 |
+
return BaseModelOutputWithPooling(
|
| 421 |
+
last_hidden_state=sequence_output,
|
| 422 |
+
pooler_output=pooled_output,
|
| 423 |
+
)
|
| 424 |
+
|
| 425 |
+
|
| 426 |
+
@auto_docstring(
|
| 427 |
+
custom_intro="""
|
| 428 |
+
Albert Model with two heads on top as done during the pretraining: a `masked language modeling` head and a
|
| 429 |
+
`sentence order prediction (classification)` head.
|
| 430 |
+
"""
|
| 431 |
+
)
|
| 432 |
+
class AlbertForPreTraining(AlbertPreTrainedModel):
|
| 433 |
+
_tied_weights_keys = {
|
| 434 |
+
"predictions.decoder.weight": "albert.embeddings.word_embeddings.weight",
|
| 435 |
+
"predictions.decoder.bias": "predictions.bias",
|
| 436 |
+
}
|
| 437 |
+
|
| 438 |
+
def __init__(self, config: AlbertConfig):
|
| 439 |
+
super().__init__(config)
|
| 440 |
+
|
| 441 |
+
self.albert = AlbertModel(config)
|
| 442 |
+
self.predictions = AlbertMLMHead(config)
|
| 443 |
+
self.sop_classifier = AlbertSOPHead(config)
|
| 444 |
+
|
| 445 |
+
# Initialize weights and apply final processing
|
| 446 |
+
self.post_init()
|
| 447 |
+
|
| 448 |
+
def get_output_embeddings(self) -> nn.Linear:
|
| 449 |
+
return self.predictions.decoder
|
| 450 |
+
|
| 451 |
+
def set_output_embeddings(self, new_embeddings: nn.Linear) -> None:
|
| 452 |
+
self.predictions.decoder = new_embeddings
|
| 453 |
+
|
| 454 |
+
def get_input_embeddings(self) -> nn.Embedding:
|
| 455 |
+
return self.albert.embeddings.word_embeddings
|
| 456 |
+
|
| 457 |
+
@can_return_tuple
|
| 458 |
+
@auto_docstring
|
| 459 |
+
def forward(
|
| 460 |
+
self,
|
| 461 |
+
input_ids: torch.LongTensor | None = None,
|
| 462 |
+
attention_mask: torch.FloatTensor | None = None,
|
| 463 |
+
token_type_ids: torch.LongTensor | None = None,
|
| 464 |
+
position_ids: torch.LongTensor | None = None,
|
| 465 |
+
inputs_embeds: torch.FloatTensor | None = None,
|
| 466 |
+
labels: torch.LongTensor | None = None,
|
| 467 |
+
sentence_order_label: torch.LongTensor | None = None,
|
| 468 |
+
**kwargs: Unpack[TransformersKwargs],
|
| 469 |
+
) -> AlbertForPreTrainingOutput | tuple:
|
| 470 |
+
r"""
|
| 471 |
+
labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*):
|
| 472 |
+
Labels for computing the masked language modeling loss. Indices should be in `[-100, 0, ...,
|
| 473 |
+
config.vocab_size]` (see `input_ids` docstring) Tokens with indices set to `-100` are ignored (masked), the
|
| 474 |
+
loss is only computed for the tokens with labels in `[0, ..., config.vocab_size]`
|
| 475 |
+
sentence_order_label (`torch.LongTensor` of shape `(batch_size,)`, *optional*):
|
| 476 |
+
Labels for computing the next sequence prediction (classification) loss. Input should be a sequence pair
|
| 477 |
+
(see `input_ids` docstring) Indices should be in `[0, 1]`. `0` indicates original order (sequence A, then
|
| 478 |
+
sequence B), `1` indicates switched order (sequence B, then sequence A).
|
| 479 |
+
|
| 480 |
+
Example:
|
| 481 |
+
|
| 482 |
+
```python
|
| 483 |
+
>>> from transformers import AutoTokenizer, AlbertForPreTraining
|
| 484 |
+
>>> import torch
|
| 485 |
+
|
| 486 |
+
>>> tokenizer = AutoTokenizer.from_pretrained("albert/albert-base-v2")
|
| 487 |
+
>>> model = AlbertForPreTraining.from_pretrained("albert/albert-base-v2")
|
| 488 |
+
|
| 489 |
+
>>> input_ids = torch.tensor(tokenizer.encode("Hello, my dog is cute", add_special_tokens=True)).unsqueeze(0)
|
| 490 |
+
>>> # Batch size 1
|
| 491 |
+
>>> outputs = model(input_ids)
|
| 492 |
+
|
| 493 |
+
>>> prediction_logits = outputs.prediction_logits
|
| 494 |
+
>>> sop_logits = outputs.sop_logits
|
| 495 |
+
```"""
|
| 496 |
+
outputs = self.albert(
|
| 497 |
+
input_ids,
|
| 498 |
+
attention_mask=attention_mask,
|
| 499 |
+
token_type_ids=token_type_ids,
|
| 500 |
+
position_ids=position_ids,
|
| 501 |
+
inputs_embeds=inputs_embeds,
|
| 502 |
+
return_dict=True,
|
| 503 |
+
**kwargs,
|
| 504 |
+
)
|
| 505 |
+
|
| 506 |
+
sequence_output, pooled_output = outputs[:2]
|
| 507 |
+
|
| 508 |
+
prediction_scores = self.predictions(sequence_output)
|
| 509 |
+
sop_scores = self.sop_classifier(pooled_output)
|
| 510 |
+
|
| 511 |
+
total_loss = None
|
| 512 |
+
if labels is not None and sentence_order_label is not None:
|
| 513 |
+
loss_fct = CrossEntropyLoss()
|
| 514 |
+
masked_lm_loss = loss_fct(prediction_scores.view(-1, self.config.vocab_size), labels.view(-1))
|
| 515 |
+
sentence_order_loss = loss_fct(sop_scores.view(-1, 2), sentence_order_label.view(-1))
|
| 516 |
+
total_loss = masked_lm_loss + sentence_order_loss
|
| 517 |
+
|
| 518 |
+
return AlbertForPreTrainingOutput(
|
| 519 |
+
loss=total_loss,
|
| 520 |
+
prediction_logits=prediction_scores,
|
| 521 |
+
sop_logits=sop_scores,
|
| 522 |
+
hidden_states=outputs.hidden_states,
|
| 523 |
+
attentions=outputs.attentions,
|
| 524 |
+
)
|
| 525 |
+
|
| 526 |
+
|
| 527 |
+
class AlbertMLMHead(nn.Module):
|
| 528 |
+
def __init__(self, config: AlbertConfig):
|
| 529 |
+
super().__init__()
|
| 530 |
+
|
| 531 |
+
self.LayerNorm = nn.LayerNorm(config.embedding_size, eps=config.layer_norm_eps)
|
| 532 |
+
self.bias = nn.Parameter(torch.zeros(config.vocab_size))
|
| 533 |
+
self.dense = nn.Linear(config.hidden_size, config.embedding_size)
|
| 534 |
+
self.decoder = nn.Linear(config.embedding_size, config.vocab_size)
|
| 535 |
+
self.activation = ACT2FN[config.hidden_act]
|
| 536 |
+
|
| 537 |
+
def forward(self, hidden_states: torch.Tensor) -> torch.Tensor:
|
| 538 |
+
hidden_states = self.dense(hidden_states)
|
| 539 |
+
hidden_states = self.activation(hidden_states)
|
| 540 |
+
hidden_states = self.LayerNorm(hidden_states)
|
| 541 |
+
hidden_states = self.decoder(hidden_states)
|
| 542 |
+
|
| 543 |
+
prediction_scores = hidden_states
|
| 544 |
+
|
| 545 |
+
return prediction_scores
|
| 546 |
+
|
| 547 |
+
|
| 548 |
+
class AlbertSOPHead(nn.Module):
|
| 549 |
+
def __init__(self, config: AlbertConfig):
|
| 550 |
+
super().__init__()
|
| 551 |
+
|
| 552 |
+
self.dropout = nn.Dropout(config.classifier_dropout_prob)
|
| 553 |
+
self.classifier = nn.Linear(config.hidden_size, config.num_labels)
|
| 554 |
+
|
| 555 |
+
def forward(self, pooled_output: torch.Tensor) -> torch.Tensor:
|
| 556 |
+
dropout_pooled_output = self.dropout(pooled_output)
|
| 557 |
+
logits = self.classifier(dropout_pooled_output)
|
| 558 |
+
return logits
|
| 559 |
+
|
| 560 |
+
|
| 561 |
+
@auto_docstring
|
| 562 |
+
class AlbertForMaskedLM(AlbertPreTrainedModel):
|
| 563 |
+
_tied_weights_keys = {
|
| 564 |
+
"predictions.decoder.weight": "albert.embeddings.word_embeddings.weight",
|
| 565 |
+
"predictions.decoder.bias": "predictions.bias",
|
| 566 |
+
}
|
| 567 |
+
|
| 568 |
+
def __init__(self, config):
|
| 569 |
+
super().__init__(config)
|
| 570 |
+
|
| 571 |
+
self.albert = AlbertModel(config, add_pooling_layer=False)
|
| 572 |
+
self.predictions = AlbertMLMHead(config)
|
| 573 |
+
|
| 574 |
+
# Initialize weights and apply final processing
|
| 575 |
+
self.post_init()
|
| 576 |
+
|
| 577 |
+
def get_output_embeddings(self) -> nn.Linear:
|
| 578 |
+
return self.predictions.decoder
|
| 579 |
+
|
| 580 |
+
def set_output_embeddings(self, new_embeddings: nn.Linear) -> None:
|
| 581 |
+
self.predictions.decoder = new_embeddings
|
| 582 |
+
self.predictions.bias = new_embeddings.bias
|
| 583 |
+
|
| 584 |
+
def get_input_embeddings(self) -> nn.Embedding:
|
| 585 |
+
return self.albert.embeddings.word_embeddings
|
| 586 |
+
|
| 587 |
+
@can_return_tuple
|
| 588 |
+
@auto_docstring
|
| 589 |
+
def forward(
|
| 590 |
+
self,
|
| 591 |
+
input_ids: torch.LongTensor | None = None,
|
| 592 |
+
attention_mask: torch.FloatTensor | None = None,
|
| 593 |
+
token_type_ids: torch.LongTensor | None = None,
|
| 594 |
+
position_ids: torch.LongTensor | None = None,
|
| 595 |
+
inputs_embeds: torch.FloatTensor | None = None,
|
| 596 |
+
labels: torch.LongTensor | None = None,
|
| 597 |
+
**kwargs: Unpack[TransformersKwargs],
|
| 598 |
+
) -> MaskedLMOutput | tuple:
|
| 599 |
+
r"""
|
| 600 |
+
labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*):
|
| 601 |
+
Labels for computing the masked language modeling loss. Indices should be in `[-100, 0, ...,
|
| 602 |
+
config.vocab_size]` (see `input_ids` docstring) Tokens with indices set to `-100` are ignored (masked), the
|
| 603 |
+
loss is only computed for the tokens with labels in `[0, ..., config.vocab_size]`
|
| 604 |
+
|
| 605 |
+
Example:
|
| 606 |
+
|
| 607 |
+
```python
|
| 608 |
+
>>> import torch
|
| 609 |
+
>>> from transformers import AutoTokenizer, AlbertForMaskedLM
|
| 610 |
+
|
| 611 |
+
>>> tokenizer = AutoTokenizer.from_pretrained("albert/albert-base-v2")
|
| 612 |
+
>>> model = AlbertForMaskedLM.from_pretrained("albert/albert-base-v2")
|
| 613 |
+
|
| 614 |
+
>>> # add mask_token
|
| 615 |
+
>>> inputs = tokenizer("The capital of [MASK] is Paris.", return_tensors="pt")
|
| 616 |
+
>>> with torch.no_grad():
|
| 617 |
+
... logits = model(**inputs).logits
|
| 618 |
+
|
| 619 |
+
>>> # retrieve index of [MASK]
|
| 620 |
+
>>> mask_token_index = (inputs.input_ids == tokenizer.mask_token_id)[0].nonzero(as_tuple=True)[0]
|
| 621 |
+
>>> predicted_token_id = logits[0, mask_token_index].argmax(axis=-1)
|
| 622 |
+
>>> tokenizer.decode(predicted_token_id)
|
| 623 |
+
'france'
|
| 624 |
+
```
|
| 625 |
+
|
| 626 |
+
```python
|
| 627 |
+
>>> labels = tokenizer("The capital of France is Paris.", return_tensors="pt")["input_ids"]
|
| 628 |
+
>>> labels = torch.where(inputs.input_ids == tokenizer.mask_token_id, labels, -100)
|
| 629 |
+
>>> outputs = model(**inputs, labels=labels)
|
| 630 |
+
>>> round(outputs.loss.item(), 2)
|
| 631 |
+
0.81
|
| 632 |
+
```
|
| 633 |
+
"""
|
| 634 |
+
outputs = self.albert(
|
| 635 |
+
input_ids=input_ids,
|
| 636 |
+
attention_mask=attention_mask,
|
| 637 |
+
token_type_ids=token_type_ids,
|
| 638 |
+
position_ids=position_ids,
|
| 639 |
+
inputs_embeds=inputs_embeds,
|
| 640 |
+
return_dict=True,
|
| 641 |
+
**kwargs,
|
| 642 |
+
)
|
| 643 |
+
sequence_outputs = outputs[0]
|
| 644 |
+
|
| 645 |
+
prediction_scores = self.predictions(sequence_outputs)
|
| 646 |
+
|
| 647 |
+
masked_lm_loss = None
|
| 648 |
+
if labels is not None:
|
| 649 |
+
loss_fct = CrossEntropyLoss()
|
| 650 |
+
masked_lm_loss = loss_fct(prediction_scores.view(-1, self.config.vocab_size), labels.view(-1))
|
| 651 |
+
|
| 652 |
+
return MaskedLMOutput(
|
| 653 |
+
loss=masked_lm_loss,
|
| 654 |
+
logits=prediction_scores,
|
| 655 |
+
hidden_states=outputs.hidden_states,
|
| 656 |
+
attentions=outputs.attentions,
|
| 657 |
+
)
|
| 658 |
+
|
| 659 |
+
|
| 660 |
+
@auto_docstring(
|
| 661 |
+
custom_intro="""
|
| 662 |
+
Albert Model transformer with a sequence classification/regression head on top (a linear layer on top of the pooled
|
| 663 |
+
output) e.g. for GLUE tasks.
|
| 664 |
+
"""
|
| 665 |
+
)
|
| 666 |
+
class AlbertForSequenceClassification(AlbertPreTrainedModel):
|
| 667 |
+
def __init__(self, config: AlbertConfig):
|
| 668 |
+
super().__init__(config)
|
| 669 |
+
self.num_labels = config.num_labels
|
| 670 |
+
self.config = config
|
| 671 |
+
|
| 672 |
+
self.albert = AlbertModel(config)
|
| 673 |
+
self.dropout = nn.Dropout(config.classifier_dropout_prob)
|
| 674 |
+
self.classifier = nn.Linear(config.hidden_size, self.config.num_labels)
|
| 675 |
+
|
| 676 |
+
# Initialize weights and apply final processing
|
| 677 |
+
self.post_init()
|
| 678 |
+
|
| 679 |
+
@can_return_tuple
|
| 680 |
+
@auto_docstring
|
| 681 |
+
def forward(
|
| 682 |
+
self,
|
| 683 |
+
input_ids: torch.LongTensor | None = None,
|
| 684 |
+
attention_mask: torch.FloatTensor | None = None,
|
| 685 |
+
token_type_ids: torch.LongTensor | None = None,
|
| 686 |
+
position_ids: torch.LongTensor | None = None,
|
| 687 |
+
inputs_embeds: torch.FloatTensor | None = None,
|
| 688 |
+
labels: torch.LongTensor | None = None,
|
| 689 |
+
**kwargs: Unpack[TransformersKwargs],
|
| 690 |
+
) -> SequenceClassifierOutput | tuple:
|
| 691 |
+
r"""
|
| 692 |
+
labels (`torch.LongTensor` of shape `(batch_size,)`, *optional*):
|
| 693 |
+
Labels for computing the sequence classification/regression loss. Indices should be in `[0, ...,
|
| 694 |
+
config.num_labels - 1]`. If `config.num_labels == 1` a regression loss is computed (Mean-Square loss), If
|
| 695 |
+
`config.num_labels > 1` a classification loss is computed (Cross-Entropy).
|
| 696 |
+
"""
|
| 697 |
+
outputs = self.albert(
|
| 698 |
+
input_ids=input_ids,
|
| 699 |
+
attention_mask=attention_mask,
|
| 700 |
+
token_type_ids=token_type_ids,
|
| 701 |
+
position_ids=position_ids,
|
| 702 |
+
inputs_embeds=inputs_embeds,
|
| 703 |
+
return_dict=True,
|
| 704 |
+
**kwargs,
|
| 705 |
+
)
|
| 706 |
+
|
| 707 |
+
pooled_output = outputs[1]
|
| 708 |
+
|
| 709 |
+
pooled_output = self.dropout(pooled_output)
|
| 710 |
+
logits = self.classifier(pooled_output)
|
| 711 |
+
|
| 712 |
+
loss = None
|
| 713 |
+
if labels is not None:
|
| 714 |
+
if self.config.problem_type is None:
|
| 715 |
+
if self.num_labels == 1:
|
| 716 |
+
self.config.problem_type = "regression"
|
| 717 |
+
elif self.num_labels > 1 and (labels.dtype == torch.long or labels.dtype == torch.int):
|
| 718 |
+
self.config.problem_type = "single_label_classification"
|
| 719 |
+
else:
|
| 720 |
+
self.config.problem_type = "multi_label_classification"
|
| 721 |
+
|
| 722 |
+
if self.config.problem_type == "regression":
|
| 723 |
+
loss_fct = MSELoss()
|
| 724 |
+
if self.num_labels == 1:
|
| 725 |
+
loss = loss_fct(logits.squeeze(), labels.squeeze())
|
| 726 |
+
else:
|
| 727 |
+
loss = loss_fct(logits, labels)
|
| 728 |
+
elif self.config.problem_type == "single_label_classification":
|
| 729 |
+
loss_fct = CrossEntropyLoss()
|
| 730 |
+
loss = loss_fct(logits.view(-1, self.num_labels), labels.view(-1))
|
| 731 |
+
elif self.config.problem_type == "multi_label_classification":
|
| 732 |
+
loss_fct = BCEWithLogitsLoss()
|
| 733 |
+
loss = loss_fct(logits, labels)
|
| 734 |
+
|
| 735 |
+
return SequenceClassifierOutput(
|
| 736 |
+
loss=loss,
|
| 737 |
+
logits=logits,
|
| 738 |
+
hidden_states=outputs.hidden_states,
|
| 739 |
+
attentions=outputs.attentions,
|
| 740 |
+
)
|
| 741 |
+
|
| 742 |
+
|
| 743 |
+
@auto_docstring
|
| 744 |
+
class AlbertForTokenClassification(AlbertPreTrainedModel):
|
| 745 |
+
def __init__(self, config: AlbertConfig):
|
| 746 |
+
super().__init__(config)
|
| 747 |
+
self.num_labels = config.num_labels
|
| 748 |
+
|
| 749 |
+
self.albert = AlbertModel(config, add_pooling_layer=False)
|
| 750 |
+
classifier_dropout_prob = (
|
| 751 |
+
config.classifier_dropout_prob
|
| 752 |
+
if config.classifier_dropout_prob is not None
|
| 753 |
+
else config.hidden_dropout_prob
|
| 754 |
+
)
|
| 755 |
+
self.dropout = nn.Dropout(classifier_dropout_prob)
|
| 756 |
+
self.classifier = nn.Linear(config.hidden_size, self.config.num_labels)
|
| 757 |
+
|
| 758 |
+
# Initialize weights and apply final processing
|
| 759 |
+
self.post_init()
|
| 760 |
+
|
| 761 |
+
@can_return_tuple
|
| 762 |
+
@auto_docstring
|
| 763 |
+
def forward(
|
| 764 |
+
self,
|
| 765 |
+
input_ids: torch.LongTensor | None = None,
|
| 766 |
+
attention_mask: torch.FloatTensor | None = None,
|
| 767 |
+
token_type_ids: torch.LongTensor | None = None,
|
| 768 |
+
position_ids: torch.LongTensor | None = None,
|
| 769 |
+
inputs_embeds: torch.FloatTensor | None = None,
|
| 770 |
+
labels: torch.LongTensor | None = None,
|
| 771 |
+
**kwargs: Unpack[TransformersKwargs],
|
| 772 |
+
) -> TokenClassifierOutput | tuple:
|
| 773 |
+
r"""
|
| 774 |
+
labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*):
|
| 775 |
+
Labels for computing the token classification loss. Indices should be in `[0, ..., config.num_labels - 1]`.
|
| 776 |
+
"""
|
| 777 |
+
outputs = self.albert(
|
| 778 |
+
input_ids,
|
| 779 |
+
attention_mask=attention_mask,
|
| 780 |
+
token_type_ids=token_type_ids,
|
| 781 |
+
position_ids=position_ids,
|
| 782 |
+
inputs_embeds=inputs_embeds,
|
| 783 |
+
return_dict=True,
|
| 784 |
+
**kwargs,
|
| 785 |
+
)
|
| 786 |
+
|
| 787 |
+
sequence_output = outputs[0]
|
| 788 |
+
|
| 789 |
+
sequence_output = self.dropout(sequence_output)
|
| 790 |
+
logits = self.classifier(sequence_output)
|
| 791 |
+
|
| 792 |
+
loss = None
|
| 793 |
+
if labels is not None:
|
| 794 |
+
loss_fct = CrossEntropyLoss()
|
| 795 |
+
loss = loss_fct(logits.view(-1, self.num_labels), labels.view(-1))
|
| 796 |
+
|
| 797 |
+
return TokenClassifierOutput(
|
| 798 |
+
loss=loss,
|
| 799 |
+
logits=logits,
|
| 800 |
+
hidden_states=outputs.hidden_states,
|
| 801 |
+
attentions=outputs.attentions,
|
| 802 |
+
)
|
| 803 |
+
|
| 804 |
+
|
| 805 |
+
@auto_docstring
|
| 806 |
+
class AlbertForQuestionAnswering(AlbertPreTrainedModel):
|
| 807 |
+
def __init__(self, config: AlbertConfig):
|
| 808 |
+
super().__init__(config)
|
| 809 |
+
self.num_labels = config.num_labels
|
| 810 |
+
|
| 811 |
+
self.albert = AlbertModel(config, add_pooling_layer=False)
|
| 812 |
+
self.qa_outputs = nn.Linear(config.hidden_size, config.num_labels)
|
| 813 |
+
|
| 814 |
+
# Initialize weights and apply final processing
|
| 815 |
+
self.post_init()
|
| 816 |
+
|
| 817 |
+
@can_return_tuple
|
| 818 |
+
@auto_docstring
|
| 819 |
+
def forward(
|
| 820 |
+
self,
|
| 821 |
+
input_ids: torch.LongTensor | None = None,
|
| 822 |
+
attention_mask: torch.FloatTensor | None = None,
|
| 823 |
+
token_type_ids: torch.LongTensor | None = None,
|
| 824 |
+
position_ids: torch.LongTensor | None = None,
|
| 825 |
+
inputs_embeds: torch.FloatTensor | None = None,
|
| 826 |
+
start_positions: torch.LongTensor | None = None,
|
| 827 |
+
end_positions: torch.LongTensor | None = None,
|
| 828 |
+
**kwargs: Unpack[TransformersKwargs],
|
| 829 |
+
) -> AlbertForPreTrainingOutput | tuple:
|
| 830 |
+
outputs = self.albert(
|
| 831 |
+
input_ids=input_ids,
|
| 832 |
+
attention_mask=attention_mask,
|
| 833 |
+
token_type_ids=token_type_ids,
|
| 834 |
+
position_ids=position_ids,
|
| 835 |
+
inputs_embeds=inputs_embeds,
|
| 836 |
+
return_dict=True,
|
| 837 |
+
**kwargs,
|
| 838 |
+
)
|
| 839 |
+
|
| 840 |
+
sequence_output = outputs[0]
|
| 841 |
+
|
| 842 |
+
logits: torch.Tensor = self.qa_outputs(sequence_output)
|
| 843 |
+
start_logits, end_logits = logits.split(1, dim=-1)
|
| 844 |
+
start_logits = start_logits.squeeze(-1).contiguous()
|
| 845 |
+
end_logits = end_logits.squeeze(-1).contiguous()
|
| 846 |
+
|
| 847 |
+
total_loss = None
|
| 848 |
+
if start_positions is not None and end_positions is not None:
|
| 849 |
+
# If we are on multi-GPU, split add a dimension
|
| 850 |
+
if len(start_positions.size()) > 1:
|
| 851 |
+
start_positions = start_positions.squeeze(-1)
|
| 852 |
+
if len(end_positions.size()) > 1:
|
| 853 |
+
end_positions = end_positions.squeeze(-1)
|
| 854 |
+
# sometimes the start/end positions are outside our model inputs, we ignore these terms
|
| 855 |
+
ignored_index = start_logits.size(1)
|
| 856 |
+
start_positions = start_positions.clamp(0, ignored_index)
|
| 857 |
+
end_positions = end_positions.clamp(0, ignored_index)
|
| 858 |
+
|
| 859 |
+
loss_fct = CrossEntropyLoss(ignore_index=ignored_index)
|
| 860 |
+
start_loss = loss_fct(start_logits, start_positions)
|
| 861 |
+
end_loss = loss_fct(end_logits, end_positions)
|
| 862 |
+
total_loss = (start_loss + end_loss) / 2
|
| 863 |
+
|
| 864 |
+
return QuestionAnsweringModelOutput(
|
| 865 |
+
loss=total_loss,
|
| 866 |
+
start_logits=start_logits,
|
| 867 |
+
end_logits=end_logits,
|
| 868 |
+
hidden_states=outputs.hidden_states,
|
| 869 |
+
attentions=outputs.attentions,
|
| 870 |
+
)
|
| 871 |
+
|
| 872 |
+
|
| 873 |
+
@auto_docstring
|
| 874 |
+
class AlbertForMultipleChoice(AlbertPreTrainedModel):
|
| 875 |
+
def __init__(self, config: AlbertConfig):
|
| 876 |
+
super().__init__(config)
|
| 877 |
+
|
| 878 |
+
self.albert = AlbertModel(config)
|
| 879 |
+
self.dropout = nn.Dropout(config.classifier_dropout_prob)
|
| 880 |
+
self.classifier = nn.Linear(config.hidden_size, 1)
|
| 881 |
+
|
| 882 |
+
# Initialize weights and apply final processing
|
| 883 |
+
self.post_init()
|
| 884 |
+
|
| 885 |
+
@can_return_tuple
|
| 886 |
+
@auto_docstring
|
| 887 |
+
def forward(
|
| 888 |
+
self,
|
| 889 |
+
input_ids: torch.LongTensor | None = None,
|
| 890 |
+
attention_mask: torch.FloatTensor | None = None,
|
| 891 |
+
token_type_ids: torch.LongTensor | None = None,
|
| 892 |
+
position_ids: torch.LongTensor | None = None,
|
| 893 |
+
inputs_embeds: torch.FloatTensor | None = None,
|
| 894 |
+
labels: torch.LongTensor | None = None,
|
| 895 |
+
**kwargs: Unpack[TransformersKwargs],
|
| 896 |
+
) -> AlbertForPreTrainingOutput | tuple:
|
| 897 |
+
r"""
|
| 898 |
+
input_ids (`torch.LongTensor` of shape `(batch_size, num_choices, sequence_length)`):
|
| 899 |
+
Indices of input sequence tokens in the vocabulary.
|
| 900 |
+
|
| 901 |
+
Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.__call__`] and
|
| 902 |
+
[`PreTrainedTokenizer.encode`] for details.
|
| 903 |
+
|
| 904 |
+
[What are input IDs?](../glossary#input-ids)
|
| 905 |
+
token_type_ids (`torch.LongTensor` of shape `(batch_size, num_choices, sequence_length)`, *optional*):
|
| 906 |
+
Segment token indices to indicate first and second portions of the inputs. Indices are selected in `[0,
|
| 907 |
+
1]`:
|
| 908 |
+
|
| 909 |
+
- 0 corresponds to a *sentence A* token,
|
| 910 |
+
- 1 corresponds to a *sentence B* token.
|
| 911 |
+
|
| 912 |
+
[What are token type IDs?](../glossary#token-type-ids)
|
| 913 |
+
position_ids (`torch.LongTensor` of shape `(batch_size, num_choices, sequence_length)`, *optional*):
|
| 914 |
+
Indices of positions of each input sequence tokens in the position embeddings. Selected in the range `[0,
|
| 915 |
+
config.max_position_embeddings - 1]`.
|
| 916 |
+
|
| 917 |
+
[What are position IDs?](../glossary#position-ids)
|
| 918 |
+
inputs_embeds (`torch.FloatTensor` of shape `(batch_size, num_choices, sequence_length, hidden_size)`, *optional*):
|
| 919 |
+
Optionally, instead of passing `input_ids` you can choose to directly pass an embedded representation. This
|
| 920 |
+
is useful if you want more control over how to convert `input_ids` indices into associated vectors than the
|
| 921 |
+
model's internal embedding lookup matrix.
|
| 922 |
+
labels (`torch.LongTensor` of shape `(batch_size,)`, *optional*):
|
| 923 |
+
Labels for computing the multiple choice classification loss. Indices should be in `[0, ...,
|
| 924 |
+
num_choices-1]` where *num_choices* is the size of the second dimension of the input tensors. (see
|
| 925 |
+
*input_ids* above)
|
| 926 |
+
"""
|
| 927 |
+
num_choices = input_ids.shape[1] if input_ids is not None else inputs_embeds.shape[1]
|
| 928 |
+
|
| 929 |
+
input_ids = input_ids.view(-1, input_ids.size(-1)) if input_ids is not None else None
|
| 930 |
+
attention_mask = attention_mask.view(-1, attention_mask.size(-1)) if attention_mask is not None else None
|
| 931 |
+
token_type_ids = token_type_ids.view(-1, token_type_ids.size(-1)) if token_type_ids is not None else None
|
| 932 |
+
position_ids = position_ids.view(-1, position_ids.size(-1)) if position_ids is not None else None
|
| 933 |
+
inputs_embeds = (
|
| 934 |
+
inputs_embeds.view(-1, inputs_embeds.size(-2), inputs_embeds.size(-1))
|
| 935 |
+
if inputs_embeds is not None
|
| 936 |
+
else None
|
| 937 |
+
)
|
| 938 |
+
outputs = self.albert(
|
| 939 |
+
input_ids,
|
| 940 |
+
attention_mask=attention_mask,
|
| 941 |
+
token_type_ids=token_type_ids,
|
| 942 |
+
position_ids=position_ids,
|
| 943 |
+
inputs_embeds=inputs_embeds,
|
| 944 |
+
return_dict=True,
|
| 945 |
+
**kwargs,
|
| 946 |
+
)
|
| 947 |
+
|
| 948 |
+
pooled_output = outputs[1]
|
| 949 |
+
|
| 950 |
+
pooled_output = self.dropout(pooled_output)
|
| 951 |
+
logits: torch.Tensor = self.classifier(pooled_output)
|
| 952 |
+
reshaped_logits = logits.view(-1, num_choices)
|
| 953 |
+
|
| 954 |
+
loss = None
|
| 955 |
+
if labels is not None:
|
| 956 |
+
loss_fct = CrossEntropyLoss()
|
| 957 |
+
loss = loss_fct(reshaped_logits, labels)
|
| 958 |
+
|
| 959 |
+
return MultipleChoiceModelOutput(
|
| 960 |
+
loss=loss,
|
| 961 |
+
logits=reshaped_logits,
|
| 962 |
+
hidden_states=outputs.hidden_states,
|
| 963 |
+
attentions=outputs.attentions,
|
| 964 |
+
)
|
| 965 |
+
|
| 966 |
+
|
| 967 |
+
__all__ = [
|
| 968 |
+
"AlbertPreTrainedModel",
|
| 969 |
+
"AlbertModel",
|
| 970 |
+
"AlbertForPreTraining",
|
| 971 |
+
"AlbertForMaskedLM",
|
| 972 |
+
"AlbertForSequenceClassification",
|
| 973 |
+
"AlbertForTokenClassification",
|
| 974 |
+
"AlbertForQuestionAnswering",
|
| 975 |
+
"AlbertForMultipleChoice",
|
| 976 |
+
]
|
third_party/transformers/src/transformers/models/albert/tokenization_albert.py
ADDED
|
@@ -0,0 +1,176 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright 2018 Google AI, Google Brain and the HuggingFace Inc. team.
|
| 2 |
+
#
|
| 3 |
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
| 4 |
+
# you may not use this file except in compliance with the License.
|
| 5 |
+
# You may obtain a copy of the License at
|
| 6 |
+
#
|
| 7 |
+
# http://www.apache.org/licenses/LICENSE-2.0
|
| 8 |
+
#
|
| 9 |
+
# Unless required by applicable law or agreed to in writing, software
|
| 10 |
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
| 11 |
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 12 |
+
# See the License for the specific language governing permissions and
|
| 13 |
+
# limitations under the License.
|
| 14 |
+
"""Tokenization classes for ALBERT model."""
|
| 15 |
+
|
| 16 |
+
from tokenizers import Regex, Tokenizer, decoders, normalizers, pre_tokenizers, processors
|
| 17 |
+
from tokenizers.models import Unigram
|
| 18 |
+
|
| 19 |
+
from ...tokenization_utils_tokenizers import TokenizersBackend
|
| 20 |
+
from ...utils import logging
|
| 21 |
+
|
| 22 |
+
|
| 23 |
+
logger = logging.get_logger(__name__)
|
| 24 |
+
|
| 25 |
+
VOCAB_FILES_NAMES = {"vocab_file": "spiece.model", "tokenizer_file": "tokenizer.json"}
|
| 26 |
+
|
| 27 |
+
|
| 28 |
+
class AlbertTokenizer(TokenizersBackend):
|
| 29 |
+
"""
|
| 30 |
+
Construct a "fast" ALBERT tokenizer (backed by HuggingFace's *tokenizers* library). Based on
|
| 31 |
+
[Unigram](https://huggingface.co/docs/tokenizers/python/latest/components.html?highlight=unigram#models). This
|
| 32 |
+
tokenizer inherits from [`PreTrainedTokenizerFast`] which contains most of the main methods. Users should refer to
|
| 33 |
+
this superclass for more information regarding those methods
|
| 34 |
+
|
| 35 |
+
Args:
|
| 36 |
+
do_lower_case (`bool`, *optional*, defaults to `True`):
|
| 37 |
+
Whether or not to lowercase the input when tokenizing.
|
| 38 |
+
keep_accents (`bool`, *optional*, defaults to `False`):
|
| 39 |
+
Whether or not to keep accents when tokenizing.
|
| 40 |
+
bos_token (`str`, *optional*, defaults to `"[CLS]"`):
|
| 41 |
+
The beginning of sequence token that was used during pretraining. Can be used a sequence classifier token.
|
| 42 |
+
|
| 43 |
+
<Tip>
|
| 44 |
+
|
| 45 |
+
When building a sequence using special tokens, this is not the token that is used for the beginning of
|
| 46 |
+
sequence. The token used is the `cls_token`.
|
| 47 |
+
|
| 48 |
+
</Tip>
|
| 49 |
+
|
| 50 |
+
eos_token (`str`, *optional*, defaults to `"[SEP]"`):
|
| 51 |
+
The end of sequence token. .. note:: When building a sequence using special tokens, this is not the token
|
| 52 |
+
that is used for the end of sequence. The token used is the `sep_token`.
|
| 53 |
+
unk_token (`str`, *optional*, defaults to `"<unk>"`):
|
| 54 |
+
The unknown token. A token that is not in the vocabulary cannot be converted to an ID and is set to be this
|
| 55 |
+
token instead.
|
| 56 |
+
sep_token (`str`, *optional*, defaults to `"[SEP]"`):
|
| 57 |
+
The separator token, which is used when building a sequence from multiple sequences, e.g. two sequences for
|
| 58 |
+
sequence classification or for a text and a question for question answering. It is also used as the last
|
| 59 |
+
token of a sequence built with special tokens.
|
| 60 |
+
pad_token (`str`, *optional*, defaults to `"<pad>"`):
|
| 61 |
+
The token used for padding, for example when batching sequences of different lengths.
|
| 62 |
+
cls_token (`str`, *optional*, defaults to `"[CLS]"`):
|
| 63 |
+
The classifier token which is used when doing sequence classification (classification of the whole sequence
|
| 64 |
+
instead of per-token classification). It is the first token of the sequence when built with special tokens.
|
| 65 |
+
mask_token (`str`, *optional*, defaults to `"[MASK]"`):
|
| 66 |
+
The token used for masking values. This is the token used when training this model with masked language
|
| 67 |
+
modeling. This is the token which the model will try to predict.
|
| 68 |
+
add_prefix_space (`bool`, *optional*, defaults to `True`):
|
| 69 |
+
Whether or not to add an initial space to the input. This allows to treat the leading word just as any
|
| 70 |
+
other word.
|
| 71 |
+
trim_offsets (`bool`, *optional*, defaults to `True`):
|
| 72 |
+
Whether the post processing step should trim offsets to avoid including whitespaces.
|
| 73 |
+
vocab (`str` or `list[tuple[str, float]]`, *optional*):
|
| 74 |
+
Custom vocabulary with `(token, score)` tuples. If not provided, vocabulary is loaded from `vocab_file`.
|
| 75 |
+
vocab_file (`str`, *optional*):
|
| 76 |
+
[SentencePiece](https://github.com/google/sentencepiece) file (generally has a .model extension) that
|
| 77 |
+
contains the vocabulary necessary to instantiate a tokenizer.
|
| 78 |
+
"""
|
| 79 |
+
|
| 80 |
+
vocab_files_names = VOCAB_FILES_NAMES
|
| 81 |
+
model_input_names = ["input_ids", "attention_mask"]
|
| 82 |
+
model = Unigram
|
| 83 |
+
|
| 84 |
+
def __init__(
|
| 85 |
+
self,
|
| 86 |
+
vocab: str | list[tuple[str, float]] | None = None,
|
| 87 |
+
do_lower_case: bool = True,
|
| 88 |
+
keep_accents: bool = False,
|
| 89 |
+
bos_token: str = "[CLS]",
|
| 90 |
+
eos_token: str = "[SEP]",
|
| 91 |
+
unk_token: str = "<unk>",
|
| 92 |
+
sep_token: str = "[SEP]",
|
| 93 |
+
pad_token: str = "<pad>",
|
| 94 |
+
cls_token: str = "[CLS]",
|
| 95 |
+
mask_token: str = "[MASK]",
|
| 96 |
+
add_prefix_space: bool = True,
|
| 97 |
+
trim_offsets: bool = True,
|
| 98 |
+
**kwargs,
|
| 99 |
+
):
|
| 100 |
+
self.add_prefix_space = add_prefix_space
|
| 101 |
+
self.trim_offsets = trim_offsets
|
| 102 |
+
self.do_lower_case = do_lower_case
|
| 103 |
+
self.keep_accents = keep_accents
|
| 104 |
+
|
| 105 |
+
if vocab is not None:
|
| 106 |
+
self._vocab_scores = vocab
|
| 107 |
+
else:
|
| 108 |
+
self._vocab_scores = [
|
| 109 |
+
(str(pad_token), 0.0),
|
| 110 |
+
(str(unk_token), 0.0),
|
| 111 |
+
(str(cls_token), 0.0),
|
| 112 |
+
(str(sep_token), 0.0),
|
| 113 |
+
(str(mask_token), 0.0),
|
| 114 |
+
]
|
| 115 |
+
|
| 116 |
+
self._tokenizer = Tokenizer(
|
| 117 |
+
Unigram(
|
| 118 |
+
self._vocab_scores,
|
| 119 |
+
unk_id=1,
|
| 120 |
+
byte_fallback=False,
|
| 121 |
+
)
|
| 122 |
+
)
|
| 123 |
+
|
| 124 |
+
list_normalizers = [
|
| 125 |
+
normalizers.Replace("``", '"'),
|
| 126 |
+
normalizers.Replace("''", '"'),
|
| 127 |
+
normalizers.NFKD(),
|
| 128 |
+
normalizers.StripAccents(),
|
| 129 |
+
normalizers.Lowercase(),
|
| 130 |
+
normalizers.Replace(Regex(" {2,}"), " "),
|
| 131 |
+
]
|
| 132 |
+
if not self.keep_accents:
|
| 133 |
+
list_normalizers.append(normalizers.NFKD())
|
| 134 |
+
list_normalizers.append(normalizers.StripAccents())
|
| 135 |
+
if self.do_lower_case:
|
| 136 |
+
list_normalizers.append(normalizers.Lowercase())
|
| 137 |
+
|
| 138 |
+
list_normalizers.append(normalizers.Replace(Regex(" {2,}"), " "))
|
| 139 |
+
self._tokenizer.normalizer = normalizers.Sequence(list_normalizers)
|
| 140 |
+
|
| 141 |
+
prepend_scheme = "always" if add_prefix_space else "never"
|
| 142 |
+
self._tokenizer.pre_tokenizer = pre_tokenizers.Sequence(
|
| 143 |
+
[
|
| 144 |
+
pre_tokenizers.WhitespaceSplit(),
|
| 145 |
+
pre_tokenizers.Metaspace(replacement="▁", prepend_scheme=prepend_scheme),
|
| 146 |
+
]
|
| 147 |
+
)
|
| 148 |
+
|
| 149 |
+
self._tokenizer.decoder = decoders.Metaspace(replacement="▁", prepend_scheme=prepend_scheme)
|
| 150 |
+
|
| 151 |
+
self._tokenizer.post_processor = processors.TemplateProcessing(
|
| 152 |
+
single="[CLS]:0 $A:0 [SEP]:0",
|
| 153 |
+
pair="[CLS]:0 $A:0 [SEP]:0 $B:1 [SEP]:1",
|
| 154 |
+
special_tokens=[
|
| 155 |
+
("[CLS]", self._tokenizer.token_to_id(str(cls_token))),
|
| 156 |
+
("[SEP]", self._tokenizer.token_to_id(str(sep_token))),
|
| 157 |
+
],
|
| 158 |
+
)
|
| 159 |
+
|
| 160 |
+
super().__init__(
|
| 161 |
+
do_lower_case=self.do_lower_case,
|
| 162 |
+
keep_accents=self.keep_accents,
|
| 163 |
+
bos_token=bos_token,
|
| 164 |
+
eos_token=eos_token,
|
| 165 |
+
sep_token=sep_token,
|
| 166 |
+
cls_token=cls_token,
|
| 167 |
+
unk_token=unk_token,
|
| 168 |
+
pad_token=pad_token,
|
| 169 |
+
mask_token=mask_token,
|
| 170 |
+
add_prefix_space=add_prefix_space,
|
| 171 |
+
trim_offsets=trim_offsets,
|
| 172 |
+
**kwargs,
|
| 173 |
+
)
|
| 174 |
+
|
| 175 |
+
|
| 176 |
+
__all__ = ["AlbertTokenizer"]
|
third_party/transformers/src/transformers/models/bark/generation_configuration_bark.py
ADDED
|
@@ -0,0 +1,327 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright 2023 The Suno AI Authors and The HuggingFace Inc. team. All rights reserved.
|
| 2 |
+
#
|
| 3 |
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
| 4 |
+
# you may not use this file except in compliance with the License.
|
| 5 |
+
# You may obtain a copy of the License at
|
| 6 |
+
#
|
| 7 |
+
# http://www.apache.org/licenses/LICENSE-2.0
|
| 8 |
+
#
|
| 9 |
+
# Unless required by applicable law or agreed to in writing, software
|
| 10 |
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
| 11 |
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 12 |
+
# See the License for the specific language governing permissions and
|
| 13 |
+
# limitations under the License.
|
| 14 |
+
"""BARK model generation configuration"""
|
| 15 |
+
|
| 16 |
+
import copy
|
| 17 |
+
|
| 18 |
+
from ...generation.configuration_utils import GenerationConfig
|
| 19 |
+
from ...utils import logging
|
| 20 |
+
|
| 21 |
+
|
| 22 |
+
logger = logging.get_logger(__name__)
|
| 23 |
+
|
| 24 |
+
|
| 25 |
+
class BarkSemanticGenerationConfig(GenerationConfig):
|
| 26 |
+
model_type = "semantic"
|
| 27 |
+
|
| 28 |
+
def __init__(
|
| 29 |
+
self,
|
| 30 |
+
eos_token_id=10_000,
|
| 31 |
+
renormalize_logits=True,
|
| 32 |
+
max_new_tokens=768,
|
| 33 |
+
output_scores=False,
|
| 34 |
+
return_dict_in_generate=False,
|
| 35 |
+
output_hidden_states=False,
|
| 36 |
+
output_attentions=False,
|
| 37 |
+
temperature=1.0,
|
| 38 |
+
do_sample=False,
|
| 39 |
+
text_encoding_offset=10_048,
|
| 40 |
+
text_pad_token=129_595,
|
| 41 |
+
semantic_infer_token=129_599,
|
| 42 |
+
semantic_vocab_size=10_000,
|
| 43 |
+
max_input_semantic_length=256,
|
| 44 |
+
semantic_rate_hz=49.9,
|
| 45 |
+
min_eos_p=None,
|
| 46 |
+
**kwargs,
|
| 47 |
+
):
|
| 48 |
+
"""Class that holds a generation configuration for [`BarkSemanticModel`].
|
| 49 |
+
|
| 50 |
+
This configuration inherit from [`GenerationConfig`] and can be used to control the model generation. Read the
|
| 51 |
+
documentation from [`GenerationConfig`] for more information.
|
| 52 |
+
|
| 53 |
+
Args:
|
| 54 |
+
eos_token_id (`int`, *optional*, defaults to 10_000):
|
| 55 |
+
The id of the *end-of-sequence* token.
|
| 56 |
+
renormalize_logits (`bool`, *optional*, defaults to `True`):
|
| 57 |
+
Whether to renormalize the logits after applying all the logits processors (including the
|
| 58 |
+
custom ones). It's highly recommended to set this flag to `True` as the search algorithms suppose the
|
| 59 |
+
score logits are normalized but some logit processors break the normalization.
|
| 60 |
+
max_new_tokens (`int`, *optional*, defaults to 768):
|
| 61 |
+
The maximum numbers of tokens to generate, ignoring the number of tokens in the prompt.
|
| 62 |
+
output_scores (`bool`, *optional*, defaults to `False`):
|
| 63 |
+
Whether or not to return the prediction scores. See `scores` under returned tensors for more details.
|
| 64 |
+
return_dict_in_generate (`bool`, *optional*, defaults to `False`):
|
| 65 |
+
Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple.
|
| 66 |
+
output_hidden_states (`bool`, *optional*, defaults to `False`):
|
| 67 |
+
Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors
|
| 68 |
+
for more details.
|
| 69 |
+
output_attentions (`bool`, *optional*, defaults to `False`):
|
| 70 |
+
Whether or not to return the attentions tensors of all attention layers. See `attentions` under
|
| 71 |
+
returned tensors for more details.
|
| 72 |
+
temperature (`float`, *optional*, defaults to 1.0):
|
| 73 |
+
The value used to modulate the next token probabilities.
|
| 74 |
+
do_sample (`bool`, *optional*, defaults to `False`):
|
| 75 |
+
Whether or not to use sampling ; use greedy decoding otherwise.
|
| 76 |
+
text_encoding_offset (`int`, *optional*, defaults to 10_048):
|
| 77 |
+
Text encoding offset.
|
| 78 |
+
text_pad_token (`int`, *optional*, defaults to 129_595):
|
| 79 |
+
Text pad token.
|
| 80 |
+
semantic_infer_token (`int`, *optional*, defaults to 129_599):
|
| 81 |
+
Semantic infer token.
|
| 82 |
+
semantic_vocab_size (`int`, *optional*, defaults to 10_000):
|
| 83 |
+
Semantic vocab size.
|
| 84 |
+
max_input_semantic_length (`int`, *optional*, defaults to 256):
|
| 85 |
+
Max length of semantic input vector.
|
| 86 |
+
semantic_rate_hz (`float`, *optional*, defaults to 49.9):
|
| 87 |
+
Semantic rate in Hertz.
|
| 88 |
+
min_eos_p (`float`, *optional*):
|
| 89 |
+
Minimum threshold of the probability of the EOS token for it to be sampled. This is an early stopping
|
| 90 |
+
strategy to mitigate potential unwanted generations at the end of a prompt. The original implementation
|
| 91 |
+
suggests a default value of 0.2.
|
| 92 |
+
"""
|
| 93 |
+
super().__init__(
|
| 94 |
+
temperature=temperature,
|
| 95 |
+
do_sample=do_sample,
|
| 96 |
+
eos_token_id=eos_token_id,
|
| 97 |
+
renormalize_logits=renormalize_logits,
|
| 98 |
+
max_new_tokens=max_new_tokens,
|
| 99 |
+
output_scores=output_scores,
|
| 100 |
+
return_dict_in_generate=return_dict_in_generate,
|
| 101 |
+
output_hidden_states=output_hidden_states,
|
| 102 |
+
output_attentions=output_attentions,
|
| 103 |
+
**kwargs,
|
| 104 |
+
)
|
| 105 |
+
|
| 106 |
+
self.text_encoding_offset = text_encoding_offset
|
| 107 |
+
self.text_pad_token = text_pad_token
|
| 108 |
+
self.semantic_pad_token = eos_token_id
|
| 109 |
+
self.semantic_infer_token = semantic_infer_token
|
| 110 |
+
self.semantic_vocab_size = semantic_vocab_size
|
| 111 |
+
self.max_input_semantic_length = max_input_semantic_length
|
| 112 |
+
self.semantic_rate_hz = semantic_rate_hz
|
| 113 |
+
self.min_eos_p = min_eos_p
|
| 114 |
+
|
| 115 |
+
|
| 116 |
+
class BarkCoarseGenerationConfig(GenerationConfig):
|
| 117 |
+
model_type = "coarse_acoustics"
|
| 118 |
+
|
| 119 |
+
def __init__(
|
| 120 |
+
self,
|
| 121 |
+
renormalize_logits=True,
|
| 122 |
+
output_scores=False,
|
| 123 |
+
return_dict_in_generate=False,
|
| 124 |
+
output_hidden_states=False,
|
| 125 |
+
output_attentions=False,
|
| 126 |
+
temperature=1.0,
|
| 127 |
+
do_sample=False,
|
| 128 |
+
coarse_semantic_pad_token=12_048,
|
| 129 |
+
coarse_rate_hz=75,
|
| 130 |
+
n_coarse_codebooks=2,
|
| 131 |
+
coarse_infer_token=12_050,
|
| 132 |
+
max_coarse_input_length=256,
|
| 133 |
+
max_coarse_history: int = 630,
|
| 134 |
+
sliding_window_len: int = 60,
|
| 135 |
+
**kwargs,
|
| 136 |
+
):
|
| 137 |
+
"""Class that holds a generation configuration for [`BarkCoarseModel`].
|
| 138 |
+
|
| 139 |
+
This configuration inherit from [`GenerationConfig`] and can be used to control the model generation. Read the
|
| 140 |
+
documentation from [`GenerationConfig`] for more information.
|
| 141 |
+
|
| 142 |
+
Args:
|
| 143 |
+
renormalize_logits (`bool`, *optional*, defaults to `True`):
|
| 144 |
+
Whether to renormalize the logits after applying all the logits processors (including the
|
| 145 |
+
custom ones). It's highly recommended to set this flag to `True` as the search algorithms suppose the
|
| 146 |
+
score logits are normalized but some logit processors break the normalization.
|
| 147 |
+
output_scores (`bool`, *optional*, defaults to `False`):
|
| 148 |
+
Whether or not to return the prediction scores. See `scores` under returned tensors for more details.
|
| 149 |
+
return_dict_in_generate (`bool`, *optional*, defaults to `False`):
|
| 150 |
+
Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple.
|
| 151 |
+
output_hidden_states (`bool`, *optional*, defaults to `False`):
|
| 152 |
+
Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors
|
| 153 |
+
for more details.
|
| 154 |
+
output_attentions (`bool`, *optional*, defaults to `False`):
|
| 155 |
+
Whether or not to return the attentions tensors of all attention layers. See `attentions` under
|
| 156 |
+
returned tensors for more details.
|
| 157 |
+
temperature (`float`, *optional*, defaults to 1.0):
|
| 158 |
+
The value used to modulate the next token probabilities.
|
| 159 |
+
do_sample (`bool`, *optional*, defaults to `False`):
|
| 160 |
+
Whether or not to use sampling ; use greedy decoding otherwise.
|
| 161 |
+
coarse_semantic_pad_token (`int`, *optional*, defaults to 12_048):
|
| 162 |
+
Coarse semantic pad token.
|
| 163 |
+
coarse_rate_hz (`int`, *optional*, defaults to 75):
|
| 164 |
+
Coarse rate in Hertz.
|
| 165 |
+
n_coarse_codebooks (`int`, *optional*, defaults to 2):
|
| 166 |
+
Number of coarse codebooks.
|
| 167 |
+
coarse_infer_token (`int`, *optional*, defaults to 12_050):
|
| 168 |
+
Coarse infer token.
|
| 169 |
+
max_coarse_input_length (`int`, *optional*, defaults to 256):
|
| 170 |
+
Max length of input coarse vector.
|
| 171 |
+
max_coarse_history (`int`, *optional*, defaults to 630):
|
| 172 |
+
Max length of the output of the coarse acoustics model used in the fine generation step.
|
| 173 |
+
sliding_window_len (`int`, *optional*, defaults to 60):
|
| 174 |
+
The coarse generation step uses a sliding window to generate raw audio.
|
| 175 |
+
"""
|
| 176 |
+
super().__init__(
|
| 177 |
+
temperature=temperature,
|
| 178 |
+
do_sample=do_sample,
|
| 179 |
+
renormalize_logits=renormalize_logits,
|
| 180 |
+
output_scores=output_scores,
|
| 181 |
+
return_dict_in_generate=return_dict_in_generate,
|
| 182 |
+
output_hidden_states=output_hidden_states,
|
| 183 |
+
output_attentions=output_attentions,
|
| 184 |
+
**kwargs,
|
| 185 |
+
)
|
| 186 |
+
|
| 187 |
+
self.coarse_semantic_pad_token = coarse_semantic_pad_token
|
| 188 |
+
self.coarse_rate_hz = coarse_rate_hz
|
| 189 |
+
self.n_coarse_codebooks = n_coarse_codebooks
|
| 190 |
+
self.coarse_infer_token = coarse_infer_token
|
| 191 |
+
self.max_coarse_input_length = max_coarse_input_length
|
| 192 |
+
self.max_coarse_history = max_coarse_history
|
| 193 |
+
self.sliding_window_len = sliding_window_len
|
| 194 |
+
|
| 195 |
+
|
| 196 |
+
class BarkFineGenerationConfig(GenerationConfig):
|
| 197 |
+
model_type = "fine_acoustics"
|
| 198 |
+
|
| 199 |
+
def __init__(
|
| 200 |
+
self,
|
| 201 |
+
temperature=1.0,
|
| 202 |
+
max_fine_history_length=512,
|
| 203 |
+
max_fine_input_length=1024,
|
| 204 |
+
n_fine_codebooks=8,
|
| 205 |
+
**kwargs,
|
| 206 |
+
):
|
| 207 |
+
"""Class that holds a generation configuration for [`BarkFineModel`].
|
| 208 |
+
|
| 209 |
+
[`BarkFineModel`] is an autoencoder model, so should not usually be used for generation. However, under the
|
| 210 |
+
hood, it uses `temperature` when used by [`BarkModel`]
|
| 211 |
+
|
| 212 |
+
This configuration inherit from [`GenerationConfig`] and can be used to control the model generation. Read the
|
| 213 |
+
documentation from [`GenerationConfig`] for more information.
|
| 214 |
+
|
| 215 |
+
Args:
|
| 216 |
+
temperature (`float`, *optional*):
|
| 217 |
+
The value used to modulate the next token probabilities.
|
| 218 |
+
max_fine_history_length (`int`, *optional*, defaults to 512):
|
| 219 |
+
Max length of the fine history vector.
|
| 220 |
+
max_fine_input_length (`int`, *optional*, defaults to 1024):
|
| 221 |
+
Max length of fine input vector.
|
| 222 |
+
n_fine_codebooks (`int`, *optional*, defaults to 8):
|
| 223 |
+
Number of codebooks used.
|
| 224 |
+
"""
|
| 225 |
+
super().__init__(temperature=temperature)
|
| 226 |
+
|
| 227 |
+
self.max_fine_history_length = max_fine_history_length
|
| 228 |
+
self.max_fine_input_length = max_fine_input_length
|
| 229 |
+
self.n_fine_codebooks = n_fine_codebooks
|
| 230 |
+
|
| 231 |
+
def validate(self, **kwargs):
|
| 232 |
+
"""
|
| 233 |
+
Overrides GenerationConfig.validate because BarkFineGenerationConfig don't use any parameters outside
|
| 234 |
+
temperature.
|
| 235 |
+
"""
|
| 236 |
+
|
| 237 |
+
|
| 238 |
+
class BarkGenerationConfig(GenerationConfig):
|
| 239 |
+
model_type = "bark"
|
| 240 |
+
|
| 241 |
+
# TODO (joao): nested from_dict
|
| 242 |
+
|
| 243 |
+
def __init__(
|
| 244 |
+
self,
|
| 245 |
+
semantic_config: dict | None = None,
|
| 246 |
+
coarse_acoustics_config: dict | None = None,
|
| 247 |
+
fine_acoustics_config: dict | None = None,
|
| 248 |
+
sample_rate=24_000,
|
| 249 |
+
codebook_size=1024,
|
| 250 |
+
**kwargs,
|
| 251 |
+
):
|
| 252 |
+
"""Class that holds a generation configuration for [`BarkModel`].
|
| 253 |
+
|
| 254 |
+
The [`BarkModel`] does not have a `generate` method, but uses this class to generate speeches with a nested
|
| 255 |
+
[`BarkGenerationConfig`] which uses [`BarkSemanticGenerationConfig`], [`BarkCoarseGenerationConfig`],
|
| 256 |
+
[`BarkFineGenerationConfig`].
|
| 257 |
+
|
| 258 |
+
This configuration inherit from [`GenerationConfig`] and can be used to control the model generation. Read the
|
| 259 |
+
documentation from [`GenerationConfig`] for more information.
|
| 260 |
+
|
| 261 |
+
Args:
|
| 262 |
+
semantic_config (`Dict`, *optional*):
|
| 263 |
+
Semantic generation configuration.
|
| 264 |
+
coarse_acoustics_config (`Dict`, *optional*):
|
| 265 |
+
Coarse generation configuration.
|
| 266 |
+
fine_acoustics_config (`Dict`, *optional*):
|
| 267 |
+
Fine generation configuration.
|
| 268 |
+
sample_rate (`int`, *optional*, defaults to 24_000):
|
| 269 |
+
Sample rate.
|
| 270 |
+
codebook_size (`int`, *optional*, defaults to 1024):
|
| 271 |
+
Vector length for each codebook.
|
| 272 |
+
"""
|
| 273 |
+
if semantic_config is None:
|
| 274 |
+
semantic_config = {}
|
| 275 |
+
logger.info("semantic_config is None. initializing the semantic model with default values.")
|
| 276 |
+
|
| 277 |
+
if coarse_acoustics_config is None:
|
| 278 |
+
coarse_acoustics_config = {}
|
| 279 |
+
logger.info("coarse_acoustics_config is None. initializing the coarse model with default values.")
|
| 280 |
+
|
| 281 |
+
if fine_acoustics_config is None:
|
| 282 |
+
fine_acoustics_config = {}
|
| 283 |
+
logger.info("fine_acoustics_config is None. initializing the fine model with default values.")
|
| 284 |
+
|
| 285 |
+
self.semantic_config = BarkSemanticGenerationConfig(**semantic_config)
|
| 286 |
+
self.coarse_acoustics_config = BarkCoarseGenerationConfig(**coarse_acoustics_config)
|
| 287 |
+
self.fine_acoustics_config = BarkFineGenerationConfig(**fine_acoustics_config)
|
| 288 |
+
|
| 289 |
+
self.sample_rate = sample_rate
|
| 290 |
+
self.codebook_size = codebook_size
|
| 291 |
+
|
| 292 |
+
@classmethod
|
| 293 |
+
def from_sub_model_configs(
|
| 294 |
+
cls,
|
| 295 |
+
semantic_config: BarkSemanticGenerationConfig,
|
| 296 |
+
coarse_acoustics_config: BarkCoarseGenerationConfig,
|
| 297 |
+
fine_acoustics_config: BarkFineGenerationConfig,
|
| 298 |
+
**kwargs,
|
| 299 |
+
):
|
| 300 |
+
r"""
|
| 301 |
+
Instantiate a [`BarkGenerationConfig`] (or a derived class) from bark sub-models generation configuration.
|
| 302 |
+
|
| 303 |
+
Returns:
|
| 304 |
+
[`BarkGenerationConfig`]: An instance of a configuration object
|
| 305 |
+
"""
|
| 306 |
+
return cls(
|
| 307 |
+
semantic_config=semantic_config.to_dict(),
|
| 308 |
+
coarse_acoustics_config=coarse_acoustics_config.to_dict(),
|
| 309 |
+
fine_acoustics_config=fine_acoustics_config.to_dict(),
|
| 310 |
+
**kwargs,
|
| 311 |
+
)
|
| 312 |
+
|
| 313 |
+
def to_dict(self):
|
| 314 |
+
"""
|
| 315 |
+
Serializes this instance to a Python dictionary. Override the default [`~PreTrainedConfig.to_dict`].
|
| 316 |
+
|
| 317 |
+
Returns:
|
| 318 |
+
`dict[str, any]`: Dictionary of all the attributes that make up this configuration instance,
|
| 319 |
+
"""
|
| 320 |
+
output = copy.deepcopy(self.__dict__)
|
| 321 |
+
|
| 322 |
+
output["semantic_config"] = self.semantic_config.to_dict()
|
| 323 |
+
output["coarse_acoustics_config"] = self.coarse_acoustics_config.to_dict()
|
| 324 |
+
output["fine_acoustics_config"] = self.fine_acoustics_config.to_dict()
|
| 325 |
+
|
| 326 |
+
output["model_type"] = self.__class__.model_type
|
| 327 |
+
return output
|
third_party/transformers/src/transformers/models/big_bird/__init__.py
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright 2024 The HuggingFace Team. All rights reserved.
|
| 2 |
+
#
|
| 3 |
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
| 4 |
+
# you may not use this file except in compliance with the License.
|
| 5 |
+
# You may obtain a copy of the License at
|
| 6 |
+
#
|
| 7 |
+
# http://www.apache.org/licenses/LICENSE-2.0
|
| 8 |
+
#
|
| 9 |
+
# Unless required by applicable law or agreed to in writing, software
|
| 10 |
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
| 11 |
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 12 |
+
# See the License for the specific language governing permissions and
|
| 13 |
+
# limitations under the License.
|
| 14 |
+
from typing import TYPE_CHECKING
|
| 15 |
+
|
| 16 |
+
from ...utils import _LazyModule
|
| 17 |
+
from ...utils.import_utils import define_import_structure
|
| 18 |
+
|
| 19 |
+
|
| 20 |
+
if TYPE_CHECKING:
|
| 21 |
+
from .configuration_big_bird import *
|
| 22 |
+
from .modeling_big_bird import *
|
| 23 |
+
from .tokenization_big_bird import *
|
| 24 |
+
else:
|
| 25 |
+
import sys
|
| 26 |
+
|
| 27 |
+
_file = globals()["__file__"]
|
| 28 |
+
sys.modules[__name__] = _LazyModule(__name__, _file, define_import_structure(_file), module_spec=__spec__)
|
third_party/transformers/src/transformers/models/big_bird/configuration_big_bird.py
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright 2021 Google Research and The HuggingFace Inc. team. All rights reserved.
|
| 2 |
+
#
|
| 3 |
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
| 4 |
+
# you may not use this file except in compliance with the License.
|
| 5 |
+
# You may obtain a copy of the License at
|
| 6 |
+
#
|
| 7 |
+
# http://www.apache.org/licenses/LICENSE-2.0
|
| 8 |
+
#
|
| 9 |
+
# Unless required by applicable law or agreed to in writing, software
|
| 10 |
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
| 11 |
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 12 |
+
# See the License for the specific language governing permissions and
|
| 13 |
+
# limitations under the License.
|
| 14 |
+
"""BigBird model configuration"""
|
| 15 |
+
|
| 16 |
+
from huggingface_hub.dataclasses import strict
|
| 17 |
+
|
| 18 |
+
from ...configuration_utils import PreTrainedConfig
|
| 19 |
+
from ...utils import auto_docstring
|
| 20 |
+
|
| 21 |
+
|
| 22 |
+
@auto_docstring(checkpoint="google/bigbird-roberta-base")
|
| 23 |
+
@strict
|
| 24 |
+
class BigBirdConfig(PreTrainedConfig):
|
| 25 |
+
r"""
|
| 26 |
+
attention_type (`str`, *optional*, defaults to `"block_sparse"`):
|
| 27 |
+
Whether to use block sparse attention (with n complexity) as introduced in paper or original attention
|
| 28 |
+
layer (with n^2 complexity). Possible values are `"original_full"` and `"block_sparse"`.
|
| 29 |
+
use_bias (`bool`, *optional*, defaults to `True`):
|
| 30 |
+
Whether to use bias in query, key, value.
|
| 31 |
+
rescale_embeddings (`bool`, *optional*, defaults to `False`):
|
| 32 |
+
Whether to rescale embeddings with (hidden_size ** 0.5).
|
| 33 |
+
block_size (`int`, *optional*, defaults to 64):
|
| 34 |
+
Size of each block. Useful only when `attention_type == "block_sparse"`.
|
| 35 |
+
num_random_blocks (`int`, *optional*, defaults to 3):
|
| 36 |
+
Each query is going to attend these many number of random blocks. Useful only when `attention_type ==
|
| 37 |
+
"block_sparse"`.
|
| 38 |
+
|
| 39 |
+
Example:
|
| 40 |
+
|
| 41 |
+
```python
|
| 42 |
+
>>> from transformers import BigBirdConfig, BigBirdModel
|
| 43 |
+
|
| 44 |
+
>>> # Initializing a BigBird google/bigbird-roberta-base style configuration
|
| 45 |
+
>>> configuration = BigBirdConfig()
|
| 46 |
+
|
| 47 |
+
>>> # Initializing a model (with random weights) from the google/bigbird-roberta-base style configuration
|
| 48 |
+
>>> model = BigBirdModel(configuration)
|
| 49 |
+
|
| 50 |
+
>>> # Accessing the model configuration
|
| 51 |
+
>>> configuration = model.config
|
| 52 |
+
```"""
|
| 53 |
+
|
| 54 |
+
model_type = "big_bird"
|
| 55 |
+
|
| 56 |
+
vocab_size: int = 50358
|
| 57 |
+
hidden_size: int = 768
|
| 58 |
+
num_hidden_layers: int = 12
|
| 59 |
+
num_attention_heads: int = 12
|
| 60 |
+
intermediate_size: int = 3072
|
| 61 |
+
hidden_act: str = "gelu_new"
|
| 62 |
+
hidden_dropout_prob: float | int = 0.1
|
| 63 |
+
attention_probs_dropout_prob: float | int = 0.1
|
| 64 |
+
max_position_embeddings: int = 4096
|
| 65 |
+
type_vocab_size: int = 2
|
| 66 |
+
initializer_range: float = 0.02
|
| 67 |
+
layer_norm_eps: float = 1e-12
|
| 68 |
+
use_cache: bool = True
|
| 69 |
+
pad_token_id: int | None = 0
|
| 70 |
+
bos_token_id: int | None = 1
|
| 71 |
+
eos_token_id: int | list[int] | None = 2
|
| 72 |
+
sep_token_id: int | None = 66
|
| 73 |
+
attention_type: str = "block_sparse"
|
| 74 |
+
use_bias: bool = True
|
| 75 |
+
rescale_embeddings: bool = False
|
| 76 |
+
block_size: int = 64
|
| 77 |
+
num_random_blocks: int = 3
|
| 78 |
+
classifier_dropout: float | int | None = None
|
| 79 |
+
is_decoder: bool = False
|
| 80 |
+
add_cross_attention: bool = False
|
| 81 |
+
tie_word_embeddings: bool = True
|
| 82 |
+
|
| 83 |
+
|
| 84 |
+
__all__ = ["BigBirdConfig"]
|
third_party/transformers/src/transformers/models/big_bird/convert_bigbird_original_tf_checkpoint_to_pytorch.py
ADDED
|
@@ -0,0 +1,251 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright 2021 The HuggingFace Inc. team.
|
| 2 |
+
#
|
| 3 |
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
| 4 |
+
# you may not use this file except in compliance with the License.
|
| 5 |
+
# You may obtain a copy of the License at
|
| 6 |
+
#
|
| 7 |
+
# http://www.apache.org/licenses/LICENSE-2.0
|
| 8 |
+
#
|
| 9 |
+
# Unless required by applicable law or agreed to in writing, software
|
| 10 |
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
| 11 |
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 12 |
+
# See the License for the specific language governing permissions and
|
| 13 |
+
# limitations under the License.
|
| 14 |
+
"""Convert BigBird checkpoint."""
|
| 15 |
+
|
| 16 |
+
import argparse
|
| 17 |
+
import math
|
| 18 |
+
import os
|
| 19 |
+
|
| 20 |
+
import torch
|
| 21 |
+
|
| 22 |
+
from transformers import BigBirdConfig, BigBirdForPreTraining, BigBirdForQuestionAnswering
|
| 23 |
+
from transformers.utils import logging
|
| 24 |
+
|
| 25 |
+
|
| 26 |
+
logger = logging.get_logger(__name__)
|
| 27 |
+
logging.set_verbosity_info()
|
| 28 |
+
|
| 29 |
+
|
| 30 |
+
_TRIVIA_QA_MAPPING = {
|
| 31 |
+
"big_bird_attention": "attention/self",
|
| 32 |
+
"output_layer_norm": "output/LayerNorm",
|
| 33 |
+
"attention_output": "attention/output/dense",
|
| 34 |
+
"output": "output/dense",
|
| 35 |
+
"self_attention_layer_norm": "attention/output/LayerNorm",
|
| 36 |
+
"intermediate": "intermediate/dense",
|
| 37 |
+
"word_embeddings": "bert/embeddings/word_embeddings",
|
| 38 |
+
"position_embedding": "bert/embeddings/position_embeddings",
|
| 39 |
+
"type_embeddings": "bert/embeddings/token_type_embeddings",
|
| 40 |
+
"embeddings": "bert/embeddings",
|
| 41 |
+
"layer_normalization": "output/LayerNorm",
|
| 42 |
+
"layer_norm": "LayerNorm",
|
| 43 |
+
"trivia_qa_head": "qa_classifier",
|
| 44 |
+
"dense": "intermediate/dense",
|
| 45 |
+
"dense_1": "qa_outputs",
|
| 46 |
+
}
|
| 47 |
+
|
| 48 |
+
|
| 49 |
+
def load_tf_weights_in_big_bird(model, tf_checkpoint_path, is_trivia_qa=False):
|
| 50 |
+
"""Load tf checkpoints in a pytorch model."""
|
| 51 |
+
|
| 52 |
+
def load_tf_weights_bert(init_vars, tf_path):
|
| 53 |
+
names = []
|
| 54 |
+
tf_weights = {}
|
| 55 |
+
|
| 56 |
+
for name, shape in init_vars:
|
| 57 |
+
array = tf.train.load_variable(tf_path, name)
|
| 58 |
+
name = name.replace("bert/encoder/LayerNorm", "bert/embeddings/LayerNorm")
|
| 59 |
+
logger.info(f"Loading TF weight {name} with shape {shape}")
|
| 60 |
+
names.append(name)
|
| 61 |
+
tf_weights[name] = array
|
| 62 |
+
|
| 63 |
+
return names, tf_weights
|
| 64 |
+
|
| 65 |
+
def load_tf_weights_trivia_qa(init_vars):
|
| 66 |
+
names = []
|
| 67 |
+
tf_weights = {}
|
| 68 |
+
|
| 69 |
+
for i, var in enumerate(init_vars):
|
| 70 |
+
name_items = var.name.split("/")
|
| 71 |
+
|
| 72 |
+
if "transformer_scaffold" in name_items[0]:
|
| 73 |
+
layer_name_items = name_items[0].split("_")
|
| 74 |
+
if len(layer_name_items) < 3:
|
| 75 |
+
layer_name_items += [0]
|
| 76 |
+
|
| 77 |
+
name_items[0] = f"bert/encoder/layer_{layer_name_items[2]}"
|
| 78 |
+
|
| 79 |
+
name = "/".join([_TRIVIA_QA_MAPPING.get(x, x) for x in name_items])[:-2] # remove last :0 in variable
|
| 80 |
+
|
| 81 |
+
if "self/attention/output" in name:
|
| 82 |
+
name = name.replace("self/attention/output", "output")
|
| 83 |
+
|
| 84 |
+
if i >= len(init_vars) - 2:
|
| 85 |
+
name = name.replace("intermediate", "output")
|
| 86 |
+
|
| 87 |
+
logger.info(f"Loading TF weight {name} with shape {var.shape}")
|
| 88 |
+
array = var.value().numpy()
|
| 89 |
+
names.append(name)
|
| 90 |
+
tf_weights[name] = array
|
| 91 |
+
|
| 92 |
+
return names, tf_weights
|
| 93 |
+
|
| 94 |
+
try:
|
| 95 |
+
import re
|
| 96 |
+
|
| 97 |
+
import numpy as np
|
| 98 |
+
import tensorflow as tf
|
| 99 |
+
except ImportError:
|
| 100 |
+
logger.error(
|
| 101 |
+
"Loading a TensorFlow model in PyTorch, requires TensorFlow to be installed. Please see "
|
| 102 |
+
"https://www.tensorflow.org/install/ for installation instructions."
|
| 103 |
+
)
|
| 104 |
+
raise
|
| 105 |
+
tf_path = os.path.abspath(tf_checkpoint_path)
|
| 106 |
+
logger.info(f"Converting TensorFlow checkpoint from {tf_path}")
|
| 107 |
+
|
| 108 |
+
# Load weights from TF model
|
| 109 |
+
init_vars = tf.saved_model.load(tf_path).variables if is_trivia_qa else tf.train.list_variables(tf_path)
|
| 110 |
+
|
| 111 |
+
if len(init_vars) <= 0:
|
| 112 |
+
raise ValueError("Loaded trained variables cannot be empty.")
|
| 113 |
+
|
| 114 |
+
pt_names = list(model.state_dict().keys())
|
| 115 |
+
|
| 116 |
+
if is_trivia_qa:
|
| 117 |
+
names, tf_weights = load_tf_weights_trivia_qa(init_vars)
|
| 118 |
+
else:
|
| 119 |
+
names, tf_weights = load_tf_weights_bert(init_vars, tf_path)
|
| 120 |
+
|
| 121 |
+
for txt_name in names:
|
| 122 |
+
array = tf_weights[txt_name]
|
| 123 |
+
name = txt_name.split("/")
|
| 124 |
+
# adam_v and adam_m are variables used in AdamWeightDecayOptimizer to calculated m and v
|
| 125 |
+
# which are not required for using pretrained model
|
| 126 |
+
if any(
|
| 127 |
+
n in ["adam_v", "adam_m", "AdamWeightDecayOptimizer", "AdamWeightDecayOptimizer_1", "global_step"]
|
| 128 |
+
for n in name
|
| 129 |
+
):
|
| 130 |
+
logger.info(f"Skipping {'/'.join(name)}")
|
| 131 |
+
continue
|
| 132 |
+
pointer = model
|
| 133 |
+
pt_name = []
|
| 134 |
+
for m_name in name:
|
| 135 |
+
if re.fullmatch(r"[A-Za-z]+_\d+", m_name):
|
| 136 |
+
scope_names = re.split(r"_(\d+)", m_name)
|
| 137 |
+
else:
|
| 138 |
+
scope_names = [m_name]
|
| 139 |
+
if scope_names[0] == "kernel" or scope_names[0] == "gamma":
|
| 140 |
+
pointer = getattr(pointer, "weight")
|
| 141 |
+
pt_name.append("weight")
|
| 142 |
+
elif scope_names[0] == "output_bias" or scope_names[0] == "beta":
|
| 143 |
+
pointer = getattr(pointer, "bias")
|
| 144 |
+
pt_name.append("bias")
|
| 145 |
+
elif scope_names[0] == "output_weights":
|
| 146 |
+
pointer = getattr(pointer, "weight")
|
| 147 |
+
pt_name.append("weight")
|
| 148 |
+
elif scope_names[0] == "squad":
|
| 149 |
+
pointer = getattr(pointer, "classifier")
|
| 150 |
+
pt_name.append("classifier")
|
| 151 |
+
elif scope_names[0] == "transform":
|
| 152 |
+
pointer = getattr(pointer, "transform")
|
| 153 |
+
pt_name.append("transform")
|
| 154 |
+
if ("bias" in name) or ("kernel" in name):
|
| 155 |
+
pointer = getattr(pointer, "dense")
|
| 156 |
+
pt_name.append("dense")
|
| 157 |
+
elif ("beta" in name) or ("gamma" in name):
|
| 158 |
+
pointer = getattr(pointer, "LayerNorm")
|
| 159 |
+
pt_name.append("LayerNorm")
|
| 160 |
+
else:
|
| 161 |
+
try:
|
| 162 |
+
pointer = getattr(pointer, scope_names[0])
|
| 163 |
+
pt_name.append(f"{scope_names[0]}")
|
| 164 |
+
except AttributeError:
|
| 165 |
+
logger.info(f"Skipping {m_name}")
|
| 166 |
+
continue
|
| 167 |
+
if len(scope_names) >= 2:
|
| 168 |
+
num = int(scope_names[1])
|
| 169 |
+
pointer = pointer[num]
|
| 170 |
+
pt_name.append(f"{num}")
|
| 171 |
+
if m_name[-11:] == "_embeddings" or m_name == "embeddings":
|
| 172 |
+
pointer = getattr(pointer, "weight")
|
| 173 |
+
pt_name.append("weight")
|
| 174 |
+
elif m_name == "kernel":
|
| 175 |
+
array = np.transpose(array)
|
| 176 |
+
try:
|
| 177 |
+
if len(array.shape) > len(pointer.shape) and math.prod(array.shape) == math.prod(pointer.shape):
|
| 178 |
+
# print(txt_name, array.shape)
|
| 179 |
+
if (
|
| 180 |
+
txt_name.endswith("attention/self/key/kernel")
|
| 181 |
+
or txt_name.endswith("attention/self/query/kernel")
|
| 182 |
+
or txt_name.endswith("attention/self/value/kernel")
|
| 183 |
+
):
|
| 184 |
+
array = array.transpose(1, 0, 2).reshape(pointer.shape)
|
| 185 |
+
elif txt_name.endswith("attention/output/dense/kernel"):
|
| 186 |
+
array = array.transpose(0, 2, 1).reshape(pointer.shape)
|
| 187 |
+
else:
|
| 188 |
+
array = array.reshape(pointer.shape)
|
| 189 |
+
|
| 190 |
+
if pointer.shape != array.shape:
|
| 191 |
+
raise ValueError(
|
| 192 |
+
f"Pointer shape {pointer.shape} and array shape {array.shape} mismatched of {txt_name}."
|
| 193 |
+
)
|
| 194 |
+
except ValueError as e:
|
| 195 |
+
e.args += (pointer.shape, array.shape)
|
| 196 |
+
raise
|
| 197 |
+
pt_weight_name = ".".join(pt_name)
|
| 198 |
+
logger.info(f"Initialize PyTorch weight {pt_weight_name} from {txt_name}.")
|
| 199 |
+
pointer.data = torch.from_numpy(array)
|
| 200 |
+
tf_weights.pop(txt_name, None)
|
| 201 |
+
pt_names.remove(pt_weight_name)
|
| 202 |
+
|
| 203 |
+
logger.info(f"Weights not copied to PyTorch model: {', '.join(tf_weights.keys())}.")
|
| 204 |
+
logger.info(f"Weights not initialized in PyTorch model: {', '.join(pt_names)}.")
|
| 205 |
+
return model
|
| 206 |
+
|
| 207 |
+
|
| 208 |
+
def convert_tf_checkpoint_to_pytorch(tf_checkpoint_path, big_bird_config_file, pytorch_dump_path, is_trivia_qa):
|
| 209 |
+
# Initialise PyTorch model
|
| 210 |
+
config = BigBirdConfig.from_json_file(big_bird_config_file)
|
| 211 |
+
print(f"Building PyTorch model from configuration: {config}")
|
| 212 |
+
|
| 213 |
+
if is_trivia_qa:
|
| 214 |
+
model = BigBirdForQuestionAnswering(config)
|
| 215 |
+
else:
|
| 216 |
+
model = BigBirdForPreTraining(config)
|
| 217 |
+
|
| 218 |
+
# Load weights from tf checkpoint
|
| 219 |
+
load_tf_weights_in_big_bird(model, tf_checkpoint_path, is_trivia_qa=is_trivia_qa)
|
| 220 |
+
|
| 221 |
+
# Save pytorch-model
|
| 222 |
+
print(f"Save PyTorch model to {pytorch_dump_path}")
|
| 223 |
+
model.save_pretrained(pytorch_dump_path)
|
| 224 |
+
|
| 225 |
+
|
| 226 |
+
if __name__ == "__main__":
|
| 227 |
+
parser = argparse.ArgumentParser()
|
| 228 |
+
# Required parameters
|
| 229 |
+
parser.add_argument(
|
| 230 |
+
"--tf_checkpoint_path", default=None, type=str, required=True, help="Path to the TensorFlow checkpoint path."
|
| 231 |
+
)
|
| 232 |
+
parser.add_argument(
|
| 233 |
+
"--big_bird_config_file",
|
| 234 |
+
default=None,
|
| 235 |
+
type=str,
|
| 236 |
+
required=True,
|
| 237 |
+
help=(
|
| 238 |
+
"The config json file corresponding to the pre-trained BERT model. \n"
|
| 239 |
+
"This specifies the model architecture."
|
| 240 |
+
),
|
| 241 |
+
)
|
| 242 |
+
parser.add_argument(
|
| 243 |
+
"--pytorch_dump_path", default=None, type=str, required=True, help="Path to the output PyTorch model."
|
| 244 |
+
)
|
| 245 |
+
parser.add_argument(
|
| 246 |
+
"--is_trivia_qa", action="store_true", help="Whether to convert a model with a trivia_qa head."
|
| 247 |
+
)
|
| 248 |
+
args = parser.parse_args()
|
| 249 |
+
convert_tf_checkpoint_to_pytorch(
|
| 250 |
+
args.tf_checkpoint_path, args.big_bird_config_file, args.pytorch_dump_path, args.is_trivia_qa
|
| 251 |
+
)
|
third_party/transformers/src/transformers/models/big_bird/modeling_big_bird.py
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
third_party/transformers/src/transformers/models/big_bird/tokenization_big_bird.py
ADDED
|
@@ -0,0 +1,151 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright 2018 Google AI, Google Brain and the HuggingFace Inc. team.
|
| 2 |
+
#
|
| 3 |
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
| 4 |
+
# you may not use this file except in compliance with the License.
|
| 5 |
+
# You may obtain a copy of the License at
|
| 6 |
+
#
|
| 7 |
+
# http://www.apache.org/licenses/LICENSE-2.0
|
| 8 |
+
#
|
| 9 |
+
# Unless required by applicable law or agreed to in writing, software
|
| 10 |
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
| 11 |
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 12 |
+
# See the License for the specific language governing permissions and
|
| 13 |
+
# limitations under the License.
|
| 14 |
+
"""Tokenization classes for Big Bird model."""
|
| 15 |
+
|
| 16 |
+
from tokenizers import Regex, Tokenizer, decoders, normalizers, pre_tokenizers, processors
|
| 17 |
+
from tokenizers.models import Unigram
|
| 18 |
+
|
| 19 |
+
from ...tokenization_python import AddedToken
|
| 20 |
+
from ...tokenization_utils_tokenizers import TokenizersBackend
|
| 21 |
+
from ...utils import logging
|
| 22 |
+
|
| 23 |
+
|
| 24 |
+
logger = logging.get_logger(__name__)
|
| 25 |
+
VOCAB_FILES_NAMES = {"vocab_file": "spiece.model", "tokenizer_file": "tokenizer.json"}
|
| 26 |
+
|
| 27 |
+
|
| 28 |
+
SPIECE_UNDERLINE = "▁"
|
| 29 |
+
|
| 30 |
+
|
| 31 |
+
class BigBirdTokenizer(TokenizersBackend):
|
| 32 |
+
"""
|
| 33 |
+
Construct a "fast" BigBird tokenizer (backed by HuggingFace's *tokenizers* library). Based on
|
| 34 |
+
[Unigram](https://huggingface.co/docs/tokenizers/python/latest/components.html?highlight=unigram#models). This
|
| 35 |
+
tokenizer inherits from [`PreTrainedTokenizerFast`] which contains most of the main methods. Users should refer to
|
| 36 |
+
this superclass for more information regarding those methods
|
| 37 |
+
|
| 38 |
+
Args:
|
| 39 |
+
vocab (`str`, `dict` or `list`, *optional*):
|
| 40 |
+
Custom vocabulary dictionary. If not provided, vocabulary is loaded from vocab_file.
|
| 41 |
+
unk_token (`str`, *optional*, defaults to `"<unk>"`):
|
| 42 |
+
The unknown token. A token that is not in the vocabulary cannot be converted to an ID and is set to be this
|
| 43 |
+
token instead.
|
| 44 |
+
bos_token (`str`, *optional*, defaults to `"<s>"`):
|
| 45 |
+
The beginning of sequence token that was used during pretraining. Can be used a sequence classifier token.
|
| 46 |
+
|
| 47 |
+
<Tip>
|
| 48 |
+
|
| 49 |
+
When building a sequence using special tokens, this is not the token that is used for the beginning of
|
| 50 |
+
sequence. The token used is the `cls_token`.
|
| 51 |
+
|
| 52 |
+
</Tip>
|
| 53 |
+
|
| 54 |
+
eos_token (`str`, *optional*, defaults to `"</s>"`):
|
| 55 |
+
The end of sequence token. .. note:: When building a sequence using special tokens, this is not the token
|
| 56 |
+
that is used for the end of sequence. The token used is the `sep_token`.
|
| 57 |
+
pad_token (`str`, *optional*, defaults to `"<pad>"`):
|
| 58 |
+
The token used for padding, for example when batching sequences of different lengths.
|
| 59 |
+
sep_token (`str`, *optional*, defaults to `"[SEP]"`):
|
| 60 |
+
The separator token, which is used when building a sequence from multiple sequences, e.g. two sequences for
|
| 61 |
+
sequence classification or for a text and a question for question answering. It is also used as the last
|
| 62 |
+
token of a sequence built with special tokens.
|
| 63 |
+
mask_token (`str`, *optional*, defaults to `"[MASK]"`):
|
| 64 |
+
The token used for masking values. This is the token used when training this model with masked language
|
| 65 |
+
modeling. This is the token which the model will try to predict.
|
| 66 |
+
cls_token (`str`, *optional*, defaults to `"[CLS]"`):
|
| 67 |
+
The classifier token which is used when doing sequence classification (classification of the whole sequence
|
| 68 |
+
instead of per-token classification). It is the first token of the sequence when built with special tokens.
|
| 69 |
+
add_prefix_space (`bool`, *optional*, defaults to `True`):
|
| 70 |
+
Whether or not to add an initial space to the input. This allows to treat the leading word just as any
|
| 71 |
+
other word.
|
| 72 |
+
vocab_file (`str`, *optional*):
|
| 73 |
+
[SentencePiece](https://github.com/google/sentencepiece) file (generally has a *.spm* extension) that
|
| 74 |
+
contains the vocabulary necessary to instantiate a tokenizer.
|
| 75 |
+
tokenizer_file (`str`, *optional*):
|
| 76 |
+
Path to a tokenizers JSON file containing the serialization of a tokenizer.
|
| 77 |
+
"""
|
| 78 |
+
|
| 79 |
+
vocab_files_names = VOCAB_FILES_NAMES
|
| 80 |
+
model_input_names = ["input_ids", "attention_mask"]
|
| 81 |
+
prefix_tokens: list[int] = []
|
| 82 |
+
model = Unigram
|
| 83 |
+
|
| 84 |
+
def __init__(
|
| 85 |
+
self,
|
| 86 |
+
vocab: str | dict | list | None = None,
|
| 87 |
+
unk_token="<unk>",
|
| 88 |
+
bos_token="<s>",
|
| 89 |
+
eos_token="</s>",
|
| 90 |
+
pad_token="<pad>",
|
| 91 |
+
sep_token="[SEP]",
|
| 92 |
+
mask_token="[MASK]",
|
| 93 |
+
cls_token="[CLS]",
|
| 94 |
+
add_prefix_space=True,
|
| 95 |
+
**kwargs,
|
| 96 |
+
):
|
| 97 |
+
bos_token = AddedToken(bos_token, lstrip=False, rstrip=False) if isinstance(bos_token, str) else bos_token
|
| 98 |
+
eos_token = AddedToken(eos_token, lstrip=False, rstrip=False) if isinstance(eos_token, str) else eos_token
|
| 99 |
+
unk_token = AddedToken(unk_token, lstrip=False, rstrip=False) if isinstance(unk_token, str) else unk_token
|
| 100 |
+
pad_token = AddedToken(pad_token, lstrip=False, rstrip=False) if isinstance(pad_token, str) else pad_token
|
| 101 |
+
cls_token = AddedToken(cls_token, lstrip=False, rstrip=False) if isinstance(cls_token, str) else cls_token
|
| 102 |
+
sep_token = AddedToken(sep_token, lstrip=False, rstrip=False) if isinstance(sep_token, str) else sep_token
|
| 103 |
+
mask_token = AddedToken(mask_token, lstrip=True, rstrip=False) if isinstance(mask_token, str) else mask_token
|
| 104 |
+
|
| 105 |
+
self.add_prefix_space = add_prefix_space
|
| 106 |
+
|
| 107 |
+
# Convert vocab to list of (token, score) tuples
|
| 108 |
+
if vocab is None:
|
| 109 |
+
vocab = [(str(pad_token), 0.0), (str(eos_token), 0.0), (str(bos_token), 0.0), (str(unk_token), 0.0)]
|
| 110 |
+
unk_id = 3
|
| 111 |
+
elif isinstance(vocab, list):
|
| 112 |
+
# vocab.insert(100, (str(unk_token), 0.0)) # Ensure unk_token is in vocab at index 100
|
| 113 |
+
unk_id = vocab.index((str(unk_token), 0.0)) if (str(unk_token), 0.0) in vocab else 100
|
| 114 |
+
|
| 115 |
+
self._tokenizer = Tokenizer(Unigram(vocab, unk_id=unk_id, byte_fallback=False))
|
| 116 |
+
self._tokenizer.normalizer = normalizers.Sequence(
|
| 117 |
+
[normalizers.Strip(left=False, right=False), normalizers.Replace(Regex(r" {2,}"), SPIECE_UNDERLINE)]
|
| 118 |
+
)
|
| 119 |
+
|
| 120 |
+
prepend_scheme = "always" if add_prefix_space else "never"
|
| 121 |
+
self._tokenizer.pre_tokenizer = pre_tokenizers.Metaspace(
|
| 122 |
+
replacement="▁", prepend_scheme=prepend_scheme, split=True
|
| 123 |
+
)
|
| 124 |
+
self._tokenizer.decoder = decoders.Metaspace(replacement="▁", prepend_scheme=prepend_scheme, split=True)
|
| 125 |
+
|
| 126 |
+
super().__init__(
|
| 127 |
+
bos_token=bos_token,
|
| 128 |
+
eos_token=eos_token,
|
| 129 |
+
unk_token=unk_token,
|
| 130 |
+
pad_token=pad_token,
|
| 131 |
+
mask_token=mask_token,
|
| 132 |
+
cls_token=cls_token,
|
| 133 |
+
sep_token=sep_token,
|
| 134 |
+
add_prefix_space=add_prefix_space,
|
| 135 |
+
**kwargs,
|
| 136 |
+
)
|
| 137 |
+
|
| 138 |
+
# Ensure cls_token and sep_token are in vocab
|
| 139 |
+
cls_token_str = str(cls_token)
|
| 140 |
+
sep_token_str = str(sep_token)
|
| 141 |
+
cls_token_id = self.cls_token_id
|
| 142 |
+
sep_token_id = self.sep_token_id
|
| 143 |
+
|
| 144 |
+
self._tokenizer.post_processor = processors.TemplateProcessing(
|
| 145 |
+
single=f"{cls_token_str}:0 $A:0 {sep_token_str}:0",
|
| 146 |
+
pair=f"{cls_token_str}:0 $A:0 {sep_token_str}:0 $B:1 {sep_token_str}:1",
|
| 147 |
+
special_tokens=[(cls_token_str, cls_token_id), (sep_token_str, sep_token_id)],
|
| 148 |
+
)
|
| 149 |
+
|
| 150 |
+
|
| 151 |
+
__all__ = ["BigBirdTokenizer"]
|
third_party/transformers/src/transformers/models/bigbird_pegasus/__init__.py
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright 2024 The HuggingFace Team. All rights reserved.
|
| 2 |
+
#
|
| 3 |
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
| 4 |
+
# you may not use this file except in compliance with the License.
|
| 5 |
+
# You may obtain a copy of the License at
|
| 6 |
+
#
|
| 7 |
+
# http://www.apache.org/licenses/LICENSE-2.0
|
| 8 |
+
#
|
| 9 |
+
# Unless required by applicable law or agreed to in writing, software
|
| 10 |
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
| 11 |
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 12 |
+
# See the License for the specific language governing permissions and
|
| 13 |
+
# limitations under the License.
|
| 14 |
+
from typing import TYPE_CHECKING
|
| 15 |
+
|
| 16 |
+
from ...utils import _LazyModule
|
| 17 |
+
from ...utils.import_utils import define_import_structure
|
| 18 |
+
|
| 19 |
+
|
| 20 |
+
if TYPE_CHECKING:
|
| 21 |
+
from .configuration_bigbird_pegasus import *
|
| 22 |
+
from .modeling_bigbird_pegasus import *
|
| 23 |
+
else:
|
| 24 |
+
import sys
|
| 25 |
+
|
| 26 |
+
_file = globals()["__file__"]
|
| 27 |
+
sys.modules[__name__] = _LazyModule(__name__, _file, define_import_structure(_file), module_spec=__spec__)
|
third_party/transformers/src/transformers/models/bigbird_pegasus/configuration_bigbird_pegasus.py
ADDED
|
@@ -0,0 +1,93 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright Google Research and The HuggingFace Inc. team. All rights reserved.
|
| 2 |
+
#
|
| 3 |
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
| 4 |
+
# you may not use this file except in compliance with the License.
|
| 5 |
+
# You may obtain a copy of the License at
|
| 6 |
+
#
|
| 7 |
+
# http://www.apache.org/licenses/LICENSE-2.0
|
| 8 |
+
#
|
| 9 |
+
# Unless required by applicable law or agreed to in writing, software
|
| 10 |
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
| 11 |
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 12 |
+
# See the License for the specific language governing permissions and
|
| 13 |
+
# limitations under the License.
|
| 14 |
+
"""BigBirdPegasus model configuration"""
|
| 15 |
+
|
| 16 |
+
from huggingface_hub.dataclasses import strict
|
| 17 |
+
|
| 18 |
+
from ...configuration_utils import PreTrainedConfig
|
| 19 |
+
from ...utils import auto_docstring
|
| 20 |
+
|
| 21 |
+
|
| 22 |
+
@auto_docstring(checkpoint="google/bigbird-pegasus-large-arxiv")
|
| 23 |
+
@strict
|
| 24 |
+
class BigBirdPegasusConfig(PreTrainedConfig):
|
| 25 |
+
r"""
|
| 26 |
+
attention_type (`str`, *optional*, defaults to `"block_sparse"`):
|
| 27 |
+
Whether to use block sparse attention (with n complexity) as introduced in paper or original attention
|
| 28 |
+
layer (with n^2 complexity). Possible values are `"original_full"` and `"block_sparse"`.
|
| 29 |
+
block_size (`int`, *optional*, defaults to 64):
|
| 30 |
+
Size of each block. Useful only when `attention_type == "block_sparse"`.
|
| 31 |
+
num_random_blocks (`int`, *optional*, defaults to 3):
|
| 32 |
+
Each query is going to attend these many number of random blocks. Useful only when `attention_type ==
|
| 33 |
+
"block_sparse"`.
|
| 34 |
+
use_bias (`bool`, *optional*, defaults to `True`):
|
| 35 |
+
Whether to use bias in query, key, value.
|
| 36 |
+
|
| 37 |
+
Example:
|
| 38 |
+
|
| 39 |
+
```python
|
| 40 |
+
>>> from transformers import BigBirdPegasusConfig, BigBirdPegasusModel
|
| 41 |
+
|
| 42 |
+
>>> # Initializing a BigBirdPegasus bigbird-pegasus-base style configuration
|
| 43 |
+
>>> configuration = BigBirdPegasusConfig()
|
| 44 |
+
|
| 45 |
+
>>> # Initializing a model (with random weights) from the bigbird-pegasus-base style configuration
|
| 46 |
+
>>> model = BigBirdPegasusModel(configuration)
|
| 47 |
+
|
| 48 |
+
>>> # Accessing the model configuration
|
| 49 |
+
>>> configuration = model.config
|
| 50 |
+
```"""
|
| 51 |
+
|
| 52 |
+
model_type = "bigbird_pegasus"
|
| 53 |
+
keys_to_ignore_at_inference = ["past_key_values"]
|
| 54 |
+
attribute_map = {
|
| 55 |
+
"num_attention_heads": "encoder_attention_heads",
|
| 56 |
+
"hidden_size": "d_model",
|
| 57 |
+
"attention_probs_dropout_prob": "attention_dropout",
|
| 58 |
+
"num_hidden_layers": "encoder_layers",
|
| 59 |
+
}
|
| 60 |
+
|
| 61 |
+
vocab_size: int = 96103
|
| 62 |
+
max_position_embeddings: int = 4096
|
| 63 |
+
encoder_layers: int = 16
|
| 64 |
+
encoder_ffn_dim: int = 4096
|
| 65 |
+
encoder_attention_heads: int = 16
|
| 66 |
+
decoder_layers: int = 16
|
| 67 |
+
decoder_ffn_dim: int = 4096
|
| 68 |
+
decoder_attention_heads: int = 16
|
| 69 |
+
encoder_layerdrop: float | int = 0.0
|
| 70 |
+
decoder_layerdrop: float | int = 0.0
|
| 71 |
+
use_cache: bool = True
|
| 72 |
+
is_encoder_decoder: bool = True
|
| 73 |
+
activation_function: str = "gelu_new"
|
| 74 |
+
d_model: int = 1024
|
| 75 |
+
dropout: float | int = 0.1
|
| 76 |
+
attention_dropout: float | int = 0.0
|
| 77 |
+
activation_dropout: float | int = 0.0
|
| 78 |
+
init_std: float = 0.02
|
| 79 |
+
decoder_start_token_id: int = 2
|
| 80 |
+
classifier_dropout: float | int = 0.0
|
| 81 |
+
scale_embedding: bool = True
|
| 82 |
+
pad_token_id: int | None = 0
|
| 83 |
+
bos_token_id: int | None = 2
|
| 84 |
+
eos_token_id: int | list[int] | None = 1
|
| 85 |
+
attention_type: str = "block_sparse" # only for encoder
|
| 86 |
+
block_size: int = 64
|
| 87 |
+
num_random_blocks: int = 3
|
| 88 |
+
use_bias: bool = False
|
| 89 |
+
is_decoder: bool = False
|
| 90 |
+
tie_word_embeddings: bool = True
|
| 91 |
+
|
| 92 |
+
|
| 93 |
+
__all__ = ["BigBirdPegasusConfig"]
|
third_party/transformers/src/transformers/models/bigbird_pegasus/convert_bigbird_pegasus_tf_to_pytorch.py
ADDED
|
@@ -0,0 +1,168 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright 2021 The HuggingFace Inc. team.
|
| 2 |
+
#
|
| 3 |
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
| 4 |
+
# you may not use this file except in compliance with the License.
|
| 5 |
+
# You may obtain a copy of the License at
|
| 6 |
+
#
|
| 7 |
+
# http://www.apache.org/licenses/LICENSE-2.0
|
| 8 |
+
#
|
| 9 |
+
# Unless required by applicable law or agreed to in writing, software
|
| 10 |
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
| 11 |
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 12 |
+
# See the License for the specific language governing permissions and
|
| 13 |
+
# limitations under the License.
|
| 14 |
+
|
| 15 |
+
import argparse
|
| 16 |
+
|
| 17 |
+
import tensorflow as tf
|
| 18 |
+
import torch
|
| 19 |
+
from tqdm import tqdm
|
| 20 |
+
|
| 21 |
+
from transformers import BigBirdPegasusConfig, BigBirdPegasusForConditionalGeneration
|
| 22 |
+
|
| 23 |
+
|
| 24 |
+
INIT_COMMON = [
|
| 25 |
+
# tf -> hf
|
| 26 |
+
("/", "."),
|
| 27 |
+
("layer_", "layers."),
|
| 28 |
+
("kernel", "weight"),
|
| 29 |
+
("beta", "bias"),
|
| 30 |
+
("gamma", "weight"),
|
| 31 |
+
("pegasus", "model"),
|
| 32 |
+
]
|
| 33 |
+
END_COMMON = [
|
| 34 |
+
(".output.dense", ".fc2"),
|
| 35 |
+
("intermediate.LayerNorm", "final_layer_norm"),
|
| 36 |
+
("intermediate.dense", "fc1"),
|
| 37 |
+
]
|
| 38 |
+
|
| 39 |
+
DECODER_PATTERNS = (
|
| 40 |
+
INIT_COMMON
|
| 41 |
+
+ [
|
| 42 |
+
("attention.self.LayerNorm", "self_attn_layer_norm"),
|
| 43 |
+
("attention.output.dense", "self_attn.out_proj"),
|
| 44 |
+
("attention.self", "self_attn"),
|
| 45 |
+
("attention.encdec.LayerNorm", "encoder_attn_layer_norm"),
|
| 46 |
+
("attention.encdec_output.dense", "encoder_attn.out_proj"),
|
| 47 |
+
("attention.encdec", "encoder_attn"),
|
| 48 |
+
("key", "k_proj"),
|
| 49 |
+
("value", "v_proj"),
|
| 50 |
+
("query", "q_proj"),
|
| 51 |
+
("decoder.LayerNorm", "decoder.layernorm_embedding"),
|
| 52 |
+
]
|
| 53 |
+
+ END_COMMON
|
| 54 |
+
)
|
| 55 |
+
|
| 56 |
+
REMAINING_PATTERNS = (
|
| 57 |
+
INIT_COMMON
|
| 58 |
+
+ [
|
| 59 |
+
("embeddings.word_embeddings", "shared.weight"),
|
| 60 |
+
("embeddings.position_embeddings", "embed_positions.weight"),
|
| 61 |
+
("attention.self.LayerNorm", "self_attn_layer_norm"),
|
| 62 |
+
("attention.output.dense", "self_attn.output"),
|
| 63 |
+
("attention.self", "self_attn.self"),
|
| 64 |
+
("encoder.LayerNorm", "encoder.layernorm_embedding"),
|
| 65 |
+
]
|
| 66 |
+
+ END_COMMON
|
| 67 |
+
)
|
| 68 |
+
|
| 69 |
+
KEYS_TO_IGNORE = [
|
| 70 |
+
"encdec/key/bias",
|
| 71 |
+
"encdec/query/bias",
|
| 72 |
+
"encdec/value/bias",
|
| 73 |
+
"self/key/bias",
|
| 74 |
+
"self/query/bias",
|
| 75 |
+
"self/value/bias",
|
| 76 |
+
"encdec_output/dense/bias",
|
| 77 |
+
"attention/output/dense/bias",
|
| 78 |
+
]
|
| 79 |
+
|
| 80 |
+
|
| 81 |
+
def rename_state_dict_key(k, patterns):
|
| 82 |
+
for tf_name, hf_name in patterns:
|
| 83 |
+
k = k.replace(tf_name, hf_name)
|
| 84 |
+
return k
|
| 85 |
+
|
| 86 |
+
|
| 87 |
+
def convert_bigbird_pegasus(tf_weights: dict, config_update: dict) -> BigBirdPegasusForConditionalGeneration:
|
| 88 |
+
cfg = BigBirdPegasusConfig(**config_update)
|
| 89 |
+
torch_model = BigBirdPegasusForConditionalGeneration(cfg)
|
| 90 |
+
state_dict = torch_model.state_dict()
|
| 91 |
+
mapping = {}
|
| 92 |
+
|
| 93 |
+
# separating decoder weights
|
| 94 |
+
decoder_weights = {k: tf_weights[k] for k in tf_weights if k.startswith("pegasus/decoder")}
|
| 95 |
+
remaining_weights = {k: tf_weights[k] for k in tf_weights if not k.startswith("pegasus/decoder")}
|
| 96 |
+
|
| 97 |
+
for k, v in tqdm(decoder_weights.items(), "tf -> hf conversion"):
|
| 98 |
+
conditions = [k.endswith(ending) for ending in KEYS_TO_IGNORE]
|
| 99 |
+
if any(conditions):
|
| 100 |
+
continue
|
| 101 |
+
patterns = DECODER_PATTERNS
|
| 102 |
+
new_k = rename_state_dict_key(k, patterns)
|
| 103 |
+
if new_k not in state_dict:
|
| 104 |
+
raise ValueError(f"could not find new key {new_k} in state dict. (converted from {k})")
|
| 105 |
+
if any(i in k for i in ["dense", "query", "key", "value"]):
|
| 106 |
+
v = v.T
|
| 107 |
+
mapping[new_k] = torch.from_numpy(v)
|
| 108 |
+
assert v.shape == state_dict[new_k].shape, f"{new_k}, {k}, {v.shape}, {state_dict[new_k].shape}"
|
| 109 |
+
|
| 110 |
+
for k, v in tqdm(remaining_weights.items(), "tf -> hf conversion"):
|
| 111 |
+
conditions = [k.endswith(ending) for ending in KEYS_TO_IGNORE]
|
| 112 |
+
if any(conditions):
|
| 113 |
+
continue
|
| 114 |
+
patterns = REMAINING_PATTERNS
|
| 115 |
+
new_k = rename_state_dict_key(k, patterns)
|
| 116 |
+
if new_k not in state_dict and k != "pegasus/embeddings/position_embeddings":
|
| 117 |
+
raise ValueError(f"could not find new key {new_k} in state dict. (converted from {k})")
|
| 118 |
+
if any(i in k for i in ["dense", "query", "key", "value"]):
|
| 119 |
+
v = v.T
|
| 120 |
+
mapping[new_k] = torch.from_numpy(v)
|
| 121 |
+
if k != "pegasus/embeddings/position_embeddings":
|
| 122 |
+
assert v.shape == state_dict[new_k].shape, f"{new_k}, {k}, {v.shape}, {state_dict[new_k].shape}"
|
| 123 |
+
|
| 124 |
+
mapping["model.encoder.embed_positions.weight"] = mapping["model.embed_positions.weight"]
|
| 125 |
+
mapping["model.decoder.embed_positions.weight"] = mapping.pop("model.embed_positions.weight")
|
| 126 |
+
missing, extra = torch_model.load_state_dict(mapping, strict=False)
|
| 127 |
+
unexpected_missing = [
|
| 128 |
+
k
|
| 129 |
+
for k in missing
|
| 130 |
+
if k
|
| 131 |
+
not in [
|
| 132 |
+
"final_logits_bias",
|
| 133 |
+
"model.encoder.embed_tokens.weight",
|
| 134 |
+
"model.decoder.embed_tokens.weight",
|
| 135 |
+
"lm_head.weight",
|
| 136 |
+
]
|
| 137 |
+
]
|
| 138 |
+
assert unexpected_missing == [], f"no matches found for the following torch keys {unexpected_missing}"
|
| 139 |
+
assert extra == [], f"no matches found for the following tf keys {extra}"
|
| 140 |
+
return torch_model
|
| 141 |
+
|
| 142 |
+
|
| 143 |
+
def get_tf_weights_as_numpy(path) -> dict:
|
| 144 |
+
init_vars = tf.train.list_variables(path)
|
| 145 |
+
tf_weights = {}
|
| 146 |
+
ignore_name = ["global_step"]
|
| 147 |
+
for name, shape in tqdm(init_vars, desc="converting tf checkpoint to dict"):
|
| 148 |
+
skip_key = any(pat in name for pat in ignore_name)
|
| 149 |
+
if skip_key:
|
| 150 |
+
continue
|
| 151 |
+
array = tf.train.load_variable(path, name)
|
| 152 |
+
tf_weights[name] = array
|
| 153 |
+
return tf_weights
|
| 154 |
+
|
| 155 |
+
|
| 156 |
+
def convert_bigbird_pegasus_ckpt_to_pytorch(ckpt_path: str, save_dir: str, config_update: dict):
|
| 157 |
+
tf_weights = get_tf_weights_as_numpy(ckpt_path)
|
| 158 |
+
torch_model = convert_bigbird_pegasus(tf_weights, config_update)
|
| 159 |
+
torch_model.save_pretrained(save_dir)
|
| 160 |
+
|
| 161 |
+
|
| 162 |
+
if __name__ == "__main__":
|
| 163 |
+
parser = argparse.ArgumentParser()
|
| 164 |
+
parser.add_argument("--tf_ckpt_path", type=str, help="passed to tf.train.list_variables")
|
| 165 |
+
parser.add_argument("--save_dir", default=None, type=str, help="Path to the output PyTorch model.")
|
| 166 |
+
args = parser.parse_args()
|
| 167 |
+
config_update = {}
|
| 168 |
+
convert_bigbird_pegasus_ckpt_to_pytorch(args.tf_ckpt_path, args.save_dir, config_update=config_update)
|
third_party/transformers/src/transformers/models/bigbird_pegasus/modeling_bigbird_pegasus.py
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
third_party/transformers/src/transformers/models/bitnet/__init__.py
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright 2025 The BitNet Team and The HuggingFace Inc. team. All rights reserved.
|
| 2 |
+
#
|
| 3 |
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
| 4 |
+
# you may not use this file except in compliance with the License.
|
| 5 |
+
# You may obtain a copy of the License at
|
| 6 |
+
#
|
| 7 |
+
# http://www.apache.org/licenses/LICENSE-2.0
|
| 8 |
+
#
|
| 9 |
+
# Unless required by applicable law or agreed to in writing, software
|
| 10 |
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
| 11 |
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 12 |
+
# See the License for the specific language governing permissions and
|
| 13 |
+
# limitations under the License.
|
| 14 |
+
from typing import TYPE_CHECKING
|
| 15 |
+
|
| 16 |
+
from ...utils import _LazyModule
|
| 17 |
+
from ...utils.import_utils import define_import_structure
|
| 18 |
+
|
| 19 |
+
|
| 20 |
+
if TYPE_CHECKING:
|
| 21 |
+
from .configuration_bitnet import *
|
| 22 |
+
from .modeling_bitnet import *
|
| 23 |
+
else:
|
| 24 |
+
import sys
|
| 25 |
+
|
| 26 |
+
_file = globals()["__file__"]
|
| 27 |
+
sys.modules[__name__] = _LazyModule(__name__, _file, define_import_structure(_file), module_spec=__spec__)
|
third_party/transformers/src/transformers/models/bitnet/configuration_bitnet.py
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright 2025 The BitNet Team and The HuggingFace Inc. team. All rights reserved.
|
| 2 |
+
#
|
| 3 |
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
| 4 |
+
# you may not use this file except in compliance with the License.
|
| 5 |
+
# You may obtain a copy of the License at
|
| 6 |
+
#
|
| 7 |
+
# http://www.apache.org/licenses/LICENSE-2.0
|
| 8 |
+
#
|
| 9 |
+
# Unless required by applicable law or agreed to in writing, software
|
| 10 |
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
| 11 |
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 12 |
+
# See the License for the specific language governing permissions and
|
| 13 |
+
"""BitNet model configuration"""
|
| 14 |
+
|
| 15 |
+
from huggingface_hub.dataclasses import strict
|
| 16 |
+
|
| 17 |
+
from ...configuration_utils import PreTrainedConfig
|
| 18 |
+
from ...modeling_rope_utils import RopeParameters
|
| 19 |
+
from ...utils import auto_docstring
|
| 20 |
+
|
| 21 |
+
|
| 22 |
+
@auto_docstring(checkpoint="microsoft/bitnet-b1.58-2B-4T")
|
| 23 |
+
@strict
|
| 24 |
+
class BitNetConfig(PreTrainedConfig):
|
| 25 |
+
r"""
|
| 26 |
+
```python
|
| 27 |
+
>>> from transformers import BitNetModel, BitNetConfig
|
| 28 |
+
|
| 29 |
+
>>> # Initializing a BitNet style configuration
|
| 30 |
+
>>> configuration = BitNetConfig()
|
| 31 |
+
|
| 32 |
+
>>> # Initializing a model from the BitNet style configuration
|
| 33 |
+
>>> model = BitNetModel(configuration)
|
| 34 |
+
|
| 35 |
+
>>> # Accessing the model configuration
|
| 36 |
+
>>> configuration = model.config
|
| 37 |
+
```
|
| 38 |
+
"""
|
| 39 |
+
|
| 40 |
+
model_type = "bitnet"
|
| 41 |
+
keys_to_ignore_at_inference = ["past_key_values"]
|
| 42 |
+
default_theta = 500000.0
|
| 43 |
+
|
| 44 |
+
vocab_size: int = 128256
|
| 45 |
+
hidden_size: int = 2560
|
| 46 |
+
intermediate_size: int = 6912
|
| 47 |
+
num_hidden_layers: int = 30
|
| 48 |
+
num_attention_heads: int = 20
|
| 49 |
+
num_key_value_heads: int | None = 5
|
| 50 |
+
hidden_act: str = "relu2"
|
| 51 |
+
max_position_embeddings: int = 2048
|
| 52 |
+
initializer_range: float = 0.02
|
| 53 |
+
rms_norm_eps: float = 1e-5
|
| 54 |
+
use_cache: bool = True
|
| 55 |
+
pad_token_id: int | None = None
|
| 56 |
+
bos_token_id: int | None = 128000
|
| 57 |
+
eos_token_id: int | list[int] | None = 128001
|
| 58 |
+
tie_word_embeddings: bool = False
|
| 59 |
+
attention_bias: bool = False
|
| 60 |
+
attention_dropout: float | int | None = 0.0
|
| 61 |
+
rope_parameters: RopeParameters | dict | None = None
|
| 62 |
+
|
| 63 |
+
def __post_init__(self, **kwargs):
|
| 64 |
+
# for backward compatibility
|
| 65 |
+
if self.num_key_value_heads is None:
|
| 66 |
+
self.num_key_value_heads = self.num_attention_heads
|
| 67 |
+
|
| 68 |
+
super().__post_init__(**kwargs)
|
| 69 |
+
|
| 70 |
+
|
| 71 |
+
__all__ = ["BitNetConfig"]
|
third_party/transformers/src/transformers/models/bitnet/modeling_bitnet.py
ADDED
|
@@ -0,0 +1,501 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨
|
| 2 |
+
# This file was automatically generated from src/transformers/models/bitnet/modular_bitnet.py.
|
| 3 |
+
# Do NOT edit this file manually as any edits will be overwritten by the generation of
|
| 4 |
+
# the file from the modular. If any change should be done, please apply the change to the
|
| 5 |
+
# modular_bitnet.py file directly. One of our CI enforces this.
|
| 6 |
+
# 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨
|
| 7 |
+
# Copyright 2025 The BitNet Team and The HuggingFace Inc. team. All rights reserved.
|
| 8 |
+
#
|
| 9 |
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
| 10 |
+
# you may not use this file except in compliance with the License.
|
| 11 |
+
# You may obtain a copy of the License at
|
| 12 |
+
#
|
| 13 |
+
# http://www.apache.org/licenses/LICENSE-2.0
|
| 14 |
+
#
|
| 15 |
+
# Unless required by applicable law or agreed to in writing, software
|
| 16 |
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
| 17 |
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 18 |
+
# See the License for the specific language governing permissions and
|
| 19 |
+
|
| 20 |
+
from collections.abc import Callable
|
| 21 |
+
from typing import Optional
|
| 22 |
+
|
| 23 |
+
import torch
|
| 24 |
+
from torch import nn
|
| 25 |
+
|
| 26 |
+
from ...activations import ACT2FN
|
| 27 |
+
from ...cache_utils import Cache, DynamicCache
|
| 28 |
+
from ...generation import GenerationMixin
|
| 29 |
+
from ...integrations import use_kernel_forward_from_hub, use_kernel_func_from_hub, use_kernelized_func
|
| 30 |
+
from ...masking_utils import create_causal_mask
|
| 31 |
+
from ...modeling_flash_attention_utils import FlashAttentionKwargs
|
| 32 |
+
from ...modeling_layers import GradientCheckpointingLayer
|
| 33 |
+
from ...modeling_outputs import BaseModelOutputWithPast, CausalLMOutputWithPast
|
| 34 |
+
from ...modeling_rope_utils import ROPE_INIT_FUNCTIONS, dynamic_rope_update
|
| 35 |
+
from ...modeling_utils import ALL_ATTENTION_FUNCTIONS, PreTrainedModel
|
| 36 |
+
from ...processing_utils import Unpack
|
| 37 |
+
from ...utils import TransformersKwargs, auto_docstring, can_return_tuple
|
| 38 |
+
from ...utils.generic import maybe_autocast, merge_with_config_defaults
|
| 39 |
+
from ...utils.output_capturing import capture_outputs
|
| 40 |
+
from .configuration_bitnet import BitNetConfig
|
| 41 |
+
|
| 42 |
+
|
| 43 |
+
@use_kernel_forward_from_hub("RMSNorm")
|
| 44 |
+
class BitNetRMSNorm(nn.Module):
|
| 45 |
+
def __init__(self, hidden_size, eps: float = 1e-6) -> None:
|
| 46 |
+
"""
|
| 47 |
+
BitNetRMSNorm is equivalent to T5LayerNorm
|
| 48 |
+
"""
|
| 49 |
+
super().__init__()
|
| 50 |
+
self.weight = nn.Parameter(torch.ones(hidden_size))
|
| 51 |
+
self.variance_epsilon = eps
|
| 52 |
+
|
| 53 |
+
def forward(self, hidden_states: torch.Tensor) -> torch.Tensor:
|
| 54 |
+
input_dtype = hidden_states.dtype
|
| 55 |
+
hidden_states = hidden_states.to(torch.float32)
|
| 56 |
+
variance = hidden_states.pow(2).mean(-1, keepdim=True)
|
| 57 |
+
hidden_states = hidden_states * torch.rsqrt(variance + self.variance_epsilon)
|
| 58 |
+
return self.weight * hidden_states.to(input_dtype)
|
| 59 |
+
|
| 60 |
+
def extra_repr(self):
|
| 61 |
+
return f"{tuple(self.weight.shape)}, eps={self.variance_epsilon}"
|
| 62 |
+
|
| 63 |
+
|
| 64 |
+
class BitNetMLP(nn.Module):
|
| 65 |
+
def __init__(self, config: BitNetConfig):
|
| 66 |
+
super().__init__()
|
| 67 |
+
self.config = config
|
| 68 |
+
self.hidden_size = config.hidden_size
|
| 69 |
+
self.intermediate_size = config.intermediate_size
|
| 70 |
+
self.gate_proj = nn.Linear(self.hidden_size, self.intermediate_size, bias=False)
|
| 71 |
+
self.up_proj = nn.Linear(self.hidden_size, self.intermediate_size, bias=False)
|
| 72 |
+
self.down_proj = nn.Linear(self.intermediate_size, self.hidden_size, bias=False)
|
| 73 |
+
self.act_fn = ACT2FN[config.hidden_act]
|
| 74 |
+
self.ffn_sub_norm = BitNetRMSNorm(config.intermediate_size, eps=config.rms_norm_eps)
|
| 75 |
+
|
| 76 |
+
def forward(self, x):
|
| 77 |
+
down_proj = self.down_proj(self.ffn_sub_norm(self.act_fn(self.gate_proj(x)) * self.up_proj(x)))
|
| 78 |
+
return down_proj
|
| 79 |
+
|
| 80 |
+
|
| 81 |
+
def rotate_half(x):
|
| 82 |
+
"""Rotates half the hidden dims of the input."""
|
| 83 |
+
x1 = x[..., : x.shape[-1] // 2]
|
| 84 |
+
x2 = x[..., x.shape[-1] // 2 :]
|
| 85 |
+
return torch.cat((-x2, x1), dim=-1)
|
| 86 |
+
|
| 87 |
+
|
| 88 |
+
@use_kernel_func_from_hub("rotary_pos_emb")
|
| 89 |
+
def apply_rotary_pos_emb(q, k, cos, sin, unsqueeze_dim=1):
|
| 90 |
+
"""Applies Rotary Position Embedding to the query and key tensors.
|
| 91 |
+
|
| 92 |
+
Args:
|
| 93 |
+
q (`torch.Tensor`): The query tensor.
|
| 94 |
+
k (`torch.Tensor`): The key tensor.
|
| 95 |
+
cos (`torch.Tensor`): The cosine part of the rotary embedding.
|
| 96 |
+
sin (`torch.Tensor`): The sine part of the rotary embedding.
|
| 97 |
+
unsqueeze_dim (`int`, *optional*, defaults to 1):
|
| 98 |
+
The 'unsqueeze_dim' argument specifies the dimension along which to unsqueeze cos[position_ids] and
|
| 99 |
+
sin[position_ids] so that they can be properly broadcasted to the dimensions of q and k. For example, note
|
| 100 |
+
that cos[position_ids] and sin[position_ids] have the shape [batch_size, seq_len, head_dim]. Then, if q and
|
| 101 |
+
k have the shape [batch_size, heads, seq_len, head_dim], then setting unsqueeze_dim=1 makes
|
| 102 |
+
cos[position_ids] and sin[position_ids] broadcastable to the shapes of q and k. Similarly, if q and k have
|
| 103 |
+
the shape [batch_size, seq_len, heads, head_dim], then set unsqueeze_dim=2.
|
| 104 |
+
Returns:
|
| 105 |
+
`tuple(torch.Tensor)` comprising of the query and key tensors rotated using the Rotary Position Embedding.
|
| 106 |
+
"""
|
| 107 |
+
cos = cos.unsqueeze(unsqueeze_dim)
|
| 108 |
+
sin = sin.unsqueeze(unsqueeze_dim)
|
| 109 |
+
q_embed = (q * cos) + (rotate_half(q) * sin)
|
| 110 |
+
k_embed = (k * cos) + (rotate_half(k) * sin)
|
| 111 |
+
return q_embed, k_embed
|
| 112 |
+
|
| 113 |
+
|
| 114 |
+
def repeat_kv(hidden_states: torch.Tensor, n_rep: int) -> torch.Tensor:
|
| 115 |
+
"""
|
| 116 |
+
This is the equivalent of torch.repeat_interleave(x, dim=1, repeats=n_rep). The hidden states go from (batch,
|
| 117 |
+
num_key_value_heads, seqlen, head_dim) to (batch, num_attention_heads, seqlen, head_dim)
|
| 118 |
+
"""
|
| 119 |
+
batch, num_key_value_heads, slen, head_dim = hidden_states.shape
|
| 120 |
+
if n_rep == 1:
|
| 121 |
+
return hidden_states
|
| 122 |
+
hidden_states = hidden_states[:, :, None, :, :].expand(batch, num_key_value_heads, n_rep, slen, head_dim)
|
| 123 |
+
return hidden_states.reshape(batch, num_key_value_heads * n_rep, slen, head_dim)
|
| 124 |
+
|
| 125 |
+
|
| 126 |
+
def eager_attention_forward(
|
| 127 |
+
module: nn.Module,
|
| 128 |
+
query: torch.Tensor,
|
| 129 |
+
key: torch.Tensor,
|
| 130 |
+
value: torch.Tensor,
|
| 131 |
+
attention_mask: torch.Tensor | None,
|
| 132 |
+
scaling: float,
|
| 133 |
+
dropout: float = 0.0,
|
| 134 |
+
**kwargs: Unpack[TransformersKwargs],
|
| 135 |
+
):
|
| 136 |
+
key_states = repeat_kv(key, module.num_key_value_groups)
|
| 137 |
+
value_states = repeat_kv(value, module.num_key_value_groups)
|
| 138 |
+
|
| 139 |
+
attn_weights = torch.matmul(query, key_states.transpose(2, 3)) * scaling
|
| 140 |
+
if attention_mask is not None:
|
| 141 |
+
attn_weights = attn_weights + attention_mask
|
| 142 |
+
|
| 143 |
+
attn_weights = nn.functional.softmax(attn_weights, dim=-1, dtype=torch.float32).to(query.dtype)
|
| 144 |
+
attn_weights = nn.functional.dropout(attn_weights, p=dropout, training=module.training)
|
| 145 |
+
attn_output = torch.matmul(attn_weights, value_states)
|
| 146 |
+
attn_output = attn_output.transpose(1, 2).contiguous()
|
| 147 |
+
|
| 148 |
+
return attn_output, attn_weights
|
| 149 |
+
|
| 150 |
+
|
| 151 |
+
@use_kernelized_func(apply_rotary_pos_emb)
|
| 152 |
+
class BitNetAttention(nn.Module):
|
| 153 |
+
"""Multi-headed attention from 'Attention Is All You Need' paper"""
|
| 154 |
+
|
| 155 |
+
def __init__(self, config: BitNetConfig, layer_idx: int):
|
| 156 |
+
super().__init__()
|
| 157 |
+
self.config = config
|
| 158 |
+
self.layer_idx = layer_idx
|
| 159 |
+
self.head_dim = getattr(config, "head_dim", config.hidden_size // config.num_attention_heads)
|
| 160 |
+
self.num_key_value_groups = config.num_attention_heads // config.num_key_value_heads
|
| 161 |
+
self.scaling = self.head_dim**-0.5
|
| 162 |
+
self.attention_dropout = config.attention_dropout
|
| 163 |
+
self.is_causal = True
|
| 164 |
+
|
| 165 |
+
self.q_proj = nn.Linear(
|
| 166 |
+
config.hidden_size, config.num_attention_heads * self.head_dim, bias=config.attention_bias
|
| 167 |
+
)
|
| 168 |
+
self.k_proj = nn.Linear(
|
| 169 |
+
config.hidden_size, config.num_key_value_heads * self.head_dim, bias=config.attention_bias
|
| 170 |
+
)
|
| 171 |
+
self.v_proj = nn.Linear(
|
| 172 |
+
config.hidden_size, config.num_key_value_heads * self.head_dim, bias=config.attention_bias
|
| 173 |
+
)
|
| 174 |
+
self.o_proj = nn.Linear(
|
| 175 |
+
config.num_attention_heads * self.head_dim, config.hidden_size, bias=config.attention_bias
|
| 176 |
+
)
|
| 177 |
+
self.attn_sub_norm = BitNetRMSNorm(config.hidden_size, eps=config.rms_norm_eps)
|
| 178 |
+
|
| 179 |
+
def forward(
|
| 180 |
+
self,
|
| 181 |
+
hidden_states: torch.Tensor,
|
| 182 |
+
position_embeddings: tuple[torch.Tensor, torch.Tensor],
|
| 183 |
+
attention_mask: torch.Tensor | None,
|
| 184 |
+
past_key_values: Cache | None = None,
|
| 185 |
+
**kwargs: Unpack[FlashAttentionKwargs],
|
| 186 |
+
) -> tuple[torch.Tensor, torch.Tensor | None]:
|
| 187 |
+
input_shape = hidden_states.shape[:-1]
|
| 188 |
+
hidden_shape = (*input_shape, -1, self.head_dim)
|
| 189 |
+
|
| 190 |
+
query_states = self.q_proj(hidden_states).view(hidden_shape).transpose(1, 2)
|
| 191 |
+
key_states = self.k_proj(hidden_states).view(hidden_shape).transpose(1, 2)
|
| 192 |
+
value_states = self.v_proj(hidden_states).view(hidden_shape).transpose(1, 2)
|
| 193 |
+
|
| 194 |
+
cos, sin = position_embeddings
|
| 195 |
+
query_states, key_states = apply_rotary_pos_emb(query_states, key_states, cos, sin)
|
| 196 |
+
|
| 197 |
+
if past_key_values is not None:
|
| 198 |
+
key_states, value_states = past_key_values.update(key_states, value_states, self.layer_idx)
|
| 199 |
+
|
| 200 |
+
attention_interface: Callable = ALL_ATTENTION_FUNCTIONS.get_interface(
|
| 201 |
+
self.config._attn_implementation, eager_attention_forward
|
| 202 |
+
)
|
| 203 |
+
|
| 204 |
+
attn_output, attn_weights = attention_interface(
|
| 205 |
+
self,
|
| 206 |
+
query_states,
|
| 207 |
+
key_states,
|
| 208 |
+
value_states,
|
| 209 |
+
attention_mask,
|
| 210 |
+
dropout=0.0 if not self.training else self.attention_dropout,
|
| 211 |
+
scaling=self.scaling,
|
| 212 |
+
**kwargs,
|
| 213 |
+
)
|
| 214 |
+
|
| 215 |
+
attn_output = attn_output.reshape(*input_shape, -1).contiguous()
|
| 216 |
+
attn_output = self.attn_sub_norm(attn_output) # diff with Llama
|
| 217 |
+
attn_output = self.o_proj(attn_output)
|
| 218 |
+
return attn_output, attn_weights
|
| 219 |
+
|
| 220 |
+
|
| 221 |
+
class BitNetDecoderLayer(GradientCheckpointingLayer):
|
| 222 |
+
def __init__(self, config: BitNetConfig, layer_idx: int):
|
| 223 |
+
super().__init__()
|
| 224 |
+
self.hidden_size = config.hidden_size
|
| 225 |
+
|
| 226 |
+
self.self_attn = BitNetAttention(config=config, layer_idx=layer_idx)
|
| 227 |
+
|
| 228 |
+
self.mlp = BitNetMLP(config)
|
| 229 |
+
self.input_layernorm = BitNetRMSNorm(config.hidden_size, eps=config.rms_norm_eps)
|
| 230 |
+
self.post_attention_layernorm = BitNetRMSNorm(config.hidden_size, eps=config.rms_norm_eps)
|
| 231 |
+
|
| 232 |
+
def forward(
|
| 233 |
+
self,
|
| 234 |
+
hidden_states: torch.Tensor,
|
| 235 |
+
attention_mask: torch.Tensor | None = None,
|
| 236 |
+
position_ids: torch.LongTensor | None = None,
|
| 237 |
+
past_key_values: Cache | None = None,
|
| 238 |
+
use_cache: bool | None = False,
|
| 239 |
+
position_embeddings: tuple[torch.Tensor, torch.Tensor] | None = None,
|
| 240 |
+
**kwargs: Unpack[TransformersKwargs],
|
| 241 |
+
) -> torch.Tensor:
|
| 242 |
+
residual = hidden_states
|
| 243 |
+
hidden_states = self.input_layernorm(hidden_states)
|
| 244 |
+
# Self Attention
|
| 245 |
+
hidden_states, _ = self.self_attn(
|
| 246 |
+
hidden_states=hidden_states,
|
| 247 |
+
attention_mask=attention_mask,
|
| 248 |
+
position_ids=position_ids,
|
| 249 |
+
past_key_values=past_key_values,
|
| 250 |
+
use_cache=use_cache,
|
| 251 |
+
position_embeddings=position_embeddings,
|
| 252 |
+
**kwargs,
|
| 253 |
+
)
|
| 254 |
+
hidden_states = residual + hidden_states
|
| 255 |
+
|
| 256 |
+
# Fully Connected
|
| 257 |
+
residual = hidden_states
|
| 258 |
+
hidden_states = self.post_attention_layernorm(hidden_states)
|
| 259 |
+
hidden_states = self.mlp(hidden_states)
|
| 260 |
+
hidden_states = residual + hidden_states
|
| 261 |
+
return hidden_states
|
| 262 |
+
|
| 263 |
+
|
| 264 |
+
class BitNetRotaryEmbedding(nn.Module):
|
| 265 |
+
inv_freq: torch.Tensor # fix linting for `register_buffer`
|
| 266 |
+
|
| 267 |
+
def __init__(self, config: BitNetConfig, device=None):
|
| 268 |
+
super().__init__()
|
| 269 |
+
self.max_seq_len_cached = config.max_position_embeddings
|
| 270 |
+
self.original_max_seq_len = config.max_position_embeddings
|
| 271 |
+
|
| 272 |
+
self.config = config
|
| 273 |
+
|
| 274 |
+
self.rope_type = self.config.rope_parameters["rope_type"]
|
| 275 |
+
rope_init_fn: Callable = self.compute_default_rope_parameters
|
| 276 |
+
if self.rope_type != "default":
|
| 277 |
+
rope_init_fn = ROPE_INIT_FUNCTIONS[self.rope_type]
|
| 278 |
+
inv_freq, self.attention_scaling = rope_init_fn(self.config, device)
|
| 279 |
+
|
| 280 |
+
self.register_buffer("inv_freq", inv_freq, persistent=False)
|
| 281 |
+
self.register_buffer("original_inv_freq", inv_freq.clone(), persistent=False)
|
| 282 |
+
|
| 283 |
+
@staticmethod
|
| 284 |
+
def compute_default_rope_parameters(
|
| 285 |
+
config: BitNetConfig | None = None,
|
| 286 |
+
device: Optional["torch.device"] = None,
|
| 287 |
+
seq_len: int | None = None,
|
| 288 |
+
) -> tuple["torch.Tensor", float]:
|
| 289 |
+
"""
|
| 290 |
+
Computes the inverse frequencies according to the original RoPE implementation
|
| 291 |
+
Args:
|
| 292 |
+
config ([`~transformers.PreTrainedConfig`]):
|
| 293 |
+
The model configuration.
|
| 294 |
+
device (`torch.device`):
|
| 295 |
+
The device to use for initialization of the inverse frequencies.
|
| 296 |
+
seq_len (`int`, *optional*):
|
| 297 |
+
The current sequence length. Unused for this type of RoPE.
|
| 298 |
+
Returns:
|
| 299 |
+
Tuple of (`torch.Tensor`, `float`), containing the inverse frequencies for the RoPE embeddings and the
|
| 300 |
+
post-processing scaling factor applied to the computed cos/sin (unused in this type of RoPE).
|
| 301 |
+
"""
|
| 302 |
+
base = config.rope_parameters["rope_theta"]
|
| 303 |
+
dim = getattr(config, "head_dim", None) or config.hidden_size // config.num_attention_heads
|
| 304 |
+
|
| 305 |
+
attention_factor = 1.0 # Unused in this type of RoPE
|
| 306 |
+
|
| 307 |
+
# Compute the inverse frequencies
|
| 308 |
+
inv_freq = 1.0 / (
|
| 309 |
+
base ** (torch.arange(0, dim, 2, dtype=torch.int64).to(device=device, dtype=torch.float) / dim)
|
| 310 |
+
)
|
| 311 |
+
return inv_freq, attention_factor
|
| 312 |
+
|
| 313 |
+
@torch.no_grad()
|
| 314 |
+
@dynamic_rope_update # power user: used with advanced RoPE types (e.g. dynamic rope)
|
| 315 |
+
def forward(self, x, position_ids):
|
| 316 |
+
inv_freq_expanded = self.inv_freq[None, :, None].float().expand(position_ids.shape[0], -1, 1).to(x.device)
|
| 317 |
+
position_ids_expanded = position_ids[:, None, :].float()
|
| 318 |
+
|
| 319 |
+
device_type = x.device.type if isinstance(x.device.type, str) and x.device.type != "mps" else "cpu"
|
| 320 |
+
with maybe_autocast(device_type=device_type, enabled=False): # Force float32
|
| 321 |
+
freqs = (inv_freq_expanded.float() @ position_ids_expanded.float()).transpose(1, 2)
|
| 322 |
+
emb = torch.cat((freqs, freqs), dim=-1)
|
| 323 |
+
cos = emb.cos() * self.attention_scaling
|
| 324 |
+
sin = emb.sin() * self.attention_scaling
|
| 325 |
+
|
| 326 |
+
return cos.to(dtype=x.dtype), sin.to(dtype=x.dtype)
|
| 327 |
+
|
| 328 |
+
|
| 329 |
+
@auto_docstring
|
| 330 |
+
class BitNetPreTrainedModel(PreTrainedModel):
|
| 331 |
+
config: BitNetConfig
|
| 332 |
+
base_model_prefix = "model"
|
| 333 |
+
supports_gradient_checkpointing = True
|
| 334 |
+
_no_split_modules = ["BitNetDecoderLayer"]
|
| 335 |
+
_skip_keys_device_placement = ["past_key_values"]
|
| 336 |
+
_supports_flash_attn = True
|
| 337 |
+
_supports_sdpa = True
|
| 338 |
+
_supports_flex_attn = True
|
| 339 |
+
|
| 340 |
+
_can_compile_fullgraph = True
|
| 341 |
+
_supports_attention_backend = True
|
| 342 |
+
_can_record_outputs = {
|
| 343 |
+
"hidden_states": BitNetDecoderLayer,
|
| 344 |
+
"attentions": BitNetAttention,
|
| 345 |
+
}
|
| 346 |
+
|
| 347 |
+
|
| 348 |
+
@auto_docstring
|
| 349 |
+
class BitNetModel(BitNetPreTrainedModel):
|
| 350 |
+
def __init__(self, config: BitNetConfig):
|
| 351 |
+
super().__init__(config)
|
| 352 |
+
self.padding_idx = config.pad_token_id
|
| 353 |
+
self.vocab_size = config.vocab_size
|
| 354 |
+
|
| 355 |
+
self.embed_tokens = nn.Embedding(config.vocab_size, config.hidden_size, self.padding_idx)
|
| 356 |
+
self.layers = nn.ModuleList(
|
| 357 |
+
[BitNetDecoderLayer(config, layer_idx) for layer_idx in range(config.num_hidden_layers)]
|
| 358 |
+
)
|
| 359 |
+
self.norm = BitNetRMSNorm(config.hidden_size, eps=config.rms_norm_eps)
|
| 360 |
+
self.rotary_emb = BitNetRotaryEmbedding(config=config)
|
| 361 |
+
self.gradient_checkpointing = False
|
| 362 |
+
|
| 363 |
+
# Initialize weights and apply final processing
|
| 364 |
+
self.post_init()
|
| 365 |
+
|
| 366 |
+
@merge_with_config_defaults
|
| 367 |
+
@capture_outputs
|
| 368 |
+
@auto_docstring
|
| 369 |
+
def forward(
|
| 370 |
+
self,
|
| 371 |
+
input_ids: torch.LongTensor | None = None,
|
| 372 |
+
attention_mask: torch.Tensor | None = None,
|
| 373 |
+
position_ids: torch.LongTensor | None = None,
|
| 374 |
+
past_key_values: Cache | None = None,
|
| 375 |
+
inputs_embeds: torch.FloatTensor | None = None,
|
| 376 |
+
use_cache: bool | None = None,
|
| 377 |
+
**kwargs: Unpack[TransformersKwargs],
|
| 378 |
+
) -> BaseModelOutputWithPast:
|
| 379 |
+
if (input_ids is None) ^ (inputs_embeds is not None):
|
| 380 |
+
raise ValueError("You must specify exactly one of input_ids or inputs_embeds")
|
| 381 |
+
|
| 382 |
+
if inputs_embeds is None:
|
| 383 |
+
inputs_embeds: torch.Tensor = self.embed_tokens(input_ids)
|
| 384 |
+
|
| 385 |
+
if use_cache and past_key_values is None:
|
| 386 |
+
past_key_values = DynamicCache(config=self.config)
|
| 387 |
+
|
| 388 |
+
if position_ids is None:
|
| 389 |
+
past_seen_tokens = past_key_values.get_seq_length() if past_key_values is not None else 0
|
| 390 |
+
position_ids = torch.arange(inputs_embeds.shape[1], device=inputs_embeds.device) + past_seen_tokens
|
| 391 |
+
position_ids = position_ids.unsqueeze(0)
|
| 392 |
+
|
| 393 |
+
causal_mask = create_causal_mask(
|
| 394 |
+
config=self.config,
|
| 395 |
+
inputs_embeds=inputs_embeds,
|
| 396 |
+
attention_mask=attention_mask,
|
| 397 |
+
past_key_values=past_key_values,
|
| 398 |
+
position_ids=position_ids,
|
| 399 |
+
)
|
| 400 |
+
|
| 401 |
+
hidden_states = inputs_embeds
|
| 402 |
+
position_embeddings = self.rotary_emb(hidden_states, position_ids=position_ids)
|
| 403 |
+
|
| 404 |
+
for decoder_layer in self.layers[: self.config.num_hidden_layers]:
|
| 405 |
+
hidden_states = decoder_layer(
|
| 406 |
+
hidden_states,
|
| 407 |
+
attention_mask=causal_mask,
|
| 408 |
+
position_embeddings=position_embeddings,
|
| 409 |
+
position_ids=position_ids,
|
| 410 |
+
past_key_values=past_key_values,
|
| 411 |
+
use_cache=use_cache,
|
| 412 |
+
**kwargs,
|
| 413 |
+
)
|
| 414 |
+
|
| 415 |
+
hidden_states = self.norm(hidden_states)
|
| 416 |
+
return BaseModelOutputWithPast(
|
| 417 |
+
last_hidden_state=hidden_states,
|
| 418 |
+
past_key_values=past_key_values,
|
| 419 |
+
)
|
| 420 |
+
|
| 421 |
+
|
| 422 |
+
@auto_docstring
|
| 423 |
+
class BitNetForCausalLM(BitNetPreTrainedModel, GenerationMixin):
|
| 424 |
+
_tied_weights_keys = {"lm_head.weight": "model.embed_tokens.weight"}
|
| 425 |
+
_tp_plan = None
|
| 426 |
+
_pp_plan = None
|
| 427 |
+
|
| 428 |
+
def __init__(self, config):
|
| 429 |
+
super().__init__(config)
|
| 430 |
+
self.model = BitNetModel(config)
|
| 431 |
+
self.vocab_size = config.vocab_size
|
| 432 |
+
self.lm_head = nn.Linear(config.hidden_size, config.vocab_size, bias=False)
|
| 433 |
+
|
| 434 |
+
# Initialize weights and apply final processing
|
| 435 |
+
self.post_init()
|
| 436 |
+
|
| 437 |
+
@can_return_tuple
|
| 438 |
+
@auto_docstring
|
| 439 |
+
def forward(
|
| 440 |
+
self,
|
| 441 |
+
input_ids: torch.LongTensor | None = None,
|
| 442 |
+
attention_mask: torch.Tensor | None = None,
|
| 443 |
+
position_ids: torch.LongTensor | None = None,
|
| 444 |
+
past_key_values: Cache | None = None,
|
| 445 |
+
inputs_embeds: torch.FloatTensor | None = None,
|
| 446 |
+
labels: torch.LongTensor | None = None,
|
| 447 |
+
use_cache: bool | None = None,
|
| 448 |
+
logits_to_keep: int | torch.Tensor = 0,
|
| 449 |
+
**kwargs: Unpack[TransformersKwargs],
|
| 450 |
+
) -> CausalLMOutputWithPast:
|
| 451 |
+
r"""
|
| 452 |
+
labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*):
|
| 453 |
+
Labels for computing the masked language modeling loss. Indices should either be in `[0, transformers.,
|
| 454 |
+
config.vocab_size]` or -100 (see `input_ids` docstring). Tokens with indices set to `-100` are ignored
|
| 455 |
+
(masked), the loss is only computed for the tokens with labels in `[0, transformers., config.vocab_size]`.
|
| 456 |
+
|
| 457 |
+
Example:
|
| 458 |
+
|
| 459 |
+
```python
|
| 460 |
+
>>> from transformers import AutoTokenizer, BitNetForCausalLM
|
| 461 |
+
|
| 462 |
+
>>> model = BitNetForCausalLM.from_pretrained("microsoft/bitnet-b1.58-2B-4T")
|
| 463 |
+
>>> tokenizer = AutoTokenizer.from_pretrained("microsoft/bitnet-b1.58-2B-4T")
|
| 464 |
+
|
| 465 |
+
>>> prompt = f'<|begin_of_text|>User: Hey, are you conscious? Can you talk to me?<|eot_id|>Assistant: '
|
| 466 |
+
>>> inputs = tokenizer(prompt, return_tensors="pt")
|
| 467 |
+
|
| 468 |
+
>>> # Generate
|
| 469 |
+
>>> generate_ids = model.generate(inputs.input_ids, max_length=100)
|
| 470 |
+
>>> tokenizer.batch_decode(generate_ids, skip_special_tokens=True, clean_up_tokenization_spaces=False)[0]
|
| 471 |
+
"User: Hey, are you conscious? Can you talk to me?Assistant: No, I'm not conscious. I'm an artificial intelligence designed to assist with information and tasks. How can I help you today?"
|
| 472 |
+
```"""
|
| 473 |
+
outputs: BaseModelOutputWithPast = self.model(
|
| 474 |
+
input_ids=input_ids,
|
| 475 |
+
attention_mask=attention_mask,
|
| 476 |
+
position_ids=position_ids,
|
| 477 |
+
past_key_values=past_key_values,
|
| 478 |
+
inputs_embeds=inputs_embeds,
|
| 479 |
+
use_cache=use_cache,
|
| 480 |
+
**kwargs,
|
| 481 |
+
)
|
| 482 |
+
|
| 483 |
+
hidden_states = outputs.last_hidden_state
|
| 484 |
+
# Only compute necessary logits, and do not upcast them to float if we are not computing the loss
|
| 485 |
+
slice_indices = slice(-logits_to_keep, None) if isinstance(logits_to_keep, int) else logits_to_keep
|
| 486 |
+
logits = self.lm_head(hidden_states[:, slice_indices, :])
|
| 487 |
+
|
| 488 |
+
loss = None
|
| 489 |
+
if labels is not None:
|
| 490 |
+
loss = self.loss_function(logits=logits, labels=labels, vocab_size=self.config.vocab_size, **kwargs)
|
| 491 |
+
|
| 492 |
+
return CausalLMOutputWithPast(
|
| 493 |
+
loss=loss,
|
| 494 |
+
logits=logits,
|
| 495 |
+
past_key_values=outputs.past_key_values,
|
| 496 |
+
hidden_states=outputs.hidden_states,
|
| 497 |
+
attentions=outputs.attentions,
|
| 498 |
+
)
|
| 499 |
+
|
| 500 |
+
|
| 501 |
+
__all__ = ["BitNetForCausalLM", "BitNetModel", "BitNetPreTrainedModel"]
|
third_party/transformers/src/transformers/models/bitnet/modular_bitnet.py
ADDED
|
@@ -0,0 +1,148 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright 2025 The BitNet Team and The HuggingFace Inc. team. All rights reserved.
|
| 2 |
+
#
|
| 3 |
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
| 4 |
+
# you may not use this file except in compliance with the License.
|
| 5 |
+
# You may obtain a copy of the License at
|
| 6 |
+
#
|
| 7 |
+
# http://www.apache.org/licenses/LICENSE-2.0
|
| 8 |
+
#
|
| 9 |
+
# Unless required by applicable law or agreed to in writing, software
|
| 10 |
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
| 11 |
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 12 |
+
# See the License for the specific language governing permissions and
|
| 13 |
+
"""PyTorch BitNet model."""
|
| 14 |
+
|
| 15 |
+
from collections.abc import Callable
|
| 16 |
+
|
| 17 |
+
import torch
|
| 18 |
+
|
| 19 |
+
from ...cache_utils import Cache
|
| 20 |
+
from ...modeling_flash_attention_utils import FlashAttentionKwargs
|
| 21 |
+
from ...modeling_outputs import CausalLMOutputWithPast
|
| 22 |
+
from ...modeling_utils import ALL_ATTENTION_FUNCTIONS
|
| 23 |
+
from ...processing_utils import Unpack
|
| 24 |
+
from ...utils import logging
|
| 25 |
+
from ..gemma.modeling_gemma import GemmaMLP
|
| 26 |
+
from ..llama.modeling_llama import (
|
| 27 |
+
LlamaAttention,
|
| 28 |
+
LlamaDecoderLayer,
|
| 29 |
+
LlamaForCausalLM,
|
| 30 |
+
LlamaModel,
|
| 31 |
+
LlamaRMSNorm,
|
| 32 |
+
apply_rotary_pos_emb,
|
| 33 |
+
eager_attention_forward,
|
| 34 |
+
)
|
| 35 |
+
from .configuration_bitnet import BitNetConfig
|
| 36 |
+
|
| 37 |
+
|
| 38 |
+
logger = logging.get_logger(__name__)
|
| 39 |
+
|
| 40 |
+
|
| 41 |
+
class BitNetRMSNorm(LlamaRMSNorm):
|
| 42 |
+
pass
|
| 43 |
+
|
| 44 |
+
|
| 45 |
+
class BitNetMLP(GemmaMLP):
|
| 46 |
+
def __init__(self, config: BitNetConfig):
|
| 47 |
+
super().__init__(config)
|
| 48 |
+
self.ffn_sub_norm = BitNetRMSNorm(config.intermediate_size, eps=config.rms_norm_eps)
|
| 49 |
+
|
| 50 |
+
def forward(self, x):
|
| 51 |
+
down_proj = self.down_proj(self.ffn_sub_norm(self.act_fn(self.gate_proj(x)) * self.up_proj(x)))
|
| 52 |
+
return down_proj
|
| 53 |
+
|
| 54 |
+
|
| 55 |
+
class BitNetAttention(LlamaAttention):
|
| 56 |
+
def __init__(self, config: BitNetConfig, layer_idx: int):
|
| 57 |
+
super().__init__(config, layer_idx)
|
| 58 |
+
self.attn_sub_norm = BitNetRMSNorm(config.hidden_size, eps=config.rms_norm_eps)
|
| 59 |
+
|
| 60 |
+
def forward(
|
| 61 |
+
self,
|
| 62 |
+
hidden_states: torch.Tensor,
|
| 63 |
+
position_embeddings: tuple[torch.Tensor, torch.Tensor],
|
| 64 |
+
attention_mask: torch.Tensor | None,
|
| 65 |
+
past_key_values: Cache | None = None,
|
| 66 |
+
**kwargs: Unpack[FlashAttentionKwargs],
|
| 67 |
+
) -> tuple[torch.Tensor, torch.Tensor | None]:
|
| 68 |
+
input_shape = hidden_states.shape[:-1]
|
| 69 |
+
hidden_shape = (*input_shape, -1, self.head_dim)
|
| 70 |
+
|
| 71 |
+
query_states = self.q_proj(hidden_states).view(hidden_shape).transpose(1, 2)
|
| 72 |
+
key_states = self.k_proj(hidden_states).view(hidden_shape).transpose(1, 2)
|
| 73 |
+
value_states = self.v_proj(hidden_states).view(hidden_shape).transpose(1, 2)
|
| 74 |
+
|
| 75 |
+
cos, sin = position_embeddings
|
| 76 |
+
query_states, key_states = apply_rotary_pos_emb(query_states, key_states, cos, sin)
|
| 77 |
+
|
| 78 |
+
if past_key_values is not None:
|
| 79 |
+
key_states, value_states = past_key_values.update(key_states, value_states, self.layer_idx)
|
| 80 |
+
|
| 81 |
+
attention_interface: Callable = ALL_ATTENTION_FUNCTIONS.get_interface(
|
| 82 |
+
self.config._attn_implementation, eager_attention_forward
|
| 83 |
+
)
|
| 84 |
+
|
| 85 |
+
attn_output, attn_weights = attention_interface(
|
| 86 |
+
self,
|
| 87 |
+
query_states,
|
| 88 |
+
key_states,
|
| 89 |
+
value_states,
|
| 90 |
+
attention_mask,
|
| 91 |
+
dropout=0.0 if not self.training else self.attention_dropout,
|
| 92 |
+
scaling=self.scaling,
|
| 93 |
+
**kwargs,
|
| 94 |
+
)
|
| 95 |
+
|
| 96 |
+
attn_output = attn_output.reshape(*input_shape, -1).contiguous()
|
| 97 |
+
attn_output = self.attn_sub_norm(attn_output) # diff with Llama
|
| 98 |
+
attn_output = self.o_proj(attn_output)
|
| 99 |
+
return attn_output, attn_weights
|
| 100 |
+
|
| 101 |
+
|
| 102 |
+
class BitNetDecoderLayer(LlamaDecoderLayer):
|
| 103 |
+
pass
|
| 104 |
+
|
| 105 |
+
|
| 106 |
+
class BitNetModel(LlamaModel):
|
| 107 |
+
pass
|
| 108 |
+
|
| 109 |
+
|
| 110 |
+
class BitNetForCausalLM(LlamaForCausalLM):
|
| 111 |
+
_tied_weights_keys = {"lm_head.weight": "model.embed_tokens.weight"}
|
| 112 |
+
_tp_plan = None
|
| 113 |
+
_pp_plan = None
|
| 114 |
+
|
| 115 |
+
def forward(
|
| 116 |
+
self,
|
| 117 |
+
**super_kwargs,
|
| 118 |
+
) -> CausalLMOutputWithPast:
|
| 119 |
+
r"""
|
| 120 |
+
labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*):
|
| 121 |
+
Labels for computing the masked language modeling loss. Indices should either be in `[0, transformers.,
|
| 122 |
+
config.vocab_size]` or -100 (see `input_ids` docstring). Tokens with indices set to `-100` are ignored
|
| 123 |
+
(masked), the loss is only computed for the tokens with labels in `[0, transformers., config.vocab_size]`.
|
| 124 |
+
|
| 125 |
+
Example:
|
| 126 |
+
|
| 127 |
+
```python
|
| 128 |
+
>>> from transformers import AutoTokenizer, BitNetForCausalLM
|
| 129 |
+
|
| 130 |
+
>>> model = BitNetForCausalLM.from_pretrained("microsoft/bitnet-b1.58-2B-4T")
|
| 131 |
+
>>> tokenizer = AutoTokenizer.from_pretrained("microsoft/bitnet-b1.58-2B-4T")
|
| 132 |
+
|
| 133 |
+
>>> prompt = f'<|begin_of_text|>User: Hey, are you conscious? Can you talk to me?<|eot_id|>Assistant: '
|
| 134 |
+
>>> inputs = tokenizer(prompt, return_tensors="pt")
|
| 135 |
+
|
| 136 |
+
>>> # Generate
|
| 137 |
+
>>> generate_ids = model.generate(inputs.input_ids, max_length=100)
|
| 138 |
+
>>> tokenizer.batch_decode(generate_ids, skip_special_tokens=True, clean_up_tokenization_spaces=False)[0]
|
| 139 |
+
"User: Hey, are you conscious? Can you talk to me?Assistant: No, I'm not conscious. I'm an artificial intelligence designed to assist with information and tasks. How can I help you today?"
|
| 140 |
+
```"""
|
| 141 |
+
return super().forward(**super_kwargs)
|
| 142 |
+
|
| 143 |
+
|
| 144 |
+
__all__ = [
|
| 145 |
+
"BitNetForCausalLM",
|
| 146 |
+
"BitNetModel",
|
| 147 |
+
"BitNetPreTrainedModel", # noqa: F822
|
| 148 |
+
]
|
third_party/transformers/src/transformers/models/blip/__init__.py
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright 2024 The HuggingFace Team. All rights reserved.
|
| 2 |
+
#
|
| 3 |
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
| 4 |
+
# you may not use this file except in compliance with the License.
|
| 5 |
+
# You may obtain a copy of the License at
|
| 6 |
+
#
|
| 7 |
+
# http://www.apache.org/licenses/LICENSE-2.0
|
| 8 |
+
#
|
| 9 |
+
# Unless required by applicable law or agreed to in writing, software
|
| 10 |
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
| 11 |
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 12 |
+
# See the License for the specific language governing permissions and
|
| 13 |
+
# limitations under the License.
|
| 14 |
+
from typing import TYPE_CHECKING
|
| 15 |
+
|
| 16 |
+
from ...utils import _LazyModule
|
| 17 |
+
from ...utils.import_utils import define_import_structure
|
| 18 |
+
|
| 19 |
+
|
| 20 |
+
if TYPE_CHECKING:
|
| 21 |
+
from .configuration_blip import *
|
| 22 |
+
from .image_processing_blip import *
|
| 23 |
+
from .image_processing_pil_blip import *
|
| 24 |
+
from .modeling_blip import *
|
| 25 |
+
from .modeling_blip_text import *
|
| 26 |
+
from .processing_blip import *
|
| 27 |
+
else:
|
| 28 |
+
import sys
|
| 29 |
+
|
| 30 |
+
_file = globals()["__file__"]
|
| 31 |
+
sys.modules[__name__] = _LazyModule(__name__, _file, define_import_structure(_file), module_spec=__spec__)
|
third_party/transformers/src/transformers/models/blip/configuration_blip.py
ADDED
|
@@ -0,0 +1,174 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright 2022 The HuggingFace Inc. team. All rights reserved.
|
| 2 |
+
#
|
| 3 |
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
| 4 |
+
# you may not use this file except in compliance with the License.
|
| 5 |
+
# You may obtain a copy of the License at
|
| 6 |
+
#
|
| 7 |
+
# http://www.apache.org/licenses/LICENSE-2.0
|
| 8 |
+
#
|
| 9 |
+
# Unless required by applicable law or agreed to in writing, software
|
| 10 |
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
| 11 |
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 12 |
+
# See the License for the specific language governing permissions and
|
| 13 |
+
# limitations under the License.
|
| 14 |
+
"""Blip model configuration"""
|
| 15 |
+
|
| 16 |
+
from huggingface_hub.dataclasses import strict
|
| 17 |
+
|
| 18 |
+
from ...configuration_utils import PreTrainedConfig
|
| 19 |
+
from ...utils import auto_docstring, logging
|
| 20 |
+
|
| 21 |
+
|
| 22 |
+
logger = logging.get_logger(__name__)
|
| 23 |
+
|
| 24 |
+
|
| 25 |
+
@auto_docstring(checkpoint="Salesforce/blip-vqa-base")
|
| 26 |
+
@strict
|
| 27 |
+
class BlipTextConfig(PreTrainedConfig):
|
| 28 |
+
r"""
|
| 29 |
+
label_smoothing (float, *optional*):
|
| 30 |
+
A float in [0.0, 1.0]. Specifies the amount of smoothing when computing the loss, where 0.0 means no smoothing. The targets
|
| 31 |
+
become a mixture of the original ground truth and a uniform distribution as described in
|
| 32 |
+
`Rethinking the Inception Architecture for Computer Vision <https://huggingface.co/papers/1512.00567>`__. Default: :math:`0.0`.
|
| 33 |
+
|
| 34 |
+
Example:
|
| 35 |
+
|
| 36 |
+
```python
|
| 37 |
+
>>> from transformers import BlipTextConfig, BlipTextModel
|
| 38 |
+
|
| 39 |
+
>>> # Initializing a BlipTextConfig with Salesforce/blip-vqa-base style configuration
|
| 40 |
+
>>> configuration = BlipTextConfig()
|
| 41 |
+
|
| 42 |
+
>>> # Initializing a BlipTextModel (with random weights) from the Salesforce/blip-vqa-base style configuration
|
| 43 |
+
>>> model = BlipTextModel(configuration)
|
| 44 |
+
|
| 45 |
+
>>> # Accessing the model configuration
|
| 46 |
+
>>> configuration = model.config
|
| 47 |
+
```"""
|
| 48 |
+
|
| 49 |
+
model_type = "blip_text_model"
|
| 50 |
+
base_config_key = "text_config"
|
| 51 |
+
|
| 52 |
+
vocab_size: int = 30524
|
| 53 |
+
hidden_size: int = 768
|
| 54 |
+
encoder_hidden_size: int = 768
|
| 55 |
+
intermediate_size: int = 3072
|
| 56 |
+
projection_dim: int = 768
|
| 57 |
+
num_hidden_layers: int = 12
|
| 58 |
+
num_attention_heads: int = 8
|
| 59 |
+
max_position_embeddings: int = 512
|
| 60 |
+
hidden_act: str = "gelu"
|
| 61 |
+
layer_norm_eps: float = 1e-12
|
| 62 |
+
hidden_dropout_prob: float | int = 0.0
|
| 63 |
+
attention_probs_dropout_prob: float | int = 0.0
|
| 64 |
+
initializer_range: float = 0.02
|
| 65 |
+
bos_token_id: int | None = 30522
|
| 66 |
+
eos_token_id: int | list[int] | None = 2
|
| 67 |
+
pad_token_id: int | None = 0
|
| 68 |
+
sep_token_id: int | None = 102
|
| 69 |
+
is_decoder: bool = True
|
| 70 |
+
use_cache: bool = True
|
| 71 |
+
label_smoothing: float = 0.0
|
| 72 |
+
|
| 73 |
+
|
| 74 |
+
@auto_docstring(checkpoint="Salesforce/blip-vqa-base")
|
| 75 |
+
@strict
|
| 76 |
+
class BlipVisionConfig(PreTrainedConfig):
|
| 77 |
+
r"""
|
| 78 |
+
Example:
|
| 79 |
+
|
| 80 |
+
```python
|
| 81 |
+
>>> from transformers import BlipVisionConfig, BlipVisionModel
|
| 82 |
+
|
| 83 |
+
>>> # Initializing a BlipVisionConfig with Salesforce/blip-vqa-base style configuration
|
| 84 |
+
>>> configuration = BlipVisionConfig()
|
| 85 |
+
|
| 86 |
+
>>> # Initializing a BlipVisionModel (with random weights) from the Salesforce/blip-vqa-base style configuration
|
| 87 |
+
>>> model = BlipVisionModel(configuration)
|
| 88 |
+
|
| 89 |
+
>>> # Accessing the model configuration
|
| 90 |
+
>>> configuration = model.config
|
| 91 |
+
```"""
|
| 92 |
+
|
| 93 |
+
model_type = "blip_vision_model"
|
| 94 |
+
base_config_key = "vision_config"
|
| 95 |
+
|
| 96 |
+
hidden_size: int = 768
|
| 97 |
+
intermediate_size: int = 3072
|
| 98 |
+
projection_dim: int = 512
|
| 99 |
+
num_hidden_layers: int = 12
|
| 100 |
+
num_attention_heads: int = 12
|
| 101 |
+
image_size: int | list[int] | tuple[int, int] = 384
|
| 102 |
+
patch_size: int | list[int] | tuple[int, int] = 16
|
| 103 |
+
hidden_act: str = "gelu"
|
| 104 |
+
layer_norm_eps: float = 1e-5
|
| 105 |
+
attention_dropout: float | int = 0.0
|
| 106 |
+
initializer_range: float = 1e-10
|
| 107 |
+
|
| 108 |
+
|
| 109 |
+
@auto_docstring(checkpoint="Salesforce/blip-vqa-base")
|
| 110 |
+
@strict
|
| 111 |
+
class BlipConfig(PreTrainedConfig):
|
| 112 |
+
r"""
|
| 113 |
+
image_text_hidden_size (`int`, *optional*, defaults to 256):
|
| 114 |
+
Dimensionality of the hidden state of the image-text fusion layer.
|
| 115 |
+
label_smoothing (float, *optional*):
|
| 116 |
+
A float in [0.0, 1.0]. Specifies the amount of smoothing when computing the loss, where 0.0 means no smoothing. The targets
|
| 117 |
+
become a mixture of the original ground truth and a uniform distribution as described in
|
| 118 |
+
`Rethinking the Inception Architecture for Computer Vision <https://huggingface.co/papers/1512.00567>`__. Default: :math:`0.0`.
|
| 119 |
+
|
| 120 |
+
Example:
|
| 121 |
+
|
| 122 |
+
```python
|
| 123 |
+
>>> from transformers import BlipConfig, BlipModel
|
| 124 |
+
|
| 125 |
+
>>> # Initializing a BlipConfig with Salesforce/blip-vqa-base style configuration
|
| 126 |
+
>>> configuration = BlipConfig()
|
| 127 |
+
|
| 128 |
+
>>> # Initializing a BlipPModel (with random weights) from the Salesforce/blip-vqa-base style configuration
|
| 129 |
+
>>> model = BlipModel(configuration)
|
| 130 |
+
|
| 131 |
+
>>> # Accessing the model configuration
|
| 132 |
+
>>> configuration = model.config
|
| 133 |
+
|
| 134 |
+
>>> # We can also initialize a BlipConfig from a BlipTextConfig and a BlipVisionConfig
|
| 135 |
+
|
| 136 |
+
>>> # Initializing a BLIPText and BLIPVision configuration
|
| 137 |
+
>>> config_text = BlipTextConfig()
|
| 138 |
+
>>> config_vision = BlipVisionConfig()
|
| 139 |
+
|
| 140 |
+
>>> config = BlipConfig(text_config=config_text, vision_config=config_vision)
|
| 141 |
+
```"""
|
| 142 |
+
|
| 143 |
+
model_type = "blip"
|
| 144 |
+
sub_configs = {"text_config": BlipTextConfig, "vision_config": BlipVisionConfig}
|
| 145 |
+
|
| 146 |
+
text_config: dict | PreTrainedConfig | None = None
|
| 147 |
+
vision_config: dict | PreTrainedConfig | None = None
|
| 148 |
+
projection_dim: int = 512
|
| 149 |
+
logit_scale_init_value: float = 2.6592
|
| 150 |
+
image_text_hidden_size: int = 256
|
| 151 |
+
label_smoothing: float = 0.0
|
| 152 |
+
tie_word_embeddings: bool = True
|
| 153 |
+
initializer_factor: float = 1.0
|
| 154 |
+
initializer_range: float = 0.02
|
| 155 |
+
|
| 156 |
+
def __post_init__(self, **kwargs):
|
| 157 |
+
if self.text_config is None:
|
| 158 |
+
self.text_config = BlipTextConfig()
|
| 159 |
+
logger.info("`text_config` is `None`. Initializing the `BlipTextConfig` with default values.")
|
| 160 |
+
elif isinstance(self.text_config, dict):
|
| 161 |
+
self.text_config = BlipTextConfig(**self.text_config)
|
| 162 |
+
|
| 163 |
+
if self.vision_config is None:
|
| 164 |
+
self.vision_config = BlipVisionConfig()
|
| 165 |
+
logger.info("`vision_config` is `None`. initializing the `BlipVisionConfig` with default values.")
|
| 166 |
+
elif isinstance(self.vision_config, dict):
|
| 167 |
+
self.vision_config = BlipVisionConfig(**self.vision_config)
|
| 168 |
+
|
| 169 |
+
self.text_config.encoder_hidden_size = self.vision_config.hidden_size
|
| 170 |
+
|
| 171 |
+
super().__post_init__(**kwargs)
|
| 172 |
+
|
| 173 |
+
|
| 174 |
+
__all__ = ["BlipConfig", "BlipTextConfig", "BlipVisionConfig"]
|
third_party/transformers/src/transformers/models/blip/convert_blip_original_pytorch_to_hf.py
ADDED
|
@@ -0,0 +1,192 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright 2022 The HuggingFace Inc. team. All rights reserved.
|
| 2 |
+
#
|
| 3 |
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
| 4 |
+
# you may not use this file except in compliance with the License.
|
| 5 |
+
# You may obtain a copy of the License at
|
| 6 |
+
#
|
| 7 |
+
# http://www.apache.org/licenses/LICENSE-2.0
|
| 8 |
+
#
|
| 9 |
+
# Unless required by applicable law or agreed to in writing, software
|
| 10 |
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
| 11 |
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 12 |
+
# See the License for the specific language governing permissions and
|
| 13 |
+
# limitations under the License.
|
| 14 |
+
|
| 15 |
+
import argparse
|
| 16 |
+
import re
|
| 17 |
+
from io import BytesIO
|
| 18 |
+
|
| 19 |
+
import httpx
|
| 20 |
+
import torch
|
| 21 |
+
|
| 22 |
+
# git clone https://github.com/salesforce/BLIP.git
|
| 23 |
+
from models.blip import blip_decoder
|
| 24 |
+
from models.blip_itm import blip_itm
|
| 25 |
+
from models.blip_vqa import blip_vqa
|
| 26 |
+
from PIL import Image
|
| 27 |
+
from torchvision import transforms
|
| 28 |
+
from torchvision.transforms.functional import InterpolationMode
|
| 29 |
+
|
| 30 |
+
from transformers import (
|
| 31 |
+
BertTokenizer,
|
| 32 |
+
BlipConfig,
|
| 33 |
+
BlipForConditionalGeneration,
|
| 34 |
+
BlipForImageTextRetrieval,
|
| 35 |
+
BlipForQuestionAnswering,
|
| 36 |
+
)
|
| 37 |
+
|
| 38 |
+
|
| 39 |
+
def load_demo_image(image_size, device):
|
| 40 |
+
url = "https://storage.googleapis.com/sfr-vision-language-research/BLIP/demo.jpg"
|
| 41 |
+
with httpx.stream("GET", url) as response:
|
| 42 |
+
raw_image = Image.open(BytesIO(response.read())).convert("RGB")
|
| 43 |
+
|
| 44 |
+
transform = transforms.Compose(
|
| 45 |
+
[
|
| 46 |
+
transforms.Resize((image_size, image_size), interpolation=InterpolationMode.BICUBIC),
|
| 47 |
+
transforms.ToTensor(),
|
| 48 |
+
transforms.Normalize((0.48145466, 0.4578275, 0.40821073), (0.26862954, 0.26130258, 0.27577711)),
|
| 49 |
+
]
|
| 50 |
+
)
|
| 51 |
+
image = transform(raw_image).unsqueeze(0).to(device)
|
| 52 |
+
return image
|
| 53 |
+
|
| 54 |
+
|
| 55 |
+
def rename_key(key):
|
| 56 |
+
if "visual_encoder" in key:
|
| 57 |
+
key = re.sub("visual_encoder*", "vision_model.encoder", key)
|
| 58 |
+
if "blocks" in key:
|
| 59 |
+
key = re.sub(r"blocks", "layers", key)
|
| 60 |
+
if "attn" in key:
|
| 61 |
+
key = re.sub(r"attn", "self_attn", key)
|
| 62 |
+
if "norm1" in key:
|
| 63 |
+
key = re.sub(r"norm1", "layer_norm1", key)
|
| 64 |
+
if "norm2" in key:
|
| 65 |
+
key = re.sub(r"norm2", "layer_norm2", key)
|
| 66 |
+
if "encoder.norm" in key:
|
| 67 |
+
key = re.sub(r"encoder.norm", "post_layernorm", key)
|
| 68 |
+
if "encoder.patch_embed.proj" in key:
|
| 69 |
+
key = re.sub(r"encoder.patch_embed.proj", "embeddings.patch_embedding", key)
|
| 70 |
+
|
| 71 |
+
if "encoder.pos_embed" in key:
|
| 72 |
+
key = re.sub(r"encoder.pos_embed", "embeddings.position_embedding", key)
|
| 73 |
+
if "encoder.cls_token" in key:
|
| 74 |
+
key = re.sub(r"encoder.cls_token", "embeddings.class_embedding", key)
|
| 75 |
+
|
| 76 |
+
if "self_attn" in key:
|
| 77 |
+
key = re.sub(r"self_attn.proj", "self_attn.projection", key)
|
| 78 |
+
|
| 79 |
+
return key
|
| 80 |
+
|
| 81 |
+
|
| 82 |
+
@torch.no_grad()
|
| 83 |
+
def convert_blip_checkpoint(pytorch_dump_folder_path, config_path=None):
|
| 84 |
+
"""
|
| 85 |
+
Copy/paste/tweak model's weights to transformers design.
|
| 86 |
+
"""
|
| 87 |
+
if config_path is not None:
|
| 88 |
+
config = BlipConfig.from_pretrained(config_path)
|
| 89 |
+
else:
|
| 90 |
+
config = BlipConfig(projection_dim=512, text_config={}, vision_config={})
|
| 91 |
+
|
| 92 |
+
hf_model = BlipForConditionalGeneration(config).eval()
|
| 93 |
+
|
| 94 |
+
model_url = "https://storage.googleapis.com/sfr-vision-language-research/BLIP/models/model_base_capfilt_large.pth"
|
| 95 |
+
|
| 96 |
+
pt_model = blip_decoder(pretrained=model_url, image_size=384, vit="base")
|
| 97 |
+
pt_model = pt_model.eval()
|
| 98 |
+
|
| 99 |
+
modified_state_dict = pt_model.state_dict()
|
| 100 |
+
for key in modified_state_dict.copy():
|
| 101 |
+
value = modified_state_dict.pop(key)
|
| 102 |
+
renamed_key = rename_key(key)
|
| 103 |
+
modified_state_dict[renamed_key] = value
|
| 104 |
+
|
| 105 |
+
hf_model.load_state_dict(modified_state_dict)
|
| 106 |
+
|
| 107 |
+
image_size = 384
|
| 108 |
+
image = load_demo_image(image_size=image_size, device="cpu")
|
| 109 |
+
tokenizer = BertTokenizer.from_pretrained("google-bert/bert-base-uncased")
|
| 110 |
+
input_ids = tokenizer(["a picture of"]).input_ids
|
| 111 |
+
|
| 112 |
+
out = hf_model.generate(image, input_ids)
|
| 113 |
+
|
| 114 |
+
assert out[0].tolist() == [30522, 1037, 3861, 1997, 1037, 2450, 3564, 2006, 1996, 3509, 2007, 2014, 3899, 102]
|
| 115 |
+
|
| 116 |
+
out = hf_model.generate(image)
|
| 117 |
+
|
| 118 |
+
assert out[0].tolist() == [30522, 1037, 2450, 3564, 2006, 1996, 3509, 2007, 2014, 3899, 102]
|
| 119 |
+
|
| 120 |
+
if pytorch_dump_folder_path is not None:
|
| 121 |
+
hf_model.save_pretrained(pytorch_dump_folder_path)
|
| 122 |
+
|
| 123 |
+
# model_url = 'https://storage.googleapis.com/sfr-vision-language-research/BLIP/models/model_vqa.pth'
|
| 124 |
+
model_url = (
|
| 125 |
+
"https://storage.googleapis.com/sfr-vision-language-research/BLIP/models/model_base_vqa_capfilt_large.pth"
|
| 126 |
+
)
|
| 127 |
+
|
| 128 |
+
vqa_model = blip_vqa(pretrained=model_url, image_size=image_size, vit="base")
|
| 129 |
+
vqa_model.eval()
|
| 130 |
+
|
| 131 |
+
modified_state_dict = vqa_model.state_dict()
|
| 132 |
+
for key in modified_state_dict.copy():
|
| 133 |
+
value = modified_state_dict.pop(key)
|
| 134 |
+
renamed_key = rename_key(key)
|
| 135 |
+
modified_state_dict[renamed_key] = value
|
| 136 |
+
|
| 137 |
+
hf_vqa_model = BlipForQuestionAnswering(config)
|
| 138 |
+
|
| 139 |
+
hf_vqa_model.load_state_dict(modified_state_dict)
|
| 140 |
+
|
| 141 |
+
question = ["How many dogs are in this image?"]
|
| 142 |
+
question_input_ids = tokenizer(question, return_tensors="pt").input_ids
|
| 143 |
+
|
| 144 |
+
answer = hf_vqa_model.generate(question_input_ids, image)
|
| 145 |
+
print(tokenizer.decode(answer[0]))
|
| 146 |
+
|
| 147 |
+
assert tokenizer.decode(answer[0]) == "[UNK] 1 [SEP]"
|
| 148 |
+
if pytorch_dump_folder_path is not None:
|
| 149 |
+
hf_vqa_model.save_pretrained(pytorch_dump_folder_path + "_vqa")
|
| 150 |
+
|
| 151 |
+
model_url = "https://storage.googleapis.com/sfr-vision-language-research/BLIP/models/model_base_retrieval_coco.pth"
|
| 152 |
+
|
| 153 |
+
itm_model = blip_itm(pretrained=model_url, image_size=image_size, vit="base")
|
| 154 |
+
itm_model.eval()
|
| 155 |
+
|
| 156 |
+
modified_state_dict = itm_model.state_dict()
|
| 157 |
+
for key in modified_state_dict.copy():
|
| 158 |
+
value = modified_state_dict.pop(key)
|
| 159 |
+
renamed_key = rename_key(key)
|
| 160 |
+
modified_state_dict[renamed_key] = value
|
| 161 |
+
|
| 162 |
+
hf_itm_model = BlipForImageTextRetrieval(config)
|
| 163 |
+
|
| 164 |
+
question = ["A picture of a woman with a dog sitting in a beach"]
|
| 165 |
+
question_input_ids = tokenizer(
|
| 166 |
+
question,
|
| 167 |
+
return_tensors="pt",
|
| 168 |
+
padding="max_length",
|
| 169 |
+
truncation=True,
|
| 170 |
+
max_length=35,
|
| 171 |
+
).input_ids
|
| 172 |
+
|
| 173 |
+
hf_itm_model.load_state_dict(modified_state_dict)
|
| 174 |
+
hf_itm_model.eval()
|
| 175 |
+
|
| 176 |
+
out_itm = hf_itm_model(question_input_ids, image, use_itm_head=True)
|
| 177 |
+
out = hf_itm_model(question_input_ids, image, use_itm_head=False)
|
| 178 |
+
|
| 179 |
+
assert out[0].item() == 0.2110687494277954
|
| 180 |
+
assert torch.nn.functional.softmax(out_itm[0], dim=1)[:, 1].item() == 0.45698845386505127
|
| 181 |
+
|
| 182 |
+
if pytorch_dump_folder_path is not None:
|
| 183 |
+
hf_itm_model.save_pretrained(pytorch_dump_folder_path + "_itm")
|
| 184 |
+
|
| 185 |
+
|
| 186 |
+
if __name__ == "__main__":
|
| 187 |
+
parser = argparse.ArgumentParser()
|
| 188 |
+
parser.add_argument("--pytorch_dump_folder_path", default=None, type=str, help="Path to the output PyTorch model.")
|
| 189 |
+
parser.add_argument("--config_path", default=None, type=str, help="Path to hf config.json of model to convert")
|
| 190 |
+
args = parser.parse_args()
|
| 191 |
+
|
| 192 |
+
convert_blip_checkpoint(args.pytorch_dump_folder_path, args.config_path)
|
third_party/transformers/src/transformers/models/blip/image_processing_blip.py
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright 2022 The HuggingFace Inc. team. All rights reserved.
|
| 2 |
+
#
|
| 3 |
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
| 4 |
+
# you may not use this file except in compliance with the License.
|
| 5 |
+
# You may obtain a copy of the License at
|
| 6 |
+
#
|
| 7 |
+
# http://www.apache.org/licenses/LICENSE-2.0
|
| 8 |
+
#
|
| 9 |
+
# Unless required by applicable law or agreed to in writing, software
|
| 10 |
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
| 11 |
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 12 |
+
# See the License for the specific language governing permissions and
|
| 13 |
+
# limitations under the License.
|
| 14 |
+
"""Image processor class for BLIP."""
|
| 15 |
+
|
| 16 |
+
from ...image_processing_backends import PilBackend
|
| 17 |
+
from ...image_utils import OPENAI_CLIP_MEAN, OPENAI_CLIP_STD, PILImageResampling
|
| 18 |
+
from ...utils import auto_docstring
|
| 19 |
+
|
| 20 |
+
|
| 21 |
+
@auto_docstring
|
| 22 |
+
class BlipImageProcessorPil(PilBackend):
|
| 23 |
+
resample = PILImageResampling.BICUBIC
|
| 24 |
+
image_mean = OPENAI_CLIP_MEAN
|
| 25 |
+
image_std = OPENAI_CLIP_STD
|
| 26 |
+
size = {"height": 384, "width": 384}
|
| 27 |
+
default_to_square = True
|
| 28 |
+
do_resize = True
|
| 29 |
+
do_rescale = True
|
| 30 |
+
do_normalize = True
|
| 31 |
+
do_convert_rgb = True
|
| 32 |
+
|
| 33 |
+
|
| 34 |
+
__all__ = ["BlipImageProcessorPil"]
|
third_party/transformers/src/transformers/models/blip/image_processing_pil_blip.py
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright 2022 The HuggingFace Inc. team. All rights reserved.
|
| 2 |
+
#
|
| 3 |
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
| 4 |
+
# you may not use this file except in compliance with the License.
|
| 5 |
+
# You may obtain a copy of the License at
|
| 6 |
+
#
|
| 7 |
+
# http://www.apache.org/licenses/LICENSE-2.0
|
| 8 |
+
#
|
| 9 |
+
# Unless required by applicable law or agreed to in writing, software
|
| 10 |
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
| 11 |
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 12 |
+
# See the License for the specific language governing permissions and
|
| 13 |
+
# limitations under the License.
|
| 14 |
+
"""Image processor class for BLIP."""
|
| 15 |
+
|
| 16 |
+
from ...image_processing_backends import TorchvisionBackend
|
| 17 |
+
from ...image_utils import OPENAI_CLIP_MEAN, OPENAI_CLIP_STD, PILImageResampling
|
| 18 |
+
from ...utils import auto_docstring
|
| 19 |
+
|
| 20 |
+
|
| 21 |
+
@auto_docstring
|
| 22 |
+
class BlipImageProcessor(TorchvisionBackend):
|
| 23 |
+
resample = PILImageResampling.BICUBIC
|
| 24 |
+
image_mean = OPENAI_CLIP_MEAN
|
| 25 |
+
image_std = OPENAI_CLIP_STD
|
| 26 |
+
size = {"height": 384, "width": 384}
|
| 27 |
+
default_to_square = True
|
| 28 |
+
do_resize = True
|
| 29 |
+
do_rescale = True
|
| 30 |
+
do_normalize = True
|
| 31 |
+
do_convert_rgb = True
|
| 32 |
+
|
| 33 |
+
|
| 34 |
+
__all__ = ["BlipImageProcessor"]
|
third_party/transformers/src/transformers/models/blip/modeling_blip.py
ADDED
|
@@ -0,0 +1,1302 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright 2022 The Salesforce Team Authors and The HuggingFace Team. All rights reserved.
|
| 2 |
+
#
|
| 3 |
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
| 4 |
+
# you may not use this file except in compliance with the License.
|
| 5 |
+
# You may obtain a copy of the License at
|
| 6 |
+
#
|
| 7 |
+
# http://www.apache.org/licenses/LICENSE-2.0
|
| 8 |
+
#
|
| 9 |
+
# Unless required by applicable law or agreed to in writing, software
|
| 10 |
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
| 11 |
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 12 |
+
# See the License for the specific language governing permissions and
|
| 13 |
+
# limitations under the License.
|
| 14 |
+
"""PyTorch BLIP model."""
|
| 15 |
+
|
| 16 |
+
from dataclasses import dataclass
|
| 17 |
+
from typing import Any
|
| 18 |
+
|
| 19 |
+
import torch
|
| 20 |
+
from torch import nn
|
| 21 |
+
from torch.nn.functional import normalize
|
| 22 |
+
|
| 23 |
+
from ... import initialization as init
|
| 24 |
+
from ...activations import ACT2FN
|
| 25 |
+
from ...generation import GenerationMixin
|
| 26 |
+
from ...modeling_layers import GradientCheckpointingLayer
|
| 27 |
+
from ...modeling_outputs import (
|
| 28 |
+
BaseModelOutput,
|
| 29 |
+
BaseModelOutputWithPooling,
|
| 30 |
+
BaseModelOutputWithPoolingAndCrossAttentions,
|
| 31 |
+
)
|
| 32 |
+
from ...modeling_utils import PreTrainedModel
|
| 33 |
+
from ...processing_utils import Unpack
|
| 34 |
+
from ...utils import ModelOutput, TransformersKwargs, auto_docstring, can_return_tuple, logging, torch_int
|
| 35 |
+
from ...utils.generic import merge_with_config_defaults
|
| 36 |
+
from ...utils.output_capturing import capture_outputs
|
| 37 |
+
from .configuration_blip import BlipConfig, BlipTextConfig, BlipVisionConfig
|
| 38 |
+
from .modeling_blip_text import BlipTextLMHeadModel, BlipTextModel
|
| 39 |
+
|
| 40 |
+
|
| 41 |
+
logger = logging.get_logger(__name__)
|
| 42 |
+
|
| 43 |
+
|
| 44 |
+
# Copied from transformers.models.clip.modeling_clip.contrastive_loss
|
| 45 |
+
def contrastive_loss(logits: torch.Tensor) -> torch.Tensor:
|
| 46 |
+
return nn.functional.cross_entropy(logits, torch.arange(len(logits), device=logits.device))
|
| 47 |
+
|
| 48 |
+
|
| 49 |
+
# Copied from transformers.models.clip.modeling_clip.clip_loss with clip->blip
|
| 50 |
+
def blip_loss(similarity: torch.Tensor) -> torch.Tensor:
|
| 51 |
+
caption_loss = contrastive_loss(similarity)
|
| 52 |
+
image_loss = contrastive_loss(similarity.t())
|
| 53 |
+
return (caption_loss + image_loss) / 2.0
|
| 54 |
+
|
| 55 |
+
|
| 56 |
+
@dataclass
|
| 57 |
+
@auto_docstring(
|
| 58 |
+
custom_intro="""
|
| 59 |
+
Adapted from the base class for vision model's outputs that also contains image embeddings of the pooling of the
|
| 60 |
+
last hidden states. This class also adds the loss term from the text decoder.
|
| 61 |
+
"""
|
| 62 |
+
)
|
| 63 |
+
class BlipForConditionalGenerationModelOutput(ModelOutput):
|
| 64 |
+
r"""
|
| 65 |
+
loss (`torch.FloatTensor`, *optional*, returned when `labels` is provided, `torch.FloatTensor` of shape `(1,)`):
|
| 66 |
+
Language modeling loss from the text decoder.
|
| 67 |
+
logits (`torch.FloatTensor` of shape `(batch_size, sequence_length, config.vocab_size)`, *optional*):
|
| 68 |
+
Prediction scores of the language modeling head of the text decoder model.
|
| 69 |
+
image_embeds (`torch.FloatTensor` of shape `(batch_size, output_dim)`, *optional*):
|
| 70 |
+
The image embeddings obtained after applying the Vision Transformer model to the input image.
|
| 71 |
+
hidden_states (`tuple(torch.FloatTensor)`, *optional*, returned when `output_hidden_states=True`):
|
| 72 |
+
Tuple of `torch.FloatTensor` (one for the output of the embeddings, if the model has an embedding layer, +
|
| 73 |
+
one for the output of each layer) of shape `(batch_size, sequence_length, hidden_size)`.
|
| 74 |
+
|
| 75 |
+
Hidden-states of the model at the output of each layer plus the optional initial embedding outputs.
|
| 76 |
+
attentions (`tuple(torch.FloatTensor)`, *optional*, returned when `output_attentions=True` is passed):
|
| 77 |
+
Tuple of `torch.FloatTensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length,
|
| 78 |
+
sequence_length)`.
|
| 79 |
+
|
| 80 |
+
Attentions weights after the attention softmax, used to compute the weighted average in the self-attention
|
| 81 |
+
heads.
|
| 82 |
+
"""
|
| 83 |
+
|
| 84 |
+
loss: tuple[torch.FloatTensor] | None = None
|
| 85 |
+
logits: tuple[torch.FloatTensor] | None = None
|
| 86 |
+
image_embeds: torch.FloatTensor | None = None
|
| 87 |
+
last_hidden_state: torch.FloatTensor | None = None
|
| 88 |
+
hidden_states: tuple[torch.FloatTensor, ...] | None = None
|
| 89 |
+
attentions: tuple[torch.FloatTensor, ...] | None = None
|
| 90 |
+
|
| 91 |
+
|
| 92 |
+
@dataclass
|
| 93 |
+
@auto_docstring(
|
| 94 |
+
custom_intro="""
|
| 95 |
+
Adapted from the base class for vision model's outputs that also contains image embeddings of the pooling of the
|
| 96 |
+
last hidden states. This class also adds the loss term from the text decoder.
|
| 97 |
+
"""
|
| 98 |
+
)
|
| 99 |
+
class BlipTextVisionModelOutput(ModelOutput):
|
| 100 |
+
r"""
|
| 101 |
+
loss (`torch.FloatTensor` of shape `(1,)`, *optional*, returned when `labels` is provided):
|
| 102 |
+
Language modeling loss from the text decoder.
|
| 103 |
+
image_embeds (`torch.FloatTensor` of shape `(batch_size, output_dim)` *optional* returned when model is initialized with `with_projection=True`):
|
| 104 |
+
The image embeddings obtained by applying the projection layer to the pooler_output.
|
| 105 |
+
"""
|
| 106 |
+
|
| 107 |
+
loss: torch.FloatTensor | None = None
|
| 108 |
+
image_embeds: torch.FloatTensor | None = None
|
| 109 |
+
last_hidden_state: torch.FloatTensor | None = None
|
| 110 |
+
hidden_states: tuple[torch.FloatTensor, ...] | None = None
|
| 111 |
+
attentions: tuple[torch.FloatTensor, ...] | None = None
|
| 112 |
+
|
| 113 |
+
|
| 114 |
+
@dataclass
|
| 115 |
+
@auto_docstring(
|
| 116 |
+
custom_intro="""
|
| 117 |
+
Adapted from the base class for vision model's outputs that also contains image embeddings of the pooling of the
|
| 118 |
+
last hidden states. This class also adds the loss term from the text decoder as well as the image-text similarity
|
| 119 |
+
scores.
|
| 120 |
+
"""
|
| 121 |
+
)
|
| 122 |
+
class BlipImageTextMatchingModelOutput(ModelOutput):
|
| 123 |
+
r"""
|
| 124 |
+
itm_score (`torch.FloatTensor`):
|
| 125 |
+
The image-text similarity scores.
|
| 126 |
+
loss (`torch.FloatTensor` of shape `(1,)`, *optional*, returned when `labels` is provided):
|
| 127 |
+
Language modeling loss from the text decoder.
|
| 128 |
+
image_embeds (`torch.FloatTensor` of shape `(batch_size, output_dim)` *optional* returned when model is initialized with `with_projection=True`):
|
| 129 |
+
The image embeddings obtained by applying the projection layer to the pooler_output.
|
| 130 |
+
vision_pooler_output (`torch.FloatTensor` of shape `(batch_size, hidden_size)`, *optional*):
|
| 131 |
+
Last layer hidden-state of the vision of the vision-only branch of the model.
|
| 132 |
+
question_embeds (`torch.FloatTensor`):
|
| 133 |
+
The question embeddings obtained by the text projection layer.
|
| 134 |
+
"""
|
| 135 |
+
|
| 136 |
+
itm_score: torch.FloatTensor | None = None
|
| 137 |
+
loss: torch.FloatTensor | None = None
|
| 138 |
+
image_embeds: torch.FloatTensor | None = None
|
| 139 |
+
last_hidden_state: torch.FloatTensor | None = None
|
| 140 |
+
hidden_states: tuple[torch.FloatTensor, ...] | None = None
|
| 141 |
+
vision_pooler_output: torch.FloatTensor | None = None
|
| 142 |
+
attentions: tuple[torch.FloatTensor, ...] | None = None
|
| 143 |
+
question_embeds: tuple[torch.FloatTensor] | None = None
|
| 144 |
+
|
| 145 |
+
|
| 146 |
+
@dataclass
|
| 147 |
+
@auto_docstring
|
| 148 |
+
class BlipOutput(ModelOutput):
|
| 149 |
+
r"""
|
| 150 |
+
loss (`torch.FloatTensor` of shape `(1,)`, *optional*, returned when `return_loss` is `True`):
|
| 151 |
+
Contrastive loss for image-text similarity.
|
| 152 |
+
logits_per_image (`torch.FloatTensor` of shape `(image_batch_size, text_batch_size)`):
|
| 153 |
+
The scaled dot product scores between `image_embeds` and `text_embeds`. This represents the image-text
|
| 154 |
+
similarity scores.
|
| 155 |
+
logits_per_text (`torch.FloatTensor` of shape `(text_batch_size, image_batch_size)`):
|
| 156 |
+
The scaled dot product scores between `text_embeds` and `image_embeds`. This represents the text-image
|
| 157 |
+
similarity scores.
|
| 158 |
+
text_embeds (`torch.FloatTensor` of shape `(batch_size, output_dim`):
|
| 159 |
+
The text embeddings obtained by applying the projection layer to the pooled output of [`BlipTextModel`].
|
| 160 |
+
image_embeds (`torch.FloatTensor` of shape `(batch_size, output_dim`):
|
| 161 |
+
The image embeddings obtained by applying the projection layer to the pooled output of [`BlipVisionModel`].
|
| 162 |
+
text_model_output (`BaseModelOutputWithPooling`):
|
| 163 |
+
The output of the [`BlipTextModel`].
|
| 164 |
+
vision_model_output (`BaseModelOutputWithPooling`):
|
| 165 |
+
The output of the [`BlipVisionModel`].
|
| 166 |
+
"""
|
| 167 |
+
|
| 168 |
+
loss: torch.FloatTensor | None = None
|
| 169 |
+
logits_per_image: torch.FloatTensor | None = None
|
| 170 |
+
logits_per_text: torch.FloatTensor | None = None
|
| 171 |
+
text_embeds: torch.FloatTensor | None = None
|
| 172 |
+
image_embeds: torch.FloatTensor | None = None
|
| 173 |
+
text_model_output: BaseModelOutputWithPooling = None
|
| 174 |
+
vision_model_output: BaseModelOutputWithPooling = None
|
| 175 |
+
|
| 176 |
+
def to_tuple(self) -> tuple[Any]:
|
| 177 |
+
return tuple(
|
| 178 |
+
self[k] if k not in ["text_model_output", "vision_model_output"] else getattr(self, k).to_tuple()
|
| 179 |
+
for k in self.keys()
|
| 180 |
+
)
|
| 181 |
+
|
| 182 |
+
|
| 183 |
+
class BlipVisionEmbeddings(nn.Module):
|
| 184 |
+
def __init__(self, config: BlipVisionConfig):
|
| 185 |
+
super().__init__()
|
| 186 |
+
self.config = config
|
| 187 |
+
self.embed_dim = config.hidden_size
|
| 188 |
+
self.image_size = config.image_size
|
| 189 |
+
self.patch_size = config.patch_size
|
| 190 |
+
|
| 191 |
+
self.class_embedding = nn.Parameter(torch.randn(1, 1, self.embed_dim))
|
| 192 |
+
|
| 193 |
+
self.patch_embedding = nn.Conv2d(
|
| 194 |
+
in_channels=3, out_channels=self.embed_dim, kernel_size=self.patch_size, stride=self.patch_size
|
| 195 |
+
)
|
| 196 |
+
|
| 197 |
+
self.num_patches = (self.image_size // self.patch_size) ** 2
|
| 198 |
+
self.num_positions = self.num_patches + 1
|
| 199 |
+
|
| 200 |
+
self.position_embedding = nn.Parameter(torch.randn(1, self.num_positions, self.embed_dim))
|
| 201 |
+
|
| 202 |
+
def interpolate_pos_encoding(self, embeddings: torch.Tensor, height: int, width: int) -> torch.Tensor:
|
| 203 |
+
"""
|
| 204 |
+
This method allows to interpolate the pre-trained position encodings, to be able to use the model on higher resolution
|
| 205 |
+
images. This method is also adapted to support torch.jit tracing.
|
| 206 |
+
|
| 207 |
+
Adapted from:
|
| 208 |
+
- https://github.com/facebookresearch/dino/blob/de9ee3df6cf39fac952ab558447af1fa1365362a/vision_transformer.py#L174-L194, and
|
| 209 |
+
- https://github.com/facebookresearch/dinov2/blob/e1277af2ba9496fbadf7aec6eba56e8d882d1e35/dinov2/models/vision_transformer.py#L179-L211
|
| 210 |
+
"""
|
| 211 |
+
|
| 212 |
+
num_patches = embeddings.shape[1] - 1
|
| 213 |
+
num_positions = self.position_embedding.shape[1] - 1
|
| 214 |
+
|
| 215 |
+
# always interpolate when tracing to ensure the exported model works for dynamic input shapes
|
| 216 |
+
if not torch.jit.is_tracing() and num_patches == num_positions and height == width:
|
| 217 |
+
return self.position_embedding
|
| 218 |
+
|
| 219 |
+
class_pos_embed = self.position_embedding[:, :1]
|
| 220 |
+
patch_pos_embed = self.position_embedding[:, 1:]
|
| 221 |
+
|
| 222 |
+
dim = embeddings.shape[-1]
|
| 223 |
+
|
| 224 |
+
new_height = height // self.patch_size
|
| 225 |
+
new_width = width // self.patch_size
|
| 226 |
+
|
| 227 |
+
sqrt_num_positions = torch_int(num_positions**0.5)
|
| 228 |
+
patch_pos_embed = patch_pos_embed.reshape(1, sqrt_num_positions, sqrt_num_positions, dim)
|
| 229 |
+
patch_pos_embed = patch_pos_embed.permute(0, 3, 1, 2)
|
| 230 |
+
|
| 231 |
+
patch_pos_embed = nn.functional.interpolate(
|
| 232 |
+
patch_pos_embed,
|
| 233 |
+
size=(new_height, new_width),
|
| 234 |
+
mode="bicubic",
|
| 235 |
+
align_corners=False,
|
| 236 |
+
)
|
| 237 |
+
|
| 238 |
+
patch_pos_embed = patch_pos_embed.permute(0, 2, 3, 1).view(1, -1, dim)
|
| 239 |
+
|
| 240 |
+
return torch.cat((class_pos_embed, patch_pos_embed), dim=1)
|
| 241 |
+
|
| 242 |
+
def forward(self, pixel_values: torch.FloatTensor, interpolate_pos_encoding: bool = False) -> torch.Tensor:
|
| 243 |
+
batch_size, _, height, width = pixel_values.shape
|
| 244 |
+
target_dtype = self.patch_embedding.weight.dtype
|
| 245 |
+
patch_embeds = self.patch_embedding(pixel_values.to(dtype=target_dtype)) # shape = [*, width, grid, grid]
|
| 246 |
+
patch_embeds = patch_embeds.flatten(2).transpose(1, 2)
|
| 247 |
+
class_embeds = self.class_embedding.expand(batch_size, 1, -1).to(target_dtype)
|
| 248 |
+
embeddings = torch.cat([class_embeds, patch_embeds], dim=1)
|
| 249 |
+
if interpolate_pos_encoding:
|
| 250 |
+
position_embedding = self.interpolate_pos_encoding(embeddings, height, width)
|
| 251 |
+
else:
|
| 252 |
+
position_embedding = self.position_embedding
|
| 253 |
+
embeddings = embeddings + position_embedding[:, : embeddings.size(1), :].to(target_dtype)
|
| 254 |
+
return embeddings
|
| 255 |
+
|
| 256 |
+
|
| 257 |
+
# Copied from transformers.models.clip.modeling_clip.CLIPTextEmbeddings with CLIP->Blip
|
| 258 |
+
class BlipTextEmbeddings(nn.Module):
|
| 259 |
+
def __init__(self, config: BlipTextConfig):
|
| 260 |
+
super().__init__()
|
| 261 |
+
embed_dim = config.hidden_size
|
| 262 |
+
|
| 263 |
+
self.token_embedding = nn.Embedding(config.vocab_size, embed_dim)
|
| 264 |
+
self.position_embedding = nn.Embedding(config.max_position_embeddings, embed_dim)
|
| 265 |
+
|
| 266 |
+
# position_ids (1, len position emb) is contiguous in memory and exported when serialized
|
| 267 |
+
self.register_buffer(
|
| 268 |
+
"position_ids", torch.arange(config.max_position_embeddings).expand((1, -1)), persistent=False
|
| 269 |
+
)
|
| 270 |
+
|
| 271 |
+
def forward(
|
| 272 |
+
self,
|
| 273 |
+
input_ids: torch.LongTensor | None = None,
|
| 274 |
+
position_ids: torch.LongTensor | None = None,
|
| 275 |
+
inputs_embeds: torch.FloatTensor | None = None,
|
| 276 |
+
) -> torch.Tensor:
|
| 277 |
+
seq_length = input_ids.shape[-1] if input_ids is not None else inputs_embeds.shape[-2]
|
| 278 |
+
max_position_embedding = self.position_embedding.weight.shape[0]
|
| 279 |
+
|
| 280 |
+
if seq_length > max_position_embedding:
|
| 281 |
+
raise ValueError(
|
| 282 |
+
f"Sequence length must be less than max_position_embeddings (got `sequence length`: "
|
| 283 |
+
f"{seq_length} and max_position_embeddings: {max_position_embedding}"
|
| 284 |
+
)
|
| 285 |
+
|
| 286 |
+
if position_ids is None:
|
| 287 |
+
position_ids = self.position_ids[:, :seq_length]
|
| 288 |
+
|
| 289 |
+
if inputs_embeds is None:
|
| 290 |
+
inputs_embeds = self.token_embedding(input_ids)
|
| 291 |
+
|
| 292 |
+
position_embeddings = self.position_embedding(position_ids)
|
| 293 |
+
embeddings = inputs_embeds + position_embeddings
|
| 294 |
+
|
| 295 |
+
return embeddings
|
| 296 |
+
|
| 297 |
+
|
| 298 |
+
class BlipAttention(nn.Module):
|
| 299 |
+
"""Multi-headed attention from 'Attention Is All You Need' paper"""
|
| 300 |
+
|
| 301 |
+
def __init__(self, config):
|
| 302 |
+
super().__init__()
|
| 303 |
+
self.config = config
|
| 304 |
+
self.embed_dim = config.hidden_size
|
| 305 |
+
self.num_heads = config.num_attention_heads
|
| 306 |
+
self.head_dim = self.embed_dim // self.num_heads
|
| 307 |
+
if self.head_dim * self.num_heads != self.embed_dim:
|
| 308 |
+
raise ValueError(
|
| 309 |
+
f"embed_dim must be divisible by num_heads (got `embed_dim`: {self.embed_dim} and `num_heads`:"
|
| 310 |
+
f" {self.num_heads})."
|
| 311 |
+
)
|
| 312 |
+
self.scale = self.head_dim**-0.5
|
| 313 |
+
self.dropout = nn.Dropout(config.attention_dropout)
|
| 314 |
+
|
| 315 |
+
self.qkv = nn.Linear(self.embed_dim, 3 * self.embed_dim)
|
| 316 |
+
|
| 317 |
+
self.projection = nn.Linear(self.embed_dim, self.embed_dim)
|
| 318 |
+
|
| 319 |
+
def _shape(self, tensor: torch.Tensor, seq_len: int, bsz: int):
|
| 320 |
+
return tensor.view(bsz, seq_len, self.num_heads, self.head_dim).transpose(1, 2).contiguous()
|
| 321 |
+
|
| 322 |
+
def forward(
|
| 323 |
+
self,
|
| 324 |
+
hidden_states: torch.Tensor,
|
| 325 |
+
**kwargs: Unpack[TransformersKwargs],
|
| 326 |
+
) -> tuple[torch.Tensor, torch.Tensor]:
|
| 327 |
+
"""Input shape: Batch x Time x Channel"""
|
| 328 |
+
|
| 329 |
+
bsz, tgt_len, embed_dim = hidden_states.size()
|
| 330 |
+
|
| 331 |
+
mixed_qkv = (
|
| 332 |
+
self.qkv(hidden_states)
|
| 333 |
+
.reshape(bsz, tgt_len, 3, self.num_heads, embed_dim // self.num_heads)
|
| 334 |
+
.permute(2, 0, 3, 1, 4)
|
| 335 |
+
)
|
| 336 |
+
query_states, key_states, value_states = mixed_qkv[0], mixed_qkv[1], mixed_qkv[2]
|
| 337 |
+
|
| 338 |
+
# Take the dot product between "query" and "key" to get the raw attention scores.
|
| 339 |
+
attention_scores = torch.matmul(query_states, key_states.transpose(-1, -2))
|
| 340 |
+
|
| 341 |
+
attention_scores = attention_scores * self.scale
|
| 342 |
+
|
| 343 |
+
# Normalize the attention scores to probabilities.
|
| 344 |
+
attention_probs = nn.functional.softmax(attention_scores, dim=-1)
|
| 345 |
+
|
| 346 |
+
# This is actually dropping out entire tokens to attend to, which might
|
| 347 |
+
# seem a bit unusual, but is taken from the original Transformer paper.
|
| 348 |
+
attention_probs = self.dropout(attention_probs)
|
| 349 |
+
|
| 350 |
+
context_layer = torch.matmul(attention_probs, value_states).permute(0, 2, 1, 3)
|
| 351 |
+
|
| 352 |
+
new_context_layer_shape = context_layer.size()[:-2] + (self.embed_dim,)
|
| 353 |
+
context_layer = context_layer.reshape(new_context_layer_shape)
|
| 354 |
+
|
| 355 |
+
output = self.projection(context_layer)
|
| 356 |
+
|
| 357 |
+
return output, attention_probs
|
| 358 |
+
|
| 359 |
+
|
| 360 |
+
# Copied from transformers.models.clip.modeling_clip.CLIPMLP with CLIP->Blip
|
| 361 |
+
class BlipMLP(nn.Module):
|
| 362 |
+
def __init__(self, config):
|
| 363 |
+
super().__init__()
|
| 364 |
+
self.config = config
|
| 365 |
+
self.activation_fn = ACT2FN[config.hidden_act]
|
| 366 |
+
self.fc1 = nn.Linear(config.hidden_size, config.intermediate_size)
|
| 367 |
+
self.fc2 = nn.Linear(config.intermediate_size, config.hidden_size)
|
| 368 |
+
|
| 369 |
+
def forward(self, hidden_states: torch.Tensor) -> torch.Tensor:
|
| 370 |
+
hidden_states = self.fc1(hidden_states)
|
| 371 |
+
hidden_states = self.activation_fn(hidden_states)
|
| 372 |
+
hidden_states = self.fc2(hidden_states)
|
| 373 |
+
return hidden_states
|
| 374 |
+
|
| 375 |
+
|
| 376 |
+
class BlipEncoderLayer(GradientCheckpointingLayer):
|
| 377 |
+
def __init__(self, config: BlipConfig):
|
| 378 |
+
super().__init__()
|
| 379 |
+
self.embed_dim = config.hidden_size
|
| 380 |
+
self.self_attn = BlipAttention(config)
|
| 381 |
+
self.layer_norm1 = nn.LayerNorm(self.embed_dim, eps=config.layer_norm_eps)
|
| 382 |
+
self.mlp = BlipMLP(config)
|
| 383 |
+
self.layer_norm2 = nn.LayerNorm(self.embed_dim, eps=config.layer_norm_eps)
|
| 384 |
+
|
| 385 |
+
@auto_docstring
|
| 386 |
+
def forward(
|
| 387 |
+
self,
|
| 388 |
+
hidden_states: torch.Tensor,
|
| 389 |
+
**kwargs: Unpack[TransformersKwargs],
|
| 390 |
+
) -> torch.FloatTensor:
|
| 391 |
+
residual = hidden_states
|
| 392 |
+
|
| 393 |
+
hidden_states = self.layer_norm1(hidden_states)
|
| 394 |
+
hidden_states, _ = self.self_attn(
|
| 395 |
+
hidden_states=hidden_states,
|
| 396 |
+
**kwargs,
|
| 397 |
+
)
|
| 398 |
+
hidden_states = hidden_states + residual
|
| 399 |
+
residual = hidden_states
|
| 400 |
+
hidden_states = self.layer_norm2(hidden_states)
|
| 401 |
+
hidden_states = self.mlp(hidden_states)
|
| 402 |
+
|
| 403 |
+
hidden_states = hidden_states + residual
|
| 404 |
+
|
| 405 |
+
return hidden_states
|
| 406 |
+
|
| 407 |
+
|
| 408 |
+
@auto_docstring
|
| 409 |
+
class BlipPreTrainedModel(PreTrainedModel):
|
| 410 |
+
config: BlipConfig
|
| 411 |
+
base_model_prefix = "blip"
|
| 412 |
+
input_modalities = ("image", "text")
|
| 413 |
+
supports_gradient_checkpointing = True
|
| 414 |
+
_no_split_modules = ["BlipEncoderLayer", "BlipTextEmbeddings"]
|
| 415 |
+
_skip_keys_device_placement = ["past_key_values"]
|
| 416 |
+
|
| 417 |
+
@torch.no_grad()
|
| 418 |
+
def _init_weights(self, module):
|
| 419 |
+
"""Initialize the weights"""
|
| 420 |
+
super()._init_weights(module)
|
| 421 |
+
std = self.config.initializer_range
|
| 422 |
+
if isinstance(module, BlipVisionEmbeddings):
|
| 423 |
+
if hasattr(self.config, "vision_config"):
|
| 424 |
+
std = self.config.vision_config.initializer_range
|
| 425 |
+
init.trunc_normal_(module.position_embedding, mean=0.0, std=std)
|
| 426 |
+
init.trunc_normal_(module.class_embedding, mean=0.0, std=std)
|
| 427 |
+
elif isinstance(module, BlipTextEmbeddings):
|
| 428 |
+
init.copy_(module.position_ids, torch.arange(module.position_ids.shape[-1]).expand((1, -1)))
|
| 429 |
+
|
| 430 |
+
|
| 431 |
+
class BlipEncoder(nn.Module):
|
| 432 |
+
"""
|
| 433 |
+
Transformer encoder consisting of `config.num_hidden_layers` self attention layers. Each layer is a
|
| 434 |
+
[`BlipEncoderLayer`].
|
| 435 |
+
|
| 436 |
+
Args:
|
| 437 |
+
config (`BlipConfig`):
|
| 438 |
+
The corresponding vision configuration for the `BlipEncoder`.
|
| 439 |
+
"""
|
| 440 |
+
|
| 441 |
+
def __init__(self, config: BlipConfig):
|
| 442 |
+
super().__init__()
|
| 443 |
+
self.config = config
|
| 444 |
+
self.layers = nn.ModuleList([BlipEncoderLayer(config) for _ in range(config.num_hidden_layers)])
|
| 445 |
+
self.gradient_checkpointing = False
|
| 446 |
+
|
| 447 |
+
@auto_docstring
|
| 448 |
+
def forward(
|
| 449 |
+
self,
|
| 450 |
+
inputs_embeds,
|
| 451 |
+
**kwargs: Unpack[TransformersKwargs],
|
| 452 |
+
) -> tuple | BaseModelOutput:
|
| 453 |
+
hidden_states = inputs_embeds
|
| 454 |
+
for encoder_layer in self.layers:
|
| 455 |
+
hidden_states = encoder_layer(
|
| 456 |
+
hidden_states,
|
| 457 |
+
**kwargs,
|
| 458 |
+
)
|
| 459 |
+
|
| 460 |
+
return BaseModelOutput(last_hidden_state=hidden_states)
|
| 461 |
+
|
| 462 |
+
|
| 463 |
+
class BlipVisionModel(BlipPreTrainedModel):
|
| 464 |
+
main_input_name = "pixel_values"
|
| 465 |
+
input_modalities = ("image",)
|
| 466 |
+
config: BlipVisionConfig
|
| 467 |
+
_can_record_outputs = {
|
| 468 |
+
"hidden_states": BlipEncoderLayer,
|
| 469 |
+
"attentions": BlipAttention,
|
| 470 |
+
}
|
| 471 |
+
|
| 472 |
+
def __init__(self, config: BlipVisionConfig):
|
| 473 |
+
super().__init__(config)
|
| 474 |
+
self.config = config
|
| 475 |
+
embed_dim = config.hidden_size
|
| 476 |
+
|
| 477 |
+
self.embeddings = BlipVisionEmbeddings(config)
|
| 478 |
+
self.encoder = BlipEncoder(config)
|
| 479 |
+
self.post_layernorm = nn.LayerNorm(embed_dim, eps=config.layer_norm_eps)
|
| 480 |
+
|
| 481 |
+
self.post_init()
|
| 482 |
+
|
| 483 |
+
@merge_with_config_defaults
|
| 484 |
+
@capture_outputs(tie_last_hidden_states=False)
|
| 485 |
+
@auto_docstring
|
| 486 |
+
def forward(
|
| 487 |
+
self,
|
| 488 |
+
pixel_values: torch.FloatTensor | None = None,
|
| 489 |
+
interpolate_pos_encoding: bool = False,
|
| 490 |
+
**kwargs: Unpack[TransformersKwargs],
|
| 491 |
+
) -> tuple | BaseModelOutputWithPooling:
|
| 492 |
+
if pixel_values is None:
|
| 493 |
+
raise ValueError("You have to specify pixel_values")
|
| 494 |
+
|
| 495 |
+
hidden_states = self.embeddings(pixel_values, interpolate_pos_encoding=interpolate_pos_encoding)
|
| 496 |
+
|
| 497 |
+
encoder_outputs: BaseModelOutput = self.encoder(
|
| 498 |
+
inputs_embeds=hidden_states,
|
| 499 |
+
**kwargs,
|
| 500 |
+
)
|
| 501 |
+
|
| 502 |
+
last_hidden_state = encoder_outputs.last_hidden_state
|
| 503 |
+
last_hidden_state = self.post_layernorm(last_hidden_state)
|
| 504 |
+
|
| 505 |
+
pooled_output = last_hidden_state[:, 0, :]
|
| 506 |
+
pooled_output = self.post_layernorm(pooled_output)
|
| 507 |
+
|
| 508 |
+
return BaseModelOutputWithPooling(
|
| 509 |
+
last_hidden_state=last_hidden_state,
|
| 510 |
+
pooler_output=pooled_output,
|
| 511 |
+
)
|
| 512 |
+
|
| 513 |
+
def get_input_embeddings(self):
|
| 514 |
+
return self.embeddings
|
| 515 |
+
|
| 516 |
+
|
| 517 |
+
@auto_docstring(
|
| 518 |
+
custom_intro="""
|
| 519 |
+
This model is going to be deprecated in future versions. Please use `BlipForConditionalGeneration`, `BlipForQuestionAnswering` or `BlipForImageTextRetrieval` depending on your usecase.
|
| 520 |
+
"""
|
| 521 |
+
)
|
| 522 |
+
class BlipModel(BlipPreTrainedModel):
|
| 523 |
+
config: BlipConfig
|
| 524 |
+
|
| 525 |
+
def __init__(self, config: BlipConfig):
|
| 526 |
+
super().__init__(config)
|
| 527 |
+
|
| 528 |
+
if not isinstance(config.text_config, BlipTextConfig):
|
| 529 |
+
raise TypeError(
|
| 530 |
+
"config.text_config is expected to be of type BlipTextConfig but is of type"
|
| 531 |
+
f" {type(config.text_config)}."
|
| 532 |
+
)
|
| 533 |
+
|
| 534 |
+
if not isinstance(config.vision_config, BlipVisionConfig):
|
| 535 |
+
raise TypeError(
|
| 536 |
+
"config.vision_config is expected to be of type BlipVisionConfig but is of type"
|
| 537 |
+
f" {type(config.vision_config)}."
|
| 538 |
+
)
|
| 539 |
+
|
| 540 |
+
text_config = config.text_config
|
| 541 |
+
vision_config = config.vision_config
|
| 542 |
+
|
| 543 |
+
self.projection_dim = config.projection_dim
|
| 544 |
+
self.text_embed_dim = text_config.hidden_size
|
| 545 |
+
self.vision_embed_dim = vision_config.hidden_size
|
| 546 |
+
|
| 547 |
+
self.text_model = BlipTextModel(text_config)
|
| 548 |
+
self.vision_model = BlipVisionModel(vision_config)
|
| 549 |
+
|
| 550 |
+
self.visual_projection = nn.Linear(self.vision_embed_dim, self.projection_dim, bias=False)
|
| 551 |
+
self.text_projection = nn.Linear(self.text_embed_dim, self.projection_dim, bias=False)
|
| 552 |
+
self.logit_scale = nn.Parameter(torch.tensor(self.config.logit_scale_init_value))
|
| 553 |
+
|
| 554 |
+
logger.warning(
|
| 555 |
+
"`BlipModel` is going to be deprecated in future release, please use `BlipForConditionalGeneration`, `BlipForQuestionAnswering` or `BlipForImageTextRetrieval` depending on your usecase."
|
| 556 |
+
)
|
| 557 |
+
|
| 558 |
+
# Initialize weights and apply final processing
|
| 559 |
+
self.post_init()
|
| 560 |
+
|
| 561 |
+
def get_input_embeddings(self):
|
| 562 |
+
return self.text_model.get_input_embeddings()
|
| 563 |
+
|
| 564 |
+
def set_input_embeddings(self, value):
|
| 565 |
+
self.text_model.set_input_embeddings(value)
|
| 566 |
+
|
| 567 |
+
@can_return_tuple
|
| 568 |
+
@auto_docstring
|
| 569 |
+
def get_text_features(
|
| 570 |
+
self,
|
| 571 |
+
input_ids: torch.Tensor | None = None,
|
| 572 |
+
attention_mask: torch.Tensor | None = None,
|
| 573 |
+
position_ids: torch.Tensor | None = None,
|
| 574 |
+
**kwargs: Unpack[TransformersKwargs],
|
| 575 |
+
) -> tuple | BaseModelOutputWithPooling:
|
| 576 |
+
r"""
|
| 577 |
+
Examples:
|
| 578 |
+
|
| 579 |
+
```python
|
| 580 |
+
>>> from transformers import AutoProcessor, BlipModel
|
| 581 |
+
|
| 582 |
+
>>> model = BlipModel.from_pretrained("Salesforce/blip-image-captioning-base")
|
| 583 |
+
>>> processor = AutoProcessor.from_pretrained("Salesforce/blip-image-captioning-base")
|
| 584 |
+
|
| 585 |
+
>>> inputs = processor(text=["a photo of a cat", "a photo of a dog"], padding=True, return_tensors="pt")
|
| 586 |
+
>>> text_features = model.get_text_features(**inputs)
|
| 587 |
+
```"""
|
| 588 |
+
text_outputs: BaseModelOutputWithPoolingAndCrossAttentions = self.text_model(
|
| 589 |
+
input_ids=input_ids,
|
| 590 |
+
attention_mask=attention_mask,
|
| 591 |
+
position_ids=position_ids,
|
| 592 |
+
return_dict=True,
|
| 593 |
+
**kwargs,
|
| 594 |
+
)
|
| 595 |
+
pooled_output = text_outputs.pooler_output
|
| 596 |
+
text_outputs.pooler_output = self.text_projection(pooled_output)
|
| 597 |
+
|
| 598 |
+
return text_outputs
|
| 599 |
+
|
| 600 |
+
@can_return_tuple
|
| 601 |
+
@auto_docstring
|
| 602 |
+
def get_image_features(
|
| 603 |
+
self,
|
| 604 |
+
pixel_values: torch.FloatTensor | None = None,
|
| 605 |
+
interpolate_pos_encoding: bool = False,
|
| 606 |
+
**kwargs: Unpack[TransformersKwargs],
|
| 607 |
+
) -> tuple | BaseModelOutputWithPooling:
|
| 608 |
+
r"""
|
| 609 |
+
Examples:
|
| 610 |
+
|
| 611 |
+
```python
|
| 612 |
+
>>> from PIL import Image
|
| 613 |
+
>>> import httpx
|
| 614 |
+
>>> from io import BytesIO
|
| 615 |
+
>>> from transformers import AutoProcessor, BlipModel
|
| 616 |
+
|
| 617 |
+
>>> model = BlipModel.from_pretrained("Salesforce/blip-image-captioning-base")
|
| 618 |
+
>>> processor = AutoProcessor.from_pretrained("Salesforce/blip-image-captioning-base")
|
| 619 |
+
|
| 620 |
+
>>> url = "http://images.cocodataset.org/val2017/000000039769.jpg"
|
| 621 |
+
>>> with httpx.stream("GET", url) as response:
|
| 622 |
+
... image = Image.open(BytesIO(response.read()))
|
| 623 |
+
|
| 624 |
+
>>> inputs = processor(images=image, return_tensors="pt")
|
| 625 |
+
|
| 626 |
+
>>> image_features = model.get_image_features(**inputs)
|
| 627 |
+
```"""
|
| 628 |
+
|
| 629 |
+
vision_outputs: BaseModelOutputWithPooling = self.vision_model(
|
| 630 |
+
pixel_values=pixel_values,
|
| 631 |
+
interpolate_pos_encoding=interpolate_pos_encoding,
|
| 632 |
+
return_dict=True,
|
| 633 |
+
**kwargs,
|
| 634 |
+
)
|
| 635 |
+
pooled_output = vision_outputs.pooler_output
|
| 636 |
+
vision_outputs.pooler_output = self.visual_projection(pooled_output)
|
| 637 |
+
|
| 638 |
+
return vision_outputs
|
| 639 |
+
|
| 640 |
+
@auto_docstring
|
| 641 |
+
def get_multimodal_features(
|
| 642 |
+
self,
|
| 643 |
+
input_ids: torch.LongTensor | None = None,
|
| 644 |
+
pixel_values: torch.FloatTensor | None = None,
|
| 645 |
+
attention_mask: torch.Tensor | None = None,
|
| 646 |
+
interpolate_pos_encoding: bool = False,
|
| 647 |
+
) -> torch.FloatTensor:
|
| 648 |
+
r"""
|
| 649 |
+
Returns:
|
| 650 |
+
multimodal_features (`torch.FloatTensor` of shape `(batch_size, output_dim`): The multimodal embeddings
|
| 651 |
+
obtained by applying the image embeddings to the text encoder using the cross-attention mechanism.
|
| 652 |
+
|
| 653 |
+
Examples:
|
| 654 |
+
```python
|
| 655 |
+
>>> from PIL import Image
|
| 656 |
+
>>> import httpx
|
| 657 |
+
>>> from io import BytesIO
|
| 658 |
+
>>> from transformers import AutoProcessor, BlipModel
|
| 659 |
+
|
| 660 |
+
>>> model = BlipModel.from_pretrained("Salesforce/blip-image-captioning-base")
|
| 661 |
+
>>> processor = AutoProcessor.from_pretrained("Salesforce/blip-image-captioning-base")
|
| 662 |
+
|
| 663 |
+
>>> url = "http://images.cocodataset.org/val2017/000000039769.jpg"
|
| 664 |
+
>>> with httpx.stream("GET", url) as response:
|
| 665 |
+
... image = Image.open(BytesIO(response.read()))
|
| 666 |
+
>>> texts = ["a photo of a cat", "a photo of a dog"]
|
| 667 |
+
>>> inputs = processor(images=image, text=texts, padding=True, return_tensors="pt")
|
| 668 |
+
|
| 669 |
+
>>> multimodal_features = model.get_multimodal_features(**inputs)
|
| 670 |
+
```"""
|
| 671 |
+
vision_outputs = self.vision_model(
|
| 672 |
+
pixel_values=pixel_values,
|
| 673 |
+
interpolate_pos_encoding=interpolate_pos_encoding,
|
| 674 |
+
)
|
| 675 |
+
|
| 676 |
+
image_embeds = vision_outputs[0]
|
| 677 |
+
image_atts = torch.ones(image_embeds.size()[:-1], dtype=torch.long)
|
| 678 |
+
|
| 679 |
+
text_outputs = self.text_model(
|
| 680 |
+
input_ids=input_ids,
|
| 681 |
+
attention_mask=attention_mask,
|
| 682 |
+
encoder_hidden_states=image_embeds,
|
| 683 |
+
encoder_attention_mask=image_atts,
|
| 684 |
+
)
|
| 685 |
+
|
| 686 |
+
pooled_output = text_outputs[1] # pooled_output
|
| 687 |
+
multimodal_features = self.text_projection(pooled_output)
|
| 688 |
+
|
| 689 |
+
return multimodal_features
|
| 690 |
+
|
| 691 |
+
@can_return_tuple
|
| 692 |
+
@auto_docstring
|
| 693 |
+
def forward(
|
| 694 |
+
self,
|
| 695 |
+
input_ids: torch.LongTensor | None = None,
|
| 696 |
+
pixel_values: torch.FloatTensor | None = None,
|
| 697 |
+
attention_mask: torch.Tensor | None = None,
|
| 698 |
+
position_ids: torch.LongTensor | None = None,
|
| 699 |
+
return_loss: bool | None = None,
|
| 700 |
+
interpolate_pos_encoding: bool = False,
|
| 701 |
+
**kwargs: Unpack[TransformersKwargs],
|
| 702 |
+
) -> tuple | BlipOutput:
|
| 703 |
+
r"""
|
| 704 |
+
return_loss (`bool`, *optional*):
|
| 705 |
+
Whether or not to return the contrastive loss.
|
| 706 |
+
|
| 707 |
+
Examples:
|
| 708 |
+
|
| 709 |
+
```python
|
| 710 |
+
>>> from PIL import Image
|
| 711 |
+
>>> import httpx
|
| 712 |
+
>>> from io import BytesIO
|
| 713 |
+
>>> from transformers import AutoProcessor, BlipModel
|
| 714 |
+
|
| 715 |
+
>>> model = BlipModel.from_pretrained("Salesforce/blip-image-captioning-base")
|
| 716 |
+
>>> processor = AutoProcessor.from_pretrained("Salesforce/blip-image-captioning-base")
|
| 717 |
+
|
| 718 |
+
>>> url = "http://images.cocodataset.org/val2017/000000039769.jpg"
|
| 719 |
+
>>> with httpx.stream("GET", url) as response:
|
| 720 |
+
... image = Image.open(BytesIO(response.read()))
|
| 721 |
+
|
| 722 |
+
>>> inputs = processor(
|
| 723 |
+
... text=["a photo of a cat", "a photo of a dog"], images=image, return_tensors="pt", padding=True
|
| 724 |
+
... )
|
| 725 |
+
|
| 726 |
+
>>> outputs = model(**inputs)
|
| 727 |
+
>>> logits_per_image = outputs.logits_per_image # this is the image-text similarity score
|
| 728 |
+
>>> probs = logits_per_image.softmax(dim=1) # we can take the softmax to get the label probabilities
|
| 729 |
+
```"""
|
| 730 |
+
vision_outputs = self.vision_model(
|
| 731 |
+
pixel_values=pixel_values,
|
| 732 |
+
interpolate_pos_encoding=interpolate_pos_encoding,
|
| 733 |
+
**kwargs,
|
| 734 |
+
)
|
| 735 |
+
|
| 736 |
+
text_outputs = self.text_model(
|
| 737 |
+
input_ids=input_ids,
|
| 738 |
+
attention_mask=attention_mask,
|
| 739 |
+
position_ids=position_ids,
|
| 740 |
+
**kwargs,
|
| 741 |
+
)
|
| 742 |
+
|
| 743 |
+
image_embeds = vision_outputs.pooler_output
|
| 744 |
+
image_embeds = self.visual_projection(image_embeds)
|
| 745 |
+
|
| 746 |
+
text_embeds = text_outputs.pooler_output
|
| 747 |
+
text_embeds = self.text_projection(text_embeds)
|
| 748 |
+
|
| 749 |
+
# normalized features
|
| 750 |
+
image_embeds = image_embeds / image_embeds.norm(p=2, dim=-1, keepdim=True)
|
| 751 |
+
text_embeds = text_embeds / text_embeds.norm(p=2, dim=-1, keepdim=True)
|
| 752 |
+
|
| 753 |
+
# cosine similarity as logits
|
| 754 |
+
logit_scale = self.logit_scale.exp().to(device=text_embeds.device)
|
| 755 |
+
image_embeds = image_embeds.to(device=text_embeds.device, dtype=text_embeds.dtype)
|
| 756 |
+
logits_per_text = torch.matmul(text_embeds, image_embeds.t()) * logit_scale
|
| 757 |
+
logits_per_image = logits_per_text.t()
|
| 758 |
+
|
| 759 |
+
loss = None
|
| 760 |
+
if return_loss:
|
| 761 |
+
loss = blip_loss(logits_per_text)
|
| 762 |
+
|
| 763 |
+
return BlipOutput(
|
| 764 |
+
loss=loss,
|
| 765 |
+
logits_per_image=logits_per_image,
|
| 766 |
+
logits_per_text=logits_per_text,
|
| 767 |
+
text_embeds=text_embeds,
|
| 768 |
+
image_embeds=image_embeds,
|
| 769 |
+
text_model_output=text_outputs,
|
| 770 |
+
vision_model_output=vision_outputs,
|
| 771 |
+
)
|
| 772 |
+
|
| 773 |
+
|
| 774 |
+
@auto_docstring(
|
| 775 |
+
custom_intro="""
|
| 776 |
+
BLIP Model for image captioning. The model consists of a vision encoder and a text decoder. One can optionally pass
|
| 777 |
+
`input_ids` to the model, which serve as a text prompt, to make the text decoder continue the prompt. Otherwise,
|
| 778 |
+
the decoder starts generating text from the [BOS] (beginning-of-sequence) token. will start generating the caption
|
| 779 |
+
from the text input. If no text input is provided, the decoder will start with the [BOS] token only.
|
| 780 |
+
"""
|
| 781 |
+
)
|
| 782 |
+
class BlipForConditionalGeneration(BlipPreTrainedModel, GenerationMixin):
|
| 783 |
+
config: BlipConfig
|
| 784 |
+
main_input_name = "pixel_values"
|
| 785 |
+
_tied_weights_keys = {
|
| 786 |
+
"text_decoder.cls.predictions.decoder.bias": "text_decoder.cls.predictions.bias",
|
| 787 |
+
"text_decoder.cls.predictions.decoder.weight": "text_decoder.bert.embeddings.word_embeddings.weight",
|
| 788 |
+
} # TODO @arthurzucker check why we need this when for other models, their subPreTrainedModel handle it themselves.
|
| 789 |
+
|
| 790 |
+
def __init__(self, config: BlipConfig):
|
| 791 |
+
super().__init__(config)
|
| 792 |
+
|
| 793 |
+
self.vision_model = BlipVisionModel(config.vision_config)
|
| 794 |
+
|
| 795 |
+
self.text_decoder = BlipTextLMHeadModel(config.text_config)
|
| 796 |
+
|
| 797 |
+
self.decoder_input_ids = config.text_config.bos_token_id
|
| 798 |
+
self.decoder_pad_token_id = config.text_config.pad_token_id
|
| 799 |
+
|
| 800 |
+
# Initialize weights and apply final processing
|
| 801 |
+
self.post_init()
|
| 802 |
+
|
| 803 |
+
def get_input_embeddings(self):
|
| 804 |
+
return self.text_decoder.get_input_embeddings()
|
| 805 |
+
|
| 806 |
+
def set_input_embeddings(self, value):
|
| 807 |
+
self.text_decoder.set_input_embeddings(value)
|
| 808 |
+
|
| 809 |
+
@can_return_tuple
|
| 810 |
+
@auto_docstring
|
| 811 |
+
def forward(
|
| 812 |
+
self,
|
| 813 |
+
pixel_values: torch.FloatTensor,
|
| 814 |
+
input_ids: torch.LongTensor | None = None,
|
| 815 |
+
attention_mask: torch.LongTensor | None = None,
|
| 816 |
+
labels: torch.LongTensor | None = None,
|
| 817 |
+
interpolate_pos_encoding: bool = False,
|
| 818 |
+
logits_to_keep: int | torch.Tensor = 0,
|
| 819 |
+
**kwargs: Unpack[TransformersKwargs],
|
| 820 |
+
) -> tuple | BlipForConditionalGenerationModelOutput:
|
| 821 |
+
r"""
|
| 822 |
+
Examples:
|
| 823 |
+
|
| 824 |
+
```python
|
| 825 |
+
>>> from PIL import Image
|
| 826 |
+
>>> import httpx
|
| 827 |
+
>>> from io import BytesIO
|
| 828 |
+
>>> from transformers import AutoProcessor, BlipForConditionalGeneration
|
| 829 |
+
|
| 830 |
+
>>> processor = AutoProcessor.from_pretrained("Salesforce/blip-image-captioning-base")
|
| 831 |
+
>>> model = BlipForConditionalGeneration.from_pretrained("Salesforce/blip-image-captioning-base")
|
| 832 |
+
|
| 833 |
+
>>> url = "http://images.cocodataset.org/val2017/000000039769.jpg"
|
| 834 |
+
>>> with httpx.stream("GET", url) as response:
|
| 835 |
+
... image = Image.open(BytesIO(response.read()))
|
| 836 |
+
>>> text = "A picture of"
|
| 837 |
+
|
| 838 |
+
>>> inputs = processor(images=image, text=text, return_tensors="pt")
|
| 839 |
+
|
| 840 |
+
>>> outputs = model(**inputs)
|
| 841 |
+
```"""
|
| 842 |
+
|
| 843 |
+
vision_outputs = self.vision_model(
|
| 844 |
+
pixel_values=pixel_values,
|
| 845 |
+
interpolate_pos_encoding=interpolate_pos_encoding,
|
| 846 |
+
**kwargs,
|
| 847 |
+
)
|
| 848 |
+
|
| 849 |
+
image_embeds = vision_outputs.last_hidden_state
|
| 850 |
+
|
| 851 |
+
outputs = self.text_decoder(
|
| 852 |
+
input_ids=input_ids,
|
| 853 |
+
attention_mask=attention_mask,
|
| 854 |
+
encoder_hidden_states=image_embeds,
|
| 855 |
+
labels=labels,
|
| 856 |
+
reduction="mean",
|
| 857 |
+
logits_to_keep=logits_to_keep,
|
| 858 |
+
**kwargs,
|
| 859 |
+
)
|
| 860 |
+
|
| 861 |
+
return BlipForConditionalGenerationModelOutput(
|
| 862 |
+
loss=outputs.loss,
|
| 863 |
+
logits=outputs.logits,
|
| 864 |
+
image_embeds=image_embeds,
|
| 865 |
+
last_hidden_state=vision_outputs.last_hidden_state,
|
| 866 |
+
hidden_states=vision_outputs.hidden_states,
|
| 867 |
+
attentions=vision_outputs.attentions,
|
| 868 |
+
)
|
| 869 |
+
|
| 870 |
+
@torch.no_grad()
|
| 871 |
+
def generate(
|
| 872 |
+
self,
|
| 873 |
+
pixel_values: torch.FloatTensor,
|
| 874 |
+
input_ids: torch.LongTensor | None = None,
|
| 875 |
+
attention_mask: torch.LongTensor | None = None,
|
| 876 |
+
interpolate_pos_encoding: bool = False,
|
| 877 |
+
**generate_kwargs,
|
| 878 |
+
) -> torch.LongTensor:
|
| 879 |
+
r"""
|
| 880 |
+
Overrides *generate* function to be able to use the model as a conditional generator
|
| 881 |
+
|
| 882 |
+
Parameters:
|
| 883 |
+
pixel_values (*torch.FloatTensor* of shape *(batch_size, num_channels, image_height, image_width)*:
|
| 884 |
+
Input image to be processed
|
| 885 |
+
input_ids (*torch.LongTensor* of shape *(batch_size, sequence_length)*, *optional*):
|
| 886 |
+
The sequence used as a prompt for the generation.
|
| 887 |
+
attention_mask (*torch.LongTensor* of shape *(batch_size, sequence_length)*, *optional*):
|
| 888 |
+
Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`:
|
| 889 |
+
|
| 890 |
+
|
| 891 |
+
Examples:
|
| 892 |
+
```python
|
| 893 |
+
>>> from PIL import Image
|
| 894 |
+
>>> import httpx
|
| 895 |
+
>>> from io import BytesIO
|
| 896 |
+
>>> from transformers import AutoProcessor, BlipForConditionalGeneration
|
| 897 |
+
|
| 898 |
+
>>> model = BlipForConditionalGeneration.from_pretrained("Salesforce/blip-image-captioning-base")
|
| 899 |
+
>>> processor = AutoProcessor.from_pretrained("Salesforce/blip-image-captioning-base")
|
| 900 |
+
|
| 901 |
+
>>> url = "http://images.cocodataset.org/val2017/000000039769.jpg"
|
| 902 |
+
>>> with httpx.stream("GET", url) as response:
|
| 903 |
+
... image = Image.open(BytesIO(response.read()))
|
| 904 |
+
|
| 905 |
+
>>> inputs = processor(images=image, return_tensors="pt")
|
| 906 |
+
|
| 907 |
+
>>> outputs = model.generate(**inputs)
|
| 908 |
+
>>> print(processor.decode(outputs[0], skip_special_tokens=True))
|
| 909 |
+
two cats sleeping on a couch
|
| 910 |
+
```
|
| 911 |
+
"""
|
| 912 |
+
|
| 913 |
+
batch_size = pixel_values.shape[0]
|
| 914 |
+
vision_outputs = self.vision_model(
|
| 915 |
+
pixel_values=pixel_values,
|
| 916 |
+
interpolate_pos_encoding=interpolate_pos_encoding,
|
| 917 |
+
)
|
| 918 |
+
|
| 919 |
+
image_embeds = vision_outputs[0]
|
| 920 |
+
|
| 921 |
+
image_attention_mask = torch.ones(image_embeds.size()[:-1], dtype=torch.long, device=image_embeds.device)
|
| 922 |
+
|
| 923 |
+
if isinstance(input_ids, list):
|
| 924 |
+
input_ids = torch.LongTensor(input_ids)
|
| 925 |
+
elif input_ids is None:
|
| 926 |
+
input_ids = (
|
| 927 |
+
torch.LongTensor([[self.decoder_input_ids, self.config.text_config.eos_token_id]])
|
| 928 |
+
.repeat(batch_size, 1)
|
| 929 |
+
.to(image_embeds.device)
|
| 930 |
+
)
|
| 931 |
+
|
| 932 |
+
input_ids[:, 0] = self.config.text_config.bos_token_id
|
| 933 |
+
attention_mask = attention_mask[:, :-1] if attention_mask is not None else None
|
| 934 |
+
|
| 935 |
+
outputs = self.text_decoder.generate(
|
| 936 |
+
input_ids=input_ids[:, :-1],
|
| 937 |
+
eos_token_id=self.config.text_config.sep_token_id,
|
| 938 |
+
pad_token_id=self.config.text_config.pad_token_id,
|
| 939 |
+
attention_mask=attention_mask,
|
| 940 |
+
encoder_hidden_states=image_embeds,
|
| 941 |
+
encoder_attention_mask=image_attention_mask,
|
| 942 |
+
**generate_kwargs,
|
| 943 |
+
)
|
| 944 |
+
|
| 945 |
+
return outputs
|
| 946 |
+
|
| 947 |
+
|
| 948 |
+
@auto_docstring(
|
| 949 |
+
custom_intro="""
|
| 950 |
+
BLIP Model for visual question answering. The model consists of a vision encoder, a text encoder as well as a text
|
| 951 |
+
decoder. The vision encoder will encode the input image, the text encoder will encode the input question together
|
| 952 |
+
with the encoding of the image, and the text decoder will output the answer to the question.
|
| 953 |
+
"""
|
| 954 |
+
)
|
| 955 |
+
class BlipForQuestionAnswering(BlipPreTrainedModel, GenerationMixin):
|
| 956 |
+
config: BlipConfig
|
| 957 |
+
_tied_weights_keys = {
|
| 958 |
+
"text_decoder.cls.predictions.decoder.bias": "text_decoder.cls.predictions.bias",
|
| 959 |
+
"text_decoder.cls.predictions.decoder.weight": "text_decoder.bert.embeddings.word_embeddings.weight",
|
| 960 |
+
}
|
| 961 |
+
|
| 962 |
+
def __init__(self, config: BlipConfig):
|
| 963 |
+
super().__init__(config)
|
| 964 |
+
|
| 965 |
+
self.vision_model = BlipVisionModel(config.vision_config)
|
| 966 |
+
|
| 967 |
+
self.text_encoder = BlipTextModel(config.text_config, add_pooling_layer=False)
|
| 968 |
+
self.text_decoder = BlipTextLMHeadModel(config.text_config)
|
| 969 |
+
|
| 970 |
+
self.decoder_pad_token_id = config.text_config.pad_token_id
|
| 971 |
+
self.decoder_start_token_id = config.text_config.bos_token_id
|
| 972 |
+
|
| 973 |
+
# Initialize weights and apply final processing
|
| 974 |
+
self.post_init()
|
| 975 |
+
|
| 976 |
+
def set_input_embeddings(self, value):
|
| 977 |
+
self.text_encoder.set_input_embeddings(value)
|
| 978 |
+
|
| 979 |
+
def get_input_embeddings(self):
|
| 980 |
+
# This will return shared embeddings if they are shared else specific to encoder.
|
| 981 |
+
return self.text_encoder.get_input_embeddings()
|
| 982 |
+
|
| 983 |
+
@can_return_tuple
|
| 984 |
+
@auto_docstring
|
| 985 |
+
def forward(
|
| 986 |
+
self,
|
| 987 |
+
input_ids: torch.LongTensor,
|
| 988 |
+
pixel_values: torch.FloatTensor,
|
| 989 |
+
decoder_input_ids: torch.LongTensor | None = None,
|
| 990 |
+
decoder_attention_mask: torch.LongTensor | None = None,
|
| 991 |
+
attention_mask: torch.LongTensor | None = None,
|
| 992 |
+
labels: torch.LongTensor | None = None,
|
| 993 |
+
interpolate_pos_encoding: bool = False,
|
| 994 |
+
**kwargs: Unpack[TransformersKwargs],
|
| 995 |
+
) -> tuple | BlipTextVisionModelOutput:
|
| 996 |
+
r"""
|
| 997 |
+
Examples:
|
| 998 |
+
|
| 999 |
+
```python
|
| 1000 |
+
>>> from PIL import Image
|
| 1001 |
+
>>> import httpx
|
| 1002 |
+
>>> from io import BytesIO
|
| 1003 |
+
>>> from transformers import AutoProcessor, BlipForQuestionAnswering
|
| 1004 |
+
|
| 1005 |
+
>>> model = BlipForQuestionAnswering.from_pretrained("Salesforce/blip-vqa-base")
|
| 1006 |
+
>>> processor = AutoProcessor.from_pretrained("Salesforce/blip-vqa-base")
|
| 1007 |
+
|
| 1008 |
+
>>> url = "http://images.cocodataset.org/val2017/000000039769.jpg"
|
| 1009 |
+
>>> with httpx.stream("GET", url) as response:
|
| 1010 |
+
... image = Image.open(BytesIO(response.read()))
|
| 1011 |
+
|
| 1012 |
+
>>> # training
|
| 1013 |
+
>>> text = "How many cats are in the picture?"
|
| 1014 |
+
>>> label = "2"
|
| 1015 |
+
>>> inputs = processor(images=image, text=text, return_tensors="pt")
|
| 1016 |
+
>>> labels = processor(text=label, return_tensors="pt").input_ids
|
| 1017 |
+
|
| 1018 |
+
>>> inputs["labels"] = labels
|
| 1019 |
+
>>> outputs = model(**inputs)
|
| 1020 |
+
>>> loss = outputs.loss
|
| 1021 |
+
>>> loss.backward()
|
| 1022 |
+
|
| 1023 |
+
>>> # inference
|
| 1024 |
+
>>> text = "How many cats are in the picture?"
|
| 1025 |
+
>>> inputs = processor(images=image, text=text, return_tensors="pt")
|
| 1026 |
+
>>> outputs = model.generate(**inputs)
|
| 1027 |
+
>>> print(processor.decode(outputs[0], skip_special_tokens=True))
|
| 1028 |
+
2
|
| 1029 |
+
```"""
|
| 1030 |
+
if labels is None and decoder_input_ids is None:
|
| 1031 |
+
raise ValueError(
|
| 1032 |
+
"Either `decoder_input_ids` or `labels` should be passed when calling `forward` with"
|
| 1033 |
+
" `BlipForQuestionAnswering`. if you are training the model make sure that `labels` is passed, if you"
|
| 1034 |
+
" are using the model for inference make sure that `decoder_input_ids` is passed or call `generate`"
|
| 1035 |
+
)
|
| 1036 |
+
|
| 1037 |
+
vision_outputs = self.vision_model(
|
| 1038 |
+
pixel_values=pixel_values,
|
| 1039 |
+
interpolate_pos_encoding=interpolate_pos_encoding,
|
| 1040 |
+
**kwargs,
|
| 1041 |
+
)
|
| 1042 |
+
|
| 1043 |
+
image_embeds = vision_outputs.last_hidden_state
|
| 1044 |
+
image_attention_mask = torch.ones(image_embeds.size()[:-1], dtype=torch.long)
|
| 1045 |
+
|
| 1046 |
+
question_embeds = self.text_encoder(
|
| 1047 |
+
input_ids=input_ids,
|
| 1048 |
+
attention_mask=attention_mask,
|
| 1049 |
+
encoder_hidden_states=image_embeds,
|
| 1050 |
+
encoder_attention_mask=image_attention_mask,
|
| 1051 |
+
**kwargs,
|
| 1052 |
+
)
|
| 1053 |
+
|
| 1054 |
+
if labels is not None and decoder_input_ids is None:
|
| 1055 |
+
# labels are already shifted right, see: https://github.com/huggingface/transformers/pull/23153
|
| 1056 |
+
decoder_input_ids = labels
|
| 1057 |
+
|
| 1058 |
+
question_embeds = question_embeds[0]
|
| 1059 |
+
|
| 1060 |
+
answer_output = self.text_decoder(
|
| 1061 |
+
input_ids=decoder_input_ids,
|
| 1062 |
+
attention_mask=decoder_attention_mask,
|
| 1063 |
+
encoder_hidden_states=question_embeds,
|
| 1064 |
+
encoder_attention_mask=attention_mask,
|
| 1065 |
+
labels=labels,
|
| 1066 |
+
reduction="mean",
|
| 1067 |
+
**kwargs,
|
| 1068 |
+
)
|
| 1069 |
+
|
| 1070 |
+
if labels is not None:
|
| 1071 |
+
decoder_loss = answer_output.loss.mean()
|
| 1072 |
+
else:
|
| 1073 |
+
decoder_loss = None
|
| 1074 |
+
|
| 1075 |
+
return BlipTextVisionModelOutput(
|
| 1076 |
+
loss=decoder_loss,
|
| 1077 |
+
image_embeds=image_embeds,
|
| 1078 |
+
last_hidden_state=vision_outputs.last_hidden_state,
|
| 1079 |
+
hidden_states=vision_outputs.hidden_states,
|
| 1080 |
+
attentions=vision_outputs.attentions,
|
| 1081 |
+
)
|
| 1082 |
+
|
| 1083 |
+
@torch.no_grad()
|
| 1084 |
+
def generate(
|
| 1085 |
+
self,
|
| 1086 |
+
input_ids: torch.LongTensor,
|
| 1087 |
+
pixel_values: torch.FloatTensor,
|
| 1088 |
+
attention_mask: torch.LongTensor | None = None,
|
| 1089 |
+
interpolate_pos_encoding: bool = False,
|
| 1090 |
+
**generate_kwargs,
|
| 1091 |
+
) -> torch.LongTensor:
|
| 1092 |
+
r"""
|
| 1093 |
+
Overrides *generate* function to be able to use the model as a conditional generator
|
| 1094 |
+
|
| 1095 |
+
Parameters:
|
| 1096 |
+
input_ids (*torch.LongTensor* of shape *(batch_size, sequence_length)*):
|
| 1097 |
+
The sequence used as a prompt for the generation.
|
| 1098 |
+
pixel_values (*torch.FloatTensor* of shape *(batch_size, num_channels, image_height, image_width)*:
|
| 1099 |
+
Input image to be processed
|
| 1100 |
+
attention_mask (*torch.LongTensor* of shape *(batch_size, sequence_length)*, *optional*):
|
| 1101 |
+
Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`. `1` for
|
| 1102 |
+
tokens that are NOT MASKED, `0` for MASKED tokens.
|
| 1103 |
+
**generate_kwargs:
|
| 1104 |
+
Additional arguments passed to the *generate* function of the decoder
|
| 1105 |
+
|
| 1106 |
+
|
| 1107 |
+
Examples:
|
| 1108 |
+
```python
|
| 1109 |
+
>>> from PIL import Image
|
| 1110 |
+
>>> import httpx
|
| 1111 |
+
>>> from io import BytesIO
|
| 1112 |
+
>>> from transformers import AutoProcessor, BlipForQuestionAnswering
|
| 1113 |
+
|
| 1114 |
+
>>> model = BlipForQuestionAnswering.from_pretrained("Salesforce/blip-vqa-base")
|
| 1115 |
+
>>> processor = AutoProcessor.from_pretrained("Salesforce/blip-vqa-base")
|
| 1116 |
+
|
| 1117 |
+
>>> url = "http://images.cocodataset.org/val2017/000000039769.jpg"
|
| 1118 |
+
>>> with httpx.stream("GET", url) as response:
|
| 1119 |
+
... image = Image.open(BytesIO(response.read()))
|
| 1120 |
+
>>> text = "How many cats are in the picture?"
|
| 1121 |
+
|
| 1122 |
+
>>> inputs = processor(images=image, text=text, return_tensors="pt")
|
| 1123 |
+
|
| 1124 |
+
>>> outputs = model.generate(**inputs)
|
| 1125 |
+
>>> print(processor.decode(outputs[0], skip_special_tokens=True))
|
| 1126 |
+
2
|
| 1127 |
+
```
|
| 1128 |
+
"""
|
| 1129 |
+
vision_outputs = self.vision_model(
|
| 1130 |
+
pixel_values=pixel_values,
|
| 1131 |
+
interpolate_pos_encoding=interpolate_pos_encoding,
|
| 1132 |
+
)
|
| 1133 |
+
|
| 1134 |
+
image_embeds = vision_outputs[0]
|
| 1135 |
+
|
| 1136 |
+
image_attention_mask = torch.ones(image_embeds.size()[:-1], dtype=torch.long, device=image_embeds.device)
|
| 1137 |
+
|
| 1138 |
+
if isinstance(input_ids, list):
|
| 1139 |
+
input_ids = torch.LongTensor(input_ids)
|
| 1140 |
+
|
| 1141 |
+
question_outputs = self.text_encoder(
|
| 1142 |
+
input_ids=input_ids,
|
| 1143 |
+
attention_mask=attention_mask,
|
| 1144 |
+
encoder_hidden_states=image_embeds,
|
| 1145 |
+
encoder_attention_mask=image_attention_mask,
|
| 1146 |
+
return_dict=False,
|
| 1147 |
+
)
|
| 1148 |
+
|
| 1149 |
+
question_embeds = question_outputs[0]
|
| 1150 |
+
|
| 1151 |
+
question_attention_mask = torch.ones(
|
| 1152 |
+
question_embeds.size()[:-1], dtype=torch.long, device=question_embeds.device
|
| 1153 |
+
)
|
| 1154 |
+
|
| 1155 |
+
bos_ids = torch.full(
|
| 1156 |
+
(question_embeds.size(0), 1), fill_value=self.decoder_start_token_id, device=question_embeds.device
|
| 1157 |
+
)
|
| 1158 |
+
|
| 1159 |
+
outputs = self.text_decoder.generate(
|
| 1160 |
+
input_ids=bos_ids,
|
| 1161 |
+
eos_token_id=self.config.text_config.sep_token_id,
|
| 1162 |
+
pad_token_id=self.config.text_config.pad_token_id,
|
| 1163 |
+
encoder_hidden_states=question_embeds,
|
| 1164 |
+
encoder_attention_mask=question_attention_mask,
|
| 1165 |
+
**generate_kwargs,
|
| 1166 |
+
)
|
| 1167 |
+
|
| 1168 |
+
return outputs
|
| 1169 |
+
|
| 1170 |
+
|
| 1171 |
+
@auto_docstring(
|
| 1172 |
+
custom_intro="""
|
| 1173 |
+
BLIP Model with a vision and text projector, and a classification head on top. The model is used in the context of
|
| 1174 |
+
image-text retrieval. Given an image and a text, the model returns the probability of the text being relevant to
|
| 1175 |
+
the image.
|
| 1176 |
+
"""
|
| 1177 |
+
)
|
| 1178 |
+
class BlipForImageTextRetrieval(BlipPreTrainedModel):
|
| 1179 |
+
config: BlipConfig
|
| 1180 |
+
|
| 1181 |
+
def __init__(self, config: BlipConfig):
|
| 1182 |
+
super().__init__(config)
|
| 1183 |
+
|
| 1184 |
+
self.vision_model = BlipVisionModel(config.vision_config)
|
| 1185 |
+
|
| 1186 |
+
self.text_encoder = BlipTextModel(config.text_config, add_pooling_layer=False)
|
| 1187 |
+
|
| 1188 |
+
# vision projection layer
|
| 1189 |
+
self.vision_proj = nn.Linear(config.vision_config.hidden_size, config.image_text_hidden_size)
|
| 1190 |
+
|
| 1191 |
+
# text projection layer
|
| 1192 |
+
self.text_proj = nn.Linear(config.text_config.hidden_size, config.image_text_hidden_size)
|
| 1193 |
+
|
| 1194 |
+
# image text matching head
|
| 1195 |
+
self.itm_head = nn.Linear(config.text_config.hidden_size, 2)
|
| 1196 |
+
|
| 1197 |
+
self.decoder_pad_token_id = (
|
| 1198 |
+
config.text_config.pad_token_id
|
| 1199 |
+
if not hasattr(config, "decoder_pad_token_id")
|
| 1200 |
+
else config.decoder_pad_token_id
|
| 1201 |
+
)
|
| 1202 |
+
self.decoder_start_token_id = (
|
| 1203 |
+
config.text_config.bos_token_id
|
| 1204 |
+
if not hasattr(config, "decoder_start_token_id")
|
| 1205 |
+
else config.decoder_start_token_id
|
| 1206 |
+
)
|
| 1207 |
+
|
| 1208 |
+
# Initialize weights and apply final processing
|
| 1209 |
+
self.post_init()
|
| 1210 |
+
|
| 1211 |
+
def get_input_embeddings(self):
|
| 1212 |
+
return self.text_encoder.get_input_embeddings()
|
| 1213 |
+
|
| 1214 |
+
def set_input_embeddings(self, value):
|
| 1215 |
+
self.text_encoder.set_input_embeddings(value)
|
| 1216 |
+
|
| 1217 |
+
@can_return_tuple
|
| 1218 |
+
@auto_docstring
|
| 1219 |
+
def forward(
|
| 1220 |
+
self,
|
| 1221 |
+
input_ids: torch.LongTensor,
|
| 1222 |
+
pixel_values: torch.FloatTensor,
|
| 1223 |
+
use_itm_head: bool | None = True,
|
| 1224 |
+
attention_mask: torch.LongTensor | None = None,
|
| 1225 |
+
interpolate_pos_encoding: bool = False,
|
| 1226 |
+
**kwargs: Unpack[TransformersKwargs],
|
| 1227 |
+
) -> tuple | BlipTextVisionModelOutput:
|
| 1228 |
+
r"""
|
| 1229 |
+
use_itm_head (`bool`, *optional*, defaults to `True`):
|
| 1230 |
+
Whether or not to use the image-text matching head.
|
| 1231 |
+
|
| 1232 |
+
Examples:
|
| 1233 |
+
|
| 1234 |
+
```python
|
| 1235 |
+
>>> from PIL import Image
|
| 1236 |
+
>>> import httpx
|
| 1237 |
+
>>> from io import BytesIO
|
| 1238 |
+
>>> from transformers import AutoProcessor, BlipForImageTextRetrieval
|
| 1239 |
+
|
| 1240 |
+
>>> model = BlipForImageTextRetrieval.from_pretrained("Salesforce/blip-itm-base-coco")
|
| 1241 |
+
>>> processor = AutoProcessor.from_pretrained("Salesforce/blip-itm-base-coco")
|
| 1242 |
+
|
| 1243 |
+
>>> url = "http://images.cocodataset.org/val2017/000000039769.jpg"
|
| 1244 |
+
>>> with httpx.stream("GET", url) as response:
|
| 1245 |
+
... image = Image.open(BytesIO(response.read()))
|
| 1246 |
+
>>> text = "an image of a cat"
|
| 1247 |
+
|
| 1248 |
+
>>> inputs = processor(images=image, text=text, return_tensors="pt")
|
| 1249 |
+
>>> outputs = model(**inputs)
|
| 1250 |
+
```
|
| 1251 |
+
"""
|
| 1252 |
+
vision_outputs = self.vision_model(
|
| 1253 |
+
pixel_values=pixel_values,
|
| 1254 |
+
interpolate_pos_encoding=interpolate_pos_encoding,
|
| 1255 |
+
**kwargs,
|
| 1256 |
+
)
|
| 1257 |
+
|
| 1258 |
+
image_embeds = vision_outputs.last_hidden_state
|
| 1259 |
+
image_atts = torch.ones(image_embeds.size()[:-1], dtype=torch.long)
|
| 1260 |
+
|
| 1261 |
+
if use_itm_head:
|
| 1262 |
+
question_embeds = self.text_encoder(
|
| 1263 |
+
input_ids=input_ids,
|
| 1264 |
+
attention_mask=attention_mask,
|
| 1265 |
+
encoder_hidden_states=image_embeds,
|
| 1266 |
+
encoder_attention_mask=image_atts,
|
| 1267 |
+
**kwargs,
|
| 1268 |
+
)
|
| 1269 |
+
question_embeds = question_embeds.last_hidden_state
|
| 1270 |
+
|
| 1271 |
+
output = self.itm_head(question_embeds[:, 0, :])
|
| 1272 |
+
else:
|
| 1273 |
+
question_embeds = self.text_encoder(
|
| 1274 |
+
input_ids=input_ids,
|
| 1275 |
+
attention_mask=attention_mask,
|
| 1276 |
+
**kwargs,
|
| 1277 |
+
)
|
| 1278 |
+
question_embeds = question_embeds.last_hidden_state
|
| 1279 |
+
|
| 1280 |
+
image_feat = normalize(self.vision_proj(image_embeds[:, 0, :]), dim=-1)
|
| 1281 |
+
text_feat = normalize(self.text_proj(question_embeds[:, 0, :]), dim=-1)
|
| 1282 |
+
|
| 1283 |
+
output = image_feat @ text_feat.t()
|
| 1284 |
+
|
| 1285 |
+
return BlipImageTextMatchingModelOutput(
|
| 1286 |
+
itm_score=output,
|
| 1287 |
+
last_hidden_state=vision_outputs.last_hidden_state,
|
| 1288 |
+
hidden_states=vision_outputs.hidden_states,
|
| 1289 |
+
attentions=vision_outputs.attentions,
|
| 1290 |
+
question_embeds=question_embeds,
|
| 1291 |
+
)
|
| 1292 |
+
|
| 1293 |
+
|
| 1294 |
+
__all__ = [
|
| 1295 |
+
"BlipModel",
|
| 1296 |
+
"BlipPreTrainedModel",
|
| 1297 |
+
"BlipForConditionalGeneration",
|
| 1298 |
+
"BlipForQuestionAnswering",
|
| 1299 |
+
"BlipVisionModel",
|
| 1300 |
+
"BlipTextModel",
|
| 1301 |
+
"BlipForImageTextRetrieval",
|
| 1302 |
+
]
|
third_party/transformers/src/transformers/models/blip/modeling_blip_text.py
ADDED
|
@@ -0,0 +1,801 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright 2022 The Salesforce Team Authors and The HuggingFace Team. All rights reserved.
|
| 2 |
+
#
|
| 3 |
+
# Licensed under the BSD-3-clause license (the "License");
|
| 4 |
+
# you may not use this file except in compliance with the License.
|
| 5 |
+
# You may obtain a copy of the License at
|
| 6 |
+
#
|
| 7 |
+
# https://opensource.org/licenses/BSD-3-Clause
|
| 8 |
+
#
|
| 9 |
+
# Unless required by applicable law or agreed to in writing, software
|
| 10 |
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
| 11 |
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 12 |
+
# See the License for the specific language governing permissions and
|
| 13 |
+
# limitations under the License.
|
| 14 |
+
|
| 15 |
+
|
| 16 |
+
import math
|
| 17 |
+
|
| 18 |
+
import torch
|
| 19 |
+
from torch import Tensor, device, nn
|
| 20 |
+
from torch.nn import CrossEntropyLoss
|
| 21 |
+
|
| 22 |
+
from ... import initialization as init
|
| 23 |
+
from ...activations import ACT2FN
|
| 24 |
+
from ...cache_utils import Cache, DynamicCache, EncoderDecoderCache
|
| 25 |
+
from ...generation import GenerationMixin
|
| 26 |
+
from ...modeling_layers import GradientCheckpointingLayer
|
| 27 |
+
from ...modeling_outputs import (
|
| 28 |
+
BaseModelOutputWithPastAndCrossAttentions,
|
| 29 |
+
BaseModelOutputWithPoolingAndCrossAttentions,
|
| 30 |
+
CausalLMOutputWithCrossAttentions,
|
| 31 |
+
)
|
| 32 |
+
from ...modeling_utils import PreTrainedModel
|
| 33 |
+
from ...processing_utils import Unpack
|
| 34 |
+
from ...pytorch_utils import apply_chunking_to_forward
|
| 35 |
+
from ...utils import TransformersKwargs, can_return_tuple, logging
|
| 36 |
+
from ...utils.generic import merge_with_config_defaults
|
| 37 |
+
from ...utils.output_capturing import OutputRecorder, capture_outputs
|
| 38 |
+
from .configuration_blip import BlipTextConfig
|
| 39 |
+
|
| 40 |
+
|
| 41 |
+
logger = logging.get_logger(__name__)
|
| 42 |
+
|
| 43 |
+
|
| 44 |
+
# Adapted from https://github.com/salesforce/BLIP/blob/main/models/med.py#L52
|
| 45 |
+
class BlipTextEmbeddings(nn.Module):
|
| 46 |
+
"""Construct the embeddings from word and position embeddings."""
|
| 47 |
+
|
| 48 |
+
def __init__(self, config):
|
| 49 |
+
super().__init__()
|
| 50 |
+
self.word_embeddings = nn.Embedding(config.vocab_size, config.hidden_size, padding_idx=config.pad_token_id)
|
| 51 |
+
self.position_embeddings = nn.Embedding(config.max_position_embeddings, config.hidden_size)
|
| 52 |
+
|
| 53 |
+
self.LayerNorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps)
|
| 54 |
+
self.dropout = nn.Dropout(config.hidden_dropout_prob)
|
| 55 |
+
|
| 56 |
+
# position_ids (1, len position emb) is contiguous in memory and exported when serialized
|
| 57 |
+
self.register_buffer(
|
| 58 |
+
"position_ids", torch.arange(config.max_position_embeddings).expand((1, -1)), persistent=False
|
| 59 |
+
)
|
| 60 |
+
|
| 61 |
+
self.config = config
|
| 62 |
+
|
| 63 |
+
def forward(
|
| 64 |
+
self,
|
| 65 |
+
input_ids: torch.LongTensor | None = None,
|
| 66 |
+
position_ids: torch.LongTensor | None = None,
|
| 67 |
+
inputs_embeds: torch.FloatTensor | None = None,
|
| 68 |
+
past_key_values_length: int = 0,
|
| 69 |
+
) -> torch.Tensor:
|
| 70 |
+
if input_ids is not None:
|
| 71 |
+
input_shape = input_ids.size()
|
| 72 |
+
else:
|
| 73 |
+
input_shape = inputs_embeds.size()[:-1]
|
| 74 |
+
|
| 75 |
+
seq_length = input_shape[1]
|
| 76 |
+
|
| 77 |
+
if position_ids is None:
|
| 78 |
+
position_ids = self.position_ids[:, past_key_values_length : seq_length + past_key_values_length]
|
| 79 |
+
|
| 80 |
+
if inputs_embeds is None:
|
| 81 |
+
inputs_embeds = self.word_embeddings(input_ids)
|
| 82 |
+
|
| 83 |
+
embeddings = inputs_embeds
|
| 84 |
+
|
| 85 |
+
position_embeddings = self.position_embeddings(position_ids)
|
| 86 |
+
embeddings += position_embeddings
|
| 87 |
+
|
| 88 |
+
embeddings = self.LayerNorm(embeddings)
|
| 89 |
+
embeddings = self.dropout(embeddings)
|
| 90 |
+
return embeddings
|
| 91 |
+
|
| 92 |
+
|
| 93 |
+
# Adapted from https://github.com/salesforce/BLIP/blob/main/models/med.py#L97
|
| 94 |
+
class BlipTextSelfAttention(nn.Module):
|
| 95 |
+
def __init__(self, config, is_cross_attention, layer_idx=None):
|
| 96 |
+
super().__init__()
|
| 97 |
+
self.config = config
|
| 98 |
+
if config.hidden_size % config.num_attention_heads != 0 and not hasattr(config, "embedding_size"):
|
| 99 |
+
raise ValueError(
|
| 100 |
+
"The hidden size (%d) is not a multiple of the number of attention heads (%d)"
|
| 101 |
+
% (config.hidden_size, config.num_attention_heads)
|
| 102 |
+
)
|
| 103 |
+
|
| 104 |
+
self.num_attention_heads = config.num_attention_heads
|
| 105 |
+
self.attention_head_size = int(config.hidden_size / config.num_attention_heads)
|
| 106 |
+
self.all_head_size = self.num_attention_heads * self.attention_head_size
|
| 107 |
+
self.layer_idx = layer_idx
|
| 108 |
+
|
| 109 |
+
self.query = nn.Linear(config.hidden_size, self.all_head_size)
|
| 110 |
+
if is_cross_attention:
|
| 111 |
+
self.key = nn.Linear(config.encoder_hidden_size, self.all_head_size)
|
| 112 |
+
self.value = nn.Linear(config.encoder_hidden_size, self.all_head_size)
|
| 113 |
+
else:
|
| 114 |
+
self.key = nn.Linear(config.hidden_size, self.all_head_size)
|
| 115 |
+
self.value = nn.Linear(config.hidden_size, self.all_head_size)
|
| 116 |
+
|
| 117 |
+
self.dropout = nn.Dropout(config.attention_probs_dropout_prob)
|
| 118 |
+
|
| 119 |
+
def save_attn_gradients(self, attn_gradients):
|
| 120 |
+
self.attn_gradients = attn_gradients
|
| 121 |
+
|
| 122 |
+
def get_attn_gradients(self):
|
| 123 |
+
return self.attn_gradients
|
| 124 |
+
|
| 125 |
+
def save_attention_map(self, attention_map):
|
| 126 |
+
self.attention_map = attention_map
|
| 127 |
+
|
| 128 |
+
def get_attention_map(self):
|
| 129 |
+
return self.attention_map
|
| 130 |
+
|
| 131 |
+
def forward(
|
| 132 |
+
self,
|
| 133 |
+
hidden_states: torch.Tensor,
|
| 134 |
+
attention_mask: torch.FloatTensor | None = None,
|
| 135 |
+
encoder_hidden_states: torch.FloatTensor | None = None,
|
| 136 |
+
encoder_attention_mask: torch.FloatTensor | None = None,
|
| 137 |
+
past_key_values: Cache | None = None,
|
| 138 |
+
**kwargs: Unpack[TransformersKwargs],
|
| 139 |
+
) -> tuple[torch.Tensor, torch.Tensor]:
|
| 140 |
+
batch_size, seq_length, _ = hidden_states.shape
|
| 141 |
+
query_layer = (
|
| 142 |
+
self.query(hidden_states)
|
| 143 |
+
.view(batch_size, -1, self.num_attention_heads, self.attention_head_size)
|
| 144 |
+
.transpose(1, 2)
|
| 145 |
+
)
|
| 146 |
+
|
| 147 |
+
# If this is instantiated as a cross-attention module, the keys
|
| 148 |
+
# and values come from an encoder; the attention mask needs to be
|
| 149 |
+
# such that the encoder's padding tokens are not attended to.
|
| 150 |
+
is_cross_attention = encoder_hidden_states is not None
|
| 151 |
+
attention_mask = encoder_attention_mask if is_cross_attention else attention_mask
|
| 152 |
+
|
| 153 |
+
is_updated = False
|
| 154 |
+
if past_key_values is not None:
|
| 155 |
+
if isinstance(past_key_values, EncoderDecoderCache):
|
| 156 |
+
is_updated = past_key_values.is_updated.get(self.layer_idx)
|
| 157 |
+
if is_cross_attention:
|
| 158 |
+
# after the first generated id, we can subsequently re-use all key/value_layer from cache
|
| 159 |
+
curr_past_key_values = past_key_values.cross_attention_cache
|
| 160 |
+
else:
|
| 161 |
+
curr_past_key_values = past_key_values.self_attention_cache
|
| 162 |
+
else:
|
| 163 |
+
curr_past_key_values = past_key_values
|
| 164 |
+
|
| 165 |
+
current_states = encoder_hidden_states if is_cross_attention else hidden_states
|
| 166 |
+
if is_cross_attention and past_key_values is not None and is_updated:
|
| 167 |
+
# reuse k,v, cross_attentions
|
| 168 |
+
key_layer = curr_past_key_values.layers[self.layer_idx].keys
|
| 169 |
+
value_layer = curr_past_key_values.layers[self.layer_idx].values
|
| 170 |
+
else:
|
| 171 |
+
key_layer = (
|
| 172 |
+
self.key(current_states)
|
| 173 |
+
.view(batch_size, -1, self.num_attention_heads, self.attention_head_size)
|
| 174 |
+
.transpose(1, 2)
|
| 175 |
+
)
|
| 176 |
+
value_layer = (
|
| 177 |
+
self.value(current_states)
|
| 178 |
+
.view(batch_size, -1, self.num_attention_heads, self.attention_head_size)
|
| 179 |
+
.transpose(1, 2)
|
| 180 |
+
)
|
| 181 |
+
|
| 182 |
+
if past_key_values is not None:
|
| 183 |
+
key_layer, value_layer = curr_past_key_values.update(key_layer, value_layer, self.layer_idx)
|
| 184 |
+
# set flag that curr layer for cross-attn is already updated so we can re-use in subsequent calls
|
| 185 |
+
if is_cross_attention and isinstance(past_key_values, EncoderDecoderCache):
|
| 186 |
+
past_key_values.is_updated[self.layer_idx] = True
|
| 187 |
+
|
| 188 |
+
# Take the dot product between "query" and "key" to get the raw attention scores.
|
| 189 |
+
attention_scores = torch.matmul(query_layer, key_layer.transpose(-1, -2))
|
| 190 |
+
|
| 191 |
+
attention_scores = attention_scores / math.sqrt(self.attention_head_size)
|
| 192 |
+
if attention_mask is not None:
|
| 193 |
+
# Apply the attention mask is (precomputed for all layers in BlipTextModel forward() function)
|
| 194 |
+
attention_scores = attention_scores + attention_mask.to(attention_scores.device)
|
| 195 |
+
|
| 196 |
+
# Normalize the attention scores to probabilities.
|
| 197 |
+
attention_probs = nn.Softmax(dim=-1)(attention_scores)
|
| 198 |
+
|
| 199 |
+
# This is actually dropping out entire tokens to attend to, which might
|
| 200 |
+
# seem a bit unusual, but is taken from the original Transformer paper.
|
| 201 |
+
attention_probs_dropped = self.dropout(attention_probs)
|
| 202 |
+
|
| 203 |
+
context_layer = torch.matmul(attention_probs_dropped, value_layer)
|
| 204 |
+
|
| 205 |
+
context_layer = context_layer.permute(0, 2, 1, 3).contiguous()
|
| 206 |
+
new_context_layer_shape = context_layer.size()[:-2] + (self.all_head_size,)
|
| 207 |
+
context_layer = context_layer.view(*new_context_layer_shape)
|
| 208 |
+
|
| 209 |
+
return context_layer, attention_probs
|
| 210 |
+
|
| 211 |
+
|
| 212 |
+
# Copied from transformers.models.bert.modeling_bert.BertSelfOutput with Bert -> BlipText
|
| 213 |
+
class BlipTextSelfOutput(nn.Module):
|
| 214 |
+
def __init__(self, config):
|
| 215 |
+
super().__init__()
|
| 216 |
+
self.dense = nn.Linear(config.hidden_size, config.hidden_size)
|
| 217 |
+
self.LayerNorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps)
|
| 218 |
+
self.dropout = nn.Dropout(config.hidden_dropout_prob)
|
| 219 |
+
|
| 220 |
+
def forward(self, hidden_states: torch.Tensor, input_tensor: torch.Tensor) -> torch.Tensor:
|
| 221 |
+
hidden_states = self.dense(hidden_states)
|
| 222 |
+
hidden_states = self.dropout(hidden_states)
|
| 223 |
+
hidden_states = self.LayerNorm(hidden_states + input_tensor)
|
| 224 |
+
return hidden_states
|
| 225 |
+
|
| 226 |
+
|
| 227 |
+
# Adapted from https://github.com/salesforce/BLIP/blob/main/models/med.py#242
|
| 228 |
+
class BlipTextAttention(nn.Module):
|
| 229 |
+
def __init__(self, config, is_cross_attention=False, layer_idx=None):
|
| 230 |
+
super().__init__()
|
| 231 |
+
self.self = BlipTextSelfAttention(config, is_cross_attention, layer_idx=layer_idx)
|
| 232 |
+
self.output = BlipTextSelfOutput(config)
|
| 233 |
+
|
| 234 |
+
def forward(
|
| 235 |
+
self,
|
| 236 |
+
hidden_states: torch.Tensor,
|
| 237 |
+
attention_mask: torch.FloatTensor | None = None,
|
| 238 |
+
encoder_hidden_states: torch.FloatTensor | None = None,
|
| 239 |
+
past_key_values: Cache | None = None,
|
| 240 |
+
**kwargs: Unpack[TransformersKwargs],
|
| 241 |
+
) -> tuple[torch.Tensor, torch.Tensor]:
|
| 242 |
+
context_layer, attention_probs = self.self(
|
| 243 |
+
hidden_states,
|
| 244 |
+
attention_mask=attention_mask,
|
| 245 |
+
encoder_hidden_states=encoder_hidden_states,
|
| 246 |
+
past_key_values=past_key_values,
|
| 247 |
+
)
|
| 248 |
+
attention_output = self.output(context_layer, hidden_states)
|
| 249 |
+
return attention_output, attention_probs
|
| 250 |
+
|
| 251 |
+
|
| 252 |
+
# Copied from transformers.models.bert.modeling_bert.BertIntermediate with Bert -> BlipText
|
| 253 |
+
class BlipTextIntermediate(nn.Module):
|
| 254 |
+
def __init__(self, config):
|
| 255 |
+
super().__init__()
|
| 256 |
+
self.dense = nn.Linear(config.hidden_size, config.intermediate_size)
|
| 257 |
+
if isinstance(config.hidden_act, str):
|
| 258 |
+
self.intermediate_act_fn = ACT2FN[config.hidden_act]
|
| 259 |
+
else:
|
| 260 |
+
self.intermediate_act_fn = config.hidden_act
|
| 261 |
+
|
| 262 |
+
def forward(self, hidden_states: torch.Tensor) -> torch.Tensor:
|
| 263 |
+
hidden_states = self.dense(hidden_states)
|
| 264 |
+
hidden_states = self.intermediate_act_fn(hidden_states)
|
| 265 |
+
return hidden_states
|
| 266 |
+
|
| 267 |
+
|
| 268 |
+
# Copied from transformers.models.bert.modeling_bert.BertOutput with Bert -> BlipText
|
| 269 |
+
class BlipTextOutput(nn.Module):
|
| 270 |
+
def __init__(self, config):
|
| 271 |
+
super().__init__()
|
| 272 |
+
self.dense = nn.Linear(config.intermediate_size, config.hidden_size)
|
| 273 |
+
self.LayerNorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps)
|
| 274 |
+
self.dropout = nn.Dropout(config.hidden_dropout_prob)
|
| 275 |
+
|
| 276 |
+
def forward(self, hidden_states: torch.Tensor, input_tensor: torch.Tensor) -> torch.Tensor:
|
| 277 |
+
hidden_states = self.dense(hidden_states)
|
| 278 |
+
hidden_states = self.dropout(hidden_states)
|
| 279 |
+
hidden_states = self.LayerNorm(hidden_states + input_tensor)
|
| 280 |
+
return hidden_states
|
| 281 |
+
|
| 282 |
+
|
| 283 |
+
class BlipTextLayer(GradientCheckpointingLayer):
|
| 284 |
+
def __init__(self, config, layer_num):
|
| 285 |
+
super().__init__()
|
| 286 |
+
self.config = config
|
| 287 |
+
self.chunk_size_feed_forward = config.chunk_size_feed_forward
|
| 288 |
+
self.seq_len_dim = 1
|
| 289 |
+
self.attention = BlipTextAttention(config, layer_idx=layer_num)
|
| 290 |
+
self.layer_num = layer_num
|
| 291 |
+
if self.config.is_decoder:
|
| 292 |
+
self.crossattention = BlipTextAttention(
|
| 293 |
+
config, is_cross_attention=self.config.is_decoder, layer_idx=layer_num
|
| 294 |
+
)
|
| 295 |
+
self.intermediate = BlipTextIntermediate(config)
|
| 296 |
+
self.output = BlipTextOutput(config)
|
| 297 |
+
|
| 298 |
+
def forward(
|
| 299 |
+
self,
|
| 300 |
+
hidden_states: torch.Tensor,
|
| 301 |
+
encoder_hidden_states: torch.FloatTensor | None = None,
|
| 302 |
+
attention_mask: torch.FloatTensor | None = None,
|
| 303 |
+
encoder_attention_mask: torch.FloatTensor | None = None,
|
| 304 |
+
past_key_values: Cache | None = None,
|
| 305 |
+
**kwargs: Unpack[TransformersKwargs],
|
| 306 |
+
) -> torch.Tensor:
|
| 307 |
+
attention_output, _ = self.attention(
|
| 308 |
+
hidden_states,
|
| 309 |
+
attention_mask=attention_mask,
|
| 310 |
+
past_key_values=past_key_values,
|
| 311 |
+
)
|
| 312 |
+
|
| 313 |
+
if encoder_hidden_states is not None:
|
| 314 |
+
attention_output, _ = self.crossattention(
|
| 315 |
+
attention_output,
|
| 316 |
+
attention_mask=encoder_attention_mask,
|
| 317 |
+
encoder_hidden_states=encoder_hidden_states,
|
| 318 |
+
past_key_values=past_key_values,
|
| 319 |
+
)
|
| 320 |
+
layer_output = apply_chunking_to_forward(
|
| 321 |
+
self.feed_forward_chunk, self.chunk_size_feed_forward, self.seq_len_dim, attention_output
|
| 322 |
+
)
|
| 323 |
+
return layer_output
|
| 324 |
+
|
| 325 |
+
def feed_forward_chunk(self, attention_output):
|
| 326 |
+
intermediate_output = self.intermediate(attention_output)
|
| 327 |
+
layer_output = self.output(intermediate_output, attention_output)
|
| 328 |
+
return layer_output
|
| 329 |
+
|
| 330 |
+
|
| 331 |
+
# Adapted from https://github.com/salesforce/BLIP/blob/main/models/med.py#L386
|
| 332 |
+
class BlipTextEncoder(nn.Module):
|
| 333 |
+
def __init__(self, config):
|
| 334 |
+
super().__init__()
|
| 335 |
+
self.config = config
|
| 336 |
+
self.layer = nn.ModuleList([BlipTextLayer(config, i) for i in range(config.num_hidden_layers)])
|
| 337 |
+
self.gradient_checkpointing = False
|
| 338 |
+
|
| 339 |
+
def forward(
|
| 340 |
+
self,
|
| 341 |
+
hidden_states: torch.Tensor,
|
| 342 |
+
attention_mask: torch.FloatTensor | None = None,
|
| 343 |
+
encoder_hidden_states: torch.FloatTensor | None = None,
|
| 344 |
+
encoder_attention_mask: torch.FloatTensor | None = None,
|
| 345 |
+
past_key_values: Cache | None = None,
|
| 346 |
+
use_cache: bool | None = None,
|
| 347 |
+
**kwargs: Unpack[TransformersKwargs],
|
| 348 |
+
) -> BaseModelOutputWithPastAndCrossAttentions:
|
| 349 |
+
if self.gradient_checkpointing and self.training:
|
| 350 |
+
if use_cache:
|
| 351 |
+
logger.warning(
|
| 352 |
+
"`use_cache=True` is incompatible with gradient checkpointing. Setting `use_cache=False`..."
|
| 353 |
+
)
|
| 354 |
+
use_cache = False
|
| 355 |
+
|
| 356 |
+
if use_cache:
|
| 357 |
+
# The model acts as encoder decoder but is not an encoder decoder. So we cast all cache objects to
|
| 358 |
+
# `EncoderDecoderCache` type assuming that the incoming cache is from `self_attention`
|
| 359 |
+
if isinstance(past_key_values, DynamicCache):
|
| 360 |
+
past_key_values = EncoderDecoderCache(past_key_values, DynamicCache(config=self.config))
|
| 361 |
+
elif past_key_values is None:
|
| 362 |
+
past_key_values = EncoderDecoderCache(
|
| 363 |
+
DynamicCache(config=self.config), DynamicCache(config=self.config)
|
| 364 |
+
)
|
| 365 |
+
|
| 366 |
+
for layer_module in self.layer:
|
| 367 |
+
hidden_states = layer_module(
|
| 368 |
+
hidden_states,
|
| 369 |
+
encoder_hidden_states,
|
| 370 |
+
attention_mask=attention_mask,
|
| 371 |
+
encoder_attention_mask=encoder_attention_mask,
|
| 372 |
+
past_key_values=past_key_values,
|
| 373 |
+
**kwargs,
|
| 374 |
+
)
|
| 375 |
+
|
| 376 |
+
return BaseModelOutputWithPastAndCrossAttentions(
|
| 377 |
+
last_hidden_state=hidden_states,
|
| 378 |
+
past_key_values=past_key_values,
|
| 379 |
+
)
|
| 380 |
+
|
| 381 |
+
|
| 382 |
+
# Copied from transformers.models.bert.modeling_bert.BertPooler with Bert->BlipText
|
| 383 |
+
class BlipTextPooler(nn.Module):
|
| 384 |
+
def __init__(self, config):
|
| 385 |
+
super().__init__()
|
| 386 |
+
self.dense = nn.Linear(config.hidden_size, config.hidden_size)
|
| 387 |
+
self.activation = nn.Tanh()
|
| 388 |
+
|
| 389 |
+
def forward(self, hidden_states: torch.Tensor) -> torch.Tensor:
|
| 390 |
+
# We "pool" the model by simply taking the hidden state corresponding
|
| 391 |
+
# to the first token.
|
| 392 |
+
first_token_tensor = hidden_states[:, 0]
|
| 393 |
+
pooled_output = self.dense(first_token_tensor)
|
| 394 |
+
pooled_output = self.activation(pooled_output)
|
| 395 |
+
return pooled_output
|
| 396 |
+
|
| 397 |
+
|
| 398 |
+
# Copied from transformers.models.bert.modeling_bert.BertPredictionHeadTransform with Bert->BlipText
|
| 399 |
+
class BlipTextPredictionHeadTransform(nn.Module):
|
| 400 |
+
def __init__(self, config):
|
| 401 |
+
super().__init__()
|
| 402 |
+
self.dense = nn.Linear(config.hidden_size, config.hidden_size)
|
| 403 |
+
if isinstance(config.hidden_act, str):
|
| 404 |
+
self.transform_act_fn = ACT2FN[config.hidden_act]
|
| 405 |
+
else:
|
| 406 |
+
self.transform_act_fn = config.hidden_act
|
| 407 |
+
self.LayerNorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps)
|
| 408 |
+
|
| 409 |
+
def forward(self, hidden_states: torch.Tensor) -> torch.Tensor:
|
| 410 |
+
hidden_states = self.dense(hidden_states)
|
| 411 |
+
hidden_states = self.transform_act_fn(hidden_states)
|
| 412 |
+
hidden_states = self.LayerNorm(hidden_states)
|
| 413 |
+
return hidden_states
|
| 414 |
+
|
| 415 |
+
|
| 416 |
+
# Copied from transformers.models.bert.modeling_bert.BertLMPredictionHead with Bert->BlipText
|
| 417 |
+
class BlipTextLMPredictionHead(nn.Module):
|
| 418 |
+
def __init__(self, config):
|
| 419 |
+
super().__init__()
|
| 420 |
+
self.transform = BlipTextPredictionHeadTransform(config)
|
| 421 |
+
|
| 422 |
+
# The output weights are the same as the input embeddings, but there is
|
| 423 |
+
# an output-only bias for each token.
|
| 424 |
+
self.decoder = nn.Linear(config.hidden_size, config.vocab_size, bias=True)
|
| 425 |
+
self.bias = nn.Parameter(torch.zeros(config.vocab_size))
|
| 426 |
+
|
| 427 |
+
def forward(self, hidden_states):
|
| 428 |
+
hidden_states = self.transform(hidden_states)
|
| 429 |
+
hidden_states = self.decoder(hidden_states)
|
| 430 |
+
return hidden_states
|
| 431 |
+
|
| 432 |
+
|
| 433 |
+
# Copied from transformers.models.bert.modeling_bert.BertOnlyMLMHead with Bert->BlipText
|
| 434 |
+
class BlipTextOnlyMLMHead(nn.Module):
|
| 435 |
+
def __init__(self, config):
|
| 436 |
+
super().__init__()
|
| 437 |
+
self.predictions = BlipTextLMPredictionHead(config)
|
| 438 |
+
|
| 439 |
+
def forward(self, sequence_output: torch.Tensor) -> torch.Tensor:
|
| 440 |
+
prediction_scores = self.predictions(sequence_output)
|
| 441 |
+
return prediction_scores
|
| 442 |
+
|
| 443 |
+
|
| 444 |
+
# Adapted from https://github.com/salesforce/BLIP/blob/main/models/med.py#L548
|
| 445 |
+
class BlipTextPreTrainedModel(PreTrainedModel):
|
| 446 |
+
"""
|
| 447 |
+
An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained
|
| 448 |
+
models.
|
| 449 |
+
"""
|
| 450 |
+
|
| 451 |
+
config: BlipTextConfig
|
| 452 |
+
base_model_prefix = "bert"
|
| 453 |
+
_no_split_modules = []
|
| 454 |
+
_can_record_outputs = {
|
| 455 |
+
"hidden_states": BlipTextLayer,
|
| 456 |
+
"attentions": [
|
| 457 |
+
OutputRecorder(BlipTextSelfAttention, index=1, layer_name=".attention."),
|
| 458 |
+
],
|
| 459 |
+
"cross_attentions": [
|
| 460 |
+
OutputRecorder(BlipTextSelfAttention, index=1, layer_name=".crossattention."),
|
| 461 |
+
],
|
| 462 |
+
}
|
| 463 |
+
|
| 464 |
+
def _init_weights(self, module):
|
| 465 |
+
super()._init_weights(module)
|
| 466 |
+
if isinstance(module, BlipTextEmbeddings):
|
| 467 |
+
init.copy_(module.position_ids, torch.arange(module.position_ids.shape[-1]).expand((1, -1)))
|
| 468 |
+
|
| 469 |
+
|
| 470 |
+
# Adapted from https://github.com/salesforce/BLIP/blob/3a29b7410476bf5f2ba0955827390eb6ea1f4f9d/models/med.py#L571
|
| 471 |
+
class BlipTextModel(BlipTextPreTrainedModel):
|
| 472 |
+
"""
|
| 473 |
+
The model can behave as an encoder (with only self-attention) as well as a decoder, in which case a layer of
|
| 474 |
+
cross-attention is added between the self-attention layers, following the architecture described in [Attention is
|
| 475 |
+
all you need](https://huggingface.co/papers/1706.03762) by Ashish Vaswani, Noam Shazeer, Niki Parmar, Jakob Uszkoreit,
|
| 476 |
+
Llion Jones, Aidan N. Gomez, Lukasz Kaiser and Illia Polosukhin. argument and `is_decoder` set to `True`; an
|
| 477 |
+
`encoder_hidden_states` is then expected as an input to the forward pass.
|
| 478 |
+
"""
|
| 479 |
+
|
| 480 |
+
def __init__(self, config, add_pooling_layer=True):
|
| 481 |
+
super().__init__(config)
|
| 482 |
+
self.config = config
|
| 483 |
+
|
| 484 |
+
self.embeddings = BlipTextEmbeddings(config)
|
| 485 |
+
self.encoder = BlipTextEncoder(config)
|
| 486 |
+
self.pooler = BlipTextPooler(config) if add_pooling_layer else None
|
| 487 |
+
|
| 488 |
+
self.post_init()
|
| 489 |
+
|
| 490 |
+
def get_input_embeddings(self):
|
| 491 |
+
return self.embeddings.word_embeddings
|
| 492 |
+
|
| 493 |
+
def set_input_embeddings(self, value):
|
| 494 |
+
self.embeddings.word_embeddings = value
|
| 495 |
+
|
| 496 |
+
def get_extended_attention_mask(
|
| 497 |
+
self, attention_mask: Tensor, input_shape: tuple[int], device: device, is_decoder: bool
|
| 498 |
+
) -> Tensor:
|
| 499 |
+
"""
|
| 500 |
+
Makes broadcastable attention and causal masks so that future and masked tokens are ignored.
|
| 501 |
+
|
| 502 |
+
Arguments:
|
| 503 |
+
attention_mask (`torch.Tensor`):
|
| 504 |
+
Mask with ones indicating tokens to attend to, zeros for tokens to ignore.
|
| 505 |
+
input_shape (`tuple[int]`):
|
| 506 |
+
The shape of the input to the model.
|
| 507 |
+
device (`torch.device`):
|
| 508 |
+
The device of the input to the model.
|
| 509 |
+
|
| 510 |
+
Returns:
|
| 511 |
+
`torch.Tensor` The extended attention mask, with a the same dtype as `attention_mask.dtype`.
|
| 512 |
+
"""
|
| 513 |
+
# We can provide a self-attention mask of dimensions [batch_size, from_seq_length, to_seq_length]
|
| 514 |
+
# ourselves in which case we just need to make it broadcastable to all heads.
|
| 515 |
+
if attention_mask.dim() == 3:
|
| 516 |
+
extended_attention_mask = attention_mask[:, None, :, :]
|
| 517 |
+
elif attention_mask.dim() == 2:
|
| 518 |
+
# Provided a padding mask of dimensions [batch_size, seq_length]
|
| 519 |
+
# - if the model is a decoder, apply a causal mask in addition to the padding mask
|
| 520 |
+
# - if the model is an encoder, make the mask broadcastable to [batch_size, num_heads, seq_length, seq_length]
|
| 521 |
+
if is_decoder:
|
| 522 |
+
batch_size, seq_length = input_shape
|
| 523 |
+
|
| 524 |
+
seq_ids = torch.arange(seq_length, device=device)
|
| 525 |
+
causal_mask = seq_ids[None, None, :].repeat(batch_size, seq_length, 1) <= seq_ids[None, :, None]
|
| 526 |
+
# in case past_key_values are used we need to add a prefix ones mask to the causal mask
|
| 527 |
+
causal_mask = causal_mask.to(attention_mask.dtype)
|
| 528 |
+
|
| 529 |
+
if causal_mask.shape[1] < attention_mask.shape[1]:
|
| 530 |
+
prefix_seq_len = attention_mask.shape[1] - causal_mask.shape[1]
|
| 531 |
+
causal_mask = torch.cat(
|
| 532 |
+
[
|
| 533 |
+
torch.ones(
|
| 534 |
+
(batch_size, seq_length, prefix_seq_len), device=device, dtype=causal_mask.dtype
|
| 535 |
+
),
|
| 536 |
+
causal_mask,
|
| 537 |
+
],
|
| 538 |
+
axis=-1,
|
| 539 |
+
)
|
| 540 |
+
|
| 541 |
+
extended_attention_mask = causal_mask[:, None, :, :] * attention_mask[:, None, None, :]
|
| 542 |
+
else:
|
| 543 |
+
extended_attention_mask = attention_mask[:, None, None, :]
|
| 544 |
+
else:
|
| 545 |
+
raise ValueError(
|
| 546 |
+
f"Wrong shape for input_ids (shape {input_shape}) or attention_mask (shape {attention_mask.shape})"
|
| 547 |
+
)
|
| 548 |
+
|
| 549 |
+
# Since attention_mask is 1.0 for positions we want to attend and 0.0 for
|
| 550 |
+
# masked positions, this operation will create a tensor which is 0.0 for
|
| 551 |
+
# positions we want to attend and -10000.0 for masked positions.
|
| 552 |
+
# Since we are adding it to the raw scores before the softmax, this is
|
| 553 |
+
# effectively the same as removing these entirely.
|
| 554 |
+
extended_attention_mask = extended_attention_mask.to(dtype=self.dtype) # fp16 compatibility
|
| 555 |
+
extended_attention_mask = (1.0 - extended_attention_mask) * -10000.0
|
| 556 |
+
return extended_attention_mask
|
| 557 |
+
|
| 558 |
+
@merge_with_config_defaults
|
| 559 |
+
@capture_outputs
|
| 560 |
+
def forward(
|
| 561 |
+
self,
|
| 562 |
+
input_ids: torch.Tensor | None = None,
|
| 563 |
+
attention_mask: torch.Tensor | None = None,
|
| 564 |
+
position_ids: torch.Tensor | None = None,
|
| 565 |
+
inputs_embeds: torch.Tensor | None = None,
|
| 566 |
+
encoder_embeds: torch.Tensor | None = None,
|
| 567 |
+
encoder_hidden_states: torch.Tensor | None = None,
|
| 568 |
+
encoder_attention_mask: torch.Tensor | None = None,
|
| 569 |
+
past_key_values: Cache | None = None,
|
| 570 |
+
use_cache: bool | None = None,
|
| 571 |
+
is_decoder: bool | None = False,
|
| 572 |
+
**kwargs: Unpack[TransformersKwargs],
|
| 573 |
+
) -> BaseModelOutputWithPoolingAndCrossAttentions:
|
| 574 |
+
r"""
|
| 575 |
+
encoder_hidden_states (`torch.FloatTensor`, *optional*):
|
| 576 |
+
Sequence of hidden-states at the output of the last layer of the encoder. Used in the cross-attention if
|
| 577 |
+
the model is configured as a decoder.
|
| 578 |
+
encoder_attention_mask (`torch.FloatTensor`, *optional*):
|
| 579 |
+
Mask to avoid performing attention on the padding token indices of the encoder input. This mask is used in
|
| 580 |
+
the cross-attention if the model is configured as a decoder. Mask values selected in `[0, 1]`:
|
| 581 |
+
- 1 for tokens that are **not masked**,
|
| 582 |
+
- 0 for tokens that are **masked**.
|
| 583 |
+
past_key_values (`Cache`, *optional*):
|
| 584 |
+
Contains precomputed key and value hidden states of the attention blocks. Can be used to speed up decoding.
|
| 585 |
+
If `past_key_values` are used, the user can optionally input only the last `decoder_input_ids` (those that
|
| 586 |
+
don't have their past key value states given to this model) of shape `(batch_size, 1)` instead of all
|
| 587 |
+
`decoder_input_ids` of shape `(batch_size, sequence_length)`.
|
| 588 |
+
use_cache (`bool`, *optional*):
|
| 589 |
+
If set to `True`, `past_key_values` key value states are returned and can be used to speed up decoding (see
|
| 590 |
+
`past_key_values`).
|
| 591 |
+
"""
|
| 592 |
+
if not is_decoder:
|
| 593 |
+
use_cache = False
|
| 594 |
+
|
| 595 |
+
if input_ids is not None and inputs_embeds is not None:
|
| 596 |
+
raise ValueError("You cannot specify both input_ids and inputs_embeds at the same time")
|
| 597 |
+
elif input_ids is not None:
|
| 598 |
+
self.warn_if_padding_and_no_attention_mask(input_ids, attention_mask)
|
| 599 |
+
input_shape = input_ids.size()
|
| 600 |
+
batch_size, seq_length = input_shape
|
| 601 |
+
device = input_ids.device
|
| 602 |
+
elif inputs_embeds is not None:
|
| 603 |
+
input_shape = inputs_embeds.size()[:-1]
|
| 604 |
+
batch_size, seq_length = input_shape
|
| 605 |
+
device = inputs_embeds.device
|
| 606 |
+
elif encoder_embeds is not None:
|
| 607 |
+
input_shape = encoder_embeds.size()[:-1]
|
| 608 |
+
batch_size, seq_length = input_shape
|
| 609 |
+
device = encoder_embeds.device
|
| 610 |
+
else:
|
| 611 |
+
raise ValueError("You have to specify either input_ids or inputs_embeds or encoder_embeds")
|
| 612 |
+
|
| 613 |
+
past_key_values_length = 0 if past_key_values is None else past_key_values.get_seq_length()
|
| 614 |
+
|
| 615 |
+
if attention_mask is None:
|
| 616 |
+
attention_mask = torch.ones((batch_size, seq_length + past_key_values_length)).to(device)
|
| 617 |
+
|
| 618 |
+
# We can provide a self-attention mask of dimensions [batch_size, from_seq_length, to_seq_length]
|
| 619 |
+
# ourselves in which case we just need to make it broadcastable to all heads.
|
| 620 |
+
extended_attention_mask: torch.Tensor = self.get_extended_attention_mask(
|
| 621 |
+
attention_mask, input_shape, device, is_decoder
|
| 622 |
+
)
|
| 623 |
+
|
| 624 |
+
# If a 2D or 3D attention mask is provided for the cross-attention
|
| 625 |
+
# we need to make broadcastable to [batch_size, num_heads, seq_length, seq_length]
|
| 626 |
+
if encoder_hidden_states is not None:
|
| 627 |
+
if isinstance(encoder_hidden_states, list):
|
| 628 |
+
encoder_batch_size, encoder_sequence_length, _ = encoder_hidden_states[0].size()
|
| 629 |
+
else:
|
| 630 |
+
encoder_batch_size, encoder_sequence_length, _ = encoder_hidden_states.size()
|
| 631 |
+
encoder_hidden_shape = (encoder_batch_size, encoder_sequence_length)
|
| 632 |
+
|
| 633 |
+
if isinstance(encoder_attention_mask, list):
|
| 634 |
+
encoder_extended_attention_mask = [self.invert_attention_mask(mask) for mask in encoder_attention_mask]
|
| 635 |
+
elif encoder_attention_mask is None:
|
| 636 |
+
encoder_attention_mask = torch.ones(encoder_hidden_shape, device=device)
|
| 637 |
+
encoder_extended_attention_mask = self.invert_attention_mask(encoder_attention_mask)
|
| 638 |
+
else:
|
| 639 |
+
encoder_extended_attention_mask = self.invert_attention_mask(encoder_attention_mask)
|
| 640 |
+
else:
|
| 641 |
+
encoder_extended_attention_mask = None
|
| 642 |
+
|
| 643 |
+
if encoder_embeds is None:
|
| 644 |
+
embedding_output = self.embeddings(
|
| 645 |
+
input_ids=input_ids,
|
| 646 |
+
position_ids=position_ids,
|
| 647 |
+
inputs_embeds=inputs_embeds,
|
| 648 |
+
past_key_values_length=past_key_values_length,
|
| 649 |
+
)
|
| 650 |
+
else:
|
| 651 |
+
embedding_output = encoder_embeds
|
| 652 |
+
|
| 653 |
+
encoder_outputs: BaseModelOutputWithPastAndCrossAttentions = self.encoder(
|
| 654 |
+
embedding_output,
|
| 655 |
+
attention_mask=extended_attention_mask,
|
| 656 |
+
encoder_hidden_states=encoder_hidden_states,
|
| 657 |
+
encoder_attention_mask=encoder_extended_attention_mask,
|
| 658 |
+
past_key_values=past_key_values,
|
| 659 |
+
use_cache=use_cache,
|
| 660 |
+
**kwargs,
|
| 661 |
+
)
|
| 662 |
+
sequence_output = encoder_outputs.last_hidden_state
|
| 663 |
+
pooled_output = self.pooler(sequence_output) if self.pooler is not None else None
|
| 664 |
+
|
| 665 |
+
return BaseModelOutputWithPoolingAndCrossAttentions(
|
| 666 |
+
last_hidden_state=sequence_output,
|
| 667 |
+
pooler_output=pooled_output,
|
| 668 |
+
past_key_values=encoder_outputs.past_key_values,
|
| 669 |
+
hidden_states=encoder_outputs.hidden_states,
|
| 670 |
+
attentions=encoder_outputs.attentions,
|
| 671 |
+
cross_attentions=encoder_outputs.cross_attentions,
|
| 672 |
+
)
|
| 673 |
+
|
| 674 |
+
|
| 675 |
+
# Adapted from https://github.com/salesforce/BLIP/blob/main/models/med.py#L811
|
| 676 |
+
class BlipTextLMHeadModel(BlipTextPreTrainedModel, GenerationMixin):
|
| 677 |
+
_tied_weights_keys = {
|
| 678 |
+
"cls.predictions.decoder.bias": "cls.predictions.bias",
|
| 679 |
+
"cls.predictions.decoder.weight": "bert.embeddings.word_embeddings.weight",
|
| 680 |
+
}
|
| 681 |
+
|
| 682 |
+
def __init__(self, config):
|
| 683 |
+
super().__init__(config)
|
| 684 |
+
|
| 685 |
+
self.bert = BlipTextModel(config, add_pooling_layer=False)
|
| 686 |
+
self.cls = BlipTextOnlyMLMHead(config)
|
| 687 |
+
self.label_smoothing = config.label_smoothing
|
| 688 |
+
|
| 689 |
+
self.post_init()
|
| 690 |
+
|
| 691 |
+
def get_input_embeddings(self):
|
| 692 |
+
return self.bert.get_input_embeddings()
|
| 693 |
+
|
| 694 |
+
def set_input_embeddings(self, new_embeddings):
|
| 695 |
+
self.bert.set_input_embeddings(new_embeddings)
|
| 696 |
+
|
| 697 |
+
def get_output_embeddings(self):
|
| 698 |
+
return self.cls.predictions.decoder
|
| 699 |
+
|
| 700 |
+
def set_output_embeddings(self, new_embeddings):
|
| 701 |
+
self.cls.predictions.decoder = new_embeddings
|
| 702 |
+
self.cls.predictions.bias = new_embeddings.bias
|
| 703 |
+
|
| 704 |
+
@can_return_tuple
|
| 705 |
+
def forward(
|
| 706 |
+
self,
|
| 707 |
+
input_ids: torch.Tensor | None = None,
|
| 708 |
+
attention_mask: torch.Tensor | None = None,
|
| 709 |
+
position_ids: torch.Tensor | None = None,
|
| 710 |
+
inputs_embeds: torch.Tensor | None = None,
|
| 711 |
+
encoder_hidden_states: torch.Tensor | None = None,
|
| 712 |
+
encoder_attention_mask: torch.Tensor | None = None,
|
| 713 |
+
labels: torch.Tensor | None = None,
|
| 714 |
+
past_key_values: Cache | None = None,
|
| 715 |
+
use_cache: bool | None = None,
|
| 716 |
+
return_logits: bool | None = False,
|
| 717 |
+
is_decoder: bool | None = True,
|
| 718 |
+
reduction: str | None = "mean",
|
| 719 |
+
logits_to_keep: int | torch.Tensor = 0,
|
| 720 |
+
**kwargs: Unpack[TransformersKwargs],
|
| 721 |
+
) -> CausalLMOutputWithCrossAttentions:
|
| 722 |
+
r"""
|
| 723 |
+
encoder_hidden_states (`torch.FloatTensor`, *optional*): Sequence of
|
| 724 |
+
hidden-states at the output of the last layer of the encoder. Used in the cross-attention if the model is
|
| 725 |
+
configured as a decoder.
|
| 726 |
+
encoder_attention_mask (`torch.FloatTensor`, *optional*):
|
| 727 |
+
Mask to avoid performing attention on the padding token indices of the encoder input. This mask is used in
|
| 728 |
+
the cross-attention if the model is configured as a decoder. Mask values selected in `[0, 1]`:
|
| 729 |
+
- 1 for tokens that are **not masked**,
|
| 730 |
+
- 0 for tokens that are **masked**.
|
| 731 |
+
labels (`torch.LongTensor`, *optional*):
|
| 732 |
+
Labels for computing the left-to-right language modeling loss (next word prediction). Indices should be in
|
| 733 |
+
`[-100, 0, ..., config.vocab_size]` (see `input_ids` docstring) Tokens with indices set to `-100` are
|
| 734 |
+
ignored (masked), the loss is only computed for the tokens with labels n `[0, ..., config.vocab_size]`
|
| 735 |
+
past_key_values (`Cache`, *optional*):
|
| 736 |
+
Contains precomputed key and value hidden states of the attention blocks. Can be used to speed up decoding.
|
| 737 |
+
If `past_key_values` are used, the user can optionally input only the last `decoder_input_ids` (those that
|
| 738 |
+
don't have their past key value states given to this model) of shape `(batch_size, 1)` instead of all
|
| 739 |
+
`decoder_input_ids` of shape `(batch_size, sequence_length)`.
|
| 740 |
+
use_cache (`bool`, *optional*):
|
| 741 |
+
If set to `True`, `past_key_values` key value states are returned and can be used to speed up decoding (see
|
| 742 |
+
`past_key_values`).
|
| 743 |
+
"""
|
| 744 |
+
if labels is not None:
|
| 745 |
+
use_cache = False
|
| 746 |
+
|
| 747 |
+
outputs: BaseModelOutputWithPoolingAndCrossAttentions = self.bert(
|
| 748 |
+
input_ids,
|
| 749 |
+
attention_mask=attention_mask,
|
| 750 |
+
position_ids=position_ids,
|
| 751 |
+
inputs_embeds=inputs_embeds,
|
| 752 |
+
encoder_hidden_states=encoder_hidden_states,
|
| 753 |
+
encoder_attention_mask=encoder_attention_mask,
|
| 754 |
+
past_key_values=past_key_values,
|
| 755 |
+
use_cache=use_cache,
|
| 756 |
+
is_decoder=is_decoder,
|
| 757 |
+
**kwargs,
|
| 758 |
+
)
|
| 759 |
+
|
| 760 |
+
hidden_states = outputs.last_hidden_state
|
| 761 |
+
# Only compute necessary logits
|
| 762 |
+
slice_indices = slice(-logits_to_keep, None) if isinstance(logits_to_keep, int) else logits_to_keep
|
| 763 |
+
prediction_scores = self.cls(hidden_states[:, slice_indices, :])
|
| 764 |
+
|
| 765 |
+
if return_logits:
|
| 766 |
+
return prediction_scores[:, :-1, :].contiguous()
|
| 767 |
+
|
| 768 |
+
lm_loss = None
|
| 769 |
+
if labels is not None:
|
| 770 |
+
# we are doing next-token prediction; shift prediction scores and input ids by one
|
| 771 |
+
shifted_prediction_scores = prediction_scores[:, :-1, :].contiguous()
|
| 772 |
+
labels = labels[:, 1:].contiguous().to(shifted_prediction_scores.device)
|
| 773 |
+
loss_fct = CrossEntropyLoss(reduction=reduction, label_smoothing=self.label_smoothing)
|
| 774 |
+
lm_loss = loss_fct(shifted_prediction_scores.view(-1, self.config.vocab_size), labels.view(-1))
|
| 775 |
+
if reduction == "none":
|
| 776 |
+
lm_loss = lm_loss.view(prediction_scores.size(0), -1).sum(1)
|
| 777 |
+
|
| 778 |
+
return CausalLMOutputWithCrossAttentions(
|
| 779 |
+
loss=lm_loss,
|
| 780 |
+
logits=prediction_scores,
|
| 781 |
+
past_key_values=outputs.past_key_values,
|
| 782 |
+
hidden_states=outputs.hidden_states,
|
| 783 |
+
attentions=outputs.attentions,
|
| 784 |
+
cross_attentions=outputs.cross_attentions,
|
| 785 |
+
)
|
| 786 |
+
|
| 787 |
+
def prepare_inputs_for_generation(self, input_ids, past_key_values=None, attention_mask=None, **model_kwargs):
|
| 788 |
+
# Overwrite -- hardcoded key return (`is_decoder=True`)
|
| 789 |
+
|
| 790 |
+
model_inputs = super().prepare_inputs_for_generation(
|
| 791 |
+
input_ids,
|
| 792 |
+
past_key_values=past_key_values,
|
| 793 |
+
attention_mask=attention_mask,
|
| 794 |
+
**model_kwargs,
|
| 795 |
+
)
|
| 796 |
+
model_inputs["is_decoder"] = True
|
| 797 |
+
|
| 798 |
+
return model_inputs
|
| 799 |
+
|
| 800 |
+
|
| 801 |
+
__all__ = ["BlipTextModel", "BlipTextLMHeadModel", "BlipTextPreTrainedModel"]
|
third_party/transformers/src/transformers/models/blip/processing_blip.py
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright 2022 The HuggingFace Inc. team.
|
| 2 |
+
#
|
| 3 |
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
| 4 |
+
# you may not use this file except in compliance with the License.
|
| 5 |
+
# You may obtain a copy of the License at
|
| 6 |
+
#
|
| 7 |
+
# http://www.apache.org/licenses/LICENSE-2.0
|
| 8 |
+
#
|
| 9 |
+
# Unless required by applicable law or agreed to in writing, software
|
| 10 |
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
| 11 |
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 12 |
+
# See the License for the specific language governing permissions and
|
| 13 |
+
# limitations under the License.
|
| 14 |
+
"""
|
| 15 |
+
Processor class for Blip.
|
| 16 |
+
"""
|
| 17 |
+
|
| 18 |
+
from ...image_utils import ImageInput
|
| 19 |
+
from ...processing_utils import ProcessingKwargs, ProcessorMixin, Unpack
|
| 20 |
+
from ...tokenization_utils_base import BatchEncoding, PreTokenizedInput, TextInput
|
| 21 |
+
from ...utils import auto_docstring
|
| 22 |
+
|
| 23 |
+
|
| 24 |
+
class BlipProcessorKwargs(ProcessingKwargs, total=False):
|
| 25 |
+
_defaults = {
|
| 26 |
+
"text_kwargs": {
|
| 27 |
+
"add_special_tokens": True,
|
| 28 |
+
"padding": False,
|
| 29 |
+
"stride": 0,
|
| 30 |
+
"return_overflowing_tokens": False,
|
| 31 |
+
"return_special_tokens_mask": False,
|
| 32 |
+
"return_offsets_mapping": False,
|
| 33 |
+
"return_token_type_ids": False,
|
| 34 |
+
"return_length": False,
|
| 35 |
+
"verbose": True,
|
| 36 |
+
},
|
| 37 |
+
}
|
| 38 |
+
|
| 39 |
+
|
| 40 |
+
@auto_docstring
|
| 41 |
+
class BlipProcessor(ProcessorMixin):
|
| 42 |
+
def __init__(self, image_processor, tokenizer, **kwargs):
|
| 43 |
+
tokenizer.return_token_type_ids = False
|
| 44 |
+
super().__init__(image_processor, tokenizer)
|
| 45 |
+
|
| 46 |
+
@auto_docstring
|
| 47 |
+
def __call__(
|
| 48 |
+
self,
|
| 49 |
+
images: ImageInput | None = None,
|
| 50 |
+
text: str | list[str] | TextInput | PreTokenizedInput | None = None,
|
| 51 |
+
**kwargs: Unpack[BlipProcessorKwargs],
|
| 52 |
+
) -> BatchEncoding:
|
| 53 |
+
if images is None and text is None:
|
| 54 |
+
raise ValueError("You have to specify either images or text.")
|
| 55 |
+
|
| 56 |
+
text_encoding = None
|
| 57 |
+
|
| 58 |
+
# add pixel_values encoding. If we also have text_encoding, update image encoding and return it.
|
| 59 |
+
# else, return the text encoding.
|
| 60 |
+
output_kwargs = self._merge_kwargs(
|
| 61 |
+
BlipProcessorKwargs,
|
| 62 |
+
tokenizer_init_kwargs=self.tokenizer.init_kwargs,
|
| 63 |
+
**kwargs,
|
| 64 |
+
)
|
| 65 |
+
if text is not None:
|
| 66 |
+
text_encoding = self.tokenizer(text, **output_kwargs["text_kwargs"])
|
| 67 |
+
if images is not None:
|
| 68 |
+
encoding_image_processor = self.image_processor(images, **output_kwargs["images_kwargs"])
|
| 69 |
+
|
| 70 |
+
if text_encoding is not None:
|
| 71 |
+
encoding_image_processor.update(text_encoding)
|
| 72 |
+
return encoding_image_processor
|
| 73 |
+
|
| 74 |
+
return text_encoding
|
| 75 |
+
|
| 76 |
+
@property
|
| 77 |
+
def model_input_names(self):
|
| 78 |
+
tokenizer_input_names = self.tokenizer.model_input_names
|
| 79 |
+
image_processor_input_names = self.image_processor.model_input_names
|
| 80 |
+
tokenizer_input_names = [name for name in tokenizer_input_names if name != "token_type_ids"]
|
| 81 |
+
return tokenizer_input_names + image_processor_input_names
|
| 82 |
+
|
| 83 |
+
|
| 84 |
+
__all__ = ["BlipProcessor"]
|
third_party/transformers/src/transformers/models/camembert/__init__.py
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright 2024 The HuggingFace Team. All rights reserved.
|
| 2 |
+
#
|
| 3 |
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
| 4 |
+
# you may not use this file except in compliance with the License.
|
| 5 |
+
# You may obtain a copy of the License at
|
| 6 |
+
#
|
| 7 |
+
# http://www.apache.org/licenses/LICENSE-2.0
|
| 8 |
+
#
|
| 9 |
+
# Unless required by applicable law or agreed to in writing, software
|
| 10 |
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
| 11 |
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 12 |
+
# See the License for the specific language governing permissions and
|
| 13 |
+
# limitations under the License.
|
| 14 |
+
from typing import TYPE_CHECKING
|
| 15 |
+
|
| 16 |
+
from ...utils import _LazyModule
|
| 17 |
+
from ...utils.import_utils import define_import_structure
|
| 18 |
+
|
| 19 |
+
|
| 20 |
+
if TYPE_CHECKING:
|
| 21 |
+
from .configuration_camembert import *
|
| 22 |
+
from .modeling_camembert import *
|
| 23 |
+
from .tokenization_camembert import *
|
| 24 |
+
else:
|
| 25 |
+
import sys
|
| 26 |
+
|
| 27 |
+
_file = globals()["__file__"]
|
| 28 |
+
sys.modules[__name__] = _LazyModule(__name__, _file, define_import_structure(_file), module_spec=__spec__)
|
third_party/transformers/src/transformers/models/camembert/configuration_camembert.py
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright 2018 The Google AI Language Team Authors and The HuggingFace Inc. team.
|
| 2 |
+
# Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved.
|
| 3 |
+
#
|
| 4 |
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
| 5 |
+
# you may not use this file except in compliance with the License.
|
| 6 |
+
# You may obtain a copy of the License at
|
| 7 |
+
#
|
| 8 |
+
# http://www.apache.org/licenses/LICENSE-2.0
|
| 9 |
+
#
|
| 10 |
+
# Unless required by applicable law or agreed to in writing, software
|
| 11 |
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
| 12 |
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 13 |
+
# See the License for the specific language governing permissions and
|
| 14 |
+
# limitations under the License.
|
| 15 |
+
"""CamemBERT configuration"""
|
| 16 |
+
|
| 17 |
+
from huggingface_hub.dataclasses import strict
|
| 18 |
+
|
| 19 |
+
from ...configuration_utils import PreTrainedConfig
|
| 20 |
+
from ...utils import auto_docstring
|
| 21 |
+
|
| 22 |
+
|
| 23 |
+
@auto_docstring(checkpoint="almanach/camembert-base")
|
| 24 |
+
@strict
|
| 25 |
+
class CamembertConfig(PreTrainedConfig):
|
| 26 |
+
r"""
|
| 27 |
+
Example:
|
| 28 |
+
|
| 29 |
+
```python
|
| 30 |
+
>>> from transformers import CamembertConfig, CamembertModel
|
| 31 |
+
|
| 32 |
+
>>> # Initializing a Camembert almanach/camembert-base style configuration
|
| 33 |
+
>>> configuration = CamembertConfig()
|
| 34 |
+
|
| 35 |
+
>>> # Initializing a model (with random weights) from the almanach/camembert-base style configuration
|
| 36 |
+
>>> model = CamembertModel(configuration)
|
| 37 |
+
|
| 38 |
+
>>> # Accessing the model configuration
|
| 39 |
+
>>> configuration = model.config
|
| 40 |
+
```"""
|
| 41 |
+
|
| 42 |
+
model_type = "camembert"
|
| 43 |
+
|
| 44 |
+
vocab_size: int = 30522
|
| 45 |
+
hidden_size: int = 768
|
| 46 |
+
num_hidden_layers: int = 12
|
| 47 |
+
num_attention_heads: int = 12
|
| 48 |
+
intermediate_size: int = 3072
|
| 49 |
+
hidden_act: str = "gelu"
|
| 50 |
+
hidden_dropout_prob: float | int = 0.1
|
| 51 |
+
attention_probs_dropout_prob: float | int = 0.1
|
| 52 |
+
max_position_embeddings: int = 512
|
| 53 |
+
type_vocab_size: int = 2
|
| 54 |
+
initializer_range: float = 0.02
|
| 55 |
+
layer_norm_eps: float = 1e-12
|
| 56 |
+
pad_token_id: int | None = 1
|
| 57 |
+
bos_token_id: int | None = 0
|
| 58 |
+
eos_token_id: int | list[int] | None = 2
|
| 59 |
+
use_cache: bool = True
|
| 60 |
+
classifier_dropout: float | int | None = None
|
| 61 |
+
is_decoder: bool = False
|
| 62 |
+
add_cross_attention: bool = False
|
| 63 |
+
tie_word_embeddings: bool = True
|
| 64 |
+
|
| 65 |
+
|
| 66 |
+
__all__ = ["CamembertConfig"]
|
third_party/transformers/src/transformers/models/camembert/modeling_camembert.py
ADDED
|
@@ -0,0 +1,1272 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨
|
| 2 |
+
# This file was automatically generated from src/transformers/models/camembert/modular_camembert.py.
|
| 3 |
+
# Do NOT edit this file manually as any edits will be overwritten by the generation of
|
| 4 |
+
# the file from the modular. If any change should be done, please apply the change to the
|
| 5 |
+
# modular_camembert.py file directly. One of our CI enforces this.
|
| 6 |
+
# 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨
|
| 7 |
+
# Copyright 2019 Inria, Facebook AI Research and the HuggingFace Inc. team.
|
| 8 |
+
# Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved.
|
| 9 |
+
#
|
| 10 |
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
| 11 |
+
# you may not use this file except in compliance with the License.
|
| 12 |
+
# You may obtain a copy of the License at
|
| 13 |
+
#
|
| 14 |
+
# http://www.apache.org/licenses/LICENSE-2.0
|
| 15 |
+
#
|
| 16 |
+
# Unless required by applicable law or agreed to in writing, software
|
| 17 |
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
| 18 |
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 19 |
+
# See the License for the specific language governing permissions and
|
| 20 |
+
# limitations under the License.
|
| 21 |
+
|
| 22 |
+
from collections.abc import Callable
|
| 23 |
+
|
| 24 |
+
import torch
|
| 25 |
+
import torch.nn as nn
|
| 26 |
+
from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss
|
| 27 |
+
|
| 28 |
+
from ... import initialization as init
|
| 29 |
+
from ...activations import ACT2FN, gelu
|
| 30 |
+
from ...cache_utils import Cache, DynamicCache, EncoderDecoderCache
|
| 31 |
+
from ...generation import GenerationMixin
|
| 32 |
+
from ...masking_utils import create_bidirectional_mask, create_causal_mask
|
| 33 |
+
from ...modeling_layers import GradientCheckpointingLayer
|
| 34 |
+
from ...modeling_outputs import (
|
| 35 |
+
BaseModelOutputWithPastAndCrossAttentions,
|
| 36 |
+
BaseModelOutputWithPoolingAndCrossAttentions,
|
| 37 |
+
CausalLMOutputWithCrossAttentions,
|
| 38 |
+
MaskedLMOutput,
|
| 39 |
+
MultipleChoiceModelOutput,
|
| 40 |
+
QuestionAnsweringModelOutput,
|
| 41 |
+
SequenceClassifierOutput,
|
| 42 |
+
TokenClassifierOutput,
|
| 43 |
+
)
|
| 44 |
+
from ...modeling_utils import ALL_ATTENTION_FUNCTIONS, PreTrainedModel
|
| 45 |
+
from ...processing_utils import Unpack
|
| 46 |
+
from ...pytorch_utils import apply_chunking_to_forward
|
| 47 |
+
from ...utils import TransformersKwargs, auto_docstring, logging
|
| 48 |
+
from ...utils.generic import can_return_tuple, merge_with_config_defaults
|
| 49 |
+
from ...utils.output_capturing import capture_outputs
|
| 50 |
+
from .configuration_camembert import CamembertConfig
|
| 51 |
+
|
| 52 |
+
|
| 53 |
+
logger = logging.get_logger(__name__)
|
| 54 |
+
|
| 55 |
+
|
| 56 |
+
class CamembertEmbeddings(nn.Module):
|
| 57 |
+
"""Construct the embeddings from word, position and token_type embeddings."""
|
| 58 |
+
|
| 59 |
+
def __init__(self, config):
|
| 60 |
+
super().__init__()
|
| 61 |
+
self.word_embeddings = nn.Embedding(config.vocab_size, config.hidden_size, padding_idx=config.pad_token_id)
|
| 62 |
+
self.token_type_embeddings = nn.Embedding(config.type_vocab_size, config.hidden_size)
|
| 63 |
+
|
| 64 |
+
self.LayerNorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps)
|
| 65 |
+
self.dropout = nn.Dropout(config.hidden_dropout_prob)
|
| 66 |
+
# position_ids (1, len position emb) is contiguous in memory and exported when serialized
|
| 67 |
+
self.register_buffer(
|
| 68 |
+
"position_ids", torch.arange(config.max_position_embeddings).expand((1, -1)), persistent=False
|
| 69 |
+
)
|
| 70 |
+
self.register_buffer(
|
| 71 |
+
"token_type_ids", torch.zeros(self.position_ids.size(), dtype=torch.long), persistent=False
|
| 72 |
+
)
|
| 73 |
+
|
| 74 |
+
self.padding_idx = config.pad_token_id
|
| 75 |
+
self.position_embeddings = nn.Embedding(
|
| 76 |
+
config.max_position_embeddings, config.hidden_size, padding_idx=self.padding_idx
|
| 77 |
+
)
|
| 78 |
+
|
| 79 |
+
def forward(
|
| 80 |
+
self,
|
| 81 |
+
input_ids: torch.LongTensor | None = None,
|
| 82 |
+
token_type_ids: torch.LongTensor | None = None,
|
| 83 |
+
position_ids: torch.LongTensor | None = None,
|
| 84 |
+
inputs_embeds: torch.FloatTensor | None = None,
|
| 85 |
+
past_key_values_length: int = 0,
|
| 86 |
+
) -> torch.Tensor:
|
| 87 |
+
if position_ids is None:
|
| 88 |
+
if input_ids is not None:
|
| 89 |
+
# Create the position ids from the input token ids. Any padded tokens remain padded.
|
| 90 |
+
position_ids = self.create_position_ids_from_input_ids(
|
| 91 |
+
input_ids, self.padding_idx, past_key_values_length
|
| 92 |
+
)
|
| 93 |
+
else:
|
| 94 |
+
position_ids = self.create_position_ids_from_inputs_embeds(inputs_embeds, self.padding_idx)
|
| 95 |
+
|
| 96 |
+
if input_ids is not None:
|
| 97 |
+
input_shape = input_ids.size()
|
| 98 |
+
else:
|
| 99 |
+
input_shape = inputs_embeds.size()[:-1]
|
| 100 |
+
|
| 101 |
+
batch_size, seq_length = input_shape
|
| 102 |
+
|
| 103 |
+
# Setting the token_type_ids to the registered buffer in constructor where it is all zeros, which usually occurs
|
| 104 |
+
# when its auto-generated, registered buffer helps users when tracing the model without passing token_type_ids, solves
|
| 105 |
+
# issue #5664
|
| 106 |
+
if token_type_ids is None:
|
| 107 |
+
if hasattr(self, "token_type_ids"):
|
| 108 |
+
# NOTE: We assume either pos ids to have bsz == 1 (broadcastable) or bsz == effective bsz (input_shape[0])
|
| 109 |
+
buffered_token_type_ids = self.token_type_ids.expand(position_ids.shape[0], -1)
|
| 110 |
+
buffered_token_type_ids = torch.gather(buffered_token_type_ids, dim=1, index=position_ids)
|
| 111 |
+
token_type_ids = buffered_token_type_ids.expand(batch_size, seq_length)
|
| 112 |
+
else:
|
| 113 |
+
token_type_ids = torch.zeros(input_shape, dtype=torch.long, device=self.position_ids.device)
|
| 114 |
+
|
| 115 |
+
if inputs_embeds is None:
|
| 116 |
+
inputs_embeds = self.word_embeddings(input_ids)
|
| 117 |
+
token_type_embeddings = self.token_type_embeddings(token_type_ids)
|
| 118 |
+
embeddings = inputs_embeds + token_type_embeddings
|
| 119 |
+
|
| 120 |
+
position_embeddings = self.position_embeddings(position_ids)
|
| 121 |
+
embeddings = embeddings + position_embeddings
|
| 122 |
+
|
| 123 |
+
embeddings = self.LayerNorm(embeddings)
|
| 124 |
+
embeddings = self.dropout(embeddings)
|
| 125 |
+
return embeddings
|
| 126 |
+
|
| 127 |
+
@staticmethod
|
| 128 |
+
def create_position_ids_from_inputs_embeds(inputs_embeds, padding_idx):
|
| 129 |
+
"""
|
| 130 |
+
We are provided embeddings directly. We cannot infer which are padded so just generate sequential position ids.
|
| 131 |
+
|
| 132 |
+
Args:
|
| 133 |
+
inputs_embeds: torch.Tensor
|
| 134 |
+
|
| 135 |
+
Returns: torch.Tensor
|
| 136 |
+
"""
|
| 137 |
+
input_shape = inputs_embeds.size()[:-1]
|
| 138 |
+
sequence_length = input_shape[1]
|
| 139 |
+
|
| 140 |
+
position_ids = torch.arange(
|
| 141 |
+
padding_idx + 1, sequence_length + padding_idx + 1, dtype=torch.long, device=inputs_embeds.device
|
| 142 |
+
)
|
| 143 |
+
return position_ids.unsqueeze(0).expand(input_shape)
|
| 144 |
+
|
| 145 |
+
@staticmethod
|
| 146 |
+
def create_position_ids_from_input_ids(input_ids, padding_idx, past_key_values_length=0):
|
| 147 |
+
"""
|
| 148 |
+
Replace non-padding symbols with their position numbers. Position numbers begin at padding_idx+1. Padding symbols
|
| 149 |
+
are ignored. This is modified from fairseq's `utils.make_positions`.
|
| 150 |
+
|
| 151 |
+
Args:
|
| 152 |
+
x: torch.Tensor x:
|
| 153 |
+
|
| 154 |
+
Returns: torch.Tensor
|
| 155 |
+
"""
|
| 156 |
+
# The series of casts and type-conversions here are carefully balanced to both work with ONNX export and XLA.
|
| 157 |
+
mask = input_ids.ne(padding_idx).int()
|
| 158 |
+
incremental_indices = (torch.cumsum(mask, dim=1).type_as(mask) + past_key_values_length) * mask
|
| 159 |
+
return incremental_indices.long() + padding_idx
|
| 160 |
+
|
| 161 |
+
|
| 162 |
+
def eager_attention_forward(
|
| 163 |
+
module: nn.Module,
|
| 164 |
+
query: torch.Tensor,
|
| 165 |
+
key: torch.Tensor,
|
| 166 |
+
value: torch.Tensor,
|
| 167 |
+
attention_mask: torch.Tensor | None,
|
| 168 |
+
scaling: float | None = None,
|
| 169 |
+
dropout: float = 0.0,
|
| 170 |
+
**kwargs: Unpack[TransformersKwargs],
|
| 171 |
+
):
|
| 172 |
+
if scaling is None:
|
| 173 |
+
scaling = query.size(-1) ** -0.5
|
| 174 |
+
|
| 175 |
+
# Take the dot product between "query" and "key" to get the raw attention scores.
|
| 176 |
+
attn_weights = torch.matmul(query, key.transpose(2, 3)) * scaling
|
| 177 |
+
|
| 178 |
+
if attention_mask is not None:
|
| 179 |
+
attn_weights = attn_weights + attention_mask
|
| 180 |
+
|
| 181 |
+
attn_weights = nn.functional.softmax(attn_weights, dim=-1)
|
| 182 |
+
attn_weights = nn.functional.dropout(attn_weights, p=dropout, training=module.training)
|
| 183 |
+
|
| 184 |
+
attn_output = torch.matmul(attn_weights, value)
|
| 185 |
+
attn_output = attn_output.transpose(1, 2).contiguous()
|
| 186 |
+
|
| 187 |
+
return attn_output, attn_weights
|
| 188 |
+
|
| 189 |
+
|
| 190 |
+
class CamembertSelfAttention(nn.Module):
|
| 191 |
+
def __init__(self, config, is_causal=False, layer_idx=None):
|
| 192 |
+
super().__init__()
|
| 193 |
+
if config.hidden_size % config.num_attention_heads != 0 and not hasattr(config, "embedding_size"):
|
| 194 |
+
raise ValueError(
|
| 195 |
+
f"The hidden size ({config.hidden_size}) is not a multiple of the number of attention "
|
| 196 |
+
f"heads ({config.num_attention_heads})"
|
| 197 |
+
)
|
| 198 |
+
self.config = config
|
| 199 |
+
|
| 200 |
+
self.num_attention_heads = config.num_attention_heads
|
| 201 |
+
self.attention_head_size = int(config.hidden_size / config.num_attention_heads)
|
| 202 |
+
self.all_head_size = self.num_attention_heads * self.attention_head_size
|
| 203 |
+
self.scaling = self.attention_head_size**-0.5
|
| 204 |
+
|
| 205 |
+
self.query = nn.Linear(config.hidden_size, self.all_head_size)
|
| 206 |
+
self.key = nn.Linear(config.hidden_size, self.all_head_size)
|
| 207 |
+
self.value = nn.Linear(config.hidden_size, self.all_head_size)
|
| 208 |
+
|
| 209 |
+
self.dropout = nn.Dropout(config.attention_probs_dropout_prob)
|
| 210 |
+
|
| 211 |
+
self.is_decoder = config.is_decoder
|
| 212 |
+
self.is_causal = is_causal
|
| 213 |
+
self.layer_idx = layer_idx
|
| 214 |
+
|
| 215 |
+
def forward(
|
| 216 |
+
self,
|
| 217 |
+
hidden_states: torch.Tensor,
|
| 218 |
+
attention_mask: torch.FloatTensor | None = None,
|
| 219 |
+
past_key_values: Cache | None = None,
|
| 220 |
+
**kwargs: Unpack[TransformersKwargs],
|
| 221 |
+
) -> tuple[torch.Tensor]:
|
| 222 |
+
input_shape = hidden_states.shape[:-1]
|
| 223 |
+
hidden_shape = (*input_shape, -1, self.attention_head_size)
|
| 224 |
+
|
| 225 |
+
# get all proj
|
| 226 |
+
query_layer = self.query(hidden_states).view(*hidden_shape).transpose(1, 2)
|
| 227 |
+
key_layer = self.key(hidden_states).view(*hidden_shape).transpose(1, 2)
|
| 228 |
+
value_layer = self.value(hidden_states).view(*hidden_shape).transpose(1, 2)
|
| 229 |
+
|
| 230 |
+
if past_key_values is not None:
|
| 231 |
+
# decoder-only camembert can have a simple dynamic cache for example
|
| 232 |
+
current_past_key_values = past_key_values
|
| 233 |
+
if isinstance(past_key_values, EncoderDecoderCache):
|
| 234 |
+
current_past_key_values = past_key_values.self_attention_cache
|
| 235 |
+
|
| 236 |
+
# save all key/value_layer to cache to be re-used for fast auto-regressive generation
|
| 237 |
+
key_layer, value_layer = current_past_key_values.update(key_layer, value_layer, self.layer_idx)
|
| 238 |
+
|
| 239 |
+
attention_interface: Callable = ALL_ATTENTION_FUNCTIONS.get_interface(
|
| 240 |
+
self.config._attn_implementation, eager_attention_forward
|
| 241 |
+
)
|
| 242 |
+
|
| 243 |
+
attn_output, attn_weights = attention_interface(
|
| 244 |
+
self,
|
| 245 |
+
query_layer,
|
| 246 |
+
key_layer,
|
| 247 |
+
value_layer,
|
| 248 |
+
attention_mask,
|
| 249 |
+
dropout=0.0 if not self.training else self.dropout.p,
|
| 250 |
+
scaling=self.scaling,
|
| 251 |
+
**kwargs,
|
| 252 |
+
)
|
| 253 |
+
attn_output = attn_output.reshape(*input_shape, -1).contiguous()
|
| 254 |
+
return attn_output, attn_weights
|
| 255 |
+
|
| 256 |
+
|
| 257 |
+
class CamembertCrossAttention(nn.Module):
|
| 258 |
+
def __init__(self, config, is_causal=False, layer_idx=None):
|
| 259 |
+
super().__init__()
|
| 260 |
+
if config.hidden_size % config.num_attention_heads != 0 and not hasattr(config, "embedding_size"):
|
| 261 |
+
raise ValueError(
|
| 262 |
+
f"The hidden size ({config.hidden_size}) is not a multiple of the number of attention "
|
| 263 |
+
f"heads ({config.num_attention_heads})"
|
| 264 |
+
)
|
| 265 |
+
self.config = config
|
| 266 |
+
|
| 267 |
+
self.num_attention_heads = config.num_attention_heads
|
| 268 |
+
self.attention_head_size = int(config.hidden_size / config.num_attention_heads)
|
| 269 |
+
self.all_head_size = self.num_attention_heads * self.attention_head_size
|
| 270 |
+
self.scaling = self.attention_head_size**-0.5
|
| 271 |
+
|
| 272 |
+
self.query = nn.Linear(config.hidden_size, self.all_head_size)
|
| 273 |
+
self.key = nn.Linear(config.hidden_size, self.all_head_size)
|
| 274 |
+
self.value = nn.Linear(config.hidden_size, self.all_head_size)
|
| 275 |
+
|
| 276 |
+
self.dropout = nn.Dropout(config.attention_probs_dropout_prob)
|
| 277 |
+
|
| 278 |
+
self.is_causal = is_causal
|
| 279 |
+
self.layer_idx = layer_idx
|
| 280 |
+
|
| 281 |
+
def forward(
|
| 282 |
+
self,
|
| 283 |
+
hidden_states: torch.Tensor,
|
| 284 |
+
encoder_hidden_states: torch.FloatTensor | None = None,
|
| 285 |
+
attention_mask: torch.FloatTensor | None = None,
|
| 286 |
+
past_key_values: EncoderDecoderCache | None = None,
|
| 287 |
+
**kwargs: Unpack[TransformersKwargs],
|
| 288 |
+
) -> tuple[torch.Tensor]:
|
| 289 |
+
# determine input shapes
|
| 290 |
+
bsz, tgt_len = hidden_states.shape[:-1]
|
| 291 |
+
src_len = encoder_hidden_states.shape[1]
|
| 292 |
+
|
| 293 |
+
q_input_shape = (bsz, tgt_len, -1, self.attention_head_size)
|
| 294 |
+
kv_input_shape = (bsz, src_len, -1, self.attention_head_size)
|
| 295 |
+
|
| 296 |
+
# get query proj
|
| 297 |
+
query_layer = self.query(hidden_states).view(*q_input_shape).transpose(1, 2)
|
| 298 |
+
|
| 299 |
+
is_updated = past_key_values.is_updated.get(self.layer_idx) if past_key_values is not None else False
|
| 300 |
+
if past_key_values is not None and is_updated:
|
| 301 |
+
# reuse k,v, cross_attentions
|
| 302 |
+
key_layer = past_key_values.cross_attention_cache.layers[self.layer_idx].keys
|
| 303 |
+
value_layer = past_key_values.cross_attention_cache.layers[self.layer_idx].values
|
| 304 |
+
else:
|
| 305 |
+
key_layer = self.key(encoder_hidden_states).view(*kv_input_shape).transpose(1, 2)
|
| 306 |
+
value_layer = self.value(encoder_hidden_states).view(*kv_input_shape).transpose(1, 2)
|
| 307 |
+
|
| 308 |
+
if past_key_values is not None:
|
| 309 |
+
# save all states to the cache
|
| 310 |
+
key_layer, value_layer = past_key_values.cross_attention_cache.update(
|
| 311 |
+
key_layer, value_layer, self.layer_idx
|
| 312 |
+
)
|
| 313 |
+
# set flag that curr layer for cross-attn is already updated so we can re-use in subsequent calls
|
| 314 |
+
past_key_values.is_updated[self.layer_idx] = True
|
| 315 |
+
|
| 316 |
+
attention_interface: Callable = ALL_ATTENTION_FUNCTIONS.get_interface(
|
| 317 |
+
self.config._attn_implementation, eager_attention_forward
|
| 318 |
+
)
|
| 319 |
+
|
| 320 |
+
attn_output, attn_weights = attention_interface(
|
| 321 |
+
self,
|
| 322 |
+
query_layer,
|
| 323 |
+
key_layer,
|
| 324 |
+
value_layer,
|
| 325 |
+
attention_mask,
|
| 326 |
+
dropout=0.0 if not self.training else self.dropout.p,
|
| 327 |
+
scaling=self.scaling,
|
| 328 |
+
**kwargs,
|
| 329 |
+
)
|
| 330 |
+
attn_output = attn_output.reshape(bsz, tgt_len, -1).contiguous()
|
| 331 |
+
return attn_output, attn_weights
|
| 332 |
+
|
| 333 |
+
|
| 334 |
+
class CamembertSelfOutput(nn.Module):
|
| 335 |
+
def __init__(self, config):
|
| 336 |
+
super().__init__()
|
| 337 |
+
self.dense = nn.Linear(config.hidden_size, config.hidden_size)
|
| 338 |
+
self.LayerNorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps)
|
| 339 |
+
self.dropout = nn.Dropout(config.hidden_dropout_prob)
|
| 340 |
+
|
| 341 |
+
def forward(self, hidden_states: torch.Tensor, input_tensor: torch.Tensor) -> torch.Tensor:
|
| 342 |
+
hidden_states = self.dense(hidden_states)
|
| 343 |
+
hidden_states = self.dropout(hidden_states)
|
| 344 |
+
hidden_states = self.LayerNorm(hidden_states + input_tensor)
|
| 345 |
+
return hidden_states
|
| 346 |
+
|
| 347 |
+
|
| 348 |
+
class CamembertAttention(nn.Module):
|
| 349 |
+
def __init__(self, config, is_causal=False, layer_idx=None, is_cross_attention=False):
|
| 350 |
+
super().__init__()
|
| 351 |
+
self.is_cross_attention = is_cross_attention
|
| 352 |
+
attention_class = CamembertCrossAttention if is_cross_attention else CamembertSelfAttention
|
| 353 |
+
self.self = attention_class(config, is_causal=is_causal, layer_idx=layer_idx)
|
| 354 |
+
self.output = CamembertSelfOutput(config)
|
| 355 |
+
|
| 356 |
+
def forward(
|
| 357 |
+
self,
|
| 358 |
+
hidden_states: torch.Tensor,
|
| 359 |
+
attention_mask: torch.FloatTensor | None = None,
|
| 360 |
+
encoder_hidden_states: torch.FloatTensor | None = None,
|
| 361 |
+
encoder_attention_mask: torch.FloatTensor | None = None,
|
| 362 |
+
past_key_values: Cache | None = None,
|
| 363 |
+
**kwargs: Unpack[TransformersKwargs],
|
| 364 |
+
) -> tuple[torch.Tensor]:
|
| 365 |
+
attention_mask = attention_mask if not self.is_cross_attention else encoder_attention_mask
|
| 366 |
+
attention_output, attn_weights = self.self(
|
| 367 |
+
hidden_states,
|
| 368 |
+
encoder_hidden_states=encoder_hidden_states,
|
| 369 |
+
attention_mask=attention_mask,
|
| 370 |
+
past_key_values=past_key_values,
|
| 371 |
+
**kwargs,
|
| 372 |
+
)
|
| 373 |
+
attention_output = self.output(attention_output, hidden_states)
|
| 374 |
+
return attention_output, attn_weights
|
| 375 |
+
|
| 376 |
+
|
| 377 |
+
class CamembertIntermediate(nn.Module):
|
| 378 |
+
def __init__(self, config):
|
| 379 |
+
super().__init__()
|
| 380 |
+
self.dense = nn.Linear(config.hidden_size, config.intermediate_size)
|
| 381 |
+
if isinstance(config.hidden_act, str):
|
| 382 |
+
self.intermediate_act_fn = ACT2FN[config.hidden_act]
|
| 383 |
+
else:
|
| 384 |
+
self.intermediate_act_fn = config.hidden_act
|
| 385 |
+
|
| 386 |
+
def forward(self, hidden_states: torch.Tensor) -> torch.Tensor:
|
| 387 |
+
hidden_states = self.dense(hidden_states)
|
| 388 |
+
hidden_states = self.intermediate_act_fn(hidden_states)
|
| 389 |
+
return hidden_states
|
| 390 |
+
|
| 391 |
+
|
| 392 |
+
class CamembertOutput(nn.Module):
|
| 393 |
+
def __init__(self, config):
|
| 394 |
+
super().__init__()
|
| 395 |
+
self.dense = nn.Linear(config.intermediate_size, config.hidden_size)
|
| 396 |
+
self.LayerNorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps)
|
| 397 |
+
self.dropout = nn.Dropout(config.hidden_dropout_prob)
|
| 398 |
+
|
| 399 |
+
def forward(self, hidden_states: torch.Tensor, input_tensor: torch.Tensor) -> torch.Tensor:
|
| 400 |
+
hidden_states = self.dense(hidden_states)
|
| 401 |
+
hidden_states = self.dropout(hidden_states)
|
| 402 |
+
hidden_states = self.LayerNorm(hidden_states + input_tensor)
|
| 403 |
+
return hidden_states
|
| 404 |
+
|
| 405 |
+
|
| 406 |
+
class CamembertLayer(GradientCheckpointingLayer):
|
| 407 |
+
def __init__(self, config, layer_idx=None):
|
| 408 |
+
super().__init__()
|
| 409 |
+
self.chunk_size_feed_forward = config.chunk_size_feed_forward
|
| 410 |
+
self.seq_len_dim = 1
|
| 411 |
+
self.attention = CamembertAttention(config, is_causal=config.is_decoder, layer_idx=layer_idx)
|
| 412 |
+
self.is_decoder = config.is_decoder
|
| 413 |
+
self.add_cross_attention = config.add_cross_attention
|
| 414 |
+
if self.add_cross_attention:
|
| 415 |
+
if not self.is_decoder:
|
| 416 |
+
raise ValueError(f"{self} should be used as a decoder model if cross attention is added")
|
| 417 |
+
self.crossattention = CamembertAttention(
|
| 418 |
+
config,
|
| 419 |
+
is_causal=False,
|
| 420 |
+
layer_idx=layer_idx,
|
| 421 |
+
is_cross_attention=True,
|
| 422 |
+
)
|
| 423 |
+
self.intermediate = CamembertIntermediate(config)
|
| 424 |
+
self.output = CamembertOutput(config)
|
| 425 |
+
|
| 426 |
+
def forward(
|
| 427 |
+
self,
|
| 428 |
+
hidden_states: torch.Tensor,
|
| 429 |
+
attention_mask: torch.FloatTensor | None = None,
|
| 430 |
+
encoder_hidden_states: torch.FloatTensor | None = None,
|
| 431 |
+
encoder_attention_mask: torch.FloatTensor | None = None,
|
| 432 |
+
past_key_values: Cache | None = None,
|
| 433 |
+
**kwargs: Unpack[TransformersKwargs],
|
| 434 |
+
) -> torch.Tensor:
|
| 435 |
+
self_attention_output, _ = self.attention(
|
| 436 |
+
hidden_states,
|
| 437 |
+
attention_mask,
|
| 438 |
+
past_key_values=past_key_values,
|
| 439 |
+
**kwargs,
|
| 440 |
+
)
|
| 441 |
+
attention_output = self_attention_output
|
| 442 |
+
|
| 443 |
+
if self.is_decoder and encoder_hidden_states is not None:
|
| 444 |
+
if not hasattr(self, "crossattention"):
|
| 445 |
+
raise ValueError(
|
| 446 |
+
f"If `encoder_hidden_states` are passed, {self} has to be instantiated with cross-attention layers"
|
| 447 |
+
" by setting `config.add_cross_attention=True`"
|
| 448 |
+
)
|
| 449 |
+
|
| 450 |
+
cross_attention_output, _ = self.crossattention(
|
| 451 |
+
self_attention_output,
|
| 452 |
+
None, # attention_mask
|
| 453 |
+
encoder_hidden_states,
|
| 454 |
+
encoder_attention_mask,
|
| 455 |
+
past_key_values=past_key_values,
|
| 456 |
+
**kwargs,
|
| 457 |
+
)
|
| 458 |
+
attention_output = cross_attention_output
|
| 459 |
+
|
| 460 |
+
layer_output = apply_chunking_to_forward(
|
| 461 |
+
self.feed_forward_chunk, self.chunk_size_feed_forward, self.seq_len_dim, attention_output
|
| 462 |
+
)
|
| 463 |
+
return layer_output
|
| 464 |
+
|
| 465 |
+
def feed_forward_chunk(self, attention_output):
|
| 466 |
+
intermediate_output = self.intermediate(attention_output)
|
| 467 |
+
layer_output = self.output(intermediate_output, attention_output)
|
| 468 |
+
return layer_output
|
| 469 |
+
|
| 470 |
+
|
| 471 |
+
class CamembertLMHead(nn.Module):
|
| 472 |
+
"""Camembert Head for masked language modeling."""
|
| 473 |
+
|
| 474 |
+
def __init__(self, config):
|
| 475 |
+
super().__init__()
|
| 476 |
+
self.dense = nn.Linear(config.hidden_size, config.hidden_size)
|
| 477 |
+
self.layer_norm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps)
|
| 478 |
+
|
| 479 |
+
self.decoder = nn.Linear(config.hidden_size, config.vocab_size)
|
| 480 |
+
self.bias = nn.Parameter(torch.zeros(config.vocab_size))
|
| 481 |
+
|
| 482 |
+
def forward(self, features, **kwargs):
|
| 483 |
+
x = self.dense(features)
|
| 484 |
+
x = gelu(x)
|
| 485 |
+
x = self.layer_norm(x)
|
| 486 |
+
|
| 487 |
+
# project back to size of vocabulary with bias
|
| 488 |
+
x = self.decoder(x)
|
| 489 |
+
|
| 490 |
+
return x
|
| 491 |
+
|
| 492 |
+
|
| 493 |
+
@auto_docstring
|
| 494 |
+
class CamembertPreTrainedModel(PreTrainedModel):
|
| 495 |
+
config_class = CamembertConfig
|
| 496 |
+
base_model_prefix = "roberta"
|
| 497 |
+
supports_gradient_checkpointing = True
|
| 498 |
+
_supports_flash_attn = True
|
| 499 |
+
_supports_sdpa = True
|
| 500 |
+
_supports_flex_attn = True
|
| 501 |
+
_supports_attention_backend = True
|
| 502 |
+
_can_record_outputs = {
|
| 503 |
+
"hidden_states": CamembertLayer,
|
| 504 |
+
"attentions": CamembertSelfAttention,
|
| 505 |
+
"cross_attentions": CamembertCrossAttention,
|
| 506 |
+
}
|
| 507 |
+
|
| 508 |
+
@torch.no_grad()
|
| 509 |
+
def _init_weights(self, module):
|
| 510 |
+
"""Initialize the weights"""
|
| 511 |
+
super()._init_weights(module)
|
| 512 |
+
if isinstance(module, CamembertLMHead):
|
| 513 |
+
init.zeros_(module.bias)
|
| 514 |
+
elif isinstance(module, CamembertEmbeddings):
|
| 515 |
+
init.copy_(module.position_ids, torch.arange(module.position_ids.shape[-1]).expand((1, -1)))
|
| 516 |
+
init.zeros_(module.token_type_ids)
|
| 517 |
+
|
| 518 |
+
|
| 519 |
+
class CamembertEncoder(nn.Module):
|
| 520 |
+
def __init__(self, config):
|
| 521 |
+
super().__init__()
|
| 522 |
+
self.config = config
|
| 523 |
+
self.layer = nn.ModuleList([CamembertLayer(config, layer_idx=i) for i in range(config.num_hidden_layers)])
|
| 524 |
+
|
| 525 |
+
def forward(
|
| 526 |
+
self,
|
| 527 |
+
hidden_states: torch.Tensor,
|
| 528 |
+
attention_mask: torch.FloatTensor | None = None,
|
| 529 |
+
encoder_hidden_states: torch.FloatTensor | None = None,
|
| 530 |
+
encoder_attention_mask: torch.FloatTensor | None = None,
|
| 531 |
+
past_key_values: Cache | None = None,
|
| 532 |
+
use_cache: bool | None = None,
|
| 533 |
+
**kwargs: Unpack[TransformersKwargs],
|
| 534 |
+
) -> tuple[torch.Tensor] | BaseModelOutputWithPastAndCrossAttentions:
|
| 535 |
+
for i, layer_module in enumerate(self.layer):
|
| 536 |
+
hidden_states = layer_module(
|
| 537 |
+
hidden_states,
|
| 538 |
+
attention_mask,
|
| 539 |
+
encoder_hidden_states, # as a positional argument for gradient checkpointing
|
| 540 |
+
encoder_attention_mask=encoder_attention_mask,
|
| 541 |
+
past_key_values=past_key_values,
|
| 542 |
+
**kwargs,
|
| 543 |
+
)
|
| 544 |
+
|
| 545 |
+
return BaseModelOutputWithPastAndCrossAttentions(
|
| 546 |
+
last_hidden_state=hidden_states,
|
| 547 |
+
past_key_values=past_key_values if use_cache else None,
|
| 548 |
+
)
|
| 549 |
+
|
| 550 |
+
|
| 551 |
+
class CamembertPooler(nn.Module):
|
| 552 |
+
def __init__(self, config):
|
| 553 |
+
super().__init__()
|
| 554 |
+
self.dense = nn.Linear(config.hidden_size, config.hidden_size)
|
| 555 |
+
self.activation = nn.Tanh()
|
| 556 |
+
|
| 557 |
+
def forward(self, hidden_states: torch.Tensor) -> torch.Tensor:
|
| 558 |
+
# We "pool" the model by simply taking the hidden state corresponding
|
| 559 |
+
# to the first token.
|
| 560 |
+
first_token_tensor = hidden_states[:, 0]
|
| 561 |
+
pooled_output = self.dense(first_token_tensor)
|
| 562 |
+
pooled_output = self.activation(pooled_output)
|
| 563 |
+
return pooled_output
|
| 564 |
+
|
| 565 |
+
|
| 566 |
+
@auto_docstring(
|
| 567 |
+
custom_intro="""
|
| 568 |
+
The model can behave as an encoder (with only self-attention) as well as a decoder, in which case a layer of
|
| 569 |
+
cross-attention is added between the self-attention layers, following the architecture described in [Attention is
|
| 570 |
+
all you need](https://huggingface.co/papers/1706.03762) by Ashish Vaswani, Noam Shazeer, Niki Parmar, Jakob Uszkoreit,
|
| 571 |
+
Llion Jones, Aidan N. Gomez, Lukasz Kaiser and Illia Polosukhin.
|
| 572 |
+
|
| 573 |
+
To behave as an decoder the model needs to be initialized with the `is_decoder` argument of the configuration set
|
| 574 |
+
to `True`. To be used in a Seq2Seq model, the model needs to initialized with both `is_decoder` argument and
|
| 575 |
+
`add_cross_attention` set to `True`; an `encoder_hidden_states` is then expected as an input to the forward pass.
|
| 576 |
+
"""
|
| 577 |
+
)
|
| 578 |
+
class CamembertModel(CamembertPreTrainedModel):
|
| 579 |
+
_no_split_modules = ["CamembertEmbeddings", "CamembertLayer"]
|
| 580 |
+
|
| 581 |
+
def __init__(self, config, add_pooling_layer=True):
|
| 582 |
+
r"""
|
| 583 |
+
add_pooling_layer (bool, *optional*, defaults to `True`):
|
| 584 |
+
Whether to add a pooling layer
|
| 585 |
+
"""
|
| 586 |
+
super().__init__(config)
|
| 587 |
+
self.config = config
|
| 588 |
+
self.gradient_checkpointing = False
|
| 589 |
+
|
| 590 |
+
self.embeddings = CamembertEmbeddings(config)
|
| 591 |
+
self.encoder = CamembertEncoder(config)
|
| 592 |
+
|
| 593 |
+
self.pooler = CamembertPooler(config) if add_pooling_layer else None
|
| 594 |
+
|
| 595 |
+
# Initialize weights and apply final processing
|
| 596 |
+
self.post_init()
|
| 597 |
+
|
| 598 |
+
def get_input_embeddings(self):
|
| 599 |
+
return self.embeddings.word_embeddings
|
| 600 |
+
|
| 601 |
+
def set_input_embeddings(self, value):
|
| 602 |
+
self.embeddings.word_embeddings = value
|
| 603 |
+
|
| 604 |
+
@merge_with_config_defaults
|
| 605 |
+
@capture_outputs
|
| 606 |
+
@auto_docstring
|
| 607 |
+
def forward(
|
| 608 |
+
self,
|
| 609 |
+
input_ids: torch.Tensor | None = None,
|
| 610 |
+
attention_mask: torch.Tensor | None = None,
|
| 611 |
+
token_type_ids: torch.Tensor | None = None,
|
| 612 |
+
position_ids: torch.Tensor | None = None,
|
| 613 |
+
inputs_embeds: torch.Tensor | None = None,
|
| 614 |
+
encoder_hidden_states: torch.Tensor | None = None,
|
| 615 |
+
encoder_attention_mask: torch.Tensor | None = None,
|
| 616 |
+
past_key_values: Cache | None = None,
|
| 617 |
+
use_cache: bool | None = None,
|
| 618 |
+
**kwargs: Unpack[TransformersKwargs],
|
| 619 |
+
) -> tuple[torch.Tensor] | BaseModelOutputWithPoolingAndCrossAttentions:
|
| 620 |
+
if (input_ids is None) ^ (inputs_embeds is not None):
|
| 621 |
+
raise ValueError("You must specify exactly one of input_ids or inputs_embeds")
|
| 622 |
+
|
| 623 |
+
if self.config.is_decoder:
|
| 624 |
+
use_cache = use_cache if use_cache is not None else self.config.use_cache
|
| 625 |
+
else:
|
| 626 |
+
use_cache = False
|
| 627 |
+
|
| 628 |
+
if use_cache and past_key_values is None:
|
| 629 |
+
past_key_values = (
|
| 630 |
+
EncoderDecoderCache(DynamicCache(config=self.config), DynamicCache(config=self.config))
|
| 631 |
+
if encoder_hidden_states is not None or self.config.is_encoder_decoder
|
| 632 |
+
else DynamicCache(config=self.config)
|
| 633 |
+
)
|
| 634 |
+
|
| 635 |
+
past_key_values_length = past_key_values.get_seq_length() if past_key_values is not None else 0
|
| 636 |
+
|
| 637 |
+
embedding_output = self.embeddings(
|
| 638 |
+
input_ids=input_ids,
|
| 639 |
+
position_ids=position_ids,
|
| 640 |
+
token_type_ids=token_type_ids,
|
| 641 |
+
inputs_embeds=inputs_embeds,
|
| 642 |
+
past_key_values_length=past_key_values_length,
|
| 643 |
+
)
|
| 644 |
+
|
| 645 |
+
attention_mask, encoder_attention_mask = self._create_attention_masks(
|
| 646 |
+
attention_mask=attention_mask,
|
| 647 |
+
encoder_attention_mask=encoder_attention_mask,
|
| 648 |
+
embedding_output=embedding_output,
|
| 649 |
+
encoder_hidden_states=encoder_hidden_states,
|
| 650 |
+
past_key_values=past_key_values,
|
| 651 |
+
)
|
| 652 |
+
|
| 653 |
+
encoder_outputs = self.encoder(
|
| 654 |
+
embedding_output,
|
| 655 |
+
attention_mask=attention_mask,
|
| 656 |
+
encoder_hidden_states=encoder_hidden_states,
|
| 657 |
+
encoder_attention_mask=encoder_attention_mask,
|
| 658 |
+
past_key_values=past_key_values,
|
| 659 |
+
use_cache=use_cache,
|
| 660 |
+
position_ids=position_ids,
|
| 661 |
+
**kwargs,
|
| 662 |
+
)
|
| 663 |
+
sequence_output = encoder_outputs.last_hidden_state
|
| 664 |
+
pooled_output = self.pooler(sequence_output) if self.pooler is not None else None
|
| 665 |
+
|
| 666 |
+
return BaseModelOutputWithPoolingAndCrossAttentions(
|
| 667 |
+
last_hidden_state=sequence_output,
|
| 668 |
+
pooler_output=pooled_output,
|
| 669 |
+
past_key_values=encoder_outputs.past_key_values,
|
| 670 |
+
)
|
| 671 |
+
|
| 672 |
+
def _create_attention_masks(
|
| 673 |
+
self,
|
| 674 |
+
attention_mask,
|
| 675 |
+
encoder_attention_mask,
|
| 676 |
+
embedding_output,
|
| 677 |
+
encoder_hidden_states,
|
| 678 |
+
past_key_values,
|
| 679 |
+
):
|
| 680 |
+
if self.config.is_decoder:
|
| 681 |
+
attention_mask = create_causal_mask(
|
| 682 |
+
config=self.config,
|
| 683 |
+
inputs_embeds=embedding_output,
|
| 684 |
+
attention_mask=attention_mask,
|
| 685 |
+
past_key_values=past_key_values,
|
| 686 |
+
)
|
| 687 |
+
else:
|
| 688 |
+
attention_mask = create_bidirectional_mask(
|
| 689 |
+
config=self.config,
|
| 690 |
+
inputs_embeds=embedding_output,
|
| 691 |
+
attention_mask=attention_mask,
|
| 692 |
+
)
|
| 693 |
+
|
| 694 |
+
if encoder_attention_mask is not None:
|
| 695 |
+
encoder_attention_mask = create_bidirectional_mask(
|
| 696 |
+
config=self.config,
|
| 697 |
+
inputs_embeds=embedding_output,
|
| 698 |
+
attention_mask=encoder_attention_mask,
|
| 699 |
+
encoder_hidden_states=encoder_hidden_states,
|
| 700 |
+
)
|
| 701 |
+
|
| 702 |
+
return attention_mask, encoder_attention_mask
|
| 703 |
+
|
| 704 |
+
|
| 705 |
+
@auto_docstring
|
| 706 |
+
class CamembertForMaskedLM(CamembertPreTrainedModel):
|
| 707 |
+
_tied_weights_keys = {
|
| 708 |
+
"lm_head.decoder.weight": "roberta.embeddings.word_embeddings.weight",
|
| 709 |
+
"lm_head.decoder.bias": "lm_head.bias",
|
| 710 |
+
}
|
| 711 |
+
|
| 712 |
+
def __init__(self, config):
|
| 713 |
+
super().__init__(config)
|
| 714 |
+
|
| 715 |
+
if config.is_decoder:
|
| 716 |
+
logger.warning(
|
| 717 |
+
"If you want to use `CamembertForMaskedLM` make sure `config.is_decoder=False` for "
|
| 718 |
+
"bi-directional self-attention."
|
| 719 |
+
)
|
| 720 |
+
self.lm_head = CamembertLMHead(config)
|
| 721 |
+
|
| 722 |
+
self.roberta = CamembertModel(config, add_pooling_layer=False)
|
| 723 |
+
|
| 724 |
+
# Initialize weights and apply final processing
|
| 725 |
+
self.post_init()
|
| 726 |
+
|
| 727 |
+
def get_output_embeddings(self):
|
| 728 |
+
return self.lm_head.decoder
|
| 729 |
+
|
| 730 |
+
def set_output_embeddings(self, new_embeddings):
|
| 731 |
+
self.lm_head.decoder = new_embeddings
|
| 732 |
+
|
| 733 |
+
@can_return_tuple
|
| 734 |
+
@auto_docstring
|
| 735 |
+
def forward(
|
| 736 |
+
self,
|
| 737 |
+
input_ids: torch.LongTensor | None = None,
|
| 738 |
+
attention_mask: torch.FloatTensor | None = None,
|
| 739 |
+
token_type_ids: torch.LongTensor | None = None,
|
| 740 |
+
position_ids: torch.LongTensor | None = None,
|
| 741 |
+
inputs_embeds: torch.FloatTensor | None = None,
|
| 742 |
+
encoder_hidden_states: torch.FloatTensor | None = None,
|
| 743 |
+
encoder_attention_mask: torch.FloatTensor | None = None,
|
| 744 |
+
labels: torch.LongTensor | None = None,
|
| 745 |
+
**kwargs: Unpack[TransformersKwargs],
|
| 746 |
+
) -> tuple[torch.Tensor] | MaskedLMOutput:
|
| 747 |
+
r"""
|
| 748 |
+
token_type_ids (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*):
|
| 749 |
+
Segment token indices to indicate first and second portions of the inputs. Indices are selected in `[0,1]`:
|
| 750 |
+
|
| 751 |
+
- 0 corresponds to a *sentence A* token,
|
| 752 |
+
- 1 corresponds to a *sentence B* token.
|
| 753 |
+
This parameter can only be used when the model is initialized with `type_vocab_size` parameter with value
|
| 754 |
+
>= 2. All the value in this tensor should be always < type_vocab_size.
|
| 755 |
+
|
| 756 |
+
[What are token type IDs?](../glossary#token-type-ids)
|
| 757 |
+
labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*):
|
| 758 |
+
Labels for computing the masked language modeling loss. Indices should be in `[-100, 0, ...,
|
| 759 |
+
config.vocab_size]` (see `input_ids` docstring) Tokens with indices set to `-100` are ignored (masked), the
|
| 760 |
+
loss is only computed for the tokens with labels in `[0, ..., config.vocab_size]`
|
| 761 |
+
"""
|
| 762 |
+
outputs = self.roberta(
|
| 763 |
+
input_ids,
|
| 764 |
+
attention_mask=attention_mask,
|
| 765 |
+
token_type_ids=token_type_ids,
|
| 766 |
+
position_ids=position_ids,
|
| 767 |
+
inputs_embeds=inputs_embeds,
|
| 768 |
+
encoder_hidden_states=encoder_hidden_states,
|
| 769 |
+
encoder_attention_mask=encoder_attention_mask,
|
| 770 |
+
return_dict=True,
|
| 771 |
+
**kwargs,
|
| 772 |
+
)
|
| 773 |
+
sequence_output = outputs[0]
|
| 774 |
+
prediction_scores = self.lm_head(sequence_output)
|
| 775 |
+
|
| 776 |
+
masked_lm_loss = None
|
| 777 |
+
if labels is not None:
|
| 778 |
+
# move labels to correct device
|
| 779 |
+
labels = labels.to(prediction_scores.device)
|
| 780 |
+
loss_fct = CrossEntropyLoss()
|
| 781 |
+
masked_lm_loss = loss_fct(prediction_scores.view(-1, self.config.vocab_size), labels.view(-1))
|
| 782 |
+
|
| 783 |
+
return MaskedLMOutput(
|
| 784 |
+
loss=masked_lm_loss,
|
| 785 |
+
logits=prediction_scores,
|
| 786 |
+
hidden_states=outputs.hidden_states,
|
| 787 |
+
attentions=outputs.attentions,
|
| 788 |
+
)
|
| 789 |
+
|
| 790 |
+
|
| 791 |
+
class CamembertClassificationHead(nn.Module):
|
| 792 |
+
"""Head for sentence-level classification tasks."""
|
| 793 |
+
|
| 794 |
+
def __init__(self, config):
|
| 795 |
+
super().__init__()
|
| 796 |
+
self.dense = nn.Linear(config.hidden_size, config.hidden_size)
|
| 797 |
+
classifier_dropout = (
|
| 798 |
+
config.classifier_dropout if config.classifier_dropout is not None else config.hidden_dropout_prob
|
| 799 |
+
)
|
| 800 |
+
self.dropout = nn.Dropout(classifier_dropout)
|
| 801 |
+
self.out_proj = nn.Linear(config.hidden_size, config.num_labels)
|
| 802 |
+
|
| 803 |
+
def forward(self, features, **kwargs):
|
| 804 |
+
x = features[:, 0, :] # take <s> token (equiv. to [CLS])
|
| 805 |
+
x = self.dropout(x)
|
| 806 |
+
x = self.dense(x)
|
| 807 |
+
x = torch.tanh(x)
|
| 808 |
+
x = self.dropout(x)
|
| 809 |
+
x = self.out_proj(x)
|
| 810 |
+
return x
|
| 811 |
+
|
| 812 |
+
|
| 813 |
+
@auto_docstring(
|
| 814 |
+
custom_intro="""
|
| 815 |
+
Camembert Model transformer with a sequence classification/regression head on top (a linear layer on top of the
|
| 816 |
+
pooled output) e.g. for GLUE tasks.
|
| 817 |
+
"""
|
| 818 |
+
)
|
| 819 |
+
class CamembertForSequenceClassification(CamembertPreTrainedModel):
|
| 820 |
+
def __init__(self, config):
|
| 821 |
+
super().__init__(config)
|
| 822 |
+
self.num_labels = config.num_labels
|
| 823 |
+
self.config = config
|
| 824 |
+
self.classifier = CamembertClassificationHead(config)
|
| 825 |
+
|
| 826 |
+
self.roberta = CamembertModel(config, add_pooling_layer=False)
|
| 827 |
+
|
| 828 |
+
# Initialize weights and apply final processing
|
| 829 |
+
self.post_init()
|
| 830 |
+
|
| 831 |
+
@can_return_tuple
|
| 832 |
+
@auto_docstring
|
| 833 |
+
def forward(
|
| 834 |
+
self,
|
| 835 |
+
input_ids: torch.LongTensor | None = None,
|
| 836 |
+
attention_mask: torch.FloatTensor | None = None,
|
| 837 |
+
token_type_ids: torch.LongTensor | None = None,
|
| 838 |
+
position_ids: torch.LongTensor | None = None,
|
| 839 |
+
inputs_embeds: torch.FloatTensor | None = None,
|
| 840 |
+
labels: torch.LongTensor | None = None,
|
| 841 |
+
**kwargs: Unpack[TransformersKwargs],
|
| 842 |
+
) -> tuple[torch.Tensor] | SequenceClassifierOutput:
|
| 843 |
+
r"""
|
| 844 |
+
token_type_ids (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*):
|
| 845 |
+
Segment token indices to indicate first and second portions of the inputs. Indices are selected in `[0,1]`:
|
| 846 |
+
|
| 847 |
+
- 0 corresponds to a *sentence A* token,
|
| 848 |
+
- 1 corresponds to a *sentence B* token.
|
| 849 |
+
This parameter can only be used when the model is initialized with `type_vocab_size` parameter with value
|
| 850 |
+
>= 2. All the value in this tensor should be always < type_vocab_size.
|
| 851 |
+
|
| 852 |
+
[What are token type IDs?](../glossary#token-type-ids)
|
| 853 |
+
labels (`torch.LongTensor` of shape `(batch_size,)`, *optional*):
|
| 854 |
+
Labels for computing the sequence classification/regression loss. Indices should be in `[0, ...,
|
| 855 |
+
config.num_labels - 1]`. If `config.num_labels == 1` a regression loss is computed (Mean-Square loss), If
|
| 856 |
+
`config.num_labels > 1` a classification loss is computed (Cross-Entropy).
|
| 857 |
+
"""
|
| 858 |
+
outputs = self.roberta(
|
| 859 |
+
input_ids,
|
| 860 |
+
attention_mask=attention_mask,
|
| 861 |
+
token_type_ids=token_type_ids,
|
| 862 |
+
position_ids=position_ids,
|
| 863 |
+
inputs_embeds=inputs_embeds,
|
| 864 |
+
return_dict=True,
|
| 865 |
+
**kwargs,
|
| 866 |
+
)
|
| 867 |
+
sequence_output = outputs[0]
|
| 868 |
+
logits = self.classifier(sequence_output)
|
| 869 |
+
|
| 870 |
+
loss = None
|
| 871 |
+
if labels is not None:
|
| 872 |
+
# move labels to correct device
|
| 873 |
+
labels = labels.to(logits.device)
|
| 874 |
+
if self.config.problem_type is None:
|
| 875 |
+
if self.num_labels == 1:
|
| 876 |
+
self.config.problem_type = "regression"
|
| 877 |
+
elif self.num_labels > 1 and (labels.dtype == torch.long or labels.dtype == torch.int):
|
| 878 |
+
self.config.problem_type = "single_label_classification"
|
| 879 |
+
else:
|
| 880 |
+
self.config.problem_type = "multi_label_classification"
|
| 881 |
+
|
| 882 |
+
if self.config.problem_type == "regression":
|
| 883 |
+
loss_fct = MSELoss()
|
| 884 |
+
if self.num_labels == 1:
|
| 885 |
+
loss = loss_fct(logits.squeeze(), labels.squeeze())
|
| 886 |
+
else:
|
| 887 |
+
loss = loss_fct(logits, labels)
|
| 888 |
+
elif self.config.problem_type == "single_label_classification":
|
| 889 |
+
loss_fct = CrossEntropyLoss()
|
| 890 |
+
loss = loss_fct(logits.view(-1, self.num_labels), labels.view(-1))
|
| 891 |
+
elif self.config.problem_type == "multi_label_classification":
|
| 892 |
+
loss_fct = BCEWithLogitsLoss()
|
| 893 |
+
loss = loss_fct(logits, labels)
|
| 894 |
+
|
| 895 |
+
return SequenceClassifierOutput(
|
| 896 |
+
loss=loss,
|
| 897 |
+
logits=logits,
|
| 898 |
+
hidden_states=outputs.hidden_states,
|
| 899 |
+
attentions=outputs.attentions,
|
| 900 |
+
)
|
| 901 |
+
|
| 902 |
+
|
| 903 |
+
@auto_docstring
|
| 904 |
+
class CamembertForMultipleChoice(CamembertPreTrainedModel):
|
| 905 |
+
def __init__(self, config):
|
| 906 |
+
super().__init__(config)
|
| 907 |
+
self.dropout = nn.Dropout(config.hidden_dropout_prob)
|
| 908 |
+
self.classifier = nn.Linear(config.hidden_size, 1)
|
| 909 |
+
|
| 910 |
+
self.roberta = CamembertModel(config, add_pooling_layer=False)
|
| 911 |
+
|
| 912 |
+
# Initialize weights and apply final processing
|
| 913 |
+
self.post_init()
|
| 914 |
+
|
| 915 |
+
@can_return_tuple
|
| 916 |
+
@auto_docstring
|
| 917 |
+
def forward(
|
| 918 |
+
self,
|
| 919 |
+
input_ids: torch.LongTensor | None = None,
|
| 920 |
+
token_type_ids: torch.LongTensor | None = None,
|
| 921 |
+
attention_mask: torch.FloatTensor | None = None,
|
| 922 |
+
labels: torch.LongTensor | None = None,
|
| 923 |
+
position_ids: torch.LongTensor | None = None,
|
| 924 |
+
inputs_embeds: torch.FloatTensor | None = None,
|
| 925 |
+
**kwargs: Unpack[TransformersKwargs],
|
| 926 |
+
) -> tuple[torch.Tensor] | MultipleChoiceModelOutput:
|
| 927 |
+
r"""
|
| 928 |
+
input_ids (`torch.LongTensor` of shape `(batch_size, num_choices, sequence_length)`):
|
| 929 |
+
Indices of input sequence tokens in the vocabulary.
|
| 930 |
+
|
| 931 |
+
Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and
|
| 932 |
+
[`PreTrainedTokenizer.__call__`] for details.
|
| 933 |
+
|
| 934 |
+
[What are input IDs?](../glossary#input-ids)
|
| 935 |
+
token_type_ids (`torch.LongTensor` of shape `(batch_size, num_choices, sequence_length)`, *optional*):
|
| 936 |
+
Segment token indices to indicate first and second portions of the inputs. Indices are selected in `[0,1]`:
|
| 937 |
+
|
| 938 |
+
- 0 corresponds to a *sentence A* token,
|
| 939 |
+
- 1 corresponds to a *sentence B* token.
|
| 940 |
+
This parameter can only be used when the model is initialized with `type_vocab_size` parameter with value
|
| 941 |
+
>= 2. All the value in this tensor should be always < type_vocab_size.
|
| 942 |
+
|
| 943 |
+
[What are token type IDs?](../glossary#token-type-ids)
|
| 944 |
+
labels (`torch.LongTensor` of shape `(batch_size,)`, *optional*):
|
| 945 |
+
Labels for computing the multiple choice classification loss. Indices should be in `[0, ...,
|
| 946 |
+
num_choices-1]` where `num_choices` is the size of the second dimension of the input tensors. (See
|
| 947 |
+
`input_ids` above)
|
| 948 |
+
position_ids (`torch.LongTensor` of shape `(batch_size, num_choices, sequence_length)`, *optional*):
|
| 949 |
+
Indices of positions of each input sequence tokens in the position embeddings. Selected in the range `[0,
|
| 950 |
+
config.max_position_embeddings - 1]`.
|
| 951 |
+
|
| 952 |
+
[What are position IDs?](../glossary#position-ids)
|
| 953 |
+
inputs_embeds (`torch.FloatTensor` of shape `(batch_size, num_choices, sequence_length, hidden_size)`, *optional*):
|
| 954 |
+
Optionally, instead of passing `input_ids` you can choose to directly pass an embedded representation. This
|
| 955 |
+
is useful if you want more control over how to convert `input_ids` indices into associated vectors than the
|
| 956 |
+
model's internal embedding lookup matrix.
|
| 957 |
+
"""
|
| 958 |
+
num_choices = input_ids.shape[1] if input_ids is not None else inputs_embeds.shape[1]
|
| 959 |
+
|
| 960 |
+
flat_input_ids = input_ids.view(-1, input_ids.size(-1)) if input_ids is not None else None
|
| 961 |
+
flat_position_ids = position_ids.view(-1, position_ids.size(-1)) if position_ids is not None else None
|
| 962 |
+
flat_token_type_ids = token_type_ids.view(-1, token_type_ids.size(-1)) if token_type_ids is not None else None
|
| 963 |
+
flat_attention_mask = attention_mask.view(-1, attention_mask.size(-1)) if attention_mask is not None else None
|
| 964 |
+
flat_inputs_embeds = (
|
| 965 |
+
inputs_embeds.view(-1, inputs_embeds.size(-2), inputs_embeds.size(-1))
|
| 966 |
+
if inputs_embeds is not None
|
| 967 |
+
else None
|
| 968 |
+
)
|
| 969 |
+
|
| 970 |
+
outputs = self.roberta(
|
| 971 |
+
flat_input_ids,
|
| 972 |
+
position_ids=flat_position_ids,
|
| 973 |
+
token_type_ids=flat_token_type_ids,
|
| 974 |
+
attention_mask=flat_attention_mask,
|
| 975 |
+
inputs_embeds=flat_inputs_embeds,
|
| 976 |
+
return_dict=True,
|
| 977 |
+
**kwargs,
|
| 978 |
+
)
|
| 979 |
+
pooled_output = outputs[1]
|
| 980 |
+
|
| 981 |
+
pooled_output = self.dropout(pooled_output)
|
| 982 |
+
logits = self.classifier(pooled_output)
|
| 983 |
+
reshaped_logits = logits.view(-1, num_choices)
|
| 984 |
+
|
| 985 |
+
loss = None
|
| 986 |
+
if labels is not None:
|
| 987 |
+
# move labels to correct device
|
| 988 |
+
labels = labels.to(reshaped_logits.device)
|
| 989 |
+
loss_fct = CrossEntropyLoss()
|
| 990 |
+
loss = loss_fct(reshaped_logits, labels)
|
| 991 |
+
|
| 992 |
+
return MultipleChoiceModelOutput(
|
| 993 |
+
loss=loss,
|
| 994 |
+
logits=reshaped_logits,
|
| 995 |
+
hidden_states=outputs.hidden_states,
|
| 996 |
+
attentions=outputs.attentions,
|
| 997 |
+
)
|
| 998 |
+
|
| 999 |
+
|
| 1000 |
+
@auto_docstring
|
| 1001 |
+
class CamembertForTokenClassification(CamembertPreTrainedModel):
|
| 1002 |
+
def __init__(self, config):
|
| 1003 |
+
super().__init__(config)
|
| 1004 |
+
self.num_labels = config.num_labels
|
| 1005 |
+
classifier_dropout = (
|
| 1006 |
+
config.classifier_dropout if config.classifier_dropout is not None else config.hidden_dropout_prob
|
| 1007 |
+
)
|
| 1008 |
+
self.dropout = nn.Dropout(classifier_dropout)
|
| 1009 |
+
self.classifier = nn.Linear(config.hidden_size, config.num_labels)
|
| 1010 |
+
|
| 1011 |
+
self.roberta = CamembertModel(config, add_pooling_layer=False)
|
| 1012 |
+
|
| 1013 |
+
# Initialize weights and apply final processing
|
| 1014 |
+
self.post_init()
|
| 1015 |
+
|
| 1016 |
+
@can_return_tuple
|
| 1017 |
+
@auto_docstring
|
| 1018 |
+
def forward(
|
| 1019 |
+
self,
|
| 1020 |
+
input_ids: torch.LongTensor | None = None,
|
| 1021 |
+
attention_mask: torch.FloatTensor | None = None,
|
| 1022 |
+
token_type_ids: torch.LongTensor | None = None,
|
| 1023 |
+
position_ids: torch.LongTensor | None = None,
|
| 1024 |
+
inputs_embeds: torch.FloatTensor | None = None,
|
| 1025 |
+
labels: torch.LongTensor | None = None,
|
| 1026 |
+
**kwargs: Unpack[TransformersKwargs],
|
| 1027 |
+
) -> tuple[torch.Tensor] | TokenClassifierOutput:
|
| 1028 |
+
r"""
|
| 1029 |
+
token_type_ids (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*):
|
| 1030 |
+
Segment token indices to indicate first and second portions of the inputs. Indices are selected in `[0,1]`:
|
| 1031 |
+
|
| 1032 |
+
- 0 corresponds to a *sentence A* token,
|
| 1033 |
+
- 1 corresponds to a *sentence B* token.
|
| 1034 |
+
This parameter can only be used when the model is initialized with `type_vocab_size` parameter with value
|
| 1035 |
+
>= 2. All the value in this tensor should be always < type_vocab_size.
|
| 1036 |
+
|
| 1037 |
+
[What are token type IDs?](../glossary#token-type-ids)
|
| 1038 |
+
labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*):
|
| 1039 |
+
Labels for computing the token classification loss. Indices should be in `[0, ..., config.num_labels - 1]`.
|
| 1040 |
+
"""
|
| 1041 |
+
outputs = self.roberta(
|
| 1042 |
+
input_ids,
|
| 1043 |
+
attention_mask=attention_mask,
|
| 1044 |
+
token_type_ids=token_type_ids,
|
| 1045 |
+
position_ids=position_ids,
|
| 1046 |
+
inputs_embeds=inputs_embeds,
|
| 1047 |
+
return_dict=True,
|
| 1048 |
+
**kwargs,
|
| 1049 |
+
)
|
| 1050 |
+
|
| 1051 |
+
sequence_output = outputs[0]
|
| 1052 |
+
|
| 1053 |
+
sequence_output = self.dropout(sequence_output)
|
| 1054 |
+
logits = self.classifier(sequence_output)
|
| 1055 |
+
|
| 1056 |
+
loss = None
|
| 1057 |
+
if labels is not None:
|
| 1058 |
+
# move labels to correct device
|
| 1059 |
+
labels = labels.to(logits.device)
|
| 1060 |
+
loss_fct = CrossEntropyLoss()
|
| 1061 |
+
loss = loss_fct(logits.view(-1, self.num_labels), labels.view(-1))
|
| 1062 |
+
|
| 1063 |
+
return TokenClassifierOutput(
|
| 1064 |
+
loss=loss,
|
| 1065 |
+
logits=logits,
|
| 1066 |
+
hidden_states=outputs.hidden_states,
|
| 1067 |
+
attentions=outputs.attentions,
|
| 1068 |
+
)
|
| 1069 |
+
|
| 1070 |
+
|
| 1071 |
+
@auto_docstring
|
| 1072 |
+
class CamembertForQuestionAnswering(CamembertPreTrainedModel):
|
| 1073 |
+
def __init__(self, config):
|
| 1074 |
+
super().__init__(config)
|
| 1075 |
+
self.num_labels = config.num_labels
|
| 1076 |
+
self.qa_outputs = nn.Linear(config.hidden_size, config.num_labels)
|
| 1077 |
+
|
| 1078 |
+
self.roberta = CamembertModel(config, add_pooling_layer=False)
|
| 1079 |
+
|
| 1080 |
+
# Initialize weights and apply final processing
|
| 1081 |
+
self.post_init()
|
| 1082 |
+
|
| 1083 |
+
@can_return_tuple
|
| 1084 |
+
@auto_docstring
|
| 1085 |
+
def forward(
|
| 1086 |
+
self,
|
| 1087 |
+
input_ids: torch.LongTensor | None = None,
|
| 1088 |
+
attention_mask: torch.FloatTensor | None = None,
|
| 1089 |
+
token_type_ids: torch.LongTensor | None = None,
|
| 1090 |
+
position_ids: torch.LongTensor | None = None,
|
| 1091 |
+
inputs_embeds: torch.FloatTensor | None = None,
|
| 1092 |
+
start_positions: torch.LongTensor | None = None,
|
| 1093 |
+
end_positions: torch.LongTensor | None = None,
|
| 1094 |
+
**kwargs: Unpack[TransformersKwargs],
|
| 1095 |
+
) -> tuple[torch.Tensor] | QuestionAnsweringModelOutput:
|
| 1096 |
+
r"""
|
| 1097 |
+
token_type_ids (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*):
|
| 1098 |
+
Segment token indices to indicate first and second portions of the inputs. Indices are selected in `[0,1]`:
|
| 1099 |
+
|
| 1100 |
+
- 0 corresponds to a *sentence A* token,
|
| 1101 |
+
- 1 corresponds to a *sentence B* token.
|
| 1102 |
+
This parameter can only be used when the model is initialized with `type_vocab_size` parameter with value
|
| 1103 |
+
>= 2. All the value in this tensor should be always < type_vocab_size.
|
| 1104 |
+
|
| 1105 |
+
[What are token type IDs?](../glossary#token-type-ids)
|
| 1106 |
+
"""
|
| 1107 |
+
outputs = self.roberta(
|
| 1108 |
+
input_ids,
|
| 1109 |
+
attention_mask=attention_mask,
|
| 1110 |
+
token_type_ids=token_type_ids,
|
| 1111 |
+
position_ids=position_ids,
|
| 1112 |
+
inputs_embeds=inputs_embeds,
|
| 1113 |
+
return_dict=True,
|
| 1114 |
+
**kwargs,
|
| 1115 |
+
)
|
| 1116 |
+
|
| 1117 |
+
sequence_output = outputs[0]
|
| 1118 |
+
|
| 1119 |
+
logits = self.qa_outputs(sequence_output)
|
| 1120 |
+
start_logits, end_logits = logits.split(1, dim=-1)
|
| 1121 |
+
start_logits = start_logits.squeeze(-1).contiguous()
|
| 1122 |
+
end_logits = end_logits.squeeze(-1).contiguous()
|
| 1123 |
+
|
| 1124 |
+
total_loss = None
|
| 1125 |
+
if start_positions is not None and end_positions is not None:
|
| 1126 |
+
# If we are on multi-GPU, split add a dimension
|
| 1127 |
+
if len(start_positions.size()) > 1:
|
| 1128 |
+
start_positions = start_positions.squeeze(-1)
|
| 1129 |
+
if len(end_positions.size()) > 1:
|
| 1130 |
+
end_positions = end_positions.squeeze(-1)
|
| 1131 |
+
# sometimes the start/end positions are outside our model inputs, we ignore these terms
|
| 1132 |
+
ignored_index = start_logits.size(1)
|
| 1133 |
+
start_positions = start_positions.clamp(0, ignored_index)
|
| 1134 |
+
end_positions = end_positions.clamp(0, ignored_index)
|
| 1135 |
+
|
| 1136 |
+
loss_fct = CrossEntropyLoss(ignore_index=ignored_index)
|
| 1137 |
+
start_loss = loss_fct(start_logits, start_positions)
|
| 1138 |
+
end_loss = loss_fct(end_logits, end_positions)
|
| 1139 |
+
total_loss = (start_loss + end_loss) / 2
|
| 1140 |
+
|
| 1141 |
+
return QuestionAnsweringModelOutput(
|
| 1142 |
+
loss=total_loss,
|
| 1143 |
+
start_logits=start_logits,
|
| 1144 |
+
end_logits=end_logits,
|
| 1145 |
+
hidden_states=outputs.hidden_states,
|
| 1146 |
+
attentions=outputs.attentions,
|
| 1147 |
+
)
|
| 1148 |
+
|
| 1149 |
+
|
| 1150 |
+
@auto_docstring(
|
| 1151 |
+
custom_intro="""
|
| 1152 |
+
Camembert Model with a `language modeling` head on top for CLM fine-tuning.
|
| 1153 |
+
"""
|
| 1154 |
+
)
|
| 1155 |
+
class CamembertForCausalLM(CamembertPreTrainedModel, GenerationMixin):
|
| 1156 |
+
_tied_weights_keys = {
|
| 1157 |
+
"lm_head.decoder.weight": "roberta.embeddings.word_embeddings.weight",
|
| 1158 |
+
"lm_head.decoder.bias": "lm_head.bias",
|
| 1159 |
+
}
|
| 1160 |
+
|
| 1161 |
+
def __init__(self, config):
|
| 1162 |
+
super().__init__(config)
|
| 1163 |
+
|
| 1164 |
+
if not config.is_decoder:
|
| 1165 |
+
logger.warning("If you want to use `CamembertLMHeadModel` as a standalone, add `is_decoder=True.`")
|
| 1166 |
+
self.lm_head = CamembertLMHead(config)
|
| 1167 |
+
|
| 1168 |
+
self.roberta = CamembertModel(config, add_pooling_layer=False)
|
| 1169 |
+
|
| 1170 |
+
# Initialize weights and apply final processing
|
| 1171 |
+
self.post_init()
|
| 1172 |
+
|
| 1173 |
+
def get_output_embeddings(self):
|
| 1174 |
+
return self.lm_head.decoder
|
| 1175 |
+
|
| 1176 |
+
def set_output_embeddings(self, new_embeddings):
|
| 1177 |
+
self.lm_head.decoder = new_embeddings
|
| 1178 |
+
|
| 1179 |
+
@can_return_tuple
|
| 1180 |
+
@auto_docstring
|
| 1181 |
+
def forward(
|
| 1182 |
+
self,
|
| 1183 |
+
input_ids: torch.LongTensor | None = None,
|
| 1184 |
+
attention_mask: torch.FloatTensor | None = None,
|
| 1185 |
+
token_type_ids: torch.LongTensor | None = None,
|
| 1186 |
+
position_ids: torch.LongTensor | None = None,
|
| 1187 |
+
inputs_embeds: torch.FloatTensor | None = None,
|
| 1188 |
+
encoder_hidden_states: torch.FloatTensor | None = None,
|
| 1189 |
+
encoder_attention_mask: torch.FloatTensor | None = None,
|
| 1190 |
+
labels: torch.LongTensor | None = None,
|
| 1191 |
+
past_key_values: tuple[tuple[torch.FloatTensor]] | None = None,
|
| 1192 |
+
use_cache: bool | None = None,
|
| 1193 |
+
logits_to_keep: int | torch.Tensor = 0,
|
| 1194 |
+
**kwargs: Unpack[TransformersKwargs],
|
| 1195 |
+
) -> tuple[torch.Tensor] | CausalLMOutputWithCrossAttentions:
|
| 1196 |
+
r"""
|
| 1197 |
+
token_type_ids (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*):
|
| 1198 |
+
Segment token indices to indicate first and second portions of the inputs. Indices are selected in `[0,1]`:
|
| 1199 |
+
|
| 1200 |
+
- 0 corresponds to a *sentence A* token,
|
| 1201 |
+
- 1 corresponds to a *sentence B* token.
|
| 1202 |
+
This parameter can only be used when the model is initialized with `type_vocab_size` parameter with value
|
| 1203 |
+
>= 2. All the value in this tensor should be always < type_vocab_size.
|
| 1204 |
+
|
| 1205 |
+
[What are token type IDs?](../glossary#token-type-ids)
|
| 1206 |
+
labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*):
|
| 1207 |
+
Labels for computing the left-to-right language modeling loss (next word prediction). Indices should be in
|
| 1208 |
+
`[-100, 0, ..., config.vocab_size]` (see `input_ids` docstring) Tokens with indices set to `-100` are
|
| 1209 |
+
ignored (masked), the loss is only computed for the tokens with labels in `[0, ..., config.vocab_size]`
|
| 1210 |
+
|
| 1211 |
+
Example:
|
| 1212 |
+
|
| 1213 |
+
```python
|
| 1214 |
+
>>> from transformers import AutoTokenizer, CamembertForCausalLM, AutoConfig
|
| 1215 |
+
>>> import torch
|
| 1216 |
+
|
| 1217 |
+
>>> tokenizer = AutoTokenizer.from_pretrained("almanach/camembert-base")
|
| 1218 |
+
>>> config = AutoConfig.from_pretrained("almanach/camembert-base")
|
| 1219 |
+
>>> config.is_decoder = True
|
| 1220 |
+
>>> model = CamembertForCausalLM.from_pretrained("almanach/camembert-base", config=config)
|
| 1221 |
+
|
| 1222 |
+
>>> inputs = tokenizer("Hello, my dog is cute", return_tensors="pt")
|
| 1223 |
+
>>> outputs = model(**inputs)
|
| 1224 |
+
|
| 1225 |
+
>>> prediction_logits = outputs.logits
|
| 1226 |
+
```"""
|
| 1227 |
+
if labels is not None:
|
| 1228 |
+
use_cache = False
|
| 1229 |
+
|
| 1230 |
+
outputs: BaseModelOutputWithPoolingAndCrossAttentions = self.roberta(
|
| 1231 |
+
input_ids,
|
| 1232 |
+
attention_mask=attention_mask,
|
| 1233 |
+
token_type_ids=token_type_ids,
|
| 1234 |
+
position_ids=position_ids,
|
| 1235 |
+
inputs_embeds=inputs_embeds,
|
| 1236 |
+
encoder_hidden_states=encoder_hidden_states,
|
| 1237 |
+
encoder_attention_mask=encoder_attention_mask,
|
| 1238 |
+
past_key_values=past_key_values,
|
| 1239 |
+
use_cache=use_cache,
|
| 1240 |
+
return_dict=True,
|
| 1241 |
+
**kwargs,
|
| 1242 |
+
)
|
| 1243 |
+
|
| 1244 |
+
hidden_states = outputs.last_hidden_state
|
| 1245 |
+
# Only compute necessary logits, and do not upcast them to float if we are not computing the loss
|
| 1246 |
+
slice_indices = slice(-logits_to_keep, None) if isinstance(logits_to_keep, int) else logits_to_keep
|
| 1247 |
+
logits = self.lm_head(hidden_states[:, slice_indices, :])
|
| 1248 |
+
|
| 1249 |
+
loss = None
|
| 1250 |
+
if labels is not None:
|
| 1251 |
+
loss = self.loss_function(logits=logits, labels=labels, vocab_size=self.config.vocab_size, **kwargs)
|
| 1252 |
+
|
| 1253 |
+
return CausalLMOutputWithCrossAttentions(
|
| 1254 |
+
loss=loss,
|
| 1255 |
+
logits=logits,
|
| 1256 |
+
past_key_values=outputs.past_key_values,
|
| 1257 |
+
hidden_states=outputs.hidden_states,
|
| 1258 |
+
attentions=outputs.attentions,
|
| 1259 |
+
cross_attentions=outputs.cross_attentions,
|
| 1260 |
+
)
|
| 1261 |
+
|
| 1262 |
+
|
| 1263 |
+
__all__ = [
|
| 1264 |
+
"CamembertForCausalLM",
|
| 1265 |
+
"CamembertForMaskedLM",
|
| 1266 |
+
"CamembertForMultipleChoice",
|
| 1267 |
+
"CamembertForQuestionAnswering",
|
| 1268 |
+
"CamembertForSequenceClassification",
|
| 1269 |
+
"CamembertForTokenClassification",
|
| 1270 |
+
"CamembertModel",
|
| 1271 |
+
"CamembertPreTrainedModel",
|
| 1272 |
+
]
|
third_party/transformers/src/transformers/models/camembert/modular_camembert.py
ADDED
|
@@ -0,0 +1,534 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright 2019 Inria, Facebook AI Research and the HuggingFace Inc. team.
|
| 2 |
+
# Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved.
|
| 3 |
+
#
|
| 4 |
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
| 5 |
+
# you may not use this file except in compliance with the License.
|
| 6 |
+
# You may obtain a copy of the License at
|
| 7 |
+
#
|
| 8 |
+
# http://www.apache.org/licenses/LICENSE-2.0
|
| 9 |
+
#
|
| 10 |
+
# Unless required by applicable law or agreed to in writing, software
|
| 11 |
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
| 12 |
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 13 |
+
# See the License for the specific language governing permissions and
|
| 14 |
+
# limitations under the License.
|
| 15 |
+
"""PyTorch CamemBERT model."""
|
| 16 |
+
|
| 17 |
+
import torch
|
| 18 |
+
from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss
|
| 19 |
+
|
| 20 |
+
from ...modeling_outputs import (
|
| 21 |
+
BaseModelOutputWithPoolingAndCrossAttentions,
|
| 22 |
+
CausalLMOutputWithCrossAttentions,
|
| 23 |
+
MaskedLMOutput,
|
| 24 |
+
MultipleChoiceModelOutput,
|
| 25 |
+
QuestionAnsweringModelOutput,
|
| 26 |
+
SequenceClassifierOutput,
|
| 27 |
+
TokenClassifierOutput,
|
| 28 |
+
)
|
| 29 |
+
from ...processing_utils import Unpack
|
| 30 |
+
from ...utils import TransformersKwargs, auto_docstring
|
| 31 |
+
from ...utils.generic import can_return_tuple
|
| 32 |
+
from ..roberta.modeling_roberta import (
|
| 33 |
+
RobertaForCausalLM,
|
| 34 |
+
RobertaForMaskedLM,
|
| 35 |
+
RobertaForMultipleChoice,
|
| 36 |
+
RobertaForQuestionAnswering,
|
| 37 |
+
RobertaForSequenceClassification,
|
| 38 |
+
RobertaForTokenClassification,
|
| 39 |
+
RobertaModel,
|
| 40 |
+
RobertaPreTrainedModel,
|
| 41 |
+
)
|
| 42 |
+
|
| 43 |
+
|
| 44 |
+
class CamembertPreTrainedModel(RobertaPreTrainedModel):
|
| 45 |
+
base_model_prefix = "roberta"
|
| 46 |
+
|
| 47 |
+
|
| 48 |
+
class CamembertModel(RobertaModel):
|
| 49 |
+
pass
|
| 50 |
+
|
| 51 |
+
|
| 52 |
+
class CamembertForMaskedLM(RobertaForMaskedLM):
|
| 53 |
+
_tied_weights_keys = {
|
| 54 |
+
"lm_head.decoder.weight": "roberta.embeddings.word_embeddings.weight",
|
| 55 |
+
"lm_head.decoder.bias": "lm_head.bias",
|
| 56 |
+
}
|
| 57 |
+
|
| 58 |
+
def __init__(self, config):
|
| 59 |
+
super().__init__(config)
|
| 60 |
+
del self.camembert
|
| 61 |
+
|
| 62 |
+
self.roberta = CamembertModel(config, add_pooling_layer=False)
|
| 63 |
+
|
| 64 |
+
@can_return_tuple
|
| 65 |
+
@auto_docstring
|
| 66 |
+
def forward(
|
| 67 |
+
self,
|
| 68 |
+
input_ids: torch.LongTensor | None = None,
|
| 69 |
+
attention_mask: torch.FloatTensor | None = None,
|
| 70 |
+
token_type_ids: torch.LongTensor | None = None,
|
| 71 |
+
position_ids: torch.LongTensor | None = None,
|
| 72 |
+
inputs_embeds: torch.FloatTensor | None = None,
|
| 73 |
+
encoder_hidden_states: torch.FloatTensor | None = None,
|
| 74 |
+
encoder_attention_mask: torch.FloatTensor | None = None,
|
| 75 |
+
labels: torch.LongTensor | None = None,
|
| 76 |
+
**kwargs: Unpack[TransformersKwargs],
|
| 77 |
+
) -> tuple[torch.Tensor] | MaskedLMOutput:
|
| 78 |
+
r"""
|
| 79 |
+
token_type_ids (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*):
|
| 80 |
+
Segment token indices to indicate first and second portions of the inputs. Indices are selected in `[0,1]`:
|
| 81 |
+
|
| 82 |
+
- 0 corresponds to a *sentence A* token,
|
| 83 |
+
- 1 corresponds to a *sentence B* token.
|
| 84 |
+
This parameter can only be used when the model is initialized with `type_vocab_size` parameter with value
|
| 85 |
+
>= 2. All the value in this tensor should be always < type_vocab_size.
|
| 86 |
+
|
| 87 |
+
[What are token type IDs?](../glossary#token-type-ids)
|
| 88 |
+
labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*):
|
| 89 |
+
Labels for computing the masked language modeling loss. Indices should be in `[-100, 0, ...,
|
| 90 |
+
config.vocab_size]` (see `input_ids` docstring) Tokens with indices set to `-100` are ignored (masked), the
|
| 91 |
+
loss is only computed for the tokens with labels in `[0, ..., config.vocab_size]`
|
| 92 |
+
"""
|
| 93 |
+
outputs = self.roberta(
|
| 94 |
+
input_ids,
|
| 95 |
+
attention_mask=attention_mask,
|
| 96 |
+
token_type_ids=token_type_ids,
|
| 97 |
+
position_ids=position_ids,
|
| 98 |
+
inputs_embeds=inputs_embeds,
|
| 99 |
+
encoder_hidden_states=encoder_hidden_states,
|
| 100 |
+
encoder_attention_mask=encoder_attention_mask,
|
| 101 |
+
return_dict=True,
|
| 102 |
+
**kwargs,
|
| 103 |
+
)
|
| 104 |
+
sequence_output = outputs[0]
|
| 105 |
+
prediction_scores = self.lm_head(sequence_output)
|
| 106 |
+
|
| 107 |
+
masked_lm_loss = None
|
| 108 |
+
if labels is not None:
|
| 109 |
+
# move labels to correct device
|
| 110 |
+
labels = labels.to(prediction_scores.device)
|
| 111 |
+
loss_fct = CrossEntropyLoss()
|
| 112 |
+
masked_lm_loss = loss_fct(prediction_scores.view(-1, self.config.vocab_size), labels.view(-1))
|
| 113 |
+
|
| 114 |
+
return MaskedLMOutput(
|
| 115 |
+
loss=masked_lm_loss,
|
| 116 |
+
logits=prediction_scores,
|
| 117 |
+
hidden_states=outputs.hidden_states,
|
| 118 |
+
attentions=outputs.attentions,
|
| 119 |
+
)
|
| 120 |
+
|
| 121 |
+
|
| 122 |
+
class CamembertForSequenceClassification(RobertaForSequenceClassification):
|
| 123 |
+
def __init__(self, config):
|
| 124 |
+
super().__init__(config)
|
| 125 |
+
del self.camembert
|
| 126 |
+
|
| 127 |
+
self.roberta = CamembertModel(config, add_pooling_layer=False)
|
| 128 |
+
|
| 129 |
+
@can_return_tuple
|
| 130 |
+
@auto_docstring
|
| 131 |
+
def forward(
|
| 132 |
+
self,
|
| 133 |
+
input_ids: torch.LongTensor | None = None,
|
| 134 |
+
attention_mask: torch.FloatTensor | None = None,
|
| 135 |
+
token_type_ids: torch.LongTensor | None = None,
|
| 136 |
+
position_ids: torch.LongTensor | None = None,
|
| 137 |
+
inputs_embeds: torch.FloatTensor | None = None,
|
| 138 |
+
labels: torch.LongTensor | None = None,
|
| 139 |
+
**kwargs: Unpack[TransformersKwargs],
|
| 140 |
+
) -> tuple[torch.Tensor] | SequenceClassifierOutput:
|
| 141 |
+
r"""
|
| 142 |
+
token_type_ids (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*):
|
| 143 |
+
Segment token indices to indicate first and second portions of the inputs. Indices are selected in `[0,1]`:
|
| 144 |
+
|
| 145 |
+
- 0 corresponds to a *sentence A* token,
|
| 146 |
+
- 1 corresponds to a *sentence B* token.
|
| 147 |
+
This parameter can only be used when the model is initialized with `type_vocab_size` parameter with value
|
| 148 |
+
>= 2. All the value in this tensor should be always < type_vocab_size.
|
| 149 |
+
|
| 150 |
+
[What are token type IDs?](../glossary#token-type-ids)
|
| 151 |
+
labels (`torch.LongTensor` of shape `(batch_size,)`, *optional*):
|
| 152 |
+
Labels for computing the sequence classification/regression loss. Indices should be in `[0, ...,
|
| 153 |
+
config.num_labels - 1]`. If `config.num_labels == 1` a regression loss is computed (Mean-Square loss), If
|
| 154 |
+
`config.num_labels > 1` a classification loss is computed (Cross-Entropy).
|
| 155 |
+
"""
|
| 156 |
+
outputs = self.roberta(
|
| 157 |
+
input_ids,
|
| 158 |
+
attention_mask=attention_mask,
|
| 159 |
+
token_type_ids=token_type_ids,
|
| 160 |
+
position_ids=position_ids,
|
| 161 |
+
inputs_embeds=inputs_embeds,
|
| 162 |
+
return_dict=True,
|
| 163 |
+
**kwargs,
|
| 164 |
+
)
|
| 165 |
+
sequence_output = outputs[0]
|
| 166 |
+
logits = self.classifier(sequence_output)
|
| 167 |
+
|
| 168 |
+
loss = None
|
| 169 |
+
if labels is not None:
|
| 170 |
+
# move labels to correct device
|
| 171 |
+
labels = labels.to(logits.device)
|
| 172 |
+
if self.config.problem_type is None:
|
| 173 |
+
if self.num_labels == 1:
|
| 174 |
+
self.config.problem_type = "regression"
|
| 175 |
+
elif self.num_labels > 1 and (labels.dtype == torch.long or labels.dtype == torch.int):
|
| 176 |
+
self.config.problem_type = "single_label_classification"
|
| 177 |
+
else:
|
| 178 |
+
self.config.problem_type = "multi_label_classification"
|
| 179 |
+
|
| 180 |
+
if self.config.problem_type == "regression":
|
| 181 |
+
loss_fct = MSELoss()
|
| 182 |
+
if self.num_labels == 1:
|
| 183 |
+
loss = loss_fct(logits.squeeze(), labels.squeeze())
|
| 184 |
+
else:
|
| 185 |
+
loss = loss_fct(logits, labels)
|
| 186 |
+
elif self.config.problem_type == "single_label_classification":
|
| 187 |
+
loss_fct = CrossEntropyLoss()
|
| 188 |
+
loss = loss_fct(logits.view(-1, self.num_labels), labels.view(-1))
|
| 189 |
+
elif self.config.problem_type == "multi_label_classification":
|
| 190 |
+
loss_fct = BCEWithLogitsLoss()
|
| 191 |
+
loss = loss_fct(logits, labels)
|
| 192 |
+
|
| 193 |
+
return SequenceClassifierOutput(
|
| 194 |
+
loss=loss,
|
| 195 |
+
logits=logits,
|
| 196 |
+
hidden_states=outputs.hidden_states,
|
| 197 |
+
attentions=outputs.attentions,
|
| 198 |
+
)
|
| 199 |
+
|
| 200 |
+
|
| 201 |
+
class CamembertForMultipleChoice(RobertaForMultipleChoice):
|
| 202 |
+
def __init__(self, config):
|
| 203 |
+
super().__init__(config)
|
| 204 |
+
del self.camembert
|
| 205 |
+
|
| 206 |
+
self.roberta = CamembertModel(config, add_pooling_layer=False)
|
| 207 |
+
|
| 208 |
+
@can_return_tuple
|
| 209 |
+
@auto_docstring
|
| 210 |
+
def forward(
|
| 211 |
+
self,
|
| 212 |
+
input_ids: torch.LongTensor | None = None,
|
| 213 |
+
token_type_ids: torch.LongTensor | None = None,
|
| 214 |
+
attention_mask: torch.FloatTensor | None = None,
|
| 215 |
+
labels: torch.LongTensor | None = None,
|
| 216 |
+
position_ids: torch.LongTensor | None = None,
|
| 217 |
+
inputs_embeds: torch.FloatTensor | None = None,
|
| 218 |
+
**kwargs: Unpack[TransformersKwargs],
|
| 219 |
+
) -> tuple[torch.Tensor] | MultipleChoiceModelOutput:
|
| 220 |
+
r"""
|
| 221 |
+
input_ids (`torch.LongTensor` of shape `(batch_size, num_choices, sequence_length)`):
|
| 222 |
+
Indices of input sequence tokens in the vocabulary.
|
| 223 |
+
|
| 224 |
+
Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and
|
| 225 |
+
[`PreTrainedTokenizer.__call__`] for details.
|
| 226 |
+
|
| 227 |
+
[What are input IDs?](../glossary#input-ids)
|
| 228 |
+
token_type_ids (`torch.LongTensor` of shape `(batch_size, num_choices, sequence_length)`, *optional*):
|
| 229 |
+
Segment token indices to indicate first and second portions of the inputs. Indices are selected in `[0,1]`:
|
| 230 |
+
|
| 231 |
+
- 0 corresponds to a *sentence A* token,
|
| 232 |
+
- 1 corresponds to a *sentence B* token.
|
| 233 |
+
This parameter can only be used when the model is initialized with `type_vocab_size` parameter with value
|
| 234 |
+
>= 2. All the value in this tensor should be always < type_vocab_size.
|
| 235 |
+
|
| 236 |
+
[What are token type IDs?](../glossary#token-type-ids)
|
| 237 |
+
labels (`torch.LongTensor` of shape `(batch_size,)`, *optional*):
|
| 238 |
+
Labels for computing the multiple choice classification loss. Indices should be in `[0, ...,
|
| 239 |
+
num_choices-1]` where `num_choices` is the size of the second dimension of the input tensors. (See
|
| 240 |
+
`input_ids` above)
|
| 241 |
+
position_ids (`torch.LongTensor` of shape `(batch_size, num_choices, sequence_length)`, *optional*):
|
| 242 |
+
Indices of positions of each input sequence tokens in the position embeddings. Selected in the range `[0,
|
| 243 |
+
config.max_position_embeddings - 1]`.
|
| 244 |
+
|
| 245 |
+
[What are position IDs?](../glossary#position-ids)
|
| 246 |
+
inputs_embeds (`torch.FloatTensor` of shape `(batch_size, num_choices, sequence_length, hidden_size)`, *optional*):
|
| 247 |
+
Optionally, instead of passing `input_ids` you can choose to directly pass an embedded representation. This
|
| 248 |
+
is useful if you want more control over how to convert `input_ids` indices into associated vectors than the
|
| 249 |
+
model's internal embedding lookup matrix.
|
| 250 |
+
"""
|
| 251 |
+
num_choices = input_ids.shape[1] if input_ids is not None else inputs_embeds.shape[1]
|
| 252 |
+
|
| 253 |
+
flat_input_ids = input_ids.view(-1, input_ids.size(-1)) if input_ids is not None else None
|
| 254 |
+
flat_position_ids = position_ids.view(-1, position_ids.size(-1)) if position_ids is not None else None
|
| 255 |
+
flat_token_type_ids = token_type_ids.view(-1, token_type_ids.size(-1)) if token_type_ids is not None else None
|
| 256 |
+
flat_attention_mask = attention_mask.view(-1, attention_mask.size(-1)) if attention_mask is not None else None
|
| 257 |
+
flat_inputs_embeds = (
|
| 258 |
+
inputs_embeds.view(-1, inputs_embeds.size(-2), inputs_embeds.size(-1))
|
| 259 |
+
if inputs_embeds is not None
|
| 260 |
+
else None
|
| 261 |
+
)
|
| 262 |
+
|
| 263 |
+
outputs = self.roberta(
|
| 264 |
+
flat_input_ids,
|
| 265 |
+
position_ids=flat_position_ids,
|
| 266 |
+
token_type_ids=flat_token_type_ids,
|
| 267 |
+
attention_mask=flat_attention_mask,
|
| 268 |
+
inputs_embeds=flat_inputs_embeds,
|
| 269 |
+
return_dict=True,
|
| 270 |
+
**kwargs,
|
| 271 |
+
)
|
| 272 |
+
pooled_output = outputs[1]
|
| 273 |
+
|
| 274 |
+
pooled_output = self.dropout(pooled_output)
|
| 275 |
+
logits = self.classifier(pooled_output)
|
| 276 |
+
reshaped_logits = logits.view(-1, num_choices)
|
| 277 |
+
|
| 278 |
+
loss = None
|
| 279 |
+
if labels is not None:
|
| 280 |
+
# move labels to correct device
|
| 281 |
+
labels = labels.to(reshaped_logits.device)
|
| 282 |
+
loss_fct = CrossEntropyLoss()
|
| 283 |
+
loss = loss_fct(reshaped_logits, labels)
|
| 284 |
+
|
| 285 |
+
return MultipleChoiceModelOutput(
|
| 286 |
+
loss=loss,
|
| 287 |
+
logits=reshaped_logits,
|
| 288 |
+
hidden_states=outputs.hidden_states,
|
| 289 |
+
attentions=outputs.attentions,
|
| 290 |
+
)
|
| 291 |
+
|
| 292 |
+
|
| 293 |
+
class CamembertForTokenClassification(RobertaForTokenClassification):
|
| 294 |
+
def __init__(self, config):
|
| 295 |
+
super().__init__(config)
|
| 296 |
+
del self.camembert
|
| 297 |
+
|
| 298 |
+
self.roberta = CamembertModel(config, add_pooling_layer=False)
|
| 299 |
+
|
| 300 |
+
@can_return_tuple
|
| 301 |
+
@auto_docstring
|
| 302 |
+
def forward(
|
| 303 |
+
self,
|
| 304 |
+
input_ids: torch.LongTensor | None = None,
|
| 305 |
+
attention_mask: torch.FloatTensor | None = None,
|
| 306 |
+
token_type_ids: torch.LongTensor | None = None,
|
| 307 |
+
position_ids: torch.LongTensor | None = None,
|
| 308 |
+
inputs_embeds: torch.FloatTensor | None = None,
|
| 309 |
+
labels: torch.LongTensor | None = None,
|
| 310 |
+
**kwargs: Unpack[TransformersKwargs],
|
| 311 |
+
) -> tuple[torch.Tensor] | TokenClassifierOutput:
|
| 312 |
+
r"""
|
| 313 |
+
token_type_ids (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*):
|
| 314 |
+
Segment token indices to indicate first and second portions of the inputs. Indices are selected in `[0,1]`:
|
| 315 |
+
|
| 316 |
+
- 0 corresponds to a *sentence A* token,
|
| 317 |
+
- 1 corresponds to a *sentence B* token.
|
| 318 |
+
This parameter can only be used when the model is initialized with `type_vocab_size` parameter with value
|
| 319 |
+
>= 2. All the value in this tensor should be always < type_vocab_size.
|
| 320 |
+
|
| 321 |
+
[What are token type IDs?](../glossary#token-type-ids)
|
| 322 |
+
labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*):
|
| 323 |
+
Labels for computing the token classification loss. Indices should be in `[0, ..., config.num_labels - 1]`.
|
| 324 |
+
"""
|
| 325 |
+
outputs = self.roberta(
|
| 326 |
+
input_ids,
|
| 327 |
+
attention_mask=attention_mask,
|
| 328 |
+
token_type_ids=token_type_ids,
|
| 329 |
+
position_ids=position_ids,
|
| 330 |
+
inputs_embeds=inputs_embeds,
|
| 331 |
+
return_dict=True,
|
| 332 |
+
**kwargs,
|
| 333 |
+
)
|
| 334 |
+
|
| 335 |
+
sequence_output = outputs[0]
|
| 336 |
+
|
| 337 |
+
sequence_output = self.dropout(sequence_output)
|
| 338 |
+
logits = self.classifier(sequence_output)
|
| 339 |
+
|
| 340 |
+
loss = None
|
| 341 |
+
if labels is not None:
|
| 342 |
+
# move labels to correct device
|
| 343 |
+
labels = labels.to(logits.device)
|
| 344 |
+
loss_fct = CrossEntropyLoss()
|
| 345 |
+
loss = loss_fct(logits.view(-1, self.num_labels), labels.view(-1))
|
| 346 |
+
|
| 347 |
+
return TokenClassifierOutput(
|
| 348 |
+
loss=loss,
|
| 349 |
+
logits=logits,
|
| 350 |
+
hidden_states=outputs.hidden_states,
|
| 351 |
+
attentions=outputs.attentions,
|
| 352 |
+
)
|
| 353 |
+
|
| 354 |
+
|
| 355 |
+
class CamembertForQuestionAnswering(RobertaForQuestionAnswering):
|
| 356 |
+
def __init__(self, config):
|
| 357 |
+
super().__init__(config)
|
| 358 |
+
del self.camembert
|
| 359 |
+
|
| 360 |
+
self.roberta = CamembertModel(config, add_pooling_layer=False)
|
| 361 |
+
|
| 362 |
+
@can_return_tuple
|
| 363 |
+
@auto_docstring
|
| 364 |
+
def forward(
|
| 365 |
+
self,
|
| 366 |
+
input_ids: torch.LongTensor | None = None,
|
| 367 |
+
attention_mask: torch.FloatTensor | None = None,
|
| 368 |
+
token_type_ids: torch.LongTensor | None = None,
|
| 369 |
+
position_ids: torch.LongTensor | None = None,
|
| 370 |
+
inputs_embeds: torch.FloatTensor | None = None,
|
| 371 |
+
start_positions: torch.LongTensor | None = None,
|
| 372 |
+
end_positions: torch.LongTensor | None = None,
|
| 373 |
+
**kwargs: Unpack[TransformersKwargs],
|
| 374 |
+
) -> tuple[torch.Tensor] | QuestionAnsweringModelOutput:
|
| 375 |
+
r"""
|
| 376 |
+
token_type_ids (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*):
|
| 377 |
+
Segment token indices to indicate first and second portions of the inputs. Indices are selected in `[0,1]`:
|
| 378 |
+
|
| 379 |
+
- 0 corresponds to a *sentence A* token,
|
| 380 |
+
- 1 corresponds to a *sentence B* token.
|
| 381 |
+
This parameter can only be used when the model is initialized with `type_vocab_size` parameter with value
|
| 382 |
+
>= 2. All the value in this tensor should be always < type_vocab_size.
|
| 383 |
+
|
| 384 |
+
[What are token type IDs?](../glossary#token-type-ids)
|
| 385 |
+
"""
|
| 386 |
+
outputs = self.roberta(
|
| 387 |
+
input_ids,
|
| 388 |
+
attention_mask=attention_mask,
|
| 389 |
+
token_type_ids=token_type_ids,
|
| 390 |
+
position_ids=position_ids,
|
| 391 |
+
inputs_embeds=inputs_embeds,
|
| 392 |
+
return_dict=True,
|
| 393 |
+
**kwargs,
|
| 394 |
+
)
|
| 395 |
+
|
| 396 |
+
sequence_output = outputs[0]
|
| 397 |
+
|
| 398 |
+
logits = self.qa_outputs(sequence_output)
|
| 399 |
+
start_logits, end_logits = logits.split(1, dim=-1)
|
| 400 |
+
start_logits = start_logits.squeeze(-1).contiguous()
|
| 401 |
+
end_logits = end_logits.squeeze(-1).contiguous()
|
| 402 |
+
|
| 403 |
+
total_loss = None
|
| 404 |
+
if start_positions is not None and end_positions is not None:
|
| 405 |
+
# If we are on multi-GPU, split add a dimension
|
| 406 |
+
if len(start_positions.size()) > 1:
|
| 407 |
+
start_positions = start_positions.squeeze(-1)
|
| 408 |
+
if len(end_positions.size()) > 1:
|
| 409 |
+
end_positions = end_positions.squeeze(-1)
|
| 410 |
+
# sometimes the start/end positions are outside our model inputs, we ignore these terms
|
| 411 |
+
ignored_index = start_logits.size(1)
|
| 412 |
+
start_positions = start_positions.clamp(0, ignored_index)
|
| 413 |
+
end_positions = end_positions.clamp(0, ignored_index)
|
| 414 |
+
|
| 415 |
+
loss_fct = CrossEntropyLoss(ignore_index=ignored_index)
|
| 416 |
+
start_loss = loss_fct(start_logits, start_positions)
|
| 417 |
+
end_loss = loss_fct(end_logits, end_positions)
|
| 418 |
+
total_loss = (start_loss + end_loss) / 2
|
| 419 |
+
|
| 420 |
+
return QuestionAnsweringModelOutput(
|
| 421 |
+
loss=total_loss,
|
| 422 |
+
start_logits=start_logits,
|
| 423 |
+
end_logits=end_logits,
|
| 424 |
+
hidden_states=outputs.hidden_states,
|
| 425 |
+
attentions=outputs.attentions,
|
| 426 |
+
)
|
| 427 |
+
|
| 428 |
+
|
| 429 |
+
class CamembertForCausalLM(RobertaForCausalLM):
|
| 430 |
+
_tied_weights_keys = {
|
| 431 |
+
"lm_head.decoder.weight": "roberta.embeddings.word_embeddings.weight",
|
| 432 |
+
"lm_head.decoder.bias": "lm_head.bias",
|
| 433 |
+
}
|
| 434 |
+
|
| 435 |
+
def __init__(self, config):
|
| 436 |
+
super().__init__(config)
|
| 437 |
+
del self.camembert
|
| 438 |
+
|
| 439 |
+
self.roberta = CamembertModel(config, add_pooling_layer=False)
|
| 440 |
+
|
| 441 |
+
@can_return_tuple
|
| 442 |
+
@auto_docstring
|
| 443 |
+
def forward(
|
| 444 |
+
self,
|
| 445 |
+
input_ids: torch.LongTensor | None = None,
|
| 446 |
+
attention_mask: torch.FloatTensor | None = None,
|
| 447 |
+
token_type_ids: torch.LongTensor | None = None,
|
| 448 |
+
position_ids: torch.LongTensor | None = None,
|
| 449 |
+
inputs_embeds: torch.FloatTensor | None = None,
|
| 450 |
+
encoder_hidden_states: torch.FloatTensor | None = None,
|
| 451 |
+
encoder_attention_mask: torch.FloatTensor | None = None,
|
| 452 |
+
labels: torch.LongTensor | None = None,
|
| 453 |
+
past_key_values: tuple[tuple[torch.FloatTensor]] | None = None,
|
| 454 |
+
use_cache: bool | None = None,
|
| 455 |
+
logits_to_keep: int | torch.Tensor = 0,
|
| 456 |
+
**kwargs: Unpack[TransformersKwargs],
|
| 457 |
+
) -> tuple[torch.Tensor] | CausalLMOutputWithCrossAttentions:
|
| 458 |
+
r"""
|
| 459 |
+
token_type_ids (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*):
|
| 460 |
+
Segment token indices to indicate first and second portions of the inputs. Indices are selected in `[0,1]`:
|
| 461 |
+
|
| 462 |
+
- 0 corresponds to a *sentence A* token,
|
| 463 |
+
- 1 corresponds to a *sentence B* token.
|
| 464 |
+
This parameter can only be used when the model is initialized with `type_vocab_size` parameter with value
|
| 465 |
+
>= 2. All the value in this tensor should be always < type_vocab_size.
|
| 466 |
+
|
| 467 |
+
[What are token type IDs?](../glossary#token-type-ids)
|
| 468 |
+
labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*):
|
| 469 |
+
Labels for computing the left-to-right language modeling loss (next word prediction). Indices should be in
|
| 470 |
+
`[-100, 0, ..., config.vocab_size]` (see `input_ids` docstring) Tokens with indices set to `-100` are
|
| 471 |
+
ignored (masked), the loss is only computed for the tokens with labels in `[0, ..., config.vocab_size]`
|
| 472 |
+
|
| 473 |
+
Example:
|
| 474 |
+
|
| 475 |
+
```python
|
| 476 |
+
>>> from transformers import AutoTokenizer, CamembertForCausalLM, AutoConfig
|
| 477 |
+
>>> import torch
|
| 478 |
+
|
| 479 |
+
>>> tokenizer = AutoTokenizer.from_pretrained("almanach/camembert-base")
|
| 480 |
+
>>> config = AutoConfig.from_pretrained("almanach/camembert-base")
|
| 481 |
+
>>> config.is_decoder = True
|
| 482 |
+
>>> model = CamembertForCausalLM.from_pretrained("almanach/camembert-base", config=config)
|
| 483 |
+
|
| 484 |
+
>>> inputs = tokenizer("Hello, my dog is cute", return_tensors="pt")
|
| 485 |
+
>>> outputs = model(**inputs)
|
| 486 |
+
|
| 487 |
+
>>> prediction_logits = outputs.logits
|
| 488 |
+
```"""
|
| 489 |
+
if labels is not None:
|
| 490 |
+
use_cache = False
|
| 491 |
+
|
| 492 |
+
outputs: BaseModelOutputWithPoolingAndCrossAttentions = self.roberta(
|
| 493 |
+
input_ids,
|
| 494 |
+
attention_mask=attention_mask,
|
| 495 |
+
token_type_ids=token_type_ids,
|
| 496 |
+
position_ids=position_ids,
|
| 497 |
+
inputs_embeds=inputs_embeds,
|
| 498 |
+
encoder_hidden_states=encoder_hidden_states,
|
| 499 |
+
encoder_attention_mask=encoder_attention_mask,
|
| 500 |
+
past_key_values=past_key_values,
|
| 501 |
+
use_cache=use_cache,
|
| 502 |
+
return_dict=True,
|
| 503 |
+
**kwargs,
|
| 504 |
+
)
|
| 505 |
+
|
| 506 |
+
hidden_states = outputs.last_hidden_state
|
| 507 |
+
# Only compute necessary logits, and do not upcast them to float if we are not computing the loss
|
| 508 |
+
slice_indices = slice(-logits_to_keep, None) if isinstance(logits_to_keep, int) else logits_to_keep
|
| 509 |
+
logits = self.lm_head(hidden_states[:, slice_indices, :])
|
| 510 |
+
|
| 511 |
+
loss = None
|
| 512 |
+
if labels is not None:
|
| 513 |
+
loss = self.loss_function(logits=logits, labels=labels, vocab_size=self.config.vocab_size, **kwargs)
|
| 514 |
+
|
| 515 |
+
return CausalLMOutputWithCrossAttentions(
|
| 516 |
+
loss=loss,
|
| 517 |
+
logits=logits,
|
| 518 |
+
past_key_values=outputs.past_key_values,
|
| 519 |
+
hidden_states=outputs.hidden_states,
|
| 520 |
+
attentions=outputs.attentions,
|
| 521 |
+
cross_attentions=outputs.cross_attentions,
|
| 522 |
+
)
|
| 523 |
+
|
| 524 |
+
|
| 525 |
+
__all__ = [
|
| 526 |
+
"CamembertForCausalLM",
|
| 527 |
+
"CamembertForMaskedLM",
|
| 528 |
+
"CamembertForMultipleChoice",
|
| 529 |
+
"CamembertForQuestionAnswering",
|
| 530 |
+
"CamembertForSequenceClassification",
|
| 531 |
+
"CamembertForTokenClassification",
|
| 532 |
+
"CamembertModel",
|
| 533 |
+
"CamembertPreTrainedModel",
|
| 534 |
+
]
|
third_party/transformers/src/transformers/models/camembert/tokenization_camembert.py
ADDED
|
@@ -0,0 +1,166 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright 2018 Google AI, Google Brain and Carnegie Mellon University Authors and the HuggingFace Inc. team.
|
| 2 |
+
#
|
| 3 |
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
| 4 |
+
# you may not use this file except in compliance with the License.
|
| 5 |
+
# You may obtain a copy of the License at
|
| 6 |
+
#
|
| 7 |
+
# http://www.apache.org/licenses/LICENSE-2.0
|
| 8 |
+
#
|
| 9 |
+
# Unless required by applicable law or agreed to in writing, software
|
| 10 |
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
| 11 |
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 12 |
+
# See the License for the specific language governing permissions and
|
| 13 |
+
# limitations under the License
|
| 14 |
+
"""Tokenization classes for Camembert model."""
|
| 15 |
+
|
| 16 |
+
from tokenizers import Regex, Tokenizer, decoders, normalizers, pre_tokenizers, processors
|
| 17 |
+
from tokenizers.models import Unigram
|
| 18 |
+
|
| 19 |
+
from ...tokenization_python import AddedToken
|
| 20 |
+
from ...tokenization_utils_tokenizers import TokenizersBackend
|
| 21 |
+
from ...utils import logging
|
| 22 |
+
|
| 23 |
+
|
| 24 |
+
logger = logging.get_logger(__name__)
|
| 25 |
+
|
| 26 |
+
VOCAB_FILES_NAMES = {"vocab_file": "sentencepiece.bpe.model", "tokenizer_file": "tokenizer.json"}
|
| 27 |
+
|
| 28 |
+
|
| 29 |
+
SPIECE_UNDERLINE = "▁"
|
| 30 |
+
|
| 31 |
+
|
| 32 |
+
class CamembertTokenizer(TokenizersBackend):
|
| 33 |
+
"""
|
| 34 |
+
Construct a "fast" CamemBERT tokenizer (backed by HuggingFace's *tokenizers* library). Adapted from
|
| 35 |
+
[`RobertaTokenizer`] and [`XLNetTokenizer`]. Based on
|
| 36 |
+
[Unigram](https://huggingface.co/docs/tokenizers/python/latest/components.html?highlight=unigram#models).
|
| 37 |
+
|
| 38 |
+
This tokenizer inherits from [`PreTrainedTokenizerFast`] which contains most of the main methods. Users should
|
| 39 |
+
refer to this superclass for more information regarding those methods.
|
| 40 |
+
|
| 41 |
+
Args:
|
| 42 |
+
bos_token (`str`, *optional*, defaults to `"<s>"`):
|
| 43 |
+
The beginning of sequence token that was used during pretraining. Can be used a sequence classifier token.
|
| 44 |
+
|
| 45 |
+
<Tip>
|
| 46 |
+
|
| 47 |
+
When building a sequence using special tokens, this is not the token that is used for the beginning of
|
| 48 |
+
sequence. The token used is the `cls_token`.
|
| 49 |
+
|
| 50 |
+
</Tip>
|
| 51 |
+
|
| 52 |
+
eos_token (`str`, *optional*, defaults to `"</s>"`):
|
| 53 |
+
The end of sequence token.
|
| 54 |
+
|
| 55 |
+
<Tip>
|
| 56 |
+
|
| 57 |
+
When building a sequence using special tokens, this is not the token that is used for the end of sequence.
|
| 58 |
+
The token used is the `sep_token`.
|
| 59 |
+
|
| 60 |
+
</Tip>
|
| 61 |
+
|
| 62 |
+
sep_token (`str`, *optional*, defaults to `"</s>"`):
|
| 63 |
+
The separator token, which is used when building a sequence from multiple sequences, e.g. two sequences for
|
| 64 |
+
sequence classification or for a text and a question for question answering. It is also used as the last
|
| 65 |
+
token of a sequence built with special tokens.
|
| 66 |
+
cls_token (`str`, *optional*, defaults to `"<s>"`):
|
| 67 |
+
The classifier token which is used when doing sequence classification (classification of the whole sequence
|
| 68 |
+
instead of per-token classification). It is the first token of the sequence when built with special tokens.
|
| 69 |
+
unk_token (`str`, *optional*, defaults to `"<unk>"`):
|
| 70 |
+
The unknown token. A token that is not in the vocabulary cannot be converted to an ID and is set to be this
|
| 71 |
+
token instead.
|
| 72 |
+
pad_token (`str`, *optional*, defaults to `"<pad>"`):
|
| 73 |
+
The token used for padding, for example when batching sequences of different lengths.
|
| 74 |
+
mask_token (`str`, *optional*, defaults to `"<mask>"`):
|
| 75 |
+
The token used for masking values. This is the token used when training this model with masked language
|
| 76 |
+
modeling. This is the token which the model will try to predict.
|
| 77 |
+
additional_special_tokens (`list[str]`, *optional*, defaults to `["<s>NOTUSED", "</s>NOTUSED"]`):
|
| 78 |
+
Additional special tokens used by the tokenizer.
|
| 79 |
+
add_prefix_space (`bool`, *optional*, defaults to `True`):
|
| 80 |
+
Whether or not to add an initial space to the input. This allows to treat the leading word just as any
|
| 81 |
+
other word.
|
| 82 |
+
vocab_file (`str`, *optional*):
|
| 83 |
+
[SentencePiece](https://github.com/google/sentencepiece) file (generally has a *.spm* extension) that
|
| 84 |
+
contains the vocabulary necessary to instantiate a tokenizer.
|
| 85 |
+
vocab (`str`, `dict` or `list`, *optional*):
|
| 86 |
+
Custom vocabulary dictionary. If not provided, vocabulary is loaded from vocab_file.
|
| 87 |
+
"""
|
| 88 |
+
|
| 89 |
+
vocab_files_names = VOCAB_FILES_NAMES
|
| 90 |
+
model_input_names = ["input_ids", "attention_mask"]
|
| 91 |
+
slow_tokenizer_class = None
|
| 92 |
+
|
| 93 |
+
def __init__(
|
| 94 |
+
self,
|
| 95 |
+
bos_token="<s>",
|
| 96 |
+
eos_token="</s>",
|
| 97 |
+
sep_token="</s>",
|
| 98 |
+
cls_token="<s>",
|
| 99 |
+
unk_token="<unk>",
|
| 100 |
+
pad_token="<pad>",
|
| 101 |
+
mask_token="<mask>",
|
| 102 |
+
additional_special_tokens=None,
|
| 103 |
+
add_prefix_space=True,
|
| 104 |
+
vocab_file=None,
|
| 105 |
+
vocab: str | dict | list | None = None,
|
| 106 |
+
**kwargs,
|
| 107 |
+
):
|
| 108 |
+
self.vocab_file = vocab_file
|
| 109 |
+
self.add_prefix_space = add_prefix_space
|
| 110 |
+
|
| 111 |
+
mask_token = AddedToken(mask_token, lstrip=True, special=True) if isinstance(mask_token, str) else mask_token
|
| 112 |
+
|
| 113 |
+
if additional_special_tokens is None:
|
| 114 |
+
additional_special_tokens = ["<s>NOTUSED", "</s>NOTUSED", "<unk>NOTUSED"]
|
| 115 |
+
|
| 116 |
+
if vocab is not None:
|
| 117 |
+
self._vocab = vocab
|
| 118 |
+
unk_index = next((i for i, (tok, _) in enumerate(self._vocab) if tok == str(unk_token)), 0)
|
| 119 |
+
self._tokenizer = Tokenizer(Unigram(self._vocab, unk_id=unk_index, byte_fallback=False))
|
| 120 |
+
else:
|
| 121 |
+
self._vocab = [
|
| 122 |
+
("<s>NOTUSED", 0.0),
|
| 123 |
+
(str(pad_token), 0.0),
|
| 124 |
+
("</s>NOTUSED", 0.0),
|
| 125 |
+
(str(unk_token), 0.0),
|
| 126 |
+
("<unk>NOTUSED", -100),
|
| 127 |
+
(str(mask_token), 0.0),
|
| 128 |
+
]
|
| 129 |
+
self._tokenizer = Tokenizer(Unigram(self._vocab, unk_id=3, byte_fallback=False))
|
| 130 |
+
|
| 131 |
+
self._tokenizer.normalizer = normalizers.Sequence(
|
| 132 |
+
[
|
| 133 |
+
normalizers.Replace(Regex(r"\s{2,}|[\n\r\t]"), " "),
|
| 134 |
+
normalizers.Strip(left=False, right=True),
|
| 135 |
+
]
|
| 136 |
+
)
|
| 137 |
+
|
| 138 |
+
prepend_scheme = "always" if add_prefix_space else "never"
|
| 139 |
+
self._tokenizer.pre_tokenizer = pre_tokenizers.Metaspace(replacement="▁", prepend_scheme=prepend_scheme)
|
| 140 |
+
self._tokenizer.decoder = decoders.Metaspace(replacement="▁", prepend_scheme=prepend_scheme)
|
| 141 |
+
|
| 142 |
+
super().__init__(
|
| 143 |
+
bos_token=bos_token,
|
| 144 |
+
eos_token=eos_token,
|
| 145 |
+
sep_token=sep_token,
|
| 146 |
+
cls_token=cls_token,
|
| 147 |
+
unk_token=unk_token,
|
| 148 |
+
pad_token=pad_token,
|
| 149 |
+
mask_token=mask_token,
|
| 150 |
+
additional_special_tokens=additional_special_tokens,
|
| 151 |
+
add_prefix_space=add_prefix_space,
|
| 152 |
+
**kwargs,
|
| 153 |
+
)
|
| 154 |
+
|
| 155 |
+
# always adds BOS/EOS with "</s> </s>" separator for pairs
|
| 156 |
+
self._tokenizer.post_processor = processors.TemplateProcessing(
|
| 157 |
+
single=f"{self.bos_token} $A {self.eos_token}",
|
| 158 |
+
pair=f"{self.bos_token} $A {self.eos_token} {self.eos_token} $B {self.eos_token}",
|
| 159 |
+
special_tokens=[
|
| 160 |
+
(self.bos_token, self.bos_token_id),
|
| 161 |
+
(self.eos_token, self.eos_token_id),
|
| 162 |
+
],
|
| 163 |
+
)
|
| 164 |
+
|
| 165 |
+
|
| 166 |
+
__all__ = ["CamembertTokenizer"]
|
third_party/transformers/src/transformers/models/canine/__init__.py
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright 2024 The HuggingFace Team. All rights reserved.
|
| 2 |
+
#
|
| 3 |
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
| 4 |
+
# you may not use this file except in compliance with the License.
|
| 5 |
+
# You may obtain a copy of the License at
|
| 6 |
+
#
|
| 7 |
+
# http://www.apache.org/licenses/LICENSE-2.0
|
| 8 |
+
#
|
| 9 |
+
# Unless required by applicable law or agreed to in writing, software
|
| 10 |
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
| 11 |
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 12 |
+
# See the License for the specific language governing permissions and
|
| 13 |
+
# limitations under the License.
|
| 14 |
+
from typing import TYPE_CHECKING
|
| 15 |
+
|
| 16 |
+
from ...utils import _LazyModule
|
| 17 |
+
from ...utils.import_utils import define_import_structure
|
| 18 |
+
|
| 19 |
+
|
| 20 |
+
if TYPE_CHECKING:
|
| 21 |
+
from .configuration_canine import *
|
| 22 |
+
from .modeling_canine import *
|
| 23 |
+
from .tokenization_canine import *
|
| 24 |
+
else:
|
| 25 |
+
import sys
|
| 26 |
+
|
| 27 |
+
_file = globals()["__file__"]
|
| 28 |
+
sys.modules[__name__] = _LazyModule(__name__, _file, define_import_structure(_file), module_spec=__spec__)
|
third_party/transformers/src/transformers/models/canine/configuration_canine.py
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright Google AI and The HuggingFace Inc. team. All rights reserved.
|
| 2 |
+
#
|
| 3 |
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
| 4 |
+
# you may not use this file except in compliance with the License.
|
| 5 |
+
# You may obtain a copy of the License at
|
| 6 |
+
#
|
| 7 |
+
# http://www.apache.org/licenses/LICENSE-2.0
|
| 8 |
+
#
|
| 9 |
+
# Unless required by applicable law or agreed to in writing, software
|
| 10 |
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
| 11 |
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 12 |
+
# See the License for the specific language governing permissions and
|
| 13 |
+
# limitations under the License.
|
| 14 |
+
"""CANINE model configuration"""
|
| 15 |
+
|
| 16 |
+
from huggingface_hub.dataclasses import strict
|
| 17 |
+
|
| 18 |
+
from ...configuration_utils import PreTrainedConfig
|
| 19 |
+
from ...utils import auto_docstring
|
| 20 |
+
|
| 21 |
+
|
| 22 |
+
@auto_docstring(checkpoint="google/canine-s")
|
| 23 |
+
@strict
|
| 24 |
+
class CanineConfig(PreTrainedConfig):
|
| 25 |
+
r"""
|
| 26 |
+
downsampling_rate (`int`, *optional*, defaults to 4):
|
| 27 |
+
The rate at which to downsample the original character sequence length before applying the deep Transformer
|
| 28 |
+
encoder.
|
| 29 |
+
upsampling_kernel_size (`int`, *optional*, defaults to 4):
|
| 30 |
+
The kernel size (i.e. the number of characters in each window) of the convolutional projection layer when
|
| 31 |
+
projecting back from `hidden_size`*2 to `hidden_size`.
|
| 32 |
+
num_hash_functions (`int`, *optional*, defaults to 8):
|
| 33 |
+
The number of hash functions to use. Each hash function has its own embedding matrix.
|
| 34 |
+
num_hash_buckets (`int`, *optional*, defaults to 16384):
|
| 35 |
+
The number of hash buckets to use.
|
| 36 |
+
local_transformer_stride (`int`, *optional*, defaults to 128):
|
| 37 |
+
The stride of the local attention of the first shallow Transformer encoder. Defaults to 128 for good
|
| 38 |
+
TPU/XLA memory alignment.
|
| 39 |
+
|
| 40 |
+
Example:
|
| 41 |
+
|
| 42 |
+
```python
|
| 43 |
+
>>> from transformers import CanineConfig, CanineModel
|
| 44 |
+
|
| 45 |
+
>>> # Initializing a CANINE google/canine-s style configuration
|
| 46 |
+
>>> configuration = CanineConfig()
|
| 47 |
+
|
| 48 |
+
>>> # Initializing a model (with random weights) from the google/canine-s style configuration
|
| 49 |
+
>>> model = CanineModel(configuration)
|
| 50 |
+
|
| 51 |
+
>>> # Accessing the model configuration
|
| 52 |
+
>>> configuration = model.config
|
| 53 |
+
```"""
|
| 54 |
+
|
| 55 |
+
model_type = "canine"
|
| 56 |
+
|
| 57 |
+
hidden_size: int = 768
|
| 58 |
+
num_hidden_layers: int = 12
|
| 59 |
+
num_attention_heads: int = 12
|
| 60 |
+
intermediate_size: int = 3072
|
| 61 |
+
hidden_act: str = "gelu"
|
| 62 |
+
hidden_dropout_prob: float | int = 0.1
|
| 63 |
+
attention_probs_dropout_prob: float | int = 0.1
|
| 64 |
+
max_position_embeddings: int = 16384
|
| 65 |
+
type_vocab_size: int = 16
|
| 66 |
+
initializer_range: float = 0.02
|
| 67 |
+
layer_norm_eps: float = 1e-12
|
| 68 |
+
pad_token_id: int | None = 0
|
| 69 |
+
bos_token_id: int | None = 0xE000
|
| 70 |
+
eos_token_id: int | list[int] | None = 0xE001
|
| 71 |
+
downsampling_rate: int = 4
|
| 72 |
+
upsampling_kernel_size: int = 4
|
| 73 |
+
num_hash_functions: int = 8
|
| 74 |
+
num_hash_buckets: int = 16384
|
| 75 |
+
local_transformer_stride: int = 128 # Good TPU/XLA memory alignment
|
| 76 |
+
|
| 77 |
+
|
| 78 |
+
__all__ = ["CanineConfig"]
|
third_party/transformers/src/transformers/models/canine/convert_canine_original_tf_checkpoint_to_pytorch.py
ADDED
|
@@ -0,0 +1,165 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright 2021 The HuggingFace Inc. team.
|
| 2 |
+
#
|
| 3 |
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
| 4 |
+
# you may not use this file except in compliance with the License.
|
| 5 |
+
# You may obtain a copy of the License at
|
| 6 |
+
#
|
| 7 |
+
# http://www.apache.org/licenses/LICENSE-2.0
|
| 8 |
+
#
|
| 9 |
+
# Unless required by applicable law or agreed to in writing, software
|
| 10 |
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
| 11 |
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 12 |
+
# See the License for the specific language governing permissions and
|
| 13 |
+
# limitations under the License.
|
| 14 |
+
"""Convert CANINE checkpoint."""
|
| 15 |
+
|
| 16 |
+
import argparse
|
| 17 |
+
import os
|
| 18 |
+
|
| 19 |
+
import torch
|
| 20 |
+
|
| 21 |
+
from transformers import CanineConfig, CanineModel, CanineTokenizer
|
| 22 |
+
from transformers.utils import logging
|
| 23 |
+
|
| 24 |
+
|
| 25 |
+
logger = logging.get_logger(__name__)
|
| 26 |
+
logging.set_verbosity_info()
|
| 27 |
+
|
| 28 |
+
|
| 29 |
+
def load_tf_weights_in_canine(model, config, tf_checkpoint_path):
|
| 30 |
+
"""Load tf checkpoints in a pytorch model."""
|
| 31 |
+
try:
|
| 32 |
+
import re
|
| 33 |
+
|
| 34 |
+
import numpy as np
|
| 35 |
+
import tensorflow as tf
|
| 36 |
+
except ImportError:
|
| 37 |
+
logger.error(
|
| 38 |
+
"Loading a TensorFlow model in PyTorch, requires TensorFlow to be installed. Please see "
|
| 39 |
+
"https://www.tensorflow.org/install/ for installation instructions."
|
| 40 |
+
)
|
| 41 |
+
raise
|
| 42 |
+
tf_path = os.path.abspath(tf_checkpoint_path)
|
| 43 |
+
logger.info(f"Converting TensorFlow checkpoint from {tf_path}")
|
| 44 |
+
# Load weights from TF model
|
| 45 |
+
init_vars = tf.train.list_variables(tf_path)
|
| 46 |
+
names = []
|
| 47 |
+
arrays = []
|
| 48 |
+
for name, shape in init_vars:
|
| 49 |
+
logger.info(f"Loading TF weight {name} with shape {shape}")
|
| 50 |
+
array = tf.train.load_variable(tf_path, name)
|
| 51 |
+
names.append(name)
|
| 52 |
+
arrays.append(array)
|
| 53 |
+
|
| 54 |
+
for name, array in zip(names, arrays):
|
| 55 |
+
name = name.split("/")
|
| 56 |
+
# adam_v and adam_m are variables used in AdamWeightDecayOptimizer to calculated m and v
|
| 57 |
+
# which are not required for using pretrained model
|
| 58 |
+
# also discard the cls weights (which were used for the next sentence prediction pre-training task)
|
| 59 |
+
if any(
|
| 60 |
+
n
|
| 61 |
+
in [
|
| 62 |
+
"adam_v",
|
| 63 |
+
"adam_m",
|
| 64 |
+
"AdamWeightDecayOptimizer",
|
| 65 |
+
"AdamWeightDecayOptimizer_1",
|
| 66 |
+
"global_step",
|
| 67 |
+
"cls",
|
| 68 |
+
"autoregressive_decoder",
|
| 69 |
+
"char_output_weights",
|
| 70 |
+
]
|
| 71 |
+
for n in name
|
| 72 |
+
):
|
| 73 |
+
logger.info(f"Skipping {'/'.join(name)}")
|
| 74 |
+
continue
|
| 75 |
+
# if first scope name starts with "bert", change it to "encoder"
|
| 76 |
+
if name[0] == "bert":
|
| 77 |
+
name[0] = "encoder"
|
| 78 |
+
# remove "embeddings" middle name of HashBucketCodepointEmbedders
|
| 79 |
+
elif name[1] == "embeddings":
|
| 80 |
+
name.remove(name[1])
|
| 81 |
+
# rename segment_embeddings to token_type_embeddings
|
| 82 |
+
elif name[1] == "segment_embeddings":
|
| 83 |
+
name[1] = "token_type_embeddings"
|
| 84 |
+
# rename initial convolutional projection layer
|
| 85 |
+
elif name[1] == "initial_char_encoder":
|
| 86 |
+
name = ["chars_to_molecules"] + name[-2:]
|
| 87 |
+
# rename final convolutional projection layer
|
| 88 |
+
elif name[0] == "final_char_encoder" and name[1] in ["LayerNorm", "conv"]:
|
| 89 |
+
name = ["projection"] + name[1:]
|
| 90 |
+
pointer = model
|
| 91 |
+
for m_name in name:
|
| 92 |
+
if (re.fullmatch(r"[A-Za-z]+_\d+", m_name)) and "Embedder" not in m_name:
|
| 93 |
+
scope_names = re.split(r"_(\d+)", m_name)
|
| 94 |
+
else:
|
| 95 |
+
scope_names = [m_name]
|
| 96 |
+
if scope_names[0] == "kernel" or scope_names[0] == "gamma":
|
| 97 |
+
pointer = getattr(pointer, "weight")
|
| 98 |
+
elif scope_names[0] == "output_bias" or scope_names[0] == "beta":
|
| 99 |
+
pointer = getattr(pointer, "bias")
|
| 100 |
+
elif scope_names[0] == "output_weights":
|
| 101 |
+
pointer = getattr(pointer, "weight")
|
| 102 |
+
else:
|
| 103 |
+
try:
|
| 104 |
+
pointer = getattr(pointer, scope_names[0])
|
| 105 |
+
except AttributeError:
|
| 106 |
+
logger.info(f"Skipping {'/'.join(name)}")
|
| 107 |
+
continue
|
| 108 |
+
if len(scope_names) >= 2:
|
| 109 |
+
num = int(scope_names[1])
|
| 110 |
+
pointer = pointer[num]
|
| 111 |
+
if m_name[-11:] == "_embeddings":
|
| 112 |
+
pointer = getattr(pointer, "weight")
|
| 113 |
+
elif m_name[-10:] in [f"Embedder_{i}" for i in range(8)]:
|
| 114 |
+
pointer = getattr(pointer, "weight")
|
| 115 |
+
elif m_name == "kernel":
|
| 116 |
+
array = np.transpose(array)
|
| 117 |
+
|
| 118 |
+
if pointer.shape != array.shape:
|
| 119 |
+
raise ValueError(f"Pointer shape {pointer.shape} and array shape {array.shape} mismatched")
|
| 120 |
+
|
| 121 |
+
logger.info(f"Initialize PyTorch weight {name}")
|
| 122 |
+
pointer.data = torch.from_numpy(array)
|
| 123 |
+
return model
|
| 124 |
+
|
| 125 |
+
|
| 126 |
+
def convert_tf_checkpoint_to_pytorch(tf_checkpoint_path, pytorch_dump_path):
|
| 127 |
+
# Initialize PyTorch model
|
| 128 |
+
config = CanineConfig()
|
| 129 |
+
model = CanineModel(config)
|
| 130 |
+
model.eval()
|
| 131 |
+
|
| 132 |
+
print(f"Building PyTorch model from configuration: {config}")
|
| 133 |
+
|
| 134 |
+
# Load weights from tf checkpoint
|
| 135 |
+
load_tf_weights_in_canine(model, config, tf_checkpoint_path)
|
| 136 |
+
|
| 137 |
+
# Save pytorch-model (weights and configuration)
|
| 138 |
+
print(f"Save PyTorch model to {pytorch_dump_path}")
|
| 139 |
+
model.save_pretrained(pytorch_dump_path)
|
| 140 |
+
|
| 141 |
+
# Save tokenizer files
|
| 142 |
+
tokenizer = CanineTokenizer()
|
| 143 |
+
print(f"Save tokenizer files to {pytorch_dump_path}")
|
| 144 |
+
tokenizer.save_pretrained(pytorch_dump_path)
|
| 145 |
+
|
| 146 |
+
|
| 147 |
+
if __name__ == "__main__":
|
| 148 |
+
parser = argparse.ArgumentParser()
|
| 149 |
+
# Required parameters
|
| 150 |
+
parser.add_argument(
|
| 151 |
+
"--tf_checkpoint_path",
|
| 152 |
+
default=None,
|
| 153 |
+
type=str,
|
| 154 |
+
required=True,
|
| 155 |
+
help="Path to the TensorFlow checkpoint. Should end with model.ckpt",
|
| 156 |
+
)
|
| 157 |
+
parser.add_argument(
|
| 158 |
+
"--pytorch_dump_path",
|
| 159 |
+
default=None,
|
| 160 |
+
type=str,
|
| 161 |
+
required=True,
|
| 162 |
+
help="Path to a folder where the PyTorch model will be placed.",
|
| 163 |
+
)
|
| 164 |
+
args = parser.parse_args()
|
| 165 |
+
convert_tf_checkpoint_to_pytorch(args.tf_checkpoint_path, args.pytorch_dump_path)
|
third_party/transformers/src/transformers/models/canine/modeling_canine.py
ADDED
|
@@ -0,0 +1,1358 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright 2021 Google AI The HuggingFace Inc. team. All rights reserved.
|
| 2 |
+
#
|
| 3 |
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
| 4 |
+
# you may not use this file except in compliance with the License.
|
| 5 |
+
# You may obtain a copy of the License at
|
| 6 |
+
#
|
| 7 |
+
# http://www.apache.org/licenses/LICENSE-2.0
|
| 8 |
+
#
|
| 9 |
+
# Unless required by applicable law or agreed to in writing, software
|
| 10 |
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
| 11 |
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 12 |
+
# See the License for the specific language governing permissions and
|
| 13 |
+
# limitations under the License.
|
| 14 |
+
"""PyTorch CANINE model."""
|
| 15 |
+
|
| 16 |
+
import copy
|
| 17 |
+
import math
|
| 18 |
+
from dataclasses import dataclass
|
| 19 |
+
|
| 20 |
+
import torch
|
| 21 |
+
from torch import nn
|
| 22 |
+
from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss
|
| 23 |
+
|
| 24 |
+
from ... import initialization as init
|
| 25 |
+
from ...activations import ACT2FN
|
| 26 |
+
from ...modeling_layers import GradientCheckpointingLayer
|
| 27 |
+
from ...modeling_outputs import (
|
| 28 |
+
BaseModelOutput,
|
| 29 |
+
ModelOutput,
|
| 30 |
+
MultipleChoiceModelOutput,
|
| 31 |
+
QuestionAnsweringModelOutput,
|
| 32 |
+
SequenceClassifierOutput,
|
| 33 |
+
TokenClassifierOutput,
|
| 34 |
+
)
|
| 35 |
+
from ...modeling_utils import PreTrainedModel
|
| 36 |
+
from ...pytorch_utils import apply_chunking_to_forward
|
| 37 |
+
from ...utils import auto_docstring, logging
|
| 38 |
+
from .configuration_canine import CanineConfig
|
| 39 |
+
|
| 40 |
+
|
| 41 |
+
logger = logging.get_logger(__name__)
|
| 42 |
+
|
| 43 |
+
|
| 44 |
+
# Support up to 16 hash functions.
|
| 45 |
+
_PRIMES = [31, 43, 59, 61, 73, 97, 103, 113, 137, 149, 157, 173, 181, 193, 211, 223]
|
| 46 |
+
|
| 47 |
+
|
| 48 |
+
@dataclass
|
| 49 |
+
@auto_docstring(
|
| 50 |
+
custom_intro="""
|
| 51 |
+
Output type of [`CanineModel`]. Based on [`~modeling_outputs.BaseModelOutputWithPooling`], but with slightly
|
| 52 |
+
different `hidden_states` and `attentions`, as these also include the hidden states and attentions of the shallow
|
| 53 |
+
Transformer encoders.
|
| 54 |
+
"""
|
| 55 |
+
)
|
| 56 |
+
class CanineModelOutputWithPooling(ModelOutput):
|
| 57 |
+
r"""
|
| 58 |
+
last_hidden_state (`torch.FloatTensor` of shape `(batch_size, sequence_length, hidden_size)`):
|
| 59 |
+
Sequence of hidden-states at the output of the last layer of the model (i.e. the output of the final
|
| 60 |
+
shallow Transformer encoder).
|
| 61 |
+
pooler_output (`torch.FloatTensor` of shape `(batch_size, hidden_size)`):
|
| 62 |
+
Hidden-state of the first token of the sequence (classification token) at the last layer of the deep
|
| 63 |
+
Transformer encoder, further processed by a Linear layer and a Tanh activation function. The Linear layer
|
| 64 |
+
weights are trained from the next sentence prediction (classification) objective during pretraining.
|
| 65 |
+
hidden_states (`tuple(torch.FloatTensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`):
|
| 66 |
+
Tuple of `torch.FloatTensor` (one for the input to each encoder + one for the output of each layer of each
|
| 67 |
+
encoder) of shape `(batch_size, sequence_length, hidden_size)` and `(batch_size, sequence_length //
|
| 68 |
+
config.downsampling_rate, hidden_size)`. Hidden-states of the model at the output of each layer plus the
|
| 69 |
+
initial input to each Transformer encoder. The hidden states of the shallow encoders have length
|
| 70 |
+
`sequence_length`, but the hidden states of the deep encoder have length `sequence_length` //
|
| 71 |
+
`config.downsampling_rate`.
|
| 72 |
+
attentions (`tuple(torch.FloatTensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`):
|
| 73 |
+
Tuple of `torch.FloatTensor` (one for each layer) of the 3 Transformer encoders of shape `(batch_size,
|
| 74 |
+
num_heads, sequence_length, sequence_length)` and `(batch_size, num_heads, sequence_length //
|
| 75 |
+
config.downsampling_rate, sequence_length // config.downsampling_rate)`. Attentions weights after the
|
| 76 |
+
attention softmax, used to compute the weighted average in the self-attention heads.
|
| 77 |
+
"""
|
| 78 |
+
|
| 79 |
+
last_hidden_state: torch.FloatTensor | None = None
|
| 80 |
+
pooler_output: torch.FloatTensor | None = None
|
| 81 |
+
hidden_states: tuple[torch.FloatTensor] | None = None
|
| 82 |
+
attentions: tuple[torch.FloatTensor] | None = None
|
| 83 |
+
|
| 84 |
+
|
| 85 |
+
class CanineEmbeddings(nn.Module):
|
| 86 |
+
"""Construct the character, position and token_type embeddings."""
|
| 87 |
+
|
| 88 |
+
def __init__(self, config):
|
| 89 |
+
super().__init__()
|
| 90 |
+
|
| 91 |
+
self.config = config
|
| 92 |
+
|
| 93 |
+
# character embeddings
|
| 94 |
+
shard_embedding_size = config.hidden_size // config.num_hash_functions
|
| 95 |
+
for i in range(config.num_hash_functions):
|
| 96 |
+
name = f"HashBucketCodepointEmbedder_{i}"
|
| 97 |
+
setattr(self, name, nn.Embedding(config.num_hash_buckets, shard_embedding_size))
|
| 98 |
+
self.char_position_embeddings = nn.Embedding(config.num_hash_buckets, config.hidden_size)
|
| 99 |
+
self.token_type_embeddings = nn.Embedding(config.type_vocab_size, config.hidden_size)
|
| 100 |
+
|
| 101 |
+
self.LayerNorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps)
|
| 102 |
+
self.dropout = nn.Dropout(config.hidden_dropout_prob)
|
| 103 |
+
|
| 104 |
+
# position_ids (1, len position emb) is contiguous in memory and exported when serialized
|
| 105 |
+
self.register_buffer(
|
| 106 |
+
"position_ids", torch.arange(config.max_position_embeddings).expand((1, -1)), persistent=False
|
| 107 |
+
)
|
| 108 |
+
|
| 109 |
+
def _hash_bucket_tensors(self, input_ids, num_hashes: int, num_buckets: int):
|
| 110 |
+
"""
|
| 111 |
+
Converts ids to hash bucket ids via multiple hashing.
|
| 112 |
+
|
| 113 |
+
Args:
|
| 114 |
+
input_ids: The codepoints or other IDs to be hashed.
|
| 115 |
+
num_hashes: The number of hash functions to use.
|
| 116 |
+
num_buckets: The number of hash buckets (i.e. embeddings in each table).
|
| 117 |
+
|
| 118 |
+
Returns:
|
| 119 |
+
A list of tensors, each of which is the hash bucket IDs from one hash function.
|
| 120 |
+
"""
|
| 121 |
+
if num_hashes > len(_PRIMES):
|
| 122 |
+
raise ValueError(f"`num_hashes` must be <= {len(_PRIMES)}")
|
| 123 |
+
|
| 124 |
+
primes = _PRIMES[:num_hashes]
|
| 125 |
+
|
| 126 |
+
result_tensors = []
|
| 127 |
+
for prime in primes:
|
| 128 |
+
hashed = ((input_ids + 1) * prime) % num_buckets
|
| 129 |
+
result_tensors.append(hashed)
|
| 130 |
+
return result_tensors
|
| 131 |
+
|
| 132 |
+
def _embed_hash_buckets(self, input_ids, embedding_size: int, num_hashes: int, num_buckets: int):
|
| 133 |
+
"""Converts IDs (e.g. codepoints) into embeddings via multiple hashing."""
|
| 134 |
+
if embedding_size % num_hashes != 0:
|
| 135 |
+
raise ValueError(f"Expected `embedding_size` ({embedding_size}) % `num_hashes` ({num_hashes}) == 0")
|
| 136 |
+
|
| 137 |
+
hash_bucket_tensors = self._hash_bucket_tensors(input_ids, num_hashes=num_hashes, num_buckets=num_buckets)
|
| 138 |
+
embedding_shards = []
|
| 139 |
+
for i, hash_bucket_ids in enumerate(hash_bucket_tensors):
|
| 140 |
+
name = f"HashBucketCodepointEmbedder_{i}"
|
| 141 |
+
shard_embeddings = getattr(self, name)(hash_bucket_ids)
|
| 142 |
+
embedding_shards.append(shard_embeddings)
|
| 143 |
+
|
| 144 |
+
return torch.cat(embedding_shards, dim=-1)
|
| 145 |
+
|
| 146 |
+
def forward(
|
| 147 |
+
self,
|
| 148 |
+
input_ids: torch.LongTensor | None = None,
|
| 149 |
+
token_type_ids: torch.LongTensor | None = None,
|
| 150 |
+
position_ids: torch.LongTensor | None = None,
|
| 151 |
+
inputs_embeds: torch.FloatTensor | None = None,
|
| 152 |
+
) -> torch.FloatTensor:
|
| 153 |
+
if input_ids is not None:
|
| 154 |
+
input_shape = input_ids.size()
|
| 155 |
+
else:
|
| 156 |
+
input_shape = inputs_embeds.size()[:-1]
|
| 157 |
+
|
| 158 |
+
seq_length = input_shape[1]
|
| 159 |
+
|
| 160 |
+
if position_ids is None:
|
| 161 |
+
position_ids = self.position_ids[:, :seq_length]
|
| 162 |
+
|
| 163 |
+
if token_type_ids is None:
|
| 164 |
+
token_type_ids = torch.zeros(input_shape, dtype=torch.long, device=self.position_ids.device)
|
| 165 |
+
|
| 166 |
+
if inputs_embeds is None:
|
| 167 |
+
inputs_embeds = self._embed_hash_buckets(
|
| 168 |
+
input_ids, self.config.hidden_size, self.config.num_hash_functions, self.config.num_hash_buckets
|
| 169 |
+
)
|
| 170 |
+
|
| 171 |
+
token_type_embeddings = self.token_type_embeddings(token_type_ids)
|
| 172 |
+
embeddings = inputs_embeds + token_type_embeddings
|
| 173 |
+
|
| 174 |
+
position_embeddings = self.char_position_embeddings(position_ids)
|
| 175 |
+
embeddings += position_embeddings
|
| 176 |
+
|
| 177 |
+
embeddings = self.LayerNorm(embeddings)
|
| 178 |
+
embeddings = self.dropout(embeddings)
|
| 179 |
+
return embeddings
|
| 180 |
+
|
| 181 |
+
|
| 182 |
+
class CharactersToMolecules(nn.Module):
|
| 183 |
+
"""Convert character sequence to initial molecule sequence (i.e. downsample) using strided convolutions."""
|
| 184 |
+
|
| 185 |
+
def __init__(self, config):
|
| 186 |
+
super().__init__()
|
| 187 |
+
|
| 188 |
+
self.conv = nn.Conv1d(
|
| 189 |
+
in_channels=config.hidden_size,
|
| 190 |
+
out_channels=config.hidden_size,
|
| 191 |
+
kernel_size=config.downsampling_rate,
|
| 192 |
+
stride=config.downsampling_rate,
|
| 193 |
+
)
|
| 194 |
+
self.activation = ACT2FN[config.hidden_act]
|
| 195 |
+
|
| 196 |
+
self.LayerNorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps)
|
| 197 |
+
|
| 198 |
+
def forward(self, char_encoding: torch.Tensor) -> torch.Tensor:
|
| 199 |
+
# `cls_encoding`: [batch, 1, hidden_size]
|
| 200 |
+
cls_encoding = char_encoding[:, 0:1, :]
|
| 201 |
+
|
| 202 |
+
# char_encoding has shape [batch, char_seq, hidden_size]
|
| 203 |
+
# We transpose it to be [batch, hidden_size, char_seq]
|
| 204 |
+
char_encoding = torch.transpose(char_encoding, 1, 2)
|
| 205 |
+
downsampled = self.conv(char_encoding)
|
| 206 |
+
downsampled = torch.transpose(downsampled, 1, 2)
|
| 207 |
+
downsampled = self.activation(downsampled)
|
| 208 |
+
|
| 209 |
+
# Truncate the last molecule in order to reserve a position for [CLS].
|
| 210 |
+
# Often, the last position is never used (unless we completely fill the
|
| 211 |
+
# text buffer). This is important in order to maintain alignment on TPUs
|
| 212 |
+
# (i.e. a multiple of 128).
|
| 213 |
+
downsampled_truncated = downsampled[:, 0:-1, :]
|
| 214 |
+
|
| 215 |
+
# We also keep [CLS] as a separate sequence position since we always
|
| 216 |
+
# want to reserve a position (and the model capacity that goes along
|
| 217 |
+
# with that) in the deep BERT stack.
|
| 218 |
+
# `result`: [batch, molecule_seq, molecule_dim]
|
| 219 |
+
result = torch.cat([cls_encoding, downsampled_truncated], dim=1)
|
| 220 |
+
|
| 221 |
+
result = self.LayerNorm(result)
|
| 222 |
+
|
| 223 |
+
return result
|
| 224 |
+
|
| 225 |
+
|
| 226 |
+
class ConvProjection(nn.Module):
|
| 227 |
+
"""
|
| 228 |
+
Project representations from hidden_size*2 back to hidden_size across a window of w = config.upsampling_kernel_size
|
| 229 |
+
characters.
|
| 230 |
+
"""
|
| 231 |
+
|
| 232 |
+
def __init__(self, config):
|
| 233 |
+
super().__init__()
|
| 234 |
+
self.config = config
|
| 235 |
+
self.conv = nn.Conv1d(
|
| 236 |
+
in_channels=config.hidden_size * 2,
|
| 237 |
+
out_channels=config.hidden_size,
|
| 238 |
+
kernel_size=config.upsampling_kernel_size,
|
| 239 |
+
stride=1,
|
| 240 |
+
)
|
| 241 |
+
self.activation = ACT2FN[config.hidden_act]
|
| 242 |
+
self.LayerNorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps)
|
| 243 |
+
self.dropout = nn.Dropout(config.hidden_dropout_prob)
|
| 244 |
+
|
| 245 |
+
def forward(
|
| 246 |
+
self,
|
| 247 |
+
inputs: torch.Tensor,
|
| 248 |
+
final_seq_char_positions: torch.Tensor | None = None,
|
| 249 |
+
) -> torch.Tensor:
|
| 250 |
+
# inputs has shape [batch, mol_seq, molecule_hidden_size+char_hidden_final]
|
| 251 |
+
# we transpose it to be [batch, molecule_hidden_size+char_hidden_final, mol_seq]
|
| 252 |
+
inputs = torch.transpose(inputs, 1, 2)
|
| 253 |
+
|
| 254 |
+
# PyTorch < 1.9 does not support padding="same" (which is used in the original implementation),
|
| 255 |
+
# so we pad the tensor manually before passing it to the conv layer
|
| 256 |
+
# based on https://github.com/google-research/big_transfer/blob/49afe42338b62af9fbe18f0258197a33ee578a6b/bit_tf2/models.py#L36-L38
|
| 257 |
+
pad_total = self.config.upsampling_kernel_size - 1
|
| 258 |
+
pad_beg = pad_total // 2
|
| 259 |
+
pad_end = pad_total - pad_beg
|
| 260 |
+
|
| 261 |
+
pad = nn.ConstantPad1d((pad_beg, pad_end), 0)
|
| 262 |
+
# `result`: shape (batch_size, char_seq_len, hidden_size)
|
| 263 |
+
result = self.conv(pad(inputs))
|
| 264 |
+
result = torch.transpose(result, 1, 2)
|
| 265 |
+
result = self.activation(result)
|
| 266 |
+
result = self.LayerNorm(result)
|
| 267 |
+
result = self.dropout(result)
|
| 268 |
+
final_char_seq = result
|
| 269 |
+
|
| 270 |
+
if final_seq_char_positions is not None:
|
| 271 |
+
# Limit transformer query seq and attention mask to these character
|
| 272 |
+
# positions to greatly reduce the compute cost. Typically, this is just
|
| 273 |
+
# done for the MLM training task.
|
| 274 |
+
# TODO add support for MLM
|
| 275 |
+
raise NotImplementedError("CanineForMaskedLM is currently not supported")
|
| 276 |
+
else:
|
| 277 |
+
query_seq = final_char_seq
|
| 278 |
+
|
| 279 |
+
return query_seq
|
| 280 |
+
|
| 281 |
+
|
| 282 |
+
class CanineSelfAttention(nn.Module):
|
| 283 |
+
def __init__(self, config):
|
| 284 |
+
super().__init__()
|
| 285 |
+
if config.hidden_size % config.num_attention_heads != 0 and not hasattr(config, "embedding_size"):
|
| 286 |
+
raise ValueError(
|
| 287 |
+
f"The hidden size ({config.hidden_size}) is not a multiple of the number of attention "
|
| 288 |
+
f"heads ({config.num_attention_heads})"
|
| 289 |
+
)
|
| 290 |
+
|
| 291 |
+
self.num_attention_heads = config.num_attention_heads
|
| 292 |
+
self.attention_head_size = int(config.hidden_size / config.num_attention_heads)
|
| 293 |
+
self.all_head_size = self.num_attention_heads * self.attention_head_size
|
| 294 |
+
|
| 295 |
+
self.query = nn.Linear(config.hidden_size, self.all_head_size)
|
| 296 |
+
self.key = nn.Linear(config.hidden_size, self.all_head_size)
|
| 297 |
+
self.value = nn.Linear(config.hidden_size, self.all_head_size)
|
| 298 |
+
|
| 299 |
+
self.dropout = nn.Dropout(config.attention_probs_dropout_prob)
|
| 300 |
+
|
| 301 |
+
def forward(
|
| 302 |
+
self,
|
| 303 |
+
from_tensor: torch.Tensor,
|
| 304 |
+
to_tensor: torch.Tensor,
|
| 305 |
+
attention_mask: torch.FloatTensor | None = None,
|
| 306 |
+
output_attentions: bool | None = False,
|
| 307 |
+
) -> tuple[torch.Tensor, torch.Tensor | None]:
|
| 308 |
+
batch_size, seq_length, _ = from_tensor.shape
|
| 309 |
+
|
| 310 |
+
# If this is instantiated as a cross-attention module, the keys
|
| 311 |
+
# and values come from an encoder; the attention mask needs to be
|
| 312 |
+
# such that the encoder's padding tokens are not attended to.
|
| 313 |
+
|
| 314 |
+
key_layer = (
|
| 315 |
+
self.key(to_tensor)
|
| 316 |
+
.view(batch_size, -1, self.num_attention_heads, self.attention_head_size)
|
| 317 |
+
.transpose(1, 2)
|
| 318 |
+
)
|
| 319 |
+
value_layer = (
|
| 320 |
+
self.value(to_tensor)
|
| 321 |
+
.view(batch_size, -1, self.num_attention_heads, self.attention_head_size)
|
| 322 |
+
.transpose(1, 2)
|
| 323 |
+
)
|
| 324 |
+
query_layer = (
|
| 325 |
+
self.query(from_tensor)
|
| 326 |
+
.view(batch_size, -1, self.num_attention_heads, self.attention_head_size)
|
| 327 |
+
.transpose(1, 2)
|
| 328 |
+
)
|
| 329 |
+
|
| 330 |
+
# Take the dot product between "query" and "key" to get the raw attention scores.
|
| 331 |
+
attention_scores = torch.matmul(query_layer, key_layer.transpose(-1, -2))
|
| 332 |
+
|
| 333 |
+
attention_scores = attention_scores / math.sqrt(self.attention_head_size)
|
| 334 |
+
if attention_mask is not None:
|
| 335 |
+
if attention_mask.ndim == 3:
|
| 336 |
+
# if attention_mask is 3D, do the following:
|
| 337 |
+
attention_mask = torch.unsqueeze(attention_mask, dim=1)
|
| 338 |
+
# Since attention_mask is 1.0 for positions we want to attend and 0.0 for
|
| 339 |
+
# masked positions, this operation will create a tensor which is 0.0 for
|
| 340 |
+
# positions we want to attend and the dtype's smallest value for masked positions.
|
| 341 |
+
attention_mask = (1.0 - attention_mask.float()) * torch.finfo(attention_scores.dtype).min
|
| 342 |
+
# Apply the attention mask (precomputed for all layers in CanineModel forward() function)
|
| 343 |
+
attention_scores = attention_scores + attention_mask
|
| 344 |
+
|
| 345 |
+
# Normalize the attention scores to probabilities.
|
| 346 |
+
attention_probs = nn.functional.softmax(attention_scores, dim=-1)
|
| 347 |
+
|
| 348 |
+
# This is actually dropping out entire tokens to attend to, which might
|
| 349 |
+
# seem a bit unusual, but is taken from the original Transformer paper.
|
| 350 |
+
attention_probs = self.dropout(attention_probs)
|
| 351 |
+
|
| 352 |
+
context_layer = torch.matmul(attention_probs, value_layer)
|
| 353 |
+
|
| 354 |
+
context_layer = context_layer.permute(0, 2, 1, 3).contiguous()
|
| 355 |
+
new_context_layer_shape = context_layer.size()[:-2] + (self.all_head_size,)
|
| 356 |
+
context_layer = context_layer.view(*new_context_layer_shape)
|
| 357 |
+
|
| 358 |
+
outputs = (context_layer, attention_probs) if output_attentions else (context_layer,)
|
| 359 |
+
|
| 360 |
+
return outputs
|
| 361 |
+
|
| 362 |
+
|
| 363 |
+
class CanineSelfOutput(nn.Module):
|
| 364 |
+
def __init__(self, config):
|
| 365 |
+
super().__init__()
|
| 366 |
+
self.dense = nn.Linear(config.hidden_size, config.hidden_size)
|
| 367 |
+
self.LayerNorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps)
|
| 368 |
+
self.dropout = nn.Dropout(config.hidden_dropout_prob)
|
| 369 |
+
|
| 370 |
+
def forward(
|
| 371 |
+
self, hidden_states: tuple[torch.FloatTensor], input_tensor: torch.FloatTensor
|
| 372 |
+
) -> tuple[torch.FloatTensor, torch.FloatTensor]:
|
| 373 |
+
hidden_states = self.dense(hidden_states)
|
| 374 |
+
hidden_states = self.dropout(hidden_states)
|
| 375 |
+
hidden_states = self.LayerNorm(hidden_states + input_tensor)
|
| 376 |
+
return hidden_states
|
| 377 |
+
|
| 378 |
+
|
| 379 |
+
class CanineAttention(nn.Module):
|
| 380 |
+
"""
|
| 381 |
+
Additional arguments related to local attention:
|
| 382 |
+
|
| 383 |
+
- **local** (`bool`, *optional*, defaults to `False`) -- Whether to apply local attention.
|
| 384 |
+
- **always_attend_to_first_position** (`bool`, *optional*, defaults to `False`) -- Should all blocks be able to
|
| 385 |
+
attend
|
| 386 |
+
to the `to_tensor`'s first position (e.g. a [CLS] position)? - **first_position_attends_to_all** (`bool`,
|
| 387 |
+
*optional*, defaults to `False`) -- Should the *from_tensor*'s first position be able to attend to all
|
| 388 |
+
positions within the *from_tensor*? - **attend_from_chunk_width** (`int`, *optional*, defaults to 128) -- The
|
| 389 |
+
width of each block-wise chunk in `from_tensor`. - **attend_from_chunk_stride** (`int`, *optional*, defaults to
|
| 390 |
+
128) -- The number of elements to skip when moving to the next block in `from_tensor`. -
|
| 391 |
+
**attend_to_chunk_width** (`int`, *optional*, defaults to 128) -- The width of each block-wise chunk in
|
| 392 |
+
*to_tensor*. - **attend_to_chunk_stride** (`int`, *optional*, defaults to 128) -- The number of elements to
|
| 393 |
+
skip when moving to the next block in `to_tensor`.
|
| 394 |
+
"""
|
| 395 |
+
|
| 396 |
+
def __init__(
|
| 397 |
+
self,
|
| 398 |
+
config,
|
| 399 |
+
local=False,
|
| 400 |
+
always_attend_to_first_position: bool = False,
|
| 401 |
+
first_position_attends_to_all: bool = False,
|
| 402 |
+
attend_from_chunk_width: int = 128,
|
| 403 |
+
attend_from_chunk_stride: int = 128,
|
| 404 |
+
attend_to_chunk_width: int = 128,
|
| 405 |
+
attend_to_chunk_stride: int = 128,
|
| 406 |
+
):
|
| 407 |
+
super().__init__()
|
| 408 |
+
self.self = CanineSelfAttention(config)
|
| 409 |
+
self.output = CanineSelfOutput(config)
|
| 410 |
+
|
| 411 |
+
# additional arguments related to local attention
|
| 412 |
+
self.local = local
|
| 413 |
+
if attend_from_chunk_width < attend_from_chunk_stride:
|
| 414 |
+
raise ValueError(
|
| 415 |
+
"`attend_from_chunk_width` < `attend_from_chunk_stride` would cause sequence positions to get skipped."
|
| 416 |
+
)
|
| 417 |
+
if attend_to_chunk_width < attend_to_chunk_stride:
|
| 418 |
+
raise ValueError(
|
| 419 |
+
"`attend_to_chunk_width` < `attend_to_chunk_stride`would cause sequence positions to get skipped."
|
| 420 |
+
)
|
| 421 |
+
self.always_attend_to_first_position = always_attend_to_first_position
|
| 422 |
+
self.first_position_attends_to_all = first_position_attends_to_all
|
| 423 |
+
self.attend_from_chunk_width = attend_from_chunk_width
|
| 424 |
+
self.attend_from_chunk_stride = attend_from_chunk_stride
|
| 425 |
+
self.attend_to_chunk_width = attend_to_chunk_width
|
| 426 |
+
self.attend_to_chunk_stride = attend_to_chunk_stride
|
| 427 |
+
|
| 428 |
+
def forward(
|
| 429 |
+
self,
|
| 430 |
+
hidden_states: tuple[torch.FloatTensor],
|
| 431 |
+
attention_mask: torch.FloatTensor | None = None,
|
| 432 |
+
output_attentions: bool | None = False,
|
| 433 |
+
) -> tuple[torch.FloatTensor, torch.FloatTensor | None]:
|
| 434 |
+
if not self.local:
|
| 435 |
+
self_outputs = self.self(hidden_states, hidden_states, attention_mask, output_attentions)
|
| 436 |
+
attention_output = self_outputs[0]
|
| 437 |
+
else:
|
| 438 |
+
from_seq_length = to_seq_length = hidden_states.shape[1]
|
| 439 |
+
from_tensor = to_tensor = hidden_states
|
| 440 |
+
|
| 441 |
+
# Create chunks (windows) that we will attend *from* and then concatenate them.
|
| 442 |
+
from_chunks = []
|
| 443 |
+
if self.first_position_attends_to_all:
|
| 444 |
+
from_chunks.append((0, 1))
|
| 445 |
+
# We must skip this first position so that our output sequence is the
|
| 446 |
+
# correct length (this matters in the *from* sequence only).
|
| 447 |
+
from_start = 1
|
| 448 |
+
else:
|
| 449 |
+
from_start = 0
|
| 450 |
+
for chunk_start in range(from_start, from_seq_length, self.attend_from_chunk_stride):
|
| 451 |
+
chunk_end = min(from_seq_length, chunk_start + self.attend_from_chunk_width)
|
| 452 |
+
from_chunks.append((chunk_start, chunk_end))
|
| 453 |
+
|
| 454 |
+
# Determine the chunks (windows) that will attend *to*.
|
| 455 |
+
to_chunks = []
|
| 456 |
+
if self.first_position_attends_to_all:
|
| 457 |
+
to_chunks.append((0, to_seq_length))
|
| 458 |
+
for chunk_start in range(0, to_seq_length, self.attend_to_chunk_stride):
|
| 459 |
+
chunk_end = min(to_seq_length, chunk_start + self.attend_to_chunk_width)
|
| 460 |
+
to_chunks.append((chunk_start, chunk_end))
|
| 461 |
+
|
| 462 |
+
if len(from_chunks) != len(to_chunks):
|
| 463 |
+
raise ValueError(
|
| 464 |
+
f"Expected to have same number of `from_chunks` ({from_chunks}) and "
|
| 465 |
+
f"`to_chunks` ({from_chunks}). Check strides."
|
| 466 |
+
)
|
| 467 |
+
|
| 468 |
+
# next, compute attention scores for each pair of windows and concatenate
|
| 469 |
+
attention_output_chunks = []
|
| 470 |
+
attention_probs_chunks = []
|
| 471 |
+
for (from_start, from_end), (to_start, to_end) in zip(from_chunks, to_chunks):
|
| 472 |
+
from_tensor_chunk = from_tensor[:, from_start:from_end, :]
|
| 473 |
+
to_tensor_chunk = to_tensor[:, to_start:to_end, :]
|
| 474 |
+
# `attention_mask`: <float>[batch_size, from_seq, to_seq]
|
| 475 |
+
# `attention_mask_chunk`: <float>[batch_size, from_seq_chunk, to_seq_chunk]
|
| 476 |
+
attention_mask_chunk = attention_mask[:, from_start:from_end, to_start:to_end]
|
| 477 |
+
if self.always_attend_to_first_position:
|
| 478 |
+
cls_attention_mask = attention_mask[:, from_start:from_end, 0:1]
|
| 479 |
+
attention_mask_chunk = torch.cat([cls_attention_mask, attention_mask_chunk], dim=2)
|
| 480 |
+
|
| 481 |
+
cls_position = to_tensor[:, 0:1, :]
|
| 482 |
+
to_tensor_chunk = torch.cat([cls_position, to_tensor_chunk], dim=1)
|
| 483 |
+
|
| 484 |
+
attention_outputs_chunk = self.self(
|
| 485 |
+
from_tensor_chunk, to_tensor_chunk, attention_mask_chunk, output_attentions
|
| 486 |
+
)
|
| 487 |
+
attention_output_chunks.append(attention_outputs_chunk[0])
|
| 488 |
+
if output_attentions:
|
| 489 |
+
attention_probs_chunks.append(attention_outputs_chunk[1])
|
| 490 |
+
|
| 491 |
+
attention_output = torch.cat(attention_output_chunks, dim=1)
|
| 492 |
+
|
| 493 |
+
attention_output = self.output(attention_output, hidden_states)
|
| 494 |
+
outputs = (attention_output,)
|
| 495 |
+
if not self.local:
|
| 496 |
+
outputs = outputs + self_outputs[1:] # add attentions if we output them
|
| 497 |
+
else:
|
| 498 |
+
outputs = outputs + tuple(attention_probs_chunks) # add attentions if we output them
|
| 499 |
+
return outputs
|
| 500 |
+
|
| 501 |
+
|
| 502 |
+
class CanineIntermediate(nn.Module):
|
| 503 |
+
def __init__(self, config):
|
| 504 |
+
super().__init__()
|
| 505 |
+
self.dense = nn.Linear(config.hidden_size, config.intermediate_size)
|
| 506 |
+
if isinstance(config.hidden_act, str):
|
| 507 |
+
self.intermediate_act_fn = ACT2FN[config.hidden_act]
|
| 508 |
+
else:
|
| 509 |
+
self.intermediate_act_fn = config.hidden_act
|
| 510 |
+
|
| 511 |
+
def forward(self, hidden_states: torch.FloatTensor) -> torch.FloatTensor:
|
| 512 |
+
hidden_states = self.dense(hidden_states)
|
| 513 |
+
hidden_states = self.intermediate_act_fn(hidden_states)
|
| 514 |
+
return hidden_states
|
| 515 |
+
|
| 516 |
+
|
| 517 |
+
class CanineOutput(nn.Module):
|
| 518 |
+
def __init__(self, config):
|
| 519 |
+
super().__init__()
|
| 520 |
+
self.dense = nn.Linear(config.intermediate_size, config.hidden_size)
|
| 521 |
+
self.LayerNorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps)
|
| 522 |
+
self.dropout = nn.Dropout(config.hidden_dropout_prob)
|
| 523 |
+
|
| 524 |
+
def forward(self, hidden_states: tuple[torch.FloatTensor], input_tensor: torch.FloatTensor) -> torch.FloatTensor:
|
| 525 |
+
hidden_states = self.dense(hidden_states)
|
| 526 |
+
hidden_states = self.dropout(hidden_states)
|
| 527 |
+
hidden_states = self.LayerNorm(hidden_states + input_tensor)
|
| 528 |
+
return hidden_states
|
| 529 |
+
|
| 530 |
+
|
| 531 |
+
class CanineLayer(GradientCheckpointingLayer):
|
| 532 |
+
def __init__(
|
| 533 |
+
self,
|
| 534 |
+
config,
|
| 535 |
+
local,
|
| 536 |
+
always_attend_to_first_position,
|
| 537 |
+
first_position_attends_to_all,
|
| 538 |
+
attend_from_chunk_width,
|
| 539 |
+
attend_from_chunk_stride,
|
| 540 |
+
attend_to_chunk_width,
|
| 541 |
+
attend_to_chunk_stride,
|
| 542 |
+
):
|
| 543 |
+
super().__init__()
|
| 544 |
+
self.chunk_size_feed_forward = config.chunk_size_feed_forward
|
| 545 |
+
self.seq_len_dim = 1
|
| 546 |
+
self.attention = CanineAttention(
|
| 547 |
+
config,
|
| 548 |
+
local,
|
| 549 |
+
always_attend_to_first_position,
|
| 550 |
+
first_position_attends_to_all,
|
| 551 |
+
attend_from_chunk_width,
|
| 552 |
+
attend_from_chunk_stride,
|
| 553 |
+
attend_to_chunk_width,
|
| 554 |
+
attend_to_chunk_stride,
|
| 555 |
+
)
|
| 556 |
+
self.intermediate = CanineIntermediate(config)
|
| 557 |
+
self.output = CanineOutput(config)
|
| 558 |
+
|
| 559 |
+
def forward(
|
| 560 |
+
self,
|
| 561 |
+
hidden_states: tuple[torch.FloatTensor],
|
| 562 |
+
attention_mask: torch.FloatTensor | None = None,
|
| 563 |
+
output_attentions: bool | None = False,
|
| 564 |
+
) -> tuple[torch.FloatTensor, torch.FloatTensor | None]:
|
| 565 |
+
self_attention_outputs = self.attention(
|
| 566 |
+
hidden_states,
|
| 567 |
+
attention_mask,
|
| 568 |
+
output_attentions=output_attentions,
|
| 569 |
+
)
|
| 570 |
+
attention_output = self_attention_outputs[0]
|
| 571 |
+
|
| 572 |
+
outputs = self_attention_outputs[1:] # add self attentions if we output attention weights
|
| 573 |
+
|
| 574 |
+
layer_output = apply_chunking_to_forward(
|
| 575 |
+
self.feed_forward_chunk, self.chunk_size_feed_forward, self.seq_len_dim, attention_output
|
| 576 |
+
)
|
| 577 |
+
outputs = (layer_output,) + outputs
|
| 578 |
+
|
| 579 |
+
return outputs
|
| 580 |
+
|
| 581 |
+
def feed_forward_chunk(self, attention_output):
|
| 582 |
+
intermediate_output = self.intermediate(attention_output)
|
| 583 |
+
layer_output = self.output(intermediate_output, attention_output)
|
| 584 |
+
return layer_output
|
| 585 |
+
|
| 586 |
+
|
| 587 |
+
class CanineEncoder(nn.Module):
|
| 588 |
+
def __init__(
|
| 589 |
+
self,
|
| 590 |
+
config,
|
| 591 |
+
local=False,
|
| 592 |
+
always_attend_to_first_position=False,
|
| 593 |
+
first_position_attends_to_all=False,
|
| 594 |
+
attend_from_chunk_width=128,
|
| 595 |
+
attend_from_chunk_stride=128,
|
| 596 |
+
attend_to_chunk_width=128,
|
| 597 |
+
attend_to_chunk_stride=128,
|
| 598 |
+
):
|
| 599 |
+
super().__init__()
|
| 600 |
+
self.config = config
|
| 601 |
+
self.layer = nn.ModuleList(
|
| 602 |
+
[
|
| 603 |
+
CanineLayer(
|
| 604 |
+
config,
|
| 605 |
+
local,
|
| 606 |
+
always_attend_to_first_position,
|
| 607 |
+
first_position_attends_to_all,
|
| 608 |
+
attend_from_chunk_width,
|
| 609 |
+
attend_from_chunk_stride,
|
| 610 |
+
attend_to_chunk_width,
|
| 611 |
+
attend_to_chunk_stride,
|
| 612 |
+
)
|
| 613 |
+
for _ in range(config.num_hidden_layers)
|
| 614 |
+
]
|
| 615 |
+
)
|
| 616 |
+
self.gradient_checkpointing = False
|
| 617 |
+
|
| 618 |
+
def forward(
|
| 619 |
+
self,
|
| 620 |
+
hidden_states: tuple[torch.FloatTensor],
|
| 621 |
+
attention_mask: torch.FloatTensor | None = None,
|
| 622 |
+
output_attentions: bool | None = False,
|
| 623 |
+
output_hidden_states: bool | None = False,
|
| 624 |
+
return_dict: bool | None = True,
|
| 625 |
+
) -> tuple | BaseModelOutput:
|
| 626 |
+
all_hidden_states = () if output_hidden_states else None
|
| 627 |
+
all_self_attentions = () if output_attentions else None
|
| 628 |
+
|
| 629 |
+
for i, layer_module in enumerate(self.layer):
|
| 630 |
+
if output_hidden_states:
|
| 631 |
+
all_hidden_states = all_hidden_states + (hidden_states,)
|
| 632 |
+
|
| 633 |
+
layer_outputs = layer_module(hidden_states, attention_mask, output_attentions)
|
| 634 |
+
|
| 635 |
+
hidden_states = layer_outputs[0]
|
| 636 |
+
if output_attentions:
|
| 637 |
+
all_self_attentions = all_self_attentions + (layer_outputs[1],)
|
| 638 |
+
|
| 639 |
+
if output_hidden_states:
|
| 640 |
+
all_hidden_states = all_hidden_states + (hidden_states,)
|
| 641 |
+
|
| 642 |
+
if not return_dict:
|
| 643 |
+
return tuple(v for v in [hidden_states, all_hidden_states, all_self_attentions] if v is not None)
|
| 644 |
+
return BaseModelOutput(
|
| 645 |
+
last_hidden_state=hidden_states,
|
| 646 |
+
hidden_states=all_hidden_states,
|
| 647 |
+
attentions=all_self_attentions,
|
| 648 |
+
)
|
| 649 |
+
|
| 650 |
+
|
| 651 |
+
class CaninePooler(nn.Module):
|
| 652 |
+
def __init__(self, config):
|
| 653 |
+
super().__init__()
|
| 654 |
+
self.dense = nn.Linear(config.hidden_size, config.hidden_size)
|
| 655 |
+
self.activation = nn.Tanh()
|
| 656 |
+
|
| 657 |
+
def forward(self, hidden_states: tuple[torch.FloatTensor]) -> torch.FloatTensor:
|
| 658 |
+
# We "pool" the model by simply taking the hidden state corresponding
|
| 659 |
+
# to the first token.
|
| 660 |
+
first_token_tensor = hidden_states[:, 0]
|
| 661 |
+
pooled_output = self.dense(first_token_tensor)
|
| 662 |
+
pooled_output = self.activation(pooled_output)
|
| 663 |
+
return pooled_output
|
| 664 |
+
|
| 665 |
+
|
| 666 |
+
class CaninePredictionHeadTransform(nn.Module):
|
| 667 |
+
def __init__(self, config):
|
| 668 |
+
super().__init__()
|
| 669 |
+
self.dense = nn.Linear(config.hidden_size, config.hidden_size)
|
| 670 |
+
if isinstance(config.hidden_act, str):
|
| 671 |
+
self.transform_act_fn = ACT2FN[config.hidden_act]
|
| 672 |
+
else:
|
| 673 |
+
self.transform_act_fn = config.hidden_act
|
| 674 |
+
self.LayerNorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps)
|
| 675 |
+
|
| 676 |
+
def forward(self, hidden_states: tuple[torch.FloatTensor]) -> torch.FloatTensor:
|
| 677 |
+
hidden_states = self.dense(hidden_states)
|
| 678 |
+
hidden_states = self.transform_act_fn(hidden_states)
|
| 679 |
+
hidden_states = self.LayerNorm(hidden_states)
|
| 680 |
+
return hidden_states
|
| 681 |
+
|
| 682 |
+
|
| 683 |
+
class CanineLMPredictionHead(nn.Module):
|
| 684 |
+
def __init__(self, config):
|
| 685 |
+
super().__init__()
|
| 686 |
+
self.transform = CaninePredictionHeadTransform(config)
|
| 687 |
+
|
| 688 |
+
# The output weights are the same as the input embeddings, but there is
|
| 689 |
+
# an output-only bias for each token.
|
| 690 |
+
self.decoder = nn.Linear(config.hidden_size, config.vocab_size, bias=True)
|
| 691 |
+
|
| 692 |
+
self.bias = nn.Parameter(torch.zeros(config.vocab_size))
|
| 693 |
+
|
| 694 |
+
# Need a link between the two variables so that the bias is correctly resized with `resize_token_embeddings`
|
| 695 |
+
|
| 696 |
+
def forward(self, hidden_states: tuple[torch.FloatTensor]) -> torch.FloatTensor:
|
| 697 |
+
hidden_states = self.transform(hidden_states)
|
| 698 |
+
hidden_states = self.decoder(hidden_states)
|
| 699 |
+
return hidden_states
|
| 700 |
+
|
| 701 |
+
|
| 702 |
+
class CanineOnlyMLMHead(nn.Module):
|
| 703 |
+
def __init__(self, config):
|
| 704 |
+
super().__init__()
|
| 705 |
+
self.predictions = CanineLMPredictionHead(config)
|
| 706 |
+
|
| 707 |
+
def forward(
|
| 708 |
+
self,
|
| 709 |
+
sequence_output: tuple[torch.Tensor],
|
| 710 |
+
) -> tuple[torch.Tensor]:
|
| 711 |
+
prediction_scores = self.predictions(sequence_output)
|
| 712 |
+
return prediction_scores
|
| 713 |
+
|
| 714 |
+
|
| 715 |
+
@auto_docstring
|
| 716 |
+
class CaninePreTrainedModel(PreTrainedModel):
|
| 717 |
+
config: CanineConfig
|
| 718 |
+
base_model_prefix = "canine"
|
| 719 |
+
supports_gradient_checkpointing = True
|
| 720 |
+
|
| 721 |
+
def _init_weights(self, module):
|
| 722 |
+
super()._init_weights(module)
|
| 723 |
+
if isinstance(module, CanineEmbeddings):
|
| 724 |
+
init.copy_(module.position_ids, torch.arange(module.position_ids.shape[-1]).expand((1, -1)))
|
| 725 |
+
|
| 726 |
+
|
| 727 |
+
@auto_docstring
|
| 728 |
+
class CanineModel(CaninePreTrainedModel):
|
| 729 |
+
def __init__(self, config, add_pooling_layer=True):
|
| 730 |
+
r"""
|
| 731 |
+
add_pooling_layer (bool, *optional*, defaults to `True`):
|
| 732 |
+
Whether to add a pooling layer
|
| 733 |
+
"""
|
| 734 |
+
super().__init__(config)
|
| 735 |
+
self.config = config
|
| 736 |
+
shallow_config = copy.deepcopy(config)
|
| 737 |
+
shallow_config.num_hidden_layers = 1
|
| 738 |
+
|
| 739 |
+
self.char_embeddings = CanineEmbeddings(config)
|
| 740 |
+
# shallow/low-dim transformer encoder to get a initial character encoding
|
| 741 |
+
self.initial_char_encoder = CanineEncoder(
|
| 742 |
+
shallow_config,
|
| 743 |
+
local=True,
|
| 744 |
+
always_attend_to_first_position=False,
|
| 745 |
+
first_position_attends_to_all=False,
|
| 746 |
+
attend_from_chunk_width=config.local_transformer_stride,
|
| 747 |
+
attend_from_chunk_stride=config.local_transformer_stride,
|
| 748 |
+
attend_to_chunk_width=config.local_transformer_stride,
|
| 749 |
+
attend_to_chunk_stride=config.local_transformer_stride,
|
| 750 |
+
)
|
| 751 |
+
self.chars_to_molecules = CharactersToMolecules(config)
|
| 752 |
+
# deep transformer encoder
|
| 753 |
+
self.encoder = CanineEncoder(config)
|
| 754 |
+
self.projection = ConvProjection(config)
|
| 755 |
+
# shallow/low-dim transformer encoder to get a final character encoding
|
| 756 |
+
self.final_char_encoder = CanineEncoder(shallow_config)
|
| 757 |
+
|
| 758 |
+
self.pooler = CaninePooler(config) if add_pooling_layer else None
|
| 759 |
+
|
| 760 |
+
# Initialize weights and apply final processing
|
| 761 |
+
self.post_init()
|
| 762 |
+
|
| 763 |
+
def _create_3d_attention_mask_from_input_mask(self, from_tensor, to_mask):
|
| 764 |
+
"""
|
| 765 |
+
Create 3D attention mask from a 2D tensor mask.
|
| 766 |
+
|
| 767 |
+
Args:
|
| 768 |
+
from_tensor: 2D or 3D Tensor of shape [batch_size, from_seq_length, ...].
|
| 769 |
+
to_mask: int32 Tensor of shape [batch_size, to_seq_length].
|
| 770 |
+
|
| 771 |
+
Returns:
|
| 772 |
+
float Tensor of shape [batch_size, from_seq_length, to_seq_length].
|
| 773 |
+
"""
|
| 774 |
+
batch_size, from_seq_length = from_tensor.shape[0], from_tensor.shape[1]
|
| 775 |
+
|
| 776 |
+
to_seq_length = to_mask.shape[1]
|
| 777 |
+
|
| 778 |
+
to_mask = torch.reshape(to_mask, (batch_size, 1, to_seq_length)).float()
|
| 779 |
+
|
| 780 |
+
# We don't assume that `from_tensor` is a mask (although it could be). We
|
| 781 |
+
# don't actually care if we attend *from* padding tokens (only *to* padding)
|
| 782 |
+
# tokens so we create a tensor of all ones.
|
| 783 |
+
broadcast_ones = torch.ones(size=(batch_size, from_seq_length, 1), dtype=torch.float32, device=to_mask.device)
|
| 784 |
+
|
| 785 |
+
# Here we broadcast along two dimensions to create the mask.
|
| 786 |
+
mask = broadcast_ones * to_mask
|
| 787 |
+
|
| 788 |
+
return mask
|
| 789 |
+
|
| 790 |
+
def _downsample_attention_mask(self, char_attention_mask: torch.Tensor, downsampling_rate: int):
|
| 791 |
+
"""Downsample 2D character attention mask to 2D molecule attention mask using MaxPool1d layer."""
|
| 792 |
+
|
| 793 |
+
# first, make char_attention_mask 3D by adding a channel dim
|
| 794 |
+
batch_size, char_seq_len = char_attention_mask.shape
|
| 795 |
+
poolable_char_mask = torch.reshape(char_attention_mask, (batch_size, 1, char_seq_len))
|
| 796 |
+
|
| 797 |
+
# next, apply MaxPool1d to get pooled_molecule_mask of shape (batch_size, 1, mol_seq_len)
|
| 798 |
+
pooled_molecule_mask = torch.nn.MaxPool1d(kernel_size=downsampling_rate, stride=downsampling_rate)(
|
| 799 |
+
poolable_char_mask.float()
|
| 800 |
+
)
|
| 801 |
+
|
| 802 |
+
# finally, squeeze to get tensor of shape (batch_size, mol_seq_len)
|
| 803 |
+
molecule_attention_mask = torch.squeeze(pooled_molecule_mask, dim=-1)
|
| 804 |
+
|
| 805 |
+
return molecule_attention_mask
|
| 806 |
+
|
| 807 |
+
def _repeat_molecules(self, molecules: torch.Tensor, char_seq_length: int) -> torch.Tensor:
|
| 808 |
+
"""Repeats molecules to make them the same length as the char sequence."""
|
| 809 |
+
|
| 810 |
+
rate = self.config.downsampling_rate
|
| 811 |
+
|
| 812 |
+
molecules_without_extra_cls = molecules[:, 1:, :]
|
| 813 |
+
# `repeated`: [batch_size, almost_char_seq_len, molecule_hidden_size]
|
| 814 |
+
repeated = torch.repeat_interleave(molecules_without_extra_cls, repeats=rate, dim=-2)
|
| 815 |
+
|
| 816 |
+
# So far, we've repeated the elements sufficient for any `char_seq_length`
|
| 817 |
+
# that's a multiple of `downsampling_rate`. Now we account for the last
|
| 818 |
+
# n elements (n < `downsampling_rate`), i.e. the remainder of floor
|
| 819 |
+
# division. We do this by repeating the last molecule a few extra times.
|
| 820 |
+
last_molecule = molecules[:, -1:, :]
|
| 821 |
+
remainder_length = char_seq_length % rate
|
| 822 |
+
remainder_repeated = torch.repeat_interleave(
|
| 823 |
+
last_molecule,
|
| 824 |
+
# +1 molecule to compensate for truncation.
|
| 825 |
+
repeats=remainder_length + rate,
|
| 826 |
+
dim=-2,
|
| 827 |
+
)
|
| 828 |
+
|
| 829 |
+
# `repeated`: [batch_size, char_seq_len, molecule_hidden_size]
|
| 830 |
+
return torch.cat([repeated, remainder_repeated], dim=-2)
|
| 831 |
+
|
| 832 |
+
@auto_docstring
|
| 833 |
+
def forward(
|
| 834 |
+
self,
|
| 835 |
+
input_ids: torch.LongTensor | None = None,
|
| 836 |
+
attention_mask: torch.FloatTensor | None = None,
|
| 837 |
+
token_type_ids: torch.LongTensor | None = None,
|
| 838 |
+
position_ids: torch.LongTensor | None = None,
|
| 839 |
+
inputs_embeds: torch.FloatTensor | None = None,
|
| 840 |
+
output_attentions: bool | None = None,
|
| 841 |
+
output_hidden_states: bool | None = None,
|
| 842 |
+
return_dict: bool | None = None,
|
| 843 |
+
**kwargs,
|
| 844 |
+
) -> tuple | CanineModelOutputWithPooling:
|
| 845 |
+
output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions
|
| 846 |
+
output_hidden_states = (
|
| 847 |
+
output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states
|
| 848 |
+
)
|
| 849 |
+
all_hidden_states = () if output_hidden_states else None
|
| 850 |
+
all_self_attentions = () if output_attentions else None
|
| 851 |
+
return_dict = return_dict if return_dict is not None else self.config.return_dict
|
| 852 |
+
|
| 853 |
+
if input_ids is not None and inputs_embeds is not None:
|
| 854 |
+
raise ValueError("You cannot specify both input_ids and inputs_embeds at the same time")
|
| 855 |
+
elif input_ids is not None:
|
| 856 |
+
self.warn_if_padding_and_no_attention_mask(input_ids, attention_mask)
|
| 857 |
+
input_shape = input_ids.size()
|
| 858 |
+
elif inputs_embeds is not None:
|
| 859 |
+
input_shape = inputs_embeds.size()[:-1]
|
| 860 |
+
else:
|
| 861 |
+
raise ValueError("You have to specify either input_ids or inputs_embeds")
|
| 862 |
+
|
| 863 |
+
batch_size, seq_length = input_shape
|
| 864 |
+
device = input_ids.device if input_ids is not None else inputs_embeds.device
|
| 865 |
+
|
| 866 |
+
if attention_mask is None:
|
| 867 |
+
attention_mask = torch.ones(((batch_size, seq_length)), device=device)
|
| 868 |
+
if token_type_ids is None:
|
| 869 |
+
token_type_ids = torch.zeros(input_shape, dtype=torch.long, device=device)
|
| 870 |
+
|
| 871 |
+
# We can provide a self-attention mask of dimensions [batch_size, from_seq_length, to_seq_length]
|
| 872 |
+
# ourselves in which case we just need to make it broadcastable to all heads.
|
| 873 |
+
extended_attention_mask: torch.Tensor = self.get_extended_attention_mask(attention_mask, input_shape)
|
| 874 |
+
molecule_attention_mask = self._downsample_attention_mask(
|
| 875 |
+
attention_mask, downsampling_rate=self.config.downsampling_rate
|
| 876 |
+
)
|
| 877 |
+
extended_molecule_attention_mask: torch.Tensor = self.get_extended_attention_mask(
|
| 878 |
+
molecule_attention_mask, (batch_size, molecule_attention_mask.shape[-1])
|
| 879 |
+
)
|
| 880 |
+
|
| 881 |
+
# `input_char_embeddings`: shape (batch_size, char_seq, char_dim)
|
| 882 |
+
input_char_embeddings = self.char_embeddings(
|
| 883 |
+
input_ids=input_ids,
|
| 884 |
+
position_ids=position_ids,
|
| 885 |
+
token_type_ids=token_type_ids,
|
| 886 |
+
inputs_embeds=inputs_embeds,
|
| 887 |
+
)
|
| 888 |
+
|
| 889 |
+
# Contextualize character embeddings using shallow Transformer.
|
| 890 |
+
# We use a 3D attention mask for the local attention.
|
| 891 |
+
# `input_char_encoding`: shape (batch_size, char_seq_len, char_dim)
|
| 892 |
+
char_attention_mask = self._create_3d_attention_mask_from_input_mask(
|
| 893 |
+
input_ids if input_ids is not None else inputs_embeds, attention_mask
|
| 894 |
+
)
|
| 895 |
+
init_chars_encoder_outputs = self.initial_char_encoder(
|
| 896 |
+
input_char_embeddings,
|
| 897 |
+
attention_mask=char_attention_mask,
|
| 898 |
+
output_attentions=output_attentions,
|
| 899 |
+
output_hidden_states=output_hidden_states,
|
| 900 |
+
)
|
| 901 |
+
input_char_encoding = init_chars_encoder_outputs.last_hidden_state
|
| 902 |
+
|
| 903 |
+
# Downsample chars to molecules.
|
| 904 |
+
# The following lines have dimensions: [batch, molecule_seq, molecule_dim].
|
| 905 |
+
# In this transformation, we change the dimensionality from `char_dim` to
|
| 906 |
+
# `molecule_dim`, but do *NOT* add a resnet connection. Instead, we rely on
|
| 907 |
+
# the resnet connections (a) from the final char transformer stack back into
|
| 908 |
+
# the original char transformer stack and (b) the resnet connections from
|
| 909 |
+
# the final char transformer stack back into the deep BERT stack of
|
| 910 |
+
# molecules.
|
| 911 |
+
#
|
| 912 |
+
# Empirically, it is critical to use a powerful enough transformation here:
|
| 913 |
+
# mean pooling causes training to diverge with huge gradient norms in this
|
| 914 |
+
# region of the model; using a convolution here resolves this issue. From
|
| 915 |
+
# this, it seems that molecules and characters require a very different
|
| 916 |
+
# feature space; intuitively, this makes sense.
|
| 917 |
+
init_molecule_encoding = self.chars_to_molecules(input_char_encoding)
|
| 918 |
+
|
| 919 |
+
# Deep BERT encoder
|
| 920 |
+
# `molecule_sequence_output`: shape (batch_size, mol_seq_len, mol_dim)
|
| 921 |
+
encoder_outputs = self.encoder(
|
| 922 |
+
init_molecule_encoding,
|
| 923 |
+
attention_mask=extended_molecule_attention_mask,
|
| 924 |
+
output_attentions=output_attentions,
|
| 925 |
+
output_hidden_states=output_hidden_states,
|
| 926 |
+
return_dict=return_dict,
|
| 927 |
+
)
|
| 928 |
+
molecule_sequence_output = encoder_outputs[0]
|
| 929 |
+
pooled_output = self.pooler(molecule_sequence_output) if self.pooler is not None else None
|
| 930 |
+
|
| 931 |
+
# Upsample molecules back to characters.
|
| 932 |
+
# `repeated_molecules`: shape (batch_size, char_seq_len, mol_hidden_size)
|
| 933 |
+
repeated_molecules = self._repeat_molecules(molecule_sequence_output, char_seq_length=input_shape[-1])
|
| 934 |
+
|
| 935 |
+
# Concatenate representations (contextualized char embeddings and repeated molecules):
|
| 936 |
+
# `concat`: shape [batch_size, char_seq_len, molecule_hidden_size+char_hidden_final]
|
| 937 |
+
concat = torch.cat([input_char_encoding, repeated_molecules], dim=-1)
|
| 938 |
+
|
| 939 |
+
# Project representation dimension back to hidden_size
|
| 940 |
+
# `sequence_output`: shape (batch_size, char_seq_len, hidden_size])
|
| 941 |
+
sequence_output = self.projection(concat)
|
| 942 |
+
|
| 943 |
+
# Apply final shallow Transformer
|
| 944 |
+
# `sequence_output`: shape (batch_size, char_seq_len, hidden_size])
|
| 945 |
+
final_chars_encoder_outputs = self.final_char_encoder(
|
| 946 |
+
sequence_output,
|
| 947 |
+
attention_mask=extended_attention_mask,
|
| 948 |
+
output_attentions=output_attentions,
|
| 949 |
+
output_hidden_states=output_hidden_states,
|
| 950 |
+
)
|
| 951 |
+
sequence_output = final_chars_encoder_outputs.last_hidden_state
|
| 952 |
+
|
| 953 |
+
if output_hidden_states:
|
| 954 |
+
deep_encoder_hidden_states = encoder_outputs.hidden_states if return_dict else encoder_outputs[1]
|
| 955 |
+
all_hidden_states = (
|
| 956 |
+
all_hidden_states
|
| 957 |
+
+ init_chars_encoder_outputs.hidden_states
|
| 958 |
+
+ deep_encoder_hidden_states
|
| 959 |
+
+ final_chars_encoder_outputs.hidden_states
|
| 960 |
+
)
|
| 961 |
+
|
| 962 |
+
if output_attentions:
|
| 963 |
+
deep_encoder_self_attentions = encoder_outputs.attentions if return_dict else encoder_outputs[-1]
|
| 964 |
+
all_self_attentions = (
|
| 965 |
+
all_self_attentions
|
| 966 |
+
+ init_chars_encoder_outputs.attentions
|
| 967 |
+
+ deep_encoder_self_attentions
|
| 968 |
+
+ final_chars_encoder_outputs.attentions
|
| 969 |
+
)
|
| 970 |
+
|
| 971 |
+
if not return_dict:
|
| 972 |
+
output = (sequence_output, pooled_output)
|
| 973 |
+
output += tuple(v for v in [all_hidden_states, all_self_attentions] if v is not None)
|
| 974 |
+
return output
|
| 975 |
+
|
| 976 |
+
return CanineModelOutputWithPooling(
|
| 977 |
+
last_hidden_state=sequence_output,
|
| 978 |
+
pooler_output=pooled_output,
|
| 979 |
+
hidden_states=all_hidden_states,
|
| 980 |
+
attentions=all_self_attentions,
|
| 981 |
+
)
|
| 982 |
+
|
| 983 |
+
|
| 984 |
+
@auto_docstring(
|
| 985 |
+
custom_intro="""
|
| 986 |
+
CANINE Model transformer with a sequence classification/regression head on top (a linear layer on top of the pooled
|
| 987 |
+
output) e.g. for GLUE tasks.
|
| 988 |
+
"""
|
| 989 |
+
)
|
| 990 |
+
class CanineForSequenceClassification(CaninePreTrainedModel):
|
| 991 |
+
def __init__(self, config):
|
| 992 |
+
super().__init__(config)
|
| 993 |
+
self.num_labels = config.num_labels
|
| 994 |
+
|
| 995 |
+
self.canine = CanineModel(config)
|
| 996 |
+
self.dropout = nn.Dropout(config.hidden_dropout_prob)
|
| 997 |
+
self.classifier = nn.Linear(config.hidden_size, config.num_labels)
|
| 998 |
+
|
| 999 |
+
# Initialize weights and apply final processing
|
| 1000 |
+
self.post_init()
|
| 1001 |
+
|
| 1002 |
+
@auto_docstring
|
| 1003 |
+
def forward(
|
| 1004 |
+
self,
|
| 1005 |
+
input_ids: torch.LongTensor | None = None,
|
| 1006 |
+
attention_mask: torch.FloatTensor | None = None,
|
| 1007 |
+
token_type_ids: torch.LongTensor | None = None,
|
| 1008 |
+
position_ids: torch.LongTensor | None = None,
|
| 1009 |
+
inputs_embeds: torch.FloatTensor | None = None,
|
| 1010 |
+
labels: torch.LongTensor | None = None,
|
| 1011 |
+
output_attentions: bool | None = None,
|
| 1012 |
+
output_hidden_states: bool | None = None,
|
| 1013 |
+
return_dict: bool | None = None,
|
| 1014 |
+
**kwargs,
|
| 1015 |
+
) -> tuple | SequenceClassifierOutput:
|
| 1016 |
+
r"""
|
| 1017 |
+
labels (`torch.LongTensor` of shape `(batch_size,)`, *optional*):
|
| 1018 |
+
Labels for computing the sequence classification/regression loss. Indices should be in `[0, ...,
|
| 1019 |
+
config.num_labels - 1]`. If `config.num_labels == 1` a regression loss is computed (Mean-Square loss), If
|
| 1020 |
+
`config.num_labels > 1` a classification loss is computed (Cross-Entropy).
|
| 1021 |
+
"""
|
| 1022 |
+
return_dict = return_dict if return_dict is not None else self.config.return_dict
|
| 1023 |
+
|
| 1024 |
+
outputs = self.canine(
|
| 1025 |
+
input_ids,
|
| 1026 |
+
attention_mask=attention_mask,
|
| 1027 |
+
token_type_ids=token_type_ids,
|
| 1028 |
+
position_ids=position_ids,
|
| 1029 |
+
inputs_embeds=inputs_embeds,
|
| 1030 |
+
output_attentions=output_attentions,
|
| 1031 |
+
output_hidden_states=output_hidden_states,
|
| 1032 |
+
return_dict=return_dict,
|
| 1033 |
+
)
|
| 1034 |
+
|
| 1035 |
+
pooled_output = outputs[1]
|
| 1036 |
+
|
| 1037 |
+
pooled_output = self.dropout(pooled_output)
|
| 1038 |
+
logits = self.classifier(pooled_output)
|
| 1039 |
+
|
| 1040 |
+
loss = None
|
| 1041 |
+
if labels is not None:
|
| 1042 |
+
if self.config.problem_type is None:
|
| 1043 |
+
if self.num_labels == 1:
|
| 1044 |
+
self.config.problem_type = "regression"
|
| 1045 |
+
elif self.num_labels > 1 and (labels.dtype == torch.long or labels.dtype == torch.int):
|
| 1046 |
+
self.config.problem_type = "single_label_classification"
|
| 1047 |
+
else:
|
| 1048 |
+
self.config.problem_type = "multi_label_classification"
|
| 1049 |
+
|
| 1050 |
+
if self.config.problem_type == "regression":
|
| 1051 |
+
loss_fct = MSELoss()
|
| 1052 |
+
if self.num_labels == 1:
|
| 1053 |
+
loss = loss_fct(logits.squeeze(), labels.squeeze())
|
| 1054 |
+
else:
|
| 1055 |
+
loss = loss_fct(logits, labels)
|
| 1056 |
+
elif self.config.problem_type == "single_label_classification":
|
| 1057 |
+
loss_fct = CrossEntropyLoss()
|
| 1058 |
+
loss = loss_fct(logits.view(-1, self.num_labels), labels.view(-1))
|
| 1059 |
+
elif self.config.problem_type == "multi_label_classification":
|
| 1060 |
+
loss_fct = BCEWithLogitsLoss()
|
| 1061 |
+
loss = loss_fct(logits, labels)
|
| 1062 |
+
if not return_dict:
|
| 1063 |
+
output = (logits,) + outputs[2:]
|
| 1064 |
+
return ((loss,) + output) if loss is not None else output
|
| 1065 |
+
|
| 1066 |
+
return SequenceClassifierOutput(
|
| 1067 |
+
loss=loss,
|
| 1068 |
+
logits=logits,
|
| 1069 |
+
hidden_states=outputs.hidden_states,
|
| 1070 |
+
attentions=outputs.attentions,
|
| 1071 |
+
)
|
| 1072 |
+
|
| 1073 |
+
|
| 1074 |
+
@auto_docstring
|
| 1075 |
+
class CanineForMultipleChoice(CaninePreTrainedModel):
|
| 1076 |
+
def __init__(self, config):
|
| 1077 |
+
super().__init__(config)
|
| 1078 |
+
|
| 1079 |
+
self.canine = CanineModel(config)
|
| 1080 |
+
self.dropout = nn.Dropout(config.hidden_dropout_prob)
|
| 1081 |
+
self.classifier = nn.Linear(config.hidden_size, 1)
|
| 1082 |
+
|
| 1083 |
+
# Initialize weights and apply final processing
|
| 1084 |
+
self.post_init()
|
| 1085 |
+
|
| 1086 |
+
@auto_docstring
|
| 1087 |
+
def forward(
|
| 1088 |
+
self,
|
| 1089 |
+
input_ids: torch.LongTensor | None = None,
|
| 1090 |
+
attention_mask: torch.FloatTensor | None = None,
|
| 1091 |
+
token_type_ids: torch.LongTensor | None = None,
|
| 1092 |
+
position_ids: torch.LongTensor | None = None,
|
| 1093 |
+
inputs_embeds: torch.FloatTensor | None = None,
|
| 1094 |
+
labels: torch.LongTensor | None = None,
|
| 1095 |
+
output_attentions: bool | None = None,
|
| 1096 |
+
output_hidden_states: bool | None = None,
|
| 1097 |
+
return_dict: bool | None = None,
|
| 1098 |
+
**kwargs,
|
| 1099 |
+
) -> tuple | MultipleChoiceModelOutput:
|
| 1100 |
+
r"""
|
| 1101 |
+
input_ids (`torch.LongTensor` of shape `(batch_size, num_choices, sequence_length)`):
|
| 1102 |
+
Indices of input sequence tokens in the vocabulary.
|
| 1103 |
+
|
| 1104 |
+
Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and
|
| 1105 |
+
[`PreTrainedTokenizer.__call__`] for details.
|
| 1106 |
+
|
| 1107 |
+
[What are input IDs?](../glossary#input-ids)
|
| 1108 |
+
token_type_ids (`torch.LongTensor` of shape `(batch_size, num_choices, sequence_length)`, *optional*):
|
| 1109 |
+
Segment token indices to indicate first and second portions of the inputs. Indices are selected in `[0,
|
| 1110 |
+
1]`:
|
| 1111 |
+
|
| 1112 |
+
- 0 corresponds to a *sentence A* token,
|
| 1113 |
+
- 1 corresponds to a *sentence B* token.
|
| 1114 |
+
|
| 1115 |
+
[What are token type IDs?](../glossary#token-type-ids)
|
| 1116 |
+
position_ids (`torch.LongTensor` of shape `(batch_size, num_choices, sequence_length)`, *optional*):
|
| 1117 |
+
Indices of positions of each input sequence tokens in the position embeddings. Selected in the range `[0,
|
| 1118 |
+
config.max_position_embeddings - 1]`.
|
| 1119 |
+
|
| 1120 |
+
[What are position IDs?](../glossary#position-ids)
|
| 1121 |
+
inputs_embeds (`torch.FloatTensor` of shape `(batch_size, num_choices, sequence_length, hidden_size)`, *optional*):
|
| 1122 |
+
Optionally, instead of passing `input_ids` you can choose to directly pass an embedded representation. This
|
| 1123 |
+
is useful if you want more control over how to convert *input_ids* indices into associated vectors than the
|
| 1124 |
+
model's internal embedding lookup matrix.
|
| 1125 |
+
labels (`torch.LongTensor` of shape `(batch_size,)`, *optional*):
|
| 1126 |
+
Labels for computing the multiple choice classification loss. Indices should be in `[0, ...,
|
| 1127 |
+
num_choices-1]` where `num_choices` is the size of the second dimension of the input tensors. (See
|
| 1128 |
+
`input_ids` above)
|
| 1129 |
+
"""
|
| 1130 |
+
return_dict = return_dict if return_dict is not None else self.config.return_dict
|
| 1131 |
+
num_choices = input_ids.shape[1] if input_ids is not None else inputs_embeds.shape[1]
|
| 1132 |
+
|
| 1133 |
+
input_ids = input_ids.view(-1, input_ids.size(-1)) if input_ids is not None else None
|
| 1134 |
+
attention_mask = attention_mask.view(-1, attention_mask.size(-1)) if attention_mask is not None else None
|
| 1135 |
+
token_type_ids = token_type_ids.view(-1, token_type_ids.size(-1)) if token_type_ids is not None else None
|
| 1136 |
+
position_ids = position_ids.view(-1, position_ids.size(-1)) if position_ids is not None else None
|
| 1137 |
+
inputs_embeds = (
|
| 1138 |
+
inputs_embeds.view(-1, inputs_embeds.size(-2), inputs_embeds.size(-1))
|
| 1139 |
+
if inputs_embeds is not None
|
| 1140 |
+
else None
|
| 1141 |
+
)
|
| 1142 |
+
|
| 1143 |
+
outputs = self.canine(
|
| 1144 |
+
input_ids,
|
| 1145 |
+
attention_mask=attention_mask,
|
| 1146 |
+
token_type_ids=token_type_ids,
|
| 1147 |
+
position_ids=position_ids,
|
| 1148 |
+
inputs_embeds=inputs_embeds,
|
| 1149 |
+
output_attentions=output_attentions,
|
| 1150 |
+
output_hidden_states=output_hidden_states,
|
| 1151 |
+
return_dict=return_dict,
|
| 1152 |
+
)
|
| 1153 |
+
|
| 1154 |
+
pooled_output = outputs[1]
|
| 1155 |
+
|
| 1156 |
+
pooled_output = self.dropout(pooled_output)
|
| 1157 |
+
logits = self.classifier(pooled_output)
|
| 1158 |
+
reshaped_logits = logits.view(-1, num_choices)
|
| 1159 |
+
|
| 1160 |
+
loss = None
|
| 1161 |
+
if labels is not None:
|
| 1162 |
+
loss_fct = CrossEntropyLoss()
|
| 1163 |
+
loss = loss_fct(reshaped_logits, labels)
|
| 1164 |
+
|
| 1165 |
+
if not return_dict:
|
| 1166 |
+
output = (reshaped_logits,) + outputs[2:]
|
| 1167 |
+
return ((loss,) + output) if loss is not None else output
|
| 1168 |
+
|
| 1169 |
+
return MultipleChoiceModelOutput(
|
| 1170 |
+
loss=loss,
|
| 1171 |
+
logits=reshaped_logits,
|
| 1172 |
+
hidden_states=outputs.hidden_states,
|
| 1173 |
+
attentions=outputs.attentions,
|
| 1174 |
+
)
|
| 1175 |
+
|
| 1176 |
+
|
| 1177 |
+
@auto_docstring
|
| 1178 |
+
class CanineForTokenClassification(CaninePreTrainedModel):
|
| 1179 |
+
def __init__(self, config):
|
| 1180 |
+
super().__init__(config)
|
| 1181 |
+
self.num_labels = config.num_labels
|
| 1182 |
+
|
| 1183 |
+
self.canine = CanineModel(config)
|
| 1184 |
+
self.dropout = nn.Dropout(config.hidden_dropout_prob)
|
| 1185 |
+
self.classifier = nn.Linear(config.hidden_size, config.num_labels)
|
| 1186 |
+
|
| 1187 |
+
# Initialize weights and apply final processing
|
| 1188 |
+
self.post_init()
|
| 1189 |
+
|
| 1190 |
+
@auto_docstring
|
| 1191 |
+
def forward(
|
| 1192 |
+
self,
|
| 1193 |
+
input_ids: torch.LongTensor | None = None,
|
| 1194 |
+
attention_mask: torch.FloatTensor | None = None,
|
| 1195 |
+
token_type_ids: torch.LongTensor | None = None,
|
| 1196 |
+
position_ids: torch.LongTensor | None = None,
|
| 1197 |
+
inputs_embeds: torch.FloatTensor | None = None,
|
| 1198 |
+
labels: torch.LongTensor | None = None,
|
| 1199 |
+
output_attentions: bool | None = None,
|
| 1200 |
+
output_hidden_states: bool | None = None,
|
| 1201 |
+
return_dict: bool | None = None,
|
| 1202 |
+
**kwargs,
|
| 1203 |
+
) -> tuple | TokenClassifierOutput:
|
| 1204 |
+
r"""
|
| 1205 |
+
labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*):
|
| 1206 |
+
Labels for computing the token classification loss. Indices should be in `[0, ..., config.num_labels - 1]`.
|
| 1207 |
+
|
| 1208 |
+
Example:
|
| 1209 |
+
|
| 1210 |
+
```python
|
| 1211 |
+
>>> from transformers import AutoTokenizer, CanineForTokenClassification
|
| 1212 |
+
>>> import torch
|
| 1213 |
+
|
| 1214 |
+
>>> tokenizer = AutoTokenizer.from_pretrained("google/canine-s")
|
| 1215 |
+
>>> model = CanineForTokenClassification.from_pretrained("google/canine-s")
|
| 1216 |
+
|
| 1217 |
+
>>> inputs = tokenizer(
|
| 1218 |
+
... "HuggingFace is a company based in Paris and New York", add_special_tokens=False, return_tensors="pt"
|
| 1219 |
+
... )
|
| 1220 |
+
|
| 1221 |
+
>>> with torch.no_grad():
|
| 1222 |
+
... logits = model(**inputs).logits
|
| 1223 |
+
|
| 1224 |
+
>>> predicted_token_class_ids = logits.argmax(-1)
|
| 1225 |
+
|
| 1226 |
+
>>> # Note that tokens are classified rather then input words which means that
|
| 1227 |
+
>>> # there might be more predicted token classes than words.
|
| 1228 |
+
>>> # Multiple token classes might account for the same word
|
| 1229 |
+
>>> predicted_tokens_classes = [model.config.id2label[t.item()] for t in predicted_token_class_ids[0]]
|
| 1230 |
+
>>> predicted_tokens_classes # doctest: +SKIP
|
| 1231 |
+
```
|
| 1232 |
+
|
| 1233 |
+
```python
|
| 1234 |
+
>>> labels = predicted_token_class_ids
|
| 1235 |
+
>>> loss = model(**inputs, labels=labels).loss
|
| 1236 |
+
>>> round(loss.item(), 2) # doctest: +SKIP
|
| 1237 |
+
```"""
|
| 1238 |
+
return_dict = return_dict if return_dict is not None else self.config.return_dict
|
| 1239 |
+
|
| 1240 |
+
outputs = self.canine(
|
| 1241 |
+
input_ids,
|
| 1242 |
+
attention_mask=attention_mask,
|
| 1243 |
+
token_type_ids=token_type_ids,
|
| 1244 |
+
position_ids=position_ids,
|
| 1245 |
+
inputs_embeds=inputs_embeds,
|
| 1246 |
+
output_attentions=output_attentions,
|
| 1247 |
+
output_hidden_states=output_hidden_states,
|
| 1248 |
+
return_dict=return_dict,
|
| 1249 |
+
)
|
| 1250 |
+
|
| 1251 |
+
sequence_output = outputs[0]
|
| 1252 |
+
|
| 1253 |
+
sequence_output = self.dropout(sequence_output)
|
| 1254 |
+
logits = self.classifier(sequence_output)
|
| 1255 |
+
|
| 1256 |
+
loss = None
|
| 1257 |
+
if labels is not None:
|
| 1258 |
+
loss_fct = CrossEntropyLoss()
|
| 1259 |
+
loss = loss_fct(logits.view(-1, self.num_labels), labels.view(-1))
|
| 1260 |
+
|
| 1261 |
+
if not return_dict:
|
| 1262 |
+
output = (logits,) + outputs[2:]
|
| 1263 |
+
return ((loss,) + output) if loss is not None else output
|
| 1264 |
+
|
| 1265 |
+
return TokenClassifierOutput(
|
| 1266 |
+
loss=loss,
|
| 1267 |
+
logits=logits,
|
| 1268 |
+
hidden_states=outputs.hidden_states,
|
| 1269 |
+
attentions=outputs.attentions,
|
| 1270 |
+
)
|
| 1271 |
+
|
| 1272 |
+
|
| 1273 |
+
@auto_docstring
|
| 1274 |
+
class CanineForQuestionAnswering(CaninePreTrainedModel):
|
| 1275 |
+
def __init__(self, config):
|
| 1276 |
+
super().__init__(config)
|
| 1277 |
+
self.num_labels = config.num_labels
|
| 1278 |
+
|
| 1279 |
+
self.canine = CanineModel(config)
|
| 1280 |
+
self.qa_outputs = nn.Linear(config.hidden_size, config.num_labels)
|
| 1281 |
+
|
| 1282 |
+
# Initialize weights and apply final processing
|
| 1283 |
+
self.post_init()
|
| 1284 |
+
|
| 1285 |
+
@auto_docstring
|
| 1286 |
+
def forward(
|
| 1287 |
+
self,
|
| 1288 |
+
input_ids: torch.LongTensor | None = None,
|
| 1289 |
+
attention_mask: torch.FloatTensor | None = None,
|
| 1290 |
+
token_type_ids: torch.LongTensor | None = None,
|
| 1291 |
+
position_ids: torch.LongTensor | None = None,
|
| 1292 |
+
inputs_embeds: torch.FloatTensor | None = None,
|
| 1293 |
+
start_positions: torch.LongTensor | None = None,
|
| 1294 |
+
end_positions: torch.LongTensor | None = None,
|
| 1295 |
+
output_attentions: bool | None = None,
|
| 1296 |
+
output_hidden_states: bool | None = None,
|
| 1297 |
+
return_dict: bool | None = None,
|
| 1298 |
+
**kwargs,
|
| 1299 |
+
) -> tuple | QuestionAnsweringModelOutput:
|
| 1300 |
+
return_dict = return_dict if return_dict is not None else self.config.return_dict
|
| 1301 |
+
|
| 1302 |
+
outputs = self.canine(
|
| 1303 |
+
input_ids,
|
| 1304 |
+
attention_mask=attention_mask,
|
| 1305 |
+
token_type_ids=token_type_ids,
|
| 1306 |
+
position_ids=position_ids,
|
| 1307 |
+
inputs_embeds=inputs_embeds,
|
| 1308 |
+
output_attentions=output_attentions,
|
| 1309 |
+
output_hidden_states=output_hidden_states,
|
| 1310 |
+
return_dict=return_dict,
|
| 1311 |
+
)
|
| 1312 |
+
|
| 1313 |
+
sequence_output = outputs[0]
|
| 1314 |
+
|
| 1315 |
+
logits = self.qa_outputs(sequence_output)
|
| 1316 |
+
start_logits, end_logits = logits.split(1, dim=-1)
|
| 1317 |
+
start_logits = start_logits.squeeze(-1)
|
| 1318 |
+
end_logits = end_logits.squeeze(-1)
|
| 1319 |
+
|
| 1320 |
+
total_loss = None
|
| 1321 |
+
if start_positions is not None and end_positions is not None:
|
| 1322 |
+
# If we are on multi-GPU, split add a dimension
|
| 1323 |
+
if len(start_positions.size()) > 1:
|
| 1324 |
+
start_positions = start_positions.squeeze(-1)
|
| 1325 |
+
if len(end_positions.size()) > 1:
|
| 1326 |
+
end_positions = end_positions.squeeze(-1)
|
| 1327 |
+
# sometimes the start/end positions are outside our model inputs, we ignore these terms
|
| 1328 |
+
ignored_index = start_logits.size(1)
|
| 1329 |
+
start_positions.clamp_(0, ignored_index)
|
| 1330 |
+
end_positions.clamp_(0, ignored_index)
|
| 1331 |
+
|
| 1332 |
+
loss_fct = CrossEntropyLoss(ignore_index=ignored_index)
|
| 1333 |
+
start_loss = loss_fct(start_logits, start_positions)
|
| 1334 |
+
end_loss = loss_fct(end_logits, end_positions)
|
| 1335 |
+
total_loss = (start_loss + end_loss) / 2
|
| 1336 |
+
|
| 1337 |
+
if not return_dict:
|
| 1338 |
+
output = (start_logits, end_logits) + outputs[2:]
|
| 1339 |
+
return ((total_loss,) + output) if total_loss is not None else output
|
| 1340 |
+
|
| 1341 |
+
return QuestionAnsweringModelOutput(
|
| 1342 |
+
loss=total_loss,
|
| 1343 |
+
start_logits=start_logits,
|
| 1344 |
+
end_logits=end_logits,
|
| 1345 |
+
hidden_states=outputs.hidden_states,
|
| 1346 |
+
attentions=outputs.attentions,
|
| 1347 |
+
)
|
| 1348 |
+
|
| 1349 |
+
|
| 1350 |
+
__all__ = [
|
| 1351 |
+
"CanineForMultipleChoice",
|
| 1352 |
+
"CanineForQuestionAnswering",
|
| 1353 |
+
"CanineForSequenceClassification",
|
| 1354 |
+
"CanineForTokenClassification",
|
| 1355 |
+
"CanineLayer",
|
| 1356 |
+
"CanineModel",
|
| 1357 |
+
"CaninePreTrainedModel",
|
| 1358 |
+
]
|
third_party/transformers/src/transformers/models/canine/tokenization_canine.py
ADDED
|
@@ -0,0 +1,156 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright Google AI and The HuggingFace Inc. team. All rights reserved.
|
| 2 |
+
#
|
| 3 |
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
| 4 |
+
# you may not use this file except in compliance with the License.
|
| 5 |
+
# You may obtain a copy of the License at
|
| 6 |
+
#
|
| 7 |
+
# http://www.apache.org/licenses/LICENSE-2.0
|
| 8 |
+
#
|
| 9 |
+
# Unless required by applicable law or agreed to in writing, software
|
| 10 |
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
| 11 |
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 12 |
+
# See the License for the specific language governing permissions and
|
| 13 |
+
# limitations under the License.
|
| 14 |
+
"""Tokenization classes for CANINE."""
|
| 15 |
+
|
| 16 |
+
from ...tokenization_python import AddedToken, PreTrainedTokenizer
|
| 17 |
+
from ...utils import logging
|
| 18 |
+
|
| 19 |
+
|
| 20 |
+
logger = logging.get_logger(__name__)
|
| 21 |
+
|
| 22 |
+
|
| 23 |
+
# Unicode defines 1,114,112 total “codepoints”
|
| 24 |
+
UNICODE_VOCAB_SIZE = 1114112
|
| 25 |
+
|
| 26 |
+
# Below: Constants defining canonical codepoints for special, pseudo-characters.
|
| 27 |
+
# Copied from https://github.com/google-research/language/blob/master/language/canine/special_codepoints.py
|
| 28 |
+
PAD = 0
|
| 29 |
+
CLS = 0xE000
|
| 30 |
+
SEP = 0xE001
|
| 31 |
+
BOS = 0xE002
|
| 32 |
+
MASK = 0xE003
|
| 33 |
+
RESERVED = 0xE004
|
| 34 |
+
|
| 35 |
+
# Maps special codepoints to human-readable names.
|
| 36 |
+
SPECIAL_CODEPOINTS: dict[int, str] = {
|
| 37 |
+
# Special symbols are represented using codepoints values that are valid,
|
| 38 |
+
# but designated as "Private Use", meaning that they will never be assigned
|
| 39 |
+
# characters by the Unicode Consortium, and are thus safe for use here.
|
| 40 |
+
#
|
| 41 |
+
# NOTE: Do *NOT* add any sort of [UNK_CHAR] here. They are explicitly
|
| 42 |
+
# excluded and should fail with a hard error.
|
| 43 |
+
CLS: "[CLS]",
|
| 44 |
+
SEP: "[SEP]",
|
| 45 |
+
BOS: "[BOS]",
|
| 46 |
+
MASK: "[MASK]",
|
| 47 |
+
PAD: "[PAD]",
|
| 48 |
+
RESERVED: "[RESERVED]",
|
| 49 |
+
}
|
| 50 |
+
|
| 51 |
+
# Maps special codepoint human-readable names to their codepoint values.
|
| 52 |
+
SPECIAL_CODEPOINTS_BY_NAME: dict[str, int] = {name: codepoint for codepoint, name in SPECIAL_CODEPOINTS.items()}
|
| 53 |
+
|
| 54 |
+
|
| 55 |
+
class CanineTokenizer(PreTrainedTokenizer):
|
| 56 |
+
r"""
|
| 57 |
+
Construct a CANINE tokenizer (i.e. a character splitter). It turns text into a sequence of characters, and then
|
| 58 |
+
converts each character into its Unicode code point.
|
| 59 |
+
|
| 60 |
+
[`CanineTokenizer`] inherits from [`PreTrainedTokenizer`].
|
| 61 |
+
|
| 62 |
+
Refer to superclass [`PreTrainedTokenizer`] for usage examples and documentation concerning parameters.
|
| 63 |
+
|
| 64 |
+
Args:
|
| 65 |
+
model_max_length (`int`, *optional*, defaults to 2048):
|
| 66 |
+
The maximum sentence length the model accepts.
|
| 67 |
+
"""
|
| 68 |
+
|
| 69 |
+
model_input_names = ["input_ids", "attention_mask", "token_type_ids"]
|
| 70 |
+
|
| 71 |
+
def __init__(
|
| 72 |
+
self,
|
| 73 |
+
bos_token=chr(CLS),
|
| 74 |
+
eos_token=chr(SEP),
|
| 75 |
+
sep_token=chr(SEP),
|
| 76 |
+
cls_token=chr(CLS),
|
| 77 |
+
pad_token=chr(PAD),
|
| 78 |
+
mask_token=chr(MASK),
|
| 79 |
+
add_prefix_space=False,
|
| 80 |
+
model_max_length=2048,
|
| 81 |
+
**kwargs,
|
| 82 |
+
):
|
| 83 |
+
bos_token = AddedToken(bos_token, lstrip=False, rstrip=False) if isinstance(bos_token, str) else bos_token
|
| 84 |
+
eos_token = AddedToken(eos_token, lstrip=False, rstrip=False) if isinstance(eos_token, str) else eos_token
|
| 85 |
+
sep_token = AddedToken(sep_token, lstrip=False, rstrip=False) if isinstance(sep_token, str) else sep_token
|
| 86 |
+
cls_token = AddedToken(cls_token, lstrip=False, rstrip=False) if isinstance(cls_token, str) else cls_token
|
| 87 |
+
pad_token = AddedToken(pad_token, lstrip=False, rstrip=False) if isinstance(pad_token, str) else pad_token
|
| 88 |
+
|
| 89 |
+
# Mask token behave like a normal word, i.e. include the space before it
|
| 90 |
+
mask_token = AddedToken(mask_token, lstrip=True, rstrip=False) if isinstance(mask_token, str) else mask_token
|
| 91 |
+
|
| 92 |
+
# Creates a mapping for looking up the IDs of special symbols.
|
| 93 |
+
self._special_codepoints: dict[str, int] = {}
|
| 94 |
+
for codepoint, name in SPECIAL_CODEPOINTS.items():
|
| 95 |
+
self._special_codepoints[name] = codepoint
|
| 96 |
+
|
| 97 |
+
# Creates a mapping for looking up the string forms of special symbol IDs.
|
| 98 |
+
self._special_codepoint_strings: dict[int, str] = {
|
| 99 |
+
codepoint: name for name, codepoint in self._special_codepoints.items()
|
| 100 |
+
}
|
| 101 |
+
|
| 102 |
+
self._unicode_vocab_size = UNICODE_VOCAB_SIZE
|
| 103 |
+
self._num_special_tokens = len(self._special_codepoints)
|
| 104 |
+
|
| 105 |
+
super().__init__(
|
| 106 |
+
bos_token=bos_token,
|
| 107 |
+
eos_token=eos_token,
|
| 108 |
+
sep_token=sep_token,
|
| 109 |
+
cls_token=cls_token,
|
| 110 |
+
pad_token=pad_token,
|
| 111 |
+
mask_token=mask_token,
|
| 112 |
+
add_prefix_space=add_prefix_space,
|
| 113 |
+
model_max_length=model_max_length,
|
| 114 |
+
token_type_ids_pattern="all_zeros",
|
| 115 |
+
token_type_ids_include_special_tokens=True,
|
| 116 |
+
special_tokens_pattern="cls_sep",
|
| 117 |
+
**kwargs,
|
| 118 |
+
)
|
| 119 |
+
|
| 120 |
+
@property
|
| 121 |
+
def vocab_size(self) -> int:
|
| 122 |
+
return self._unicode_vocab_size
|
| 123 |
+
|
| 124 |
+
def get_vocab(self):
|
| 125 |
+
vocab = {chr(i): i for i in range(self.vocab_size)}
|
| 126 |
+
vocab.update(self.added_tokens_encoder)
|
| 127 |
+
return vocab
|
| 128 |
+
|
| 129 |
+
def _tokenize(self, text: str) -> list[str]:
|
| 130 |
+
"""Tokenize a string (i.e. perform character splitting)."""
|
| 131 |
+
return list(text)
|
| 132 |
+
|
| 133 |
+
def _convert_token_to_id(self, token: str) -> int:
|
| 134 |
+
"""Converts a token (i.e. a Unicode character) in an id (i.e. its integer Unicode code point value)."""
|
| 135 |
+
try:
|
| 136 |
+
return ord(token)
|
| 137 |
+
except TypeError:
|
| 138 |
+
raise ValueError(f"invalid token: '{token}'")
|
| 139 |
+
|
| 140 |
+
def _convert_id_to_token(self, index: int) -> str:
|
| 141 |
+
"""
|
| 142 |
+
Converts a Unicode code point (integer) in a token (str). In case it's a special code point, convert to
|
| 143 |
+
human-readable format.
|
| 144 |
+
"""
|
| 145 |
+
try:
|
| 146 |
+
if index in SPECIAL_CODEPOINTS:
|
| 147 |
+
return SPECIAL_CODEPOINTS[index]
|
| 148 |
+
return chr(index)
|
| 149 |
+
except TypeError:
|
| 150 |
+
raise ValueError(f"invalid id: {index}")
|
| 151 |
+
|
| 152 |
+
def convert_tokens_to_string(self, tokens):
|
| 153 |
+
return "".join(tokens)
|
| 154 |
+
|
| 155 |
+
|
| 156 |
+
__all__ = ["CanineTokenizer"]
|
third_party/transformers/src/transformers/models/code_llama/__init__.py
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright 2024 The HuggingFace Team. All rights reserved.
|
| 2 |
+
#
|
| 3 |
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
| 4 |
+
# you may not use this file except in compliance with the License.
|
| 5 |
+
# You may obtain a copy of the License at
|
| 6 |
+
#
|
| 7 |
+
# http://www.apache.org/licenses/LICENSE-2.0
|
| 8 |
+
#
|
| 9 |
+
# Unless required by applicable law or agreed to in writing, software
|
| 10 |
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
| 11 |
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 12 |
+
# See the License for the specific language governing permissions and
|
| 13 |
+
# limitations under the License.
|
| 14 |
+
from typing import TYPE_CHECKING
|
| 15 |
+
|
| 16 |
+
from ...utils import _LazyModule
|
| 17 |
+
from ...utils.import_utils import define_import_structure
|
| 18 |
+
|
| 19 |
+
|
| 20 |
+
if TYPE_CHECKING:
|
| 21 |
+
from .tokenization_code_llama import *
|
| 22 |
+
else:
|
| 23 |
+
import sys
|
| 24 |
+
|
| 25 |
+
_file = globals()["__file__"]
|
| 26 |
+
sys.modules[__name__] = _LazyModule(__name__, _file, define_import_structure(_file), module_spec=__spec__)
|
third_party/transformers/src/transformers/models/code_llama/tokenization_code_llama.py
ADDED
|
@@ -0,0 +1,358 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright 2023 The HuggingFace Inc. team.
|
| 2 |
+
#
|
| 3 |
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
| 4 |
+
# you may not use this file except in compliance with the License.
|
| 5 |
+
# You may obtain a copy of the License at
|
| 6 |
+
#
|
| 7 |
+
# http://www.apache.org/licenses/LICENSE-2.0
|
| 8 |
+
#
|
| 9 |
+
# Unless required by applicable law or agreed to in writing, software
|
| 10 |
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
| 11 |
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 12 |
+
# See the License for the specific language governing permissions and
|
| 13 |
+
# limitations under the License.
|
| 14 |
+
|
| 15 |
+
|
| 16 |
+
from tokenizers import Tokenizer, decoders, normalizers, pre_tokenizers, processors
|
| 17 |
+
from tokenizers.models import BPE
|
| 18 |
+
|
| 19 |
+
from ...tokenization_utils_tokenizers import TokenizersBackend
|
| 20 |
+
from ...utils import logging
|
| 21 |
+
|
| 22 |
+
|
| 23 |
+
logger = logging.get_logger(__name__)
|
| 24 |
+
VOCAB_FILES_NAMES = {"vocab_file": "tokenizer.model", "tokenizer_file": "tokenizer.json"}
|
| 25 |
+
|
| 26 |
+
SPIECE_UNDERLINE = "▁"
|
| 27 |
+
|
| 28 |
+
B_INST, E_INST = "[INST]", "[/INST]"
|
| 29 |
+
B_SYS, E_SYS = "<<SYS>>\n", "\n<</SYS>>\n\n"
|
| 30 |
+
|
| 31 |
+
# fmt: off
|
| 32 |
+
DEFAULT_SYSTEM_PROMPT = """You are a helpful, respectful and honest assistant. Always answer as helpfully as possible, while being safe. Your \
|
| 33 |
+
answers should not include any harmful, unethical, racist, sexist, toxic, dangerous, or illegal content. Please ensure\
|
| 34 |
+
that your responses are socially unbiased and positive in nature.
|
| 35 |
+
|
| 36 |
+
If a question does not make any sense, or is not factually coherent, explain why instead of answering something not \
|
| 37 |
+
correct. If you don't know the answer to a question, please don't share false information."""
|
| 38 |
+
# fmt: on
|
| 39 |
+
|
| 40 |
+
|
| 41 |
+
class CodeLlamaTokenizer(TokenizersBackend):
|
| 42 |
+
"""
|
| 43 |
+
Construct a Llama tokenizer. Based on byte-level Byte-Pair-Encoding.
|
| 44 |
+
|
| 45 |
+
This uses notably ByteFallback and no normalization.
|
| 46 |
+
|
| 47 |
+
```python
|
| 48 |
+
>>> from transformers import CodeLlamaTokenizer
|
| 49 |
+
|
| 50 |
+
>>> tokenizer = CodeLlamaTokenizer.from_pretrained("hf-internal-testing/llama-tokenizer")
|
| 51 |
+
>>> tokenizer.encode("Hello this is a test")
|
| 52 |
+
[1, 15043, 445, 338, 263, 1243]
|
| 53 |
+
```
|
| 54 |
+
|
| 55 |
+
If you want to change the `bos_token` or the `eos_token`, make sure to specify them when initializing the model, or
|
| 56 |
+
call `tokenizer.update_post_processor()` to make sure that the post-processing is correctly done (otherwise the
|
| 57 |
+
values of the first token and final token of an encoded sequence will not be correct). For more details, checkout
|
| 58 |
+
[post-processors] (https://huggingface.co/docs/tokenizers/api/post-processors) documentation.
|
| 59 |
+
|
| 60 |
+
|
| 61 |
+
This tokenizer inherits from [`PreTrainedTokenizerFast`] which contains most of the main methods. Users should
|
| 62 |
+
refer to this superclass for more information regarding those methods. The default configuration match that of
|
| 63 |
+
[meta-llama/CodeLlama-7b-Instruct-hf](https://huggingface.co/meta-llama/CodeLlama-7b-Instruct-hf/blob/main/tokenizer_config.json)
|
| 64 |
+
which supports prompt infilling.
|
| 65 |
+
|
| 66 |
+
Args:
|
| 67 |
+
clean_up_tokenization_spaces (`str`, *optional*, defaults to `False`):
|
| 68 |
+
Whether to cleanup spaces after decoding, cleanup consists in removing potential artifacts like extra
|
| 69 |
+
spaces.
|
| 70 |
+
unk_token (`str`, *optional*, defaults to `"<unk>"`):
|
| 71 |
+
The unknown token. A token that is not in the vocabulary cannot be converted to an ID and is set to be this
|
| 72 |
+
token instead.
|
| 73 |
+
bos_token (`str`, *optional*, defaults to `"<s>"`):
|
| 74 |
+
The beginning of sequence token that was used during pretraining. Can be used a sequence classifier token.
|
| 75 |
+
eos_token (`str`, *optional*, defaults to `"</s>"`):
|
| 76 |
+
The end of sequence token.
|
| 77 |
+
prefix_token (`str`, *optional*, defaults to `"▁<PRE>"`):
|
| 78 |
+
Prefix token used for infilling.
|
| 79 |
+
middle_token (`str`, *optional*, defaults to `"▁<MID>"`):
|
| 80 |
+
Middle token used for infilling.
|
| 81 |
+
suffix_token (`str`, *optional*, defaults to `"▁<SUF>"`):
|
| 82 |
+
Suffix token used for infilling.
|
| 83 |
+
eot_token (`str`, *optional*, defaults to `"▁<EOT>"`):
|
| 84 |
+
End of text token used for infilling.
|
| 85 |
+
fill_token (`str`, *optional*, defaults to `"<FILL_ME>"`):
|
| 86 |
+
The token used to split the input between the prefix and suffix.
|
| 87 |
+
additional_special_tokens (`list[str]`, *optional*):
|
| 88 |
+
Additional special tokens used by the tokenizer.
|
| 89 |
+
add_bos_token (`bool`, *optional*, defaults to `True`):
|
| 90 |
+
Whether to add a beginning of sequence token at the start of sequences.
|
| 91 |
+
add_eos_token (`bool`, *optional*, defaults to `False`):
|
| 92 |
+
Whether to add an end of sequence token at the end of sequences.
|
| 93 |
+
use_default_system_prompt (`bool`, *optional*, defaults to `False`):
|
| 94 |
+
Whether or not the default system prompt for Llama should be used.
|
| 95 |
+
add_prefix_space (`bool`, *optional*):
|
| 96 |
+
Whether or not to add an initial space to the input. This allows to treat the leading word just as any
|
| 97 |
+
other word.
|
| 98 |
+
vocab (`str`, `dict` or `list`, *optional*):
|
| 99 |
+
Custom vocabulary dictionary. If not provided, vocabulary is loaded from vocab_file.
|
| 100 |
+
merges (`str` or `list`, *optional*):
|
| 101 |
+
Custom merges list. If not provided, merges are loaded from merges_file.
|
| 102 |
+
vocab_file (`str`, *optional*):
|
| 103 |
+
[SentencePiece](https://github.com/google/sentencepiece) file (generally has a .model extension) that
|
| 104 |
+
contains the vocabulary necessary to instantiate a tokenizer.
|
| 105 |
+
"""
|
| 106 |
+
|
| 107 |
+
vocab_files_names = VOCAB_FILES_NAMES
|
| 108 |
+
padding_side = "left"
|
| 109 |
+
model_input_names = ["input_ids", "attention_mask"]
|
| 110 |
+
model = BPE
|
| 111 |
+
|
| 112 |
+
def __init__(
|
| 113 |
+
self,
|
| 114 |
+
vocab: str | dict[str, int] | None = None,
|
| 115 |
+
merges: str | list[str] | None = None,
|
| 116 |
+
clean_up_tokenization_spaces=False,
|
| 117 |
+
unk_token="<unk>",
|
| 118 |
+
bos_token="<s>",
|
| 119 |
+
eos_token="</s>",
|
| 120 |
+
prefix_token="▁<PRE>",
|
| 121 |
+
middle_token="▁<MID>",
|
| 122 |
+
suffix_token="▁<SUF>",
|
| 123 |
+
eot_token="▁<EOT>",
|
| 124 |
+
fill_token="<FILL_ME>",
|
| 125 |
+
additional_special_tokens=None,
|
| 126 |
+
use_default_system_prompt: bool = False,
|
| 127 |
+
add_prefix_space: bool | None = True,
|
| 128 |
+
add_bos_token: bool = True,
|
| 129 |
+
**kwargs,
|
| 130 |
+
):
|
| 131 |
+
self.add_prefix_space = add_prefix_space if add_prefix_space is not None else True
|
| 132 |
+
self.use_default_system_prompt = use_default_system_prompt
|
| 133 |
+
additional_special_tokens = additional_special_tokens or []
|
| 134 |
+
for token in [prefix_token, middle_token, suffix_token, eot_token, fill_token]:
|
| 135 |
+
additional_special_tokens += [token] if token is not None else []
|
| 136 |
+
|
| 137 |
+
self._vocab = (
|
| 138 |
+
vocab
|
| 139 |
+
if vocab is not None
|
| 140 |
+
else {
|
| 141 |
+
str(unk_token): 0,
|
| 142 |
+
str(bos_token): 1,
|
| 143 |
+
str(eos_token): 2,
|
| 144 |
+
}
|
| 145 |
+
)
|
| 146 |
+
|
| 147 |
+
self._merges = merges or []
|
| 148 |
+
self._tokenizer = Tokenizer(
|
| 149 |
+
BPE(
|
| 150 |
+
vocab=self._vocab,
|
| 151 |
+
merges=self._merges,
|
| 152 |
+
fuse_unk=True,
|
| 153 |
+
byte_fallback=True,
|
| 154 |
+
dropout=None,
|
| 155 |
+
unk_token=str(unk_token),
|
| 156 |
+
)
|
| 157 |
+
)
|
| 158 |
+
prepend_scheme = "first" if self.add_prefix_space else "never"
|
| 159 |
+
self._tokenizer.pre_tokenizer = pre_tokenizers.Metaspace(
|
| 160 |
+
replacement="▁", prepend_scheme=prepend_scheme, split=False
|
| 161 |
+
)
|
| 162 |
+
|
| 163 |
+
self._tokenizer.decoder = decoders.Sequence(
|
| 164 |
+
[decoders.Replace("▁", " "), decoders.ByteFallback(), decoders.Fuse(), decoders.Strip(content=" ", left=1)]
|
| 165 |
+
)
|
| 166 |
+
|
| 167 |
+
super().__init__(
|
| 168 |
+
clean_up_tokenization_spaces=clean_up_tokenization_spaces,
|
| 169 |
+
unk_token=unk_token,
|
| 170 |
+
bos_token=bos_token,
|
| 171 |
+
eos_token=eos_token,
|
| 172 |
+
use_default_system_prompt=use_default_system_prompt,
|
| 173 |
+
add_prefix_space=add_prefix_space,
|
| 174 |
+
prefix_token=prefix_token,
|
| 175 |
+
middle_token=middle_token,
|
| 176 |
+
suffix_token=suffix_token,
|
| 177 |
+
eot_token=eot_token,
|
| 178 |
+
fill_token=fill_token,
|
| 179 |
+
add_bos_token=add_bos_token,
|
| 180 |
+
additional_special_tokens=additional_special_tokens,
|
| 181 |
+
**kwargs,
|
| 182 |
+
)
|
| 183 |
+
self._prefix_token = prefix_token
|
| 184 |
+
self._middle_token = middle_token
|
| 185 |
+
self._suffix_token = suffix_token
|
| 186 |
+
self._eot_token = eot_token
|
| 187 |
+
self.fill_token = fill_token
|
| 188 |
+
|
| 189 |
+
@property
|
| 190 |
+
def prefix_token(self):
|
| 191 |
+
return self._prefix_token
|
| 192 |
+
|
| 193 |
+
@property
|
| 194 |
+
def prefix_id(self):
|
| 195 |
+
if self._prefix_token is None:
|
| 196 |
+
return None
|
| 197 |
+
return self.convert_tokens_to_ids(self.prefix_token)
|
| 198 |
+
|
| 199 |
+
@property
|
| 200 |
+
def middle_token(self):
|
| 201 |
+
return self._middle_token
|
| 202 |
+
|
| 203 |
+
@property
|
| 204 |
+
def middle_id(self):
|
| 205 |
+
if self._middle_token is None:
|
| 206 |
+
return None
|
| 207 |
+
return self.convert_tokens_to_ids(self.middle_token)
|
| 208 |
+
|
| 209 |
+
@property
|
| 210 |
+
def suffix_token(self):
|
| 211 |
+
return self._suffix_token
|
| 212 |
+
|
| 213 |
+
@property
|
| 214 |
+
def suffix_id(self):
|
| 215 |
+
if self._suffix_token is None:
|
| 216 |
+
return None
|
| 217 |
+
return self.convert_tokens_to_ids(self.suffix_token)
|
| 218 |
+
|
| 219 |
+
@property
|
| 220 |
+
def eot_id(self):
|
| 221 |
+
if self._eot_token is None:
|
| 222 |
+
return None
|
| 223 |
+
return self.convert_tokens_to_ids(self.eot_token)
|
| 224 |
+
|
| 225 |
+
@property
|
| 226 |
+
def eot_token(self):
|
| 227 |
+
return self._eot_token
|
| 228 |
+
|
| 229 |
+
def set_infilling_processor(self, reset, suffix_first=False, add_special_tokens=True):
|
| 230 |
+
"""
|
| 231 |
+
Updates the normalizer to make sure the prompt format for `infilling` is respected. The infilling format is the
|
| 232 |
+
following: if suffix_first
|
| 233 |
+
" <PRE> <SUF>{suf} <MID> {pre}"
|
| 234 |
+
else:
|
| 235 |
+
" <PRE> {pre} <SUF>{suf} <MID>"
|
| 236 |
+
|
| 237 |
+
If `reset` is set to `True`, the `normalizer` and `post_processor` are reset to their "normal" behaviour, which
|
| 238 |
+
is to add a prefix space for the normalizer, and add a `bos_token` to the input text for the `post_processor`.
|
| 239 |
+
"""
|
| 240 |
+
if reset:
|
| 241 |
+
self._tokenizer.normalizer = normalizers.Sequence(
|
| 242 |
+
[
|
| 243 |
+
normalizers.Prepend(prepend="▁"),
|
| 244 |
+
normalizers.Replace(pattern=" ", content="▁"),
|
| 245 |
+
]
|
| 246 |
+
)
|
| 247 |
+
self.update_post_processor()
|
| 248 |
+
return
|
| 249 |
+
|
| 250 |
+
self._tokenizer.normalizer = normalizers.Replace(pattern=" ", content="▁")
|
| 251 |
+
pair = [self.bos_token] if self.add_bos_token and add_special_tokens else []
|
| 252 |
+
special_tokens = [(self.bos_token, self.bos_token_id)] if self.add_bos_token and add_special_tokens else []
|
| 253 |
+
if suffix_first:
|
| 254 |
+
# format as " <PRE> <SUF>{suf} <MID> {pre}"
|
| 255 |
+
pair += [self.prefix_token, self.suffix_token, "$B", self.middle_token, "$A"]
|
| 256 |
+
special_tokens += [
|
| 257 |
+
(self.prefix_token, self.prefix_id),
|
| 258 |
+
(self.suffix_token, self.suffix_id),
|
| 259 |
+
(self.middle_token, self.middle_id),
|
| 260 |
+
]
|
| 261 |
+
else:
|
| 262 |
+
# format as " <PRE> {pre} <SUF>{suf} <MID>"
|
| 263 |
+
pair += [self.prefix_token, "$A", self.suffix_token, "$B", self.middle_token]
|
| 264 |
+
special_tokens += [
|
| 265 |
+
(self.prefix_token, self.prefix_id),
|
| 266 |
+
(self.suffix_token, self.suffix_id),
|
| 267 |
+
(self.middle_token, self.middle_id),
|
| 268 |
+
]
|
| 269 |
+
|
| 270 |
+
if self.add_eos_token and add_special_tokens:
|
| 271 |
+
pair += [self.eos_token]
|
| 272 |
+
special_tokens += [(self.eos_token, self.eos_token_id)]
|
| 273 |
+
self._tokenizer.post_processor = processors.TemplateProcessing(
|
| 274 |
+
single="$A", pair=pair, special_tokens=special_tokens
|
| 275 |
+
)
|
| 276 |
+
|
| 277 |
+
def tokenize(self, text, suffix=None, suffix_first=False, **kwargs):
|
| 278 |
+
# Handle fill_token splitting
|
| 279 |
+
if self.fill_token is not None and self.fill_token in text and suffix is None:
|
| 280 |
+
text, suffix = text.split(self.fill_token)
|
| 281 |
+
|
| 282 |
+
# If no suffix, use standard tokenization
|
| 283 |
+
if suffix is None or len(suffix) < 1:
|
| 284 |
+
return super().tokenize(text, **kwargs)
|
| 285 |
+
|
| 286 |
+
# Check that infilling tokens are available
|
| 287 |
+
if None in (self.prefix_id, self.middle_id, self.suffix_id):
|
| 288 |
+
raise ValueError(
|
| 289 |
+
"The input either includes a `prefix` and a `suffix` used for the infilling task,"
|
| 290 |
+
f" or can be split on the {self.fill_token} token, creating a suffix and prefix,"
|
| 291 |
+
" but the model does not support `infilling`."
|
| 292 |
+
)
|
| 293 |
+
|
| 294 |
+
# Temporarily set infilling processor
|
| 295 |
+
self.set_infilling_processor(False, suffix_first=suffix_first, add_special_tokens=False)
|
| 296 |
+
|
| 297 |
+
# Remove text_pair and pair from kwargs if present to avoid conflict
|
| 298 |
+
kwargs.pop("text_pair", None)
|
| 299 |
+
kwargs.pop("pair", None)
|
| 300 |
+
|
| 301 |
+
# Tokenize with infilling format
|
| 302 |
+
# The processor will handle the special token arrangement
|
| 303 |
+
# Use pair=suffix (not text_pair) since base class tokenize expects 'pair' parameter
|
| 304 |
+
result = super().tokenize(" " + text, pair=suffix, **kwargs)
|
| 305 |
+
|
| 306 |
+
# Reset processor
|
| 307 |
+
self.set_infilling_processor(True)
|
| 308 |
+
|
| 309 |
+
return result
|
| 310 |
+
|
| 311 |
+
def _encode_plus(self, text, text_pair=None, suffix=None, suffix_first=False, add_special_tokens=True, **kwargs):
|
| 312 |
+
is_infilling = False
|
| 313 |
+
|
| 314 |
+
if suffix is not None:
|
| 315 |
+
text_pair = suffix
|
| 316 |
+
is_infilling = True
|
| 317 |
+
elif "suffix" in kwargs:
|
| 318 |
+
text_pair = kwargs.pop("suffix")
|
| 319 |
+
is_infilling = True
|
| 320 |
+
|
| 321 |
+
if isinstance(text, str) and self.fill_token is not None and self.fill_token in text and text_pair is None:
|
| 322 |
+
text, text_pair = text.split(self.fill_token)
|
| 323 |
+
is_infilling = True
|
| 324 |
+
|
| 325 |
+
if not is_infilling:
|
| 326 |
+
return super()._encode_plus(text, text_pair=text_pair, add_special_tokens=add_special_tokens, **kwargs)
|
| 327 |
+
|
| 328 |
+
if (
|
| 329 |
+
text_pair is None
|
| 330 |
+
or (isinstance(text_pair, str) and len(text_pair) < 1)
|
| 331 |
+
or (isinstance(text_pair, list) and len(text_pair) == 0)
|
| 332 |
+
):
|
| 333 |
+
return super()._encode_plus(text, text_pair=text_pair, add_special_tokens=add_special_tokens, **kwargs)
|
| 334 |
+
|
| 335 |
+
if None in (self.prefix_id, self.middle_id, self.suffix_id):
|
| 336 |
+
raise ValueError(
|
| 337 |
+
"The input includes a `prefix` and a `suffix` used for the infilling task,"
|
| 338 |
+
" the `prefix_id, middle_id, suffix_id` must all be initialized. Current"
|
| 339 |
+
f" values : {self.prefix_id, self.middle_id, self.suffix_id}"
|
| 340 |
+
)
|
| 341 |
+
|
| 342 |
+
self.set_infilling_processor(False, suffix_first=suffix_first, add_special_tokens=add_special_tokens)
|
| 343 |
+
kwargs.pop("text_pair", None)
|
| 344 |
+
|
| 345 |
+
if isinstance(text, str):
|
| 346 |
+
text = " " + text
|
| 347 |
+
elif isinstance(text, list):
|
| 348 |
+
text = [" " + t if isinstance(t, str) else t for t in text]
|
| 349 |
+
|
| 350 |
+
result = super()._encode_plus(text, text_pair=text_pair, add_special_tokens=True, **kwargs)
|
| 351 |
+
self.set_infilling_processor(True)
|
| 352 |
+
return result
|
| 353 |
+
|
| 354 |
+
|
| 355 |
+
__all__ = ["CodeLlamaTokenizer", "CodeLlamaTokenizerFast"]
|
| 356 |
+
|
| 357 |
+
# Backward alias
|
| 358 |
+
CodeLlamaTokenizerFast = CodeLlamaTokenizer
|
third_party/transformers/src/transformers/models/cohere/__init__.py
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright 2024 The HuggingFace Team. All rights reserved.
|
| 2 |
+
#
|
| 3 |
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
| 4 |
+
# you may not use this file except in compliance with the License.
|
| 5 |
+
# You may obtain a copy of the License at
|
| 6 |
+
#
|
| 7 |
+
# http://www.apache.org/licenses/LICENSE-2.0
|
| 8 |
+
#
|
| 9 |
+
# Unless required by applicable law or agreed to in writing, software
|
| 10 |
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
| 11 |
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 12 |
+
# See the License for the specific language governing permissions and
|
| 13 |
+
# limitations under the License.
|
| 14 |
+
from typing import TYPE_CHECKING
|
| 15 |
+
|
| 16 |
+
from ...utils import _LazyModule
|
| 17 |
+
from ...utils.import_utils import define_import_structure
|
| 18 |
+
|
| 19 |
+
|
| 20 |
+
if TYPE_CHECKING:
|
| 21 |
+
from .configuration_cohere import *
|
| 22 |
+
from .modeling_cohere import *
|
| 23 |
+
from .tokenization_cohere import *
|
| 24 |
+
else:
|
| 25 |
+
import sys
|
| 26 |
+
|
| 27 |
+
_file = globals()["__file__"]
|
| 28 |
+
sys.modules[__name__] = _LazyModule(__name__, _file, define_import_structure(_file), module_spec=__spec__)
|
third_party/transformers/src/transformers/models/cohere/configuration_cohere.py
ADDED
|
@@ -0,0 +1,94 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright 2024 Cohere team. All rights reserved.
|
| 2 |
+
#
|
| 3 |
+
# This code is based on EleutherAI's GPT-NeoX library and the GPT-NeoX
|
| 4 |
+
# and OPT implementations in this library. It has been modified from its
|
| 5 |
+
# original forms to accommodate minor architectural differences compared
|
| 6 |
+
# to GPT-NeoX and OPT used by the Meta AI team that trained the model.
|
| 7 |
+
#
|
| 8 |
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
| 9 |
+
# you may not use this file except in compliance with the License.
|
| 10 |
+
# You may obtain a copy of the License at
|
| 11 |
+
#
|
| 12 |
+
# http://www.apache.org/licenses/LICENSE-2.0
|
| 13 |
+
#
|
| 14 |
+
# Unless required by applicable law or agreed to in writing, software
|
| 15 |
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
| 16 |
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 17 |
+
# See the License for the specific language governing permissions and
|
| 18 |
+
# limitations under the License.
|
| 19 |
+
"""Cohere model configuration"""
|
| 20 |
+
|
| 21 |
+
from huggingface_hub.dataclasses import strict
|
| 22 |
+
|
| 23 |
+
from ...configuration_utils import PreTrainedConfig
|
| 24 |
+
from ...modeling_rope_utils import RopeParameters
|
| 25 |
+
from ...utils import auto_docstring
|
| 26 |
+
|
| 27 |
+
|
| 28 |
+
@auto_docstring(checkpoint="CohereForAI/c4ai-command-r-v01")
|
| 29 |
+
@strict
|
| 30 |
+
class CohereConfig(PreTrainedConfig):
|
| 31 |
+
r"""
|
| 32 |
+
logit_scale (`float`, *optional*, defaults to 0.0625):
|
| 33 |
+
The scaling factor for the output logits.
|
| 34 |
+
|
| 35 |
+
```python
|
| 36 |
+
>>> from transformers import CohereModel, CohereConfig
|
| 37 |
+
|
| 38 |
+
>>> # Initializing a Cohere model configuration
|
| 39 |
+
>>> configuration = CohereConfig()
|
| 40 |
+
|
| 41 |
+
>>> # Initializing a model from the Cohere configuration
|
| 42 |
+
>>> model = CohereModel(configuration) # doctest: +SKIP
|
| 43 |
+
|
| 44 |
+
>>> # Accessing the model configuration
|
| 45 |
+
>>> configuration = model.config # doctest: +SKIP
|
| 46 |
+
```
|
| 47 |
+
"""
|
| 48 |
+
|
| 49 |
+
model_type = "cohere"
|
| 50 |
+
keys_to_ignore_at_inference = ["past_key_values"]
|
| 51 |
+
default_theta = 500000.0
|
| 52 |
+
base_model_tp_plan = {
|
| 53 |
+
"layers.*.self_attn.q_proj": "colwise",
|
| 54 |
+
"layers.*.self_attn.k_proj": "colwise",
|
| 55 |
+
"layers.*.self_attn.v_proj": "colwise",
|
| 56 |
+
"layers.*.self_attn.o_proj": "rowwise",
|
| 57 |
+
"layers.*.mlp.gate_proj": "colwise",
|
| 58 |
+
"layers.*.mlp.up_proj": "colwise",
|
| 59 |
+
"layers.*.mlp.down_proj": "rowwise",
|
| 60 |
+
}
|
| 61 |
+
base_model_pp_plan = {
|
| 62 |
+
"embed_tokens": (["input_ids"], ["inputs_embeds"]),
|
| 63 |
+
"layers": (["hidden_states", "attention_mask"], ["hidden_states"]),
|
| 64 |
+
"norm": (["hidden_states"], ["hidden_states"]),
|
| 65 |
+
}
|
| 66 |
+
vocab_size: int = 256000
|
| 67 |
+
hidden_size: int = 8192
|
| 68 |
+
intermediate_size: int = 22528
|
| 69 |
+
logit_scale: float | None = 0.0625
|
| 70 |
+
num_hidden_layers: int = 40
|
| 71 |
+
num_attention_heads: int = 64
|
| 72 |
+
num_key_value_heads: int | None = None
|
| 73 |
+
hidden_act: str = "silu"
|
| 74 |
+
max_position_embeddings: int = 8192
|
| 75 |
+
initializer_range: float = 0.02
|
| 76 |
+
layer_norm_eps: float | None = 1e-5
|
| 77 |
+
use_cache: bool = True
|
| 78 |
+
pad_token_id: int | None = 0
|
| 79 |
+
bos_token_id: int | None = 5
|
| 80 |
+
eos_token_id: int | list[int] | None = 255001
|
| 81 |
+
tie_word_embeddings: bool = True
|
| 82 |
+
rope_parameters: RopeParameters | dict | None = None
|
| 83 |
+
attention_bias: bool = False
|
| 84 |
+
attention_dropout: float | int | None = 0.0
|
| 85 |
+
use_qk_norm: bool | None = False
|
| 86 |
+
|
| 87 |
+
def __post_init__(self, **kwargs):
|
| 88 |
+
if self.num_key_value_heads is None:
|
| 89 |
+
self.num_key_value_heads = self.num_attention_heads
|
| 90 |
+
|
| 91 |
+
super().__post_init__(**kwargs)
|
| 92 |
+
|
| 93 |
+
|
| 94 |
+
__all__ = ["CohereConfig"]
|
third_party/transformers/src/transformers/models/cohere/modeling_cohere.py
ADDED
|
@@ -0,0 +1,530 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨
|
| 2 |
+
# This file was automatically generated from src/transformers/models/cohere/modular_cohere.py.
|
| 3 |
+
# Do NOT edit this file manually as any edits will be overwritten by the generation of
|
| 4 |
+
# the file from the modular. If any change should be done, please apply the change to the
|
| 5 |
+
# modular_cohere.py file directly. One of our CI enforces this.
|
| 6 |
+
# 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨
|
| 7 |
+
# Copyright 2024 Cohere team. All rights reserved.
|
| 8 |
+
#
|
| 9 |
+
# This code is based on EleutherAI's GPT-NeoX library and the GPT-NeoX
|
| 10 |
+
# and OPT implementations in this library. It has been modified from its
|
| 11 |
+
# original forms to accommodate minor architectural differences compared
|
| 12 |
+
# to GPT-NeoX and OPT used by the Meta AI team that trained the model.
|
| 13 |
+
#
|
| 14 |
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
| 15 |
+
# you may not use this file except in compliance with the License.
|
| 16 |
+
# You may obtain a copy of the License at
|
| 17 |
+
#
|
| 18 |
+
# http://www.apache.org/licenses/LICENSE-2.0
|
| 19 |
+
#
|
| 20 |
+
# Unless required by applicable law or agreed to in writing, software
|
| 21 |
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
| 22 |
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 23 |
+
# See the License for the specific language governing permissions and
|
| 24 |
+
# limitations under the License.
|
| 25 |
+
|
| 26 |
+
# This file is based on the LLama model definition file in transformers
|
| 27 |
+
|
| 28 |
+
|
| 29 |
+
from collections.abc import Callable
|
| 30 |
+
from typing import Optional
|
| 31 |
+
|
| 32 |
+
import torch
|
| 33 |
+
from torch import nn
|
| 34 |
+
|
| 35 |
+
from ...activations import ACT2FN
|
| 36 |
+
from ...cache_utils import Cache, DynamicCache
|
| 37 |
+
from ...generation import GenerationMixin
|
| 38 |
+
from ...integrations import use_kernelized_func
|
| 39 |
+
from ...masking_utils import create_causal_mask
|
| 40 |
+
from ...modeling_flash_attention_utils import FlashAttentionKwargs
|
| 41 |
+
from ...modeling_layers import GradientCheckpointingLayer
|
| 42 |
+
from ...modeling_outputs import BaseModelOutputWithPast, CausalLMOutputWithPast
|
| 43 |
+
from ...modeling_rope_utils import ROPE_INIT_FUNCTIONS, dynamic_rope_update
|
| 44 |
+
from ...modeling_utils import ALL_ATTENTION_FUNCTIONS, PreTrainedModel
|
| 45 |
+
from ...processing_utils import Unpack
|
| 46 |
+
from ...utils import TransformersKwargs, auto_docstring, can_return_tuple
|
| 47 |
+
from ...utils.generic import maybe_autocast, merge_with_config_defaults
|
| 48 |
+
from ...utils.output_capturing import capture_outputs
|
| 49 |
+
from .configuration_cohere import CohereConfig
|
| 50 |
+
|
| 51 |
+
|
| 52 |
+
class CohereLayerNorm(nn.Module):
|
| 53 |
+
def __init__(self, hidden_size=None, eps=1e-5, bias=False):
|
| 54 |
+
"""The hidden size can be a tuple or an int. The tuple is used for QKNorm to normalize across head_dim"""
|
| 55 |
+
super().__init__()
|
| 56 |
+
self.weight = nn.Parameter(torch.ones(hidden_size))
|
| 57 |
+
self.variance_epsilon = eps
|
| 58 |
+
|
| 59 |
+
def forward(self, hidden_states):
|
| 60 |
+
input_dtype = hidden_states.dtype
|
| 61 |
+
hidden_states = hidden_states.to(torch.float32)
|
| 62 |
+
mean = hidden_states.mean(-1, keepdim=True)
|
| 63 |
+
variance = (hidden_states - mean).pow(2).mean(-1, keepdim=True)
|
| 64 |
+
hidden_states = (hidden_states - mean) * torch.rsqrt(variance + self.variance_epsilon)
|
| 65 |
+
hidden_states = self.weight.to(torch.float32) * hidden_states
|
| 66 |
+
return hidden_states.to(input_dtype)
|
| 67 |
+
|
| 68 |
+
|
| 69 |
+
class CohereRotaryEmbedding(nn.Module):
|
| 70 |
+
inv_freq: torch.Tensor # fix linting for `register_buffer`
|
| 71 |
+
|
| 72 |
+
def __init__(self, config: CohereConfig, device=None):
|
| 73 |
+
super().__init__()
|
| 74 |
+
self.max_seq_len_cached = config.max_position_embeddings
|
| 75 |
+
self.original_max_seq_len = config.max_position_embeddings
|
| 76 |
+
|
| 77 |
+
self.config = config
|
| 78 |
+
|
| 79 |
+
self.rope_type = self.config.rope_parameters["rope_type"]
|
| 80 |
+
rope_init_fn: Callable = self.compute_default_rope_parameters
|
| 81 |
+
if self.rope_type != "default":
|
| 82 |
+
rope_init_fn = ROPE_INIT_FUNCTIONS[self.rope_type]
|
| 83 |
+
inv_freq, self.attention_scaling = rope_init_fn(self.config, device)
|
| 84 |
+
|
| 85 |
+
self.register_buffer("inv_freq", inv_freq, persistent=False)
|
| 86 |
+
self.register_buffer("original_inv_freq", inv_freq.clone(), persistent=False)
|
| 87 |
+
|
| 88 |
+
@staticmethod
|
| 89 |
+
def compute_default_rope_parameters(
|
| 90 |
+
config: CohereConfig | None = None,
|
| 91 |
+
device: Optional["torch.device"] = None,
|
| 92 |
+
seq_len: int | None = None,
|
| 93 |
+
) -> tuple["torch.Tensor", float]:
|
| 94 |
+
"""
|
| 95 |
+
Computes the inverse frequencies according to the original RoPE implementation
|
| 96 |
+
Args:
|
| 97 |
+
config ([`~transformers.PreTrainedConfig`]):
|
| 98 |
+
The model configuration.
|
| 99 |
+
device (`torch.device`):
|
| 100 |
+
The device to use for initialization of the inverse frequencies.
|
| 101 |
+
seq_len (`int`, *optional*):
|
| 102 |
+
The current sequence length. Unused for this type of RoPE.
|
| 103 |
+
Returns:
|
| 104 |
+
Tuple of (`torch.Tensor`, `float`), containing the inverse frequencies for the RoPE embeddings and the
|
| 105 |
+
post-processing scaling factor applied to the computed cos/sin (unused in this type of RoPE).
|
| 106 |
+
"""
|
| 107 |
+
base = config.rope_parameters["rope_theta"]
|
| 108 |
+
dim = getattr(config, "head_dim", None) or config.hidden_size // config.num_attention_heads
|
| 109 |
+
|
| 110 |
+
attention_factor = 1.0 # Unused in this type of RoPE
|
| 111 |
+
|
| 112 |
+
# Compute the inverse frequencies
|
| 113 |
+
inv_freq = 1.0 / (
|
| 114 |
+
base ** (torch.arange(0, dim, 2, dtype=torch.int64).to(device=device, dtype=torch.float) / dim)
|
| 115 |
+
)
|
| 116 |
+
return inv_freq, attention_factor
|
| 117 |
+
|
| 118 |
+
@torch.no_grad()
|
| 119 |
+
@dynamic_rope_update # power user: used with advanced RoPE types (e.g. dynamic rope)
|
| 120 |
+
def forward(self, x, position_ids):
|
| 121 |
+
inv_freq_expanded = self.inv_freq[None, :, None].float().expand(position_ids.shape[0], -1, 1)
|
| 122 |
+
position_ids_expanded = position_ids[:, None, :].float()
|
| 123 |
+
|
| 124 |
+
device_type = x.device.type if isinstance(x.device.type, str) and x.device.type != "mps" else "cpu"
|
| 125 |
+
with maybe_autocast(device_type=device_type, enabled=False): # Force float32
|
| 126 |
+
freqs = (inv_freq_expanded.float() @ position_ids_expanded.float()).transpose(1, 2)
|
| 127 |
+
emb = torch.repeat_interleave(freqs, 2, dim=-1) # diff from Llama: we interleave() instead of cat()
|
| 128 |
+
cos = emb.cos() * self.attention_scaling
|
| 129 |
+
sin = emb.sin() * self.attention_scaling
|
| 130 |
+
|
| 131 |
+
return cos.to(dtype=x.dtype), sin.to(dtype=x.dtype)
|
| 132 |
+
|
| 133 |
+
|
| 134 |
+
class CohereMLP(nn.Module):
|
| 135 |
+
def __init__(self, config):
|
| 136 |
+
super().__init__()
|
| 137 |
+
self.config = config
|
| 138 |
+
self.hidden_size = config.hidden_size
|
| 139 |
+
self.intermediate_size = config.intermediate_size
|
| 140 |
+
self.gate_proj = nn.Linear(self.hidden_size, self.intermediate_size, bias=False)
|
| 141 |
+
self.up_proj = nn.Linear(self.hidden_size, self.intermediate_size, bias=False)
|
| 142 |
+
self.down_proj = nn.Linear(self.intermediate_size, self.hidden_size, bias=False)
|
| 143 |
+
self.act_fn = ACT2FN[config.hidden_act]
|
| 144 |
+
|
| 145 |
+
def forward(self, x):
|
| 146 |
+
down_proj = self.down_proj(self.act_fn(self.gate_proj(x)) * self.up_proj(x))
|
| 147 |
+
return down_proj
|
| 148 |
+
|
| 149 |
+
|
| 150 |
+
def repeat_kv(hidden_states: torch.Tensor, n_rep: int) -> torch.Tensor:
|
| 151 |
+
"""
|
| 152 |
+
This is the equivalent of torch.repeat_interleave(x, dim=1, repeats=n_rep). The hidden states go from (batch,
|
| 153 |
+
num_key_value_heads, seqlen, head_dim) to (batch, num_attention_heads, seqlen, head_dim)
|
| 154 |
+
"""
|
| 155 |
+
batch, num_key_value_heads, slen, head_dim = hidden_states.shape
|
| 156 |
+
if n_rep == 1:
|
| 157 |
+
return hidden_states
|
| 158 |
+
hidden_states = hidden_states[:, :, None, :, :].expand(batch, num_key_value_heads, n_rep, slen, head_dim)
|
| 159 |
+
return hidden_states.reshape(batch, num_key_value_heads * n_rep, slen, head_dim)
|
| 160 |
+
|
| 161 |
+
|
| 162 |
+
def eager_attention_forward(
|
| 163 |
+
module: nn.Module,
|
| 164 |
+
query: torch.Tensor,
|
| 165 |
+
key: torch.Tensor,
|
| 166 |
+
value: torch.Tensor,
|
| 167 |
+
attention_mask: torch.Tensor | None,
|
| 168 |
+
scaling: float,
|
| 169 |
+
dropout: float = 0.0,
|
| 170 |
+
**kwargs: Unpack[TransformersKwargs],
|
| 171 |
+
):
|
| 172 |
+
key_states = repeat_kv(key, module.num_key_value_groups)
|
| 173 |
+
value_states = repeat_kv(value, module.num_key_value_groups)
|
| 174 |
+
|
| 175 |
+
attn_weights = torch.matmul(query, key_states.transpose(2, 3)) * scaling
|
| 176 |
+
if attention_mask is not None:
|
| 177 |
+
attn_weights = attn_weights + attention_mask
|
| 178 |
+
|
| 179 |
+
attn_weights = nn.functional.softmax(attn_weights, dim=-1, dtype=torch.float32).to(query.dtype)
|
| 180 |
+
attn_weights = nn.functional.dropout(attn_weights, p=dropout, training=module.training)
|
| 181 |
+
attn_output = torch.matmul(attn_weights, value_states)
|
| 182 |
+
attn_output = attn_output.transpose(1, 2).contiguous()
|
| 183 |
+
|
| 184 |
+
return attn_output, attn_weights
|
| 185 |
+
|
| 186 |
+
|
| 187 |
+
def rotate_half(x):
|
| 188 |
+
# Split and rotate. Note that this function is different from e.g. Llama.
|
| 189 |
+
x1 = x[..., ::2]
|
| 190 |
+
x2 = x[..., 1::2]
|
| 191 |
+
rot_x = torch.stack([-x2, x1], dim=-1).flatten(-2)
|
| 192 |
+
return rot_x
|
| 193 |
+
|
| 194 |
+
|
| 195 |
+
def apply_rotary_pos_emb(q, k, cos, sin, unsqueeze_dim=1):
|
| 196 |
+
"""Applies Rotary Position Embedding to the query and key tensors.
|
| 197 |
+
|
| 198 |
+
Args:
|
| 199 |
+
q (`torch.Tensor`): The query tensor.
|
| 200 |
+
k (`torch.Tensor`): The key tensor.
|
| 201 |
+
cos (`torch.Tensor`): The cosine part of the rotary embedding.
|
| 202 |
+
sin (`torch.Tensor`): The sine part of the rotary embedding.
|
| 203 |
+
unsqueeze_dim (`int`, *optional*, defaults to 1):
|
| 204 |
+
The 'unsqueeze_dim' argument specifies the dimension along which to unsqueeze cos[position_ids] and
|
| 205 |
+
sin[position_ids] so that they can be properly broadcasted to the dimensions of q and k. For example, note
|
| 206 |
+
that cos[position_ids] and sin[position_ids] have the shape [batch_size, seq_len, head_dim]. Then, if q and
|
| 207 |
+
k have the shape [batch_size, heads, seq_len, head_dim], then setting unsqueeze_dim=1 makes
|
| 208 |
+
cos[position_ids] and sin[position_ids] broadcastable to the shapes of q and k. Similarly, if q and k have
|
| 209 |
+
the shape [batch_size, seq_len, heads, head_dim], then set unsqueeze_dim=2.
|
| 210 |
+
Returns:
|
| 211 |
+
`tuple(torch.Tensor)` comprising of the query and key tensors rotated using the Rotary Position Embedding.
|
| 212 |
+
"""
|
| 213 |
+
dtype = q.dtype
|
| 214 |
+
q = q.float()
|
| 215 |
+
k = k.float()
|
| 216 |
+
cos = cos.unsqueeze(unsqueeze_dim)
|
| 217 |
+
sin = sin.unsqueeze(unsqueeze_dim)
|
| 218 |
+
q_embed = (q * cos) + (rotate_half(q) * sin)
|
| 219 |
+
k_embed = (k * cos) + (rotate_half(k) * sin)
|
| 220 |
+
return q_embed.to(dtype=dtype), k_embed.to(dtype=dtype)
|
| 221 |
+
|
| 222 |
+
|
| 223 |
+
@use_kernelized_func(apply_rotary_pos_emb)
|
| 224 |
+
class CohereAttention(nn.Module):
|
| 225 |
+
"""Multi-headed attention from 'Attention Is All You Need' paper"""
|
| 226 |
+
|
| 227 |
+
def __init__(self, config: CohereConfig, layer_idx: int | None = None):
|
| 228 |
+
super().__init__()
|
| 229 |
+
self.config = config
|
| 230 |
+
self.layer_idx = layer_idx
|
| 231 |
+
self.head_dim = getattr(config, "head_dim", config.hidden_size // config.num_attention_heads)
|
| 232 |
+
self.num_key_value_groups = config.num_attention_heads // config.num_key_value_heads
|
| 233 |
+
self.scaling = self.head_dim**-0.5
|
| 234 |
+
self.attention_dropout = config.attention_dropout
|
| 235 |
+
self.is_causal = True
|
| 236 |
+
|
| 237 |
+
self.q_proj = nn.Linear(
|
| 238 |
+
config.hidden_size, config.num_attention_heads * self.head_dim, bias=config.attention_bias
|
| 239 |
+
)
|
| 240 |
+
self.k_proj = nn.Linear(
|
| 241 |
+
config.hidden_size, config.num_key_value_heads * self.head_dim, bias=config.attention_bias
|
| 242 |
+
)
|
| 243 |
+
self.v_proj = nn.Linear(
|
| 244 |
+
config.hidden_size, config.num_key_value_heads * self.head_dim, bias=config.attention_bias
|
| 245 |
+
)
|
| 246 |
+
self.o_proj = nn.Linear(
|
| 247 |
+
config.num_attention_heads * self.head_dim, config.hidden_size, bias=config.attention_bias
|
| 248 |
+
)
|
| 249 |
+
self.use_qk_norm = config.use_qk_norm
|
| 250 |
+
if self.use_qk_norm:
|
| 251 |
+
# When sharding the model using Tensor Parallelism, need to be careful to use n_local_heads
|
| 252 |
+
self.q_norm = CohereLayerNorm(
|
| 253 |
+
hidden_size=(config.num_attention_heads, self.head_dim), eps=config.layer_norm_eps
|
| 254 |
+
)
|
| 255 |
+
self.k_norm = CohereLayerNorm(
|
| 256 |
+
hidden_size=(config.num_key_value_heads, self.head_dim), eps=config.layer_norm_eps
|
| 257 |
+
)
|
| 258 |
+
|
| 259 |
+
def forward(
|
| 260 |
+
self,
|
| 261 |
+
hidden_states: torch.Tensor,
|
| 262 |
+
position_embeddings: tuple[torch.Tensor, torch.Tensor],
|
| 263 |
+
attention_mask: torch.Tensor | None,
|
| 264 |
+
past_key_values: Cache | None = None,
|
| 265 |
+
**kwargs: Unpack[FlashAttentionKwargs],
|
| 266 |
+
) -> tuple[torch.Tensor, torch.Tensor | None]:
|
| 267 |
+
input_shape = hidden_states.shape[:-1]
|
| 268 |
+
hidden_shape = (*input_shape, -1, self.head_dim)
|
| 269 |
+
|
| 270 |
+
query_states = self.q_proj(hidden_states).view(hidden_shape)
|
| 271 |
+
key_states = self.k_proj(hidden_states).view(hidden_shape)
|
| 272 |
+
value_states = self.v_proj(hidden_states).view(hidden_shape)
|
| 273 |
+
|
| 274 |
+
if self.use_qk_norm: # main diff from Llama
|
| 275 |
+
query_states = self.q_norm(query_states)
|
| 276 |
+
key_states = self.k_norm(key_states)
|
| 277 |
+
|
| 278 |
+
query_states = query_states.transpose(1, 2)
|
| 279 |
+
key_states = key_states.transpose(1, 2)
|
| 280 |
+
value_states = value_states.transpose(1, 2)
|
| 281 |
+
|
| 282 |
+
cos, sin = position_embeddings
|
| 283 |
+
query_states, key_states = apply_rotary_pos_emb(query_states, key_states, cos, sin)
|
| 284 |
+
|
| 285 |
+
if past_key_values is not None:
|
| 286 |
+
key_states, value_states = past_key_values.update(key_states, value_states, self.layer_idx)
|
| 287 |
+
|
| 288 |
+
attention_interface: Callable = ALL_ATTENTION_FUNCTIONS.get_interface(
|
| 289 |
+
self.config._attn_implementation, eager_attention_forward
|
| 290 |
+
)
|
| 291 |
+
|
| 292 |
+
attn_output, attn_weights = attention_interface(
|
| 293 |
+
self,
|
| 294 |
+
query_states,
|
| 295 |
+
key_states,
|
| 296 |
+
value_states,
|
| 297 |
+
attention_mask,
|
| 298 |
+
dropout=0.0 if not self.training else self.attention_dropout,
|
| 299 |
+
scaling=self.scaling,
|
| 300 |
+
**kwargs,
|
| 301 |
+
)
|
| 302 |
+
|
| 303 |
+
attn_output = attn_output.reshape(*input_shape, -1).contiguous()
|
| 304 |
+
attn_output = self.o_proj(attn_output)
|
| 305 |
+
return attn_output, attn_weights
|
| 306 |
+
|
| 307 |
+
|
| 308 |
+
class CohereDecoderLayer(GradientCheckpointingLayer):
|
| 309 |
+
def __init__(self, config: CohereConfig, layer_idx: int):
|
| 310 |
+
super().__init__()
|
| 311 |
+
self.hidden_size = config.hidden_size
|
| 312 |
+
self.self_attn = CohereAttention(config=config, layer_idx=layer_idx)
|
| 313 |
+
self.mlp = CohereMLP(config)
|
| 314 |
+
self.input_layernorm = CohereLayerNorm(hidden_size=(config.hidden_size), eps=config.layer_norm_eps)
|
| 315 |
+
|
| 316 |
+
def forward(
|
| 317 |
+
self,
|
| 318 |
+
hidden_states: torch.Tensor,
|
| 319 |
+
attention_mask: torch.Tensor | None = None,
|
| 320 |
+
position_ids: torch.LongTensor | None = None,
|
| 321 |
+
past_key_values: Cache | None = None,
|
| 322 |
+
use_cache: bool | None = False,
|
| 323 |
+
position_embeddings: tuple[torch.Tensor, torch.Tensor] | None = None,
|
| 324 |
+
**kwargs: Unpack[FlashAttentionKwargs],
|
| 325 |
+
) -> tuple[torch.FloatTensor, tuple[torch.FloatTensor, torch.FloatTensor] | None]:
|
| 326 |
+
"""
|
| 327 |
+
Args:
|
| 328 |
+
hidden_states (`torch.FloatTensor`): input to the layer of shape `(batch, seq_len, embed_dim)`
|
| 329 |
+
attention_mask (`torch.FloatTensor`, *optional*):
|
| 330 |
+
attention mask of size `(batch_size, sequence_length)` if flash attention is used or `(batch_size, 1,
|
| 331 |
+
query_sequence_length, key_sequence_length)` if default attention is used.
|
| 332 |
+
past_key_values (`Cache`, *optional*): cached past key and value projection states
|
| 333 |
+
output_attentions (`bool`, *optional*):
|
| 334 |
+
Whether or not to return the attentions tensors of all attention layers. See `attentions` under
|
| 335 |
+
returned tensors for more detail.
|
| 336 |
+
use_cache (`bool`, *optional*):
|
| 337 |
+
If set to `True`, `past_key_values` key value states are returned and can be used to speed up decoding
|
| 338 |
+
(see `past_key_values`).
|
| 339 |
+
position_embeddings (`tuple[torch.FloatTensor, torch.FloatTensor]`, *optional*):
|
| 340 |
+
Tuple containing the cosine and sine positional embeddings of shape `(batch_size, seq_len, head_dim)`,
|
| 341 |
+
with `head_dim` being the embedding dimension of each attention head.
|
| 342 |
+
"""
|
| 343 |
+
residual = hidden_states
|
| 344 |
+
hidden_states = self.input_layernorm(hidden_states)
|
| 345 |
+
|
| 346 |
+
hidden_states_attention, _ = self.self_attn(
|
| 347 |
+
hidden_states=hidden_states,
|
| 348 |
+
attention_mask=attention_mask,
|
| 349 |
+
position_ids=position_ids,
|
| 350 |
+
past_key_values=past_key_values,
|
| 351 |
+
use_cache=use_cache,
|
| 352 |
+
position_embeddings=position_embeddings,
|
| 353 |
+
**kwargs,
|
| 354 |
+
)
|
| 355 |
+
|
| 356 |
+
hidden_states_mlp = self.mlp(hidden_states)
|
| 357 |
+
hidden_states = residual + hidden_states_attention + hidden_states_mlp
|
| 358 |
+
return hidden_states
|
| 359 |
+
|
| 360 |
+
|
| 361 |
+
@auto_docstring
|
| 362 |
+
class CoherePreTrainedModel(PreTrainedModel):
|
| 363 |
+
config: CohereConfig
|
| 364 |
+
base_model_prefix = "model"
|
| 365 |
+
supports_gradient_checkpointing = True
|
| 366 |
+
_no_split_modules = ["CohereDecoderLayer"]
|
| 367 |
+
_skip_keys_device_placement = ["past_key_values"]
|
| 368 |
+
_supports_flash_attn = True
|
| 369 |
+
_supports_sdpa = True
|
| 370 |
+
_supports_flex_attn = True
|
| 371 |
+
|
| 372 |
+
_can_compile_fullgraph = True
|
| 373 |
+
_supports_attention_backend = True
|
| 374 |
+
_can_record_outputs = {
|
| 375 |
+
"hidden_states": CohereDecoderLayer,
|
| 376 |
+
"attentions": CohereAttention,
|
| 377 |
+
}
|
| 378 |
+
|
| 379 |
+
|
| 380 |
+
@auto_docstring
|
| 381 |
+
class CohereModel(CoherePreTrainedModel):
|
| 382 |
+
def __init__(self, config: CohereConfig):
|
| 383 |
+
super().__init__(config)
|
| 384 |
+
self.padding_idx = config.pad_token_id
|
| 385 |
+
self.vocab_size = config.vocab_size
|
| 386 |
+
|
| 387 |
+
self.embed_tokens = nn.Embedding(config.vocab_size, config.hidden_size, self.padding_idx)
|
| 388 |
+
self.layers = nn.ModuleList(
|
| 389 |
+
[CohereDecoderLayer(config, layer_idx) for layer_idx in range(config.num_hidden_layers)]
|
| 390 |
+
)
|
| 391 |
+
self.norm = CohereLayerNorm(hidden_size=(config.hidden_size), eps=config.layer_norm_eps)
|
| 392 |
+
self.rotary_emb = CohereRotaryEmbedding(config=config)
|
| 393 |
+
self.gradient_checkpointing = False
|
| 394 |
+
|
| 395 |
+
# Initialize weights and apply final processing
|
| 396 |
+
self.post_init()
|
| 397 |
+
|
| 398 |
+
@merge_with_config_defaults
|
| 399 |
+
@capture_outputs
|
| 400 |
+
@auto_docstring
|
| 401 |
+
def forward(
|
| 402 |
+
self,
|
| 403 |
+
input_ids: torch.LongTensor | None = None,
|
| 404 |
+
attention_mask: torch.Tensor | None = None,
|
| 405 |
+
position_ids: torch.LongTensor | None = None,
|
| 406 |
+
past_key_values: Cache | None = None,
|
| 407 |
+
inputs_embeds: torch.FloatTensor | None = None,
|
| 408 |
+
use_cache: bool | None = None,
|
| 409 |
+
**kwargs: Unpack[TransformersKwargs],
|
| 410 |
+
) -> BaseModelOutputWithPast:
|
| 411 |
+
if (input_ids is None) ^ (inputs_embeds is not None):
|
| 412 |
+
raise ValueError("You must specify exactly one of input_ids or inputs_embeds")
|
| 413 |
+
|
| 414 |
+
if inputs_embeds is None:
|
| 415 |
+
inputs_embeds: torch.Tensor = self.embed_tokens(input_ids)
|
| 416 |
+
|
| 417 |
+
if use_cache and past_key_values is None:
|
| 418 |
+
past_key_values = DynamicCache(config=self.config)
|
| 419 |
+
|
| 420 |
+
if position_ids is None:
|
| 421 |
+
past_seen_tokens = past_key_values.get_seq_length() if past_key_values is not None else 0
|
| 422 |
+
position_ids = torch.arange(inputs_embeds.shape[1], device=inputs_embeds.device) + past_seen_tokens
|
| 423 |
+
position_ids = position_ids.unsqueeze(0)
|
| 424 |
+
|
| 425 |
+
causal_mask = create_causal_mask(
|
| 426 |
+
config=self.config,
|
| 427 |
+
inputs_embeds=inputs_embeds,
|
| 428 |
+
attention_mask=attention_mask,
|
| 429 |
+
past_key_values=past_key_values,
|
| 430 |
+
position_ids=position_ids,
|
| 431 |
+
)
|
| 432 |
+
|
| 433 |
+
hidden_states = inputs_embeds
|
| 434 |
+
position_embeddings = self.rotary_emb(hidden_states, position_ids=position_ids)
|
| 435 |
+
|
| 436 |
+
for decoder_layer in self.layers[: self.config.num_hidden_layers]:
|
| 437 |
+
hidden_states = decoder_layer(
|
| 438 |
+
hidden_states,
|
| 439 |
+
attention_mask=causal_mask,
|
| 440 |
+
position_embeddings=position_embeddings,
|
| 441 |
+
position_ids=position_ids,
|
| 442 |
+
past_key_values=past_key_values,
|
| 443 |
+
use_cache=use_cache,
|
| 444 |
+
**kwargs,
|
| 445 |
+
)
|
| 446 |
+
|
| 447 |
+
hidden_states = self.norm(hidden_states)
|
| 448 |
+
return BaseModelOutputWithPast(
|
| 449 |
+
last_hidden_state=hidden_states,
|
| 450 |
+
past_key_values=past_key_values,
|
| 451 |
+
)
|
| 452 |
+
|
| 453 |
+
|
| 454 |
+
@auto_docstring
|
| 455 |
+
class CohereForCausalLM(CoherePreTrainedModel, GenerationMixin):
|
| 456 |
+
_tied_weights_keys = {"lm_head.weight": "model.embed_tokens.weight"}
|
| 457 |
+
_tp_plan = {"lm_head": "colwise_gather_output"}
|
| 458 |
+
_pp_plan = {"lm_head": (["hidden_states"], ["logits"])}
|
| 459 |
+
|
| 460 |
+
def __init__(self, config):
|
| 461 |
+
super().__init__(config)
|
| 462 |
+
self.model = CohereModel(config)
|
| 463 |
+
self.vocab_size = config.vocab_size
|
| 464 |
+
self.lm_head = nn.Linear(config.hidden_size, config.vocab_size, bias=False)
|
| 465 |
+
self.logit_scale = config.logit_scale
|
| 466 |
+
self.tie_word_embeddings = config.tie_word_embeddings
|
| 467 |
+
|
| 468 |
+
# Initialize weights and apply final processing
|
| 469 |
+
self.post_init()
|
| 470 |
+
|
| 471 |
+
@can_return_tuple
|
| 472 |
+
@auto_docstring
|
| 473 |
+
def forward(
|
| 474 |
+
self,
|
| 475 |
+
input_ids: torch.LongTensor | None = None,
|
| 476 |
+
attention_mask: torch.Tensor | None = None,
|
| 477 |
+
position_ids: torch.LongTensor | None = None,
|
| 478 |
+
past_key_values: Cache | None = None,
|
| 479 |
+
inputs_embeds: torch.FloatTensor | None = None,
|
| 480 |
+
labels: torch.LongTensor | None = None,
|
| 481 |
+
use_cache: bool | None = None,
|
| 482 |
+
logits_to_keep: int | torch.Tensor = 0,
|
| 483 |
+
**kwargs: Unpack[TransformersKwargs],
|
| 484 |
+
) -> CausalLMOutputWithPast:
|
| 485 |
+
r"""
|
| 486 |
+
Example:
|
| 487 |
+
|
| 488 |
+
```python
|
| 489 |
+
>> from transformers import AutoTokenizer, CohereForCausalLM
|
| 490 |
+
|
| 491 |
+
>> model = CohereForCausalLM.from_pretrained("CohereForAI/c4ai-command-r-v01")
|
| 492 |
+
>> tokenizer = AutoTokenizer.from_pretrained("CohereForAI/c4ai-command-r-v01")
|
| 493 |
+
|
| 494 |
+
>> prompt = "Hey, are you conscious? Can you talk to me?"
|
| 495 |
+
>> inputs = tokenizer(prompt, return_tensors="pt")
|
| 496 |
+
|
| 497 |
+
>> # Generate
|
| 498 |
+
>> generate_ids = model.generate(inputs.input_ids, max_length=30)
|
| 499 |
+
>> tokenizer.batch_decode(generate_ids, skip_special_tokens=True, clean_up_tokenization_spaces=False)[0]
|
| 500 |
+
"Hey, are you conscious? Can you talk to me?\nI'm not conscious, but I can talk to you."
|
| 501 |
+
```"""
|
| 502 |
+
outputs: BaseModelOutputWithPast = self.model(
|
| 503 |
+
input_ids=input_ids,
|
| 504 |
+
attention_mask=attention_mask,
|
| 505 |
+
position_ids=position_ids,
|
| 506 |
+
past_key_values=past_key_values,
|
| 507 |
+
inputs_embeds=inputs_embeds,
|
| 508 |
+
use_cache=use_cache,
|
| 509 |
+
**kwargs,
|
| 510 |
+
)
|
| 511 |
+
|
| 512 |
+
hidden_states = outputs.last_hidden_state
|
| 513 |
+
slice_indices = slice(-logits_to_keep, None) if isinstance(logits_to_keep, int) else logits_to_keep
|
| 514 |
+
logits = self.lm_head(hidden_states[:, slice_indices, :])
|
| 515 |
+
logits = logits * self.logit_scale # main diff from Llama
|
| 516 |
+
|
| 517 |
+
loss = None
|
| 518 |
+
if labels is not None:
|
| 519 |
+
loss = self.loss_function(logits=logits, labels=labels, vocab_size=self.config.vocab_size, **kwargs)
|
| 520 |
+
|
| 521 |
+
return CausalLMOutputWithPast(
|
| 522 |
+
loss=loss,
|
| 523 |
+
logits=logits,
|
| 524 |
+
past_key_values=outputs.past_key_values,
|
| 525 |
+
hidden_states=outputs.hidden_states,
|
| 526 |
+
attentions=outputs.attentions,
|
| 527 |
+
)
|
| 528 |
+
|
| 529 |
+
|
| 530 |
+
__all__ = ["CohereForCausalLM", "CohereModel", "CoherePreTrainedModel"]
|
third_party/transformers/src/transformers/models/cohere/modular_cohere.py
ADDED
|
@@ -0,0 +1,326 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright 2024 Cohere team. All rights reserved.
|
| 2 |
+
#
|
| 3 |
+
# This code is based on EleutherAI's GPT-NeoX library and the GPT-NeoX
|
| 4 |
+
# and OPT implementations in this library. It has been modified from its
|
| 5 |
+
# original forms to accommodate minor architectural differences compared
|
| 6 |
+
# to GPT-NeoX and OPT used by the Meta AI team that trained the model.
|
| 7 |
+
#
|
| 8 |
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
| 9 |
+
# you may not use this file except in compliance with the License.
|
| 10 |
+
# You may obtain a copy of the License at
|
| 11 |
+
#
|
| 12 |
+
# http://www.apache.org/licenses/LICENSE-2.0
|
| 13 |
+
#
|
| 14 |
+
# Unless required by applicable law or agreed to in writing, software
|
| 15 |
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
| 16 |
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 17 |
+
# See the License for the specific language governing permissions and
|
| 18 |
+
# limitations under the License.
|
| 19 |
+
|
| 20 |
+
# This file is based on the LLama model definition file in transformers
|
| 21 |
+
|
| 22 |
+
"""PyTorch Cohere model."""
|
| 23 |
+
|
| 24 |
+
from collections.abc import Callable
|
| 25 |
+
|
| 26 |
+
import torch
|
| 27 |
+
from torch import nn
|
| 28 |
+
|
| 29 |
+
from ...cache_utils import Cache
|
| 30 |
+
from ...modeling_flash_attention_utils import FlashAttentionKwargs
|
| 31 |
+
from ...modeling_layers import GradientCheckpointingLayer
|
| 32 |
+
from ...modeling_outputs import BaseModelOutputWithPast, CausalLMOutputWithPast
|
| 33 |
+
from ...modeling_rope_utils import dynamic_rope_update
|
| 34 |
+
from ...modeling_utils import ALL_ATTENTION_FUNCTIONS
|
| 35 |
+
from ...processing_utils import Unpack
|
| 36 |
+
from ...utils import TransformersKwargs, auto_docstring, can_return_tuple, logging
|
| 37 |
+
from ...utils.generic import maybe_autocast
|
| 38 |
+
from ..llama.modeling_llama import (
|
| 39 |
+
LlamaAttention,
|
| 40 |
+
LlamaForCausalLM,
|
| 41 |
+
LlamaMLP,
|
| 42 |
+
LlamaModel,
|
| 43 |
+
LlamaRotaryEmbedding,
|
| 44 |
+
eager_attention_forward,
|
| 45 |
+
)
|
| 46 |
+
from .configuration_cohere import CohereConfig
|
| 47 |
+
|
| 48 |
+
|
| 49 |
+
logger = logging.get_logger(__name__)
|
| 50 |
+
|
| 51 |
+
|
| 52 |
+
class CohereLayerNorm(nn.Module):
|
| 53 |
+
def __init__(self, hidden_size=None, eps=1e-5, bias=False):
|
| 54 |
+
"""The hidden size can be a tuple or an int. The tuple is used for QKNorm to normalize across head_dim"""
|
| 55 |
+
super().__init__()
|
| 56 |
+
self.weight = nn.Parameter(torch.ones(hidden_size))
|
| 57 |
+
self.variance_epsilon = eps
|
| 58 |
+
|
| 59 |
+
def forward(self, hidden_states):
|
| 60 |
+
input_dtype = hidden_states.dtype
|
| 61 |
+
hidden_states = hidden_states.to(torch.float32)
|
| 62 |
+
mean = hidden_states.mean(-1, keepdim=True)
|
| 63 |
+
variance = (hidden_states - mean).pow(2).mean(-1, keepdim=True)
|
| 64 |
+
hidden_states = (hidden_states - mean) * torch.rsqrt(variance + self.variance_epsilon)
|
| 65 |
+
hidden_states = self.weight.to(torch.float32) * hidden_states
|
| 66 |
+
return hidden_states.to(input_dtype)
|
| 67 |
+
|
| 68 |
+
|
| 69 |
+
class CohereRotaryEmbedding(LlamaRotaryEmbedding):
|
| 70 |
+
@torch.no_grad()
|
| 71 |
+
@dynamic_rope_update # power user: used with advanced RoPE types (e.g. dynamic rope)
|
| 72 |
+
def forward(self, x, position_ids):
|
| 73 |
+
inv_freq_expanded = self.inv_freq[None, :, None].float().expand(position_ids.shape[0], -1, 1)
|
| 74 |
+
position_ids_expanded = position_ids[:, None, :].float()
|
| 75 |
+
|
| 76 |
+
device_type = x.device.type if isinstance(x.device.type, str) and x.device.type != "mps" else "cpu"
|
| 77 |
+
with maybe_autocast(device_type=device_type, enabled=False): # Force float32
|
| 78 |
+
freqs = (inv_freq_expanded.float() @ position_ids_expanded.float()).transpose(1, 2)
|
| 79 |
+
emb = torch.repeat_interleave(freqs, 2, dim=-1) # diff from Llama: we interleave() instead of cat()
|
| 80 |
+
cos = emb.cos() * self.attention_scaling
|
| 81 |
+
sin = emb.sin() * self.attention_scaling
|
| 82 |
+
|
| 83 |
+
return cos.to(dtype=x.dtype), sin.to(dtype=x.dtype)
|
| 84 |
+
|
| 85 |
+
|
| 86 |
+
def rotate_half(x):
|
| 87 |
+
# Split and rotate. Note that this function is different from e.g. Llama.
|
| 88 |
+
x1 = x[..., ::2]
|
| 89 |
+
x2 = x[..., 1::2]
|
| 90 |
+
rot_x = torch.stack([-x2, x1], dim=-1).flatten(-2)
|
| 91 |
+
return rot_x
|
| 92 |
+
|
| 93 |
+
|
| 94 |
+
def apply_rotary_pos_emb(q, k, cos, sin, unsqueeze_dim=1):
|
| 95 |
+
"""Applies Rotary Position Embedding to the query and key tensors.
|
| 96 |
+
|
| 97 |
+
Args:
|
| 98 |
+
q (`torch.Tensor`): The query tensor.
|
| 99 |
+
k (`torch.Tensor`): The key tensor.
|
| 100 |
+
cos (`torch.Tensor`): The cosine part of the rotary embedding.
|
| 101 |
+
sin (`torch.Tensor`): The sine part of the rotary embedding.
|
| 102 |
+
unsqueeze_dim (`int`, *optional*, defaults to 1):
|
| 103 |
+
The 'unsqueeze_dim' argument specifies the dimension along which to unsqueeze cos[position_ids] and
|
| 104 |
+
sin[position_ids] so that they can be properly broadcasted to the dimensions of q and k. For example, note
|
| 105 |
+
that cos[position_ids] and sin[position_ids] have the shape [batch_size, seq_len, head_dim]. Then, if q and
|
| 106 |
+
k have the shape [batch_size, heads, seq_len, head_dim], then setting unsqueeze_dim=1 makes
|
| 107 |
+
cos[position_ids] and sin[position_ids] broadcastable to the shapes of q and k. Similarly, if q and k have
|
| 108 |
+
the shape [batch_size, seq_len, heads, head_dim], then set unsqueeze_dim=2.
|
| 109 |
+
Returns:
|
| 110 |
+
`tuple(torch.Tensor)` comprising of the query and key tensors rotated using the Rotary Position Embedding.
|
| 111 |
+
"""
|
| 112 |
+
dtype = q.dtype
|
| 113 |
+
q = q.float()
|
| 114 |
+
k = k.float()
|
| 115 |
+
cos = cos.unsqueeze(unsqueeze_dim)
|
| 116 |
+
sin = sin.unsqueeze(unsqueeze_dim)
|
| 117 |
+
q_embed = (q * cos) + (rotate_half(q) * sin)
|
| 118 |
+
k_embed = (k * cos) + (rotate_half(k) * sin)
|
| 119 |
+
return q_embed.to(dtype=dtype), k_embed.to(dtype=dtype)
|
| 120 |
+
|
| 121 |
+
|
| 122 |
+
class CohereMLP(LlamaMLP):
|
| 123 |
+
def __init__(self, config):
|
| 124 |
+
super().__init__(config)
|
| 125 |
+
self.gate_proj = nn.Linear(self.hidden_size, self.intermediate_size, bias=False)
|
| 126 |
+
self.up_proj = nn.Linear(self.hidden_size, self.intermediate_size, bias=False)
|
| 127 |
+
self.down_proj = nn.Linear(self.intermediate_size, self.hidden_size, bias=False)
|
| 128 |
+
|
| 129 |
+
|
| 130 |
+
class CohereAttention(LlamaAttention):
|
| 131 |
+
"""Multi-headed attention from 'Attention Is All You Need' paper"""
|
| 132 |
+
|
| 133 |
+
def __init__(self, config: CohereConfig, layer_idx: int | None = None):
|
| 134 |
+
super().__init__(config, layer_idx)
|
| 135 |
+
self.use_qk_norm = config.use_qk_norm
|
| 136 |
+
if self.use_qk_norm:
|
| 137 |
+
# When sharding the model using Tensor Parallelism, need to be careful to use n_local_heads
|
| 138 |
+
self.q_norm = CohereLayerNorm(
|
| 139 |
+
hidden_size=(config.num_attention_heads, self.head_dim), eps=config.layer_norm_eps
|
| 140 |
+
)
|
| 141 |
+
self.k_norm = CohereLayerNorm(
|
| 142 |
+
hidden_size=(config.num_key_value_heads, self.head_dim), eps=config.layer_norm_eps
|
| 143 |
+
)
|
| 144 |
+
|
| 145 |
+
def forward(
|
| 146 |
+
self,
|
| 147 |
+
hidden_states: torch.Tensor,
|
| 148 |
+
position_embeddings: tuple[torch.Tensor, torch.Tensor],
|
| 149 |
+
attention_mask: torch.Tensor | None,
|
| 150 |
+
past_key_values: Cache | None = None,
|
| 151 |
+
**kwargs: Unpack[FlashAttentionKwargs],
|
| 152 |
+
) -> tuple[torch.Tensor, torch.Tensor | None]:
|
| 153 |
+
input_shape = hidden_states.shape[:-1]
|
| 154 |
+
hidden_shape = (*input_shape, -1, self.head_dim)
|
| 155 |
+
|
| 156 |
+
query_states = self.q_proj(hidden_states).view(hidden_shape)
|
| 157 |
+
key_states = self.k_proj(hidden_states).view(hidden_shape)
|
| 158 |
+
value_states = self.v_proj(hidden_states).view(hidden_shape)
|
| 159 |
+
|
| 160 |
+
if self.use_qk_norm: # main diff from Llama
|
| 161 |
+
query_states = self.q_norm(query_states)
|
| 162 |
+
key_states = self.k_norm(key_states)
|
| 163 |
+
|
| 164 |
+
query_states = query_states.transpose(1, 2)
|
| 165 |
+
key_states = key_states.transpose(1, 2)
|
| 166 |
+
value_states = value_states.transpose(1, 2)
|
| 167 |
+
|
| 168 |
+
cos, sin = position_embeddings
|
| 169 |
+
query_states, key_states = apply_rotary_pos_emb(query_states, key_states, cos, sin)
|
| 170 |
+
|
| 171 |
+
if past_key_values is not None:
|
| 172 |
+
key_states, value_states = past_key_values.update(key_states, value_states, self.layer_idx)
|
| 173 |
+
|
| 174 |
+
attention_interface: Callable = ALL_ATTENTION_FUNCTIONS.get_interface(
|
| 175 |
+
self.config._attn_implementation, eager_attention_forward
|
| 176 |
+
)
|
| 177 |
+
|
| 178 |
+
attn_output, attn_weights = attention_interface(
|
| 179 |
+
self,
|
| 180 |
+
query_states,
|
| 181 |
+
key_states,
|
| 182 |
+
value_states,
|
| 183 |
+
attention_mask,
|
| 184 |
+
dropout=0.0 if not self.training else self.attention_dropout,
|
| 185 |
+
scaling=self.scaling,
|
| 186 |
+
**kwargs,
|
| 187 |
+
)
|
| 188 |
+
|
| 189 |
+
attn_output = attn_output.reshape(*input_shape, -1).contiguous()
|
| 190 |
+
attn_output = self.o_proj(attn_output)
|
| 191 |
+
return attn_output, attn_weights
|
| 192 |
+
|
| 193 |
+
|
| 194 |
+
class CohereDecoderLayer(GradientCheckpointingLayer):
|
| 195 |
+
def __init__(self, config: CohereConfig, layer_idx: int):
|
| 196 |
+
super().__init__()
|
| 197 |
+
self.hidden_size = config.hidden_size
|
| 198 |
+
self.self_attn = CohereAttention(config=config, layer_idx=layer_idx)
|
| 199 |
+
self.mlp = CohereMLP(config)
|
| 200 |
+
self.input_layernorm = CohereLayerNorm(hidden_size=(config.hidden_size), eps=config.layer_norm_eps)
|
| 201 |
+
|
| 202 |
+
def forward(
|
| 203 |
+
self,
|
| 204 |
+
hidden_states: torch.Tensor,
|
| 205 |
+
attention_mask: torch.Tensor | None = None,
|
| 206 |
+
position_ids: torch.LongTensor | None = None,
|
| 207 |
+
past_key_values: Cache | None = None,
|
| 208 |
+
use_cache: bool | None = False,
|
| 209 |
+
position_embeddings: tuple[torch.Tensor, torch.Tensor] | None = None,
|
| 210 |
+
**kwargs: Unpack[FlashAttentionKwargs],
|
| 211 |
+
) -> tuple[torch.FloatTensor, tuple[torch.FloatTensor, torch.FloatTensor] | None]:
|
| 212 |
+
"""
|
| 213 |
+
Args:
|
| 214 |
+
hidden_states (`torch.FloatTensor`): input to the layer of shape `(batch, seq_len, embed_dim)`
|
| 215 |
+
attention_mask (`torch.FloatTensor`, *optional*):
|
| 216 |
+
attention mask of size `(batch_size, sequence_length)` if flash attention is used or `(batch_size, 1,
|
| 217 |
+
query_sequence_length, key_sequence_length)` if default attention is used.
|
| 218 |
+
past_key_values (`Cache`, *optional*): cached past key and value projection states
|
| 219 |
+
output_attentions (`bool`, *optional*):
|
| 220 |
+
Whether or not to return the attentions tensors of all attention layers. See `attentions` under
|
| 221 |
+
returned tensors for more detail.
|
| 222 |
+
use_cache (`bool`, *optional*):
|
| 223 |
+
If set to `True`, `past_key_values` key value states are returned and can be used to speed up decoding
|
| 224 |
+
(see `past_key_values`).
|
| 225 |
+
position_embeddings (`tuple[torch.FloatTensor, torch.FloatTensor]`, *optional*):
|
| 226 |
+
Tuple containing the cosine and sine positional embeddings of shape `(batch_size, seq_len, head_dim)`,
|
| 227 |
+
with `head_dim` being the embedding dimension of each attention head.
|
| 228 |
+
"""
|
| 229 |
+
residual = hidden_states
|
| 230 |
+
hidden_states = self.input_layernorm(hidden_states)
|
| 231 |
+
|
| 232 |
+
hidden_states_attention, _ = self.self_attn(
|
| 233 |
+
hidden_states=hidden_states,
|
| 234 |
+
attention_mask=attention_mask,
|
| 235 |
+
position_ids=position_ids,
|
| 236 |
+
past_key_values=past_key_values,
|
| 237 |
+
use_cache=use_cache,
|
| 238 |
+
position_embeddings=position_embeddings,
|
| 239 |
+
**kwargs,
|
| 240 |
+
)
|
| 241 |
+
|
| 242 |
+
hidden_states_mlp = self.mlp(hidden_states)
|
| 243 |
+
hidden_states = residual + hidden_states_attention + hidden_states_mlp
|
| 244 |
+
return hidden_states
|
| 245 |
+
|
| 246 |
+
|
| 247 |
+
class CohereModel(LlamaModel):
|
| 248 |
+
def __init__(self, config: CohereConfig):
|
| 249 |
+
super().__init__(config)
|
| 250 |
+
self.layers = nn.ModuleList(
|
| 251 |
+
[CohereDecoderLayer(config, layer_idx) for layer_idx in range(config.num_hidden_layers)]
|
| 252 |
+
)
|
| 253 |
+
self.norm = CohereLayerNorm(hidden_size=(config.hidden_size), eps=config.layer_norm_eps)
|
| 254 |
+
|
| 255 |
+
|
| 256 |
+
class CohereForCausalLM(LlamaForCausalLM):
|
| 257 |
+
def __init__(self, config):
|
| 258 |
+
super().__init__(config)
|
| 259 |
+
self.model = CohereModel(config)
|
| 260 |
+
self.logit_scale = config.logit_scale
|
| 261 |
+
self.tie_word_embeddings = config.tie_word_embeddings
|
| 262 |
+
|
| 263 |
+
@can_return_tuple
|
| 264 |
+
@auto_docstring
|
| 265 |
+
def forward(
|
| 266 |
+
self,
|
| 267 |
+
input_ids: torch.LongTensor | None = None,
|
| 268 |
+
attention_mask: torch.Tensor | None = None,
|
| 269 |
+
position_ids: torch.LongTensor | None = None,
|
| 270 |
+
past_key_values: Cache | None = None,
|
| 271 |
+
inputs_embeds: torch.FloatTensor | None = None,
|
| 272 |
+
labels: torch.LongTensor | None = None,
|
| 273 |
+
use_cache: bool | None = None,
|
| 274 |
+
logits_to_keep: int | torch.Tensor = 0,
|
| 275 |
+
**kwargs: Unpack[TransformersKwargs],
|
| 276 |
+
) -> CausalLMOutputWithPast:
|
| 277 |
+
r"""
|
| 278 |
+
Example:
|
| 279 |
+
|
| 280 |
+
```python
|
| 281 |
+
>> from transformers import AutoTokenizer, CohereForCausalLM
|
| 282 |
+
|
| 283 |
+
>> model = CohereForCausalLM.from_pretrained("CohereForAI/c4ai-command-r-v01")
|
| 284 |
+
>> tokenizer = AutoTokenizer.from_pretrained("CohereForAI/c4ai-command-r-v01")
|
| 285 |
+
|
| 286 |
+
>> prompt = "Hey, are you conscious? Can you talk to me?"
|
| 287 |
+
>> inputs = tokenizer(prompt, return_tensors="pt")
|
| 288 |
+
|
| 289 |
+
>> # Generate
|
| 290 |
+
>> generate_ids = model.generate(inputs.input_ids, max_length=30)
|
| 291 |
+
>> tokenizer.batch_decode(generate_ids, skip_special_tokens=True, clean_up_tokenization_spaces=False)[0]
|
| 292 |
+
"Hey, are you conscious? Can you talk to me?\nI'm not conscious, but I can talk to you."
|
| 293 |
+
```"""
|
| 294 |
+
outputs: BaseModelOutputWithPast = self.model(
|
| 295 |
+
input_ids=input_ids,
|
| 296 |
+
attention_mask=attention_mask,
|
| 297 |
+
position_ids=position_ids,
|
| 298 |
+
past_key_values=past_key_values,
|
| 299 |
+
inputs_embeds=inputs_embeds,
|
| 300 |
+
use_cache=use_cache,
|
| 301 |
+
**kwargs,
|
| 302 |
+
)
|
| 303 |
+
|
| 304 |
+
hidden_states = outputs.last_hidden_state
|
| 305 |
+
slice_indices = slice(-logits_to_keep, None) if isinstance(logits_to_keep, int) else logits_to_keep
|
| 306 |
+
logits = self.lm_head(hidden_states[:, slice_indices, :])
|
| 307 |
+
logits = logits * self.logit_scale # main diff from Llama
|
| 308 |
+
|
| 309 |
+
loss = None
|
| 310 |
+
if labels is not None:
|
| 311 |
+
loss = self.loss_function(logits=logits, labels=labels, vocab_size=self.config.vocab_size, **kwargs)
|
| 312 |
+
|
| 313 |
+
return CausalLMOutputWithPast(
|
| 314 |
+
loss=loss,
|
| 315 |
+
logits=logits,
|
| 316 |
+
past_key_values=outputs.past_key_values,
|
| 317 |
+
hidden_states=outputs.hidden_states,
|
| 318 |
+
attentions=outputs.attentions,
|
| 319 |
+
)
|
| 320 |
+
|
| 321 |
+
|
| 322 |
+
__all__ = [
|
| 323 |
+
"CohereForCausalLM",
|
| 324 |
+
"CohereModel",
|
| 325 |
+
"CoherePreTrainedModel", # noqa: F822
|
| 326 |
+
]
|
third_party/transformers/src/transformers/models/cohere/tokenization_cohere.py
ADDED
|
@@ -0,0 +1,384 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright 2024 Cohere team. All rights reserved.
|
| 2 |
+
#
|
| 3 |
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
| 4 |
+
# you may not use this file except in compliance with the License.
|
| 5 |
+
# You may obtain a copy of the License at
|
| 6 |
+
#
|
| 7 |
+
# http://www.apache.org/licenses/LICENSE-2.0
|
| 8 |
+
#
|
| 9 |
+
# Unless required by applicable law or agreed to in writing, software
|
| 10 |
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
| 11 |
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 12 |
+
# See the License for the specific language governing permissions and
|
| 13 |
+
# limitations under the License.
|
| 14 |
+
|
| 15 |
+
# This file is based on the tokenization_llama.py file in transformers
|
| 16 |
+
|
| 17 |
+
from typing import Literal
|
| 18 |
+
|
| 19 |
+
from tokenizers import Tokenizer, decoders, normalizers, pre_tokenizers
|
| 20 |
+
from tokenizers.models import BPE
|
| 21 |
+
|
| 22 |
+
from ...tokenization_utils_tokenizers import TokenizersBackend
|
| 23 |
+
from ...utils import logging
|
| 24 |
+
|
| 25 |
+
|
| 26 |
+
logger = logging.get_logger(__name__)
|
| 27 |
+
VOCAB_FILES_NAMES = {"vocab_file": "vocab.json", "merges_file": "merges.txt", "tokenizer_file": "tokenizer.json"}
|
| 28 |
+
|
| 29 |
+
PRETRAINED_VOCAB_FILES_MAP = {
|
| 30 |
+
"tokenizer_file": {
|
| 31 |
+
"Cohere/Command-nightly": "https://huggingface.co/Cohere/Command-nightly/blob/main/tokenizer.json",
|
| 32 |
+
},
|
| 33 |
+
}
|
| 34 |
+
|
| 35 |
+
# fmt: off
|
| 36 |
+
DEFAULT_SYSTEM_PROMPT = "You are Command-R, a brilliant, sophisticated, AI-assistant trained to assist human users by providing thorough responses. You are trained by Cohere."
|
| 37 |
+
DEFAULT_RAG_PREAMBLE = """## Task and Context
|
| 38 |
+
You help people answer their questions and other requests interactively. You will be asked a very wide array of requests on all kinds of topics. You will be equipped with a wide range of search engines or similar tools to help you, which you use to research your answer. You should focus on serving the user's needs as best you can, which will be wide-ranging.
|
| 39 |
+
|
| 40 |
+
## Style Guide
|
| 41 |
+
Unless the user asks for a different style of answer, you should answer in full sentences, using proper grammar and spelling."""
|
| 42 |
+
# fmt: on
|
| 43 |
+
|
| 44 |
+
|
| 45 |
+
class CohereTokenizer(TokenizersBackend):
|
| 46 |
+
"""
|
| 47 |
+
Construct a Cohere tokenizer. Based on byte-level Byte-Pair-Encoding.
|
| 48 |
+
|
| 49 |
+
This uses notably ByteFallback and NFC normalization.
|
| 50 |
+
|
| 51 |
+
```python
|
| 52 |
+
>>> from transformers import AutoTokenizer
|
| 53 |
+
|
| 54 |
+
>>> tokenizer = AutoTokenizer.from_pretrained("CohereForAI/c4ai-command-r-v01")
|
| 55 |
+
>>> tokenizer.encode("Hello this is a test")
|
| 56 |
+
[5, 28339, 2075, 1801, 1671, 3282]
|
| 57 |
+
```
|
| 58 |
+
|
| 59 |
+
If you want to change the `bos_token` or the `eos_token`, make sure to specify them when initializing the model, or
|
| 60 |
+
call `tokenizer.update_post_processor()` to make sure that the post-processing is correctly done (otherwise the
|
| 61 |
+
values of the first token and final token of an encoded sequence will not be correct). For more details, checkout
|
| 62 |
+
[post-processors] (https://huggingface.co/docs/tokenizers/api/post-processors) documentation.
|
| 63 |
+
|
| 64 |
+
You can get around that behavior by passing `add_prefix_space=True` when instantiating this tokenizer, but since
|
| 65 |
+
the model was not pretrained this way, it might yield a decrease in performance.
|
| 66 |
+
|
| 67 |
+
<Tip>
|
| 68 |
+
|
| 69 |
+
When used with `is_split_into_words=True`, this tokenizer needs to be instantiated with `add_prefix_space=True`.
|
| 70 |
+
|
| 71 |
+
</Tip>
|
| 72 |
+
|
| 73 |
+
This tokenizer inherits from [`TokenizersBackend`] which contains most of the main methods. Users should
|
| 74 |
+
refer to this superclass for more information regarding those methods.
|
| 75 |
+
|
| 76 |
+
Args:
|
| 77 |
+
vocab_file (`str`, *optional*):
|
| 78 |
+
Path to the vocabulary file.
|
| 79 |
+
merges_file (`str`, *optional*):
|
| 80 |
+
Path to the merges file.
|
| 81 |
+
tokenizer_file (`str`, *optional*):
|
| 82 |
+
[tokenizers](https://github.com/huggingface/tokenizers) file (generally has a .json extension) that
|
| 83 |
+
contains everything needed to load the tokenizer.
|
| 84 |
+
clean_up_tokenization_spaces (`bool`, *optional*, defaults to `False`):
|
| 85 |
+
Whether or not to cleanup spaces after decoding, cleanup consists in removing potential artifacts like
|
| 86 |
+
extra spaces.
|
| 87 |
+
unk_token (`str` or `tokenizers.AddedToken`, *optional*, defaults to `"<UNK>"`):
|
| 88 |
+
The unknown token. A token that is not in the vocabulary cannot be converted to an ID and is set to be this
|
| 89 |
+
token instead.
|
| 90 |
+
bos_token (`str` or `tokenizers.AddedToken`, *optional*, defaults to `"<BOS_TOKEN>"`):
|
| 91 |
+
The beginning of sequence token that was used during pretraining. Can be used a sequence classifier token.
|
| 92 |
+
eos_token (`str` or `tokenizers.AddedToken`, *optional*, defaults to `"<|END_OF_TURN_TOKEN|>"`):
|
| 93 |
+
The end of sequence token.
|
| 94 |
+
add_bos_token (`bool`, *optional*, defaults to `True`):
|
| 95 |
+
Whether or not to add an `bos_token` at the start of sequences.
|
| 96 |
+
add_eos_token (`bool`, *optional*, defaults to `False`):
|
| 97 |
+
Whether or not to add an `eos_token` at the end of sequences.
|
| 98 |
+
use_default_system_prompt (`bool`, *optional*, defaults to `False`):
|
| 99 |
+
Whether or not the default system prompt for Cohere tokenizer should be used.
|
| 100 |
+
add_prefix_space (`bool`, *optional*, defaults to `False`):
|
| 101 |
+
Whether or not the tokenizer should automatically add a prefix space
|
| 102 |
+
vocab (`str`, `dict` or `list`, *optional*):
|
| 103 |
+
Custom vocabulary dictionary. If not provided, vocabulary is loaded from vocab_file.
|
| 104 |
+
merges (`str` or `list[str]`, *optional*):
|
| 105 |
+
Custom merges list. If not provided, merges are loaded from `merges_file`.
|
| 106 |
+
"""
|
| 107 |
+
|
| 108 |
+
vocab_files_names = VOCAB_FILES_NAMES
|
| 109 |
+
pretrained_vocab_files_map = PRETRAINED_VOCAB_FILES_MAP
|
| 110 |
+
padding_side = "left"
|
| 111 |
+
model_input_names = ["input_ids", "attention_mask"]
|
| 112 |
+
model = BPE
|
| 113 |
+
# No `max_model_input_sizes`
|
| 114 |
+
|
| 115 |
+
def __init__(
|
| 116 |
+
self,
|
| 117 |
+
vocab: str | dict[str, int] | None = None,
|
| 118 |
+
merges: str | list[str] | None = None,
|
| 119 |
+
errors: str = "replace",
|
| 120 |
+
unk_token: str = "<UNK>",
|
| 121 |
+
bos_token: str = "<BOS_TOKEN>",
|
| 122 |
+
eos_token: str = "<|END_OF_TURN_TOKEN|>",
|
| 123 |
+
pad_token: str = "<PAD>",
|
| 124 |
+
cls_token: str = "<CLS>",
|
| 125 |
+
sep_token: str = "<SEP>",
|
| 126 |
+
mask_token: str = "<MASK_TOKEN>",
|
| 127 |
+
use_default_system_prompt: bool = False,
|
| 128 |
+
add_prefix_space: bool = False,
|
| 129 |
+
**kwargs,
|
| 130 |
+
):
|
| 131 |
+
self.use_default_system_prompt = use_default_system_prompt
|
| 132 |
+
self.add_prefix_space = add_prefix_space
|
| 133 |
+
self.grounded_generation_template = kwargs.pop("grounded_generation_template", None)
|
| 134 |
+
self.tool_use_template = kwargs.pop("tool_use_template", None)
|
| 135 |
+
|
| 136 |
+
self._vocab = (
|
| 137 |
+
vocab
|
| 138 |
+
if vocab is not None
|
| 139 |
+
else {
|
| 140 |
+
str(pad_token): 0,
|
| 141 |
+
str(unk_token): 1,
|
| 142 |
+
str(cls_token): 2,
|
| 143 |
+
str(sep_token): 3,
|
| 144 |
+
str(mask_token): 4,
|
| 145 |
+
str(bos_token): 5,
|
| 146 |
+
}
|
| 147 |
+
)
|
| 148 |
+
|
| 149 |
+
self._merges = merges or []
|
| 150 |
+
self._tokenizer = Tokenizer(
|
| 151 |
+
BPE(
|
| 152 |
+
vocab=self._vocab,
|
| 153 |
+
merges=self._merges,
|
| 154 |
+
dropout=None,
|
| 155 |
+
continuing_subword_prefix="",
|
| 156 |
+
end_of_word_suffix="",
|
| 157 |
+
fuse_unk=False,
|
| 158 |
+
)
|
| 159 |
+
)
|
| 160 |
+
|
| 161 |
+
self._tokenizer.normalizer = normalizers.NFC()
|
| 162 |
+
self._tokenizer.pre_tokenizer = pre_tokenizers.Sequence(
|
| 163 |
+
[
|
| 164 |
+
pre_tokenizers.Digits(individual_digits=True),
|
| 165 |
+
pre_tokenizers.ByteLevel(add_prefix_space=add_prefix_space, trim_offsets=True),
|
| 166 |
+
]
|
| 167 |
+
)
|
| 168 |
+
self._tokenizer.decoder = decoders.ByteLevel(add_prefix_space=add_prefix_space, trim_offsets=True)
|
| 169 |
+
|
| 170 |
+
super().__init__(
|
| 171 |
+
errors=errors,
|
| 172 |
+
unk_token=unk_token,
|
| 173 |
+
bos_token=bos_token,
|
| 174 |
+
eos_token=eos_token,
|
| 175 |
+
pad_token=pad_token,
|
| 176 |
+
cls_token=cls_token,
|
| 177 |
+
sep_token=sep_token,
|
| 178 |
+
mask_token=mask_token,
|
| 179 |
+
use_default_system_prompt=use_default_system_prompt,
|
| 180 |
+
add_prefix_space=add_prefix_space,
|
| 181 |
+
**kwargs,
|
| 182 |
+
)
|
| 183 |
+
|
| 184 |
+
self._post_init()
|
| 185 |
+
|
| 186 |
+
def apply_tool_use_template(
|
| 187 |
+
self,
|
| 188 |
+
conversation: list[dict[str, str]],
|
| 189 |
+
tools: list[dict],
|
| 190 |
+
**kwargs,
|
| 191 |
+
) -> str | list[int]:
|
| 192 |
+
"""Create a Command-R tool-use prompt.
|
| 193 |
+
|
| 194 |
+
Once rendered, the prompt instructs the model to generate a list of actions to perform on a set of user supplied tools
|
| 195 |
+
to help carry out the user's requests.
|
| 196 |
+
|
| 197 |
+
Conceptually, this works in the same way as `apply_chat_format`, but takes an additional `tools` parameter.
|
| 198 |
+
|
| 199 |
+
Converts a chat in the form of a list of dictionaries with `"role"` and `"content"` keys and a list of available
|
| 200 |
+
tools for the model to use into a prompt string, or a list of token ids.
|
| 201 |
+
This method will use the tokenizer's `default_tool_use_template` template specified at the class level.
|
| 202 |
+
You can override the default template using the `tool_use_template` kwarg but the quality of your results may decrease.
|
| 203 |
+
|
| 204 |
+
Args:
|
| 205 |
+
conversation (list[dict[str, str]]): A list of dicts
|
| 206 |
+
with "role" and "content" keys, representing the chat history so far.
|
| 207 |
+
tools (list[Dict]): a list of tools to render into the prompt for the model to choose from.
|
| 208 |
+
See an example at the bottom of the docstring.
|
| 209 |
+
The format should be:
|
| 210 |
+
* name (str): The name of the tool to be called. Valid names contain only the characters a-z,
|
| 211 |
+
A-Z, 0-9, _ and must not begin with a digit.
|
| 212 |
+
* description (str): The description of what the tool does, the model uses the description to
|
| 213 |
+
choose when and how to call the function.
|
| 214 |
+
* parameter_definitions (list[Dict]): The input parameters of the tool. Accepts a dictionary
|
| 215 |
+
where the key is the name of the parameter and the value is the parameter spec.
|
| 216 |
+
Valid parameter names contain only the characters a-z, A-Z, 0-9, _ and must not begin with a digit.
|
| 217 |
+
Parameter specs are as follows:
|
| 218 |
+
* description (str): The description of the parameter.
|
| 219 |
+
* type (str): the type of the parameter - most effective for python builtin data types, such as 'str', 'bool'
|
| 220 |
+
* required: boolean: Denotes whether the parameter is always present (required) or not. Defaults to not required.
|
| 221 |
+
add_generation_prompt (bool, *optional*): Whether to end the prompt with the token(s) that indicate
|
| 222 |
+
the start of an assistant message. This is useful when you want to generate a response from the model.
|
| 223 |
+
Note that this argument will be passed to the chat template, and so it must be supported in the
|
| 224 |
+
template for this argument to have any effect.
|
| 225 |
+
tokenize (`bool`, defaults to `True`):
|
| 226 |
+
Whether to tokenize the output. If `False`, the output will be a string.
|
| 227 |
+
padding (`bool`, defaults to `False`):
|
| 228 |
+
Whether to pad sequences to the maximum length. Has no effect if tokenize is `False`.
|
| 229 |
+
truncation (`bool`, defaults to `False`):
|
| 230 |
+
Whether to truncate sequences at the maximum length. Has no effect if tokenize is `False`.
|
| 231 |
+
max_length (`int`, *optional*):
|
| 232 |
+
Maximum length (in tokens) to use for padding or truncation. Has no effect if tokenize is `False`. If
|
| 233 |
+
not specified, the tokenizer's `max_length` attribute will be used as a default.
|
| 234 |
+
return_tensors (`str` or [`~utils.TensorType`], *optional*):
|
| 235 |
+
If set, will return tensors of a particular framework. Has no effect if tokenize is `False`. Acceptable
|
| 236 |
+
values are:
|
| 237 |
+
- `'pt'`: Return PyTorch `torch.Tensor` objects.
|
| 238 |
+
- `'np'`: Return NumPy `np.ndarray` objects.
|
| 239 |
+
return_dict (`bool`, *optional*, defaults to `False`):
|
| 240 |
+
Whether to return a dictionary with named outputs. Has no effect if tokenize is `False`.
|
| 241 |
+
**tokenizer_kwargs: Additional kwargs to pass to the tokenizer.
|
| 242 |
+
|
| 243 |
+
Returns:
|
| 244 |
+
`str`: A rendered prompt string.
|
| 245 |
+
or if tokenize=True:
|
| 246 |
+
`list[int]`: A list of token ids representing the tokenized chat so far, including control tokens. This
|
| 247 |
+
output is ready to pass to the model, either directly or via methods like `generate()`.
|
| 248 |
+
|
| 249 |
+
Examples:
|
| 250 |
+
|
| 251 |
+
```python
|
| 252 |
+
>> tokenizer = CohereTokenizer.from_pretrained("CohereForAI/c4ai-command-r-v01")
|
| 253 |
+
>> tools = [
|
| 254 |
+
{
|
| 255 |
+
"name": "internet_search",
|
| 256 |
+
"description": "Returns a list of relevant document snippets for a textual query retrieved from the internet",
|
| 257 |
+
"parameter_definitions": {
|
| 258 |
+
"query": {
|
| 259 |
+
"description": "Query to search the internet with",
|
| 260 |
+
"type": "str",
|
| 261 |
+
"required": True,
|
| 262 |
+
}
|
| 263 |
+
},
|
| 264 |
+
},
|
| 265 |
+
{
|
| 266 |
+
"name": "directly_answer",
|
| 267 |
+
"description": "Calls a standard (un-augmented) AI chatbot to generate a response given the conversation history",
|
| 268 |
+
"parameter_definitions": {},
|
| 269 |
+
},
|
| 270 |
+
]
|
| 271 |
+
>> conversation = [
|
| 272 |
+
{"role": "user", "content": "Whats the biggest penguin in the world?"},
|
| 273 |
+
]
|
| 274 |
+
>> # Render the prompt, ready for user to inspect, or for input into the model
|
| 275 |
+
>> prompt = tokenizer.apply_tool_use_template(conversation, tools=tools, tokenize=False, add_generation_prompt=True)
|
| 276 |
+
>> print(prompt)
|
| 277 |
+
>> inputs = tokenizer.encode(grounded_generation_prompt, add_special_tokens=False, return_tensors='pt')
|
| 278 |
+
>> outputs = model.generate(inputs, max_new_tokens=128)
|
| 279 |
+
>> print(tokenizer.decode(outputs[0]))
|
| 280 |
+
[
|
| 281 |
+
{
|
| 282 |
+
"tool_name": "internet_search",
|
| 283 |
+
"parameters": {
|
| 284 |
+
"query": "biggest penguin in the world"
|
| 285 |
+
}
|
| 286 |
+
}
|
| 287 |
+
]
|
| 288 |
+
```
|
| 289 |
+
"""
|
| 290 |
+
return self.apply_chat_template(
|
| 291 |
+
conversation,
|
| 292 |
+
chat_template="tool_use",
|
| 293 |
+
tools=tools,
|
| 294 |
+
**kwargs,
|
| 295 |
+
)
|
| 296 |
+
|
| 297 |
+
def apply_grounded_generation_template(
|
| 298 |
+
self,
|
| 299 |
+
conversation: list[dict[str, str]],
|
| 300 |
+
documents: list[dict],
|
| 301 |
+
citation_mode: Literal["fast", "accurate"] = "accurate",
|
| 302 |
+
**kwargs,
|
| 303 |
+
) -> str | list[int]:
|
| 304 |
+
"""Create a Command-R grounded generation (aka RAG) prompt.
|
| 305 |
+
|
| 306 |
+
Once rendered, the prompt instructs the model to generate a response with citations in, based on supplied documents.
|
| 307 |
+
|
| 308 |
+
Conceptually, this works in the same way as `apply_chat_format`, but takes additional `documents`
|
| 309 |
+
and parameter `citation_mode` parameters.
|
| 310 |
+
|
| 311 |
+
Converts a list of dictionaries with `"role"` and `"content"` keys and a list of
|
| 312 |
+
documents for the model to ground its response on into a prompt string, or a list of token ids.
|
| 313 |
+
This method will use the tokenizer's `grounded_generation_template` template specified at the class level.
|
| 314 |
+
You can override the default template using the `grounded_generation_template` kwarg but the quality of your results may decrease.
|
| 315 |
+
|
| 316 |
+
Args:
|
| 317 |
+
conversation (list[dict[str, str]]): A list of dicts
|
| 318 |
+
with "role" and "content" keys, representing the chat history so far.
|
| 319 |
+
documents (list[dict[str, str]): A list of dicts, representing documents or tool outputs to ground your
|
| 320 |
+
generation on. A document is a semistructured dict, with a string to string mapping. Common fields are
|
| 321 |
+
`url`, `title`, `snippet` etc but should be descriptive of the key. They will get rendered into the prompt.
|
| 322 |
+
citation_mode: either "accurate" (prompt the model to generate an answer first, then rewrite it with citation
|
| 323 |
+
spans in) or "fast", where the prompt instructs the model to generate an answer with citations in directly.
|
| 324 |
+
The former has higher quality citations, the latter requires fewer tokens to be generated.
|
| 325 |
+
add_generation_prompt (bool, *optional*): Whether to end the prompt with the token(s) that indicate
|
| 326 |
+
the start of an assistant message. This is useful when you want to generate a response from the model.
|
| 327 |
+
Note that this argument will be passed to the chat template, and so it must be supported in the
|
| 328 |
+
template for this argument to have any effect.
|
| 329 |
+
tokenize (`bool`, defaults to `True`):
|
| 330 |
+
Whether to tokenize the output. If `False`, the output will be a string.
|
| 331 |
+
padding (`bool`, defaults to `False`):
|
| 332 |
+
Whether to pad sequences to the maximum length. Has no effect if tokenize is `False`.
|
| 333 |
+
truncation (`bool`, defaults to `False`):
|
| 334 |
+
Whether to truncate sequences at the maximum length. Has no effect if tokenize is `False`.
|
| 335 |
+
max_length (`int`, *optional*):
|
| 336 |
+
Maximum length (in tokens) to use for padding or truncation. Has no effect if tokenize is `False`. If
|
| 337 |
+
not specified, the tokenizer's `max_length` attribute will be used as a default.
|
| 338 |
+
return_tensors (`str` or [`~utils.TensorType`], *optional*):
|
| 339 |
+
If set, will return tensors of a particular framework. Has no effect if tokenize is `False`. Acceptable
|
| 340 |
+
values are:
|
| 341 |
+
- `'pt'`: Return PyTorch `torch.Tensor` objects.
|
| 342 |
+
- `'np'`: Return NumPy `np.ndarray` objects.
|
| 343 |
+
return_dict (`bool`, *optional*, defaults to `False`):
|
| 344 |
+
Whether to return a dictionary with named outputs. Has no effect if tokenize is `False`.
|
| 345 |
+
**tokenizer_kwargs: Additional kwargs to pass to the tokenizer.
|
| 346 |
+
|
| 347 |
+
Returns:
|
| 348 |
+
`str`: A rendered prompt string.
|
| 349 |
+
or if tokenize=True:
|
| 350 |
+
`list[int]`: A list of token ids representing the tokenized chat so far, including control tokens. This
|
| 351 |
+
output is ready to pass to the model, either directly or via methods like `generate()`.
|
| 352 |
+
|
| 353 |
+
Examples:
|
| 354 |
+
|
| 355 |
+
```python
|
| 356 |
+
>> tokenizer = CohereTokenizer.from_pretrained('CohereForAI/c4ai-command-r-v01')
|
| 357 |
+
|
| 358 |
+
>> # define documents:
|
| 359 |
+
>> documents = [
|
| 360 |
+
{ "title": "Tall penguins", "text": "Emperor penguins are the tallest." },
|
| 361 |
+
{ "title": "Penguin habitats", "text": "Emperor penguins only live in Antarctica."}
|
| 362 |
+
]
|
| 363 |
+
>> # define a conversation:
|
| 364 |
+
>> conversation = [
|
| 365 |
+
{"role": "user", "content": "Whats the biggest penguin in the world?"}
|
| 366 |
+
]
|
| 367 |
+
>> # render the prompt, ready for user to inspect, or for input into the model:
|
| 368 |
+
>> grounded_generation_prompt = tokenizer.apply_grounded_generation_template(conversation, documents=documents, tokenize=False, add_generation_prompt=True)
|
| 369 |
+
>> print(grounded_generation_prompt)
|
| 370 |
+
>> inputs = tokenizer.encode(prompt, add_special_tokens=False, return_tensors='pt')
|
| 371 |
+
>> outputs = model.generate(inputs, max_new_tokens=128)
|
| 372 |
+
>> print(tokenizer.decode(outputs[0]))
|
| 373 |
+
```
|
| 374 |
+
"""
|
| 375 |
+
return self.apply_chat_template(
|
| 376 |
+
conversation,
|
| 377 |
+
chat_template="rag",
|
| 378 |
+
documents=documents,
|
| 379 |
+
citation_mode=citation_mode,
|
| 380 |
+
**kwargs,
|
| 381 |
+
)
|
| 382 |
+
|
| 383 |
+
|
| 384 |
+
__all__ = ["CohereTokenizer"]
|
third_party/transformers/src/transformers/models/cohere2_vision/__init__.py
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright 2025 The HuggingFace Team. All rights reserved.
|
| 2 |
+
#
|
| 3 |
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
| 4 |
+
# you may not use this file except in compliance with the License.
|
| 5 |
+
# You may obtain a copy of the License at
|
| 6 |
+
#
|
| 7 |
+
# http://www.apache.org/licenses/LICENSE-2.0
|
| 8 |
+
#
|
| 9 |
+
# Unless required by applicable law or agreed to in writing, software
|
| 10 |
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
| 11 |
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 12 |
+
# See the License for the specific language governing permissions and
|
| 13 |
+
# limitations under the License.
|
| 14 |
+
from typing import TYPE_CHECKING
|
| 15 |
+
|
| 16 |
+
from ...utils import _LazyModule
|
| 17 |
+
from ...utils.import_utils import define_import_structure
|
| 18 |
+
|
| 19 |
+
|
| 20 |
+
if TYPE_CHECKING:
|
| 21 |
+
from .configuration_cohere2_vision import *
|
| 22 |
+
from .image_processing_cohere2_vision import *
|
| 23 |
+
from .modeling_cohere2_vision import *
|
| 24 |
+
from .processing_cohere2_vision import *
|
| 25 |
+
else:
|
| 26 |
+
import sys
|
| 27 |
+
|
| 28 |
+
_file = globals()["__file__"]
|
| 29 |
+
sys.modules[__name__] = _LazyModule(__name__, _file, define_import_structure(_file), module_spec=__spec__)
|
third_party/transformers/src/transformers/models/cohere2_vision/configuration_cohere2_vision.py
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright 2025 the Cohere Inc. team. All rights reserved.
|
| 2 |
+
#
|
| 3 |
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
| 4 |
+
# you may not use this file except in compliance with the License.
|
| 5 |
+
# You may obtain a copy of the License at
|
| 6 |
+
#
|
| 7 |
+
# http://www.apache.org/licenses/LICENSE-2.0
|
| 8 |
+
#
|
| 9 |
+
# Unless required by applicable law or agreed to in writing, software
|
| 10 |
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
| 11 |
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 12 |
+
# See the License for the specific language governing permissions and
|
| 13 |
+
# limitations under the License.
|
| 14 |
+
|
| 15 |
+
|
| 16 |
+
from huggingface_hub.dataclasses import strict
|
| 17 |
+
|
| 18 |
+
from ...configuration_utils import PreTrainedConfig
|
| 19 |
+
from ...utils import auto_docstring
|
| 20 |
+
from ..auto import CONFIG_MAPPING, AutoConfig
|
| 21 |
+
|
| 22 |
+
|
| 23 |
+
@auto_docstring(checkpoint="CohereLabs/command-a-vision-07-2025")
|
| 24 |
+
@strict
|
| 25 |
+
class Cohere2VisionConfig(PreTrainedConfig):
|
| 26 |
+
r"""
|
| 27 |
+
downsample_factor (`int`, *optional*, defaults to 2):
|
| 28 |
+
The factor by which to downsample the input image.
|
| 29 |
+
alignment_intermediate_size (`int`, *optional*, defaults to 36864):
|
| 30 |
+
The size of the intermediate layer for alignment.
|
| 31 |
+
"""
|
| 32 |
+
|
| 33 |
+
model_type = "cohere2_vision"
|
| 34 |
+
sub_configs = {"text_config": AutoConfig, "vision_config": AutoConfig}
|
| 35 |
+
|
| 36 |
+
vision_config: dict | PreTrainedConfig | None = None
|
| 37 |
+
text_config: dict | PreTrainedConfig | None = None
|
| 38 |
+
downsample_factor: int = 2
|
| 39 |
+
image_token_id: int = 255036
|
| 40 |
+
alignment_intermediate_size: int = 36864
|
| 41 |
+
tie_word_embeddings: bool = True
|
| 42 |
+
|
| 43 |
+
def __post_init__(self, **kwargs):
|
| 44 |
+
if isinstance(self.vision_config, dict):
|
| 45 |
+
self.vision_config["model_type"] = self.vision_config.get("model_type", "siglip_vision_model")
|
| 46 |
+
self.vision_config = CONFIG_MAPPING[self.vision_config["model_type"]](**self.vision_config)
|
| 47 |
+
elif self.vision_config is None:
|
| 48 |
+
self.vision_config = CONFIG_MAPPING["siglip_vision_model"](
|
| 49 |
+
hidden_size=1152,
|
| 50 |
+
intermediate_size=3072,
|
| 51 |
+
image_size=512,
|
| 52 |
+
num_hidden_layers=27,
|
| 53 |
+
num_attention_heads=12,
|
| 54 |
+
)
|
| 55 |
+
|
| 56 |
+
if isinstance(self.text_config, dict):
|
| 57 |
+
self.text_config["model_type"] = self.text_config.get("model_type", "cohere2")
|
| 58 |
+
self.text_config = CONFIG_MAPPING[self.text_config["model_type"]](**self.text_config)
|
| 59 |
+
elif self.text_config is None:
|
| 60 |
+
self.text_config = CONFIG_MAPPING["cohere2"](tie_word_embeddings=self.tie_word_embeddings)
|
| 61 |
+
|
| 62 |
+
super().__post_init__(**kwargs)
|
| 63 |
+
|
| 64 |
+
|
| 65 |
+
__all__ = ["Cohere2VisionConfig"]
|
third_party/transformers/src/transformers/models/cohere2_vision/image_processing_cohere2_vision.py
ADDED
|
@@ -0,0 +1,293 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨
|
| 2 |
+
# This file was automatically generated from src/transformers/models/cohere2_vision/modular_cohere2_vision.py.
|
| 3 |
+
# Do NOT edit this file manually as any edits will be overwritten by the generation of
|
| 4 |
+
# the file from the modular. If any change should be done, please apply the change to the
|
| 5 |
+
# modular_cohere2_vision.py file directly. One of our CI enforces this.
|
| 6 |
+
# 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨
|
| 7 |
+
# Copyright 2025 the Cohere Inc. team. All rights reserved.
|
| 8 |
+
#
|
| 9 |
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
| 10 |
+
# you may not use this file except in compliance with the License.
|
| 11 |
+
# You may obtain a copy of the License at
|
| 12 |
+
#
|
| 13 |
+
# http://www.apache.org/licenses/LICENSE-2.0
|
| 14 |
+
#
|
| 15 |
+
# Unless required by applicable law or agreed to in writing, software
|
| 16 |
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
| 17 |
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 18 |
+
# See the License for the specific language governing permissions and
|
| 19 |
+
# limitations under the License.
|
| 20 |
+
|
| 21 |
+
from functools import lru_cache
|
| 22 |
+
|
| 23 |
+
import numpy as np
|
| 24 |
+
import torch
|
| 25 |
+
from torchvision.transforms.v2 import functional as tvF
|
| 26 |
+
|
| 27 |
+
from ...image_processing_backends import TorchvisionBackend
|
| 28 |
+
from ...image_processing_utils import BatchFeature
|
| 29 |
+
from ...image_transforms import group_images_by_shape, reorder_images
|
| 30 |
+
from ...image_utils import OPENAI_CLIP_MEAN, OPENAI_CLIP_STD, PILImageResampling, SizeDict
|
| 31 |
+
from ...processing_utils import ImagesKwargs, Unpack
|
| 32 |
+
from ...utils import TensorType, auto_docstring
|
| 33 |
+
|
| 34 |
+
|
| 35 |
+
class Cohere2VisionImageProcessorKwargs(ImagesKwargs, total=False):
|
| 36 |
+
r"""
|
| 37 |
+
crop_to_patches (`bool`, *optional*, defaults to `False`):
|
| 38 |
+
Whether to crop the image to patches. Can be overridden by the `crop_to_patches` parameter in the
|
| 39 |
+
`preprocess` method.
|
| 40 |
+
min_patches (`int`, *optional*, defaults to 1):
|
| 41 |
+
The minimum number of patches to be extracted from the image. Only has an effect if `crop_to_patches` is
|
| 42 |
+
set to `True`. Can be overridden by the `min_patches` parameter in the `preprocess` method.
|
| 43 |
+
max_patches (`int`, *optional*, defaults to 12):
|
| 44 |
+
The maximum number of patches to be extracted from the image. Only has an effect if `crop_to_patches` is
|
| 45 |
+
set to `True`. Can be overridden by the `max_patches` parameter in the `preprocess` method.
|
| 46 |
+
"""
|
| 47 |
+
|
| 48 |
+
crop_to_patches: bool
|
| 49 |
+
min_patches: int
|
| 50 |
+
max_patches: int
|
| 51 |
+
|
| 52 |
+
|
| 53 |
+
@lru_cache(maxsize=10)
|
| 54 |
+
def get_all_supported_aspect_ratios(max_image_tiles: int) -> list[tuple[int, int]]:
|
| 55 |
+
"""
|
| 56 |
+
Computes all allowed aspect ratios for a given maximum number of input tiles.
|
| 57 |
+
|
| 58 |
+
This function calculates all possible arrangements of tiles that can be formed
|
| 59 |
+
within the constraint of the maximum number of tiles. Each arrangement is
|
| 60 |
+
represented by its aspect ratio (width/height) and the corresponding tile configuration.
|
| 61 |
+
|
| 62 |
+
Args:
|
| 63 |
+
max_image_tiles (`int`):
|
| 64 |
+
The maximum number of tiles allowed.
|
| 65 |
+
|
| 66 |
+
Returns:
|
| 67 |
+
`list[tuple[int, int]]`: A list of tuples, each tuple representing a valid (width, height)
|
| 68 |
+
configuration in terms of number of tiles.
|
| 69 |
+
|
| 70 |
+
Example:
|
| 71 |
+
>>> get_all_supported_aspect_ratios(4)
|
| 72 |
+
[(1, 1), (1, 2), (1, 3), (1, 4), (2, 1), (2, 2), (3, 1), (4, 1)]
|
| 73 |
+
|
| 74 |
+
"""
|
| 75 |
+
aspect_ratios = []
|
| 76 |
+
for width in range(1, max_image_tiles + 1):
|
| 77 |
+
for height in range(1, max_image_tiles + 1):
|
| 78 |
+
if width * height <= max_image_tiles:
|
| 79 |
+
aspect_ratios.append((width, height))
|
| 80 |
+
return aspect_ratios
|
| 81 |
+
|
| 82 |
+
|
| 83 |
+
def get_optimal_tiled_canvas(
|
| 84 |
+
original_image_size: tuple[int, int],
|
| 85 |
+
target_tile_size: tuple[int, int],
|
| 86 |
+
min_image_tiles: int,
|
| 87 |
+
max_image_tiles: int,
|
| 88 |
+
) -> tuple[int, int]:
|
| 89 |
+
possible_resolutions = get_all_supported_aspect_ratios(max_image_tiles)
|
| 90 |
+
possible_resolutions = sorted(possible_resolutions, key=lambda x: x[0] * x[1])
|
| 91 |
+
image_height, image_width = original_image_size
|
| 92 |
+
patch_size_height, patch_size_width = target_tile_size # (height == width)
|
| 93 |
+
|
| 94 |
+
candidate_resolutions = np.array(possible_resolutions) * patch_size_height
|
| 95 |
+
# tiles following (width, height) order to align with aspect ratio convention
|
| 96 |
+
tile_size = np.stack([image_width, image_height])
|
| 97 |
+
required_scales = candidate_resolutions / tile_size
|
| 98 |
+
required_scale = np.min(required_scales, axis=-1, keepdims=True) # [n_resolutions, 1]
|
| 99 |
+
if np.all(required_scale < 1):
|
| 100 |
+
# We are forced to downscale, so try to minimize the amount of downscaling
|
| 101 |
+
best_grid = possible_resolutions[np.argmax(required_scale)]
|
| 102 |
+
else:
|
| 103 |
+
# Pick the resolution that required the least upscaling so that it most closely fits the image
|
| 104 |
+
required_scale = np.where(required_scale < 1.0, 10e9, required_scale)
|
| 105 |
+
best_grid = possible_resolutions[np.argmin(required_scale)]
|
| 106 |
+
return best_grid # (width, height)
|
| 107 |
+
|
| 108 |
+
|
| 109 |
+
@auto_docstring
|
| 110 |
+
class Cohere2VisionImageProcessor(TorchvisionBackend):
|
| 111 |
+
valid_kwargs = Cohere2VisionImageProcessorKwargs
|
| 112 |
+
resample = PILImageResampling.BICUBIC
|
| 113 |
+
image_mean = OPENAI_CLIP_MEAN
|
| 114 |
+
image_std = OPENAI_CLIP_STD
|
| 115 |
+
size = {"height": 512, "width": 512}
|
| 116 |
+
do_resize = True
|
| 117 |
+
do_rescale = True
|
| 118 |
+
do_normalize = True
|
| 119 |
+
do_convert_rgb = True
|
| 120 |
+
crop_to_patches = True
|
| 121 |
+
min_patches = 1
|
| 122 |
+
max_patches = 12
|
| 123 |
+
patch_size = 16
|
| 124 |
+
|
| 125 |
+
def __init__(self, **kwargs: Unpack[Cohere2VisionImageProcessorKwargs]):
|
| 126 |
+
super().__init__(**kwargs)
|
| 127 |
+
|
| 128 |
+
def crop_image_to_patches(
|
| 129 |
+
self,
|
| 130 |
+
images: "torch.Tensor",
|
| 131 |
+
min_patches: int,
|
| 132 |
+
max_patches: int,
|
| 133 |
+
use_thumbnail: bool = True,
|
| 134 |
+
patch_size: SizeDict | None = None,
|
| 135 |
+
resample: "PILImageResampling | tvF.InterpolationMode | int | None" = None,
|
| 136 |
+
):
|
| 137 |
+
"""
|
| 138 |
+
Crop the images to patches and return a list of cropped images.
|
| 139 |
+
The number of patches and their grid arrangement are determined by the original image size,
|
| 140 |
+
the target patch size and the minimum and maximum number of patches.
|
| 141 |
+
The aspect ratio of the patches grid is chosen to be the closest to the original image aspect ratio.
|
| 142 |
+
|
| 143 |
+
Args:
|
| 144 |
+
images (`torch.Tensor`):
|
| 145 |
+
The images to be cropped.
|
| 146 |
+
min_patches (`int`):
|
| 147 |
+
The minimum number of patches to be extracted from the image.
|
| 148 |
+
max_patches (`int`):
|
| 149 |
+
The maximum number of patches to be extracted from the image.
|
| 150 |
+
use_thumbnail (`bool`, *optional*, defaults to `True`):
|
| 151 |
+
Whether to add a thumbnail image to the list of cropped patches.
|
| 152 |
+
patch_size (`SizeDict`, *optional*):
|
| 153 |
+
The size of the output patches.
|
| 154 |
+
resample (`PILImageResampling | tvF.InterpolationMode | int | None`, *optional*):
|
| 155 |
+
Resampling filter to use when resizing.
|
| 156 |
+
"""
|
| 157 |
+
patch_size_height, patch_size_width = patch_size.height, patch_size.width
|
| 158 |
+
original_height, original_width = images.shape[-2:]
|
| 159 |
+
# find the closest aspect ratio to the target
|
| 160 |
+
num_columns, num_rows = get_optimal_tiled_canvas(
|
| 161 |
+
(original_height, original_width), (patch_size_height, patch_size_width), min_patches, max_patches
|
| 162 |
+
)
|
| 163 |
+
|
| 164 |
+
# calculate the target width and height
|
| 165 |
+
target_width = patch_size_width * num_columns
|
| 166 |
+
target_height = patch_size_height * num_rows
|
| 167 |
+
num_blocks = num_columns * num_rows
|
| 168 |
+
|
| 169 |
+
# resize the image so that each patch is of patch_size
|
| 170 |
+
resized_image = self.resize(images, SizeDict(height=target_height, width=target_width), resample=resample)
|
| 171 |
+
# split the image into patches
|
| 172 |
+
processed_images = []
|
| 173 |
+
for i in range(num_blocks):
|
| 174 |
+
column = i % num_columns
|
| 175 |
+
row = i // num_columns
|
| 176 |
+
box = (
|
| 177 |
+
column * patch_size_width,
|
| 178 |
+
row * patch_size_height,
|
| 179 |
+
(column + 1) * patch_size_width,
|
| 180 |
+
(row + 1) * patch_size_height,
|
| 181 |
+
)
|
| 182 |
+
# split the image
|
| 183 |
+
patch_image = resized_image[..., box[1] : box[3], box[0] : box[2]]
|
| 184 |
+
processed_images.append(patch_image)
|
| 185 |
+
|
| 186 |
+
if use_thumbnail and len(processed_images) != 1:
|
| 187 |
+
thumbnail_img = self.resize(images, patch_size, resample=resample)
|
| 188 |
+
processed_images.append(thumbnail_img)
|
| 189 |
+
|
| 190 |
+
processed_images = torch.stack(processed_images, dim=0).transpose(0, 1).contiguous()
|
| 191 |
+
|
| 192 |
+
return processed_images
|
| 193 |
+
|
| 194 |
+
def _preprocess(
|
| 195 |
+
self,
|
| 196 |
+
images: list["torch.Tensor"],
|
| 197 |
+
do_resize: bool,
|
| 198 |
+
size: SizeDict,
|
| 199 |
+
resample: "PILImageResampling | tvF.InterpolationMode | int | None",
|
| 200 |
+
do_rescale: bool,
|
| 201 |
+
rescale_factor: float,
|
| 202 |
+
do_normalize: bool,
|
| 203 |
+
image_mean: float | list[float] | None,
|
| 204 |
+
image_std: float | list[float] | None,
|
| 205 |
+
disable_grouping: bool | None,
|
| 206 |
+
return_tensors: str | TensorType | None,
|
| 207 |
+
crop_to_patches: bool = False,
|
| 208 |
+
min_patches: int = 1,
|
| 209 |
+
max_patches: int = 12,
|
| 210 |
+
**kwargs,
|
| 211 |
+
) -> BatchFeature:
|
| 212 |
+
if crop_to_patches:
|
| 213 |
+
grouped_images, grouped_images_index = group_images_by_shape(images, disable_grouping=disable_grouping)
|
| 214 |
+
processed_images_grouped = {}
|
| 215 |
+
num_patches = {}
|
| 216 |
+
for shape, stacked_images in grouped_images.items():
|
| 217 |
+
stacked_images = self.crop_image_to_patches(
|
| 218 |
+
stacked_images,
|
| 219 |
+
min_patches,
|
| 220 |
+
max_patches,
|
| 221 |
+
patch_size=size,
|
| 222 |
+
resample=resample,
|
| 223 |
+
)
|
| 224 |
+
processed_images_grouped[shape] = stacked_images
|
| 225 |
+
num_patches[shape] = [stacked_images.shape[1]] * stacked_images.shape[0]
|
| 226 |
+
images = reorder_images(processed_images_grouped, grouped_images_index)
|
| 227 |
+
images = [image for images_list in images for image in images_list]
|
| 228 |
+
num_patches = reorder_images(num_patches, grouped_images_index)
|
| 229 |
+
else:
|
| 230 |
+
num_patches = [1] * len(images)
|
| 231 |
+
|
| 232 |
+
# Group images by size for batched resizing
|
| 233 |
+
grouped_images, grouped_images_index = group_images_by_shape(images, disable_grouping=disable_grouping)
|
| 234 |
+
resized_images_grouped = {}
|
| 235 |
+
for shape, stacked_images in grouped_images.items():
|
| 236 |
+
if do_resize:
|
| 237 |
+
stacked_images = self.resize(image=stacked_images, size=size, resample=resample)
|
| 238 |
+
resized_images_grouped[shape] = stacked_images
|
| 239 |
+
resized_images = reorder_images(resized_images_grouped, grouped_images_index)
|
| 240 |
+
|
| 241 |
+
# Group images by size for further processing
|
| 242 |
+
# Needed in case do_resize is False, or resize returns images with different sizes
|
| 243 |
+
grouped_images, grouped_images_index = group_images_by_shape(resized_images, disable_grouping=disable_grouping)
|
| 244 |
+
processed_images_grouped = {}
|
| 245 |
+
for shape, stacked_images in grouped_images.items():
|
| 246 |
+
stacked_images = self.rescale_and_normalize(
|
| 247 |
+
stacked_images, do_rescale, rescale_factor, do_normalize, image_mean, image_std
|
| 248 |
+
)
|
| 249 |
+
processed_images_grouped[shape] = stacked_images
|
| 250 |
+
|
| 251 |
+
processed_images = reorder_images(processed_images_grouped, grouped_images_index)
|
| 252 |
+
|
| 253 |
+
return BatchFeature(
|
| 254 |
+
data={"pixel_values": processed_images, "num_patches": num_patches}, tensor_type=return_tensors
|
| 255 |
+
)
|
| 256 |
+
|
| 257 |
+
def get_number_of_image_patches(self, height: int, width: int, images_kwargs=None):
|
| 258 |
+
"""
|
| 259 |
+
A utility that returns number patches for a given image size.
|
| 260 |
+
|
| 261 |
+
Args:
|
| 262 |
+
height (`int`):
|
| 263 |
+
Height of the input image.
|
| 264 |
+
width (`int`):
|
| 265 |
+
Width of the input image.
|
| 266 |
+
images_kwargs (`dict`, *optional*)
|
| 267 |
+
Any kwargs to override defaults of the image processor.
|
| 268 |
+
Returns:
|
| 269 |
+
`int`: Number of patches per image.
|
| 270 |
+
"""
|
| 271 |
+
min_patches = images_kwargs.get("min_patches", self.min_patches) if images_kwargs else self.min_patches
|
| 272 |
+
max_patches = images_kwargs.get("max_patches", self.max_patches) if images_kwargs else self.max_patches
|
| 273 |
+
patch_size = images_kwargs.get("patch_size", self.size) if images_kwargs else self.size
|
| 274 |
+
crop_to_patches = (
|
| 275 |
+
images_kwargs.get("crop_to_patches", self.crop_to_patches) if images_kwargs else self.crop_to_patches
|
| 276 |
+
)
|
| 277 |
+
|
| 278 |
+
num_patches = 1
|
| 279 |
+
if crop_to_patches and max_patches > 1:
|
| 280 |
+
if isinstance(patch_size, dict):
|
| 281 |
+
patch_height, patch_width = patch_size["height"], patch_size["width"]
|
| 282 |
+
else:
|
| 283 |
+
patch_height, patch_width = patch_size.height, patch_size.width
|
| 284 |
+
num_columns, num_rows = get_optimal_tiled_canvas(
|
| 285 |
+
(height, width), (patch_height, patch_width), min_patches, max_patches
|
| 286 |
+
)
|
| 287 |
+
if num_columns * num_rows > 1:
|
| 288 |
+
num_patches += num_columns * num_rows
|
| 289 |
+
|
| 290 |
+
return num_patches
|
| 291 |
+
|
| 292 |
+
|
| 293 |
+
__all__ = ["Cohere2VisionImageProcessor"]
|
third_party/transformers/src/transformers/models/cohere2_vision/modeling_cohere2_vision.py
ADDED
|
@@ -0,0 +1,388 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨
|
| 2 |
+
# This file was automatically generated from src/transformers/models/cohere2_vision/modular_cohere2_vision.py.
|
| 3 |
+
# Do NOT edit this file manually as any edits will be overwritten by the generation of
|
| 4 |
+
# the file from the modular. If any change should be done, please apply the change to the
|
| 5 |
+
# modular_cohere2_vision.py file directly. One of our CI enforces this.
|
| 6 |
+
# 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨
|
| 7 |
+
# Copyright 2025 the Cohere Inc. team. All rights reserved.
|
| 8 |
+
#
|
| 9 |
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
| 10 |
+
# you may not use this file except in compliance with the License.
|
| 11 |
+
# You may obtain a copy of the License at
|
| 12 |
+
#
|
| 13 |
+
# http://www.apache.org/licenses/LICENSE-2.0
|
| 14 |
+
#
|
| 15 |
+
# Unless required by applicable law or agreed to in writing, software
|
| 16 |
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
| 17 |
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 18 |
+
# See the License for the specific language governing permissions and
|
| 19 |
+
# limitations under the License.
|
| 20 |
+
from dataclasses import dataclass
|
| 21 |
+
|
| 22 |
+
import torch
|
| 23 |
+
from torch import nn
|
| 24 |
+
|
| 25 |
+
from ...cache_utils import Cache
|
| 26 |
+
from ...generation import GenerationMixin
|
| 27 |
+
from ...modeling_flash_attention_utils import FlashAttentionKwargs
|
| 28 |
+
from ...modeling_outputs import BaseModelOutputWithPast, BaseModelOutputWithPooling, ModelOutput
|
| 29 |
+
from ...modeling_utils import PreTrainedModel
|
| 30 |
+
from ...processing_utils import Unpack
|
| 31 |
+
from ...utils import TransformersKwargs, auto_docstring, can_return_tuple, torch_compilable_check
|
| 32 |
+
from ..auto import AutoModel
|
| 33 |
+
from .configuration_cohere2_vision import Cohere2VisionConfig
|
| 34 |
+
|
| 35 |
+
|
| 36 |
+
class Cohere2VisionMultiModalProjector(nn.Module):
|
| 37 |
+
def __init__(self, config: Cohere2VisionConfig):
|
| 38 |
+
super().__init__()
|
| 39 |
+
self.config = config
|
| 40 |
+
self.downsample_factor = config.downsample_factor
|
| 41 |
+
self.intermediate_size = config.alignment_intermediate_size
|
| 42 |
+
self.linear_1 = nn.Linear(
|
| 43 |
+
config.vision_config.hidden_size * (config.downsample_factor**2), self.intermediate_size, bias=True
|
| 44 |
+
)
|
| 45 |
+
self.act = nn.SiLU()
|
| 46 |
+
self.linear_2 = nn.Linear(self.intermediate_size // 2, config.text_config.hidden_size, bias=True)
|
| 47 |
+
|
| 48 |
+
def pixel_shuffle(self, image_features): # B, S, D
|
| 49 |
+
batch_size, seq_length, feature_dim = image_features.shape
|
| 50 |
+
height = width = int(seq_length**0.5)
|
| 51 |
+
image_features = image_features.reshape(image_features.shape[0], width, height, -1)
|
| 52 |
+
channels = image_features.shape[-1]
|
| 53 |
+
image_features = image_features.reshape(
|
| 54 |
+
batch_size, width, int(height / self.downsample_factor), int(channels * self.downsample_factor)
|
| 55 |
+
)
|
| 56 |
+
image_features = image_features.permute(0, 2, 1, 3)
|
| 57 |
+
image_features = image_features.reshape(
|
| 58 |
+
batch_size, int(height / self.downsample_factor), int(width / self.downsample_factor), -1
|
| 59 |
+
)
|
| 60 |
+
image_features = image_features.permute(0, 2, 1, 3)
|
| 61 |
+
return image_features
|
| 62 |
+
|
| 63 |
+
def forward(self, image_features):
|
| 64 |
+
image_features = self.pixel_shuffle(image_features)
|
| 65 |
+
hidden_states = self.linear_1(image_features)
|
| 66 |
+
|
| 67 |
+
# Split along last dimension and apply SwiGLU
|
| 68 |
+
x, gate = hidden_states.chunk(2, dim=-1)
|
| 69 |
+
hidden_states = self.act(gate) * x
|
| 70 |
+
|
| 71 |
+
hidden_states = self.linear_2(hidden_states)
|
| 72 |
+
return hidden_states
|
| 73 |
+
|
| 74 |
+
|
| 75 |
+
@dataclass
|
| 76 |
+
@auto_docstring(
|
| 77 |
+
custom_intro="""
|
| 78 |
+
Base class for Cohere2Vision outputs, with hidden states and attentions.
|
| 79 |
+
"""
|
| 80 |
+
)
|
| 81 |
+
class Cohere2VisionModelOutputWithPast(BaseModelOutputWithPast):
|
| 82 |
+
r"""
|
| 83 |
+
past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`):
|
| 84 |
+
It is a [`~cache_utils.Cache`] instance. For more details, see our [kv cache guide](https://huggingface.co/docs/transformers/en/kv_cache).
|
| 85 |
+
|
| 86 |
+
Contains pre-computed hidden-states (key and values in the self-attention blocks) that can be used (see
|
| 87 |
+
`past_key_values` input) to speed up sequential decoding.
|
| 88 |
+
image_hidden_states (`torch.FloatTensor`, *optional*):
|
| 89 |
+
A `torch.FloatTensor` of size `(batch_size, num_images, sequence_length, hidden_size)`.
|
| 90 |
+
image_hidden_states of the model produced by the vision encoder and after projecting the last hidden state.
|
| 91 |
+
"""
|
| 92 |
+
|
| 93 |
+
image_hidden_states: torch.FloatTensor | None = None
|
| 94 |
+
|
| 95 |
+
|
| 96 |
+
@dataclass
|
| 97 |
+
@auto_docstring(
|
| 98 |
+
custom_intro="""
|
| 99 |
+
Base class for Cohere2Vision causal language model (or autoregressive) outputs.
|
| 100 |
+
"""
|
| 101 |
+
)
|
| 102 |
+
class Cohere2VisionCausalLMOutputWithPast(ModelOutput):
|
| 103 |
+
r"""
|
| 104 |
+
loss (`torch.FloatTensor` of shape `(1,)`, *optional*, returned when `labels` is provided):
|
| 105 |
+
Language modeling loss (for next-token prediction).
|
| 106 |
+
logits (`torch.FloatTensor` of shape `(batch_size, sequence_length, config.vocab_size)`):
|
| 107 |
+
Prediction scores of the language modeling head (scores for each vocabulary token before SoftMax).
|
| 108 |
+
past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`):
|
| 109 |
+
It is a [`~cache_utils.Cache`] instance. For more details, see our [kv cache guide](https://huggingface.co/docs/transformers/en/kv_cache).
|
| 110 |
+
|
| 111 |
+
Contains pre-computed hidden-states (key and values in the self-attention blocks) that can be used (see
|
| 112 |
+
`past_key_values` input) to speed up sequential decoding.
|
| 113 |
+
image_hidden_states (`torch.FloatTensor`, *optional*):
|
| 114 |
+
A `torch.FloatTensor` of size `(batch_size, num_images, sequence_length, hidden_size)`.
|
| 115 |
+
image_hidden_states of the model produced by the vision encoder and after projecting the last hidden state.
|
| 116 |
+
"""
|
| 117 |
+
|
| 118 |
+
loss: torch.FloatTensor | None = None
|
| 119 |
+
logits: torch.FloatTensor | None = None
|
| 120 |
+
past_key_values: Cache | None = None
|
| 121 |
+
hidden_states: tuple[torch.FloatTensor] | None = None
|
| 122 |
+
attentions: tuple[torch.FloatTensor] | None = None
|
| 123 |
+
image_hidden_states: torch.FloatTensor | None = None
|
| 124 |
+
|
| 125 |
+
|
| 126 |
+
@auto_docstring
|
| 127 |
+
class Cohere2VisionPreTrainedModel(PreTrainedModel):
|
| 128 |
+
config: Cohere2VisionConfig
|
| 129 |
+
base_model_prefix = "model"
|
| 130 |
+
input_modalities = ("image", "text")
|
| 131 |
+
supports_gradient_checkpointing = True
|
| 132 |
+
_skip_keys_device_placement = "past_key_values"
|
| 133 |
+
|
| 134 |
+
_supports_flash_attn = True
|
| 135 |
+
_supports_sdpa = True
|
| 136 |
+
_can_compile_fullgraph = False
|
| 137 |
+
_supports_flex_attn = True
|
| 138 |
+
_supports_attention_backend = True
|
| 139 |
+
|
| 140 |
+
|
| 141 |
+
@auto_docstring(
|
| 142 |
+
custom_intro="""
|
| 143 |
+
The Cohere2Vision model which consists of a vision backbone and a language model, without a language modeling head.
|
| 144 |
+
"""
|
| 145 |
+
)
|
| 146 |
+
class Cohere2VisionModel(Cohere2VisionPreTrainedModel):
|
| 147 |
+
def __init__(self, config: Cohere2VisionConfig):
|
| 148 |
+
super().__init__(config)
|
| 149 |
+
self.vision_tower = AutoModel.from_config(config.vision_config)
|
| 150 |
+
|
| 151 |
+
self.multi_modal_projector = Cohere2VisionMultiModalProjector(config)
|
| 152 |
+
self.language_model = AutoModel.from_config(config.text_config)
|
| 153 |
+
self.post_init()
|
| 154 |
+
|
| 155 |
+
def get_input_embeddings(self):
|
| 156 |
+
return self.language_model.get_input_embeddings()
|
| 157 |
+
|
| 158 |
+
def set_input_embeddings(self, value):
|
| 159 |
+
self.language_model.set_input_embeddings(value)
|
| 160 |
+
|
| 161 |
+
@can_return_tuple
|
| 162 |
+
@auto_docstring(
|
| 163 |
+
custom_intro="Obtains image last hidden states from the vision tower and apply multimodal projection."
|
| 164 |
+
)
|
| 165 |
+
def get_image_features(
|
| 166 |
+
self, pixel_values: torch.FloatTensor, **kwargs: Unpack[TransformersKwargs]
|
| 167 |
+
) -> tuple | BaseModelOutputWithPooling:
|
| 168 |
+
image_outputs = self.vision_tower(pixel_values, return_dict=True, **kwargs)
|
| 169 |
+
selected_image_feature = image_outputs.last_hidden_state
|
| 170 |
+
image_outputs.pooler_output = self.multi_modal_projector(selected_image_feature)
|
| 171 |
+
|
| 172 |
+
return image_outputs
|
| 173 |
+
|
| 174 |
+
def get_placeholder_mask(
|
| 175 |
+
self, input_ids: torch.LongTensor, inputs_embeds: torch.FloatTensor, image_features: torch.FloatTensor
|
| 176 |
+
):
|
| 177 |
+
"""
|
| 178 |
+
Obtains multimodal placeholder mask from `input_ids` or `inputs_embeds`, and checks that the placeholder token count is
|
| 179 |
+
equal to the length of multimodal features. If the lengths are different, an error is raised.
|
| 180 |
+
"""
|
| 181 |
+
if input_ids is None:
|
| 182 |
+
special_image_mask = inputs_embeds == self.get_input_embeddings()(
|
| 183 |
+
torch.tensor(self.config.image_token_id, dtype=torch.long, device=inputs_embeds.device)
|
| 184 |
+
)
|
| 185 |
+
special_image_mask = special_image_mask.all(-1)
|
| 186 |
+
else:
|
| 187 |
+
special_image_mask = input_ids == self.config.image_token_id
|
| 188 |
+
|
| 189 |
+
n_image_tokens = special_image_mask.sum()
|
| 190 |
+
n_image_features = image_features.shape[0] * image_features.shape[1]
|
| 191 |
+
special_image_mask = special_image_mask.unsqueeze(-1).expand_as(inputs_embeds).to(inputs_embeds.device)
|
| 192 |
+
torch_compilable_check(
|
| 193 |
+
inputs_embeds[special_image_mask].numel() == image_features.numel(),
|
| 194 |
+
f"Image features and image tokens do not match, tokens: {n_image_tokens}, features: {n_image_features}",
|
| 195 |
+
)
|
| 196 |
+
return special_image_mask
|
| 197 |
+
|
| 198 |
+
@can_return_tuple
|
| 199 |
+
@auto_docstring
|
| 200 |
+
def forward(
|
| 201 |
+
self,
|
| 202 |
+
input_ids: torch.LongTensor | None = None,
|
| 203 |
+
pixel_values: torch.FloatTensor | None = None,
|
| 204 |
+
attention_mask: torch.Tensor | None = None,
|
| 205 |
+
position_ids: torch.LongTensor | None = None,
|
| 206 |
+
past_key_values: Cache | None = None,
|
| 207 |
+
inputs_embeds: torch.FloatTensor | None = None,
|
| 208 |
+
use_cache: bool | None = None,
|
| 209 |
+
**kwargs: Unpack[FlashAttentionKwargs],
|
| 210 |
+
) -> tuple | Cohere2VisionModelOutputWithPast:
|
| 211 |
+
if (input_ids is None) ^ (inputs_embeds is not None):
|
| 212 |
+
raise ValueError("You must specify exactly one of input_ids or inputs_embeds")
|
| 213 |
+
|
| 214 |
+
if inputs_embeds is None:
|
| 215 |
+
inputs_embeds = self.get_input_embeddings()(input_ids)
|
| 216 |
+
|
| 217 |
+
if pixel_values is not None:
|
| 218 |
+
image_features = self.get_image_features(pixel_values, return_dict=True).pooler_output
|
| 219 |
+
image_features = image_features.to(inputs_embeds.device, inputs_embeds.dtype)
|
| 220 |
+
special_image_mask = self.get_placeholder_mask(
|
| 221 |
+
input_ids, inputs_embeds=inputs_embeds, image_features=image_features
|
| 222 |
+
)
|
| 223 |
+
inputs_embeds = inputs_embeds.masked_scatter(special_image_mask, image_features)
|
| 224 |
+
|
| 225 |
+
outputs = self.language_model(
|
| 226 |
+
attention_mask=attention_mask,
|
| 227 |
+
position_ids=position_ids,
|
| 228 |
+
past_key_values=past_key_values,
|
| 229 |
+
inputs_embeds=inputs_embeds,
|
| 230 |
+
use_cache=use_cache,
|
| 231 |
+
**kwargs,
|
| 232 |
+
)
|
| 233 |
+
|
| 234 |
+
return Cohere2VisionModelOutputWithPast(
|
| 235 |
+
last_hidden_state=outputs.last_hidden_state,
|
| 236 |
+
past_key_values=outputs.past_key_values,
|
| 237 |
+
hidden_states=outputs.hidden_states,
|
| 238 |
+
attentions=outputs.attentions,
|
| 239 |
+
image_hidden_states=image_features if pixel_values is not None else None,
|
| 240 |
+
)
|
| 241 |
+
|
| 242 |
+
|
| 243 |
+
@auto_docstring(
|
| 244 |
+
custom_intro="""
|
| 245 |
+
The COHERE2_VISION model which consists of a vision backbone and a language model.
|
| 246 |
+
"""
|
| 247 |
+
)
|
| 248 |
+
class Cohere2VisionForConditionalGeneration(Cohere2VisionPreTrainedModel, GenerationMixin):
|
| 249 |
+
_tied_weights_keys = {"lm_head.weight": "model.language_model.embed_tokens.weight"}
|
| 250 |
+
|
| 251 |
+
def __init__(self, config: Cohere2VisionConfig):
|
| 252 |
+
super().__init__(config)
|
| 253 |
+
self.model = Cohere2VisionModel(config)
|
| 254 |
+
self.lm_head = nn.Linear(config.text_config.hidden_size, config.text_config.vocab_size, bias=False)
|
| 255 |
+
self.post_init()
|
| 256 |
+
|
| 257 |
+
def get_input_embeddings(self):
|
| 258 |
+
return self.model.get_input_embeddings()
|
| 259 |
+
|
| 260 |
+
def set_input_embeddings(self, value):
|
| 261 |
+
self.model.set_input_embeddings(value)
|
| 262 |
+
|
| 263 |
+
def get_output_embeddings(self) -> nn.Module:
|
| 264 |
+
return self.lm_head
|
| 265 |
+
|
| 266 |
+
@auto_docstring
|
| 267 |
+
def get_image_features(
|
| 268 |
+
self, pixel_values: torch.FloatTensor, **kwargs: Unpack[TransformersKwargs]
|
| 269 |
+
) -> tuple | BaseModelOutputWithPooling:
|
| 270 |
+
return self.model.get_image_features(pixel_values=pixel_values, **kwargs)
|
| 271 |
+
|
| 272 |
+
@can_return_tuple
|
| 273 |
+
@auto_docstring
|
| 274 |
+
def forward(
|
| 275 |
+
self,
|
| 276 |
+
input_ids: torch.LongTensor | None = None,
|
| 277 |
+
pixel_values: torch.FloatTensor | None = None,
|
| 278 |
+
attention_mask: torch.Tensor | None = None,
|
| 279 |
+
position_ids: torch.LongTensor | None = None,
|
| 280 |
+
past_key_values: Cache | None = None,
|
| 281 |
+
inputs_embeds: torch.FloatTensor | None = None,
|
| 282 |
+
labels: torch.LongTensor | None = None,
|
| 283 |
+
use_cache: bool | None = None,
|
| 284 |
+
logits_to_keep: int | torch.Tensor = 0,
|
| 285 |
+
image_sizes: torch.Tensor | None = None,
|
| 286 |
+
**kwargs: Unpack[TransformersKwargs],
|
| 287 |
+
) -> tuple | Cohere2VisionCausalLMOutputWithPast:
|
| 288 |
+
r"""
|
| 289 |
+
labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*):
|
| 290 |
+
Labels for computing the masked language modeling loss. Indices should either be in `[0, ...,
|
| 291 |
+
config.vocab_size]` or -100 (see `input_ids` docstring). Tokens with indices set to `-100` are ignored
|
| 292 |
+
(masked), the loss is only computed for the tokens with labels in `[0, ..., config.vocab_size]`.
|
| 293 |
+
|
| 294 |
+
Example:
|
| 295 |
+
|
| 296 |
+
```python
|
| 297 |
+
>>> from transformers import AutoProcessor, Cohere2VisionForConditionalGeneration
|
| 298 |
+
>>> import torch
|
| 299 |
+
|
| 300 |
+
>>> processor = AutoProcessor.from_pretrained("CohereLabs/command-a-vision-07-2025", use_fast=True)
|
| 301 |
+
>>> model = Cohere2VisionForConditionalGeneration.from_pretrained("CohereLabs/command-a-vision-07-2025", device_map="auto")
|
| 302 |
+
|
| 303 |
+
>>> messages = [
|
| 304 |
+
... {
|
| 305 |
+
... "role": "user",
|
| 306 |
+
... "content": [
|
| 307 |
+
... {
|
| 308 |
+
... "type": "image",
|
| 309 |
+
... "url": "https://images.pexels.com/photos/1108099/pexels-photo-1108099.jpeg",
|
| 310 |
+
... },
|
| 311 |
+
... {"type": "text", "text": "what is in this image?"},
|
| 312 |
+
... ],
|
| 313 |
+
... },
|
| 314 |
+
... ]
|
| 315 |
+
|
| 316 |
+
>>> inputs = processor.apply_chat_template(
|
| 317 |
+
... messages, padding=True, add_generation_prompt=True, tokenize=True, return_dict=True, return_tensors="pt",
|
| 318 |
+
... ).to(model.device)
|
| 319 |
+
|
| 320 |
+
>>> gen_tokens = model.generate(**inputs, max_new_tokens=300, do_sample=True, temperature=0.3)
|
| 321 |
+
>>> processor.tokenizer.decode(gen_tokens[0][inputs.input_ids.shape[1]:], skip_special_tokens=True)
|
| 322 |
+
```"""
|
| 323 |
+
outputs = self.model(
|
| 324 |
+
input_ids=input_ids,
|
| 325 |
+
pixel_values=pixel_values,
|
| 326 |
+
attention_mask=attention_mask,
|
| 327 |
+
position_ids=position_ids,
|
| 328 |
+
past_key_values=past_key_values,
|
| 329 |
+
inputs_embeds=inputs_embeds,
|
| 330 |
+
use_cache=use_cache,
|
| 331 |
+
image_sizes=image_sizes,
|
| 332 |
+
**kwargs,
|
| 333 |
+
)
|
| 334 |
+
|
| 335 |
+
hidden_states = outputs[0]
|
| 336 |
+
# Only compute necessary logits, and do not upcast them to float if we are not computing the loss
|
| 337 |
+
slice_indices = slice(-logits_to_keep, None) if isinstance(logits_to_keep, int) else logits_to_keep
|
| 338 |
+
logits = self.lm_head(hidden_states[:, slice_indices, :])
|
| 339 |
+
|
| 340 |
+
loss = None
|
| 341 |
+
if labels is not None:
|
| 342 |
+
loss = self.loss_function(
|
| 343 |
+
logits=logits, labels=labels, vocab_size=self.config.text_config.vocab_size, **kwargs
|
| 344 |
+
)
|
| 345 |
+
|
| 346 |
+
return Cohere2VisionCausalLMOutputWithPast(
|
| 347 |
+
loss=loss,
|
| 348 |
+
logits=logits,
|
| 349 |
+
past_key_values=outputs.past_key_values,
|
| 350 |
+
hidden_states=outputs.hidden_states,
|
| 351 |
+
attentions=outputs.attentions,
|
| 352 |
+
image_hidden_states=outputs.image_hidden_states,
|
| 353 |
+
)
|
| 354 |
+
|
| 355 |
+
def prepare_inputs_for_generation(
|
| 356 |
+
self,
|
| 357 |
+
input_ids,
|
| 358 |
+
past_key_values=None,
|
| 359 |
+
inputs_embeds=None,
|
| 360 |
+
pixel_values=None,
|
| 361 |
+
attention_mask=None,
|
| 362 |
+
logits_to_keep=None,
|
| 363 |
+
is_first_iteration=False,
|
| 364 |
+
**kwargs,
|
| 365 |
+
):
|
| 366 |
+
# Overwritten -- in specific circumstances we don't want to forward image inputs to the model
|
| 367 |
+
|
| 368 |
+
model_inputs = super().prepare_inputs_for_generation(
|
| 369 |
+
input_ids,
|
| 370 |
+
past_key_values=past_key_values,
|
| 371 |
+
inputs_embeds=inputs_embeds,
|
| 372 |
+
attention_mask=attention_mask,
|
| 373 |
+
logits_to_keep=logits_to_keep,
|
| 374 |
+
is_first_iteration=is_first_iteration,
|
| 375 |
+
**kwargs,
|
| 376 |
+
)
|
| 377 |
+
|
| 378 |
+
if is_first_iteration or not kwargs.get("use_cache", True):
|
| 379 |
+
# Pixel values are used only in the first iteration if available
|
| 380 |
+
# In subsequent iterations, they are already merged with text and cached
|
| 381 |
+
# NOTE: first iteration doesn't have to be prefill, it can be the first
|
| 382 |
+
# iteration with a question and cached system prompt (continue generate from cache)
|
| 383 |
+
model_inputs["pixel_values"] = pixel_values
|
| 384 |
+
|
| 385 |
+
return model_inputs
|
| 386 |
+
|
| 387 |
+
|
| 388 |
+
__all__ = ["Cohere2VisionForConditionalGeneration", "Cohere2VisionPreTrainedModel", "Cohere2VisionModel"]
|
third_party/transformers/src/transformers/models/cohere2_vision/modular_cohere2_vision.py
ADDED
|
@@ -0,0 +1,328 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright 2025 the Cohere Inc. team. All rights reserved.
|
| 2 |
+
#
|
| 3 |
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
| 4 |
+
# you may not use this file except in compliance with the License.
|
| 5 |
+
# You may obtain a copy of the License at
|
| 6 |
+
#
|
| 7 |
+
# http://www.apache.org/licenses/LICENSE-2.0
|
| 8 |
+
#
|
| 9 |
+
# Unless required by applicable law or agreed to in writing, software
|
| 10 |
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
| 11 |
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 12 |
+
# See the License for the specific language governing permissions and
|
| 13 |
+
# limitations under the License.
|
| 14 |
+
"""PyTorch AyaVision model."""
|
| 15 |
+
|
| 16 |
+
from functools import lru_cache
|
| 17 |
+
|
| 18 |
+
import numpy as np
|
| 19 |
+
import torch
|
| 20 |
+
from torch import nn
|
| 21 |
+
|
| 22 |
+
from transformers.models.aya_vision.modeling_aya_vision import (
|
| 23 |
+
AyaVisionCausalLMOutputWithPast,
|
| 24 |
+
AyaVisionForConditionalGeneration,
|
| 25 |
+
AyaVisionModel,
|
| 26 |
+
AyaVisionModelOutputWithPast,
|
| 27 |
+
AyaVisionPreTrainedModel,
|
| 28 |
+
)
|
| 29 |
+
from transformers.models.got_ocr2.image_processing_got_ocr2 import GotOcr2ImageProcessor
|
| 30 |
+
|
| 31 |
+
from ...cache_utils import Cache
|
| 32 |
+
from ...modeling_flash_attention_utils import FlashAttentionKwargs
|
| 33 |
+
from ...modeling_outputs import BaseModelOutputWithPooling
|
| 34 |
+
from ...processing_utils import ImagesKwargs, Unpack
|
| 35 |
+
from ...utils import TransformersKwargs, auto_docstring, can_return_tuple, logging
|
| 36 |
+
from .configuration_cohere2_vision import Cohere2VisionConfig
|
| 37 |
+
|
| 38 |
+
|
| 39 |
+
logger = logging.get_logger(__name__)
|
| 40 |
+
|
| 41 |
+
|
| 42 |
+
class Cohere2VisionMultiModalProjector(nn.Module):
|
| 43 |
+
def __init__(self, config: Cohere2VisionConfig):
|
| 44 |
+
super().__init__()
|
| 45 |
+
self.config = config
|
| 46 |
+
self.downsample_factor = config.downsample_factor
|
| 47 |
+
self.intermediate_size = config.alignment_intermediate_size
|
| 48 |
+
self.linear_1 = nn.Linear(
|
| 49 |
+
config.vision_config.hidden_size * (config.downsample_factor**2), self.intermediate_size, bias=True
|
| 50 |
+
)
|
| 51 |
+
self.act = nn.SiLU()
|
| 52 |
+
self.linear_2 = nn.Linear(self.intermediate_size // 2, config.text_config.hidden_size, bias=True)
|
| 53 |
+
|
| 54 |
+
def pixel_shuffle(self, image_features): # B, S, D
|
| 55 |
+
batch_size, seq_length, feature_dim = image_features.shape
|
| 56 |
+
height = width = int(seq_length**0.5)
|
| 57 |
+
image_features = image_features.reshape(image_features.shape[0], width, height, -1)
|
| 58 |
+
channels = image_features.shape[-1]
|
| 59 |
+
image_features = image_features.reshape(
|
| 60 |
+
batch_size, width, int(height / self.downsample_factor), int(channels * self.downsample_factor)
|
| 61 |
+
)
|
| 62 |
+
image_features = image_features.permute(0, 2, 1, 3)
|
| 63 |
+
image_features = image_features.reshape(
|
| 64 |
+
batch_size, int(height / self.downsample_factor), int(width / self.downsample_factor), -1
|
| 65 |
+
)
|
| 66 |
+
image_features = image_features.permute(0, 2, 1, 3)
|
| 67 |
+
return image_features
|
| 68 |
+
|
| 69 |
+
def forward(self, image_features):
|
| 70 |
+
image_features = self.pixel_shuffle(image_features)
|
| 71 |
+
hidden_states = self.linear_1(image_features)
|
| 72 |
+
|
| 73 |
+
# Split along last dimension and apply SwiGLU
|
| 74 |
+
x, gate = hidden_states.chunk(2, dim=-1)
|
| 75 |
+
hidden_states = self.act(gate) * x
|
| 76 |
+
|
| 77 |
+
hidden_states = self.linear_2(hidden_states)
|
| 78 |
+
return hidden_states
|
| 79 |
+
|
| 80 |
+
|
| 81 |
+
class Cohere2VisionModelOutputWithPast(AyaVisionModelOutputWithPast):
|
| 82 |
+
pass
|
| 83 |
+
|
| 84 |
+
|
| 85 |
+
class Cohere2VisionCausalLMOutputWithPast(AyaVisionCausalLMOutputWithPast):
|
| 86 |
+
pass
|
| 87 |
+
|
| 88 |
+
|
| 89 |
+
class Cohere2VisionPreTrainedModel(AyaVisionPreTrainedModel):
|
| 90 |
+
base_model_prefix = "model"
|
| 91 |
+
|
| 92 |
+
|
| 93 |
+
class Cohere2VisionModel(AyaVisionModel):
|
| 94 |
+
@can_return_tuple
|
| 95 |
+
@auto_docstring(
|
| 96 |
+
custom_intro="Obtains image last hidden states from the vision tower and apply multimodal projection."
|
| 97 |
+
)
|
| 98 |
+
def get_image_features(
|
| 99 |
+
self, pixel_values: torch.FloatTensor, **kwargs: Unpack[TransformersKwargs]
|
| 100 |
+
) -> tuple | BaseModelOutputWithPooling:
|
| 101 |
+
image_outputs = self.vision_tower(pixel_values, return_dict=True, **kwargs)
|
| 102 |
+
selected_image_feature = image_outputs.last_hidden_state
|
| 103 |
+
image_outputs.pooler_output = self.multi_modal_projector(selected_image_feature)
|
| 104 |
+
|
| 105 |
+
return image_outputs
|
| 106 |
+
|
| 107 |
+
def forward(
|
| 108 |
+
self,
|
| 109 |
+
input_ids: torch.LongTensor | None = None,
|
| 110 |
+
pixel_values: torch.FloatTensor | None = None,
|
| 111 |
+
attention_mask: torch.Tensor | None = None,
|
| 112 |
+
position_ids: torch.LongTensor | None = None,
|
| 113 |
+
past_key_values: Cache | None = None,
|
| 114 |
+
inputs_embeds: torch.FloatTensor | None = None,
|
| 115 |
+
use_cache: bool | None = None,
|
| 116 |
+
**kwargs: Unpack[FlashAttentionKwargs],
|
| 117 |
+
) -> tuple | Cohere2VisionModelOutputWithPast:
|
| 118 |
+
if (input_ids is None) ^ (inputs_embeds is not None):
|
| 119 |
+
raise ValueError("You must specify exactly one of input_ids or inputs_embeds")
|
| 120 |
+
|
| 121 |
+
if inputs_embeds is None:
|
| 122 |
+
inputs_embeds = self.get_input_embeddings()(input_ids)
|
| 123 |
+
|
| 124 |
+
if pixel_values is not None:
|
| 125 |
+
image_features = self.get_image_features(pixel_values, return_dict=True).pooler_output
|
| 126 |
+
image_features = image_features.to(inputs_embeds.device, inputs_embeds.dtype)
|
| 127 |
+
special_image_mask = self.get_placeholder_mask(
|
| 128 |
+
input_ids, inputs_embeds=inputs_embeds, image_features=image_features
|
| 129 |
+
)
|
| 130 |
+
inputs_embeds = inputs_embeds.masked_scatter(special_image_mask, image_features)
|
| 131 |
+
|
| 132 |
+
outputs = self.language_model(
|
| 133 |
+
attention_mask=attention_mask,
|
| 134 |
+
position_ids=position_ids,
|
| 135 |
+
past_key_values=past_key_values,
|
| 136 |
+
inputs_embeds=inputs_embeds,
|
| 137 |
+
use_cache=use_cache,
|
| 138 |
+
**kwargs,
|
| 139 |
+
)
|
| 140 |
+
|
| 141 |
+
return Cohere2VisionModelOutputWithPast(
|
| 142 |
+
last_hidden_state=outputs.last_hidden_state,
|
| 143 |
+
past_key_values=outputs.past_key_values,
|
| 144 |
+
hidden_states=outputs.hidden_states,
|
| 145 |
+
attentions=outputs.attentions,
|
| 146 |
+
image_hidden_states=image_features if pixel_values is not None else None,
|
| 147 |
+
)
|
| 148 |
+
|
| 149 |
+
|
| 150 |
+
class Cohere2VisionForConditionalGeneration(AyaVisionForConditionalGeneration):
|
| 151 |
+
@auto_docstring
|
| 152 |
+
def get_image_features(
|
| 153 |
+
self, pixel_values: torch.FloatTensor, **kwargs: Unpack[TransformersKwargs]
|
| 154 |
+
) -> tuple | BaseModelOutputWithPooling:
|
| 155 |
+
return self.model.get_image_features(pixel_values=pixel_values, **kwargs)
|
| 156 |
+
|
| 157 |
+
def forward(
|
| 158 |
+
self,
|
| 159 |
+
input_ids: torch.LongTensor | None = None,
|
| 160 |
+
pixel_values: torch.FloatTensor | None = None,
|
| 161 |
+
attention_mask: torch.Tensor | None = None,
|
| 162 |
+
position_ids: torch.LongTensor | None = None,
|
| 163 |
+
past_key_values: Cache | None = None,
|
| 164 |
+
inputs_embeds: torch.FloatTensor | None = None,
|
| 165 |
+
labels: torch.LongTensor | None = None,
|
| 166 |
+
use_cache: bool | None = None,
|
| 167 |
+
logits_to_keep: int | torch.Tensor = 0,
|
| 168 |
+
image_sizes: torch.Tensor | None = None,
|
| 169 |
+
**kwargs: Unpack[TransformersKwargs],
|
| 170 |
+
) -> tuple | Cohere2VisionCausalLMOutputWithPast:
|
| 171 |
+
r"""
|
| 172 |
+
labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*):
|
| 173 |
+
Labels for computing the masked language modeling loss. Indices should either be in `[0, ...,
|
| 174 |
+
config.vocab_size]` or -100 (see `input_ids` docstring). Tokens with indices set to `-100` are ignored
|
| 175 |
+
(masked), the loss is only computed for the tokens with labels in `[0, ..., config.vocab_size]`.
|
| 176 |
+
|
| 177 |
+
Example:
|
| 178 |
+
|
| 179 |
+
```python
|
| 180 |
+
>>> from transformers import AutoProcessor, Cohere2VisionForConditionalGeneration
|
| 181 |
+
>>> import torch
|
| 182 |
+
|
| 183 |
+
>>> processor = AutoProcessor.from_pretrained("CohereLabs/command-a-vision-07-2025", use_fast=True)
|
| 184 |
+
>>> model = Cohere2VisionForConditionalGeneration.from_pretrained("CohereLabs/command-a-vision-07-2025", device_map="auto")
|
| 185 |
+
|
| 186 |
+
>>> messages = [
|
| 187 |
+
... {
|
| 188 |
+
... "role": "user",
|
| 189 |
+
... "content": [
|
| 190 |
+
... {
|
| 191 |
+
... "type": "image",
|
| 192 |
+
... "url": "https://images.pexels.com/photos/1108099/pexels-photo-1108099.jpeg",
|
| 193 |
+
... },
|
| 194 |
+
... {"type": "text", "text": "what is in this image?"},
|
| 195 |
+
... ],
|
| 196 |
+
... },
|
| 197 |
+
... ]
|
| 198 |
+
|
| 199 |
+
>>> inputs = processor.apply_chat_template(
|
| 200 |
+
... messages, padding=True, add_generation_prompt=True, tokenize=True, return_dict=True, return_tensors="pt",
|
| 201 |
+
... ).to(model.device)
|
| 202 |
+
|
| 203 |
+
>>> gen_tokens = model.generate(**inputs, max_new_tokens=300, do_sample=True, temperature=0.3)
|
| 204 |
+
>>> processor.tokenizer.decode(gen_tokens[0][inputs.input_ids.shape[1]:], skip_special_tokens=True)
|
| 205 |
+
```"""
|
| 206 |
+
outputs = self.model(
|
| 207 |
+
input_ids=input_ids,
|
| 208 |
+
pixel_values=pixel_values,
|
| 209 |
+
attention_mask=attention_mask,
|
| 210 |
+
position_ids=position_ids,
|
| 211 |
+
past_key_values=past_key_values,
|
| 212 |
+
inputs_embeds=inputs_embeds,
|
| 213 |
+
use_cache=use_cache,
|
| 214 |
+
image_sizes=image_sizes,
|
| 215 |
+
**kwargs,
|
| 216 |
+
)
|
| 217 |
+
|
| 218 |
+
hidden_states = outputs[0]
|
| 219 |
+
# Only compute necessary logits, and do not upcast them to float if we are not computing the loss
|
| 220 |
+
slice_indices = slice(-logits_to_keep, None) if isinstance(logits_to_keep, int) else logits_to_keep
|
| 221 |
+
logits = self.lm_head(hidden_states[:, slice_indices, :])
|
| 222 |
+
|
| 223 |
+
loss = None
|
| 224 |
+
if labels is not None:
|
| 225 |
+
loss = self.loss_function(
|
| 226 |
+
logits=logits, labels=labels, vocab_size=self.config.text_config.vocab_size, **kwargs
|
| 227 |
+
)
|
| 228 |
+
|
| 229 |
+
return Cohere2VisionCausalLMOutputWithPast(
|
| 230 |
+
loss=loss,
|
| 231 |
+
logits=logits,
|
| 232 |
+
past_key_values=outputs.past_key_values,
|
| 233 |
+
hidden_states=outputs.hidden_states,
|
| 234 |
+
attentions=outputs.attentions,
|
| 235 |
+
image_hidden_states=outputs.image_hidden_states,
|
| 236 |
+
)
|
| 237 |
+
|
| 238 |
+
|
| 239 |
+
@lru_cache(maxsize=10)
|
| 240 |
+
def get_all_supported_aspect_ratios(max_image_tiles: int) -> list[tuple[int, int]]:
|
| 241 |
+
"""
|
| 242 |
+
Computes all allowed aspect ratios for a given maximum number of input tiles.
|
| 243 |
+
|
| 244 |
+
This function calculates all possible arrangements of tiles that can be formed
|
| 245 |
+
within the constraint of the maximum number of tiles. Each arrangement is
|
| 246 |
+
represented by its aspect ratio (width/height) and the corresponding tile configuration.
|
| 247 |
+
|
| 248 |
+
Args:
|
| 249 |
+
max_image_tiles (`int`):
|
| 250 |
+
The maximum number of tiles allowed.
|
| 251 |
+
|
| 252 |
+
Returns:
|
| 253 |
+
`list[tuple[int, int]]`: A list of tuples, each tuple representing a valid (width, height)
|
| 254 |
+
configuration in terms of number of tiles.
|
| 255 |
+
|
| 256 |
+
Example:
|
| 257 |
+
>>> get_all_supported_aspect_ratios(4)
|
| 258 |
+
[(1, 1), (1, 2), (1, 3), (1, 4), (2, 1), (2, 2), (3, 1), (4, 1)]
|
| 259 |
+
|
| 260 |
+
"""
|
| 261 |
+
aspect_ratios = []
|
| 262 |
+
for width in range(1, max_image_tiles + 1):
|
| 263 |
+
for height in range(1, max_image_tiles + 1):
|
| 264 |
+
if width * height <= max_image_tiles:
|
| 265 |
+
aspect_ratios.append((width, height))
|
| 266 |
+
return aspect_ratios
|
| 267 |
+
|
| 268 |
+
|
| 269 |
+
def get_optimal_tiled_canvas(
|
| 270 |
+
original_image_size: tuple[int, int],
|
| 271 |
+
target_tile_size: tuple[int, int],
|
| 272 |
+
min_image_tiles: int,
|
| 273 |
+
max_image_tiles: int,
|
| 274 |
+
) -> tuple[int, int]:
|
| 275 |
+
possible_resolutions = get_all_supported_aspect_ratios(max_image_tiles)
|
| 276 |
+
possible_resolutions = sorted(possible_resolutions, key=lambda x: x[0] * x[1])
|
| 277 |
+
image_height, image_width = original_image_size
|
| 278 |
+
patch_size_height, patch_size_width = target_tile_size # (height == width)
|
| 279 |
+
|
| 280 |
+
candidate_resolutions = np.array(possible_resolutions) * patch_size_height
|
| 281 |
+
# tiles following (width, height) order to align with aspect ratio convention
|
| 282 |
+
tile_size = np.stack([image_width, image_height])
|
| 283 |
+
required_scales = candidate_resolutions / tile_size
|
| 284 |
+
required_scale = np.min(required_scales, axis=-1, keepdims=True) # [n_resolutions, 1]
|
| 285 |
+
if np.all(required_scale < 1):
|
| 286 |
+
# We are forced to downscale, so try to minimize the amount of downscaling
|
| 287 |
+
best_grid = possible_resolutions[np.argmax(required_scale)]
|
| 288 |
+
else:
|
| 289 |
+
# Pick the resolution that required the least upscaling so that it most closely fits the image
|
| 290 |
+
required_scale = np.where(required_scale < 1.0, 10e9, required_scale)
|
| 291 |
+
best_grid = possible_resolutions[np.argmin(required_scale)]
|
| 292 |
+
return best_grid # (width, height)
|
| 293 |
+
|
| 294 |
+
|
| 295 |
+
class Cohere2VisionImageProcessorKwargs(ImagesKwargs, total=False):
|
| 296 |
+
r"""
|
| 297 |
+
crop_to_patches (`bool`, *optional*, defaults to `False`):
|
| 298 |
+
Whether to crop the image to patches. Can be overridden by the `crop_to_patches` parameter in the
|
| 299 |
+
`preprocess` method.
|
| 300 |
+
min_patches (`int`, *optional*, defaults to 1):
|
| 301 |
+
The minimum number of patches to be extracted from the image. Only has an effect if `crop_to_patches` is
|
| 302 |
+
set to `True`. Can be overridden by the `min_patches` parameter in the `preprocess` method.
|
| 303 |
+
max_patches (`int`, *optional*, defaults to 12):
|
| 304 |
+
The maximum number of patches to be extracted from the image. Only has an effect if `crop_to_patches` is
|
| 305 |
+
set to `True`. Can be overridden by the `max_patches` parameter in the `preprocess` method.
|
| 306 |
+
"""
|
| 307 |
+
|
| 308 |
+
crop_to_patches: bool
|
| 309 |
+
min_patches: int
|
| 310 |
+
max_patches: int
|
| 311 |
+
|
| 312 |
+
|
| 313 |
+
@auto_docstring
|
| 314 |
+
class Cohere2VisionImageProcessor(GotOcr2ImageProcessor):
|
| 315 |
+
size = {"height": 512, "width": 512}
|
| 316 |
+
min_patches = 1
|
| 317 |
+
max_patches = 12
|
| 318 |
+
crop_to_patches = True
|
| 319 |
+
patch_size = 16
|
| 320 |
+
valid_kwargs = Cohere2VisionImageProcessorKwargs
|
| 321 |
+
|
| 322 |
+
|
| 323 |
+
__all__ = [
|
| 324 |
+
"Cohere2VisionForConditionalGeneration",
|
| 325 |
+
"Cohere2VisionPreTrainedModel",
|
| 326 |
+
"Cohere2VisionModel",
|
| 327 |
+
"Cohere2VisionImageProcessor",
|
| 328 |
+
]
|
third_party/transformers/src/transformers/models/cohere2_vision/processing_cohere2_vision.py
ADDED
|
@@ -0,0 +1,169 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright 2025 HuggingFace Inc. team. All rights reserved.
|
| 2 |
+
#
|
| 3 |
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
| 4 |
+
# you may not use this file except in compliance with the License.
|
| 5 |
+
# You may obtain a copy of the License at
|
| 6 |
+
#
|
| 7 |
+
# http://www.apache.org/licenses/LICENSE-2.0
|
| 8 |
+
#
|
| 9 |
+
# Unless required by applicable law or agreed to in writing, software
|
| 10 |
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
| 11 |
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 12 |
+
# See the License for the specific language governing permissions and
|
| 13 |
+
# limitations under the License.
|
| 14 |
+
|
| 15 |
+
|
| 16 |
+
from ...image_processing_utils import BatchFeature
|
| 17 |
+
from ...image_utils import ImageInput
|
| 18 |
+
from ...processing_utils import MultiModalData, ProcessingKwargs, ProcessorMixin, Unpack
|
| 19 |
+
from ...tokenization_utils_base import PreTokenizedInput, TextInput
|
| 20 |
+
from ...utils import auto_docstring
|
| 21 |
+
|
| 22 |
+
|
| 23 |
+
class Cohere2VisionProcessorKwargs(ProcessingKwargs, total=False):
|
| 24 |
+
_defaults = {
|
| 25 |
+
"text_kwargs": {
|
| 26 |
+
"padding_side": "left",
|
| 27 |
+
"padding": True,
|
| 28 |
+
"return_mm_token_type_ids": False,
|
| 29 |
+
},
|
| 30 |
+
}
|
| 31 |
+
|
| 32 |
+
|
| 33 |
+
@auto_docstring
|
| 34 |
+
class Cohere2VisionProcessor(ProcessorMixin):
|
| 35 |
+
def __init__(
|
| 36 |
+
self,
|
| 37 |
+
image_processor=None,
|
| 38 |
+
tokenizer=None,
|
| 39 |
+
chat_template=None,
|
| 40 |
+
**kwargs,
|
| 41 |
+
):
|
| 42 |
+
super().__init__(image_processor, tokenizer, chat_template=chat_template)
|
| 43 |
+
|
| 44 |
+
self.patch_size = self.image_processor.patch_size
|
| 45 |
+
self.boi_token = tokenizer.boi_token
|
| 46 |
+
self.eoi_token = tokenizer.eoi_token
|
| 47 |
+
self.image_token = tokenizer.image_token
|
| 48 |
+
self.img_line_break_token = tokenizer.img_line_break_token
|
| 49 |
+
self.image_token_id = tokenizer.image_token_id
|
| 50 |
+
|
| 51 |
+
self.image_ids = tokenizer.convert_tokens_to_ids(
|
| 52 |
+
[
|
| 53 |
+
self.image_token,
|
| 54 |
+
self.boi_token,
|
| 55 |
+
self.eoi_token,
|
| 56 |
+
self.img_line_break_token,
|
| 57 |
+
]
|
| 58 |
+
)
|
| 59 |
+
|
| 60 |
+
@auto_docstring
|
| 61 |
+
def __call__(
|
| 62 |
+
self,
|
| 63 |
+
images: ImageInput | None = None,
|
| 64 |
+
text: TextInput | PreTokenizedInput | list[TextInput] | list[PreTokenizedInput] | None = None,
|
| 65 |
+
**kwargs: Unpack[Cohere2VisionProcessorKwargs],
|
| 66 |
+
) -> BatchFeature:
|
| 67 |
+
r"""
|
| 68 |
+
Returns:
|
| 69 |
+
[`BatchFeature`]: A [`BatchFeature`] with the following fields:
|
| 70 |
+
|
| 71 |
+
- **input_ids** -- List of token ids to be fed to a model. Returned when `text` is not `None`.
|
| 72 |
+
- **attention_mask** -- List of indices specifying which tokens should be attended to by the model (when
|
| 73 |
+
`return_attention_mask=True` or if *"attention_mask"* is in `self.model_input_names` and if `text` is not
|
| 74 |
+
`None`).
|
| 75 |
+
- **pixel_values** -- Pixel values to be fed to a model. Returned when `images` is not `None`.
|
| 76 |
+
"""
|
| 77 |
+
if text is None:
|
| 78 |
+
raise ValueError("You have to specify text.")
|
| 79 |
+
elif not isinstance(text, (list, tuple)):
|
| 80 |
+
text = [text]
|
| 81 |
+
|
| 82 |
+
output_kwargs = self._merge_kwargs(
|
| 83 |
+
Cohere2VisionProcessorKwargs,
|
| 84 |
+
tokenizer_init_kwargs=self.tokenizer.init_kwargs,
|
| 85 |
+
**kwargs,
|
| 86 |
+
)
|
| 87 |
+
|
| 88 |
+
# Process images
|
| 89 |
+
image_inputs = {}
|
| 90 |
+
if images is not None:
|
| 91 |
+
image_inputs = self.image_processor(images=images, **output_kwargs["images_kwargs"])
|
| 92 |
+
batch_num_patches = iter(image_inputs.pop("num_patches"))
|
| 93 |
+
processed_text = []
|
| 94 |
+
for sample in text:
|
| 95 |
+
while self.image_token in sample:
|
| 96 |
+
num_patches = next(batch_num_patches)
|
| 97 |
+
img_patches_per_tile = int(self.patch_size**2)
|
| 98 |
+
|
| 99 |
+
img_string = f"{self.boi_token}"
|
| 100 |
+
for idx in range(1, num_patches):
|
| 101 |
+
img_string += "<placeholder>" * img_patches_per_tile + self.img_line_break_token
|
| 102 |
+
img_string += "<placeholder>" * img_patches_per_tile + self.img_line_break_token
|
| 103 |
+
img_string += f"{self.eoi_token}"
|
| 104 |
+
|
| 105 |
+
sample = sample.replace(self.image_token, img_string, 1)
|
| 106 |
+
processed_text.append(sample)
|
| 107 |
+
text = [sample.replace("<placeholder>", self.image_token) for sample in processed_text]
|
| 108 |
+
|
| 109 |
+
return_tensors = output_kwargs["text_kwargs"].pop("return_tensors", None)
|
| 110 |
+
return_mm_token_type_ids = output_kwargs["text_kwargs"].pop("return_mm_token_type_ids", False)
|
| 111 |
+
text_inputs = self.tokenizer(text, **output_kwargs["text_kwargs"], return_tensors=None)
|
| 112 |
+
|
| 113 |
+
if return_mm_token_type_ids:
|
| 114 |
+
text_inputs["mm_token_type_ids"] = self.create_mm_token_type_ids(text_inputs["input_ids"])
|
| 115 |
+
return BatchFeature(data={**text_inputs, **image_inputs}, tensor_type=return_tensors)
|
| 116 |
+
|
| 117 |
+
def _get_num_multimodal_tokens(self, image_sizes=None, **kwargs):
|
| 118 |
+
"""
|
| 119 |
+
Computes the number of placeholder tokens needed for multimodal inputs with the given sizes.
|
| 120 |
+
|
| 121 |
+
Args:
|
| 122 |
+
image_sizes (`list[list[int]]`, *optional*):
|
| 123 |
+
The input sizes formatted as (height, width) per each image.
|
| 124 |
+
|
| 125 |
+
Returns:
|
| 126 |
+
`MultiModalData`: A `MultiModalData` object holding number of tokens per each of the provided
|
| 127 |
+
input modalities, along with other useful data.
|
| 128 |
+
"""
|
| 129 |
+
|
| 130 |
+
vision_data = {}
|
| 131 |
+
if image_sizes is not None:
|
| 132 |
+
images_kwargs = Cohere2VisionProcessorKwargs._defaults.get("images_kwargs", {})
|
| 133 |
+
images_kwargs.update(kwargs)
|
| 134 |
+
|
| 135 |
+
num_image_patches = [
|
| 136 |
+
self.image_processor.get_number_of_image_patches(*image_size, images_kwargs)
|
| 137 |
+
for image_size in image_sizes
|
| 138 |
+
]
|
| 139 |
+
|
| 140 |
+
token_per_patch = int(self.patch_size**2)
|
| 141 |
+
num_image_tokens = [
|
| 142 |
+
2 + sum(token_per_patch + 1 for _ in range(num_patches)) for num_patches in num_image_patches
|
| 143 |
+
] # Add +2 and +1 for BOI/EOI and image break tokens
|
| 144 |
+
vision_data.update({"num_image_tokens": num_image_tokens, "num_image_patches": num_image_patches})
|
| 145 |
+
|
| 146 |
+
return MultiModalData(**vision_data)
|
| 147 |
+
|
| 148 |
+
def batch_decode(self, *args, **kwargs):
|
| 149 |
+
"""
|
| 150 |
+
This method forwards all its arguments to PreTrainedTokenizerFast's [`~PreTrainedTokenizer.batch_decode`]. Please
|
| 151 |
+
refer to the docstring of this method for more information.
|
| 152 |
+
"""
|
| 153 |
+
return self.tokenizer.batch_decode(*args, **kwargs)
|
| 154 |
+
|
| 155 |
+
def decode(self, *args, **kwargs):
|
| 156 |
+
"""
|
| 157 |
+
This method forwards all its arguments to PreTrainedTokenizerFast's [`~PreTrainedTokenizer.decode`]. Please refer to
|
| 158 |
+
the docstring of this method for more information.
|
| 159 |
+
"""
|
| 160 |
+
return self.tokenizer.decode(*args, **kwargs)
|
| 161 |
+
|
| 162 |
+
@property
|
| 163 |
+
def model_input_names(self):
|
| 164 |
+
tokenizer_input_names = self.tokenizer.model_input_names
|
| 165 |
+
image_processor_input_names = self.image_processor.model_input_names
|
| 166 |
+
return list(tokenizer_input_names) + list(image_processor_input_names)
|
| 167 |
+
|
| 168 |
+
|
| 169 |
+
__all__ = ["Cohere2VisionProcessor"]
|