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/altclip/__init__.py +28 -0
- third_party/transformers/src/transformers/models/altclip/configuration_altclip.py +224 -0
- third_party/transformers/src/transformers/models/altclip/modeling_altclip.py +1185 -0
- third_party/transformers/src/transformers/models/altclip/processing_altclip.py +28 -0
- third_party/transformers/src/transformers/models/auto/__init__.py +33 -0
- third_party/transformers/src/transformers/models/auto/auto_factory.py +662 -0
- third_party/transformers/src/transformers/models/auto/configuration_auto.py +1551 -0
- third_party/transformers/src/transformers/models/auto/feature_extraction_auto.py +386 -0
- third_party/transformers/src/transformers/models/auto/image_processing_auto.py +819 -0
- third_party/transformers/src/transformers/models/auto/modeling_auto.py +0 -0
- third_party/transformers/src/transformers/models/auto/processing_auto.py +465 -0
- third_party/transformers/src/transformers/models/auto/tokenization_auto.py +871 -0
- third_party/transformers/src/transformers/models/auto/video_processing_auto.py +424 -0
- third_party/transformers/src/transformers/models/autoformer/__init__.py +27 -0
- third_party/transformers/src/transformers/models/autoformer/configuration_autoformer.py +169 -0
- third_party/transformers/src/transformers/models/autoformer/modeling_autoformer.py +1832 -0
- third_party/transformers/src/transformers/models/bark/__init__.py +28 -0
- third_party/transformers/src/transformers/models/bark/configuration_bark.py +275 -0
- third_party/transformers/src/transformers/models/bark/convert_suno_to_hf.py +261 -0
- third_party/transformers/src/transformers/models/bark/modeling_bark.py +1521 -0
- third_party/transformers/src/transformers/models/bark/processing_bark.py +314 -0
- third_party/transformers/src/transformers/models/bart/__init__.py +28 -0
- third_party/transformers/src/transformers/models/bart/configuration_bart.py +86 -0
- third_party/transformers/src/transformers/models/bart/convert_bart_original_pytorch_checkpoint_to_pytorch.py +155 -0
- third_party/transformers/src/transformers/models/bart/modeling_bart.py +1322 -0
- third_party/transformers/src/transformers/models/bart/tokenization_bart.py +23 -0
- third_party/transformers/src/transformers/models/bert/__init__.py +28 -0
- third_party/transformers/src/transformers/models/bert/configuration_bert.py +66 -0
- third_party/transformers/src/transformers/models/bert/convert_bert_original_tf2_checkpoint_to_pytorch.py +246 -0
- third_party/transformers/src/transformers/models/bert/convert_bert_original_tf_checkpoint_to_pytorch.py +61 -0
- third_party/transformers/src/transformers/models/bert/convert_bert_token_dropping_original_tf2_checkpoint_to_pytorch.py +188 -0
- third_party/transformers/src/transformers/models/bert/modeling_bert.py +1395 -0
- third_party/transformers/src/transformers/models/bert/tokenization_bert.py +140 -0
- third_party/transformers/src/transformers/models/bert/tokenization_bert_legacy.py +476 -0
- third_party/transformers/src/transformers/models/bertweet/__init__.py +26 -0
- third_party/transformers/src/transformers/models/bertweet/tokenization_bertweet.py +698 -0
- third_party/transformers/src/transformers/models/biogpt/__init__.py +28 -0
- third_party/transformers/src/transformers/models/biogpt/configuration_biogpt.py +64 -0
- third_party/transformers/src/transformers/models/biogpt/convert_biogpt_original_pytorch_checkpoint_to_pytorch.py +291 -0
- third_party/transformers/src/transformers/models/biogpt/modeling_biogpt.py +678 -0
- third_party/transformers/src/transformers/models/biogpt/modular_biogpt.py +509 -0
- third_party/transformers/src/transformers/models/biogpt/tokenization_biogpt.py +329 -0
- third_party/transformers/src/transformers/models/bit/__init__.py +29 -0
- third_party/transformers/src/transformers/models/bit/configuration_bit.py +95 -0
- third_party/transformers/src/transformers/models/bit/convert_bit_to_pytorch.py +178 -0
- third_party/transformers/src/transformers/models/bit/image_processing_bit.py +36 -0
- third_party/transformers/src/transformers/models/bit/image_processing_pil_bit.py +36 -0
- third_party/transformers/src/transformers/models/bit/modeling_bit.py +832 -0
- third_party/transformers/src/transformers/models/blenderbot/__init__.py +28 -0
- third_party/transformers/src/transformers/models/blenderbot/configuration_blenderbot.py +81 -0
third_party/transformers/src/transformers/models/altclip/__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_altclip import *
|
| 22 |
+
from .modeling_altclip import *
|
| 23 |
+
from .processing_altclip 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/altclip/configuration_altclip.py
ADDED
|
@@ -0,0 +1,224 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright 2022 WenXiang ZhongzhiCheng LedellWu LiuGuang BoWenZhang 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 |
+
"""AltCLIP 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="BAAI/AltCLIP")
|
| 26 |
+
@strict
|
| 27 |
+
class AltCLIPTextConfig(PreTrainedConfig):
|
| 28 |
+
r"""
|
| 29 |
+
project_dim (`int`, *optional*, defaults to 768):
|
| 30 |
+
The dimensions of the teacher model before the mapping layer.
|
| 31 |
+
|
| 32 |
+
Examples:
|
| 33 |
+
|
| 34 |
+
```python
|
| 35 |
+
>>> from transformers import AltCLIPTextModel, AltCLIPTextConfig
|
| 36 |
+
|
| 37 |
+
>>> # Initializing a AltCLIPTextConfig with BAAI/AltCLIP style configuration
|
| 38 |
+
>>> configuration = AltCLIPTextConfig()
|
| 39 |
+
|
| 40 |
+
>>> # Initializing a AltCLIPTextModel (with random weights) from the BAAI/AltCLIP style configuration
|
| 41 |
+
>>> model = AltCLIPTextModel(configuration)
|
| 42 |
+
|
| 43 |
+
>>> # Accessing the model configuration
|
| 44 |
+
>>> configuration = model.config
|
| 45 |
+
```"""
|
| 46 |
+
|
| 47 |
+
model_type = "altclip_text_model"
|
| 48 |
+
|
| 49 |
+
vocab_size: int = 250002
|
| 50 |
+
hidden_size: int = 1024
|
| 51 |
+
num_hidden_layers: int = 24
|
| 52 |
+
num_attention_heads: int = 16
|
| 53 |
+
intermediate_size: int = 4096
|
| 54 |
+
hidden_act: str = "gelu"
|
| 55 |
+
hidden_dropout_prob: float | int = 0.1
|
| 56 |
+
attention_probs_dropout_prob: float | int = 0.1
|
| 57 |
+
max_position_embeddings: int = 514
|
| 58 |
+
type_vocab_size: int = 1
|
| 59 |
+
initializer_range: float = 0.02
|
| 60 |
+
initializer_factor: float = 0.02
|
| 61 |
+
layer_norm_eps: float = 1e-05
|
| 62 |
+
pad_token_id: int | None = 1
|
| 63 |
+
bos_token_id: int | None = 0
|
| 64 |
+
eos_token_id: int | list[int] | None = 2
|
| 65 |
+
project_dim: int = 768
|
| 66 |
+
|
| 67 |
+
|
| 68 |
+
@auto_docstring(checkpoint="BAAI/AltCLIP")
|
| 69 |
+
@strict
|
| 70 |
+
class AltCLIPVisionConfig(PreTrainedConfig):
|
| 71 |
+
r"""
|
| 72 |
+
Example:
|
| 73 |
+
|
| 74 |
+
```python
|
| 75 |
+
>>> from transformers import AltCLIPVisionConfig, AltCLIPVisionModel
|
| 76 |
+
|
| 77 |
+
>>> # Initializing a AltCLIPVisionConfig with BAAI/AltCLIP style configuration
|
| 78 |
+
>>> configuration = AltCLIPVisionConfig()
|
| 79 |
+
|
| 80 |
+
>>> # Initializing a AltCLIPVisionModel (with random weights) from the BAAI/AltCLIP style configuration
|
| 81 |
+
>>> model = AltCLIPVisionModel(configuration)
|
| 82 |
+
|
| 83 |
+
>>> # Accessing the model configuration
|
| 84 |
+
>>> configuration = model.config
|
| 85 |
+
```"""
|
| 86 |
+
|
| 87 |
+
model_type = "altclip_vision_model"
|
| 88 |
+
base_config_key = "vision_config"
|
| 89 |
+
|
| 90 |
+
hidden_size: int = 768
|
| 91 |
+
intermediate_size: int = 3072
|
| 92 |
+
projection_dim: int = 512
|
| 93 |
+
num_hidden_layers: int = 12
|
| 94 |
+
num_attention_heads: int = 12
|
| 95 |
+
num_channels: int = 3
|
| 96 |
+
image_size: int | list[int] | tuple[int, int] = 224
|
| 97 |
+
patch_size: int | list[int] | tuple[int, int] = 32
|
| 98 |
+
hidden_act: str = "quick_gelu"
|
| 99 |
+
layer_norm_eps: float = 1e-5
|
| 100 |
+
attention_dropout: float | int = 0.0
|
| 101 |
+
initializer_range: float = 0.02
|
| 102 |
+
initializer_factor: float = 1.0
|
| 103 |
+
|
| 104 |
+
|
| 105 |
+
@auto_docstring(checkpoint="BAAI/AltCLIP")
|
| 106 |
+
@strict
|
| 107 |
+
class AltCLIPConfig(PreTrainedConfig):
|
| 108 |
+
r"""
|
| 109 |
+
Example:
|
| 110 |
+
|
| 111 |
+
```python
|
| 112 |
+
>>> from transformers import AltCLIPConfig, AltCLIPModel
|
| 113 |
+
|
| 114 |
+
>>> # Initializing a AltCLIPConfig with BAAI/AltCLIP style configuration
|
| 115 |
+
>>> configuration = AltCLIPConfig()
|
| 116 |
+
|
| 117 |
+
>>> # Initializing a AltCLIPModel (with random weights) from the BAAI/AltCLIP style configuration
|
| 118 |
+
>>> model = AltCLIPModel(configuration)
|
| 119 |
+
|
| 120 |
+
>>> # Accessing the model configuration
|
| 121 |
+
>>> configuration = model.config
|
| 122 |
+
|
| 123 |
+
>>> # We can also initialize a AltCLIPConfig from a AltCLIPTextConfig and a AltCLIPVisionConfig
|
| 124 |
+
|
| 125 |
+
>>> # Initializing a AltCLIPText and AltCLIPVision configuration
|
| 126 |
+
>>> config_text = AltCLIPTextConfig()
|
| 127 |
+
>>> config_vision = AltCLIPVisionConfig()
|
| 128 |
+
|
| 129 |
+
>>> config = AltCLIPConfig(text_config=config_text, vision_config=config_vision)
|
| 130 |
+
```"""
|
| 131 |
+
|
| 132 |
+
model_type = "altclip"
|
| 133 |
+
sub_configs = {"text_config": AltCLIPTextConfig, "vision_config": AltCLIPVisionConfig}
|
| 134 |
+
text_config: dict | PreTrainedConfig | None = None
|
| 135 |
+
vision_config: dict | PreTrainedConfig | None = None
|
| 136 |
+
projection_dim: int = 768
|
| 137 |
+
logit_scale_init_value: float = 2.6592
|
| 138 |
+
initializer_factor: float = 1.0
|
| 139 |
+
|
| 140 |
+
def __post_init__(self, **kwargs):
|
| 141 |
+
if self.text_config is None:
|
| 142 |
+
text_config = {}
|
| 143 |
+
logger.info("`text_config` is `None`. Initializing the `AltCLIPTextConfig` with default values.")
|
| 144 |
+
elif isinstance(self.text_config, AltCLIPTextConfig):
|
| 145 |
+
text_config = self.text_config.to_dict()
|
| 146 |
+
else:
|
| 147 |
+
text_config = self.text_config
|
| 148 |
+
|
| 149 |
+
if self.vision_config is None:
|
| 150 |
+
vision_config = {}
|
| 151 |
+
logger.info("`vision_config` is `None`. initializing the `AltCLIPVisionConfig` with default values.")
|
| 152 |
+
elif isinstance(self.vision_config, AltCLIPVisionConfig):
|
| 153 |
+
vision_config = self.vision_config.to_dict()
|
| 154 |
+
else:
|
| 155 |
+
vision_config = self.vision_config
|
| 156 |
+
|
| 157 |
+
# For backward compatibility check keyword args
|
| 158 |
+
# Instead of simply assigning `[text|vision]_config_dict` to `[text|vision]_config`, we use the values in
|
| 159 |
+
# `[text|vision]_config_dict` to update the values in `[text|vision]_config`. The values should be same in most
|
| 160 |
+
# cases, but we don't want to break anything regarding `_config_dict` that existed before commit `8827e1b2`.
|
| 161 |
+
text_config_dict = kwargs.pop("text_config_dict", None)
|
| 162 |
+
vision_config_dict = kwargs.pop("vision_config_dict", None)
|
| 163 |
+
|
| 164 |
+
if text_config_dict is not None:
|
| 165 |
+
# This is the complete result when using `text_config_dict`.
|
| 166 |
+
_text_config_dict = AltCLIPTextConfig(**text_config_dict).to_dict()
|
| 167 |
+
|
| 168 |
+
# Give a warning if the values exist in both `_text_config_dict` and `text_config` but being different.
|
| 169 |
+
for key, value in _text_config_dict.items():
|
| 170 |
+
if key in text_config and value != text_config[key] and key != "transformers_version":
|
| 171 |
+
# If specified in `text_config_dict`
|
| 172 |
+
if key in text_config_dict:
|
| 173 |
+
message = (
|
| 174 |
+
f"`{key}` is found in both `text_config_dict` and `text_config` but with different values. "
|
| 175 |
+
f'The value `text_config_dict["{key}"]` will be used instead.'
|
| 176 |
+
)
|
| 177 |
+
# If inferred from default argument values (just to be super careful)
|
| 178 |
+
else:
|
| 179 |
+
message = (
|
| 180 |
+
f"`text_config_dict` is provided which will be used to initialize `AltCLIPTextConfig`. The "
|
| 181 |
+
f'value `text_config["{key}"]` will be overridden.'
|
| 182 |
+
)
|
| 183 |
+
logger.info(message)
|
| 184 |
+
|
| 185 |
+
# Update all values in `text_config` with the ones in `_text_config_dict`.
|
| 186 |
+
text_config.update(_text_config_dict)
|
| 187 |
+
|
| 188 |
+
if vision_config_dict is not None:
|
| 189 |
+
# This is the complete result when using `vision_config_dict`.
|
| 190 |
+
_vision_config_dict = AltCLIPVisionConfig(**vision_config_dict).to_dict()
|
| 191 |
+
# convert keys to string instead of integer
|
| 192 |
+
if "id2label" in _vision_config_dict:
|
| 193 |
+
_vision_config_dict["id2label"] = {
|
| 194 |
+
str(key): value for key, value in _vision_config_dict["id2label"].items()
|
| 195 |
+
}
|
| 196 |
+
|
| 197 |
+
# Give a warning if the values exist in both `_vision_config_dict` and `vision_config` but being different.
|
| 198 |
+
for key, value in _vision_config_dict.items():
|
| 199 |
+
if key in vision_config and value != vision_config[key] and key != "transformers_version":
|
| 200 |
+
# If specified in `vision_config_dict`
|
| 201 |
+
if key in vision_config_dict:
|
| 202 |
+
message = (
|
| 203 |
+
f"`{key}` is found in both `vision_config_dict` and `vision_config` but with different "
|
| 204 |
+
f'values. The value `vision_config_dict["{key}"]` will be used instead.'
|
| 205 |
+
)
|
| 206 |
+
# If inferred from default argument values (just to be super careful)
|
| 207 |
+
else:
|
| 208 |
+
message = (
|
| 209 |
+
f"`vision_config_dict` is provided which will be used to initialize `AltCLIPVisionConfig`. "
|
| 210 |
+
f'The value `vision_config["{key}"]` will be overridden.'
|
| 211 |
+
)
|
| 212 |
+
logger.info(message)
|
| 213 |
+
|
| 214 |
+
# Update all values in `vision_config` with the ones in `_vision_config_dict`.
|
| 215 |
+
vision_config.update(_vision_config_dict)
|
| 216 |
+
|
| 217 |
+
# Finally we can convert back our unified text/vision configs to `PretrainedConfig`
|
| 218 |
+
self.text_config = AltCLIPTextConfig(**text_config)
|
| 219 |
+
self.vision_config = AltCLIPVisionConfig(**vision_config)
|
| 220 |
+
|
| 221 |
+
super().__post_init__(**kwargs)
|
| 222 |
+
|
| 223 |
+
|
| 224 |
+
__all__ = ["AltCLIPTextConfig", "AltCLIPVisionConfig", "AltCLIPConfig"]
|
third_party/transformers/src/transformers/models/altclip/modeling_altclip.py
ADDED
|
@@ -0,0 +1,1185 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright 2022 The BAAI Teams 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 |
+
"""PyTorch AltCLIP model."""
|
| 15 |
+
|
| 16 |
+
import math
|
| 17 |
+
from collections.abc import Callable
|
| 18 |
+
from dataclasses import dataclass
|
| 19 |
+
from typing import Any
|
| 20 |
+
|
| 21 |
+
import torch
|
| 22 |
+
import torch.nn as nn
|
| 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 |
+
BaseModelOutputWithPooling,
|
| 30 |
+
BaseModelOutputWithPoolingAndProjection,
|
| 31 |
+
)
|
| 32 |
+
from ...modeling_utils import ALL_ATTENTION_FUNCTIONS, PreTrainedModel
|
| 33 |
+
from ...processing_utils import Unpack
|
| 34 |
+
from ...pytorch_utils import apply_chunking_to_forward
|
| 35 |
+
from ...utils import ModelOutput, TransformersKwargs, auto_docstring, can_return_tuple, logging, torch_int
|
| 36 |
+
from ...utils.generic import merge_with_config_defaults
|
| 37 |
+
from ...utils.output_capturing import capture_outputs
|
| 38 |
+
from .configuration_altclip import AltCLIPConfig, AltCLIPTextConfig, AltCLIPVisionConfig
|
| 39 |
+
|
| 40 |
+
|
| 41 |
+
logger = logging.get_logger(__name__)
|
| 42 |
+
|
| 43 |
+
|
| 44 |
+
# contrastive loss function, adapted from
|
| 45 |
+
# https://sachinruk.github.io/blog/pytorch/pytorch%20lightning/loss%20function/gpu/2021/03/07/CLIP.html
|
| 46 |
+
def contrastive_loss(logits: torch.Tensor) -> torch.Tensor:
|
| 47 |
+
return nn.functional.cross_entropy(logits, torch.arange(len(logits), device=logits.device))
|
| 48 |
+
|
| 49 |
+
|
| 50 |
+
def clip_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 |
+
# Copied from transformers.models.clip.modeling_clip.CLIPOutput with CLIP->AltCLIP
|
| 59 |
+
class AltCLIPOutput(ModelOutput):
|
| 60 |
+
r"""
|
| 61 |
+
loss (`torch.FloatTensor` of shape `(1,)`, *optional*, returned when `return_loss` is `True`):
|
| 62 |
+
Contrastive loss for image-text similarity.
|
| 63 |
+
logits_per_image (`torch.FloatTensor` of shape `(image_batch_size, text_batch_size)`):
|
| 64 |
+
The scaled dot product scores between `image_embeds` and `text_embeds`. This represents the image-text
|
| 65 |
+
similarity scores.
|
| 66 |
+
logits_per_text (`torch.FloatTensor` of shape `(text_batch_size, image_batch_size)`):
|
| 67 |
+
The scaled dot product scores between `text_embeds` and `image_embeds`. This represents the text-image
|
| 68 |
+
similarity scores.
|
| 69 |
+
text_embeds (`torch.FloatTensor` of shape `(batch_size, output_dim`):
|
| 70 |
+
The text embeddings obtained by applying the projection layer to the pooled output of [`AltCLIPTextModel`].
|
| 71 |
+
image_embeds (`torch.FloatTensor` of shape `(batch_size, output_dim`):
|
| 72 |
+
The image embeddings obtained by applying the projection layer to the pooled output of [`AltCLIPVisionModel`].
|
| 73 |
+
text_model_output (`BaseModelOutputWithPooling`):
|
| 74 |
+
The output of the [`AltCLIPTextModel`].
|
| 75 |
+
vision_model_output (`BaseModelOutputWithPooling`):
|
| 76 |
+
The output of the [`AltCLIPVisionModel`].
|
| 77 |
+
"""
|
| 78 |
+
|
| 79 |
+
loss: torch.FloatTensor | None = None
|
| 80 |
+
logits_per_image: torch.FloatTensor | None = None
|
| 81 |
+
logits_per_text: torch.FloatTensor | None = None
|
| 82 |
+
text_embeds: torch.FloatTensor | None = None
|
| 83 |
+
image_embeds: torch.FloatTensor | None = None
|
| 84 |
+
text_model_output: BaseModelOutputWithPooling = None
|
| 85 |
+
vision_model_output: BaseModelOutputWithPooling = None
|
| 86 |
+
|
| 87 |
+
def to_tuple(self) -> tuple[Any]:
|
| 88 |
+
return tuple(v.to_tuple() if isinstance(v, ModelOutput) else v for v in self.values())
|
| 89 |
+
|
| 90 |
+
|
| 91 |
+
# Copied from transformers.models.roberta.modeling_roberta.RobertaEmbeddings with Roberta->AltRoberta
|
| 92 |
+
class AltRobertaEmbeddings(nn.Module):
|
| 93 |
+
"""Construct the embeddings from word, position and token_type embeddings."""
|
| 94 |
+
|
| 95 |
+
def __init__(self, config):
|
| 96 |
+
super().__init__()
|
| 97 |
+
self.word_embeddings = nn.Embedding(config.vocab_size, config.hidden_size, padding_idx=config.pad_token_id)
|
| 98 |
+
self.token_type_embeddings = nn.Embedding(config.type_vocab_size, config.hidden_size)
|
| 99 |
+
|
| 100 |
+
self.LayerNorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps)
|
| 101 |
+
self.dropout = nn.Dropout(config.hidden_dropout_prob)
|
| 102 |
+
# position_ids (1, len position emb) is contiguous in memory and exported when serialized
|
| 103 |
+
self.register_buffer(
|
| 104 |
+
"position_ids", torch.arange(config.max_position_embeddings).expand((1, -1)), persistent=False
|
| 105 |
+
)
|
| 106 |
+
self.register_buffer(
|
| 107 |
+
"token_type_ids", torch.zeros(self.position_ids.size(), dtype=torch.long), persistent=False
|
| 108 |
+
)
|
| 109 |
+
|
| 110 |
+
self.padding_idx = config.pad_token_id
|
| 111 |
+
self.position_embeddings = nn.Embedding(
|
| 112 |
+
config.max_position_embeddings, config.hidden_size, padding_idx=self.padding_idx
|
| 113 |
+
)
|
| 114 |
+
|
| 115 |
+
def forward(
|
| 116 |
+
self,
|
| 117 |
+
input_ids: torch.LongTensor | None = None,
|
| 118 |
+
token_type_ids: torch.LongTensor | None = None,
|
| 119 |
+
position_ids: torch.LongTensor | None = None,
|
| 120 |
+
inputs_embeds: torch.FloatTensor | None = None,
|
| 121 |
+
past_key_values_length: int = 0,
|
| 122 |
+
) -> torch.Tensor:
|
| 123 |
+
if position_ids is None:
|
| 124 |
+
if input_ids is not None:
|
| 125 |
+
# Create the position ids from the input token ids. Any padded tokens remain padded.
|
| 126 |
+
position_ids = self.create_position_ids_from_input_ids(
|
| 127 |
+
input_ids, self.padding_idx, past_key_values_length
|
| 128 |
+
)
|
| 129 |
+
else:
|
| 130 |
+
position_ids = self.create_position_ids_from_inputs_embeds(inputs_embeds, self.padding_idx)
|
| 131 |
+
|
| 132 |
+
if input_ids is not None:
|
| 133 |
+
input_shape = input_ids.size()
|
| 134 |
+
else:
|
| 135 |
+
input_shape = inputs_embeds.size()[:-1]
|
| 136 |
+
|
| 137 |
+
batch_size, seq_length = input_shape
|
| 138 |
+
|
| 139 |
+
# Setting the token_type_ids to the registered buffer in constructor where it is all zeros, which usually occurs
|
| 140 |
+
# when its auto-generated, registered buffer helps users when tracing the model without passing token_type_ids, solves
|
| 141 |
+
# issue #5664
|
| 142 |
+
if token_type_ids is None:
|
| 143 |
+
if hasattr(self, "token_type_ids"):
|
| 144 |
+
# NOTE: We assume either pos ids to have bsz == 1 (broadcastable) or bsz == effective bsz (input_shape[0])
|
| 145 |
+
buffered_token_type_ids = self.token_type_ids.expand(position_ids.shape[0], -1)
|
| 146 |
+
buffered_token_type_ids = torch.gather(buffered_token_type_ids, dim=1, index=position_ids)
|
| 147 |
+
token_type_ids = buffered_token_type_ids.expand(batch_size, seq_length)
|
| 148 |
+
else:
|
| 149 |
+
token_type_ids = torch.zeros(input_shape, dtype=torch.long, device=self.position_ids.device)
|
| 150 |
+
|
| 151 |
+
if inputs_embeds is None:
|
| 152 |
+
inputs_embeds = self.word_embeddings(input_ids)
|
| 153 |
+
token_type_embeddings = self.token_type_embeddings(token_type_ids)
|
| 154 |
+
embeddings = inputs_embeds + token_type_embeddings
|
| 155 |
+
|
| 156 |
+
position_embeddings = self.position_embeddings(position_ids)
|
| 157 |
+
embeddings = embeddings + position_embeddings
|
| 158 |
+
|
| 159 |
+
embeddings = self.LayerNorm(embeddings)
|
| 160 |
+
embeddings = self.dropout(embeddings)
|
| 161 |
+
return embeddings
|
| 162 |
+
|
| 163 |
+
@staticmethod
|
| 164 |
+
def create_position_ids_from_inputs_embeds(inputs_embeds, padding_idx):
|
| 165 |
+
"""
|
| 166 |
+
We are provided embeddings directly. We cannot infer which are padded so just generate sequential position ids.
|
| 167 |
+
|
| 168 |
+
Args:
|
| 169 |
+
inputs_embeds: torch.Tensor
|
| 170 |
+
|
| 171 |
+
Returns: torch.Tensor
|
| 172 |
+
"""
|
| 173 |
+
input_shape = inputs_embeds.size()[:-1]
|
| 174 |
+
sequence_length = input_shape[1]
|
| 175 |
+
|
| 176 |
+
position_ids = torch.arange(
|
| 177 |
+
padding_idx + 1, sequence_length + padding_idx + 1, dtype=torch.long, device=inputs_embeds.device
|
| 178 |
+
)
|
| 179 |
+
return position_ids.unsqueeze(0).expand(input_shape)
|
| 180 |
+
|
| 181 |
+
@staticmethod
|
| 182 |
+
def create_position_ids_from_input_ids(input_ids, padding_idx, past_key_values_length=0):
|
| 183 |
+
"""
|
| 184 |
+
Replace non-padding symbols with their position numbers. Position numbers begin at padding_idx+1. Padding symbols
|
| 185 |
+
are ignored. This is modified from fairseq's `utils.make_positions`.
|
| 186 |
+
|
| 187 |
+
Args:
|
| 188 |
+
x: torch.Tensor x:
|
| 189 |
+
|
| 190 |
+
Returns: torch.Tensor
|
| 191 |
+
"""
|
| 192 |
+
# The series of casts and type-conversions here are carefully balanced to both work with ONNX export and XLA.
|
| 193 |
+
mask = input_ids.ne(padding_idx).int()
|
| 194 |
+
incremental_indices = (torch.cumsum(mask, dim=1).type_as(mask) + past_key_values_length) * mask
|
| 195 |
+
return incremental_indices.long() + padding_idx
|
| 196 |
+
|
| 197 |
+
|
| 198 |
+
class AltRobertaSelfAttention(nn.Module):
|
| 199 |
+
def __init__(self, config):
|
| 200 |
+
super().__init__()
|
| 201 |
+
self.config = config
|
| 202 |
+
if config.hidden_size % config.num_attention_heads != 0 and not hasattr(config, "embedding_size"):
|
| 203 |
+
raise ValueError(
|
| 204 |
+
f"The hidden size ({config.hidden_size}) is not a multiple of the number of attention "
|
| 205 |
+
f"heads ({config.num_attention_heads})"
|
| 206 |
+
)
|
| 207 |
+
|
| 208 |
+
self.num_attention_heads = config.num_attention_heads
|
| 209 |
+
self.attention_head_size = int(config.hidden_size / config.num_attention_heads)
|
| 210 |
+
self.all_head_size = self.num_attention_heads * self.attention_head_size
|
| 211 |
+
|
| 212 |
+
self.query = nn.Linear(config.hidden_size, self.all_head_size)
|
| 213 |
+
self.key = nn.Linear(config.hidden_size, self.all_head_size)
|
| 214 |
+
self.value = nn.Linear(config.hidden_size, self.all_head_size)
|
| 215 |
+
|
| 216 |
+
self.dropout = nn.Dropout(config.attention_probs_dropout_prob)
|
| 217 |
+
|
| 218 |
+
def forward(
|
| 219 |
+
self,
|
| 220 |
+
hidden_states: torch.Tensor,
|
| 221 |
+
attention_mask: torch.FloatTensor | None = None,
|
| 222 |
+
**kwargs: Unpack[TransformersKwargs],
|
| 223 |
+
) -> tuple[torch.Tensor]:
|
| 224 |
+
input_shape = hidden_states.shape[:-1]
|
| 225 |
+
hidden_shape = (*input_shape, -1, self.attention_head_size)
|
| 226 |
+
|
| 227 |
+
query_layer = self.query(hidden_states).view(hidden_shape).transpose(1, 2)
|
| 228 |
+
key_layer = self.key(hidden_states).view(hidden_shape).transpose(1, 2)
|
| 229 |
+
value_layer = self.value(hidden_states).view(hidden_shape).transpose(1, 2)
|
| 230 |
+
|
| 231 |
+
# Take the dot product between "query" and "key" to get the raw attention scores.
|
| 232 |
+
attention_scores = torch.matmul(query_layer, key_layer.transpose(-1, -2))
|
| 233 |
+
|
| 234 |
+
attention_scores = attention_scores / math.sqrt(self.attention_head_size)
|
| 235 |
+
if attention_mask is not None:
|
| 236 |
+
# Apply the attention mask is (precomputed for all layers in AltRobertaModel forward() function)
|
| 237 |
+
attention_scores = attention_scores + attention_mask
|
| 238 |
+
|
| 239 |
+
# Normalize the attention scores to probabilities.
|
| 240 |
+
attention_probs = nn.functional.softmax(attention_scores, dim=-1)
|
| 241 |
+
|
| 242 |
+
# This is actually dropping out entire tokens to attend to, which might
|
| 243 |
+
# seem a bit unusual, but is taken from the original Transformer paper.
|
| 244 |
+
attention_probs = self.dropout(attention_probs)
|
| 245 |
+
|
| 246 |
+
context_layer = torch.matmul(attention_probs, value_layer)
|
| 247 |
+
|
| 248 |
+
context_layer = context_layer.permute(0, 2, 1, 3).contiguous()
|
| 249 |
+
new_context_layer_shape = context_layer.size()[:-2] + (self.all_head_size,)
|
| 250 |
+
context_layer = context_layer.view(new_context_layer_shape)
|
| 251 |
+
|
| 252 |
+
return context_layer, attention_probs
|
| 253 |
+
|
| 254 |
+
|
| 255 |
+
# Copied from transformers.models.roberta.modeling_roberta.RobertaSelfOutput
|
| 256 |
+
class AltRobertaSelfOutput(nn.Module):
|
| 257 |
+
def __init__(self, config):
|
| 258 |
+
super().__init__()
|
| 259 |
+
self.dense = nn.Linear(config.hidden_size, config.hidden_size)
|
| 260 |
+
self.LayerNorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps)
|
| 261 |
+
self.dropout = nn.Dropout(config.hidden_dropout_prob)
|
| 262 |
+
|
| 263 |
+
def forward(self, hidden_states: torch.Tensor, input_tensor: torch.Tensor) -> torch.Tensor:
|
| 264 |
+
hidden_states = self.dense(hidden_states)
|
| 265 |
+
hidden_states = self.dropout(hidden_states)
|
| 266 |
+
hidden_states = self.LayerNorm(hidden_states + input_tensor)
|
| 267 |
+
return hidden_states
|
| 268 |
+
|
| 269 |
+
|
| 270 |
+
ALT_ROBERTA_SELF_ATTENTION_CLASSES = {
|
| 271 |
+
"eager": AltRobertaSelfAttention,
|
| 272 |
+
}
|
| 273 |
+
|
| 274 |
+
|
| 275 |
+
class AltRobertaAttention(nn.Module):
|
| 276 |
+
def __init__(self, config):
|
| 277 |
+
super().__init__()
|
| 278 |
+
self.self = ALT_ROBERTA_SELF_ATTENTION_CLASSES[config._attn_implementation](config)
|
| 279 |
+
self.output = AltRobertaSelfOutput(config)
|
| 280 |
+
|
| 281 |
+
def forward(
|
| 282 |
+
self,
|
| 283 |
+
hidden_states: torch.Tensor,
|
| 284 |
+
attention_mask: torch.FloatTensor | None = None,
|
| 285 |
+
**kwargs: Unpack[TransformersKwargs],
|
| 286 |
+
) -> torch.Tensor:
|
| 287 |
+
attention_output, _ = self.self(
|
| 288 |
+
hidden_states,
|
| 289 |
+
attention_mask=attention_mask,
|
| 290 |
+
**kwargs,
|
| 291 |
+
)
|
| 292 |
+
attention_output = self.output(attention_output, hidden_states)
|
| 293 |
+
return attention_output
|
| 294 |
+
|
| 295 |
+
|
| 296 |
+
# Copied from transformers.models.roberta.modeling_roberta.RobertaIntermediate with Roberta->AltRoberta
|
| 297 |
+
class AltRobertaIntermediate(nn.Module):
|
| 298 |
+
def __init__(self, config):
|
| 299 |
+
super().__init__()
|
| 300 |
+
self.dense = nn.Linear(config.hidden_size, config.intermediate_size)
|
| 301 |
+
if isinstance(config.hidden_act, str):
|
| 302 |
+
self.intermediate_act_fn = ACT2FN[config.hidden_act]
|
| 303 |
+
else:
|
| 304 |
+
self.intermediate_act_fn = config.hidden_act
|
| 305 |
+
|
| 306 |
+
def forward(self, hidden_states: torch.Tensor) -> torch.Tensor:
|
| 307 |
+
hidden_states = self.dense(hidden_states)
|
| 308 |
+
hidden_states = self.intermediate_act_fn(hidden_states)
|
| 309 |
+
return hidden_states
|
| 310 |
+
|
| 311 |
+
|
| 312 |
+
# Copied from transformers.models.roberta.modeling_roberta.RobertaOutput
|
| 313 |
+
class AltRobertaOutput(nn.Module):
|
| 314 |
+
def __init__(self, config):
|
| 315 |
+
super().__init__()
|
| 316 |
+
self.dense = nn.Linear(config.intermediate_size, config.hidden_size)
|
| 317 |
+
self.LayerNorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps)
|
| 318 |
+
self.dropout = nn.Dropout(config.hidden_dropout_prob)
|
| 319 |
+
|
| 320 |
+
def forward(self, hidden_states: torch.Tensor, input_tensor: torch.Tensor) -> torch.Tensor:
|
| 321 |
+
hidden_states = self.dense(hidden_states)
|
| 322 |
+
hidden_states = self.dropout(hidden_states)
|
| 323 |
+
hidden_states = self.LayerNorm(hidden_states + input_tensor)
|
| 324 |
+
return hidden_states
|
| 325 |
+
|
| 326 |
+
|
| 327 |
+
# Copied from transformers.models.align.modeling_align.AlignTextLayer with AlignText->AltRoberta
|
| 328 |
+
class AltRobertaLayer(GradientCheckpointingLayer):
|
| 329 |
+
def __init__(self, config):
|
| 330 |
+
super().__init__()
|
| 331 |
+
self.chunk_size_feed_forward = config.chunk_size_feed_forward
|
| 332 |
+
self.seq_len_dim = 1
|
| 333 |
+
self.attention = AltRobertaAttention(config)
|
| 334 |
+
self.intermediate = AltRobertaIntermediate(config)
|
| 335 |
+
self.output = AltRobertaOutput(config)
|
| 336 |
+
|
| 337 |
+
def forward(
|
| 338 |
+
self,
|
| 339 |
+
hidden_states: torch.Tensor,
|
| 340 |
+
attention_mask: torch.FloatTensor | None = None,
|
| 341 |
+
**kwargs: Unpack[TransformersKwargs],
|
| 342 |
+
) -> torch.Tensor:
|
| 343 |
+
hidden_states = self.attention(
|
| 344 |
+
hidden_states,
|
| 345 |
+
attention_mask=attention_mask,
|
| 346 |
+
**kwargs,
|
| 347 |
+
)
|
| 348 |
+
|
| 349 |
+
hidden_states = apply_chunking_to_forward(
|
| 350 |
+
self.feed_forward_chunk, self.chunk_size_feed_forward, self.seq_len_dim, hidden_states
|
| 351 |
+
)
|
| 352 |
+
|
| 353 |
+
return hidden_states
|
| 354 |
+
|
| 355 |
+
def feed_forward_chunk(self, attention_output):
|
| 356 |
+
intermediate_output = self.intermediate(attention_output)
|
| 357 |
+
layer_output = self.output(intermediate_output, attention_output)
|
| 358 |
+
return layer_output
|
| 359 |
+
|
| 360 |
+
|
| 361 |
+
# Copied from transformers.models.align.modeling_align.AlignTextEncoder with AlignText->AltRoberta
|
| 362 |
+
class AltRobertaEncoder(nn.Module):
|
| 363 |
+
def __init__(self, config):
|
| 364 |
+
super().__init__()
|
| 365 |
+
self.config = config
|
| 366 |
+
self.layer = nn.ModuleList([AltRobertaLayer(config) for i in range(config.num_hidden_layers)])
|
| 367 |
+
self.gradient_checkpointing = False
|
| 368 |
+
|
| 369 |
+
def forward(
|
| 370 |
+
self,
|
| 371 |
+
hidden_states: torch.Tensor,
|
| 372 |
+
attention_mask: torch.FloatTensor | None = None,
|
| 373 |
+
**kwargs: Unpack[TransformersKwargs],
|
| 374 |
+
) -> BaseModelOutput:
|
| 375 |
+
for layer_module in self.layer:
|
| 376 |
+
hidden_states = layer_module(
|
| 377 |
+
hidden_states,
|
| 378 |
+
attention_mask,
|
| 379 |
+
**kwargs,
|
| 380 |
+
)
|
| 381 |
+
|
| 382 |
+
return BaseModelOutput(
|
| 383 |
+
last_hidden_state=hidden_states,
|
| 384 |
+
)
|
| 385 |
+
|
| 386 |
+
|
| 387 |
+
# Copied from transformers.models.roberta.modeling_roberta.RobertaPooler
|
| 388 |
+
class AltRobertaPooler(nn.Module):
|
| 389 |
+
def __init__(self, config):
|
| 390 |
+
super().__init__()
|
| 391 |
+
self.dense = nn.Linear(config.hidden_size, config.hidden_size)
|
| 392 |
+
self.activation = nn.Tanh()
|
| 393 |
+
|
| 394 |
+
def forward(self, hidden_states: torch.Tensor) -> torch.Tensor:
|
| 395 |
+
# We "pool" the model by simply taking the hidden state corresponding
|
| 396 |
+
# to the first token.
|
| 397 |
+
first_token_tensor = hidden_states[:, 0]
|
| 398 |
+
pooled_output = self.dense(first_token_tensor)
|
| 399 |
+
pooled_output = self.activation(pooled_output)
|
| 400 |
+
return pooled_output
|
| 401 |
+
|
| 402 |
+
|
| 403 |
+
# Copied from transformers.models.siglip.modeling_siglip.eager_attention_forward
|
| 404 |
+
def eager_attention_forward(
|
| 405 |
+
module: nn.Module,
|
| 406 |
+
query: torch.Tensor,
|
| 407 |
+
key: torch.Tensor,
|
| 408 |
+
value: torch.Tensor,
|
| 409 |
+
attention_mask: torch.Tensor | None,
|
| 410 |
+
scaling: float,
|
| 411 |
+
dropout: float = 0.0,
|
| 412 |
+
**kwargs,
|
| 413 |
+
):
|
| 414 |
+
attn_weights = torch.matmul(query, key.transpose(-1, -2)) * scaling
|
| 415 |
+
if attention_mask is not None:
|
| 416 |
+
attn_weights = attn_weights + attention_mask
|
| 417 |
+
|
| 418 |
+
attn_weights = nn.functional.softmax(attn_weights, dim=-1, dtype=torch.float32).to(query.dtype)
|
| 419 |
+
attn_weights = nn.functional.dropout(attn_weights, p=dropout, training=module.training)
|
| 420 |
+
|
| 421 |
+
attn_output = torch.matmul(attn_weights, value)
|
| 422 |
+
attn_output = attn_output.transpose(1, 2).contiguous()
|
| 423 |
+
|
| 424 |
+
return attn_output, attn_weights
|
| 425 |
+
|
| 426 |
+
|
| 427 |
+
class AltCLIPAttention(nn.Module):
|
| 428 |
+
"""Multi-headed attention from 'Attention Is All You Need' paper"""
|
| 429 |
+
|
| 430 |
+
def __init__(self, config):
|
| 431 |
+
super().__init__()
|
| 432 |
+
self.config = config
|
| 433 |
+
self.embed_dim = config.hidden_size
|
| 434 |
+
self.num_heads = config.num_attention_heads
|
| 435 |
+
self.head_dim = self.embed_dim // self.num_heads
|
| 436 |
+
if self.head_dim * self.num_heads != self.embed_dim:
|
| 437 |
+
raise ValueError(
|
| 438 |
+
f"embed_dim must be divisible by num_heads (got `embed_dim`: {self.embed_dim} and `num_heads`:"
|
| 439 |
+
f" {self.num_heads})."
|
| 440 |
+
)
|
| 441 |
+
self.scale = self.head_dim**-0.5
|
| 442 |
+
self.dropout = config.attention_dropout
|
| 443 |
+
self.is_causal = False
|
| 444 |
+
|
| 445 |
+
self.k_proj = nn.Linear(self.embed_dim, self.embed_dim)
|
| 446 |
+
self.v_proj = nn.Linear(self.embed_dim, self.embed_dim)
|
| 447 |
+
self.q_proj = nn.Linear(self.embed_dim, self.embed_dim)
|
| 448 |
+
self.out_proj = nn.Linear(self.embed_dim, self.embed_dim)
|
| 449 |
+
|
| 450 |
+
def forward(
|
| 451 |
+
self,
|
| 452 |
+
hidden_states: torch.Tensor,
|
| 453 |
+
attention_mask: torch.Tensor | None = None,
|
| 454 |
+
**kwargs: Unpack[TransformersKwargs],
|
| 455 |
+
) -> tuple[torch.Tensor, torch.Tensor | None]:
|
| 456 |
+
"""Input shape: Batch x Time x Channel"""
|
| 457 |
+
|
| 458 |
+
batch_size, seq_length, embed_dim = hidden_states.shape
|
| 459 |
+
|
| 460 |
+
queries = self.q_proj(hidden_states)
|
| 461 |
+
keys = self.k_proj(hidden_states)
|
| 462 |
+
values = self.v_proj(hidden_states)
|
| 463 |
+
|
| 464 |
+
queries = queries.view(batch_size, seq_length, self.num_heads, self.head_dim).transpose(1, 2)
|
| 465 |
+
keys = keys.view(batch_size, seq_length, self.num_heads, self.head_dim).transpose(1, 2)
|
| 466 |
+
values = values.view(batch_size, seq_length, self.num_heads, self.head_dim).transpose(1, 2)
|
| 467 |
+
|
| 468 |
+
attention_interface: Callable = ALL_ATTENTION_FUNCTIONS.get_interface(
|
| 469 |
+
self.config._attn_implementation, eager_attention_forward
|
| 470 |
+
)
|
| 471 |
+
|
| 472 |
+
attn_output, attn_weights = attention_interface(
|
| 473 |
+
self,
|
| 474 |
+
queries,
|
| 475 |
+
keys,
|
| 476 |
+
values,
|
| 477 |
+
attention_mask,
|
| 478 |
+
scaling=self.scale,
|
| 479 |
+
dropout=0.0 if not self.training else self.dropout,
|
| 480 |
+
**kwargs,
|
| 481 |
+
)
|
| 482 |
+
|
| 483 |
+
attn_output = attn_output.reshape(batch_size, seq_length, embed_dim).contiguous()
|
| 484 |
+
attn_output = self.out_proj(attn_output)
|
| 485 |
+
return attn_output, attn_weights
|
| 486 |
+
|
| 487 |
+
|
| 488 |
+
# Copied from transformers.models.clip.modeling_clip.CLIPMLP with CLIP->AltCLIP
|
| 489 |
+
class AltCLIPMLP(nn.Module):
|
| 490 |
+
def __init__(self, config):
|
| 491 |
+
super().__init__()
|
| 492 |
+
self.config = config
|
| 493 |
+
self.activation_fn = ACT2FN[config.hidden_act]
|
| 494 |
+
self.fc1 = nn.Linear(config.hidden_size, config.intermediate_size)
|
| 495 |
+
self.fc2 = nn.Linear(config.intermediate_size, config.hidden_size)
|
| 496 |
+
|
| 497 |
+
def forward(self, hidden_states: torch.Tensor) -> torch.Tensor:
|
| 498 |
+
hidden_states = self.fc1(hidden_states)
|
| 499 |
+
hidden_states = self.activation_fn(hidden_states)
|
| 500 |
+
hidden_states = self.fc2(hidden_states)
|
| 501 |
+
return hidden_states
|
| 502 |
+
|
| 503 |
+
|
| 504 |
+
class AltCLIPEncoderLayer(GradientCheckpointingLayer):
|
| 505 |
+
def __init__(self, config: AltCLIPConfig):
|
| 506 |
+
super().__init__()
|
| 507 |
+
self.embed_dim = config.hidden_size
|
| 508 |
+
self.self_attn = AltCLIPAttention(config)
|
| 509 |
+
self.layer_norm1 = nn.LayerNorm(self.embed_dim, eps=config.layer_norm_eps)
|
| 510 |
+
self.mlp = AltCLIPMLP(config)
|
| 511 |
+
self.layer_norm2 = nn.LayerNorm(self.embed_dim, eps=config.layer_norm_eps)
|
| 512 |
+
|
| 513 |
+
def forward(
|
| 514 |
+
self,
|
| 515 |
+
hidden_states: torch.Tensor,
|
| 516 |
+
attention_mask: torch.Tensor,
|
| 517 |
+
**kwargs: Unpack[TransformersKwargs],
|
| 518 |
+
) -> tuple[torch.FloatTensor, torch.Tensor | None]:
|
| 519 |
+
residual = hidden_states
|
| 520 |
+
|
| 521 |
+
hidden_states = self.layer_norm1(hidden_states)
|
| 522 |
+
hidden_states, _ = self.self_attn(
|
| 523 |
+
hidden_states=hidden_states,
|
| 524 |
+
attention_mask=attention_mask,
|
| 525 |
+
**kwargs,
|
| 526 |
+
)
|
| 527 |
+
hidden_states = residual + hidden_states
|
| 528 |
+
|
| 529 |
+
residual = hidden_states
|
| 530 |
+
hidden_states = self.layer_norm2(hidden_states)
|
| 531 |
+
hidden_states = self.mlp(hidden_states)
|
| 532 |
+
hidden_states = residual + hidden_states
|
| 533 |
+
|
| 534 |
+
return hidden_states
|
| 535 |
+
|
| 536 |
+
|
| 537 |
+
class AltCLIPEncoder(nn.Module):
|
| 538 |
+
"""
|
| 539 |
+
Transformer encoder consisting of `config.num_hidden_layers` self attention layers. Each layer is a
|
| 540 |
+
[`AltCLIPEncoderLayer`].
|
| 541 |
+
|
| 542 |
+
Args:
|
| 543 |
+
config: AltCLIPConfig
|
| 544 |
+
"""
|
| 545 |
+
|
| 546 |
+
def __init__(self, config: AltCLIPConfig):
|
| 547 |
+
super().__init__()
|
| 548 |
+
self.config = config
|
| 549 |
+
self.layers = nn.ModuleList([AltCLIPEncoderLayer(config) for _ in range(config.num_hidden_layers)])
|
| 550 |
+
self.gradient_checkpointing = False
|
| 551 |
+
|
| 552 |
+
def forward(
|
| 553 |
+
self,
|
| 554 |
+
inputs_embeds,
|
| 555 |
+
attention_mask: torch.Tensor | None = None,
|
| 556 |
+
**kwargs: Unpack[TransformersKwargs],
|
| 557 |
+
) -> tuple | BaseModelOutput:
|
| 558 |
+
r"""
|
| 559 |
+
Args:
|
| 560 |
+
inputs_embeds (`torch.FloatTensor` of shape `(batch_size, sequence_length, hidden_size)`):
|
| 561 |
+
Optionally, instead of passing `input_ids` you can choose to directly pass an embedded representation.
|
| 562 |
+
This is useful if you want more control over how to convert `input_ids` indices into associated vectors
|
| 563 |
+
than the model's internal embedding lookup matrix.
|
| 564 |
+
attention_mask (`torch.Tensor` of shape `(batch_size, sequence_length)`, *optional*):
|
| 565 |
+
Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`:
|
| 566 |
+
|
| 567 |
+
- 1 for tokens that are **not masked**,
|
| 568 |
+
- 0 for tokens that are **masked**.
|
| 569 |
+
|
| 570 |
+
[What are attention masks?](../glossary#attention-mask)
|
| 571 |
+
|
| 572 |
+
"""
|
| 573 |
+
hidden_states = inputs_embeds
|
| 574 |
+
for encoder_layer in self.layers:
|
| 575 |
+
hidden_states = encoder_layer(
|
| 576 |
+
hidden_states,
|
| 577 |
+
attention_mask,
|
| 578 |
+
**kwargs,
|
| 579 |
+
)
|
| 580 |
+
|
| 581 |
+
return BaseModelOutput(
|
| 582 |
+
last_hidden_state=hidden_states,
|
| 583 |
+
)
|
| 584 |
+
|
| 585 |
+
|
| 586 |
+
# Copied from transformers.models.clip.modeling_clip.CLIPVisionEmbeddings with CLIP->AltCLIP
|
| 587 |
+
class AltCLIPVisionEmbeddings(nn.Module):
|
| 588 |
+
def __init__(self, config: AltCLIPVisionConfig):
|
| 589 |
+
super().__init__()
|
| 590 |
+
self.config = config
|
| 591 |
+
self.embed_dim = config.hidden_size
|
| 592 |
+
self.image_size = config.image_size
|
| 593 |
+
self.patch_size = config.patch_size
|
| 594 |
+
|
| 595 |
+
self.class_embedding = nn.Parameter(torch.randn(self.embed_dim))
|
| 596 |
+
|
| 597 |
+
self.patch_embedding = nn.Conv2d(
|
| 598 |
+
in_channels=config.num_channels,
|
| 599 |
+
out_channels=self.embed_dim,
|
| 600 |
+
kernel_size=self.patch_size,
|
| 601 |
+
stride=self.patch_size,
|
| 602 |
+
bias=False,
|
| 603 |
+
)
|
| 604 |
+
|
| 605 |
+
self.num_patches = (self.image_size // self.patch_size) ** 2
|
| 606 |
+
self.num_positions = self.num_patches + 1
|
| 607 |
+
self.position_embedding = nn.Embedding(self.num_positions, self.embed_dim)
|
| 608 |
+
self.register_buffer("position_ids", torch.arange(self.num_positions).expand((1, -1)), persistent=False)
|
| 609 |
+
|
| 610 |
+
def interpolate_pos_encoding(self, embeddings: torch.Tensor, height: int, width: int) -> torch.Tensor:
|
| 611 |
+
"""
|
| 612 |
+
This method allows to interpolate the pre-trained position encodings, to be able to use the model on higher resolution
|
| 613 |
+
images. This method is also adapted to support torch.jit tracing.
|
| 614 |
+
|
| 615 |
+
Adapted from:
|
| 616 |
+
- https://github.com/facebookresearch/dino/blob/de9ee3df6cf39fac952ab558447af1fa1365362a/vision_transformer.py#L174-L194, and
|
| 617 |
+
- https://github.com/facebookresearch/dinov2/blob/e1277af2ba9496fbadf7aec6eba56e8d882d1e35/dinov2/models/vision_transformer.py#L179-L211
|
| 618 |
+
"""
|
| 619 |
+
|
| 620 |
+
num_patches = embeddings.shape[1] - 1
|
| 621 |
+
position_embedding = self.position_embedding.weight.unsqueeze(0)
|
| 622 |
+
num_positions = position_embedding.shape[1] - 1
|
| 623 |
+
|
| 624 |
+
# always interpolate when tracing to ensure the exported model works for dynamic input shapes
|
| 625 |
+
if not torch.jit.is_tracing() and num_patches == num_positions and height == width:
|
| 626 |
+
return self.position_embedding(self.position_ids)
|
| 627 |
+
|
| 628 |
+
class_pos_embed = position_embedding[:, :1]
|
| 629 |
+
patch_pos_embed = position_embedding[:, 1:]
|
| 630 |
+
|
| 631 |
+
dim = embeddings.shape[-1]
|
| 632 |
+
|
| 633 |
+
new_height = height // self.patch_size
|
| 634 |
+
new_width = width // self.patch_size
|
| 635 |
+
|
| 636 |
+
sqrt_num_positions = torch_int(num_positions**0.5)
|
| 637 |
+
patch_pos_embed = patch_pos_embed.reshape(1, sqrt_num_positions, sqrt_num_positions, dim)
|
| 638 |
+
patch_pos_embed = patch_pos_embed.permute(0, 3, 1, 2)
|
| 639 |
+
|
| 640 |
+
patch_pos_embed = nn.functional.interpolate(
|
| 641 |
+
patch_pos_embed,
|
| 642 |
+
size=(new_height, new_width),
|
| 643 |
+
mode="bicubic",
|
| 644 |
+
align_corners=False,
|
| 645 |
+
)
|
| 646 |
+
|
| 647 |
+
patch_pos_embed = patch_pos_embed.permute(0, 2, 3, 1).view(1, -1, dim)
|
| 648 |
+
|
| 649 |
+
return torch.cat((class_pos_embed, patch_pos_embed), dim=1)
|
| 650 |
+
|
| 651 |
+
def forward(self, pixel_values: torch.FloatTensor, interpolate_pos_encoding=False) -> torch.Tensor:
|
| 652 |
+
batch_size, _, height, width = pixel_values.shape
|
| 653 |
+
if not interpolate_pos_encoding and (height != self.image_size or width != self.image_size):
|
| 654 |
+
raise ValueError(
|
| 655 |
+
f"Input image size ({height}*{width}) doesn't match model ({self.image_size}*{self.image_size})."
|
| 656 |
+
)
|
| 657 |
+
target_dtype = self.patch_embedding.weight.dtype
|
| 658 |
+
patch_embeds = self.patch_embedding(pixel_values.to(dtype=target_dtype)) # shape = [*, width, grid, grid]
|
| 659 |
+
patch_embeds = patch_embeds.flatten(2).transpose(1, 2)
|
| 660 |
+
|
| 661 |
+
class_embeds = self.class_embedding.expand(batch_size, 1, -1)
|
| 662 |
+
embeddings = torch.cat([class_embeds, patch_embeds], dim=1)
|
| 663 |
+
if interpolate_pos_encoding:
|
| 664 |
+
embeddings = embeddings + self.interpolate_pos_encoding(embeddings, height, width)
|
| 665 |
+
else:
|
| 666 |
+
embeddings = embeddings + self.position_embedding(self.position_ids)
|
| 667 |
+
return embeddings
|
| 668 |
+
|
| 669 |
+
|
| 670 |
+
@auto_docstring
|
| 671 |
+
class AltCLIPPreTrainedModel(PreTrainedModel):
|
| 672 |
+
config: AltCLIPConfig
|
| 673 |
+
base_model_prefix = "altclip"
|
| 674 |
+
input_modalities = ("image", "text")
|
| 675 |
+
supports_gradient_checkpointing = True
|
| 676 |
+
_no_split_module = []
|
| 677 |
+
|
| 678 |
+
@torch.no_grad()
|
| 679 |
+
def _init_weights(self, module):
|
| 680 |
+
"""Initialize the weights"""
|
| 681 |
+
factor = self.config.initializer_factor
|
| 682 |
+
if isinstance(module, AltCLIPVisionEmbeddings):
|
| 683 |
+
factor = self.config.initializer_factor
|
| 684 |
+
init.normal_(module.class_embedding, mean=0.0, std=module.embed_dim**-0.5 * factor)
|
| 685 |
+
init.normal_(module.patch_embedding.weight, std=module.config.initializer_range * factor)
|
| 686 |
+
init.normal_(module.position_embedding.weight, std=module.config.initializer_range * factor)
|
| 687 |
+
init.copy_(module.position_ids, torch.arange(module.num_positions).expand((1, -1)))
|
| 688 |
+
elif isinstance(module, AltCLIPAttention):
|
| 689 |
+
factor = self.config.initializer_factor
|
| 690 |
+
in_proj_std = (module.embed_dim**-0.5) * ((2 * module.config.num_hidden_layers) ** -0.5) * factor
|
| 691 |
+
out_proj_std = (module.embed_dim**-0.5) * factor
|
| 692 |
+
init.normal_(module.q_proj.weight, std=in_proj_std)
|
| 693 |
+
init.normal_(module.k_proj.weight, std=in_proj_std)
|
| 694 |
+
init.normal_(module.v_proj.weight, std=in_proj_std)
|
| 695 |
+
init.normal_(module.out_proj.weight, std=out_proj_std)
|
| 696 |
+
elif isinstance(module, AltCLIPMLP):
|
| 697 |
+
factor = self.config.initializer_factor
|
| 698 |
+
in_proj_std = (module.config.hidden_size**-0.5) * ((2 * module.config.num_hidden_layers) ** -0.5) * factor
|
| 699 |
+
fc_std = (2 * module.config.hidden_size) ** -0.5 * factor
|
| 700 |
+
init.normal_(module.fc1.weight, std=fc_std)
|
| 701 |
+
init.normal_(module.fc2.weight, std=in_proj_std)
|
| 702 |
+
elif isinstance(module, AltCLIPModel):
|
| 703 |
+
init.normal_(
|
| 704 |
+
module.text_projection.weight,
|
| 705 |
+
std=module.text_embed_dim**-0.5 * self.config.initializer_factor,
|
| 706 |
+
)
|
| 707 |
+
init.normal_(
|
| 708 |
+
module.visual_projection.weight,
|
| 709 |
+
std=module.vision_embed_dim**-0.5 * self.config.initializer_factor,
|
| 710 |
+
)
|
| 711 |
+
elif isinstance(module, nn.LayerNorm):
|
| 712 |
+
init.zeros_(module.bias)
|
| 713 |
+
init.ones_(module.weight)
|
| 714 |
+
elif isinstance(module, nn.Linear):
|
| 715 |
+
init.normal_(module.weight, mean=0.0, std=self.config.initializer_factor)
|
| 716 |
+
if module.bias is not None:
|
| 717 |
+
init.zeros_(module.bias)
|
| 718 |
+
elif isinstance(module, nn.Embedding):
|
| 719 |
+
init.normal_(module.weight, mean=0.0, std=self.config.initializer_factor)
|
| 720 |
+
# Here we need the check explicitly, as we slice the weight in the `zeros_` call, so it looses the flag
|
| 721 |
+
if module.padding_idx is not None and not getattr(module.weight, "_is_hf_initialized", False):
|
| 722 |
+
init.zeros_(module.weight[module.padding_idx])
|
| 723 |
+
elif isinstance(module, AltRobertaEmbeddings):
|
| 724 |
+
init.copy_(module.position_ids, torch.arange(module.position_ids.shape[-1]).expand((1, -1)))
|
| 725 |
+
init.zeros_(module.token_type_ids)
|
| 726 |
+
|
| 727 |
+
|
| 728 |
+
class AltCLIPVisionTransformer(nn.Module):
|
| 729 |
+
def __init__(self, config: AltCLIPVisionConfig):
|
| 730 |
+
super().__init__()
|
| 731 |
+
self.config = config
|
| 732 |
+
embed_dim = config.hidden_size
|
| 733 |
+
|
| 734 |
+
self.embeddings = AltCLIPVisionEmbeddings(config)
|
| 735 |
+
self.pre_layrnorm = nn.LayerNorm(embed_dim, eps=config.layer_norm_eps)
|
| 736 |
+
self.encoder = AltCLIPEncoder(config)
|
| 737 |
+
self.post_layernorm = nn.LayerNorm(embed_dim, eps=config.layer_norm_eps)
|
| 738 |
+
|
| 739 |
+
@auto_docstring
|
| 740 |
+
def forward(
|
| 741 |
+
self,
|
| 742 |
+
pixel_values: torch.FloatTensor | None = None,
|
| 743 |
+
interpolate_pos_encoding: bool | None = False,
|
| 744 |
+
**kwargs: Unpack[TransformersKwargs],
|
| 745 |
+
) -> tuple | BaseModelOutputWithPooling:
|
| 746 |
+
if pixel_values is None:
|
| 747 |
+
raise ValueError("You have to specify pixel_values")
|
| 748 |
+
|
| 749 |
+
hidden_states = self.embeddings(pixel_values, interpolate_pos_encoding=interpolate_pos_encoding)
|
| 750 |
+
hidden_states = self.pre_layrnorm(hidden_states)
|
| 751 |
+
|
| 752 |
+
encoder_outputs = self.encoder(
|
| 753 |
+
inputs_embeds=hidden_states,
|
| 754 |
+
**kwargs,
|
| 755 |
+
)
|
| 756 |
+
|
| 757 |
+
last_hidden_state = encoder_outputs[0]
|
| 758 |
+
pooled_output = last_hidden_state[:, 0, :]
|
| 759 |
+
pooled_output = self.post_layernorm(pooled_output)
|
| 760 |
+
|
| 761 |
+
return BaseModelOutputWithPooling(
|
| 762 |
+
last_hidden_state=last_hidden_state,
|
| 763 |
+
pooler_output=pooled_output,
|
| 764 |
+
)
|
| 765 |
+
|
| 766 |
+
|
| 767 |
+
class AltCLIPVisionModel(AltCLIPPreTrainedModel):
|
| 768 |
+
config: AltCLIPVisionConfig
|
| 769 |
+
main_input_name = "pixel_values"
|
| 770 |
+
input_modalities = ("image",)
|
| 771 |
+
_can_record_outputs = {
|
| 772 |
+
"hidden_states": AltCLIPEncoderLayer,
|
| 773 |
+
"attentions": AltCLIPAttention,
|
| 774 |
+
}
|
| 775 |
+
|
| 776 |
+
def __init__(self, config: AltCLIPVisionConfig):
|
| 777 |
+
super().__init__(config)
|
| 778 |
+
self.vision_model = AltCLIPVisionTransformer(config)
|
| 779 |
+
# Initialize weights and apply final processing
|
| 780 |
+
self.post_init()
|
| 781 |
+
|
| 782 |
+
def get_input_embeddings(self) -> nn.Module:
|
| 783 |
+
return self.vision_model.embeddings.patch_embedding
|
| 784 |
+
|
| 785 |
+
@merge_with_config_defaults
|
| 786 |
+
@capture_outputs(tie_last_hidden_states=False)
|
| 787 |
+
@auto_docstring
|
| 788 |
+
def forward(
|
| 789 |
+
self,
|
| 790 |
+
pixel_values: torch.FloatTensor | None = None,
|
| 791 |
+
interpolate_pos_encoding: bool = False,
|
| 792 |
+
**kwargs: Unpack[TransformersKwargs],
|
| 793 |
+
) -> BaseModelOutputWithPooling:
|
| 794 |
+
r"""
|
| 795 |
+
Examples:
|
| 796 |
+
|
| 797 |
+
```python
|
| 798 |
+
>>> from PIL import Image
|
| 799 |
+
>>> import httpx
|
| 800 |
+
>>> from io import BytesIO
|
| 801 |
+
>>> from transformers import AutoProcessor, AltCLIPVisionModel
|
| 802 |
+
|
| 803 |
+
>>> model = AltCLIPVisionModel.from_pretrained("BAAI/AltCLIP")
|
| 804 |
+
>>> processor = AutoProcessor.from_pretrained("BAAI/AltCLIP")
|
| 805 |
+
|
| 806 |
+
>>> url = "http://images.cocodataset.org/val2017/000000039769.jpg"
|
| 807 |
+
>>> with httpx.stream("GET", url) as response:
|
| 808 |
+
... image = Image.open(BytesIO(response.read()))
|
| 809 |
+
|
| 810 |
+
>>> inputs = processor(images=image, return_tensors="pt")
|
| 811 |
+
|
| 812 |
+
>>> outputs = model(**inputs)
|
| 813 |
+
>>> last_hidden_state = outputs.last_hidden_state
|
| 814 |
+
>>> pooled_output = outputs.pooler_output # pooled CLS states
|
| 815 |
+
```"""
|
| 816 |
+
return self.vision_model(
|
| 817 |
+
pixel_values=pixel_values,
|
| 818 |
+
interpolate_pos_encoding=interpolate_pos_encoding,
|
| 819 |
+
**kwargs,
|
| 820 |
+
)
|
| 821 |
+
|
| 822 |
+
|
| 823 |
+
@auto_docstring(
|
| 824 |
+
custom_intro="""
|
| 825 |
+
The model behaves as an encoder following the architecture described in *Attention is
|
| 826 |
+
all you need*_ by Ashish Vaswani, Noam Shazeer, Niki Parmar, Jakob Uszkoreit, Llion Jones, Aidan N. Gomez, Lukasz
|
| 827 |
+
Kaiser and Illia Polosukhin.
|
| 828 |
+
|
| 829 |
+
.. _*Attention is all you need*: https://huggingface.co/papers/1706.03762
|
| 830 |
+
"""
|
| 831 |
+
)
|
| 832 |
+
class AltRobertaModel(AltCLIPPreTrainedModel):
|
| 833 |
+
config: AltCLIPTextConfig
|
| 834 |
+
_can_record_outputs = {
|
| 835 |
+
"hidden_states": AltRobertaLayer,
|
| 836 |
+
"attentions": AltRobertaSelfAttention,
|
| 837 |
+
}
|
| 838 |
+
|
| 839 |
+
# Copied from transformers.models.clap.modeling_clap.ClapTextModel.__init__ with ClapText->AltRoberta
|
| 840 |
+
def __init__(self, config, add_pooling_layer=True):
|
| 841 |
+
r"""
|
| 842 |
+
add_pooling_layer (bool, *optional*, defaults to `True`):
|
| 843 |
+
Whether to add a pooling layer
|
| 844 |
+
"""
|
| 845 |
+
super().__init__(config)
|
| 846 |
+
self.config = config
|
| 847 |
+
|
| 848 |
+
self.embeddings = AltRobertaEmbeddings(config)
|
| 849 |
+
self.encoder = AltRobertaEncoder(config)
|
| 850 |
+
|
| 851 |
+
self.pooler = AltRobertaPooler(config) if add_pooling_layer else None
|
| 852 |
+
|
| 853 |
+
# Initialize weights and apply final processing
|
| 854 |
+
self.post_init()
|
| 855 |
+
|
| 856 |
+
def get_input_embeddings(self):
|
| 857 |
+
return self.embeddings.word_embeddings
|
| 858 |
+
|
| 859 |
+
def set_input_embeddings(self, value):
|
| 860 |
+
self.embeddings.word_embeddings = value
|
| 861 |
+
|
| 862 |
+
@merge_with_config_defaults
|
| 863 |
+
@capture_outputs
|
| 864 |
+
@auto_docstring
|
| 865 |
+
# Copied from transformers.models.clap.modeling_clap.ClapTextModel.forward
|
| 866 |
+
def forward(
|
| 867 |
+
self,
|
| 868 |
+
input_ids: torch.Tensor | None = None,
|
| 869 |
+
attention_mask: torch.Tensor | None = None,
|
| 870 |
+
token_type_ids: torch.Tensor | None = None,
|
| 871 |
+
position_ids: torch.Tensor | None = None,
|
| 872 |
+
inputs_embeds: torch.Tensor | None = None,
|
| 873 |
+
**kwargs: Unpack[TransformersKwargs],
|
| 874 |
+
) -> BaseModelOutputWithPooling:
|
| 875 |
+
if input_ids is not None and inputs_embeds is not None:
|
| 876 |
+
raise ValueError("You cannot specify both input_ids and inputs_embeds at the same time")
|
| 877 |
+
elif input_ids is not None:
|
| 878 |
+
self.warn_if_padding_and_no_attention_mask(input_ids, attention_mask)
|
| 879 |
+
input_shape = input_ids.size()
|
| 880 |
+
elif inputs_embeds is not None:
|
| 881 |
+
input_shape = inputs_embeds.size()[:-1]
|
| 882 |
+
else:
|
| 883 |
+
raise ValueError("You have to specify either input_ids or inputs_embeds")
|
| 884 |
+
|
| 885 |
+
batch_size, seq_length = input_shape
|
| 886 |
+
device = input_ids.device if input_ids is not None else inputs_embeds.device
|
| 887 |
+
|
| 888 |
+
if attention_mask is None:
|
| 889 |
+
attention_mask = torch.ones(((batch_size, seq_length)), device=device)
|
| 890 |
+
|
| 891 |
+
# We can provide a self-attention mask of dimensions [batch_size, from_seq_length, to_seq_length]
|
| 892 |
+
# ourselves in which case we just need to make it broadcastable to all heads.
|
| 893 |
+
extended_attention_mask: torch.Tensor = self.get_extended_attention_mask(attention_mask, input_shape)
|
| 894 |
+
|
| 895 |
+
embedding_output = self.embeddings(
|
| 896 |
+
input_ids=input_ids,
|
| 897 |
+
position_ids=position_ids,
|
| 898 |
+
token_type_ids=token_type_ids,
|
| 899 |
+
inputs_embeds=inputs_embeds,
|
| 900 |
+
)
|
| 901 |
+
encoder_outputs = self.encoder(
|
| 902 |
+
embedding_output,
|
| 903 |
+
attention_mask=extended_attention_mask,
|
| 904 |
+
**kwargs,
|
| 905 |
+
)
|
| 906 |
+
sequence_output = encoder_outputs[0]
|
| 907 |
+
pooled_output = self.pooler(sequence_output) if self.pooler is not None else None
|
| 908 |
+
|
| 909 |
+
return BaseModelOutputWithPooling(
|
| 910 |
+
last_hidden_state=sequence_output,
|
| 911 |
+
pooler_output=pooled_output,
|
| 912 |
+
)
|
| 913 |
+
|
| 914 |
+
|
| 915 |
+
class AltCLIPTextModel(AltCLIPPreTrainedModel):
|
| 916 |
+
config: AltCLIPTextConfig
|
| 917 |
+
input_modalities = ("text",)
|
| 918 |
+
|
| 919 |
+
def __init__(self, config):
|
| 920 |
+
super().__init__(config)
|
| 921 |
+
self.roberta = AltRobertaModel(config, add_pooling_layer=False)
|
| 922 |
+
self.transformation = nn.Linear(config.hidden_size, config.project_dim)
|
| 923 |
+
self.pre_LN = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps)
|
| 924 |
+
self.post_init()
|
| 925 |
+
|
| 926 |
+
def get_input_embeddings(self) -> nn.Module:
|
| 927 |
+
return self.roberta.embeddings.word_embeddings
|
| 928 |
+
|
| 929 |
+
def set_input_embeddings(self, value: nn.Embedding) -> None:
|
| 930 |
+
self.roberta.embeddings.word_embeddings = value
|
| 931 |
+
|
| 932 |
+
def resize_token_embeddings(self, new_num_tokens: int | None = None) -> nn.Embedding:
|
| 933 |
+
return super().resize_token_embeddings(new_num_tokens)
|
| 934 |
+
|
| 935 |
+
@can_return_tuple
|
| 936 |
+
@auto_docstring
|
| 937 |
+
def forward(
|
| 938 |
+
self,
|
| 939 |
+
input_ids: torch.Tensor | None = None,
|
| 940 |
+
attention_mask: torch.Tensor | None = None,
|
| 941 |
+
token_type_ids: torch.Tensor | None = None,
|
| 942 |
+
position_ids: torch.Tensor | None = None,
|
| 943 |
+
inputs_embeds: torch.Tensor | None = None,
|
| 944 |
+
**kwargs: Unpack[TransformersKwargs],
|
| 945 |
+
) -> tuple | BaseModelOutputWithPoolingAndProjection:
|
| 946 |
+
r"""
|
| 947 |
+
Examples:
|
| 948 |
+
|
| 949 |
+
```python
|
| 950 |
+
>>> from transformers import AutoProcessor, AltCLIPTextModel
|
| 951 |
+
|
| 952 |
+
>>> model = AltCLIPTextModel.from_pretrained("BAAI/AltCLIP")
|
| 953 |
+
>>> processor = AutoProcessor.from_pretrained("BAAI/AltCLIP")
|
| 954 |
+
|
| 955 |
+
>>> texts = ["it's a cat", "it's a dog"]
|
| 956 |
+
|
| 957 |
+
>>> inputs = processor(text=texts, padding=True, return_tensors="pt")
|
| 958 |
+
|
| 959 |
+
>>> outputs = model(**inputs)
|
| 960 |
+
>>> last_hidden_state = outputs.last_hidden_state
|
| 961 |
+
>>> pooled_output = outputs.pooler_output # pooled CLS states
|
| 962 |
+
```"""
|
| 963 |
+
|
| 964 |
+
outputs = self.roberta(
|
| 965 |
+
input_ids=input_ids,
|
| 966 |
+
attention_mask=attention_mask,
|
| 967 |
+
token_type_ids=token_type_ids,
|
| 968 |
+
position_ids=position_ids,
|
| 969 |
+
inputs_embeds=inputs_embeds,
|
| 970 |
+
**kwargs,
|
| 971 |
+
)
|
| 972 |
+
|
| 973 |
+
# last module outputs
|
| 974 |
+
sequence_output = outputs[0]
|
| 975 |
+
|
| 976 |
+
# project every module
|
| 977 |
+
sequence_output = self.pre_LN(sequence_output)
|
| 978 |
+
|
| 979 |
+
# pooler
|
| 980 |
+
projection_state = self.transformation(sequence_output)
|
| 981 |
+
pooler_output = projection_state[:, 0]
|
| 982 |
+
|
| 983 |
+
return BaseModelOutputWithPoolingAndProjection(
|
| 984 |
+
last_hidden_state=projection_state,
|
| 985 |
+
pooler_output=pooler_output,
|
| 986 |
+
hidden_states=outputs.hidden_states,
|
| 987 |
+
attentions=outputs.attentions,
|
| 988 |
+
)
|
| 989 |
+
|
| 990 |
+
|
| 991 |
+
class AltCLIPModel(AltCLIPPreTrainedModel):
|
| 992 |
+
config: AltCLIPConfig
|
| 993 |
+
_can_record_outputs = {
|
| 994 |
+
"hidden_states": AltCLIPEncoderLayer,
|
| 995 |
+
"attentions": AltCLIPAttention,
|
| 996 |
+
}
|
| 997 |
+
|
| 998 |
+
def __init__(self, config: AltCLIPConfig):
|
| 999 |
+
super().__init__(config)
|
| 1000 |
+
|
| 1001 |
+
if not isinstance(config.vision_config, AltCLIPVisionConfig):
|
| 1002 |
+
raise TypeError(
|
| 1003 |
+
"config.vision_config is expected to be of type AltCLIPVisionConfig but is of type"
|
| 1004 |
+
f" {type(config.vision_config)}."
|
| 1005 |
+
)
|
| 1006 |
+
if not isinstance(config.text_config, AltCLIPTextConfig):
|
| 1007 |
+
raise TypeError(
|
| 1008 |
+
"config.text_config is expected to be of type AltCLIPTextConfig but is of type"
|
| 1009 |
+
f" {type(config.text_config)}."
|
| 1010 |
+
)
|
| 1011 |
+
|
| 1012 |
+
text_config = config.text_config
|
| 1013 |
+
vision_config = config.vision_config
|
| 1014 |
+
# The module using it is not a PreTrainedModel subclass so we need this
|
| 1015 |
+
vision_config._attn_implementation = config._attn_implementation
|
| 1016 |
+
|
| 1017 |
+
self.projection_dim = config.projection_dim
|
| 1018 |
+
self.text_embed_dim = text_config.project_dim
|
| 1019 |
+
self.vision_embed_dim = vision_config.hidden_size
|
| 1020 |
+
|
| 1021 |
+
self.text_model = AltCLIPTextModel(text_config)
|
| 1022 |
+
self.vision_model = AltCLIPVisionTransformer(vision_config)
|
| 1023 |
+
|
| 1024 |
+
self.visual_projection = nn.Linear(self.vision_embed_dim, self.projection_dim, bias=False)
|
| 1025 |
+
self.text_projection = nn.Linear(self.text_embed_dim, self.projection_dim, bias=False)
|
| 1026 |
+
self.logit_scale = nn.Parameter(torch.tensor(self.config.logit_scale_init_value))
|
| 1027 |
+
|
| 1028 |
+
# Initialize weights and apply final processing
|
| 1029 |
+
self.post_init()
|
| 1030 |
+
|
| 1031 |
+
@can_return_tuple
|
| 1032 |
+
@auto_docstring
|
| 1033 |
+
def get_text_features(
|
| 1034 |
+
self,
|
| 1035 |
+
input_ids: torch.Tensor,
|
| 1036 |
+
attention_mask: torch.Tensor | None = None,
|
| 1037 |
+
position_ids: torch.Tensor | None = None,
|
| 1038 |
+
token_type_ids: torch.Tensor | None = None,
|
| 1039 |
+
**kwargs: Unpack[TransformersKwargs],
|
| 1040 |
+
) -> tuple | BaseModelOutputWithPooling:
|
| 1041 |
+
r"""
|
| 1042 |
+
Examples:
|
| 1043 |
+
|
| 1044 |
+
```python
|
| 1045 |
+
>>> import torch
|
| 1046 |
+
>>> from transformers import AutoProcessor, AltCLIPModel
|
| 1047 |
+
|
| 1048 |
+
>>> model = AltCLIPModel.from_pretrained("BAAI/AltCLIP")
|
| 1049 |
+
>>> processor = AutoProcessor.from_pretrained("BAAI/AltCLIP")
|
| 1050 |
+
|
| 1051 |
+
>>> inputs = processor(text=["a photo of a cat", "a photo of a dog"], padding=True, return_tensors="pt")
|
| 1052 |
+
>>> with torch.inference_mode():
|
| 1053 |
+
... text_features = model.get_text_features(**inputs)
|
| 1054 |
+
```"""
|
| 1055 |
+
text_outputs: BaseModelOutputWithPoolingAndProjection = self.text_model(
|
| 1056 |
+
input_ids=input_ids,
|
| 1057 |
+
attention_mask=attention_mask,
|
| 1058 |
+
position_ids=position_ids,
|
| 1059 |
+
token_type_ids=token_type_ids,
|
| 1060 |
+
**kwargs,
|
| 1061 |
+
)
|
| 1062 |
+
pooled_output = text_outputs.pooler_output
|
| 1063 |
+
text_outputs.pooler_output = self.text_projection(pooled_output)
|
| 1064 |
+
|
| 1065 |
+
return text_outputs
|
| 1066 |
+
|
| 1067 |
+
@merge_with_config_defaults
|
| 1068 |
+
@capture_outputs(tie_last_hidden_states=False)
|
| 1069 |
+
@auto_docstring
|
| 1070 |
+
def get_image_features(
|
| 1071 |
+
self,
|
| 1072 |
+
pixel_values: torch.FloatTensor,
|
| 1073 |
+
interpolate_pos_encoding: bool = False,
|
| 1074 |
+
**kwargs: Unpack[TransformersKwargs],
|
| 1075 |
+
) -> tuple | BaseModelOutputWithPooling:
|
| 1076 |
+
r"""
|
| 1077 |
+
Examples:
|
| 1078 |
+
|
| 1079 |
+
```python
|
| 1080 |
+
>>> import torch
|
| 1081 |
+
>>> from transformers import AutoProcessor, AltCLIPModel
|
| 1082 |
+
>>> from transformers.image_utils import load_image
|
| 1083 |
+
|
| 1084 |
+
>>> model = AltCLIPModel.from_pretrained("BAAI/AltCLIP")
|
| 1085 |
+
>>> processor = AutoProcessor.from_pretrained("BAAI/AltCLIP")
|
| 1086 |
+
|
| 1087 |
+
>>> url = "http://images.cocodataset.org/val2017/000000039769.jpg"
|
| 1088 |
+
>>> image = load_image(url)
|
| 1089 |
+
|
| 1090 |
+
>>> inputs = processor(images=image, return_tensors="pt")
|
| 1091 |
+
>>> with torch.inference_mode():
|
| 1092 |
+
... image_features = model.get_image_features(**inputs)
|
| 1093 |
+
```"""
|
| 1094 |
+
vision_outputs = self.vision_model(
|
| 1095 |
+
pixel_values=pixel_values,
|
| 1096 |
+
interpolate_pos_encoding=interpolate_pos_encoding,
|
| 1097 |
+
**kwargs,
|
| 1098 |
+
)
|
| 1099 |
+
pooled_output = vision_outputs.pooler_output
|
| 1100 |
+
vision_outputs.pooler_output = self.visual_projection(pooled_output)
|
| 1101 |
+
|
| 1102 |
+
return vision_outputs
|
| 1103 |
+
|
| 1104 |
+
@can_return_tuple
|
| 1105 |
+
@auto_docstring
|
| 1106 |
+
def forward(
|
| 1107 |
+
self,
|
| 1108 |
+
input_ids: torch.LongTensor | None = None,
|
| 1109 |
+
pixel_values: torch.FloatTensor | None = None,
|
| 1110 |
+
attention_mask: torch.Tensor | None = None,
|
| 1111 |
+
position_ids: torch.LongTensor | None = None,
|
| 1112 |
+
token_type_ids: torch.Tensor | None = None,
|
| 1113 |
+
return_loss: bool | None = None,
|
| 1114 |
+
interpolate_pos_encoding: bool = False,
|
| 1115 |
+
**kwargs: Unpack[TransformersKwargs],
|
| 1116 |
+
) -> tuple | AltCLIPOutput:
|
| 1117 |
+
r"""
|
| 1118 |
+
return_loss (`bool`, *optional*):
|
| 1119 |
+
Whether or not to return the contrastive loss.
|
| 1120 |
+
|
| 1121 |
+
Examples:
|
| 1122 |
+
|
| 1123 |
+
```python
|
| 1124 |
+
>>> from PIL import Image
|
| 1125 |
+
>>> import httpx
|
| 1126 |
+
>>> from io import BytesIO
|
| 1127 |
+
>>> from transformers import AutoProcessor, AltCLIPModel
|
| 1128 |
+
|
| 1129 |
+
>>> model = AltCLIPModel.from_pretrained("BAAI/AltCLIP")
|
| 1130 |
+
>>> processor = AutoProcessor.from_pretrained("BAAI/AltCLIP")
|
| 1131 |
+
>>> url = "http://images.cocodataset.org/val2017/000000039769.jpg"
|
| 1132 |
+
>>> with httpx.stream("GET", url) as response:
|
| 1133 |
+
... image = Image.open(BytesIO(response.read()))
|
| 1134 |
+
>>> inputs = processor(
|
| 1135 |
+
... text=["a photo of a cat", "a photo of a dog"], images=image, return_tensors="pt", padding=True
|
| 1136 |
+
... )
|
| 1137 |
+
>>> outputs = model(**inputs)
|
| 1138 |
+
>>> logits_per_image = outputs.logits_per_image # this is the image-text similarity score
|
| 1139 |
+
>>> probs = logits_per_image.softmax(dim=1) # we can take the softmax to get the label probabilities
|
| 1140 |
+
```"""
|
| 1141 |
+
text_outputs = self.text_model(
|
| 1142 |
+
input_ids=input_ids,
|
| 1143 |
+
attention_mask=attention_mask,
|
| 1144 |
+
token_type_ids=token_type_ids,
|
| 1145 |
+
position_ids=position_ids,
|
| 1146 |
+
**kwargs,
|
| 1147 |
+
)
|
| 1148 |
+
|
| 1149 |
+
vision_outputs = self.vision_model(
|
| 1150 |
+
pixel_values=pixel_values,
|
| 1151 |
+
interpolate_pos_encoding=interpolate_pos_encoding,
|
| 1152 |
+
**kwargs,
|
| 1153 |
+
)
|
| 1154 |
+
|
| 1155 |
+
image_embeds = vision_outputs[1]
|
| 1156 |
+
image_embeds = self.visual_projection(image_embeds)
|
| 1157 |
+
|
| 1158 |
+
text_embeds = text_outputs[1]
|
| 1159 |
+
text_embeds = self.text_projection(text_embeds)
|
| 1160 |
+
|
| 1161 |
+
# normalized features
|
| 1162 |
+
image_embeds = image_embeds / image_embeds.norm(p=2, dim=-1, keepdim=True)
|
| 1163 |
+
text_embeds = text_embeds / text_embeds.norm(p=2, dim=-1, keepdim=True)
|
| 1164 |
+
|
| 1165 |
+
# cosine similarity as logits
|
| 1166 |
+
logit_scale = self.logit_scale.exp()
|
| 1167 |
+
logits_per_text = torch.matmul(text_embeds, image_embeds.t()) * logit_scale
|
| 1168 |
+
logits_per_image = logits_per_text.T
|
| 1169 |
+
|
| 1170 |
+
loss = None
|
| 1171 |
+
if return_loss:
|
| 1172 |
+
loss = clip_loss(logits_per_text)
|
| 1173 |
+
|
| 1174 |
+
return AltCLIPOutput(
|
| 1175 |
+
loss=loss,
|
| 1176 |
+
logits_per_image=logits_per_image,
|
| 1177 |
+
logits_per_text=logits_per_text,
|
| 1178 |
+
text_embeds=text_embeds,
|
| 1179 |
+
image_embeds=image_embeds,
|
| 1180 |
+
text_model_output=text_outputs,
|
| 1181 |
+
vision_model_output=vision_outputs,
|
| 1182 |
+
)
|
| 1183 |
+
|
| 1184 |
+
|
| 1185 |
+
__all__ = ["AltCLIPPreTrainedModel", "AltCLIPVisionModel", "AltCLIPTextModel", "AltCLIPModel"]
|
third_party/transformers/src/transformers/models/altclip/processing_altclip.py
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright 2022 WenXiang ZhongzhiCheng LedellWu LiuGuang BoWenZhang 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 |
+
Image/Text processor class for AltCLIP
|
| 16 |
+
"""
|
| 17 |
+
|
| 18 |
+
from ...processing_utils import ProcessorMixin
|
| 19 |
+
from ...utils import auto_docstring
|
| 20 |
+
|
| 21 |
+
|
| 22 |
+
@auto_docstring
|
| 23 |
+
class AltCLIPProcessor(ProcessorMixin):
|
| 24 |
+
def __init__(self, image_processor=None, tokenizer=None):
|
| 25 |
+
super().__init__(image_processor, tokenizer)
|
| 26 |
+
|
| 27 |
+
|
| 28 |
+
__all__ = ["AltCLIPProcessor"]
|
third_party/transformers/src/transformers/models/auto/__init__.py
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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 .auto_factory import *
|
| 22 |
+
from .configuration_auto import *
|
| 23 |
+
from .feature_extraction_auto import *
|
| 24 |
+
from .image_processing_auto import *
|
| 25 |
+
from .modeling_auto import *
|
| 26 |
+
from .processing_auto import *
|
| 27 |
+
from .tokenization_auto import *
|
| 28 |
+
from .video_processing_auto import *
|
| 29 |
+
else:
|
| 30 |
+
import sys
|
| 31 |
+
|
| 32 |
+
_file = globals()["__file__"]
|
| 33 |
+
sys.modules[__name__] = _LazyModule(__name__, _file, define_import_structure(_file), module_spec=__spec__)
|
third_party/transformers/src/transformers/models/auto/auto_factory.py
ADDED
|
@@ -0,0 +1,662 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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 |
+
"""Factory function to build auto-model classes."""
|
| 15 |
+
|
| 16 |
+
import copy
|
| 17 |
+
import importlib
|
| 18 |
+
import json
|
| 19 |
+
import os
|
| 20 |
+
from collections import OrderedDict
|
| 21 |
+
from collections.abc import Iterator
|
| 22 |
+
from typing import Any, TypeVar
|
| 23 |
+
|
| 24 |
+
from huggingface_hub import repo_exists
|
| 25 |
+
|
| 26 |
+
from ...configuration_utils import PreTrainedConfig
|
| 27 |
+
from ...dynamic_module_utils import get_class_from_dynamic_module, resolve_trust_remote_code
|
| 28 |
+
from ...utils import (
|
| 29 |
+
CONFIG_NAME,
|
| 30 |
+
cached_file,
|
| 31 |
+
copy_func,
|
| 32 |
+
extract_commit_hash,
|
| 33 |
+
find_adapter_config_file,
|
| 34 |
+
is_peft_available,
|
| 35 |
+
is_torch_available,
|
| 36 |
+
logging,
|
| 37 |
+
requires_backends,
|
| 38 |
+
)
|
| 39 |
+
from .configuration_auto import AutoConfig, model_type_to_module_name, replace_list_option_in_docstrings
|
| 40 |
+
|
| 41 |
+
|
| 42 |
+
if is_torch_available():
|
| 43 |
+
from ...generation import GenerationMixin
|
| 44 |
+
|
| 45 |
+
|
| 46 |
+
logger = logging.get_logger(__name__)
|
| 47 |
+
|
| 48 |
+
_T = TypeVar("_T")
|
| 49 |
+
# Tokenizers will depend on packages installed, too much variance and there are no common base or Protocol
|
| 50 |
+
_LazyAutoMappingValue = tuple[type[Any] | None, type[Any] | None]
|
| 51 |
+
|
| 52 |
+
CLASS_DOCSTRING = """
|
| 53 |
+
This is a generic model class that will be instantiated as one of the model classes of the library when created
|
| 54 |
+
with the [`~BaseAutoModelClass.from_pretrained`] class method or the [`~BaseAutoModelClass.from_config`] class
|
| 55 |
+
method.
|
| 56 |
+
|
| 57 |
+
This class cannot be instantiated directly using `__init__()` (throws an error).
|
| 58 |
+
"""
|
| 59 |
+
|
| 60 |
+
FROM_CONFIG_DOCSTRING = """
|
| 61 |
+
Instantiates one of the model classes of the library from a configuration.
|
| 62 |
+
|
| 63 |
+
Note:
|
| 64 |
+
Loading a model from its configuration file does **not** load the model weights. It only affects the
|
| 65 |
+
model's configuration. Use [`~BaseAutoModelClass.from_pretrained`] to load the model weights.
|
| 66 |
+
|
| 67 |
+
Args:
|
| 68 |
+
config ([`PreTrainedConfig`]):
|
| 69 |
+
The model class to instantiate is selected based on the configuration class:
|
| 70 |
+
|
| 71 |
+
List options
|
| 72 |
+
attn_implementation (`str`, *optional*):
|
| 73 |
+
The attention implementation to use in the model (if relevant). Can be any of `"eager"` (manual implementation of the attention), `"sdpa"` (using [`F.scaled_dot_product_attention`](https://pytorch.org/docs/master/generated/torch.nn.functional.scaled_dot_product_attention.html)), `"flash_attention_2"` (using [Dao-AILab/flash-attention](https://github.com/Dao-AILab/flash-attention)), or `"flash_attention_3"` (using [Dao-AILab/flash-attention/hopper](https://github.com/Dao-AILab/flash-attention/tree/main/hopper)). By default, if available, SDPA will be used for torch>=2.1.1. The default is otherwise the manual `"eager"` implementation.
|
| 74 |
+
|
| 75 |
+
Examples:
|
| 76 |
+
|
| 77 |
+
```python
|
| 78 |
+
>>> from transformers import AutoConfig, BaseAutoModelClass
|
| 79 |
+
|
| 80 |
+
>>> # Download configuration from huggingface.co and cache.
|
| 81 |
+
>>> config = AutoConfig.from_pretrained("checkpoint_placeholder")
|
| 82 |
+
>>> model = BaseAutoModelClass.from_config(config)
|
| 83 |
+
```
|
| 84 |
+
"""
|
| 85 |
+
|
| 86 |
+
FROM_PRETRAINED_TORCH_DOCSTRING = """
|
| 87 |
+
Instantiate one of the model classes of the library from a pretrained model.
|
| 88 |
+
|
| 89 |
+
The model class to instantiate is selected based on the `model_type` property of the config object (either
|
| 90 |
+
passed as an argument or loaded from `pretrained_model_name_or_path` if possible), or when it's missing, by
|
| 91 |
+
falling back to using pattern matching on `pretrained_model_name_or_path`:
|
| 92 |
+
|
| 93 |
+
List options
|
| 94 |
+
|
| 95 |
+
The model is set in evaluation mode by default using `model.eval()` (so for instance, dropout modules are
|
| 96 |
+
deactivated). To train the model, you should first set it back in training mode with `model.train()`
|
| 97 |
+
|
| 98 |
+
Args:
|
| 99 |
+
pretrained_model_name_or_path (`str` or `os.PathLike`):
|
| 100 |
+
Can be either:
|
| 101 |
+
|
| 102 |
+
- A string, the *model id* of a pretrained model hosted inside a model repo on huggingface.co.
|
| 103 |
+
- A path to a *directory* containing model weights saved using
|
| 104 |
+
[`~PreTrainedModel.save_pretrained`], e.g., `./my_model_directory/`.
|
| 105 |
+
model_args (additional positional arguments, *optional*):
|
| 106 |
+
Will be passed along to the underlying model `__init__()` method.
|
| 107 |
+
config ([`PreTrainedConfig`], *optional*):
|
| 108 |
+
Configuration for the model to use instead of an automatically loaded configuration. Configuration can
|
| 109 |
+
be automatically loaded when:
|
| 110 |
+
|
| 111 |
+
- The model is a model provided by the library (loaded with the *model id* string of a pretrained
|
| 112 |
+
model).
|
| 113 |
+
- The model was saved using [`~PreTrainedModel.save_pretrained`] and is reloaded by supplying the
|
| 114 |
+
save directory.
|
| 115 |
+
- The model is loaded by supplying a local directory as `pretrained_model_name_or_path` and a
|
| 116 |
+
configuration JSON file named *config.json* is found in the directory.
|
| 117 |
+
state_dict (*dict[str, torch.Tensor]*, *optional*):
|
| 118 |
+
A state dictionary to use instead of a state dictionary loaded from saved weights file.
|
| 119 |
+
|
| 120 |
+
This option can be used if you want to create a model from a pretrained configuration but load your own
|
| 121 |
+
weights. In this case though, you should check if using [`~PreTrainedModel.save_pretrained`] and
|
| 122 |
+
[`~PreTrainedModel.from_pretrained`] is not a simpler option.
|
| 123 |
+
cache_dir (`str` or `os.PathLike`, *optional*):
|
| 124 |
+
Path to a directory in which a downloaded pretrained model configuration should be cached if the
|
| 125 |
+
standard cache should not be used.
|
| 126 |
+
force_download (`bool`, *optional*, defaults to `False`):
|
| 127 |
+
Whether or not to force the (re-)download of the model weights and configuration files, overriding the
|
| 128 |
+
cached versions if they exist.
|
| 129 |
+
proxies (`dict[str, str]`, *optional*):
|
| 130 |
+
A dictionary of proxy servers to use by protocol or endpoint, e.g., `{'http': 'foo.bar:3128',
|
| 131 |
+
'http://hostname': 'foo.bar:4012'}`. The proxies are used on each request.
|
| 132 |
+
output_loading_info(`bool`, *optional*, defaults to `False`):
|
| 133 |
+
Whether or not to also return a dictionary containing missing keys, unexpected keys and error messages.
|
| 134 |
+
local_files_only(`bool`, *optional*, defaults to `False`):
|
| 135 |
+
Whether or not to only look at local files (e.g., not try downloading the model).
|
| 136 |
+
revision (`str`, *optional*, defaults to `"main"`):
|
| 137 |
+
The specific model version to use. It can be a branch name, a tag name, or a commit id, since we use a
|
| 138 |
+
git-based system for storing models and other artifacts on huggingface.co, so `revision` can be any
|
| 139 |
+
identifier allowed by git.
|
| 140 |
+
trust_remote_code (`bool`, *optional*, defaults to `False`):
|
| 141 |
+
Whether or not to allow for custom models defined on the Hub in their own modeling files. This option
|
| 142 |
+
should only be set to `True` for repositories you trust and in which you have read the code, as it will
|
| 143 |
+
execute code present on the Hub on your local machine.
|
| 144 |
+
code_revision (`str`, *optional*, defaults to `"main"`):
|
| 145 |
+
The specific revision to use for the code on the Hub, if the code leaves in a different repository than
|
| 146 |
+
the rest of the model. It can be a branch name, a tag name, or a commit id, since we use a git-based
|
| 147 |
+
system for storing models and other artifacts on huggingface.co, so `revision` can be any identifier
|
| 148 |
+
allowed by git.
|
| 149 |
+
kwargs (additional keyword arguments, *optional*):
|
| 150 |
+
Can be used to update the configuration object (after it being loaded) and initiate the model (e.g.,
|
| 151 |
+
`output_attentions=True`). Behaves differently depending on whether a `config` is provided or
|
| 152 |
+
automatically loaded:
|
| 153 |
+
|
| 154 |
+
- If a configuration is provided with `config`, `**kwargs` will be directly passed to the
|
| 155 |
+
underlying model's `__init__` method (we assume all relevant updates to the configuration have
|
| 156 |
+
already been done)
|
| 157 |
+
- If a configuration is not provided, `kwargs` will be first passed to the configuration class
|
| 158 |
+
initialization function ([`~PreTrainedConfig.from_pretrained`]). Each key of `kwargs` that
|
| 159 |
+
corresponds to a configuration attribute will be used to override said attribute with the
|
| 160 |
+
supplied `kwargs` value. Remaining keys that do not correspond to any configuration attribute
|
| 161 |
+
will be passed to the underlying model's `__init__` function.
|
| 162 |
+
|
| 163 |
+
Examples:
|
| 164 |
+
|
| 165 |
+
```python
|
| 166 |
+
>>> from transformers import AutoConfig, BaseAutoModelClass
|
| 167 |
+
|
| 168 |
+
>>> # Download model and configuration from huggingface.co and cache.
|
| 169 |
+
>>> model = BaseAutoModelClass.from_pretrained("checkpoint_placeholder")
|
| 170 |
+
|
| 171 |
+
>>> # Update configuration during loading
|
| 172 |
+
>>> model = BaseAutoModelClass.from_pretrained("checkpoint_placeholder", output_attentions=True)
|
| 173 |
+
>>> model.config.output_attentions
|
| 174 |
+
True
|
| 175 |
+
```
|
| 176 |
+
"""
|
| 177 |
+
|
| 178 |
+
|
| 179 |
+
def _get_model_class(config, model_mapping):
|
| 180 |
+
supported_models = model_mapping[type(config)]
|
| 181 |
+
if not isinstance(supported_models, (list, tuple)):
|
| 182 |
+
return supported_models
|
| 183 |
+
|
| 184 |
+
name_to_model = {model.__name__: model for model in supported_models}
|
| 185 |
+
architectures = getattr(config, "architectures", [])
|
| 186 |
+
for arch in architectures:
|
| 187 |
+
if arch in name_to_model:
|
| 188 |
+
return name_to_model[arch]
|
| 189 |
+
|
| 190 |
+
# If not architecture is set in the config or match the supported models, the first element of the tuple is the
|
| 191 |
+
# defaults.
|
| 192 |
+
return supported_models[0]
|
| 193 |
+
|
| 194 |
+
|
| 195 |
+
class _BaseAutoModelClass:
|
| 196 |
+
# Base class for auto models.
|
| 197 |
+
_model_mapping = None
|
| 198 |
+
|
| 199 |
+
def __init__(self, *args, **kwargs) -> None:
|
| 200 |
+
raise OSError(
|
| 201 |
+
f"{self.__class__.__name__} is designed to be instantiated "
|
| 202 |
+
f"using the `{self.__class__.__name__}.from_pretrained(pretrained_model_name_or_path)` or "
|
| 203 |
+
f"`{self.__class__.__name__}.from_config(config)` methods."
|
| 204 |
+
)
|
| 205 |
+
|
| 206 |
+
@classmethod
|
| 207 |
+
def from_config(cls, config, **kwargs):
|
| 208 |
+
trust_remote_code = kwargs.pop("trust_remote_code", None)
|
| 209 |
+
has_remote_code = hasattr(config, "auto_map") and cls.__name__ in config.auto_map
|
| 210 |
+
has_local_code = type(config) in cls._model_mapping
|
| 211 |
+
explicit_local_code = has_local_code and not _get_model_class(
|
| 212 |
+
config, cls._model_mapping
|
| 213 |
+
).__module__.startswith("transformers.")
|
| 214 |
+
if has_remote_code:
|
| 215 |
+
class_ref = config.auto_map[cls.__name__]
|
| 216 |
+
if "--" in class_ref:
|
| 217 |
+
upstream_repo = class_ref.split("--")[0]
|
| 218 |
+
else:
|
| 219 |
+
upstream_repo = None
|
| 220 |
+
trust_remote_code = resolve_trust_remote_code(
|
| 221 |
+
trust_remote_code, config._name_or_path, has_local_code, has_remote_code, upstream_repo=upstream_repo
|
| 222 |
+
)
|
| 223 |
+
|
| 224 |
+
if has_remote_code and trust_remote_code and not explicit_local_code:
|
| 225 |
+
if "--" in class_ref:
|
| 226 |
+
repo_id, class_ref = class_ref.split("--")
|
| 227 |
+
else:
|
| 228 |
+
repo_id = config.name_or_path
|
| 229 |
+
model_class = get_class_from_dynamic_module(class_ref, repo_id, **kwargs)
|
| 230 |
+
# This block handles the case where the user is loading a model with `trust_remote_code=True`
|
| 231 |
+
# but a library model exists with the same name. We don't want to override the autoclass
|
| 232 |
+
# mappings in this case, or all future loads of that model will be the remote code model.
|
| 233 |
+
if not has_local_code:
|
| 234 |
+
cls.register(config.__class__, model_class, exist_ok=True)
|
| 235 |
+
model_class.register_for_auto_class(auto_class=cls)
|
| 236 |
+
_ = kwargs.pop("code_revision", None)
|
| 237 |
+
model_class = add_generation_mixin_to_remote_model(model_class)
|
| 238 |
+
return model_class._from_config(config, **kwargs)
|
| 239 |
+
elif has_local_code:
|
| 240 |
+
model_class = _get_model_class(config, cls._model_mapping)
|
| 241 |
+
return model_class._from_config(config, **kwargs)
|
| 242 |
+
|
| 243 |
+
raise ValueError(
|
| 244 |
+
f"Unrecognized configuration class {config.__class__} for this kind of AutoModel: {cls.__name__}.\n"
|
| 245 |
+
f"Model type should be one of {', '.join(c.__name__ for c in cls._model_mapping)}."
|
| 246 |
+
)
|
| 247 |
+
|
| 248 |
+
@classmethod
|
| 249 |
+
def _prepare_config_for_auto_class(cls, config: PreTrainedConfig) -> PreTrainedConfig:
|
| 250 |
+
"""Additional autoclass-specific config post-loading manipulation. May be overridden in subclasses."""
|
| 251 |
+
return config
|
| 252 |
+
|
| 253 |
+
@classmethod
|
| 254 |
+
def from_pretrained(cls, pretrained_model_name_or_path: str | os.PathLike[str], *model_args, **kwargs):
|
| 255 |
+
config = kwargs.pop("config", None)
|
| 256 |
+
trust_remote_code = kwargs.get("trust_remote_code")
|
| 257 |
+
kwargs["_from_auto"] = True
|
| 258 |
+
hub_kwargs_names = [
|
| 259 |
+
"cache_dir",
|
| 260 |
+
"force_download",
|
| 261 |
+
"local_files_only",
|
| 262 |
+
"proxies",
|
| 263 |
+
"revision",
|
| 264 |
+
"subfolder",
|
| 265 |
+
"token",
|
| 266 |
+
]
|
| 267 |
+
hub_kwargs = {name: kwargs.pop(name) for name in hub_kwargs_names if name in kwargs}
|
| 268 |
+
code_revision = kwargs.pop("code_revision", None)
|
| 269 |
+
commit_hash = kwargs.pop("_commit_hash", None)
|
| 270 |
+
adapter_kwargs = kwargs.pop("adapter_kwargs", None)
|
| 271 |
+
|
| 272 |
+
token = hub_kwargs.pop("token", None)
|
| 273 |
+
|
| 274 |
+
if token is not None:
|
| 275 |
+
hub_kwargs["token"] = token
|
| 276 |
+
|
| 277 |
+
if commit_hash is None:
|
| 278 |
+
if not isinstance(config, PreTrainedConfig):
|
| 279 |
+
# We make a call to the config file first (which may be absent) to get the commit hash as soon as possible
|
| 280 |
+
resolved_config_file = cached_file(
|
| 281 |
+
pretrained_model_name_or_path,
|
| 282 |
+
CONFIG_NAME,
|
| 283 |
+
_raise_exceptions_for_gated_repo=False,
|
| 284 |
+
_raise_exceptions_for_missing_entries=False,
|
| 285 |
+
_raise_exceptions_for_connection_errors=False,
|
| 286 |
+
**hub_kwargs,
|
| 287 |
+
)
|
| 288 |
+
commit_hash = extract_commit_hash(resolved_config_file, commit_hash)
|
| 289 |
+
else:
|
| 290 |
+
commit_hash = getattr(config, "_commit_hash", None)
|
| 291 |
+
|
| 292 |
+
if is_peft_available():
|
| 293 |
+
if adapter_kwargs is None:
|
| 294 |
+
adapter_kwargs = {}
|
| 295 |
+
adapter_kwargs = adapter_kwargs.copy() # avoid mutating original
|
| 296 |
+
if token is not None:
|
| 297 |
+
adapter_kwargs["token"] = token
|
| 298 |
+
|
| 299 |
+
maybe_adapter_path = find_adapter_config_file(
|
| 300 |
+
pretrained_model_name_or_path, _commit_hash=commit_hash, **adapter_kwargs
|
| 301 |
+
)
|
| 302 |
+
|
| 303 |
+
if maybe_adapter_path is not None:
|
| 304 |
+
with open(maybe_adapter_path, "r", encoding="utf-8") as f:
|
| 305 |
+
adapter_config = json.load(f)
|
| 306 |
+
|
| 307 |
+
adapter_kwargs["_adapter_model_path"] = pretrained_model_name_or_path
|
| 308 |
+
# Only override the model name/path if the current value doesn't point to a
|
| 309 |
+
# complete model with an embedded adapter so that local models with embedded
|
| 310 |
+
# adapters will load from the local base model rather than pull the base
|
| 311 |
+
# model named in the adapter's config from the hub.
|
| 312 |
+
if not os.path.exists(pretrained_model_name_or_path) or not os.path.exists(
|
| 313 |
+
os.path.join(pretrained_model_name_or_path, CONFIG_NAME)
|
| 314 |
+
):
|
| 315 |
+
pretrained_model_name_or_path = adapter_config["base_model_name_or_path"]
|
| 316 |
+
|
| 317 |
+
if not isinstance(config, PreTrainedConfig):
|
| 318 |
+
kwargs_orig = copy.deepcopy(kwargs)
|
| 319 |
+
# ensure not to pollute the config object with dtype="auto" - since it's
|
| 320 |
+
# meaningless in the context of the config object - torch.dtype values are acceptable
|
| 321 |
+
if kwargs.get("torch_dtype") == "auto":
|
| 322 |
+
_ = kwargs.pop("torch_dtype")
|
| 323 |
+
if kwargs.get("dtype") == "auto":
|
| 324 |
+
_ = kwargs.pop("dtype")
|
| 325 |
+
# to not overwrite the quantization_config if config has a quantization_config
|
| 326 |
+
if kwargs.get("quantization_config") is not None:
|
| 327 |
+
_ = kwargs.pop("quantization_config")
|
| 328 |
+
|
| 329 |
+
config, kwargs = AutoConfig.from_pretrained(
|
| 330 |
+
pretrained_model_name_or_path,
|
| 331 |
+
return_unused_kwargs=True,
|
| 332 |
+
code_revision=code_revision,
|
| 333 |
+
_commit_hash=commit_hash,
|
| 334 |
+
**hub_kwargs,
|
| 335 |
+
**kwargs,
|
| 336 |
+
)
|
| 337 |
+
|
| 338 |
+
# if torch_dtype=auto was passed here, ensure to pass it on
|
| 339 |
+
if kwargs_orig.get("torch_dtype", None) == "auto":
|
| 340 |
+
kwargs["torch_dtype"] = "auto"
|
| 341 |
+
if kwargs_orig.get("dtype", None) == "auto":
|
| 342 |
+
kwargs["dtype"] = "auto"
|
| 343 |
+
if kwargs_orig.get("quantization_config", None) is not None:
|
| 344 |
+
kwargs["quantization_config"] = kwargs_orig["quantization_config"]
|
| 345 |
+
|
| 346 |
+
has_remote_code = hasattr(config, "auto_map") and cls.__name__ in config.auto_map
|
| 347 |
+
has_local_code = type(config) in cls._model_mapping
|
| 348 |
+
explicit_local_code = has_local_code and not _get_model_class(
|
| 349 |
+
config, cls._model_mapping
|
| 350 |
+
).__module__.startswith("transformers.")
|
| 351 |
+
upstream_repo = None
|
| 352 |
+
if has_remote_code:
|
| 353 |
+
class_ref = config.auto_map[cls.__name__]
|
| 354 |
+
if "--" in class_ref:
|
| 355 |
+
upstream_repo = class_ref.split("--")[0]
|
| 356 |
+
trust_remote_code = resolve_trust_remote_code(
|
| 357 |
+
trust_remote_code,
|
| 358 |
+
pretrained_model_name_or_path,
|
| 359 |
+
has_local_code,
|
| 360 |
+
has_remote_code,
|
| 361 |
+
upstream_repo=upstream_repo,
|
| 362 |
+
)
|
| 363 |
+
kwargs["trust_remote_code"] = trust_remote_code
|
| 364 |
+
|
| 365 |
+
# Set the adapter kwargs
|
| 366 |
+
kwargs["adapter_kwargs"] = adapter_kwargs
|
| 367 |
+
|
| 368 |
+
if has_remote_code and trust_remote_code and not explicit_local_code:
|
| 369 |
+
model_class = get_class_from_dynamic_module(
|
| 370 |
+
class_ref, pretrained_model_name_or_path, code_revision=code_revision, **hub_kwargs, **kwargs
|
| 371 |
+
)
|
| 372 |
+
_ = hub_kwargs.pop("code_revision", None)
|
| 373 |
+
# This block handles the case where the user is loading a model with `trust_remote_code=True`
|
| 374 |
+
# but a library model exists with the same name. We don't want to override the autoclass
|
| 375 |
+
# mappings in this case, or all future loads of that model will be the remote code model.
|
| 376 |
+
if not has_local_code:
|
| 377 |
+
cls.register(config.__class__, model_class, exist_ok=True)
|
| 378 |
+
model_class.register_for_auto_class(auto_class=cls)
|
| 379 |
+
model_class = add_generation_mixin_to_remote_model(model_class)
|
| 380 |
+
return model_class.from_pretrained(
|
| 381 |
+
pretrained_model_name_or_path, *model_args, config=config, **hub_kwargs, **kwargs
|
| 382 |
+
)
|
| 383 |
+
elif has_local_code:
|
| 384 |
+
model_class = _get_model_class(config, cls._model_mapping)
|
| 385 |
+
if model_class.config_class == config.sub_configs.get("text_config", None):
|
| 386 |
+
config = config.get_text_config()
|
| 387 |
+
return model_class.from_pretrained(
|
| 388 |
+
pretrained_model_name_or_path, *model_args, config=config, **hub_kwargs, **kwargs
|
| 389 |
+
)
|
| 390 |
+
raise ValueError(
|
| 391 |
+
f"Unrecognized configuration class {config.__class__} for this kind of AutoModel: {cls.__name__}.\n"
|
| 392 |
+
f"Model type should be one of {', '.join(c.__name__ for c in cls._model_mapping)}."
|
| 393 |
+
)
|
| 394 |
+
|
| 395 |
+
@classmethod
|
| 396 |
+
def register(cls, config_class, model_class, exist_ok=False) -> None:
|
| 397 |
+
"""
|
| 398 |
+
Register a new model for this class.
|
| 399 |
+
|
| 400 |
+
Args:
|
| 401 |
+
config_class ([`PreTrainedConfig`]):
|
| 402 |
+
The configuration corresponding to the model to register.
|
| 403 |
+
model_class ([`PreTrainedModel`]):
|
| 404 |
+
The model to register.
|
| 405 |
+
"""
|
| 406 |
+
if hasattr(model_class, "config_class") and model_class.config_class.__name__ != config_class.__name__:
|
| 407 |
+
raise ValueError(
|
| 408 |
+
"The model class you are passing has a `config_class` attribute that is not consistent with the "
|
| 409 |
+
f"config class you passed (model has {model_class.config_class} and you passed {config_class}. Fix "
|
| 410 |
+
"one of those so they match!"
|
| 411 |
+
)
|
| 412 |
+
cls._model_mapping.register(config_class, model_class, exist_ok=exist_ok)
|
| 413 |
+
|
| 414 |
+
|
| 415 |
+
class _BaseAutoBackboneClass(_BaseAutoModelClass):
|
| 416 |
+
# Base class for auto backbone models.
|
| 417 |
+
_model_mapping = None
|
| 418 |
+
|
| 419 |
+
@classmethod
|
| 420 |
+
def _load_timm_backbone_from_pretrained(cls, pretrained_model_name_or_path, *model_args, **kwargs):
|
| 421 |
+
requires_backends(cls, ["vision", "timm"])
|
| 422 |
+
from ...models.timm_backbone import TimmBackboneConfig
|
| 423 |
+
|
| 424 |
+
config = kwargs.pop("config", TimmBackboneConfig())
|
| 425 |
+
|
| 426 |
+
if kwargs.get("out_features") is not None:
|
| 427 |
+
raise ValueError("Cannot specify `out_features` for timm backbones")
|
| 428 |
+
|
| 429 |
+
if kwargs.get("output_loading_info", False):
|
| 430 |
+
raise ValueError("Cannot specify `output_loading_info=True` when loading from timm")
|
| 431 |
+
|
| 432 |
+
num_channels = kwargs.pop("num_channels", config.num_channels)
|
| 433 |
+
features_only = kwargs.pop("features_only", config.features_only)
|
| 434 |
+
out_indices = kwargs.pop("out_indices", config.out_indices)
|
| 435 |
+
config = TimmBackboneConfig(
|
| 436 |
+
backbone=pretrained_model_name_or_path,
|
| 437 |
+
num_channels=num_channels,
|
| 438 |
+
features_only=features_only,
|
| 439 |
+
out_indices=out_indices,
|
| 440 |
+
)
|
| 441 |
+
# Always load a pretrained model when `from_pretrained` is called
|
| 442 |
+
kwargs.pop("use_pretrained_backbone", None)
|
| 443 |
+
return super().from_config(config, pretrained=True, **kwargs)
|
| 444 |
+
|
| 445 |
+
@classmethod
|
| 446 |
+
def from_pretrained(cls, pretrained_model_name_or_path, *model_args, **kwargs):
|
| 447 |
+
kwargs.pop("use_timm_backbone", None)
|
| 448 |
+
if not repo_exists(pretrained_model_name_or_path):
|
| 449 |
+
return cls._load_timm_backbone_from_pretrained(pretrained_model_name_or_path, *model_args, **kwargs)
|
| 450 |
+
|
| 451 |
+
return super().from_pretrained(pretrained_model_name_or_path, *model_args, **kwargs)
|
| 452 |
+
|
| 453 |
+
|
| 454 |
+
def insert_head_doc(docstring, head_doc: str = ""):
|
| 455 |
+
if len(head_doc) > 0:
|
| 456 |
+
return docstring.replace(
|
| 457 |
+
"one of the model classes of the library ",
|
| 458 |
+
f"one of the model classes of the library (with a {head_doc} head) ",
|
| 459 |
+
)
|
| 460 |
+
return docstring.replace(
|
| 461 |
+
"one of the model classes of the library ", "one of the base model classes of the library "
|
| 462 |
+
)
|
| 463 |
+
|
| 464 |
+
|
| 465 |
+
def auto_class_update(cls, checkpoint_for_example: str = "google-bert/bert-base-cased", head_doc: str = ""):
|
| 466 |
+
# Create a new class with the right name from the base class
|
| 467 |
+
model_mapping = cls._model_mapping
|
| 468 |
+
name = cls.__name__
|
| 469 |
+
class_docstring = insert_head_doc(CLASS_DOCSTRING, head_doc=head_doc)
|
| 470 |
+
cls.__doc__ = class_docstring.replace("BaseAutoModelClass", name)
|
| 471 |
+
|
| 472 |
+
# Now we need to copy and re-register `from_config` and `from_pretrained` as class methods otherwise we can't
|
| 473 |
+
# have a specific docstrings for them.
|
| 474 |
+
from_config = copy_func(_BaseAutoModelClass.from_config)
|
| 475 |
+
from_config_docstring = insert_head_doc(FROM_CONFIG_DOCSTRING, head_doc=head_doc)
|
| 476 |
+
from_config_docstring = from_config_docstring.replace("BaseAutoModelClass", name)
|
| 477 |
+
from_config_docstring = from_config_docstring.replace("checkpoint_placeholder", checkpoint_for_example)
|
| 478 |
+
from_config.__doc__ = from_config_docstring
|
| 479 |
+
from_config = replace_list_option_in_docstrings(model_mapping._model_mapping, use_model_types=False)(from_config)
|
| 480 |
+
cls.from_config = classmethod(from_config)
|
| 481 |
+
|
| 482 |
+
from_pretrained_docstring = FROM_PRETRAINED_TORCH_DOCSTRING
|
| 483 |
+
from_pretrained = copy_func(_BaseAutoModelClass.from_pretrained)
|
| 484 |
+
from_pretrained_docstring = insert_head_doc(from_pretrained_docstring, head_doc=head_doc)
|
| 485 |
+
from_pretrained_docstring = from_pretrained_docstring.replace("BaseAutoModelClass", name)
|
| 486 |
+
from_pretrained_docstring = from_pretrained_docstring.replace("checkpoint_placeholder", checkpoint_for_example)
|
| 487 |
+
shortcut = checkpoint_for_example.split("/")[-1].split("-")[0]
|
| 488 |
+
from_pretrained_docstring = from_pretrained_docstring.replace("shortcut_placeholder", shortcut)
|
| 489 |
+
from_pretrained.__doc__ = from_pretrained_docstring
|
| 490 |
+
from_pretrained = replace_list_option_in_docstrings(model_mapping._model_mapping)(from_pretrained)
|
| 491 |
+
cls.from_pretrained = classmethod(from_pretrained)
|
| 492 |
+
return cls
|
| 493 |
+
|
| 494 |
+
|
| 495 |
+
def get_values(model_mapping):
|
| 496 |
+
result = []
|
| 497 |
+
for model in model_mapping.values():
|
| 498 |
+
if isinstance(model, (list, tuple)):
|
| 499 |
+
result += list(model)
|
| 500 |
+
else:
|
| 501 |
+
result.append(model)
|
| 502 |
+
|
| 503 |
+
return result
|
| 504 |
+
|
| 505 |
+
|
| 506 |
+
def getattribute_from_module(module, attr):
|
| 507 |
+
if attr is None:
|
| 508 |
+
return None
|
| 509 |
+
if isinstance(attr, tuple):
|
| 510 |
+
return tuple(getattribute_from_module(module, a) for a in attr)
|
| 511 |
+
if isinstance(attr, dict):
|
| 512 |
+
return {k: getattribute_from_module(module, v) for k, v in attr.items()}
|
| 513 |
+
if hasattr(module, attr):
|
| 514 |
+
return getattr(module, attr)
|
| 515 |
+
# Some of the mappings have entries model_type -> object of another model type. In that case we try to grab the
|
| 516 |
+
# object at the top level.
|
| 517 |
+
transformers_module = importlib.import_module("transformers")
|
| 518 |
+
|
| 519 |
+
if module != transformers_module:
|
| 520 |
+
try:
|
| 521 |
+
return getattribute_from_module(transformers_module, attr)
|
| 522 |
+
except ValueError:
|
| 523 |
+
raise ValueError(f"Could not find {attr} neither in {module} nor in {transformers_module}!")
|
| 524 |
+
else:
|
| 525 |
+
raise ValueError(f"Could not find {attr} in {transformers_module}!")
|
| 526 |
+
|
| 527 |
+
|
| 528 |
+
def add_generation_mixin_to_remote_model(model_class):
|
| 529 |
+
"""
|
| 530 |
+
Adds `GenerationMixin` to the inheritance of `model_class`, if `model_class` is a PyTorch model.
|
| 531 |
+
|
| 532 |
+
This function is used for backwards compatibility purposes: in v4.45, we've started a deprecation cycle to make
|
| 533 |
+
`PreTrainedModel` stop inheriting from `GenerationMixin`. Without this function, older models dynamically loaded
|
| 534 |
+
from the Hub may not have the `generate` method after we remove the inheritance.
|
| 535 |
+
"""
|
| 536 |
+
# 1. If it is not a PT model (i.e. doesn't inherit Module), do nothing
|
| 537 |
+
if "torch.nn.modules.module.Module" not in str(model_class.__mro__):
|
| 538 |
+
return model_class
|
| 539 |
+
|
| 540 |
+
# 2. If it already **directly** inherits from GenerationMixin, do nothing
|
| 541 |
+
if "GenerationMixin" in str(model_class.__bases__):
|
| 542 |
+
return model_class
|
| 543 |
+
|
| 544 |
+
# 3. Prior to v4.45, we could detect whether a model was `generate`-compatible if it had its own `generate` and/or
|
| 545 |
+
# `prepare_inputs_for_generation` method.
|
| 546 |
+
has_custom_generate_in_class = hasattr(model_class, "generate") and "GenerationMixin" not in str(
|
| 547 |
+
getattr(model_class, "generate")
|
| 548 |
+
)
|
| 549 |
+
has_custom_prepare_inputs = hasattr(model_class, "prepare_inputs_for_generation") and "GenerationMixin" not in str(
|
| 550 |
+
getattr(model_class, "prepare_inputs_for_generation")
|
| 551 |
+
)
|
| 552 |
+
if has_custom_generate_in_class or has_custom_prepare_inputs:
|
| 553 |
+
model_class_with_generation_mixin = type(
|
| 554 |
+
model_class.__name__, (model_class, GenerationMixin), {**model_class.__dict__}
|
| 555 |
+
)
|
| 556 |
+
return model_class_with_generation_mixin
|
| 557 |
+
return model_class
|
| 558 |
+
|
| 559 |
+
|
| 560 |
+
class _LazyAutoMapping(OrderedDict[type[PreTrainedConfig], _LazyAutoMappingValue]):
|
| 561 |
+
"""
|
| 562 |
+
A mapping config to object (model or tokenizer for instance) that will load keys and values when it is accessed.
|
| 563 |
+
|
| 564 |
+
Args:
|
| 565 |
+
- config_mapping: The map model type to config class
|
| 566 |
+
- model_mapping: The map model type to model (or tokenizer) class
|
| 567 |
+
"""
|
| 568 |
+
|
| 569 |
+
def __init__(self, config_mapping, model_mapping) -> None:
|
| 570 |
+
self._config_mapping = config_mapping
|
| 571 |
+
self._reverse_config_mapping = {v: k for k, v in config_mapping.items()}
|
| 572 |
+
self._model_mapping = model_mapping
|
| 573 |
+
self._model_mapping._model_mapping = self
|
| 574 |
+
self._extra_content = {}
|
| 575 |
+
self._modules = {}
|
| 576 |
+
|
| 577 |
+
def __len__(self) -> int:
|
| 578 |
+
common_keys = set(self._config_mapping.keys()).intersection(self._model_mapping.keys())
|
| 579 |
+
return len(common_keys) + len(self._extra_content)
|
| 580 |
+
|
| 581 |
+
def __getitem__(self, key: type[PreTrainedConfig]) -> _LazyAutoMappingValue:
|
| 582 |
+
if key in self._extra_content:
|
| 583 |
+
return self._extra_content[key]
|
| 584 |
+
model_type = self._reverse_config_mapping[key.__name__]
|
| 585 |
+
if model_type in self._model_mapping:
|
| 586 |
+
model_name = self._model_mapping[model_type]
|
| 587 |
+
return self._load_attr_from_module(model_type, model_name)
|
| 588 |
+
|
| 589 |
+
# Maybe there was several model types associated with this config.
|
| 590 |
+
model_types = [k for k, v in self._config_mapping.items() if v == key.__name__]
|
| 591 |
+
for mtype in model_types:
|
| 592 |
+
if mtype in self._model_mapping:
|
| 593 |
+
model_name = self._model_mapping[mtype]
|
| 594 |
+
return self._load_attr_from_module(mtype, model_name)
|
| 595 |
+
raise KeyError(key)
|
| 596 |
+
|
| 597 |
+
def _load_attr_from_module(self, model_type, attr):
|
| 598 |
+
module_name = model_type_to_module_name(model_type)
|
| 599 |
+
if module_name not in self._modules:
|
| 600 |
+
self._modules[module_name] = importlib.import_module(f".{module_name}", "transformers.models")
|
| 601 |
+
return getattribute_from_module(self._modules[module_name], attr)
|
| 602 |
+
|
| 603 |
+
def keys(self) -> list[type[PreTrainedConfig]]:
|
| 604 |
+
mapping_keys = [
|
| 605 |
+
self._load_attr_from_module(key, name)
|
| 606 |
+
for key, name in self._config_mapping.items()
|
| 607 |
+
if key in self._model_mapping
|
| 608 |
+
]
|
| 609 |
+
return mapping_keys + list(self._extra_content.keys())
|
| 610 |
+
|
| 611 |
+
def get(self, key: type[PreTrainedConfig], default: _T) -> _LazyAutoMappingValue | _T:
|
| 612 |
+
try:
|
| 613 |
+
return self.__getitem__(key)
|
| 614 |
+
except KeyError:
|
| 615 |
+
return default
|
| 616 |
+
|
| 617 |
+
def __bool__(self) -> bool:
|
| 618 |
+
return bool(self.keys())
|
| 619 |
+
|
| 620 |
+
def values(self) -> list[_LazyAutoMappingValue]:
|
| 621 |
+
mapping_values = [
|
| 622 |
+
self._load_attr_from_module(key, name)
|
| 623 |
+
for key, name in self._model_mapping.items()
|
| 624 |
+
if key in self._config_mapping
|
| 625 |
+
]
|
| 626 |
+
return mapping_values + list(self._extra_content.values())
|
| 627 |
+
|
| 628 |
+
def items(self) -> list[tuple[type[PreTrainedConfig], _LazyAutoMappingValue]]:
|
| 629 |
+
mapping_items = [
|
| 630 |
+
(
|
| 631 |
+
self._load_attr_from_module(key, self._config_mapping[key]),
|
| 632 |
+
self._load_attr_from_module(key, self._model_mapping[key]),
|
| 633 |
+
)
|
| 634 |
+
for key in self._model_mapping
|
| 635 |
+
if key in self._config_mapping
|
| 636 |
+
]
|
| 637 |
+
return mapping_items + list(self._extra_content.items())
|
| 638 |
+
|
| 639 |
+
def __iter__(self) -> Iterator[type[PreTrainedConfig]]:
|
| 640 |
+
return iter(self.keys())
|
| 641 |
+
|
| 642 |
+
def __contains__(self, item: type) -> bool:
|
| 643 |
+
if item in self._extra_content:
|
| 644 |
+
return True
|
| 645 |
+
if not hasattr(item, "__name__") or item.__name__ not in self._reverse_config_mapping:
|
| 646 |
+
return False
|
| 647 |
+
model_type = self._reverse_config_mapping[item.__name__]
|
| 648 |
+
return model_type in self._model_mapping
|
| 649 |
+
|
| 650 |
+
def register(self, key: type[PreTrainedConfig], value: _LazyAutoMappingValue, exist_ok=False) -> None:
|
| 651 |
+
"""
|
| 652 |
+
Register a new model in this mapping.
|
| 653 |
+
"""
|
| 654 |
+
if hasattr(key, "__name__") and key.__name__ in self._reverse_config_mapping:
|
| 655 |
+
model_type = self._reverse_config_mapping[key.__name__]
|
| 656 |
+
if model_type in self._model_mapping and not exist_ok:
|
| 657 |
+
raise ValueError(f"'{key}' is already used by a Transformers model.")
|
| 658 |
+
|
| 659 |
+
self._extra_content[key] = value
|
| 660 |
+
|
| 661 |
+
|
| 662 |
+
__all__ = ["get_values"]
|
third_party/transformers/src/transformers/models/auto/configuration_auto.py
ADDED
|
@@ -0,0 +1,1551 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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 |
+
"""Auto Config class."""
|
| 15 |
+
|
| 16 |
+
import importlib
|
| 17 |
+
import os
|
| 18 |
+
import re
|
| 19 |
+
from collections import OrderedDict
|
| 20 |
+
from collections.abc import Callable, Iterator, KeysView, ValuesView
|
| 21 |
+
from typing import Any, TypeVar
|
| 22 |
+
|
| 23 |
+
from ...configuration_utils import PreTrainedConfig
|
| 24 |
+
from ...dynamic_module_utils import get_class_from_dynamic_module, resolve_trust_remote_code
|
| 25 |
+
from ...utils import CONFIG_NAME, logging
|
| 26 |
+
|
| 27 |
+
|
| 28 |
+
logger = logging.get_logger(__name__)
|
| 29 |
+
|
| 30 |
+
|
| 31 |
+
_CallableT = TypeVar("_CallableT", bound=Callable[..., Any])
|
| 32 |
+
|
| 33 |
+
|
| 34 |
+
CONFIG_MAPPING_NAMES = OrderedDict[str, str](
|
| 35 |
+
[
|
| 36 |
+
# Add configs here
|
| 37 |
+
("afmoe", "AfmoeConfig"),
|
| 38 |
+
("aimv2", "Aimv2Config"),
|
| 39 |
+
("aimv2_vision_model", "Aimv2VisionConfig"),
|
| 40 |
+
("albert", "AlbertConfig"),
|
| 41 |
+
("align", "AlignConfig"),
|
| 42 |
+
("altclip", "AltCLIPConfig"),
|
| 43 |
+
("apertus", "ApertusConfig"),
|
| 44 |
+
("arcee", "ArceeConfig"),
|
| 45 |
+
("aria", "AriaConfig"),
|
| 46 |
+
("aria_text", "AriaTextConfig"),
|
| 47 |
+
("audio-spectrogram-transformer", "ASTConfig"),
|
| 48 |
+
("audioflamingo3", "AudioFlamingo3Config"),
|
| 49 |
+
("audioflamingo3_encoder", "AudioFlamingo3EncoderConfig"),
|
| 50 |
+
("autoformer", "AutoformerConfig"),
|
| 51 |
+
("aya_vision", "AyaVisionConfig"),
|
| 52 |
+
("bamba", "BambaConfig"),
|
| 53 |
+
("bark", "BarkConfig"),
|
| 54 |
+
("bart", "BartConfig"),
|
| 55 |
+
("beit", "BeitConfig"),
|
| 56 |
+
("bert", "BertConfig"),
|
| 57 |
+
("bert-generation", "BertGenerationConfig"),
|
| 58 |
+
("big_bird", "BigBirdConfig"),
|
| 59 |
+
("bigbird_pegasus", "BigBirdPegasusConfig"),
|
| 60 |
+
("biogpt", "BioGptConfig"),
|
| 61 |
+
("bit", "BitConfig"),
|
| 62 |
+
("bitnet", "BitNetConfig"),
|
| 63 |
+
("blenderbot", "BlenderbotConfig"),
|
| 64 |
+
("blenderbot-small", "BlenderbotSmallConfig"),
|
| 65 |
+
("blip", "BlipConfig"),
|
| 66 |
+
("blip-2", "Blip2Config"),
|
| 67 |
+
("blip_2_qformer", "Blip2QFormerConfig"),
|
| 68 |
+
("bloom", "BloomConfig"),
|
| 69 |
+
("blt", "BltConfig"),
|
| 70 |
+
("bridgetower", "BridgeTowerConfig"),
|
| 71 |
+
("bros", "BrosConfig"),
|
| 72 |
+
("camembert", "CamembertConfig"),
|
| 73 |
+
("canine", "CanineConfig"),
|
| 74 |
+
("chameleon", "ChameleonConfig"),
|
| 75 |
+
("chinese_clip", "ChineseCLIPConfig"),
|
| 76 |
+
("chinese_clip_vision_model", "ChineseCLIPVisionConfig"),
|
| 77 |
+
("chmv2", "CHMv2Config"),
|
| 78 |
+
("clap", "ClapConfig"),
|
| 79 |
+
("clip", "CLIPConfig"),
|
| 80 |
+
("clip_text_model", "CLIPTextConfig"),
|
| 81 |
+
("clip_vision_model", "CLIPVisionConfig"),
|
| 82 |
+
("clipseg", "CLIPSegConfig"),
|
| 83 |
+
("clvp", "ClvpConfig"),
|
| 84 |
+
("code_llama", "LlamaConfig"),
|
| 85 |
+
("codegen", "CodeGenConfig"),
|
| 86 |
+
("cohere", "CohereConfig"),
|
| 87 |
+
("cohere2", "Cohere2Config"),
|
| 88 |
+
("cohere2_vision", "Cohere2VisionConfig"),
|
| 89 |
+
("cohere_asr", "CohereAsrConfig"),
|
| 90 |
+
("colmodernvbert", "ColModernVBertConfig"),
|
| 91 |
+
("colpali", "ColPaliConfig"),
|
| 92 |
+
("colqwen2", "ColQwen2Config"),
|
| 93 |
+
("conditional_detr", "ConditionalDetrConfig"),
|
| 94 |
+
("convbert", "ConvBertConfig"),
|
| 95 |
+
("convnext", "ConvNextConfig"),
|
| 96 |
+
("convnextv2", "ConvNextV2Config"),
|
| 97 |
+
("cpmant", "CpmAntConfig"),
|
| 98 |
+
("csm", "CsmConfig"),
|
| 99 |
+
("ctrl", "CTRLConfig"),
|
| 100 |
+
("cvt", "CvtConfig"),
|
| 101 |
+
("cwm", "CwmConfig"),
|
| 102 |
+
("d_fine", "DFineConfig"),
|
| 103 |
+
("dab-detr", "DabDetrConfig"),
|
| 104 |
+
("dac", "DacConfig"),
|
| 105 |
+
("data2vec-audio", "Data2VecAudioConfig"),
|
| 106 |
+
("data2vec-text", "Data2VecTextConfig"),
|
| 107 |
+
("data2vec-vision", "Data2VecVisionConfig"),
|
| 108 |
+
("dbrx", "DbrxConfig"),
|
| 109 |
+
("deberta", "DebertaConfig"),
|
| 110 |
+
("deberta-v2", "DebertaV2Config"),
|
| 111 |
+
("decision_transformer", "DecisionTransformerConfig"),
|
| 112 |
+
("deepseek_v2", "DeepseekV2Config"),
|
| 113 |
+
("deepseek_v3", "DeepseekV3Config"),
|
| 114 |
+
("deepseek_vl", "DeepseekVLConfig"),
|
| 115 |
+
("deepseek_vl_hybrid", "DeepseekVLHybridConfig"),
|
| 116 |
+
("deformable_detr", "DeformableDetrConfig"),
|
| 117 |
+
("deit", "DeiTConfig"),
|
| 118 |
+
("depth_anything", "DepthAnythingConfig"),
|
| 119 |
+
("depth_pro", "DepthProConfig"),
|
| 120 |
+
("detr", "DetrConfig"),
|
| 121 |
+
("dia", "DiaConfig"),
|
| 122 |
+
("diffllama", "DiffLlamaConfig"),
|
| 123 |
+
("dinat", "DinatConfig"),
|
| 124 |
+
("dinov2", "Dinov2Config"),
|
| 125 |
+
("dinov2_with_registers", "Dinov2WithRegistersConfig"),
|
| 126 |
+
("dinov3_convnext", "DINOv3ConvNextConfig"),
|
| 127 |
+
("dinov3_vit", "DINOv3ViTConfig"),
|
| 128 |
+
("distilbert", "DistilBertConfig"),
|
| 129 |
+
("doge", "DogeConfig"),
|
| 130 |
+
("donut-swin", "DonutSwinConfig"),
|
| 131 |
+
("dots1", "Dots1Config"),
|
| 132 |
+
("dpr", "DPRConfig"),
|
| 133 |
+
("dpt", "DPTConfig"),
|
| 134 |
+
("edgetam", "EdgeTamConfig"),
|
| 135 |
+
("edgetam_video", "EdgeTamVideoConfig"),
|
| 136 |
+
("edgetam_vision_model", "EdgeTamVisionConfig"),
|
| 137 |
+
("efficientloftr", "EfficientLoFTRConfig"),
|
| 138 |
+
("efficientnet", "EfficientNetConfig"),
|
| 139 |
+
("electra", "ElectraConfig"),
|
| 140 |
+
("emu3", "Emu3Config"),
|
| 141 |
+
("encodec", "EncodecConfig"),
|
| 142 |
+
("encoder-decoder", "EncoderDecoderConfig"),
|
| 143 |
+
("eomt", "EomtConfig"),
|
| 144 |
+
("eomt_dinov3", "EomtDinov3Config"),
|
| 145 |
+
("ernie", "ErnieConfig"),
|
| 146 |
+
("ernie4_5", "Ernie4_5Config"),
|
| 147 |
+
("ernie4_5_moe", "Ernie4_5_MoeConfig"),
|
| 148 |
+
("ernie4_5_vl_moe", "Ernie4_5_VLMoeConfig"),
|
| 149 |
+
("esm", "EsmConfig"),
|
| 150 |
+
("eurobert", "EuroBertConfig"),
|
| 151 |
+
("evolla", "EvollaConfig"),
|
| 152 |
+
("exaone4", "Exaone4Config"),
|
| 153 |
+
("exaone_moe", "ExaoneMoeConfig"),
|
| 154 |
+
("falcon", "FalconConfig"),
|
| 155 |
+
("falcon_h1", "FalconH1Config"),
|
| 156 |
+
("falcon_mamba", "FalconMambaConfig"),
|
| 157 |
+
("fast_vlm", "FastVlmConfig"),
|
| 158 |
+
("fastspeech2_conformer", "FastSpeech2ConformerConfig"),
|
| 159 |
+
("fastspeech2_conformer_with_hifigan", "FastSpeech2ConformerWithHifiGanConfig"),
|
| 160 |
+
("flaubert", "FlaubertConfig"),
|
| 161 |
+
("flava", "FlavaConfig"),
|
| 162 |
+
("flex_olmo", "FlexOlmoConfig"),
|
| 163 |
+
("florence2", "Florence2Config"),
|
| 164 |
+
("fnet", "FNetConfig"),
|
| 165 |
+
("focalnet", "FocalNetConfig"),
|
| 166 |
+
("fsmt", "FSMTConfig"),
|
| 167 |
+
("funnel", "FunnelConfig"),
|
| 168 |
+
("fuyu", "FuyuConfig"),
|
| 169 |
+
("gemma", "GemmaConfig"),
|
| 170 |
+
("gemma2", "Gemma2Config"),
|
| 171 |
+
("gemma3", "Gemma3Config"),
|
| 172 |
+
("gemma3_text", "Gemma3TextConfig"),
|
| 173 |
+
("gemma3n", "Gemma3nConfig"),
|
| 174 |
+
("gemma3n_audio", "Gemma3nAudioConfig"),
|
| 175 |
+
("gemma3n_text", "Gemma3nTextConfig"),
|
| 176 |
+
("gemma3n_vision", "Gemma3nVisionConfig"),
|
| 177 |
+
("gemma4", "Gemma4Config"),
|
| 178 |
+
("gemma4_audio", "Gemma4AudioConfig"),
|
| 179 |
+
("gemma4_text", "Gemma4TextConfig"),
|
| 180 |
+
("gemma4_vision", "Gemma4VisionConfig"),
|
| 181 |
+
("git", "GitConfig"),
|
| 182 |
+
("glm", "GlmConfig"),
|
| 183 |
+
("glm4", "Glm4Config"),
|
| 184 |
+
("glm46v", "Glm46VConfig"),
|
| 185 |
+
("glm4_moe", "Glm4MoeConfig"),
|
| 186 |
+
("glm4_moe_lite", "Glm4MoeLiteConfig"),
|
| 187 |
+
("glm4v", "Glm4vConfig"),
|
| 188 |
+
("glm4v_moe", "Glm4vMoeConfig"),
|
| 189 |
+
("glm4v_moe_text", "Glm4vMoeTextConfig"),
|
| 190 |
+
("glm4v_moe_vision", "Glm4vMoeVisionConfig"),
|
| 191 |
+
("glm4v_text", "Glm4vTextConfig"),
|
| 192 |
+
("glm4v_vision", "Glm4vVisionConfig"),
|
| 193 |
+
("glm_image", "GlmImageConfig"),
|
| 194 |
+
("glm_image_text", "GlmImageTextConfig"),
|
| 195 |
+
("glm_image_vision", "GlmImageVisionConfig"),
|
| 196 |
+
("glm_image_vqmodel", "GlmImageVQVAEConfig"),
|
| 197 |
+
("glm_moe_dsa", "GlmMoeDsaConfig"),
|
| 198 |
+
("glm_ocr", "GlmOcrConfig"),
|
| 199 |
+
("glm_ocr_text", "GlmOcrTextConfig"),
|
| 200 |
+
("glm_ocr_vision", "GlmOcrVisionConfig"),
|
| 201 |
+
("glmasr", "GlmAsrConfig"),
|
| 202 |
+
("glmasr_encoder", "GlmAsrEncoderConfig"),
|
| 203 |
+
("glpn", "GLPNConfig"),
|
| 204 |
+
("got_ocr2", "GotOcr2Config"),
|
| 205 |
+
("gpt-sw3", "GPT2Config"),
|
| 206 |
+
("gpt2", "GPT2Config"),
|
| 207 |
+
("gpt_bigcode", "GPTBigCodeConfig"),
|
| 208 |
+
("gpt_neo", "GPTNeoConfig"),
|
| 209 |
+
("gpt_neox", "GPTNeoXConfig"),
|
| 210 |
+
("gpt_neox_japanese", "GPTNeoXJapaneseConfig"),
|
| 211 |
+
("gpt_oss", "GptOssConfig"),
|
| 212 |
+
("gptj", "GPTJConfig"),
|
| 213 |
+
("granite", "GraniteConfig"),
|
| 214 |
+
("granite_speech", "GraniteSpeechConfig"),
|
| 215 |
+
("granitemoe", "GraniteMoeConfig"),
|
| 216 |
+
("granitemoehybrid", "GraniteMoeHybridConfig"),
|
| 217 |
+
("granitemoeshared", "GraniteMoeSharedConfig"),
|
| 218 |
+
("granitevision", "LlavaNextConfig"),
|
| 219 |
+
("grounding-dino", "GroundingDinoConfig"),
|
| 220 |
+
("groupvit", "GroupViTConfig"),
|
| 221 |
+
("helium", "HeliumConfig"),
|
| 222 |
+
("hgnet_v2", "HGNetV2Config"),
|
| 223 |
+
("hiera", "HieraConfig"),
|
| 224 |
+
("higgs_audio_v2", "HiggsAudioV2Config"),
|
| 225 |
+
("higgs_audio_v2_tokenizer", "HiggsAudioV2TokenizerConfig"),
|
| 226 |
+
("hubert", "HubertConfig"),
|
| 227 |
+
("hunyuan_v1_dense", "HunYuanDenseV1Config"),
|
| 228 |
+
("hunyuan_v1_moe", "HunYuanMoEV1Config"),
|
| 229 |
+
("ibert", "IBertConfig"),
|
| 230 |
+
("idefics", "IdeficsConfig"),
|
| 231 |
+
("idefics2", "Idefics2Config"),
|
| 232 |
+
("idefics3", "Idefics3Config"),
|
| 233 |
+
("idefics3_vision", "Idefics3VisionConfig"),
|
| 234 |
+
("ijepa", "IJepaConfig"),
|
| 235 |
+
("imagegpt", "ImageGPTConfig"),
|
| 236 |
+
("informer", "InformerConfig"),
|
| 237 |
+
("instructblip", "InstructBlipConfig"),
|
| 238 |
+
("instructblipvideo", "InstructBlipVideoConfig"),
|
| 239 |
+
("internvl", "InternVLConfig"),
|
| 240 |
+
("internvl_vision", "InternVLVisionConfig"),
|
| 241 |
+
("jais2", "Jais2Config"),
|
| 242 |
+
("jamba", "JambaConfig"),
|
| 243 |
+
("janus", "JanusConfig"),
|
| 244 |
+
("jetmoe", "JetMoeConfig"),
|
| 245 |
+
("jina_embeddings_v3", "JinaEmbeddingsV3Config"),
|
| 246 |
+
("kosmos-2", "Kosmos2Config"),
|
| 247 |
+
("kosmos-2.5", "Kosmos2_5Config"),
|
| 248 |
+
("kyutai_speech_to_text", "KyutaiSpeechToTextConfig"),
|
| 249 |
+
("lasr_ctc", "LasrCTCConfig"),
|
| 250 |
+
("lasr_encoder", "LasrEncoderConfig"),
|
| 251 |
+
("layoutlm", "LayoutLMConfig"),
|
| 252 |
+
("layoutlmv2", "LayoutLMv2Config"),
|
| 253 |
+
("layoutlmv3", "LayoutLMv3Config"),
|
| 254 |
+
("layoutxlm", "LayoutXLMConfig"),
|
| 255 |
+
("led", "LEDConfig"),
|
| 256 |
+
("levit", "LevitConfig"),
|
| 257 |
+
("lfm2", "Lfm2Config"),
|
| 258 |
+
("lfm2_moe", "Lfm2MoeConfig"),
|
| 259 |
+
("lfm2_vl", "Lfm2VlConfig"),
|
| 260 |
+
("lightglue", "LightGlueConfig"),
|
| 261 |
+
("lighton_ocr", "LightOnOcrConfig"),
|
| 262 |
+
("lilt", "LiltConfig"),
|
| 263 |
+
("llama", "LlamaConfig"),
|
| 264 |
+
("llama4", "Llama4Config"),
|
| 265 |
+
("llama4_text", "Llama4TextConfig"),
|
| 266 |
+
("llava", "LlavaConfig"),
|
| 267 |
+
("llava_next", "LlavaNextConfig"),
|
| 268 |
+
("llava_next_video", "LlavaNextVideoConfig"),
|
| 269 |
+
("llava_onevision", "LlavaOnevisionConfig"),
|
| 270 |
+
("longcat_flash", "LongcatFlashConfig"),
|
| 271 |
+
("longformer", "LongformerConfig"),
|
| 272 |
+
("longt5", "LongT5Config"),
|
| 273 |
+
("luke", "LukeConfig"),
|
| 274 |
+
("lw_detr", "LwDetrConfig"),
|
| 275 |
+
("lw_detr_vit", "LwDetrViTConfig"),
|
| 276 |
+
("lxmert", "LxmertConfig"),
|
| 277 |
+
("m2m_100", "M2M100Config"),
|
| 278 |
+
("mamba", "MambaConfig"),
|
| 279 |
+
("mamba2", "Mamba2Config"),
|
| 280 |
+
("marian", "MarianConfig"),
|
| 281 |
+
("markuplm", "MarkupLMConfig"),
|
| 282 |
+
("mask2former", "Mask2FormerConfig"),
|
| 283 |
+
("maskformer", "MaskFormerConfig"),
|
| 284 |
+
("maskformer-swin", "MaskFormerSwinConfig"),
|
| 285 |
+
("mbart", "MBartConfig"),
|
| 286 |
+
("megatron-bert", "MegatronBertConfig"),
|
| 287 |
+
("metaclip_2", "MetaClip2Config"),
|
| 288 |
+
("mgp-str", "MgpstrConfig"),
|
| 289 |
+
("mimi", "MimiConfig"),
|
| 290 |
+
("minimax", "MiniMaxConfig"),
|
| 291 |
+
("minimax_m2", "MiniMaxM2Config"),
|
| 292 |
+
("ministral", "MinistralConfig"),
|
| 293 |
+
("ministral3", "Ministral3Config"),
|
| 294 |
+
("mistral", "MistralConfig"),
|
| 295 |
+
("mistral3", "Mistral3Config"),
|
| 296 |
+
("mistral4", "Mistral4Config"),
|
| 297 |
+
("mixtral", "MixtralConfig"),
|
| 298 |
+
("mlcd", "MLCDVisionConfig"), # Keep this to make some original hub repositories (from `DeepGlint-AI`) works
|
| 299 |
+
("mlcd_vision_model", "MLCDVisionConfig"),
|
| 300 |
+
("mllama", "MllamaConfig"),
|
| 301 |
+
("mm-grounding-dino", "MMGroundingDinoConfig"),
|
| 302 |
+
("mobilebert", "MobileBertConfig"),
|
| 303 |
+
("mobilenet_v1", "MobileNetV1Config"),
|
| 304 |
+
("mobilenet_v2", "MobileNetV2Config"),
|
| 305 |
+
("mobilevit", "MobileViTConfig"),
|
| 306 |
+
("mobilevitv2", "MobileViTV2Config"),
|
| 307 |
+
("modernbert", "ModernBertConfig"),
|
| 308 |
+
("modernbert-decoder", "ModernBertDecoderConfig"),
|
| 309 |
+
("modernvbert", "ModernVBertConfig"),
|
| 310 |
+
("moonshine", "MoonshineConfig"),
|
| 311 |
+
("moonshine_streaming", "MoonshineStreamingConfig"),
|
| 312 |
+
("moonshine_streaming_encoder", "MoonshineStreamingEncoderConfig"),
|
| 313 |
+
("moshi", "MoshiConfig"),
|
| 314 |
+
("mpnet", "MPNetConfig"),
|
| 315 |
+
("mpt", "MptConfig"),
|
| 316 |
+
("mra", "MraConfig"),
|
| 317 |
+
("mt5", "MT5Config"),
|
| 318 |
+
("musicflamingo", "MusicFlamingoConfig"),
|
| 319 |
+
("musicflamingo_encoder", "AudioFlamingo3EncoderConfig"),
|
| 320 |
+
("musicgen", "MusicgenConfig"),
|
| 321 |
+
("musicgen_melody", "MusicgenMelodyConfig"),
|
| 322 |
+
("mvp", "MvpConfig"),
|
| 323 |
+
("nanochat", "NanoChatConfig"),
|
| 324 |
+
("nemotron", "NemotronConfig"),
|
| 325 |
+
("nemotron_h", "NemotronHConfig"),
|
| 326 |
+
("nllb-moe", "NllbMoeConfig"),
|
| 327 |
+
("nomic_bert", "NomicBertConfig"),
|
| 328 |
+
("nougat", "VisionEncoderDecoderConfig"),
|
| 329 |
+
("nystromformer", "NystromformerConfig"),
|
| 330 |
+
("olmo", "OlmoConfig"),
|
| 331 |
+
("olmo2", "Olmo2Config"),
|
| 332 |
+
("olmo3", "Olmo3Config"),
|
| 333 |
+
("olmo_hybrid", "OlmoHybridConfig"),
|
| 334 |
+
("olmoe", "OlmoeConfig"),
|
| 335 |
+
("omdet-turbo", "OmDetTurboConfig"),
|
| 336 |
+
("oneformer", "OneFormerConfig"),
|
| 337 |
+
("openai-gpt", "OpenAIGPTConfig"),
|
| 338 |
+
("opt", "OPTConfig"),
|
| 339 |
+
("ovis2", "Ovis2Config"),
|
| 340 |
+
("owlv2", "Owlv2Config"),
|
| 341 |
+
("owlvit", "OwlViTConfig"),
|
| 342 |
+
("paddleocr_vl", "PaddleOCRVLConfig"),
|
| 343 |
+
("paligemma", "PaliGemmaConfig"),
|
| 344 |
+
("parakeet_ctc", "ParakeetCTCConfig"),
|
| 345 |
+
("parakeet_encoder", "ParakeetEncoderConfig"),
|
| 346 |
+
("patchtsmixer", "PatchTSMixerConfig"),
|
| 347 |
+
("patchtst", "PatchTSTConfig"),
|
| 348 |
+
("pe_audio", "PeAudioConfig"),
|
| 349 |
+
("pe_audio_encoder", "PeAudioEncoderConfig"),
|
| 350 |
+
("pe_audio_video", "PeAudioVideoConfig"),
|
| 351 |
+
("pe_audio_video_encoder", "PeAudioVideoEncoderConfig"),
|
| 352 |
+
("pe_video", "PeVideoConfig"),
|
| 353 |
+
("pe_video_encoder", "PeVideoEncoderConfig"),
|
| 354 |
+
("pegasus", "PegasusConfig"),
|
| 355 |
+
("pegasus_x", "PegasusXConfig"),
|
| 356 |
+
("perceiver", "PerceiverConfig"),
|
| 357 |
+
("perception_lm", "PerceptionLMConfig"),
|
| 358 |
+
("persimmon", "PersimmonConfig"),
|
| 359 |
+
("phi", "PhiConfig"),
|
| 360 |
+
("phi3", "Phi3Config"),
|
| 361 |
+
("phi4_multimodal", "Phi4MultimodalConfig"),
|
| 362 |
+
("phimoe", "PhimoeConfig"),
|
| 363 |
+
("pi0", "PI0Config"),
|
| 364 |
+
("pix2struct", "Pix2StructConfig"),
|
| 365 |
+
("pixio", "PixioConfig"),
|
| 366 |
+
("pixtral", "PixtralVisionConfig"),
|
| 367 |
+
("plbart", "PLBartConfig"),
|
| 368 |
+
("poolformer", "PoolFormerConfig"),
|
| 369 |
+
("pop2piano", "Pop2PianoConfig"),
|
| 370 |
+
("pp_chart2table", "PPChart2TableConfig"),
|
| 371 |
+
("pp_doclayout_v2", "PPDocLayoutV2Config"),
|
| 372 |
+
("pp_doclayout_v3", "PPDocLayoutV3Config"),
|
| 373 |
+
("pp_lcnet", "PPLCNetConfig"),
|
| 374 |
+
("pp_lcnet_v3", "PPLCNetV3Config"),
|
| 375 |
+
("pp_ocrv5_mobile_det", "PPOCRV5MobileDetConfig"),
|
| 376 |
+
("pp_ocrv5_mobile_rec", "PPOCRV5MobileRecConfig"),
|
| 377 |
+
("pp_ocrv5_server_det", "PPOCRV5ServerDetConfig"),
|
| 378 |
+
("pp_ocrv5_server_rec", "PPOCRV5ServerRecConfig"),
|
| 379 |
+
("prompt_depth_anything", "PromptDepthAnythingConfig"),
|
| 380 |
+
("prophetnet", "ProphetNetConfig"),
|
| 381 |
+
("pvt", "PvtConfig"),
|
| 382 |
+
("pvt_v2", "PvtV2Config"),
|
| 383 |
+
("qwen2", "Qwen2Config"),
|
| 384 |
+
("qwen2_5_omni", "Qwen2_5OmniConfig"),
|
| 385 |
+
("qwen2_5_vl", "Qwen2_5_VLConfig"),
|
| 386 |
+
("qwen2_5_vl_text", "Qwen2_5_VLTextConfig"),
|
| 387 |
+
("qwen2_audio", "Qwen2AudioConfig"),
|
| 388 |
+
("qwen2_audio_encoder", "Qwen2AudioEncoderConfig"),
|
| 389 |
+
("qwen2_moe", "Qwen2MoeConfig"),
|
| 390 |
+
("qwen2_vl", "Qwen2VLConfig"),
|
| 391 |
+
("qwen2_vl_text", "Qwen2VLTextConfig"),
|
| 392 |
+
("qwen3", "Qwen3Config"),
|
| 393 |
+
("qwen3_5", "Qwen3_5Config"),
|
| 394 |
+
("qwen3_5_moe", "Qwen3_5MoeConfig"),
|
| 395 |
+
("qwen3_5_moe_text", "Qwen3_5MoeTextConfig"),
|
| 396 |
+
("qwen3_5_text", "Qwen3_5TextConfig"),
|
| 397 |
+
("qwen3_moe", "Qwen3MoeConfig"),
|
| 398 |
+
("qwen3_next", "Qwen3NextConfig"),
|
| 399 |
+
("qwen3_omni_moe", "Qwen3OmniMoeConfig"),
|
| 400 |
+
("qwen3_vl", "Qwen3VLConfig"),
|
| 401 |
+
("qwen3_vl_moe", "Qwen3VLMoeConfig"),
|
| 402 |
+
("qwen3_vl_moe_text", "Qwen3VLMoeTextConfig"),
|
| 403 |
+
("qwen3_vl_text", "Qwen3VLTextConfig"),
|
| 404 |
+
("rag", "RagConfig"),
|
| 405 |
+
("recurrent_gemma", "RecurrentGemmaConfig"),
|
| 406 |
+
("reformer", "ReformerConfig"),
|
| 407 |
+
("regnet", "RegNetConfig"),
|
| 408 |
+
("rembert", "RemBertConfig"),
|
| 409 |
+
("resnet", "ResNetConfig"),
|
| 410 |
+
("roberta", "RobertaConfig"),
|
| 411 |
+
("roberta-prelayernorm", "RobertaPreLayerNormConfig"),
|
| 412 |
+
("roc_bert", "RoCBertConfig"),
|
| 413 |
+
("roformer", "RoFormerConfig"),
|
| 414 |
+
("rt_detr", "RTDetrConfig"),
|
| 415 |
+
("rt_detr_resnet", "RTDetrResNetConfig"),
|
| 416 |
+
("rt_detr_v2", "RTDetrV2Config"),
|
| 417 |
+
("rwkv", "RwkvConfig"),
|
| 418 |
+
("sam", "SamConfig"),
|
| 419 |
+
("sam2", "Sam2Config"),
|
| 420 |
+
("sam2_hiera_det_model", "Sam2HieraDetConfig"),
|
| 421 |
+
("sam2_video", "Sam2VideoConfig"),
|
| 422 |
+
("sam2_vision_model", "Sam2VisionConfig"),
|
| 423 |
+
("sam3", "Sam3Config"),
|
| 424 |
+
("sam3_tracker", "Sam3TrackerConfig"),
|
| 425 |
+
("sam3_tracker_video", "Sam3TrackerVideoConfig"),
|
| 426 |
+
("sam3_video", "Sam3VideoConfig"),
|
| 427 |
+
("sam3_vision_model", "Sam3VisionConfig"),
|
| 428 |
+
("sam3_vit_model", "Sam3ViTConfig"),
|
| 429 |
+
("sam_hq", "SamHQConfig"),
|
| 430 |
+
("sam_hq_vision_model", "SamHQVisionConfig"),
|
| 431 |
+
("sam_vision_model", "SamVisionConfig"),
|
| 432 |
+
("seamless_m4t", "SeamlessM4TConfig"),
|
| 433 |
+
("seamless_m4t_v2", "SeamlessM4Tv2Config"),
|
| 434 |
+
("seed_oss", "SeedOssConfig"),
|
| 435 |
+
("segformer", "SegformerConfig"),
|
| 436 |
+
("seggpt", "SegGptConfig"),
|
| 437 |
+
("sew", "SEWConfig"),
|
| 438 |
+
("sew-d", "SEWDConfig"),
|
| 439 |
+
("shieldgemma2", "ShieldGemma2Config"),
|
| 440 |
+
("siglip", "SiglipConfig"),
|
| 441 |
+
("siglip2", "Siglip2Config"),
|
| 442 |
+
("siglip2_vision_model", "Siglip2VisionConfig"),
|
| 443 |
+
("siglip_vision_model", "SiglipVisionConfig"),
|
| 444 |
+
("slanext", "SLANeXtConfig"),
|
| 445 |
+
("smollm3", "SmolLM3Config"),
|
| 446 |
+
("smolvlm", "SmolVLMConfig"),
|
| 447 |
+
("smolvlm_vision", "SmolVLMVisionConfig"),
|
| 448 |
+
("solar_open", "SolarOpenConfig"),
|
| 449 |
+
("speech-encoder-decoder", "SpeechEncoderDecoderConfig"),
|
| 450 |
+
("speech_to_text", "Speech2TextConfig"),
|
| 451 |
+
("speecht5", "SpeechT5Config"),
|
| 452 |
+
("splinter", "SplinterConfig"),
|
| 453 |
+
("squeezebert", "SqueezeBertConfig"),
|
| 454 |
+
("stablelm", "StableLmConfig"),
|
| 455 |
+
("starcoder2", "Starcoder2Config"),
|
| 456 |
+
("superglue", "SuperGlueConfig"),
|
| 457 |
+
("superpoint", "SuperPointConfig"),
|
| 458 |
+
("swiftformer", "SwiftFormerConfig"),
|
| 459 |
+
("swin", "SwinConfig"),
|
| 460 |
+
("swin2sr", "Swin2SRConfig"),
|
| 461 |
+
("swinv2", "Swinv2Config"),
|
| 462 |
+
("switch_transformers", "SwitchTransformersConfig"),
|
| 463 |
+
("t5", "T5Config"),
|
| 464 |
+
("t5gemma", "T5GemmaConfig"),
|
| 465 |
+
("t5gemma2", "T5Gemma2Config"),
|
| 466 |
+
("t5gemma2_encoder", "T5Gemma2EncoderConfig"),
|
| 467 |
+
("table-transformer", "TableTransformerConfig"),
|
| 468 |
+
("tapas", "TapasConfig"),
|
| 469 |
+
("textnet", "TextNetConfig"),
|
| 470 |
+
("time_series_transformer", "TimeSeriesTransformerConfig"),
|
| 471 |
+
("timesfm", "TimesFmConfig"),
|
| 472 |
+
("timesfm2_5", "TimesFm2_5Config"),
|
| 473 |
+
("timesformer", "TimesformerConfig"),
|
| 474 |
+
("timm_backbone", "TimmBackboneConfig"),
|
| 475 |
+
("timm_wrapper", "TimmWrapperConfig"),
|
| 476 |
+
("trocr", "TrOCRConfig"),
|
| 477 |
+
("tvp", "TvpConfig"),
|
| 478 |
+
("udop", "UdopConfig"),
|
| 479 |
+
("umt5", "UMT5Config"),
|
| 480 |
+
("unispeech", "UniSpeechConfig"),
|
| 481 |
+
("unispeech-sat", "UniSpeechSatConfig"),
|
| 482 |
+
("univnet", "UnivNetConfig"),
|
| 483 |
+
("upernet", "UperNetConfig"),
|
| 484 |
+
("uvdoc", "UVDocConfig"),
|
| 485 |
+
("uvdoc_backbone", "UVDocBackboneConfig"),
|
| 486 |
+
("vaultgemma", "VaultGemmaConfig"),
|
| 487 |
+
("vibevoice_acoustic_tokenizer", "VibeVoiceAcousticTokenizerConfig"),
|
| 488 |
+
("vibevoice_acoustic_tokenizer_decoder", "VibeVoiceAcousticTokenizerDecoderConfig"),
|
| 489 |
+
("vibevoice_acoustic_tokenizer_encoder", "VibeVoiceAcousticTokenizerEncoderConfig"),
|
| 490 |
+
("vibevoice_asr", "VibeVoiceAsrConfig"),
|
| 491 |
+
("video_llama_3", "VideoLlama3Config"),
|
| 492 |
+
("video_llama_3_vision", "VideoLlama3VisionConfig"),
|
| 493 |
+
("video_llava", "VideoLlavaConfig"),
|
| 494 |
+
("videomae", "VideoMAEConfig"),
|
| 495 |
+
("videomt", "VideomtConfig"),
|
| 496 |
+
("vilt", "ViltConfig"),
|
| 497 |
+
("vipllava", "VipLlavaConfig"),
|
| 498 |
+
("vision-encoder-decoder", "VisionEncoderDecoderConfig"),
|
| 499 |
+
("vision-text-dual-encoder", "VisionTextDualEncoderConfig"),
|
| 500 |
+
("visual_bert", "VisualBertConfig"),
|
| 501 |
+
("vit", "ViTConfig"),
|
| 502 |
+
("vit_mae", "ViTMAEConfig"),
|
| 503 |
+
("vit_msn", "ViTMSNConfig"),
|
| 504 |
+
("vitdet", "VitDetConfig"),
|
| 505 |
+
("vitmatte", "VitMatteConfig"),
|
| 506 |
+
("vitpose", "VitPoseConfig"),
|
| 507 |
+
("vitpose_backbone", "VitPoseBackboneConfig"),
|
| 508 |
+
("vits", "VitsConfig"),
|
| 509 |
+
("vivit", "VivitConfig"),
|
| 510 |
+
("vjepa2", "VJEPA2Config"),
|
| 511 |
+
("voxtral", "VoxtralConfig"),
|
| 512 |
+
("voxtral_encoder", "VoxtralEncoderConfig"),
|
| 513 |
+
("voxtral_realtime", "VoxtralRealtimeConfig"),
|
| 514 |
+
("voxtral_realtime_encoder", "VoxtralRealtimeEncoderConfig"),
|
| 515 |
+
("voxtral_realtime_text", "VoxtralRealtimeTextConfig"),
|
| 516 |
+
("wav2vec2", "Wav2Vec2Config"),
|
| 517 |
+
("wav2vec2-bert", "Wav2Vec2BertConfig"),
|
| 518 |
+
("wav2vec2-conformer", "Wav2Vec2ConformerConfig"),
|
| 519 |
+
("wavlm", "WavLMConfig"),
|
| 520 |
+
("whisper", "WhisperConfig"),
|
| 521 |
+
("xclip", "XCLIPConfig"),
|
| 522 |
+
("xcodec", "XcodecConfig"),
|
| 523 |
+
("xglm", "XGLMConfig"),
|
| 524 |
+
("xlm", "XLMConfig"),
|
| 525 |
+
("xlm-roberta", "XLMRobertaConfig"),
|
| 526 |
+
("xlm-roberta-xl", "XLMRobertaXLConfig"),
|
| 527 |
+
("xlnet", "XLNetConfig"),
|
| 528 |
+
("xlstm", "xLSTMConfig"),
|
| 529 |
+
("xmod", "XmodConfig"),
|
| 530 |
+
("yolos", "YolosConfig"),
|
| 531 |
+
("yoso", "YosoConfig"),
|
| 532 |
+
("youtu", "YoutuConfig"),
|
| 533 |
+
("zamba", "ZambaConfig"),
|
| 534 |
+
("zamba2", "Zamba2Config"),
|
| 535 |
+
("zoedepth", "ZoeDepthConfig"),
|
| 536 |
+
]
|
| 537 |
+
)
|
| 538 |
+
|
| 539 |
+
|
| 540 |
+
MODEL_NAMES_MAPPING = OrderedDict[str, str](
|
| 541 |
+
[
|
| 542 |
+
# Add full (and cased) model names here
|
| 543 |
+
("afmoe", "AFMoE"),
|
| 544 |
+
("aimv2", "AIMv2"),
|
| 545 |
+
("aimv2_vision_model", "Aimv2VisionModel"),
|
| 546 |
+
("albert", "ALBERT"),
|
| 547 |
+
("align", "ALIGN"),
|
| 548 |
+
("altclip", "AltCLIP"),
|
| 549 |
+
("apertus", "Apertus"),
|
| 550 |
+
("arcee", "Arcee"),
|
| 551 |
+
("aria", "Aria"),
|
| 552 |
+
("aria_text", "AriaText"),
|
| 553 |
+
("audio-spectrogram-transformer", "Audio Spectrogram Transformer"),
|
| 554 |
+
("audioflamingo3", "AudioFlamingo3"),
|
| 555 |
+
("audioflamingo3_encoder", "AudioFlamingo3Encoder"),
|
| 556 |
+
("autoformer", "Autoformer"),
|
| 557 |
+
("aya_vision", "AyaVision"),
|
| 558 |
+
("bamba", "Bamba"),
|
| 559 |
+
("bark", "Bark"),
|
| 560 |
+
("bart", "BART"),
|
| 561 |
+
("barthez", "BARThez"),
|
| 562 |
+
("bartpho", "BARTpho"),
|
| 563 |
+
("beit", "BEiT"),
|
| 564 |
+
("bert", "BERT"),
|
| 565 |
+
("bert-generation", "Bert Generation"),
|
| 566 |
+
("bert-japanese", "BertJapanese"),
|
| 567 |
+
("bertweet", "BERTweet"),
|
| 568 |
+
("big_bird", "BigBird"),
|
| 569 |
+
("bigbird_pegasus", "BigBird-Pegasus"),
|
| 570 |
+
("biogpt", "BioGpt"),
|
| 571 |
+
("bit", "BiT"),
|
| 572 |
+
("bitnet", "BitNet"),
|
| 573 |
+
("blenderbot", "Blenderbot"),
|
| 574 |
+
("blenderbot-small", "BlenderbotSmall"),
|
| 575 |
+
("blip", "BLIP"),
|
| 576 |
+
("blip-2", "BLIP-2"),
|
| 577 |
+
("blip_2_qformer", "BLIP-2 QFormer"),
|
| 578 |
+
("bloom", "BLOOM"),
|
| 579 |
+
("blt", "Blt"),
|
| 580 |
+
("bridgetower", "BridgeTower"),
|
| 581 |
+
("bros", "BROS"),
|
| 582 |
+
("byt5", "ByT5"),
|
| 583 |
+
("camembert", "CamemBERT"),
|
| 584 |
+
("canine", "CANINE"),
|
| 585 |
+
("chameleon", "Chameleon"),
|
| 586 |
+
("chinese_clip", "Chinese-CLIP"),
|
| 587 |
+
("chinese_clip_vision_model", "ChineseCLIPVisionModel"),
|
| 588 |
+
("chmv2", "CHMv2"),
|
| 589 |
+
("clap", "CLAP"),
|
| 590 |
+
("clip", "CLIP"),
|
| 591 |
+
("clip_text_model", "CLIPTextModel"),
|
| 592 |
+
("clip_vision_model", "CLIPVisionModel"),
|
| 593 |
+
("clipseg", "CLIPSeg"),
|
| 594 |
+
("clvp", "CLVP"),
|
| 595 |
+
("code_llama", "CodeLlama"),
|
| 596 |
+
("codegen", "CodeGen"),
|
| 597 |
+
("cohere", "Cohere"),
|
| 598 |
+
("cohere2", "Cohere2"),
|
| 599 |
+
("cohere2_vision", "Cohere2Vision"),
|
| 600 |
+
("cohere_asr", "CohereASR"),
|
| 601 |
+
("colmodernvbert", "ColModernVBert"),
|
| 602 |
+
("colpali", "ColPali"),
|
| 603 |
+
("colqwen2", "ColQwen2"),
|
| 604 |
+
("conditional_detr", "Conditional DETR"),
|
| 605 |
+
("convbert", "ConvBERT"),
|
| 606 |
+
("convnext", "ConvNeXT"),
|
| 607 |
+
("convnextv2", "ConvNeXTV2"),
|
| 608 |
+
("cpm", "CPM"),
|
| 609 |
+
("cpmant", "CPM-Ant"),
|
| 610 |
+
("csm", "CSM"),
|
| 611 |
+
("ctrl", "CTRL"),
|
| 612 |
+
("cvt", "CvT"),
|
| 613 |
+
("cwm", "Code World Model (CWM)"),
|
| 614 |
+
("d_fine", "D-FINE"),
|
| 615 |
+
("dab-detr", "DAB-DETR"),
|
| 616 |
+
("dac", "DAC"),
|
| 617 |
+
("data2vec-audio", "Data2VecAudio"),
|
| 618 |
+
("data2vec-text", "Data2VecText"),
|
| 619 |
+
("data2vec-vision", "Data2VecVision"),
|
| 620 |
+
("dbrx", "DBRX"),
|
| 621 |
+
("deberta", "DeBERTa"),
|
| 622 |
+
("deberta-v2", "DeBERTa-v2"),
|
| 623 |
+
("decision_transformer", "Decision Transformer"),
|
| 624 |
+
("deepseek_v2", "DeepSeek-V2"),
|
| 625 |
+
("deepseek_v3", "DeepSeek-V3"),
|
| 626 |
+
("deepseek_vl", "DeepseekVL"),
|
| 627 |
+
("deepseek_vl_hybrid", "DeepseekVLHybrid"),
|
| 628 |
+
("deformable_detr", "Deformable DETR"),
|
| 629 |
+
("deit", "DeiT"),
|
| 630 |
+
("deplot", "DePlot"),
|
| 631 |
+
("depth_anything", "Depth Anything"),
|
| 632 |
+
("depth_anything_v2", "Depth Anything V2"),
|
| 633 |
+
("depth_pro", "DepthPro"),
|
| 634 |
+
("detr", "DETR"),
|
| 635 |
+
("dia", "Dia"),
|
| 636 |
+
("dialogpt", "DialoGPT"),
|
| 637 |
+
("diffllama", "DiffLlama"),
|
| 638 |
+
("dinat", "DiNAT"),
|
| 639 |
+
("dinov2", "DINOv2"),
|
| 640 |
+
("dinov2_with_registers", "DINOv2 with Registers"),
|
| 641 |
+
("dinov3_convnext", "DINOv3 ConvNext"),
|
| 642 |
+
("dinov3_vit", "DINOv3 ViT"),
|
| 643 |
+
("distilbert", "DistilBERT"),
|
| 644 |
+
("dit", "DiT"),
|
| 645 |
+
("doge", "Doge"),
|
| 646 |
+
("donut-swin", "DonutSwin"),
|
| 647 |
+
("dots1", "dots1"),
|
| 648 |
+
("dpr", "DPR"),
|
| 649 |
+
("dpt", "DPT"),
|
| 650 |
+
("edgetam", "EdgeTAM"),
|
| 651 |
+
("edgetam_video", "EdgeTamVideo"),
|
| 652 |
+
("edgetam_vision_model", "EdgeTamVisionModel"),
|
| 653 |
+
("efficientloftr", "EfficientLoFTR"),
|
| 654 |
+
("efficientnet", "EfficientNet"),
|
| 655 |
+
("electra", "ELECTRA"),
|
| 656 |
+
("emu3", "Emu3"),
|
| 657 |
+
("encodec", "EnCodec"),
|
| 658 |
+
("encoder-decoder", "Encoder decoder"),
|
| 659 |
+
("eomt", "EoMT"),
|
| 660 |
+
("eomt_dinov3", "EoMT-DINOv3"),
|
| 661 |
+
("ernie", "ERNIE"),
|
| 662 |
+
("ernie4_5", "Ernie4_5"),
|
| 663 |
+
("ernie4_5_moe", "Ernie4_5_MoE"),
|
| 664 |
+
("ernie4_5_vl_moe", "Ernie4_5_VLMoE"),
|
| 665 |
+
("esm", "ESM"),
|
| 666 |
+
("eurobert", "EuroBERT"),
|
| 667 |
+
("evolla", "Evolla"),
|
| 668 |
+
("exaone4", "EXAONE-4.0"),
|
| 669 |
+
("exaone_moe", "EXAONE-MoE"),
|
| 670 |
+
("falcon", "Falcon"),
|
| 671 |
+
("falcon3", "Falcon3"),
|
| 672 |
+
("falcon_h1", "FalconH1"),
|
| 673 |
+
("falcon_mamba", "FalconMamba"),
|
| 674 |
+
("fast_vlm", "FastVlm"),
|
| 675 |
+
("fastspeech2_conformer", "FastSpeech2Conformer"),
|
| 676 |
+
("fastspeech2_conformer_with_hifigan", "FastSpeech2ConformerWithHifiGan"),
|
| 677 |
+
("flan-t5", "FLAN-T5"),
|
| 678 |
+
("flan-ul2", "FLAN-UL2"),
|
| 679 |
+
("flaubert", "FlauBERT"),
|
| 680 |
+
("flava", "FLAVA"),
|
| 681 |
+
("flex_olmo", "FlexOlmo"),
|
| 682 |
+
("florence2", "Florence2"),
|
| 683 |
+
("fnet", "FNet"),
|
| 684 |
+
("focalnet", "FocalNet"),
|
| 685 |
+
("fsmt", "FairSeq Machine-Translation"),
|
| 686 |
+
("funnel", "Funnel Transformer"),
|
| 687 |
+
("fuyu", "Fuyu"),
|
| 688 |
+
("gemma", "Gemma"),
|
| 689 |
+
("gemma2", "Gemma2"),
|
| 690 |
+
("gemma3", "Gemma3ForConditionalGeneration"),
|
| 691 |
+
("gemma3_text", "Gemma3ForCausalLM"),
|
| 692 |
+
("gemma3n", "Gemma3nForConditionalGeneration"),
|
| 693 |
+
("gemma3n_audio", "Gemma3nAudioEncoder"),
|
| 694 |
+
("gemma3n_text", "Gemma3nForCausalLM"),
|
| 695 |
+
("gemma3n_vision", "TimmWrapperModel"),
|
| 696 |
+
("gemma4", "Gemma4ForConditionalGeneration"),
|
| 697 |
+
("gemma4_audio", "Gemma4AudioModel"),
|
| 698 |
+
("gemma4_text", "Gemma4ForCausalLM"),
|
| 699 |
+
("gemma4_vision", "Gemma4VisionModel"),
|
| 700 |
+
("git", "GIT"),
|
| 701 |
+
("glm", "GLM"),
|
| 702 |
+
("glm4", "GLM4"),
|
| 703 |
+
("glm46v", "Glm46V"),
|
| 704 |
+
("glm4_moe", "Glm4MoE"),
|
| 705 |
+
("glm4_moe_lite", "Glm4MoELite"),
|
| 706 |
+
("glm4v", "GLM4V"),
|
| 707 |
+
("glm4v_moe", "GLM4VMOE"),
|
| 708 |
+
("glm4v_moe_text", "GLM4VMOE"),
|
| 709 |
+
("glm4v_moe_vision", "Glm4vMoeVisionModel"),
|
| 710 |
+
("glm4v_text", "GLM4V"),
|
| 711 |
+
("glm4v_vision", "Glm4vVisionModel"),
|
| 712 |
+
("glm_image", "GlmImage"),
|
| 713 |
+
("glm_image_text", "GlmImageText"),
|
| 714 |
+
("glm_image_vision", "GlmImageVisionModel"),
|
| 715 |
+
("glm_image_vqmodel", "GlmImageVQVAE"),
|
| 716 |
+
("glm_moe_dsa", "GlmMoeDsa"),
|
| 717 |
+
("glm_ocr", "Glmocr"),
|
| 718 |
+
("glm_ocr_text", "GlmOcrText"),
|
| 719 |
+
("glm_ocr_vision", "GlmOcrVisionModel"),
|
| 720 |
+
("glmasr", "GLM-ASR"),
|
| 721 |
+
("glmasr_encoder", "GLM-ASR Encoder"),
|
| 722 |
+
("glpn", "GLPN"),
|
| 723 |
+
("got_ocr2", "GOT-OCR2"),
|
| 724 |
+
("gpt-sw3", "GPT-Sw3"),
|
| 725 |
+
("gpt2", "OpenAI GPT-2"),
|
| 726 |
+
("gpt_bigcode", "GPTBigCode"),
|
| 727 |
+
("gpt_neo", "GPT Neo"),
|
| 728 |
+
("gpt_neox", "GPT NeoX"),
|
| 729 |
+
("gpt_neox_japanese", "GPT NeoX Japanese"),
|
| 730 |
+
("gpt_oss", "GptOss"),
|
| 731 |
+
("gptj", "GPT-J"),
|
| 732 |
+
("granite", "Granite"),
|
| 733 |
+
("granite_speech", "GraniteSpeech"),
|
| 734 |
+
("granitemoe", "GraniteMoeMoe"),
|
| 735 |
+
("granitemoehybrid", "GraniteMoeHybrid"),
|
| 736 |
+
("granitemoeshared", "GraniteMoeSharedMoe"),
|
| 737 |
+
("granitevision", "LLaVA-NeXT"),
|
| 738 |
+
("grounding-dino", "Grounding DINO"),
|
| 739 |
+
("groupvit", "GroupViT"),
|
| 740 |
+
("helium", "Helium"),
|
| 741 |
+
("herbert", "HerBERT"),
|
| 742 |
+
("hgnet_v2", "HGNet-V2"),
|
| 743 |
+
("hiera", "Hiera"),
|
| 744 |
+
("higgs_audio_v2", "HiggsAudioV2"),
|
| 745 |
+
("higgs_audio_v2_tokenizer", "HiggsAudioV2Tokenizer"),
|
| 746 |
+
("hubert", "Hubert"),
|
| 747 |
+
("hunyuan_v1_dense", "HunYuanDenseV1"),
|
| 748 |
+
("hunyuan_v1_moe", "HunYuanMoeV1"),
|
| 749 |
+
("ibert", "I-BERT"),
|
| 750 |
+
("idefics", "IDEFICS"),
|
| 751 |
+
("idefics2", "Idefics2"),
|
| 752 |
+
("idefics3", "Idefics3"),
|
| 753 |
+
("idefics3_vision", "Idefics3VisionTransformer"),
|
| 754 |
+
("ijepa", "I-JEPA"),
|
| 755 |
+
("imagegpt", "ImageGPT"),
|
| 756 |
+
("informer", "Informer"),
|
| 757 |
+
("instructblip", "InstructBLIP"),
|
| 758 |
+
("instructblipvideo", "InstructBlipVideo"),
|
| 759 |
+
("internvl", "InternVL"),
|
| 760 |
+
("internvl_vision", "InternVLVision"),
|
| 761 |
+
("jais2", "Jais2"),
|
| 762 |
+
("jamba", "Jamba"),
|
| 763 |
+
("janus", "Janus"),
|
| 764 |
+
("jetmoe", "JetMoe"),
|
| 765 |
+
("jina_embeddings_v3", "JinaEmbeddingsV3"),
|
| 766 |
+
("kosmos-2", "KOSMOS-2"),
|
| 767 |
+
("kosmos-2.5", "KOSMOS-2.5"),
|
| 768 |
+
("kyutai_speech_to_text", "KyutaiSpeechToText"),
|
| 769 |
+
("lasr", "Lasr"),
|
| 770 |
+
("lasr_ctc", "Lasr"),
|
| 771 |
+
("lasr_encoder", "LasrEncoder"),
|
| 772 |
+
("layoutlm", "LayoutLM"),
|
| 773 |
+
("layoutlmv2", "LayoutLMv2"),
|
| 774 |
+
("layoutlmv3", "LayoutLMv3"),
|
| 775 |
+
("layoutxlm", "LayoutXLM"),
|
| 776 |
+
("led", "LED"),
|
| 777 |
+
("levit", "LeViT"),
|
| 778 |
+
("lfm2", "Lfm2"),
|
| 779 |
+
("lfm2_moe", "Lfm2Moe"),
|
| 780 |
+
("lfm2_vl", "Lfm2Vl"),
|
| 781 |
+
("lightglue", "LightGlue"),
|
| 782 |
+
("lighton_ocr", "LightOnOcr"),
|
| 783 |
+
("lilt", "LiLT"),
|
| 784 |
+
("llama", "LLaMA"),
|
| 785 |
+
("llama2", "Llama2"),
|
| 786 |
+
("llama3", "Llama3"),
|
| 787 |
+
("llama4", "Llama4"),
|
| 788 |
+
("llama4_text", "Llama4ForCausalLM"),
|
| 789 |
+
("llava", "LLaVa"),
|
| 790 |
+
("llava_next", "LLaVA-NeXT"),
|
| 791 |
+
("llava_next_video", "LLaVa-NeXT-Video"),
|
| 792 |
+
("llava_onevision", "LLaVA-Onevision"),
|
| 793 |
+
("longcat_flash", "LongCatFlash"),
|
| 794 |
+
("longformer", "Longformer"),
|
| 795 |
+
("longt5", "LongT5"),
|
| 796 |
+
("luke", "LUKE"),
|
| 797 |
+
("lw_detr", "LwDetr"),
|
| 798 |
+
("lw_detr_vit", "LwDetrVit"),
|
| 799 |
+
("lxmert", "LXMERT"),
|
| 800 |
+
("m2m_100", "M2M100"),
|
| 801 |
+
("madlad-400", "MADLAD-400"),
|
| 802 |
+
("mamba", "Mamba"),
|
| 803 |
+
("mamba2", "mamba2"),
|
| 804 |
+
("marian", "Marian"),
|
| 805 |
+
("markuplm", "MarkupLM"),
|
| 806 |
+
("mask2former", "Mask2Former"),
|
| 807 |
+
("maskformer", "MaskFormer"),
|
| 808 |
+
("maskformer-swin", "MaskFormerSwin"),
|
| 809 |
+
("matcha", "MatCha"),
|
| 810 |
+
("mbart", "mBART"),
|
| 811 |
+
("mbart50", "mBART-50"),
|
| 812 |
+
("megatron-bert", "Megatron-BERT"),
|
| 813 |
+
("megatron_gpt2", "Megatron-GPT2"),
|
| 814 |
+
("metaclip_2", "MetaCLIP 2"),
|
| 815 |
+
("mgp-str", "MGP-STR"),
|
| 816 |
+
("mimi", "Mimi"),
|
| 817 |
+
("minimax", "MiniMax"),
|
| 818 |
+
("minimax_m2", "MiniMax-M2"),
|
| 819 |
+
("ministral", "Ministral"),
|
| 820 |
+
("ministral3", "Ministral3"),
|
| 821 |
+
("mistral", "Mistral"),
|
| 822 |
+
("mistral3", "Mistral3"),
|
| 823 |
+
("mistral4", "Mistral4"),
|
| 824 |
+
("mixtral", "Mixtral"),
|
| 825 |
+
("mlcd", "MLCD"), # Keep this to make some original hub repositories (from `DeepGlint-AI`) works
|
| 826 |
+
("mlcd_vision_model", "MLCD"),
|
| 827 |
+
("mllama", "Mllama"),
|
| 828 |
+
("mluke", "mLUKE"),
|
| 829 |
+
("mm-grounding-dino", "MM Grounding DINO"),
|
| 830 |
+
("mms", "MMS"),
|
| 831 |
+
("mobilebert", "MobileBERT"),
|
| 832 |
+
("mobilenet_v1", "MobileNetV1"),
|
| 833 |
+
("mobilenet_v2", "MobileNetV2"),
|
| 834 |
+
("mobilevit", "MobileViT"),
|
| 835 |
+
("mobilevitv2", "MobileViTV2"),
|
| 836 |
+
("modernbert", "ModernBERT"),
|
| 837 |
+
("modernbert-decoder", "ModernBertDecoder"),
|
| 838 |
+
("modernvbert", "ModernVBert"),
|
| 839 |
+
("moonshine", "Moonshine"),
|
| 840 |
+
("moonshine_streaming", "MoonshineStreaming"),
|
| 841 |
+
("moonshine_streaming_encoder", "MoonshineStreamingEncoder"),
|
| 842 |
+
("moshi", "Moshi"),
|
| 843 |
+
("mpnet", "MPNet"),
|
| 844 |
+
("mpt", "MPT"),
|
| 845 |
+
("mra", "MRA"),
|
| 846 |
+
("mt5", "MT5"),
|
| 847 |
+
("musicflamingo", "MusicFlamingo"),
|
| 848 |
+
("musicflamingo_encoder", "AudioFlamingo3Encoder"),
|
| 849 |
+
("musicgen", "MusicGen"),
|
| 850 |
+
("musicgen_melody", "MusicGen Melody"),
|
| 851 |
+
("mvp", "MVP"),
|
| 852 |
+
("myt5", "myt5"),
|
| 853 |
+
("nanochat", "NanoChat"),
|
| 854 |
+
("nemotron", "Nemotron"),
|
| 855 |
+
("nemotron_h", "NemotronH"),
|
| 856 |
+
("nllb", "NLLB"),
|
| 857 |
+
("nllb-moe", "NLLB-MOE"),
|
| 858 |
+
("nomic_bert", "NomicBERT"),
|
| 859 |
+
("nougat", "Nougat"),
|
| 860 |
+
("nystromformer", "Nyströmformer"),
|
| 861 |
+
("olmo", "OLMo"),
|
| 862 |
+
("olmo2", "OLMo2"),
|
| 863 |
+
("olmo3", "Olmo3"),
|
| 864 |
+
("olmo_hybrid", "OlmoHybrid"),
|
| 865 |
+
("olmoe", "OLMoE"),
|
| 866 |
+
("omdet-turbo", "OmDet-Turbo"),
|
| 867 |
+
("oneformer", "OneFormer"),
|
| 868 |
+
("openai-gpt", "OpenAI GPT"),
|
| 869 |
+
("opt", "OPT"),
|
| 870 |
+
("ovis2", "Ovis2"),
|
| 871 |
+
("owlv2", "OWLv2"),
|
| 872 |
+
("owlvit", "OWL-ViT"),
|
| 873 |
+
("paddleocr_vl", "PaddleOCRVL"),
|
| 874 |
+
("paligemma", "PaliGemma"),
|
| 875 |
+
("parakeet", "Parakeet"),
|
| 876 |
+
("parakeet_ctc", "Parakeet"),
|
| 877 |
+
("parakeet_encoder", "ParakeetEncoder"),
|
| 878 |
+
("patchtsmixer", "PatchTSMixer"),
|
| 879 |
+
("patchtst", "PatchTST"),
|
| 880 |
+
("pe_audio", "PeAudio"),
|
| 881 |
+
("pe_audio_encoder", "PeAudioEncoder"),
|
| 882 |
+
("pe_audio_video", "PeAudioVideo"),
|
| 883 |
+
("pe_audio_video_encoder", "PeAudioVideoEncoder"),
|
| 884 |
+
("pe_video", "PeVideo"),
|
| 885 |
+
("pe_video_encoder", "PeVideoEncoder"),
|
| 886 |
+
("pegasus", "Pegasus"),
|
| 887 |
+
("pegasus_x", "PEGASUS-X"),
|
| 888 |
+
("perceiver", "Perceiver"),
|
| 889 |
+
("perception_lm", "PerceptionLM"),
|
| 890 |
+
("persimmon", "Persimmon"),
|
| 891 |
+
("phi", "Phi"),
|
| 892 |
+
("phi3", "Phi3"),
|
| 893 |
+
("phi4_multimodal", "Phi4Multimodal"),
|
| 894 |
+
("phimoe", "Phimoe"),
|
| 895 |
+
("phobert", "PhoBERT"),
|
| 896 |
+
("pi0", "PI0"),
|
| 897 |
+
("pix2struct", "Pix2Struct"),
|
| 898 |
+
("pixio", "Pixio"),
|
| 899 |
+
("pixtral", "Pixtral"),
|
| 900 |
+
("plbart", "PLBart"),
|
| 901 |
+
("poolformer", "PoolFormer"),
|
| 902 |
+
("pop2piano", "Pop2Piano"),
|
| 903 |
+
("pp_chart2table", "PPChart2Table"),
|
| 904 |
+
("pp_doclayout_v2", "PPDocLayoutV2"),
|
| 905 |
+
("pp_doclayout_v3", "PPDocLayoutV3"),
|
| 906 |
+
("pp_lcnet", "PPLCNet"),
|
| 907 |
+
("pp_lcnet_v3", "PPLCNetV3"),
|
| 908 |
+
("pp_ocrv5_mobile_det", "PPOCRV5MobileDet"),
|
| 909 |
+
("pp_ocrv5_mobile_rec", "PPOCRV5MobileRec"),
|
| 910 |
+
("pp_ocrv5_server_det", "PPOCRV5ServerDet"),
|
| 911 |
+
("pp_ocrv5_server_rec", "PPOCRV5ServerRec"),
|
| 912 |
+
("prompt_depth_anything", "PromptDepthAnything"),
|
| 913 |
+
("prophetnet", "ProphetNet"),
|
| 914 |
+
("pvt", "PVT"),
|
| 915 |
+
("pvt_v2", "PVTv2"),
|
| 916 |
+
("qwen2", "Qwen2"),
|
| 917 |
+
("qwen2_5_omni", "Qwen2_5Omni"),
|
| 918 |
+
("qwen2_5_vl", "Qwen2_5_VL"),
|
| 919 |
+
("qwen2_5_vl_text", "Qwen2_5_VL"),
|
| 920 |
+
("qwen2_audio", "Qwen2Audio"),
|
| 921 |
+
("qwen2_audio_encoder", "Qwen2AudioEncoder"),
|
| 922 |
+
("qwen2_moe", "Qwen2MoE"),
|
| 923 |
+
("qwen2_vl", "Qwen2VL"),
|
| 924 |
+
("qwen2_vl_text", "Qwen2VL"),
|
| 925 |
+
("qwen3", "Qwen3"),
|
| 926 |
+
("qwen3_5", "Qwen3_5"),
|
| 927 |
+
("qwen3_5_moe", "Qwen3_5Moe"),
|
| 928 |
+
("qwen3_5_moe_text", "Qwen3_5MoeText"),
|
| 929 |
+
("qwen3_5_text", "Qwen3_5Text"),
|
| 930 |
+
("qwen3_moe", "Qwen3MoE"),
|
| 931 |
+
("qwen3_next", "Qwen3Next"),
|
| 932 |
+
("qwen3_omni_moe", "Qwen3OmniMoE"),
|
| 933 |
+
("qwen3_vl", "Qwen3VL"),
|
| 934 |
+
("qwen3_vl_moe", "Qwen3VLMoe"),
|
| 935 |
+
("qwen3_vl_moe_text", "Qwen3VLMoe"),
|
| 936 |
+
("qwen3_vl_text", "Qwen3VL"),
|
| 937 |
+
("rag", "RAG"),
|
| 938 |
+
("recurrent_gemma", "RecurrentGemma"),
|
| 939 |
+
("reformer", "Reformer"),
|
| 940 |
+
("regnet", "RegNet"),
|
| 941 |
+
("rembert", "RemBERT"),
|
| 942 |
+
("resnet", "ResNet"),
|
| 943 |
+
("roberta", "RoBERTa"),
|
| 944 |
+
("roberta-prelayernorm", "RoBERTa-PreLayerNorm"),
|
| 945 |
+
("roc_bert", "RoCBert"),
|
| 946 |
+
("roformer", "RoFormer"),
|
| 947 |
+
("rt_detr", "RT-DETR"),
|
| 948 |
+
("rt_detr_resnet", "RT-DETR-ResNet"),
|
| 949 |
+
("rt_detr_v2", "RT-DETRv2"),
|
| 950 |
+
("rwkv", "RWKV"),
|
| 951 |
+
("sam", "SAM"),
|
| 952 |
+
("sam2", "SAM2"),
|
| 953 |
+
("sam2_hiera_det_model", "Sam2HieraDetModel"),
|
| 954 |
+
("sam2_video", "Sam2VideoModel"),
|
| 955 |
+
("sam2_vision_model", "Sam2VisionModel"),
|
| 956 |
+
("sam3", "SAM3"),
|
| 957 |
+
("sam3_tracker", "Sam3Tracker"),
|
| 958 |
+
("sam3_tracker_video", "Sam3TrackerVideo"),
|
| 959 |
+
("sam3_video", "Sam3VideoModel"),
|
| 960 |
+
("sam3_vision_model", "Sam3VisionModel"),
|
| 961 |
+
("sam3_vit_model", "Sam3ViTModel"),
|
| 962 |
+
("sam_hq", "SAM-HQ"),
|
| 963 |
+
("sam_hq_vision_model", "SamHQVisionModel"),
|
| 964 |
+
("sam_vision_model", "SamVisionModel"),
|
| 965 |
+
("seamless_m4t", "SeamlessM4T"),
|
| 966 |
+
("seamless_m4t_v2", "SeamlessM4Tv2"),
|
| 967 |
+
("seed_oss", "SeedOss"),
|
| 968 |
+
("segformer", "SegFormer"),
|
| 969 |
+
("seggpt", "SegGPT"),
|
| 970 |
+
("sew", "SEW"),
|
| 971 |
+
("sew-d", "SEW-D"),
|
| 972 |
+
("shieldgemma2", "Shieldgemma2"),
|
| 973 |
+
("siglip", "SigLIP"),
|
| 974 |
+
("siglip2", "SigLIP2"),
|
| 975 |
+
("siglip2_vision_model", "Siglip2VisionModel"),
|
| 976 |
+
("siglip_vision_model", "SiglipVisionModel"),
|
| 977 |
+
("slanext", "SLANeXt"),
|
| 978 |
+
("smollm3", "SmolLM3"),
|
| 979 |
+
("smolvlm", "SmolVLM"),
|
| 980 |
+
("smolvlm_vision", "SmolVLMVisionTransformer"),
|
| 981 |
+
("solar_open", "SolarOpen"),
|
| 982 |
+
("speech-encoder-decoder", "Speech Encoder decoder"),
|
| 983 |
+
("speech_to_text", "Speech2Text"),
|
| 984 |
+
("speecht5", "SpeechT5"),
|
| 985 |
+
("splinter", "Splinter"),
|
| 986 |
+
("squeezebert", "SqueezeBERT"),
|
| 987 |
+
("stablelm", "StableLm"),
|
| 988 |
+
("starcoder2", "Starcoder2"),
|
| 989 |
+
("superglue", "SuperGlue"),
|
| 990 |
+
("superpoint", "SuperPoint"),
|
| 991 |
+
("swiftformer", "SwiftFormer"),
|
| 992 |
+
("swin", "Swin Transformer"),
|
| 993 |
+
("swin2sr", "Swin2SR"),
|
| 994 |
+
("swinv2", "Swin Transformer V2"),
|
| 995 |
+
("switch_transformers", "SwitchTransformers"),
|
| 996 |
+
("t5", "T5"),
|
| 997 |
+
("t5gemma", "T5Gemma"),
|
| 998 |
+
("t5gemma2", "T5Gemma2"),
|
| 999 |
+
("t5gemma2_encoder", "T5Gemma2Encoder"),
|
| 1000 |
+
("t5v1.1", "T5v1.1"),
|
| 1001 |
+
("table-transformer", "Table Transformer"),
|
| 1002 |
+
("tapas", "TAPAS"),
|
| 1003 |
+
("textnet", "TextNet"),
|
| 1004 |
+
("time_series_transformer", "Time Series Transformer"),
|
| 1005 |
+
("timesfm", "TimesFm"),
|
| 1006 |
+
("timesfm2_5", "TimesFm2p5"),
|
| 1007 |
+
("timesformer", "TimeSformer"),
|
| 1008 |
+
("timm_backbone", "TimmBackbone"),
|
| 1009 |
+
("timm_wrapper", "TimmWrapperModel"),
|
| 1010 |
+
("trocr", "TrOCR"),
|
| 1011 |
+
("tvp", "TVP"),
|
| 1012 |
+
("udop", "UDOP"),
|
| 1013 |
+
("ul2", "UL2"),
|
| 1014 |
+
("umt5", "UMT5"),
|
| 1015 |
+
("unispeech", "UniSpeech"),
|
| 1016 |
+
("unispeech-sat", "UniSpeechSat"),
|
| 1017 |
+
("univnet", "UnivNet"),
|
| 1018 |
+
("upernet", "UPerNet"),
|
| 1019 |
+
("uvdoc", "UVDoc"),
|
| 1020 |
+
("uvdoc_backbone", "UVDocBackbone"),
|
| 1021 |
+
("vaultgemma", "VaultGemma"),
|
| 1022 |
+
("vibevoice_acoustic_tokenizer", "VibeVoiceAcousticTokenizer"),
|
| 1023 |
+
("vibevoice_acoustic_tokenizer_decoder", "VibeVoiceAcousticTokenizerDecoderConfig"),
|
| 1024 |
+
("vibevoice_acoustic_tokenizer_encoder", "VibeVoiceAcousticTokenizerEncoderConfig"),
|
| 1025 |
+
("vibevoice_asr", "VibeVoiceAsr"),
|
| 1026 |
+
("video_llama_3", "VideoLlama3"),
|
| 1027 |
+
("video_llama_3_vision", "VideoLlama3Vision"),
|
| 1028 |
+
("video_llava", "VideoLlava"),
|
| 1029 |
+
("videomae", "VideoMAE"),
|
| 1030 |
+
("videomt", "VidEoMT"),
|
| 1031 |
+
("vilt", "ViLT"),
|
| 1032 |
+
("vipllava", "VipLlava"),
|
| 1033 |
+
("vision-encoder-decoder", "Vision Encoder decoder"),
|
| 1034 |
+
("vision-text-dual-encoder", "VisionTextDualEncoder"),
|
| 1035 |
+
("visual_bert", "VisualBERT"),
|
| 1036 |
+
("vit", "ViT"),
|
| 1037 |
+
("vit_mae", "ViTMAE"),
|
| 1038 |
+
("vit_msn", "ViTMSN"),
|
| 1039 |
+
("vitdet", "VitDet"),
|
| 1040 |
+
("vitmatte", "ViTMatte"),
|
| 1041 |
+
("vitpose", "ViTPose"),
|
| 1042 |
+
("vitpose_backbone", "ViTPoseBackbone"),
|
| 1043 |
+
("vits", "VITS"),
|
| 1044 |
+
("vivit", "ViViT"),
|
| 1045 |
+
("vjepa2", "VJEPA2Model"),
|
| 1046 |
+
("voxtral", "Voxtral"),
|
| 1047 |
+
("voxtral_encoder", "Voxtral Encoder"),
|
| 1048 |
+
("voxtral_realtime", "VoxtralRealtime"),
|
| 1049 |
+
("voxtral_realtime_encoder", "VoxtralRealtime Encoder"),
|
| 1050 |
+
("voxtral_realtime_text", "VoxtralRealtime Text Model"),
|
| 1051 |
+
("wav2vec2", "Wav2Vec2"),
|
| 1052 |
+
("wav2vec2-bert", "Wav2Vec2-BERT"),
|
| 1053 |
+
("wav2vec2-conformer", "Wav2Vec2-Conformer"),
|
| 1054 |
+
("wav2vec2_phoneme", "Wav2Vec2Phoneme"),
|
| 1055 |
+
("wavlm", "WavLM"),
|
| 1056 |
+
("whisper", "Whisper"),
|
| 1057 |
+
("xclip", "X-CLIP"),
|
| 1058 |
+
("xcodec", "X-CODEC"),
|
| 1059 |
+
("xglm", "XGLM"),
|
| 1060 |
+
("xlm", "XLM"),
|
| 1061 |
+
("xlm-roberta", "XLM-RoBERTa"),
|
| 1062 |
+
("xlm-roberta-xl", "XLM-RoBERTa-XL"),
|
| 1063 |
+
("xlm-v", "XLM-V"),
|
| 1064 |
+
("xlnet", "XLNet"),
|
| 1065 |
+
("xls_r", "XLS-R"),
|
| 1066 |
+
("xlsr_wav2vec2", "XLSR-Wav2Vec2"),
|
| 1067 |
+
("xlstm", "xLSTM"),
|
| 1068 |
+
("xmod", "X-MOD"),
|
| 1069 |
+
("yolos", "YOLOS"),
|
| 1070 |
+
("yoso", "YOSO"),
|
| 1071 |
+
("youtu", "Youtu"),
|
| 1072 |
+
("zamba", "Zamba"),
|
| 1073 |
+
("zamba2", "Zamba2"),
|
| 1074 |
+
("zoedepth", "ZoeDepth"),
|
| 1075 |
+
]
|
| 1076 |
+
)
|
| 1077 |
+
|
| 1078 |
+
# This is tied to the processing `-` -> `_` in `model_type_to_module_name`. For example, instead of putting
|
| 1079 |
+
# `transfo-xl` (as in `CONFIG_MAPPING_NAMES`), we should use `transfo_xl`.
|
| 1080 |
+
DEPRECATED_MODELS = []
|
| 1081 |
+
|
| 1082 |
+
SPECIAL_MODEL_TYPE_TO_MODULE_NAME = OrderedDict[str, str](
|
| 1083 |
+
[
|
| 1084 |
+
("audioflamingo3_encoder", "audioflamingo3"),
|
| 1085 |
+
("musicflamingo_encoder", "musicflamingo"),
|
| 1086 |
+
("openai-gpt", "openai"),
|
| 1087 |
+
("blip-2", "blip_2"),
|
| 1088 |
+
("data2vec-audio", "data2vec"),
|
| 1089 |
+
("data2vec-text", "data2vec"),
|
| 1090 |
+
("data2vec-vision", "data2vec"),
|
| 1091 |
+
("donut-swin", "donut"),
|
| 1092 |
+
("kosmos-2", "kosmos2"),
|
| 1093 |
+
("kosmos-2.5", "kosmos2_5"),
|
| 1094 |
+
("mlcd_vision_model", "mlcd"),
|
| 1095 |
+
("omdet-turbo", "omdet_turbo"),
|
| 1096 |
+
("maskformer-swin", "maskformer"),
|
| 1097 |
+
("xclip", "x_clip"),
|
| 1098 |
+
("clip_vision_model", "clip"),
|
| 1099 |
+
("qwen2_audio_encoder", "qwen2_audio"),
|
| 1100 |
+
("voxtral_encoder", "voxtral"),
|
| 1101 |
+
("voxtral_realtime_encoder", "voxtral_realtime"),
|
| 1102 |
+
("voxtral_realtime_text", "voxtral_realtime"),
|
| 1103 |
+
("clip_text_model", "clip"),
|
| 1104 |
+
("aria_text", "aria"),
|
| 1105 |
+
("gemma3_text", "gemma3"),
|
| 1106 |
+
("gemma3n_audio", "gemma3n"),
|
| 1107 |
+
("gemma3n_text", "gemma3n"),
|
| 1108 |
+
("gemma3n_vision", "gemma3n"),
|
| 1109 |
+
("gemma4_audio", "gemma4"),
|
| 1110 |
+
("gemma4_text", "gemma4"),
|
| 1111 |
+
("gemma4_vision", "gemma4"),
|
| 1112 |
+
("glm4v_vision", "glm4v"),
|
| 1113 |
+
("glm4v_moe_vision", "glm4v_moe"),
|
| 1114 |
+
("glm4v_text", "glm4v"),
|
| 1115 |
+
("glm4v_moe_text", "glm4v_moe"),
|
| 1116 |
+
("glm_image_vision", "glm_image"),
|
| 1117 |
+
("glm_image_vqmodel", "glm_image"),
|
| 1118 |
+
("glm_image_text", "glm_image"),
|
| 1119 |
+
("glm_ocr_vision", "glm_ocr"),
|
| 1120 |
+
("glm_ocr_vqmodel", "glm_ocr"),
|
| 1121 |
+
("glm_ocr_text", "glm_ocr"),
|
| 1122 |
+
("glmasr_encoder", "glmasr"),
|
| 1123 |
+
("grounding-dino", "grounding_dino"),
|
| 1124 |
+
("moonshine_streaming_encoder", "moonshine_streaming"),
|
| 1125 |
+
("mm-grounding-dino", "mm_grounding_dino"),
|
| 1126 |
+
("idefics3_vision", "idefics3"),
|
| 1127 |
+
("mgp-str", "mgp_str"),
|
| 1128 |
+
("siglip_vision_model", "siglip"),
|
| 1129 |
+
("siglip2_vision_model", "siglip2"),
|
| 1130 |
+
("aimv2_vision_model", "aimv2"),
|
| 1131 |
+
("smolvlm_vision", "smolvlm"),
|
| 1132 |
+
("chinese_clip_vision_model", "chinese_clip"),
|
| 1133 |
+
("rt_detr_resnet", "rt_detr"),
|
| 1134 |
+
("granitevision", "llava_next"),
|
| 1135 |
+
("internvl_vision", "internvl"),
|
| 1136 |
+
("qwen2_5_vl_text", "qwen2_5_vl"),
|
| 1137 |
+
("qwen2_vl_text", "qwen2_vl"),
|
| 1138 |
+
("qwen3_vl_text", "qwen3_vl"),
|
| 1139 |
+
("qwen3_vl_moe_text", "qwen3_vl_moe"),
|
| 1140 |
+
("qwen3_5_text", "qwen3_5"),
|
| 1141 |
+
("qwen3_5_moe_text", "qwen3_5_moe"),
|
| 1142 |
+
("sam_vision_model", "sam"),
|
| 1143 |
+
("sam2_vision_model", "sam2"),
|
| 1144 |
+
("sam2_hiera_det_model", "sam2"),
|
| 1145 |
+
("sam3_vit_model", "sam3"),
|
| 1146 |
+
("sam3_vision_model", "sam3"),
|
| 1147 |
+
("edgetam_vision_model", "edgetam"),
|
| 1148 |
+
("sam_hq_vision_model", "sam_hq"),
|
| 1149 |
+
("t5gemma2_encoder", "t5gemma2"),
|
| 1150 |
+
("llama4_text", "llama4"),
|
| 1151 |
+
("blip_2_qformer", "blip_2"),
|
| 1152 |
+
("fastspeech2_conformer_with_hifigan", "fastspeech2_conformer"),
|
| 1153 |
+
("perception_encoder", "perception_lm"),
|
| 1154 |
+
("pe_audio_encoder", "pe_audio"),
|
| 1155 |
+
("pe_video_encoder", "pe_video"),
|
| 1156 |
+
("pe_audio_video_encoder", "pe_audio_video"),
|
| 1157 |
+
("video_llama_3_vision", "video_llama_3"),
|
| 1158 |
+
("parakeet_encoder", "parakeet"),
|
| 1159 |
+
("lw_detr_vit", "lw_detr"),
|
| 1160 |
+
("parakeet_ctc", "parakeet"),
|
| 1161 |
+
("lasr_encoder", "lasr"),
|
| 1162 |
+
("lasr_ctc", "lasr"),
|
| 1163 |
+
("wav2vec2-bert", "wav2vec2_bert"),
|
| 1164 |
+
("vibevoice_acoustic_tokenizer_encoder", "vibevoice_acoustic_tokenizer"),
|
| 1165 |
+
("vibevoice_acoustic_tokenizer_decoder", "vibevoice_acoustic_tokenizer"),
|
| 1166 |
+
("uvdoc_backbone", "uvdoc"),
|
| 1167 |
+
]
|
| 1168 |
+
)
|
| 1169 |
+
|
| 1170 |
+
|
| 1171 |
+
def model_type_to_module_name(key) -> str:
|
| 1172 |
+
"""Converts a config key to the corresponding module."""
|
| 1173 |
+
# Special treatment
|
| 1174 |
+
if key in SPECIAL_MODEL_TYPE_TO_MODULE_NAME:
|
| 1175 |
+
key = SPECIAL_MODEL_TYPE_TO_MODULE_NAME[key]
|
| 1176 |
+
|
| 1177 |
+
if key in DEPRECATED_MODELS:
|
| 1178 |
+
key = f"deprecated.{key}"
|
| 1179 |
+
return key
|
| 1180 |
+
|
| 1181 |
+
key = key.replace("-", "_")
|
| 1182 |
+
if key in DEPRECATED_MODELS:
|
| 1183 |
+
key = f"deprecated.{key}"
|
| 1184 |
+
|
| 1185 |
+
return key
|
| 1186 |
+
|
| 1187 |
+
|
| 1188 |
+
def config_class_to_model_type(config) -> str | None:
|
| 1189 |
+
"""Converts a config class name to the corresponding model type"""
|
| 1190 |
+
for key, cls in CONFIG_MAPPING_NAMES.items():
|
| 1191 |
+
if cls == config:
|
| 1192 |
+
return key
|
| 1193 |
+
# if key not found check in extra content
|
| 1194 |
+
for key, cls in CONFIG_MAPPING._extra_content.items():
|
| 1195 |
+
if cls.__name__ == config:
|
| 1196 |
+
return key
|
| 1197 |
+
return None
|
| 1198 |
+
|
| 1199 |
+
|
| 1200 |
+
class _LazyConfigMapping(OrderedDict[str, type[PreTrainedConfig]]):
|
| 1201 |
+
"""
|
| 1202 |
+
A dictionary that lazily load its values when they are requested.
|
| 1203 |
+
"""
|
| 1204 |
+
|
| 1205 |
+
def __init__(self, mapping) -> None:
|
| 1206 |
+
self._mapping = mapping
|
| 1207 |
+
self._extra_content = {}
|
| 1208 |
+
self._modules = {}
|
| 1209 |
+
|
| 1210 |
+
def __getitem__(self, key: str) -> type[PreTrainedConfig]:
|
| 1211 |
+
if key in self._extra_content:
|
| 1212 |
+
return self._extra_content[key]
|
| 1213 |
+
if key not in self._mapping:
|
| 1214 |
+
raise KeyError(key)
|
| 1215 |
+
value = self._mapping[key]
|
| 1216 |
+
module_name = model_type_to_module_name(key)
|
| 1217 |
+
if module_name not in self._modules:
|
| 1218 |
+
self._modules[module_name] = importlib.import_module(f".{module_name}", "transformers.models")
|
| 1219 |
+
if hasattr(self._modules[module_name], value):
|
| 1220 |
+
return getattr(self._modules[module_name], value)
|
| 1221 |
+
|
| 1222 |
+
# Some of the mappings have entries model_type -> config of another model type. In that case we try to grab the
|
| 1223 |
+
# object at the top level.
|
| 1224 |
+
transformers_module = importlib.import_module("transformers")
|
| 1225 |
+
return getattr(transformers_module, value)
|
| 1226 |
+
|
| 1227 |
+
def keys(self) -> list[str]:
|
| 1228 |
+
return list(self._mapping.keys()) + list(self._extra_content.keys())
|
| 1229 |
+
|
| 1230 |
+
def values(self) -> list[type[PreTrainedConfig]]:
|
| 1231 |
+
return [self[k] for k in self._mapping] + list(self._extra_content.values())
|
| 1232 |
+
|
| 1233 |
+
def items(self) -> list[tuple[str, type[PreTrainedConfig]]]:
|
| 1234 |
+
return [(k, self[k]) for k in self._mapping] + list(self._extra_content.items())
|
| 1235 |
+
|
| 1236 |
+
def __iter__(self) -> Iterator[str]:
|
| 1237 |
+
return iter(list(self._mapping.keys()) + list(self._extra_content.keys()))
|
| 1238 |
+
|
| 1239 |
+
def __contains__(self, item: object) -> bool:
|
| 1240 |
+
return item in self._mapping or item in self._extra_content
|
| 1241 |
+
|
| 1242 |
+
def register(self, key: str, value: type[PreTrainedConfig], exist_ok=False) -> None:
|
| 1243 |
+
"""
|
| 1244 |
+
Register a new configuration in this mapping.
|
| 1245 |
+
"""
|
| 1246 |
+
if key in self._mapping and not exist_ok:
|
| 1247 |
+
raise ValueError(f"'{key}' is already used by a Transformers config, pick another name.")
|
| 1248 |
+
self._extra_content[key] = value
|
| 1249 |
+
|
| 1250 |
+
|
| 1251 |
+
CONFIG_MAPPING = _LazyConfigMapping(CONFIG_MAPPING_NAMES)
|
| 1252 |
+
|
| 1253 |
+
|
| 1254 |
+
class _LazyLoadAllMappings(OrderedDict[str, str]):
|
| 1255 |
+
"""
|
| 1256 |
+
A mapping that will load all pairs of key values at the first access (either by indexing, requestions keys, values,
|
| 1257 |
+
etc.)
|
| 1258 |
+
|
| 1259 |
+
Args:
|
| 1260 |
+
mapping: The mapping to load.
|
| 1261 |
+
"""
|
| 1262 |
+
|
| 1263 |
+
def __init__(self, mapping):
|
| 1264 |
+
self._mapping = mapping
|
| 1265 |
+
self._initialized = False
|
| 1266 |
+
self._data = {}
|
| 1267 |
+
|
| 1268 |
+
def _initialize(self):
|
| 1269 |
+
if self._initialized:
|
| 1270 |
+
return
|
| 1271 |
+
|
| 1272 |
+
for model_type, map_name in self._mapping.items():
|
| 1273 |
+
module_name = model_type_to_module_name(model_type)
|
| 1274 |
+
module = importlib.import_module(f".{module_name}", "transformers.models")
|
| 1275 |
+
mapping = getattr(module, map_name)
|
| 1276 |
+
self._data.update(mapping)
|
| 1277 |
+
|
| 1278 |
+
self._initialized = True
|
| 1279 |
+
|
| 1280 |
+
def __getitem__(self, key):
|
| 1281 |
+
self._initialize()
|
| 1282 |
+
return self._data[key]
|
| 1283 |
+
|
| 1284 |
+
def keys(self) -> KeysView[str]:
|
| 1285 |
+
self._initialize()
|
| 1286 |
+
return self._data.keys()
|
| 1287 |
+
|
| 1288 |
+
def values(self) -> ValuesView[str]:
|
| 1289 |
+
self._initialize()
|
| 1290 |
+
return self._data.values()
|
| 1291 |
+
|
| 1292 |
+
def items(self) -> KeysView[str]:
|
| 1293 |
+
self._initialize()
|
| 1294 |
+
return self._data.keys()
|
| 1295 |
+
|
| 1296 |
+
def __iter__(self) -> Iterator[str]:
|
| 1297 |
+
self._initialize()
|
| 1298 |
+
return iter(self._data)
|
| 1299 |
+
|
| 1300 |
+
def __contains__(self, item: object) -> bool:
|
| 1301 |
+
self._initialize()
|
| 1302 |
+
return item in self._data
|
| 1303 |
+
|
| 1304 |
+
|
| 1305 |
+
def _get_class_name(model_class: str | list[str]):
|
| 1306 |
+
if isinstance(model_class, (list, tuple)):
|
| 1307 |
+
return " or ".join([f"[`{c}`]" for c in model_class if c is not None])
|
| 1308 |
+
return f"[`{model_class}`]"
|
| 1309 |
+
|
| 1310 |
+
|
| 1311 |
+
def _list_model_options(indent, config_to_class=None, use_model_types=True):
|
| 1312 |
+
if config_to_class is None and not use_model_types:
|
| 1313 |
+
raise ValueError("Using `use_model_types=False` requires a `config_to_class` dictionary.")
|
| 1314 |
+
if use_model_types:
|
| 1315 |
+
if config_to_class is None:
|
| 1316 |
+
model_type_to_name = {model_type: f"[`{config}`]" for model_type, config in CONFIG_MAPPING_NAMES.items()}
|
| 1317 |
+
else:
|
| 1318 |
+
model_type_to_name = {
|
| 1319 |
+
model_type: _get_class_name(model_class)
|
| 1320 |
+
for model_type, model_class in config_to_class.items()
|
| 1321 |
+
if model_type in MODEL_NAMES_MAPPING
|
| 1322 |
+
}
|
| 1323 |
+
lines = [
|
| 1324 |
+
f"{indent}- **{model_type}** -- {model_type_to_name[model_type]} ({MODEL_NAMES_MAPPING[model_type]} model)"
|
| 1325 |
+
for model_type in sorted(model_type_to_name.keys())
|
| 1326 |
+
]
|
| 1327 |
+
else:
|
| 1328 |
+
config_to_name = {
|
| 1329 |
+
CONFIG_MAPPING_NAMES[config]: _get_class_name(clas)
|
| 1330 |
+
for config, clas in config_to_class.items()
|
| 1331 |
+
if config in CONFIG_MAPPING_NAMES
|
| 1332 |
+
}
|
| 1333 |
+
config_to_model_name = {
|
| 1334 |
+
config: MODEL_NAMES_MAPPING[model_type] for model_type, config in CONFIG_MAPPING_NAMES.items()
|
| 1335 |
+
}
|
| 1336 |
+
lines = [
|
| 1337 |
+
f"{indent}- [`{config_name}`] configuration class:"
|
| 1338 |
+
f" {config_to_name[config_name]} ({config_to_model_name[config_name]} model)"
|
| 1339 |
+
for config_name in sorted(config_to_name.keys())
|
| 1340 |
+
]
|
| 1341 |
+
return "\n".join(lines)
|
| 1342 |
+
|
| 1343 |
+
|
| 1344 |
+
def replace_list_option_in_docstrings(
|
| 1345 |
+
config_to_class=None, use_model_types: bool = True
|
| 1346 |
+
) -> Callable[[_CallableT], _CallableT]:
|
| 1347 |
+
def docstring_decorator(fn):
|
| 1348 |
+
docstrings = fn.__doc__
|
| 1349 |
+
if docstrings is None:
|
| 1350 |
+
# Example: -OO
|
| 1351 |
+
return fn
|
| 1352 |
+
lines = docstrings.split("\n")
|
| 1353 |
+
i = 0
|
| 1354 |
+
while i < len(lines) and re.search(r"^(\s*)List options\s*$", lines[i]) is None:
|
| 1355 |
+
i += 1
|
| 1356 |
+
if i < len(lines):
|
| 1357 |
+
indent = re.search(r"^(\s*)List options\s*$", lines[i]).groups()[0]
|
| 1358 |
+
if use_model_types:
|
| 1359 |
+
indent = f"{indent} "
|
| 1360 |
+
lines[i] = _list_model_options(indent, config_to_class=config_to_class, use_model_types=use_model_types)
|
| 1361 |
+
docstrings = "\n".join(lines)
|
| 1362 |
+
else:
|
| 1363 |
+
raise ValueError(
|
| 1364 |
+
f"The function {fn} should have an empty 'List options' in its docstring as placeholder, current"
|
| 1365 |
+
f" docstring is:\n{docstrings}"
|
| 1366 |
+
)
|
| 1367 |
+
fn.__doc__ = docstrings
|
| 1368 |
+
return fn
|
| 1369 |
+
|
| 1370 |
+
return docstring_decorator
|
| 1371 |
+
|
| 1372 |
+
|
| 1373 |
+
class AutoConfig:
|
| 1374 |
+
r"""
|
| 1375 |
+
This is a generic configuration class that will be instantiated as one of the configuration classes of the library
|
| 1376 |
+
when created with the [`~AutoConfig.from_pretrained`] class method.
|
| 1377 |
+
|
| 1378 |
+
This class cannot be instantiated directly using `__init__()` (throws an error).
|
| 1379 |
+
"""
|
| 1380 |
+
|
| 1381 |
+
def __init__(self) -> None:
|
| 1382 |
+
raise OSError(
|
| 1383 |
+
"AutoConfig is designed to be instantiated "
|
| 1384 |
+
"using the `AutoConfig.from_pretrained(pretrained_model_name_or_path)` method."
|
| 1385 |
+
)
|
| 1386 |
+
|
| 1387 |
+
@classmethod
|
| 1388 |
+
def for_model(cls, model_type: str, *args, **kwargs) -> PreTrainedConfig:
|
| 1389 |
+
if model_type in CONFIG_MAPPING:
|
| 1390 |
+
config_class = CONFIG_MAPPING[model_type]
|
| 1391 |
+
return config_class(*args, **kwargs)
|
| 1392 |
+
raise ValueError(
|
| 1393 |
+
f"Unrecognized model identifier: {model_type}. Should contain one of {', '.join(CONFIG_MAPPING.keys())}"
|
| 1394 |
+
)
|
| 1395 |
+
|
| 1396 |
+
@classmethod
|
| 1397 |
+
@replace_list_option_in_docstrings()
|
| 1398 |
+
def from_pretrained(cls, pretrained_model_name_or_path: str | os.PathLike[str], **kwargs):
|
| 1399 |
+
r"""
|
| 1400 |
+
Instantiate one of the configuration classes of the library from a pretrained model configuration.
|
| 1401 |
+
|
| 1402 |
+
The configuration class to instantiate is selected based on the `model_type` property of the config object that
|
| 1403 |
+
is loaded, or when it's missing, by falling back to using pattern matching on `pretrained_model_name_or_path`:
|
| 1404 |
+
|
| 1405 |
+
List options
|
| 1406 |
+
|
| 1407 |
+
Args:
|
| 1408 |
+
pretrained_model_name_or_path (`str` or `os.PathLike`):
|
| 1409 |
+
Can be either:
|
| 1410 |
+
|
| 1411 |
+
- A string, the *model id* of a pretrained model configuration hosted inside a model repo on
|
| 1412 |
+
huggingface.co.
|
| 1413 |
+
- A path to a *directory* containing a configuration file saved using the
|
| 1414 |
+
[`~PreTrainedConfig.save_pretrained`] method, or the [`~PreTrainedModel.save_pretrained`] method,
|
| 1415 |
+
e.g., `./my_model_directory/`.
|
| 1416 |
+
- a path to a saved configuration JSON *file*, e.g.,
|
| 1417 |
+
`./my_model_directory/configuration.json`.
|
| 1418 |
+
cache_dir (`str` or `os.PathLike`, *optional*):
|
| 1419 |
+
Path to a directory in which a downloaded pretrained model configuration should be cached if the
|
| 1420 |
+
standard cache should not be used.
|
| 1421 |
+
force_download (`bool`, *optional*, defaults to `False`):
|
| 1422 |
+
Whether or not to force the (re-)download the model weights and configuration files and override the
|
| 1423 |
+
cached versions if they exist.
|
| 1424 |
+
proxies (`dict[str, str]`, *optional*):
|
| 1425 |
+
A dictionary of proxy servers to use by protocol or endpoint, e.g., `{'http': 'foo.bar:3128',
|
| 1426 |
+
'http://hostname': 'foo.bar:4012'}`. The proxies are used on each request.
|
| 1427 |
+
revision (`str`, *optional*, defaults to `"main"`):
|
| 1428 |
+
The specific model version to use. It can be a branch name, a tag name, or a commit id, since we use a
|
| 1429 |
+
git-based system for storing models and other artifacts on huggingface.co, so `revision` can be any
|
| 1430 |
+
identifier allowed by git.
|
| 1431 |
+
return_unused_kwargs (`bool`, *optional*, defaults to `False`):
|
| 1432 |
+
If `False`, then this function returns just the final configuration object.
|
| 1433 |
+
|
| 1434 |
+
If `True`, then this functions returns a `Tuple(config, unused_kwargs)` where *unused_kwargs* is a
|
| 1435 |
+
dictionary consisting of the key/value pairs whose keys are not configuration attributes: i.e., the
|
| 1436 |
+
part of `kwargs` which has not been used to update `config` and is otherwise ignored.
|
| 1437 |
+
trust_remote_code (`bool`, *optional*, defaults to `False`):
|
| 1438 |
+
Whether or not to allow for custom models defined on the Hub in their own modeling files. This option
|
| 1439 |
+
should only be set to `True` for repositories you trust and in which you have read the code, as it will
|
| 1440 |
+
execute code present on the Hub on your local machine.
|
| 1441 |
+
kwargs(additional keyword arguments, *optional*):
|
| 1442 |
+
The values in kwargs of any keys which are configuration attributes will be used to override the loaded
|
| 1443 |
+
values. Behavior concerning key/value pairs whose keys are *not* configuration attributes is controlled
|
| 1444 |
+
by the `return_unused_kwargs` keyword parameter.
|
| 1445 |
+
|
| 1446 |
+
Examples:
|
| 1447 |
+
|
| 1448 |
+
```python
|
| 1449 |
+
>>> from transformers import AutoConfig
|
| 1450 |
+
|
| 1451 |
+
>>> # Download configuration from huggingface.co and cache.
|
| 1452 |
+
>>> config = AutoConfig.from_pretrained("google-bert/bert-base-uncased")
|
| 1453 |
+
|
| 1454 |
+
>>> # Download configuration from huggingface.co (user-uploaded) and cache.
|
| 1455 |
+
>>> config = AutoConfig.from_pretrained("dbmdz/bert-base-german-cased")
|
| 1456 |
+
|
| 1457 |
+
>>> # If configuration file is in a directory (e.g., was saved using *save_pretrained('./test/saved_model/')*).
|
| 1458 |
+
>>> config = AutoConfig.from_pretrained("./test/bert_saved_model/")
|
| 1459 |
+
|
| 1460 |
+
>>> # Load a specific configuration file.
|
| 1461 |
+
>>> config = AutoConfig.from_pretrained("./test/bert_saved_model/my_configuration.json")
|
| 1462 |
+
|
| 1463 |
+
>>> # Change some config attributes when loading a pretrained config.
|
| 1464 |
+
>>> config = AutoConfig.from_pretrained("google-bert/bert-base-uncased", output_attentions=True, foo=False)
|
| 1465 |
+
>>> config.output_attentions
|
| 1466 |
+
True
|
| 1467 |
+
|
| 1468 |
+
>>> config, unused_kwargs = AutoConfig.from_pretrained(
|
| 1469 |
+
... "google-bert/bert-base-uncased", output_attentions=True, foo=False, return_unused_kwargs=True
|
| 1470 |
+
... )
|
| 1471 |
+
>>> config.output_attentions
|
| 1472 |
+
True
|
| 1473 |
+
|
| 1474 |
+
>>> unused_kwargs
|
| 1475 |
+
{'foo': False}
|
| 1476 |
+
```
|
| 1477 |
+
"""
|
| 1478 |
+
kwargs["_from_auto"] = True
|
| 1479 |
+
kwargs["name_or_path"] = pretrained_model_name_or_path
|
| 1480 |
+
trust_remote_code = kwargs.pop("trust_remote_code", None)
|
| 1481 |
+
code_revision = kwargs.pop("code_revision", None)
|
| 1482 |
+
|
| 1483 |
+
config_dict, unused_kwargs = PreTrainedConfig.get_config_dict(pretrained_model_name_or_path, **kwargs)
|
| 1484 |
+
has_remote_code = "auto_map" in config_dict and "AutoConfig" in config_dict["auto_map"]
|
| 1485 |
+
has_local_code = "model_type" in config_dict and config_dict["model_type"] in CONFIG_MAPPING
|
| 1486 |
+
explicit_local_code = has_local_code and not CONFIG_MAPPING[config_dict["model_type"]].__module__.startswith(
|
| 1487 |
+
"transformers."
|
| 1488 |
+
)
|
| 1489 |
+
if has_remote_code:
|
| 1490 |
+
class_ref = config_dict["auto_map"]["AutoConfig"]
|
| 1491 |
+
if "--" in class_ref:
|
| 1492 |
+
upstream_repo = class_ref.split("--")[0]
|
| 1493 |
+
else:
|
| 1494 |
+
upstream_repo = None
|
| 1495 |
+
trust_remote_code = resolve_trust_remote_code(
|
| 1496 |
+
trust_remote_code, pretrained_model_name_or_path, has_local_code, has_remote_code, upstream_repo
|
| 1497 |
+
)
|
| 1498 |
+
|
| 1499 |
+
if has_remote_code and trust_remote_code and not explicit_local_code:
|
| 1500 |
+
config_class = get_class_from_dynamic_module(
|
| 1501 |
+
class_ref, pretrained_model_name_or_path, code_revision=code_revision, **kwargs
|
| 1502 |
+
)
|
| 1503 |
+
config_class.register_for_auto_class()
|
| 1504 |
+
return config_class.from_pretrained(pretrained_model_name_or_path, **kwargs)
|
| 1505 |
+
elif "model_type" in config_dict:
|
| 1506 |
+
# Apply heuristic: if model_type is mistral but layer_types is present, treat as ministral
|
| 1507 |
+
if config_dict["model_type"] == "mistral" and "layer_types" in config_dict:
|
| 1508 |
+
logger.info(
|
| 1509 |
+
"Detected mistral model with layer_types, treating as ministral for alternating attention compatibility. "
|
| 1510 |
+
)
|
| 1511 |
+
config_dict["model_type"] = "ministral"
|
| 1512 |
+
|
| 1513 |
+
try:
|
| 1514 |
+
config_class = CONFIG_MAPPING[config_dict["model_type"]]
|
| 1515 |
+
except KeyError:
|
| 1516 |
+
raise ValueError(
|
| 1517 |
+
f"The checkpoint you are trying to load has model type `{config_dict['model_type']}` "
|
| 1518 |
+
"but Transformers does not recognize this architecture. This could be because of an "
|
| 1519 |
+
"issue with the checkpoint, or because your version of Transformers is out of date.\n\n"
|
| 1520 |
+
"You can update Transformers with the command `pip install --upgrade transformers`. If this "
|
| 1521 |
+
"does not work, and the checkpoint is very new, then there may not be a release version "
|
| 1522 |
+
"that supports this model yet. In this case, you can get the most up-to-date code by installing "
|
| 1523 |
+
"Transformers from source with the command "
|
| 1524 |
+
"`pip install git+https://github.com/huggingface/transformers.git`"
|
| 1525 |
+
)
|
| 1526 |
+
return config_class.from_dict(config_dict, **unused_kwargs)
|
| 1527 |
+
|
| 1528 |
+
raise ValueError(
|
| 1529 |
+
f"Unrecognized model in {pretrained_model_name_or_path}. "
|
| 1530 |
+
f"Should have a `model_type` key in its {CONFIG_NAME}."
|
| 1531 |
+
)
|
| 1532 |
+
|
| 1533 |
+
@staticmethod
|
| 1534 |
+
def register(model_type, config, exist_ok=False) -> None:
|
| 1535 |
+
"""
|
| 1536 |
+
Register a new configuration for this class.
|
| 1537 |
+
|
| 1538 |
+
Args:
|
| 1539 |
+
model_type (`str`): The model type like "bert" or "gpt".
|
| 1540 |
+
config ([`PreTrainedConfig`]): The config to register.
|
| 1541 |
+
"""
|
| 1542 |
+
if issubclass(config, PreTrainedConfig) and config.model_type != model_type:
|
| 1543 |
+
raise ValueError(
|
| 1544 |
+
"The config you are passing has a `model_type` attribute that is not consistent with the model type "
|
| 1545 |
+
f"you passed (config has {config.model_type} and you passed {model_type}. Fix one of those so they "
|
| 1546 |
+
"match!"
|
| 1547 |
+
)
|
| 1548 |
+
CONFIG_MAPPING.register(model_type, config, exist_ok=exist_ok)
|
| 1549 |
+
|
| 1550 |
+
|
| 1551 |
+
__all__ = ["CONFIG_MAPPING", "MODEL_NAMES_MAPPING", "AutoConfig"]
|
third_party/transformers/src/transformers/models/auto/feature_extraction_auto.py
ADDED
|
@@ -0,0 +1,386 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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 |
+
"""AutoFeatureExtractor class."""
|
| 15 |
+
|
| 16 |
+
import importlib
|
| 17 |
+
import os
|
| 18 |
+
from collections import OrderedDict
|
| 19 |
+
|
| 20 |
+
# Build the list of all feature extractors
|
| 21 |
+
from ...configuration_utils import PreTrainedConfig
|
| 22 |
+
from ...dynamic_module_utils import get_class_from_dynamic_module, resolve_trust_remote_code
|
| 23 |
+
from ...feature_extraction_utils import FeatureExtractionMixin
|
| 24 |
+
from ...utils import CONFIG_NAME, FEATURE_EXTRACTOR_NAME, PROCESSOR_NAME, cached_file, logging, safe_load_json_file
|
| 25 |
+
from .auto_factory import _LazyAutoMapping
|
| 26 |
+
from .configuration_auto import (
|
| 27 |
+
CONFIG_MAPPING_NAMES,
|
| 28 |
+
AutoConfig,
|
| 29 |
+
model_type_to_module_name,
|
| 30 |
+
replace_list_option_in_docstrings,
|
| 31 |
+
)
|
| 32 |
+
|
| 33 |
+
|
| 34 |
+
logger = logging.get_logger(__name__)
|
| 35 |
+
|
| 36 |
+
FEATURE_EXTRACTOR_MAPPING_NAMES = OrderedDict(
|
| 37 |
+
[
|
| 38 |
+
("audio-spectrogram-transformer", "ASTFeatureExtractor"),
|
| 39 |
+
("audioflamingo3", "WhisperFeatureExtractor"),
|
| 40 |
+
("clap", "ClapFeatureExtractor"),
|
| 41 |
+
("clvp", "ClvpFeatureExtractor"),
|
| 42 |
+
("cohere_asr", "CohereAsrFeatureExtractor"),
|
| 43 |
+
("csm", "EncodecFeatureExtractor"),
|
| 44 |
+
("dac", "DacFeatureExtractor"),
|
| 45 |
+
("data2vec-audio", "Wav2Vec2FeatureExtractor"),
|
| 46 |
+
("dia", "DiaFeatureExtractor"),
|
| 47 |
+
("encodec", "EncodecFeatureExtractor"),
|
| 48 |
+
("gemma3n", "Gemma3nAudioFeatureExtractor"),
|
| 49 |
+
("gemma4", "Gemma4AudioFeatureExtractor"),
|
| 50 |
+
("glmasr", "WhisperFeatureExtractor"),
|
| 51 |
+
("granite_speech", "GraniteSpeechFeatureExtractor"),
|
| 52 |
+
("higgs_audio_v2_tokenizer", "DacFeatureExtractor"),
|
| 53 |
+
("hubert", "Wav2Vec2FeatureExtractor"),
|
| 54 |
+
("kyutai_speech_to_text", "KyutaiSpeechToTextFeatureExtractor"),
|
| 55 |
+
("lasr_ctc", "LasrFeatureExtractor"),
|
| 56 |
+
("lasr_encoder", "LasrFeatureExtractor"),
|
| 57 |
+
("markuplm", "MarkupLMFeatureExtractor"),
|
| 58 |
+
("mimi", "EncodecFeatureExtractor"),
|
| 59 |
+
("moonshine", "Wav2Vec2FeatureExtractor"),
|
| 60 |
+
("moshi", "EncodecFeatureExtractor"),
|
| 61 |
+
("musicgen", "EncodecFeatureExtractor"),
|
| 62 |
+
("musicgen_melody", "MusicgenMelodyFeatureExtractor"),
|
| 63 |
+
("parakeet_ctc", "ParakeetFeatureExtractor"),
|
| 64 |
+
("parakeet_encoder", "ParakeetFeatureExtractor"),
|
| 65 |
+
("pe_audio", "PeAudioFeatureExtractor"),
|
| 66 |
+
("pe_audio_video", "PeAudioFeatureExtractor"),
|
| 67 |
+
("phi4_multimodal", "Phi4MultimodalFeatureExtractor"),
|
| 68 |
+
("pop2piano", "Pop2PianoFeatureExtractor"),
|
| 69 |
+
("qwen2_5_omni", "WhisperFeatureExtractor"),
|
| 70 |
+
("qwen2_audio", "WhisperFeatureExtractor"),
|
| 71 |
+
("qwen3_omni_moe", "WhisperFeatureExtractor"),
|
| 72 |
+
("seamless_m4t", "SeamlessM4TFeatureExtractor"),
|
| 73 |
+
("seamless_m4t_v2", "SeamlessM4TFeatureExtractor"),
|
| 74 |
+
("sew", "Wav2Vec2FeatureExtractor"),
|
| 75 |
+
("sew-d", "Wav2Vec2FeatureExtractor"),
|
| 76 |
+
("speech_to_text", "Speech2TextFeatureExtractor"),
|
| 77 |
+
("speecht5", "SpeechT5FeatureExtractor"),
|
| 78 |
+
("unispeech", "Wav2Vec2FeatureExtractor"),
|
| 79 |
+
("unispeech-sat", "Wav2Vec2FeatureExtractor"),
|
| 80 |
+
("univnet", "UnivNetFeatureExtractor"),
|
| 81 |
+
("vibevoice_acoustic_tokenizer", "VibeVoiceAcousticTokenizerFeatureExtractor"),
|
| 82 |
+
("vibevoice_asr", "VibeVoiceAcousticTokenizerFeatureExtractor"),
|
| 83 |
+
("voxtral", "WhisperFeatureExtractor"),
|
| 84 |
+
("voxtral_realtime", "VoxtralRealtimeFeatureExtractor"),
|
| 85 |
+
("wav2vec2", "Wav2Vec2FeatureExtractor"),
|
| 86 |
+
("wav2vec2-bert", "Wav2Vec2FeatureExtractor"),
|
| 87 |
+
("wav2vec2-conformer", "Wav2Vec2FeatureExtractor"),
|
| 88 |
+
("wavlm", "Wav2Vec2FeatureExtractor"),
|
| 89 |
+
("whisper", "WhisperFeatureExtractor"),
|
| 90 |
+
("xcodec", "DacFeatureExtractor"),
|
| 91 |
+
]
|
| 92 |
+
)
|
| 93 |
+
|
| 94 |
+
FEATURE_EXTRACTOR_MAPPING = _LazyAutoMapping(CONFIG_MAPPING_NAMES, FEATURE_EXTRACTOR_MAPPING_NAMES)
|
| 95 |
+
|
| 96 |
+
|
| 97 |
+
def feature_extractor_class_from_name(class_name: str):
|
| 98 |
+
for module_name, extractors in FEATURE_EXTRACTOR_MAPPING_NAMES.items():
|
| 99 |
+
if class_name in extractors:
|
| 100 |
+
module_name = model_type_to_module_name(module_name)
|
| 101 |
+
|
| 102 |
+
module = importlib.import_module(f".{module_name}", "transformers.models")
|
| 103 |
+
try:
|
| 104 |
+
return getattr(module, class_name)
|
| 105 |
+
except AttributeError:
|
| 106 |
+
continue
|
| 107 |
+
|
| 108 |
+
for extractor in FEATURE_EXTRACTOR_MAPPING._extra_content.values():
|
| 109 |
+
if getattr(extractor, "__name__", None) == class_name:
|
| 110 |
+
return extractor
|
| 111 |
+
|
| 112 |
+
# We did not find the class, but maybe it's because a dep is missing. In that case, the class will be in the main
|
| 113 |
+
# init and we return the proper dummy to get an appropriate error message.
|
| 114 |
+
main_module = importlib.import_module("transformers")
|
| 115 |
+
if hasattr(main_module, class_name):
|
| 116 |
+
return getattr(main_module, class_name)
|
| 117 |
+
|
| 118 |
+
return None
|
| 119 |
+
|
| 120 |
+
|
| 121 |
+
def get_feature_extractor_config(
|
| 122 |
+
pretrained_model_name_or_path: str | os.PathLike,
|
| 123 |
+
cache_dir: str | os.PathLike | None = None,
|
| 124 |
+
force_download: bool = False,
|
| 125 |
+
proxies: dict[str, str] | None = None,
|
| 126 |
+
token: bool | str | None = None,
|
| 127 |
+
revision: str | None = None,
|
| 128 |
+
local_files_only: bool = False,
|
| 129 |
+
**kwargs,
|
| 130 |
+
):
|
| 131 |
+
"""
|
| 132 |
+
Loads the feature extractor configuration from a pretrained model feature extractor configuration.
|
| 133 |
+
|
| 134 |
+
Args:
|
| 135 |
+
pretrained_model_name_or_path (`str` or `os.PathLike`):
|
| 136 |
+
This can be either:
|
| 137 |
+
|
| 138 |
+
- a string, the *model id* of a pretrained model configuration hosted inside a model repo on
|
| 139 |
+
huggingface.co.
|
| 140 |
+
- a path to a *directory* containing a configuration file saved using the
|
| 141 |
+
[`~FeatureExtractionMixin.save_pretrained`] method, e.g., `./my_model_directory/`.
|
| 142 |
+
|
| 143 |
+
cache_dir (`str` or `os.PathLike`, *optional*):
|
| 144 |
+
Path to a directory in which a downloaded pretrained model configuration should be cached if the standard
|
| 145 |
+
cache should not be used.
|
| 146 |
+
force_download (`bool`, *optional*, defaults to `False`):
|
| 147 |
+
Whether or not to force to (re-)download the configuration files and override the cached versions if they
|
| 148 |
+
exist.
|
| 149 |
+
proxies (`dict[str, str]`, *optional*):
|
| 150 |
+
A dictionary of proxy servers to use by protocol or endpoint, e.g., `{'http': 'foo.bar:3128',
|
| 151 |
+
'http://hostname': 'foo.bar:4012'}.` The proxies are used on each request.
|
| 152 |
+
token (`str` or *bool*, *optional*):
|
| 153 |
+
The token to use as HTTP bearer authorization for remote files. If `True`, will use the token generated
|
| 154 |
+
when running `hf auth login` (stored in `~/.huggingface`).
|
| 155 |
+
revision (`str`, *optional*, defaults to `"main"`):
|
| 156 |
+
The specific model version to use. It can be a branch name, a tag name, or a commit id, since we use a
|
| 157 |
+
git-based system for storing models and other artifacts on huggingface.co, so `revision` can be any
|
| 158 |
+
identifier allowed by git.
|
| 159 |
+
local_files_only (`bool`, *optional*, defaults to `False`):
|
| 160 |
+
If `True`, will only try to load the feature extractor configuration from local files.
|
| 161 |
+
|
| 162 |
+
<Tip>
|
| 163 |
+
|
| 164 |
+
Passing `token=True` is required when you want to use a private model.
|
| 165 |
+
|
| 166 |
+
</Tip>
|
| 167 |
+
|
| 168 |
+
Returns:
|
| 169 |
+
`Dict`: The configuration of the feature extractor.
|
| 170 |
+
|
| 171 |
+
Examples:
|
| 172 |
+
|
| 173 |
+
```python
|
| 174 |
+
# Download configuration from huggingface.co and cache.
|
| 175 |
+
feature_extractor_config = get_feature_extractor_config("facebook/wav2vec2-base-960h")
|
| 176 |
+
# This model does not have a feature extractor config so the result will be an empty dict.
|
| 177 |
+
feature_extractor_config = get_feature_extractor_config("FacebookAI/xlm-roberta-base")
|
| 178 |
+
|
| 179 |
+
# Save a pretrained feature extractor locally and you can reload its config
|
| 180 |
+
from transformers import AutoFeatureExtractor
|
| 181 |
+
|
| 182 |
+
feature_extractor = AutoFeatureExtractor.from_pretrained("facebook/wav2vec2-base-960h")
|
| 183 |
+
feature_extractor.save_pretrained("feature-extractor-test")
|
| 184 |
+
feature_extractor_config = get_feature_extractor_config("feature-extractor-test")
|
| 185 |
+
```"""
|
| 186 |
+
# Load with a priority given to the nested processor config, if available in repo
|
| 187 |
+
resolved_processor_file = cached_file(
|
| 188 |
+
pretrained_model_name_or_path,
|
| 189 |
+
filename=PROCESSOR_NAME,
|
| 190 |
+
cache_dir=cache_dir,
|
| 191 |
+
force_download=force_download,
|
| 192 |
+
proxies=proxies,
|
| 193 |
+
token=token,
|
| 194 |
+
revision=revision,
|
| 195 |
+
local_files_only=local_files_only,
|
| 196 |
+
_raise_exceptions_for_gated_repo=False,
|
| 197 |
+
_raise_exceptions_for_missing_entries=False,
|
| 198 |
+
)
|
| 199 |
+
resolved_feature_extractor_file = cached_file(
|
| 200 |
+
pretrained_model_name_or_path,
|
| 201 |
+
filename=FEATURE_EXTRACTOR_NAME,
|
| 202 |
+
cache_dir=cache_dir,
|
| 203 |
+
force_download=force_download,
|
| 204 |
+
proxies=proxies,
|
| 205 |
+
token=token,
|
| 206 |
+
revision=revision,
|
| 207 |
+
local_files_only=local_files_only,
|
| 208 |
+
_raise_exceptions_for_gated_repo=False,
|
| 209 |
+
_raise_exceptions_for_missing_entries=False,
|
| 210 |
+
)
|
| 211 |
+
|
| 212 |
+
# An empty list if none of the possible files is found in the repo
|
| 213 |
+
if not resolved_feature_extractor_file and not resolved_processor_file:
|
| 214 |
+
logger.info("Could not locate the feature extractor configuration file.")
|
| 215 |
+
return {}
|
| 216 |
+
|
| 217 |
+
# Load feature_extractor dict. Priority goes as (nested config if found -> feature extractor config)
|
| 218 |
+
# We are downloading both configs because almost all models have a `processor_config.json` but
|
| 219 |
+
# not all of these are nested. We need to check if it was saved recently as nested or if it is legacy style
|
| 220 |
+
feature_extractor_dict = {}
|
| 221 |
+
if resolved_processor_file is not None:
|
| 222 |
+
processor_dict = safe_load_json_file(resolved_processor_file)
|
| 223 |
+
if "feature_extractor" in processor_dict:
|
| 224 |
+
feature_extractor_dict = processor_dict["feature_extractor"]
|
| 225 |
+
|
| 226 |
+
if resolved_feature_extractor_file is not None and feature_extractor_dict is None:
|
| 227 |
+
feature_extractor_dict = safe_load_json_file(resolved_feature_extractor_file)
|
| 228 |
+
return feature_extractor_dict
|
| 229 |
+
|
| 230 |
+
|
| 231 |
+
class AutoFeatureExtractor:
|
| 232 |
+
r"""
|
| 233 |
+
This is a generic feature extractor class that will be instantiated as one of the feature extractor classes of the
|
| 234 |
+
library when created with the [`AutoFeatureExtractor.from_pretrained`] class method.
|
| 235 |
+
|
| 236 |
+
This class cannot be instantiated directly using `__init__()` (throws an error).
|
| 237 |
+
"""
|
| 238 |
+
|
| 239 |
+
def __init__(self):
|
| 240 |
+
raise OSError(
|
| 241 |
+
"AutoFeatureExtractor is designed to be instantiated "
|
| 242 |
+
"using the `AutoFeatureExtractor.from_pretrained(pretrained_model_name_or_path)` method."
|
| 243 |
+
)
|
| 244 |
+
|
| 245 |
+
@classmethod
|
| 246 |
+
@replace_list_option_in_docstrings(FEATURE_EXTRACTOR_MAPPING_NAMES)
|
| 247 |
+
def from_pretrained(cls, pretrained_model_name_or_path, **kwargs):
|
| 248 |
+
r"""
|
| 249 |
+
Instantiate one of the feature extractor classes of the library from a pretrained model vocabulary.
|
| 250 |
+
|
| 251 |
+
The feature extractor class to instantiate is selected based on the `model_type` property of the config object
|
| 252 |
+
(either passed as an argument or loaded from `pretrained_model_name_or_path` if possible), or when it's
|
| 253 |
+
missing, by falling back to using pattern matching on `pretrained_model_name_or_path`:
|
| 254 |
+
|
| 255 |
+
List options
|
| 256 |
+
|
| 257 |
+
Params:
|
| 258 |
+
pretrained_model_name_or_path (`str` or `os.PathLike`):
|
| 259 |
+
This can be either:
|
| 260 |
+
|
| 261 |
+
- a string, the *model id* of a pretrained feature_extractor hosted inside a model repo on
|
| 262 |
+
huggingface.co.
|
| 263 |
+
- a path to a *directory* containing a feature extractor file saved using the
|
| 264 |
+
[`~feature_extraction_utils.FeatureExtractionMixin.save_pretrained`] method, e.g.,
|
| 265 |
+
`./my_model_directory/`.
|
| 266 |
+
- a path to a saved feature extractor JSON *file*, e.g.,
|
| 267 |
+
`./my_model_directory/preprocessor_config.json`.
|
| 268 |
+
cache_dir (`str` or `os.PathLike`, *optional*):
|
| 269 |
+
Path to a directory in which a downloaded pretrained model feature extractor should be cached if the
|
| 270 |
+
standard cache should not be used.
|
| 271 |
+
force_download (`bool`, *optional*, defaults to `False`):
|
| 272 |
+
Whether or not to force to (re-)download the feature extractor files and override the cached versions
|
| 273 |
+
if they exist.
|
| 274 |
+
proxies (`dict[str, str]`, *optional*):
|
| 275 |
+
A dictionary of proxy servers to use by protocol or endpoint, e.g., `{'http': 'foo.bar:3128',
|
| 276 |
+
'http://hostname': 'foo.bar:4012'}.` The proxies are used on each request.
|
| 277 |
+
token (`str` or *bool*, *optional*):
|
| 278 |
+
The token to use as HTTP bearer authorization for remote files. If `True`, will use the token generated
|
| 279 |
+
when running `hf auth login` (stored in `~/.huggingface`).
|
| 280 |
+
revision (`str`, *optional*, defaults to `"main"`):
|
| 281 |
+
The specific model version to use. It can be a branch name, a tag name, or a commit id, since we use a
|
| 282 |
+
git-based system for storing models and other artifacts on huggingface.co, so `revision` can be any
|
| 283 |
+
identifier allowed by git.
|
| 284 |
+
return_unused_kwargs (`bool`, *optional*, defaults to `False`):
|
| 285 |
+
If `False`, then this function returns just the final feature extractor object. If `True`, then this
|
| 286 |
+
functions returns a `Tuple(feature_extractor, unused_kwargs)` where *unused_kwargs* is a dictionary
|
| 287 |
+
consisting of the key/value pairs whose keys are not feature extractor attributes: i.e., the part of
|
| 288 |
+
`kwargs` which has not been used to update `feature_extractor` and is otherwise ignored.
|
| 289 |
+
trust_remote_code (`bool`, *optional*, defaults to `False`):
|
| 290 |
+
Whether or not to allow for custom models defined on the Hub in their own modeling files. This option
|
| 291 |
+
should only be set to `True` for repositories you trust and in which you have read the code, as it will
|
| 292 |
+
execute code present on the Hub on your local machine.
|
| 293 |
+
kwargs (`dict[str, Any]`, *optional*):
|
| 294 |
+
The values in kwargs of any keys which are feature extractor attributes will be used to override the
|
| 295 |
+
loaded values. Behavior concerning key/value pairs whose keys are *not* feature extractor attributes is
|
| 296 |
+
controlled by the `return_unused_kwargs` keyword parameter.
|
| 297 |
+
|
| 298 |
+
<Tip>
|
| 299 |
+
|
| 300 |
+
Passing `token=True` is required when you want to use a private model.
|
| 301 |
+
|
| 302 |
+
</Tip>
|
| 303 |
+
|
| 304 |
+
Examples:
|
| 305 |
+
|
| 306 |
+
```python
|
| 307 |
+
>>> from transformers import AutoFeatureExtractor
|
| 308 |
+
|
| 309 |
+
>>> # Download feature extractor from huggingface.co and cache.
|
| 310 |
+
>>> feature_extractor = AutoFeatureExtractor.from_pretrained("facebook/wav2vec2-base-960h")
|
| 311 |
+
|
| 312 |
+
>>> # If feature extractor files are in a directory (e.g. feature extractor was saved using *save_pretrained('./test/saved_model/')*)
|
| 313 |
+
>>> # feature_extractor = AutoFeatureExtractor.from_pretrained("./test/saved_model/")
|
| 314 |
+
```"""
|
| 315 |
+
config = kwargs.pop("config", None)
|
| 316 |
+
trust_remote_code = kwargs.pop("trust_remote_code", None)
|
| 317 |
+
kwargs["_from_auto"] = True
|
| 318 |
+
|
| 319 |
+
config_dict, _ = FeatureExtractionMixin.get_feature_extractor_dict(pretrained_model_name_or_path, **kwargs)
|
| 320 |
+
feature_extractor_class = config_dict.get("feature_extractor_type", None)
|
| 321 |
+
feature_extractor_auto_map = None
|
| 322 |
+
if "AutoFeatureExtractor" in config_dict.get("auto_map", {}):
|
| 323 |
+
feature_extractor_auto_map = config_dict["auto_map"]["AutoFeatureExtractor"]
|
| 324 |
+
|
| 325 |
+
# If we don't find the feature extractor class in the feature extractor config, let's try the model config.
|
| 326 |
+
if feature_extractor_class is None and feature_extractor_auto_map is None:
|
| 327 |
+
if not isinstance(config, PreTrainedConfig):
|
| 328 |
+
config = AutoConfig.from_pretrained(
|
| 329 |
+
pretrained_model_name_or_path, trust_remote_code=trust_remote_code, **kwargs
|
| 330 |
+
)
|
| 331 |
+
# It could be in `config.feature_extractor_type``
|
| 332 |
+
feature_extractor_class = getattr(config, "feature_extractor_type", None)
|
| 333 |
+
if hasattr(config, "auto_map") and "AutoFeatureExtractor" in config.auto_map:
|
| 334 |
+
feature_extractor_auto_map = config.auto_map["AutoFeatureExtractor"]
|
| 335 |
+
|
| 336 |
+
if feature_extractor_class is not None:
|
| 337 |
+
feature_extractor_class = feature_extractor_class_from_name(feature_extractor_class)
|
| 338 |
+
|
| 339 |
+
has_remote_code = feature_extractor_auto_map is not None
|
| 340 |
+
has_local_code = feature_extractor_class is not None or type(config) in FEATURE_EXTRACTOR_MAPPING
|
| 341 |
+
explicit_local_code = has_local_code and not (
|
| 342 |
+
feature_extractor_class or FEATURE_EXTRACTOR_MAPPING[type(config)]
|
| 343 |
+
).__module__.startswith("transformers.")
|
| 344 |
+
if has_remote_code:
|
| 345 |
+
if "--" in feature_extractor_auto_map:
|
| 346 |
+
upstream_repo = feature_extractor_auto_map.split("--")[0]
|
| 347 |
+
else:
|
| 348 |
+
upstream_repo = None
|
| 349 |
+
trust_remote_code = resolve_trust_remote_code(
|
| 350 |
+
trust_remote_code, pretrained_model_name_or_path, has_local_code, has_remote_code, upstream_repo
|
| 351 |
+
)
|
| 352 |
+
|
| 353 |
+
if has_remote_code and trust_remote_code and not explicit_local_code:
|
| 354 |
+
feature_extractor_class = get_class_from_dynamic_module(
|
| 355 |
+
feature_extractor_auto_map, pretrained_model_name_or_path, **kwargs
|
| 356 |
+
)
|
| 357 |
+
_ = kwargs.pop("code_revision", None)
|
| 358 |
+
feature_extractor_class.register_for_auto_class()
|
| 359 |
+
return feature_extractor_class.from_pretrained(pretrained_model_name_or_path, **kwargs)
|
| 360 |
+
elif feature_extractor_class is not None:
|
| 361 |
+
return feature_extractor_class.from_pretrained(pretrained_model_name_or_path, **kwargs)
|
| 362 |
+
# Last try: we use the FEATURE_EXTRACTOR_MAPPING.
|
| 363 |
+
elif type(config) in FEATURE_EXTRACTOR_MAPPING:
|
| 364 |
+
feature_extractor_class = FEATURE_EXTRACTOR_MAPPING[type(config)]
|
| 365 |
+
return feature_extractor_class.from_pretrained(pretrained_model_name_or_path, **kwargs)
|
| 366 |
+
|
| 367 |
+
raise ValueError(
|
| 368 |
+
f"Unrecognized feature extractor in {pretrained_model_name_or_path}. Should have a "
|
| 369 |
+
f"`feature_extractor_type` key in its {FEATURE_EXTRACTOR_NAME} of {CONFIG_NAME}, or one of the following "
|
| 370 |
+
f"`model_type` keys in its {CONFIG_NAME}: {', '.join(c for c in FEATURE_EXTRACTOR_MAPPING_NAMES)}"
|
| 371 |
+
)
|
| 372 |
+
|
| 373 |
+
@staticmethod
|
| 374 |
+
def register(config_class, feature_extractor_class, exist_ok=False):
|
| 375 |
+
"""
|
| 376 |
+
Register a new feature extractor for this class.
|
| 377 |
+
|
| 378 |
+
Args:
|
| 379 |
+
config_class ([`PreTrainedConfig`]):
|
| 380 |
+
The configuration corresponding to the model to register.
|
| 381 |
+
feature_extractor_class ([`FeatureExtractorMixin`]): The feature extractor to register.
|
| 382 |
+
"""
|
| 383 |
+
FEATURE_EXTRACTOR_MAPPING.register(config_class, feature_extractor_class, exist_ok=exist_ok)
|
| 384 |
+
|
| 385 |
+
|
| 386 |
+
__all__ = ["FEATURE_EXTRACTOR_MAPPING", "AutoFeatureExtractor"]
|
third_party/transformers/src/transformers/models/auto/image_processing_auto.py
ADDED
|
@@ -0,0 +1,819 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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 |
+
"""AutoImageProcessor class."""
|
| 15 |
+
|
| 16 |
+
import importlib
|
| 17 |
+
import os
|
| 18 |
+
from collections import OrderedDict
|
| 19 |
+
from typing import TYPE_CHECKING
|
| 20 |
+
|
| 21 |
+
# Build the list of all image processors
|
| 22 |
+
from ...configuration_utils import PreTrainedConfig
|
| 23 |
+
from ...dynamic_module_utils import get_class_from_dynamic_module, resolve_trust_remote_code
|
| 24 |
+
from ...image_processing_utils import ImageProcessingMixin
|
| 25 |
+
from ...utils import (
|
| 26 |
+
CONFIG_NAME,
|
| 27 |
+
IMAGE_PROCESSOR_NAME,
|
| 28 |
+
PROCESSOR_NAME,
|
| 29 |
+
cached_file,
|
| 30 |
+
is_timm_config_dict,
|
| 31 |
+
is_timm_local_checkpoint,
|
| 32 |
+
is_torchvision_available,
|
| 33 |
+
logging,
|
| 34 |
+
safe_load_json_file,
|
| 35 |
+
)
|
| 36 |
+
from ...utils.import_utils import requires
|
| 37 |
+
from .auto_factory import _LazyAutoMapping
|
| 38 |
+
from .configuration_auto import (
|
| 39 |
+
CONFIG_MAPPING_NAMES,
|
| 40 |
+
AutoConfig,
|
| 41 |
+
model_type_to_module_name,
|
| 42 |
+
replace_list_option_in_docstrings,
|
| 43 |
+
)
|
| 44 |
+
|
| 45 |
+
|
| 46 |
+
logger = logging.get_logger(__name__)
|
| 47 |
+
|
| 48 |
+
# These image processors use Lanczos interpolation, which is not supported by fast image processors.
|
| 49 |
+
# To avoid important differences in outputs, we default to using the PIL backend for these processors.
|
| 50 |
+
DEFAULT_TO_PIL_BACKEND_IMAGE_PROCESSORS = [
|
| 51 |
+
"ChameleonImageProcessor",
|
| 52 |
+
"FlavaImageProcessor",
|
| 53 |
+
"Idefics3ImageProcessor",
|
| 54 |
+
"SmolVLMImageProcessor",
|
| 55 |
+
]
|
| 56 |
+
|
| 57 |
+
if TYPE_CHECKING:
|
| 58 |
+
# This significantly improves completion suggestion performance when
|
| 59 |
+
# the transformers package is used with Microsoft's Pylance language server.
|
| 60 |
+
IMAGE_PROCESSOR_MAPPING_NAMES: OrderedDict[str, dict[str, str | None]] = OrderedDict()
|
| 61 |
+
else:
|
| 62 |
+
IMAGE_PROCESSOR_MAPPING_NAMES = OrderedDict(
|
| 63 |
+
[
|
| 64 |
+
("aimv2", {"torchvision": "CLIPImageProcessor", "pil": "CLIPImageProcessorPil"}),
|
| 65 |
+
("aimv2_vision_model", {"torchvision": "CLIPImageProcessor", "pil": "CLIPImageProcessorPil"}),
|
| 66 |
+
("align", {"torchvision": "EfficientNetImageProcessor", "pil": "EfficientNetImageProcessorPil"}),
|
| 67 |
+
("altclip", {"torchvision": "CLIPImageProcessor", "pil": "CLIPImageProcessorPil"}),
|
| 68 |
+
("aria", {"torchvision": "AriaImageProcessor", "pil": "AriaImageProcessorPil"}),
|
| 69 |
+
("aya_vision", {"torchvision": "GotOcr2ImageProcessor", "pil": "GotOcr2ImageProcessorPil"}),
|
| 70 |
+
("beit", {"torchvision": "BeitImageProcessor", "pil": "BeitImageProcessorPil"}),
|
| 71 |
+
("bit", {"torchvision": "BitImageProcessor", "pil": "BitImageProcessorPil"}),
|
| 72 |
+
("blip", {"torchvision": "BlipImageProcessor", "pil": "BlipImageProcessorPil"}),
|
| 73 |
+
("blip-2", {"torchvision": "BlipImageProcessor", "pil": "BlipImageProcessorPil"}),
|
| 74 |
+
("bridgetower", {"torchvision": "BridgeTowerImageProcessor", "pil": "BridgeTowerImageProcessorPil"}),
|
| 75 |
+
("chameleon", {"torchvision": "ChameleonImageProcessor", "pil": "ChameleonImageProcessorPil"}),
|
| 76 |
+
("chinese_clip", {"torchvision": "ChineseCLIPImageProcessor", "pil": "ChineseCLIPImageProcessorPil"}),
|
| 77 |
+
("chmv2", {"torchvision": "CHMv2ImageProcessor"}),
|
| 78 |
+
("clip", {"torchvision": "CLIPImageProcessor", "pil": "CLIPImageProcessorPil"}),
|
| 79 |
+
("clipseg", {"torchvision": "ViTImageProcessor", "pil": "ViTImageProcessorPil"}),
|
| 80 |
+
("cohere2_vision", {"torchvision": "Cohere2VisionImageProcessor"}),
|
| 81 |
+
("colpali", {"torchvision": "SiglipImageProcessor", "pil": "SiglipImageProcessorPil"}),
|
| 82 |
+
("colqwen2", {"torchvision": "Qwen2VLImageProcessor", "pil": "Qwen2VLImageProcessorPil"}),
|
| 83 |
+
(
|
| 84 |
+
"conditional_detr",
|
| 85 |
+
{"torchvision": "ConditionalDetrImageProcessor", "pil": "ConditionalDetrImageProcessorPil"},
|
| 86 |
+
),
|
| 87 |
+
("convnext", {"torchvision": "ConvNextImageProcessor", "pil": "ConvNextImageProcessorPil"}),
|
| 88 |
+
("convnextv2", {"torchvision": "ConvNextImageProcessor", "pil": "ConvNextImageProcessorPil"}),
|
| 89 |
+
("cvt", {"torchvision": "ConvNextImageProcessor", "pil": "ConvNextImageProcessorPil"}),
|
| 90 |
+
("data2vec-vision", {"torchvision": "BeitImageProcessor", "pil": "BeitImageProcessorPil"}),
|
| 91 |
+
("deepseek_vl", {"torchvision": "DeepseekVLImageProcessor", "pil": "DeepseekVLImageProcessorPil"}),
|
| 92 |
+
(
|
| 93 |
+
"deepseek_vl_hybrid",
|
| 94 |
+
{"torchvision": "DeepseekVLHybridImageProcessor", "pil": "DeepseekVLHybridImageProcessorPil"},
|
| 95 |
+
),
|
| 96 |
+
(
|
| 97 |
+
"deformable_detr",
|
| 98 |
+
{"torchvision": "DeformableDetrImageProcessor", "pil": "DeformableDetrImageProcessorPil"},
|
| 99 |
+
),
|
| 100 |
+
("deit", {"torchvision": "DeiTImageProcessor", "pil": "DeiTImageProcessorPil"}),
|
| 101 |
+
("depth_anything", {"torchvision": "DPTImageProcessor", "pil": "DPTImageProcessorPil"}),
|
| 102 |
+
("depth_pro", {"torchvision": "DepthProImageProcessor"}),
|
| 103 |
+
("detr", {"torchvision": "DetrImageProcessor", "pil": "DetrImageProcessorPil"}),
|
| 104 |
+
("dinat", {"torchvision": "ViTImageProcessor", "pil": "ViTImageProcessorPil"}),
|
| 105 |
+
("dinov2", {"torchvision": "BitImageProcessor", "pil": "BitImageProcessorPil"}),
|
| 106 |
+
("dinov3_vit", {"torchvision": "DINOv3ViTImageProcessor"}),
|
| 107 |
+
("donut-swin", {"torchvision": "DonutImageProcessor", "pil": "DonutImageProcessorPil"}),
|
| 108 |
+
("dpt", {"torchvision": "DPTImageProcessor", "pil": "DPTImageProcessorPil"}),
|
| 109 |
+
("edgetam", {"torchvision": "Sam2ImageProcessor"}),
|
| 110 |
+
(
|
| 111 |
+
"efficientloftr",
|
| 112 |
+
{"torchvision": "EfficientLoFTRImageProcessor", "pil": "EfficientLoFTRImageProcessorPil"},
|
| 113 |
+
),
|
| 114 |
+
("efficientnet", {"torchvision": "EfficientNetImageProcessor", "pil": "EfficientNetImageProcessorPil"}),
|
| 115 |
+
("emu3", {"pil": "Emu3ImageProcessor"}),
|
| 116 |
+
("eomt", {"torchvision": "EomtImageProcessor", "pil": "EomtImageProcessorPil"}),
|
| 117 |
+
("eomt_dinov3", {"torchvision": "EomtImageProcessor", "pil": "EomtImageProcessorPil"}),
|
| 118 |
+
(
|
| 119 |
+
"ernie4_5_vl_moe",
|
| 120 |
+
{"torchvision": "Ernie4_5_VLMoeImageProcessor", "pil": "Ernie4_5_VLMoeImageProcessorPil"},
|
| 121 |
+
),
|
| 122 |
+
("flava", {"torchvision": "FlavaImageProcessor", "pil": "FlavaImageProcessorPil"}),
|
| 123 |
+
("florence2", {"torchvision": "CLIPImageProcessor", "pil": "CLIPImageProcessorPil"}),
|
| 124 |
+
("focalnet", {"torchvision": "BitImageProcessor", "pil": "BitImageProcessorPil"}),
|
| 125 |
+
("fuyu", {"torchvision": "FuyuImageProcessor", "pil": "FuyuImageProcessorPil"}),
|
| 126 |
+
("gemma3", {"torchvision": "Gemma3ImageProcessor", "pil": "Gemma3ImageProcessorPil"}),
|
| 127 |
+
("gemma3n", {"torchvision": "SiglipImageProcessor", "pil": "SiglipImageProcessorPil"}),
|
| 128 |
+
("gemma4", {"torchvision": "Gemma4ImageProcessor", "pil": "Gemma4ImageProcessorPil"}),
|
| 129 |
+
("git", {"torchvision": "CLIPImageProcessor", "pil": "CLIPImageProcessorPil"}),
|
| 130 |
+
("glm46v", {"torchvision": "Glm46VImageProcessor", "pil": "Glm46VImageProcessorPil"}),
|
| 131 |
+
("glm4v", {"torchvision": "Glm4vImageProcessor", "pil": "Glm4vImageProcessorPil"}),
|
| 132 |
+
("glm_image", {"torchvision": "GlmImageImageProcessor", "pil": "GlmImageImageProcessorPil"}),
|
| 133 |
+
("glpn", {"torchvision": "GLPNImageProcessor", "pil": "GLPNImageProcessorPil"}),
|
| 134 |
+
("got_ocr2", {"torchvision": "GotOcr2ImageProcessor", "pil": "GotOcr2ImageProcessorPil"}),
|
| 135 |
+
(
|
| 136 |
+
"grounding-dino",
|
| 137 |
+
{"torchvision": "GroundingDinoImageProcessor", "pil": "GroundingDinoImageProcessorPil"},
|
| 138 |
+
),
|
| 139 |
+
("groupvit", {"torchvision": "CLIPImageProcessor", "pil": "CLIPImageProcessorPil"}),
|
| 140 |
+
("hiera", {"torchvision": "BitImageProcessor", "pil": "BitImageProcessorPil"}),
|
| 141 |
+
("idefics", {"torchvision": "IdeficsImageProcessor", "pil": "IdeficsImageProcessorPil"}),
|
| 142 |
+
("idefics2", {"torchvision": "Idefics2ImageProcessor", "pil": "Idefics2ImageProcessorPil"}),
|
| 143 |
+
("idefics3", {"torchvision": "Idefics3ImageProcessor", "pil": "Idefics3ImageProcessorPil"}),
|
| 144 |
+
("ijepa", {"torchvision": "ViTImageProcessor", "pil": "ViTImageProcessorPil"}),
|
| 145 |
+
("imagegpt", {"torchvision": "ImageGPTImageProcessor", "pil": "ImageGPTImageProcessorPil"}),
|
| 146 |
+
("instructblip", {"torchvision": "BlipImageProcessor", "pil": "BlipImageProcessorPil"}),
|
| 147 |
+
("internvl", {"torchvision": "GotOcr2ImageProcessor", "pil": "GotOcr2ImageProcessorPil"}),
|
| 148 |
+
("janus", {"torchvision": "JanusImageProcessor", "pil": "JanusImageProcessorPil"}),
|
| 149 |
+
("kosmos-2", {"torchvision": "CLIPImageProcessor", "pil": "CLIPImageProcessorPil"}),
|
| 150 |
+
("kosmos-2.5", {"torchvision": "Kosmos2_5ImageProcessor", "pil": "Kosmos2_5ImageProcessorPil"}),
|
| 151 |
+
("layoutlmv2", {"torchvision": "LayoutLMv2ImageProcessor", "pil": "LayoutLMv2ImageProcessorPil"}),
|
| 152 |
+
("layoutlmv3", {"torchvision": "LayoutLMv3ImageProcessor", "pil": "LayoutLMv3ImageProcessorPil"}),
|
| 153 |
+
("layoutxlm", {"torchvision": "LayoutLMv2ImageProcessor", "pil": "LayoutLMv2ImageProcessorPil"}),
|
| 154 |
+
("levit", {"torchvision": "LevitImageProcessor", "pil": "LevitImageProcessorPil"}),
|
| 155 |
+
("lfm2_vl", {"torchvision": "Lfm2VlImageProcessor"}),
|
| 156 |
+
("lightglue", {"torchvision": "LightGlueImageProcessor", "pil": "LightGlueImageProcessorPil"}),
|
| 157 |
+
("lighton_ocr", {"torchvision": "PixtralImageProcessor", "pil": "PixtralImageProcessorPil"}),
|
| 158 |
+
("llama4", {"torchvision": "Llama4ImageProcessor"}),
|
| 159 |
+
("llava", {"torchvision": "LlavaImageProcessor", "pil": "LlavaImageProcessorPil"}),
|
| 160 |
+
("llava_next", {"torchvision": "LlavaNextImageProcessor", "pil": "LlavaNextImageProcessorPil"}),
|
| 161 |
+
("llava_next_video", {"torchvision": "LlavaNextImageProcessor", "pil": "LlavaNextImageProcessorPil"}),
|
| 162 |
+
(
|
| 163 |
+
"llava_onevision",
|
| 164 |
+
{"torchvision": "LlavaOnevisionImageProcessor", "pil": "LlavaOnevisionImageProcessorPil"},
|
| 165 |
+
),
|
| 166 |
+
("lw_detr", {"torchvision": "DeformableDetrImageProcessor", "pil": "DeformableDetrImageProcessorPil"}),
|
| 167 |
+
("mask2former", {"torchvision": "Mask2FormerImageProcessor", "pil": "Mask2FormerImageProcessorPil"}),
|
| 168 |
+
("maskformer", {"torchvision": "MaskFormerImageProcessor", "pil": "MaskFormerImageProcessorPil"}),
|
| 169 |
+
("metaclip_2", {"torchvision": "CLIPImageProcessor", "pil": "CLIPImageProcessorPil"}),
|
| 170 |
+
("mgp-str", {"torchvision": "ViTImageProcessor", "pil": "ViTImageProcessorPil"}),
|
| 171 |
+
("mistral3", {"torchvision": "PixtralImageProcessor", "pil": "PixtralImageProcessorPil"}),
|
| 172 |
+
("mlcd", {"torchvision": "CLIPImageProcessor", "pil": "CLIPImageProcessorPil"}),
|
| 173 |
+
("mllama", {"torchvision": "MllamaImageProcessor", "pil": "MllamaImageProcessorPil"}),
|
| 174 |
+
(
|
| 175 |
+
"mm-grounding-dino",
|
| 176 |
+
{"torchvision": "GroundingDinoImageProcessor", "pil": "GroundingDinoImageProcessorPil"},
|
| 177 |
+
),
|
| 178 |
+
("mobilenet_v1", {"torchvision": "MobileNetV1ImageProcessor", "pil": "MobileNetV1ImageProcessorPil"}),
|
| 179 |
+
("mobilenet_v2", {"torchvision": "MobileNetV2ImageProcessor", "pil": "MobileNetV2ImageProcessorPil"}),
|
| 180 |
+
("mobilevit", {"torchvision": "MobileViTImageProcessor", "pil": "MobileViTImageProcessorPil"}),
|
| 181 |
+
("mobilevitv2", {"torchvision": "MobileViTImageProcessor", "pil": "MobileViTImageProcessorPil"}),
|
| 182 |
+
("nougat", {"torchvision": "NougatImageProcessor", "pil": "NougatImageProcessorPil"}),
|
| 183 |
+
("omdet-turbo", {"torchvision": "DetrImageProcessor", "pil": "DetrImageProcessorPil"}),
|
| 184 |
+
("oneformer", {"torchvision": "OneFormerImageProcessor", "pil": "OneFormerImageProcessorPil"}),
|
| 185 |
+
("ovis2", {"torchvision": "Ovis2ImageProcessor", "pil": "Ovis2ImageProcessorPil"}),
|
| 186 |
+
("owlv2", {"torchvision": "Owlv2ImageProcessor", "pil": "Owlv2ImageProcessorPil"}),
|
| 187 |
+
("owlvit", {"torchvision": "OwlViTImageProcessor", "pil": "OwlViTImageProcessorPil"}),
|
| 188 |
+
("paddleocr_vl", {"torchvision": "PaddleOCRVLImageProcessor", "pil": "PaddleOCRVLImageProcessorPil"}),
|
| 189 |
+
("paligemma", {"torchvision": "SiglipImageProcessor", "pil": "SiglipImageProcessorPil"}),
|
| 190 |
+
("perceiver", {"torchvision": "PerceiverImageProcessor", "pil": "PerceiverImageProcessorPil"}),
|
| 191 |
+
("perception_lm", {"torchvision": "PerceptionLMImageProcessor"}),
|
| 192 |
+
("phi4_multimodal", {"torchvision": "Phi4MultimodalImageProcessor"}),
|
| 193 |
+
("pi0", {"torchvision": "PI0ImageProcessor"}),
|
| 194 |
+
("pix2struct", {"torchvision": "Pix2StructImageProcessor", "pil": "Pix2StructImageProcessorPil"}),
|
| 195 |
+
("pixio", {"torchvision": "BitImageProcessor", "pil": "BitImageProcessorPil"}),
|
| 196 |
+
("pixtral", {"torchvision": "PixtralImageProcessor", "pil": "PixtralImageProcessorPil"}),
|
| 197 |
+
("poolformer", {"torchvision": "PoolFormerImageProcessor", "pil": "PoolFormerImageProcessorPil"}),
|
| 198 |
+
(
|
| 199 |
+
"pp_chart2table",
|
| 200 |
+
{"torchvision": "PPChart2TableImageProcessor", "pil": "PPChart2TableImageProcessorPil"},
|
| 201 |
+
),
|
| 202 |
+
("pp_doclayout_v2", {"torchvision": "PPDocLayoutV2ImageProcessor"}),
|
| 203 |
+
("pp_doclayout_v3", {"torchvision": "PPDocLayoutV3ImageProcessor"}),
|
| 204 |
+
("pp_lcnet", {"torchvision": "PPLCNetImageProcessor"}),
|
| 205 |
+
("pp_ocrv5_mobile_det", {"torchvision": "PPOCRV5ServerDetImageProcessor"}),
|
| 206 |
+
("pp_ocrv5_mobile_rec", {"torchvision": "PPOCRV5ServerRecImageProcessor"}),
|
| 207 |
+
("pp_ocrv5_server_det", {"torchvision": "PPOCRV5ServerDetImageProcessor"}),
|
| 208 |
+
("pp_ocrv5_server_rec", {"torchvision": "PPOCRV5ServerRecImageProcessor"}),
|
| 209 |
+
(
|
| 210 |
+
"prompt_depth_anything",
|
| 211 |
+
{"torchvision": "PromptDepthAnythingImageProcessor", "pil": "PromptDepthAnythingImageProcessorPil"},
|
| 212 |
+
),
|
| 213 |
+
("pvt", {"torchvision": "PvtImageProcessor", "pil": "PvtImageProcessorPil"}),
|
| 214 |
+
("pvt_v2", {"torchvision": "PvtImageProcessor", "pil": "PvtImageProcessorPil"}),
|
| 215 |
+
("qwen2_5_omni", {"torchvision": "Qwen2VLImageProcessor", "pil": "Qwen2VLImageProcessorPil"}),
|
| 216 |
+
("qwen2_5_vl", {"torchvision": "Qwen2VLImageProcessor", "pil": "Qwen2VLImageProcessorPil"}),
|
| 217 |
+
("qwen2_vl", {"torchvision": "Qwen2VLImageProcessor", "pil": "Qwen2VLImageProcessorPil"}),
|
| 218 |
+
("qwen3_5", {"torchvision": "Qwen2VLImageProcessor", "pil": "Qwen2VLImageProcessorPil"}),
|
| 219 |
+
("qwen3_5_moe", {"torchvision": "Qwen2VLImageProcessor", "pil": "Qwen2VLImageProcessorPil"}),
|
| 220 |
+
("qwen3_omni_moe", {"torchvision": "Qwen2VLImageProcessor", "pil": "Qwen2VLImageProcessorPil"}),
|
| 221 |
+
("qwen3_vl", {"torchvision": "Qwen2VLImageProcessor", "pil": "Qwen2VLImageProcessorPil"}),
|
| 222 |
+
("regnet", {"torchvision": "ConvNextImageProcessor", "pil": "ConvNextImageProcessorPil"}),
|
| 223 |
+
("resnet", {"torchvision": "ConvNextImageProcessor", "pil": "ConvNextImageProcessorPil"}),
|
| 224 |
+
("rt_detr", {"torchvision": "RTDetrImageProcessor", "pil": "RTDetrImageProcessorPil"}),
|
| 225 |
+
("sam", {"torchvision": "SamImageProcessor", "pil": "SamImageProcessorPil"}),
|
| 226 |
+
("sam2", {"torchvision": "Sam2ImageProcessor"}),
|
| 227 |
+
("sam2_video", {"torchvision": "Sam2ImageProcessor"}),
|
| 228 |
+
("sam3", {"torchvision": "Sam3ImageProcessor"}),
|
| 229 |
+
("sam3_tracker", {"torchvision": "Sam3ImageProcessor"}),
|
| 230 |
+
("sam3_tracker_video", {"torchvision": "Sam3ImageProcessor"}),
|
| 231 |
+
("sam3_video", {"torchvision": "Sam3ImageProcessor"}),
|
| 232 |
+
("sam_hq", {"torchvision": "SamImageProcessor", "pil": "SamImageProcessorPil"}),
|
| 233 |
+
("segformer", {"torchvision": "SegformerImageProcessor", "pil": "SegformerImageProcessorPil"}),
|
| 234 |
+
("seggpt", {"torchvision": "SegGptImageProcessor", "pil": "SegGptImageProcessorPil"}),
|
| 235 |
+
("shieldgemma2", {"torchvision": "Gemma3ImageProcessor", "pil": "Gemma3ImageProcessorPil"}),
|
| 236 |
+
("siglip", {"torchvision": "SiglipImageProcessor", "pil": "SiglipImageProcessorPil"}),
|
| 237 |
+
("siglip2", {"torchvision": "Siglip2ImageProcessor", "pil": "Siglip2ImageProcessorPil"}),
|
| 238 |
+
("slanext", {"torchvision": "SLANeXtImageProcessor"}),
|
| 239 |
+
("smolvlm", {"torchvision": "SmolVLMImageProcessor", "pil": "SmolVLMImageProcessorPil"}),
|
| 240 |
+
("superglue", {"torchvision": "SuperGlueImageProcessor", "pil": "SuperGlueImageProcessorPil"}),
|
| 241 |
+
("superpoint", {"torchvision": "SuperPointImageProcessor", "pil": "SuperPointImageProcessorPil"}),
|
| 242 |
+
("swiftformer", {"torchvision": "ViTImageProcessor", "pil": "ViTImageProcessorPil"}),
|
| 243 |
+
("swin", {"torchvision": "ViTImageProcessor", "pil": "ViTImageProcessorPil"}),
|
| 244 |
+
("swin2sr", {"torchvision": "Swin2SRImageProcessor", "pil": "Swin2SRImageProcessorPil"}),
|
| 245 |
+
("swinv2", {"torchvision": "ViTImageProcessor", "pil": "ViTImageProcessorPil"}),
|
| 246 |
+
("t5gemma2", {"torchvision": "Gemma3ImageProcessor", "pil": "Gemma3ImageProcessorPil"}),
|
| 247 |
+
("t5gemma2_encoder", {"torchvision": "Gemma3ImageProcessor", "pil": "Gemma3ImageProcessorPil"}),
|
| 248 |
+
("table-transformer", {"torchvision": "DetrImageProcessor", "pil": "DetrImageProcessorPil"}),
|
| 249 |
+
("textnet", {"torchvision": "TextNetImageProcessor", "pil": "TextNetImageProcessorPil"}),
|
| 250 |
+
("timesformer", {"pil": "VideoMAEImageProcessorPil", "torchvision": "VideoMAEImageProcessor"}),
|
| 251 |
+
("timm_wrapper", {"pil": "TimmWrapperImageProcessor"}),
|
| 252 |
+
("trocr", {"torchvision": "ViTImageProcessor", "pil": "ViTImageProcessorPil"}),
|
| 253 |
+
("tvp", {"torchvision": "TvpImageProcessor", "pil": "TvpImageProcessorPil"}),
|
| 254 |
+
("udop", {"torchvision": "LayoutLMv3ImageProcessor", "pil": "LayoutLMv3ImageProcessorPil"}),
|
| 255 |
+
("upernet", {"torchvision": "SegformerImageProcessor", "pil": "SegformerImageProcessorPil"}),
|
| 256 |
+
("uvdoc", {"torchvision": "UVDocImageProcessor"}),
|
| 257 |
+
("video_llama_3", {"torchvision": "VideoLlama3ImageProcessor", "pil": "VideoLlama3ImageProcessorPil"}),
|
| 258 |
+
("video_llava", {"pil": "VideoLlavaImageProcessor"}),
|
| 259 |
+
("videomae", {"torchvision": "VideoMAEImageProcessor", "pil": "VideoMAEImageProcessorPil"}),
|
| 260 |
+
("vilt", {"torchvision": "ViltImageProcessor", "pil": "ViltImageProcessorPil"}),
|
| 261 |
+
("vipllava", {"torchvision": "CLIPImageProcessor", "pil": "CLIPImageProcessorPil"}),
|
| 262 |
+
("vit", {"torchvision": "ViTImageProcessor", "pil": "ViTImageProcessorPil"}),
|
| 263 |
+
("vit_mae", {"torchvision": "ViTImageProcessor", "pil": "ViTImageProcessorPil"}),
|
| 264 |
+
("vit_msn", {"torchvision": "ViTImageProcessor", "pil": "ViTImageProcessorPil"}),
|
| 265 |
+
("vitmatte", {"torchvision": "VitMatteImageProcessor", "pil": "VitMatteImageProcessorPil"}),
|
| 266 |
+
("vitpose", {"torchvision": "VitPoseImageProcessor", "pil": "VitPoseImageProcessorPil"}),
|
| 267 |
+
("vivit", {"torchvision": "VivitImageProcessor"}),
|
| 268 |
+
("xclip", {"torchvision": "CLIPImageProcessor", "pil": "CLIPImageProcessorPil"}),
|
| 269 |
+
("yolos", {"torchvision": "YolosImageProcessor", "pil": "YolosImageProcessorPil"}),
|
| 270 |
+
("zoedepth", {"torchvision": "ZoeDepthImageProcessor", "pil": "ZoeDepthImageProcessorPil"}),
|
| 271 |
+
]
|
| 272 |
+
)
|
| 273 |
+
|
| 274 |
+
IMAGE_PROCESSOR_MAPPING = _LazyAutoMapping(CONFIG_MAPPING_NAMES, IMAGE_PROCESSOR_MAPPING_NAMES)
|
| 275 |
+
|
| 276 |
+
|
| 277 |
+
def get_image_processor_class_from_name(class_name: str):
|
| 278 |
+
"""Resolve an image processor class name to its class. Handles both base names (e.g. CLIPImageProcessor)
|
| 279 |
+
and PIL backend names (e.g. CLIPImageProcessorPil). No recursion needed since names are direct."""
|
| 280 |
+
if class_name == "BaseImageProcessorFast":
|
| 281 |
+
# kept for backward compatibility - return TorchvisionBackend
|
| 282 |
+
from ...image_processing_backends import TorchvisionBackend
|
| 283 |
+
|
| 284 |
+
return TorchvisionBackend
|
| 285 |
+
|
| 286 |
+
# First, check registered extra content (user-registered classes)
|
| 287 |
+
for mapping in IMAGE_PROCESSOR_MAPPING._extra_content.values():
|
| 288 |
+
for extractor_class in mapping.values():
|
| 289 |
+
if isinstance(extractor_class, type) and getattr(extractor_class, "__name__", None) == class_name:
|
| 290 |
+
return extractor_class
|
| 291 |
+
|
| 292 |
+
# Check the mapping names - class names are either base (torchvision) or base+Pil (pil)
|
| 293 |
+
for model_type, extractors_dict in IMAGE_PROCESSOR_MAPPING_NAMES.items():
|
| 294 |
+
if class_name in extractors_dict.values():
|
| 295 |
+
module_name = model_type_to_module_name(model_type)
|
| 296 |
+
module = importlib.import_module(f".{module_name}", "transformers.models")
|
| 297 |
+
try:
|
| 298 |
+
return getattr(module, class_name)
|
| 299 |
+
except AttributeError:
|
| 300 |
+
continue
|
| 301 |
+
|
| 302 |
+
# Fallback: class may be in main init (e.g. when dep is missing, returns dummy)
|
| 303 |
+
main_module = importlib.import_module("transformers")
|
| 304 |
+
if hasattr(main_module, class_name):
|
| 305 |
+
return getattr(main_module, class_name)
|
| 306 |
+
|
| 307 |
+
return None
|
| 308 |
+
|
| 309 |
+
|
| 310 |
+
def get_image_processor_config(
|
| 311 |
+
pretrained_model_name_or_path: str | os.PathLike,
|
| 312 |
+
cache_dir: str | os.PathLike | None = None,
|
| 313 |
+
force_download: bool = False,
|
| 314 |
+
proxies: dict[str, str] | None = None,
|
| 315 |
+
token: bool | str | None = None,
|
| 316 |
+
revision: str | None = None,
|
| 317 |
+
local_files_only: bool = False,
|
| 318 |
+
**kwargs,
|
| 319 |
+
):
|
| 320 |
+
"""
|
| 321 |
+
Loads the image processor configuration from a pretrained model image processor configuration.
|
| 322 |
+
|
| 323 |
+
Args:
|
| 324 |
+
pretrained_model_name_or_path (`str` or `os.PathLike`):
|
| 325 |
+
This can be either:
|
| 326 |
+
|
| 327 |
+
- a string, the *model id* of a pretrained model configuration hosted inside a model repo on
|
| 328 |
+
huggingface.co.
|
| 329 |
+
- a path to a *directory* containing a configuration file saved using the
|
| 330 |
+
[`~ProcessorMixin.save_pretrained`] method, e.g., `./my_model_directory/`.
|
| 331 |
+
|
| 332 |
+
cache_dir (`str` or `os.PathLike`, *optional*):
|
| 333 |
+
Path to a directory in which a downloaded pretrained model configuration should be cached if the standard
|
| 334 |
+
cache should not be used.
|
| 335 |
+
force_download (`bool`, *optional*, defaults to `False`):
|
| 336 |
+
Whether or not to force to (re-)download the configuration files and override the cached versions if they
|
| 337 |
+
exist.
|
| 338 |
+
proxies (`dict[str, str]`, *optional*):
|
| 339 |
+
A dictionary of proxy servers to use by protocol or endpoint, e.g., `{'http': 'foo.bar:3128',
|
| 340 |
+
'http://hostname': 'foo.bar:4012'}.` The proxies are used on each request.
|
| 341 |
+
token (`str` or *bool*, *optional*):
|
| 342 |
+
The token to use as HTTP bearer authorization for remote files. If `True`, will use the token generated
|
| 343 |
+
when running `hf auth login` (stored in `~/.huggingface`).
|
| 344 |
+
revision (`str`, *optional*, defaults to `"main"`):
|
| 345 |
+
The specific model version to use. It can be a branch name, a tag name, or a commit id, since we use a
|
| 346 |
+
git-based system for storing models and other artifacts on huggingface.co, so `revision` can be any
|
| 347 |
+
identifier allowed by git.
|
| 348 |
+
local_files_only (`bool`, *optional*, defaults to `False`):
|
| 349 |
+
If `True`, will only try to load the image processor configuration from local files.
|
| 350 |
+
|
| 351 |
+
<Tip>
|
| 352 |
+
|
| 353 |
+
Passing `token=True` is required when you want to use a private model.
|
| 354 |
+
|
| 355 |
+
</Tip>
|
| 356 |
+
|
| 357 |
+
Returns:
|
| 358 |
+
`Dict`: The configuration of the image processor.
|
| 359 |
+
|
| 360 |
+
Examples:
|
| 361 |
+
|
| 362 |
+
```python
|
| 363 |
+
# Download configuration from huggingface.co and cache.
|
| 364 |
+
image_processor_config = get_image_processor_config("google-bert/bert-base-uncased")
|
| 365 |
+
# This model does not have a image processor config so the result will be an empty dict.
|
| 366 |
+
image_processor_config = get_image_processor_config("FacebookAI/xlm-roberta-base")
|
| 367 |
+
|
| 368 |
+
# Save a pretrained image processor locally and you can reload its config
|
| 369 |
+
from transformers import AutoImageProcessor
|
| 370 |
+
|
| 371 |
+
image_processor = AutoImageProcessor.from_pretrained("google/vit-base-patch16-224-in21k")
|
| 372 |
+
image_processor.save_pretrained("image-processor-test")
|
| 373 |
+
image_processor_config = get_image_processor_config("image-processor-test")
|
| 374 |
+
```"""
|
| 375 |
+
# Load with a priority given to the nested processor config, if available in repo
|
| 376 |
+
resolved_processor_file = cached_file(
|
| 377 |
+
pretrained_model_name_or_path,
|
| 378 |
+
filename=PROCESSOR_NAME,
|
| 379 |
+
cache_dir=cache_dir,
|
| 380 |
+
force_download=force_download,
|
| 381 |
+
proxies=proxies,
|
| 382 |
+
token=token,
|
| 383 |
+
revision=revision,
|
| 384 |
+
local_files_only=local_files_only,
|
| 385 |
+
_raise_exceptions_for_gated_repo=False,
|
| 386 |
+
_raise_exceptions_for_missing_entries=False,
|
| 387 |
+
)
|
| 388 |
+
resolved_image_processor_file = cached_file(
|
| 389 |
+
pretrained_model_name_or_path,
|
| 390 |
+
filename=IMAGE_PROCESSOR_NAME,
|
| 391 |
+
cache_dir=cache_dir,
|
| 392 |
+
force_download=force_download,
|
| 393 |
+
proxies=proxies,
|
| 394 |
+
token=token,
|
| 395 |
+
revision=revision,
|
| 396 |
+
local_files_only=local_files_only,
|
| 397 |
+
_raise_exceptions_for_gated_repo=False,
|
| 398 |
+
_raise_exceptions_for_missing_entries=False,
|
| 399 |
+
)
|
| 400 |
+
|
| 401 |
+
# An empty list if none of the possible files is found in the repo
|
| 402 |
+
if not resolved_image_processor_file and not resolved_processor_file:
|
| 403 |
+
logger.info("Could not locate the image processor configuration file.")
|
| 404 |
+
return {}
|
| 405 |
+
|
| 406 |
+
# Load image_processor dict. Priority goes as (nested config if found -> image processor config)
|
| 407 |
+
# We are downloading both configs because almost all models have a `processor_config.json` but
|
| 408 |
+
# not all of these are nested. We need to check if it was saved recently as nested or if it is legacy style
|
| 409 |
+
image_processor_dict = {}
|
| 410 |
+
if resolved_processor_file is not None:
|
| 411 |
+
processor_dict = safe_load_json_file(resolved_processor_file)
|
| 412 |
+
if "image_processor" in processor_dict:
|
| 413 |
+
image_processor_dict = processor_dict["image_processor"]
|
| 414 |
+
|
| 415 |
+
if resolved_image_processor_file is not None and image_processor_dict is None:
|
| 416 |
+
image_processor_dict = safe_load_json_file(resolved_image_processor_file)
|
| 417 |
+
|
| 418 |
+
return image_processor_dict
|
| 419 |
+
|
| 420 |
+
|
| 421 |
+
def _resolve_backend(backend: str | None, use_fast: bool | None, base_class_name: str | None) -> str:
|
| 422 |
+
"""Resolve raw backend inputs to a concrete backend name ('torchvision' or 'pil').
|
| 423 |
+
|
| 424 |
+
Handles, in order:
|
| 425 |
+
- Deprecated ``use_fast`` flag: warns and converts to an explicit backend string when no
|
| 426 |
+
explicit backend is given.
|
| 427 |
+
- Explicit backend string: returned as-is.
|
| 428 |
+
- None resolution: forces 'pil' for processors in DEFAULT_TO_PIL_BACKEND_IMAGE_PROCESSORS
|
| 429 |
+
(Lanczos interpolation, unsupported by torchvision); otherwise picks 'torchvision' when
|
| 430 |
+
available, falling back to 'pil'.
|
| 431 |
+
"""
|
| 432 |
+
if use_fast is not None:
|
| 433 |
+
logger.warning_once(
|
| 434 |
+
"The `use_fast` parameter is deprecated and will be removed in a future version. "
|
| 435 |
+
'Use `backend="torchvision"` instead of `use_fast=True`, or `backend="pil"` instead of `use_fast=False`.'
|
| 436 |
+
)
|
| 437 |
+
if backend is None:
|
| 438 |
+
backend = "torchvision" if use_fast else "pil"
|
| 439 |
+
|
| 440 |
+
if backend is None:
|
| 441 |
+
if base_class_name in DEFAULT_TO_PIL_BACKEND_IMAGE_PROCESSORS:
|
| 442 |
+
return "pil"
|
| 443 |
+
return "torchvision" if is_torchvision_available() else "pil"
|
| 444 |
+
|
| 445 |
+
return backend
|
| 446 |
+
|
| 447 |
+
|
| 448 |
+
def _load_class_with_fallback(mapping, backend):
|
| 449 |
+
"""
|
| 450 |
+
Load an image processor class from a backend-to-class mapping, with fallback.
|
| 451 |
+
|
| 452 |
+
Tries the requested backend first, then the opposite standard backend,
|
| 453 |
+
then any remaining backends. Works with both string class names and resolved class objects.
|
| 454 |
+
|
| 455 |
+
Unavailable backends are detected via DummyObject: classes whose required libraries are missing
|
| 456 |
+
are represented as DummyObject subclasses (is_dummy=True). When the torchvision backend is
|
| 457 |
+
missing but a PIL variant exists, _LazyModule transparently returns the PIL class with its own
|
| 458 |
+
warning, so _load_class_with_fallback naturally receives a usable class without extra gating.
|
| 459 |
+
|
| 460 |
+
Args:
|
| 461 |
+
mapping: dict mapping backend names (str) to class names (str) or class objects (type).
|
| 462 |
+
backend: the preferred backend name (e.g. "torchvision", "pil").
|
| 463 |
+
|
| 464 |
+
Returns:
|
| 465 |
+
The loaded class, or None if no class could be loaded.
|
| 466 |
+
"""
|
| 467 |
+
backends_to_try = [backend] + [k for k in mapping if k != backend]
|
| 468 |
+
|
| 469 |
+
for b in backends_to_try:
|
| 470 |
+
value = mapping.get(b)
|
| 471 |
+
if value is None:
|
| 472 |
+
continue
|
| 473 |
+
|
| 474 |
+
# Value can be a class object (from resolved mapping) or a string class name
|
| 475 |
+
if isinstance(value, type):
|
| 476 |
+
processor_class = value
|
| 477 |
+
else:
|
| 478 |
+
processor_class = get_image_processor_class_from_name(value)
|
| 479 |
+
|
| 480 |
+
if processor_class is None or getattr(processor_class, "is_dummy", False):
|
| 481 |
+
continue
|
| 482 |
+
|
| 483 |
+
if b != backend:
|
| 484 |
+
logger.warning_once(f"Requested {backend} backend is not available. Falling back to {b} backend.")
|
| 485 |
+
return processor_class
|
| 486 |
+
|
| 487 |
+
return None
|
| 488 |
+
|
| 489 |
+
|
| 490 |
+
def _find_mapping_for_image_processor(base_class_name: str) -> dict | None:
|
| 491 |
+
"""
|
| 492 |
+
Find the backend->class mapping that contains base_class_name in its values.
|
| 493 |
+
Returns the mapping dict (including any custom registered backends) or None.
|
| 494 |
+
"""
|
| 495 |
+
|
| 496 |
+
def _value_matches(val, name: str) -> bool:
|
| 497 |
+
if val is None:
|
| 498 |
+
return False
|
| 499 |
+
if isinstance(val, str):
|
| 500 |
+
return val == name
|
| 501 |
+
if isinstance(val, type):
|
| 502 |
+
return getattr(val, "__name__", None) == name
|
| 503 |
+
return False
|
| 504 |
+
|
| 505 |
+
for mapping_dict in IMAGE_PROCESSOR_MAPPING_NAMES.values():
|
| 506 |
+
if any(_value_matches(v, base_class_name) for v in mapping_dict.values()):
|
| 507 |
+
return mapping_dict
|
| 508 |
+
|
| 509 |
+
for content in IMAGE_PROCESSOR_MAPPING._extra_content.values():
|
| 510 |
+
if any(_value_matches(v, base_class_name) for v in content.values()):
|
| 511 |
+
return content
|
| 512 |
+
|
| 513 |
+
return None
|
| 514 |
+
|
| 515 |
+
|
| 516 |
+
def _load_backend_class(base_class_name, backend, is_legacy_fast=False):
|
| 517 |
+
"""
|
| 518 |
+
Load image processor class for a given backend. Uses the mapping from
|
| 519 |
+
IMAGE_PROCESSOR_MAPPING when base_class_name is found in its values (so config
|
| 520 |
+
overrides and custom backends are respected). Falls back to base+Pil convention
|
| 521 |
+
for remote code / unknown processors.
|
| 522 |
+
"""
|
| 523 |
+
mapping = _find_mapping_for_image_processor(base_class_name)
|
| 524 |
+
if mapping is None:
|
| 525 |
+
mapping = {
|
| 526 |
+
"torchvision": base_class_name,
|
| 527 |
+
"pil": base_class_name + "Pil",
|
| 528 |
+
}
|
| 529 |
+
processor_class = _load_class_with_fallback(mapping, backend)
|
| 530 |
+
|
| 531 |
+
# For legacy Fast classes, try the original Fast class name as last resort
|
| 532 |
+
if processor_class is None and is_legacy_fast:
|
| 533 |
+
processor_class = get_image_processor_class_from_name(base_class_name + "Fast")
|
| 534 |
+
|
| 535 |
+
return processor_class
|
| 536 |
+
|
| 537 |
+
|
| 538 |
+
def _resolve_auto_map_class_ref(auto_map, backend):
|
| 539 |
+
"""Extract the class reference string from an auto_map entry based on backend preference.
|
| 540 |
+
|
| 541 |
+
Returns:
|
| 542 |
+
A string that may be:
|
| 543 |
+
- A simple class name (e.g. `"MyImageProcessor"`)
|
| 544 |
+
- A Hub reference in the form `upstream_repo--path/to/file.py::ClassName`, where the part before
|
| 545 |
+
`--` is the upstream repo ID (used for trust_remote_code resolution).
|
| 546 |
+
"""
|
| 547 |
+
if isinstance(auto_map, dict):
|
| 548 |
+
return auto_map.get(backend) or next(iter(auto_map.values()))
|
| 549 |
+
if isinstance(auto_map, (list, tuple)):
|
| 550 |
+
if backend == "torchvision" and len(auto_map) > 1 and auto_map[1] is not None:
|
| 551 |
+
return auto_map[1]
|
| 552 |
+
return auto_map[0]
|
| 553 |
+
# Single string (legacy)
|
| 554 |
+
return auto_map
|
| 555 |
+
|
| 556 |
+
|
| 557 |
+
@requires(backends=("vision",))
|
| 558 |
+
class AutoImageProcessor:
|
| 559 |
+
r"""
|
| 560 |
+
This is a generic image processor class that will be instantiated as one of the image processor classes of the
|
| 561 |
+
library when created with the [`AutoImageProcessor.from_pretrained`] class method.
|
| 562 |
+
|
| 563 |
+
This class cannot be instantiated directly using `__init__()` (throws an error).
|
| 564 |
+
"""
|
| 565 |
+
|
| 566 |
+
def __init__(self):
|
| 567 |
+
raise OSError(
|
| 568 |
+
"AutoImageProcessor is designed to be instantiated "
|
| 569 |
+
"using the `AutoImageProcessor.from_pretrained(pretrained_model_name_or_path)` method."
|
| 570 |
+
)
|
| 571 |
+
|
| 572 |
+
@classmethod
|
| 573 |
+
@replace_list_option_in_docstrings(IMAGE_PROCESSOR_MAPPING_NAMES)
|
| 574 |
+
def from_pretrained(cls, pretrained_model_name_or_path, *inputs, **kwargs):
|
| 575 |
+
r"""
|
| 576 |
+
Instantiate one of the image processor classes of the library from a pretrained model vocabulary.
|
| 577 |
+
|
| 578 |
+
The image processor class to instantiate is selected based on the `model_type` property of the config object
|
| 579 |
+
(either passed as an argument or loaded from `pretrained_model_name_or_path` if possible), or when it's
|
| 580 |
+
missing, by falling back to using pattern matching on `pretrained_model_name_or_path`:
|
| 581 |
+
|
| 582 |
+
List options
|
| 583 |
+
|
| 584 |
+
Params:
|
| 585 |
+
pretrained_model_name_or_path (`str` or `os.PathLike`):
|
| 586 |
+
This can be either:
|
| 587 |
+
|
| 588 |
+
- a string, the *model id* of a pretrained image_processor hosted inside a model repo on
|
| 589 |
+
huggingface.co.
|
| 590 |
+
- a path to a *directory* containing a image processor file saved using the
|
| 591 |
+
[`~image_processing_utils.ImageProcessingMixin.save_pretrained`] method, e.g.,
|
| 592 |
+
`./my_model_directory/`.
|
| 593 |
+
- a path to a saved image processor JSON *file*, e.g.,
|
| 594 |
+
`./my_model_directory/preprocessor_config.json`.
|
| 595 |
+
cache_dir (`str` or `os.PathLike`, *optional*):
|
| 596 |
+
Path to a directory in which a downloaded pretrained model image processor should be cached if the
|
| 597 |
+
standard cache should not be used.
|
| 598 |
+
force_download (`bool`, *optional*, defaults to `False`):
|
| 599 |
+
Whether or not to force to (re-)download the image processor files and override the cached versions if
|
| 600 |
+
they exist.
|
| 601 |
+
proxies (`dict[str, str]`, *optional*):
|
| 602 |
+
A dictionary of proxy servers to use by protocol or endpoint, e.g., `{'http': 'foo.bar:3128',
|
| 603 |
+
'http://hostname': 'foo.bar:4012'}.` The proxies are used on each request.
|
| 604 |
+
token (`str` or *bool*, *optional*):
|
| 605 |
+
The token to use as HTTP bearer authorization for remote files. If `True`, will use the token generated
|
| 606 |
+
when running `hf auth login` (stored in `~/.huggingface`).
|
| 607 |
+
revision (`str`, *optional*, defaults to `"main"`):
|
| 608 |
+
The specific model version to use. It can be a branch name, a tag name, or a commit id, since we use a
|
| 609 |
+
git-based system for storing models and other artifacts on huggingface.co, so `revision` can be any
|
| 610 |
+
identifier allowed by git.
|
| 611 |
+
use_fast (`bool`, *optional*, defaults to `False`):
|
| 612 |
+
**Deprecated**: Use `backend="torchvision"` instead. This parameter is kept for backward compatibility.
|
| 613 |
+
Use a fast torchvision-based image processor if it is supported for a given model.
|
| 614 |
+
If a fast image processor is not available for a given model, a normal numpy-based image processor
|
| 615 |
+
is returned instead.
|
| 616 |
+
backend (`str`, *optional*, defaults to `None`):
|
| 617 |
+
The backend to use for image processing. Can be:
|
| 618 |
+
- `None`: Automatically select the best available backend (torchvision if available, otherwise pil)
|
| 619 |
+
- `"torchvision"`: Use Torchvision backend (GPU-accelerated, faster)
|
| 620 |
+
- `"pil"`: Use PIL backend (portable, CPU-only)
|
| 621 |
+
- Any custom backend name registered via `register()` method
|
| 622 |
+
return_unused_kwargs (`bool`, *optional*, defaults to `False`):
|
| 623 |
+
If `False`, then this function returns just the final image processor object. If `True`, then this
|
| 624 |
+
functions returns a `Tuple(image_processor, unused_kwargs)` where *unused_kwargs* is a dictionary
|
| 625 |
+
consisting of the key/value pairs whose keys are not image processor attributes: i.e., the part of
|
| 626 |
+
`kwargs` which has not been used to update `image_processor` and is otherwise ignored.
|
| 627 |
+
trust_remote_code (`bool`, *optional*, defaults to `False`):
|
| 628 |
+
Whether or not to allow for custom models defined on the Hub in their own modeling files. This option
|
| 629 |
+
should only be set to `True` for repositories you trust and in which you have read the code, as it will
|
| 630 |
+
execute code present on the Hub on your local machine.
|
| 631 |
+
image_processor_filename (`str`, *optional*, defaults to `"config.json"`):
|
| 632 |
+
The name of the file in the model directory to use for the image processor config.
|
| 633 |
+
kwargs (`dict[str, Any]`, *optional*):
|
| 634 |
+
The values in kwargs of any keys which are image processor attributes will be used to override the
|
| 635 |
+
loaded values. Behavior concerning key/value pairs whose keys are *not* image processor attributes is
|
| 636 |
+
controlled by the `return_unused_kwargs` keyword parameter.
|
| 637 |
+
|
| 638 |
+
<Tip>
|
| 639 |
+
|
| 640 |
+
Passing `token=True` is required when you want to use a private model.
|
| 641 |
+
|
| 642 |
+
</Tip>
|
| 643 |
+
|
| 644 |
+
Examples:
|
| 645 |
+
|
| 646 |
+
```python
|
| 647 |
+
>>> from transformers import AutoImageProcessor
|
| 648 |
+
|
| 649 |
+
>>> # Download image processor from huggingface.co and cache.
|
| 650 |
+
>>> image_processor = AutoImageProcessor.from_pretrained("google/vit-base-patch16-224-in21k")
|
| 651 |
+
|
| 652 |
+
>>> # If image processor files are in a directory (e.g. image processor was saved using *save_pretrained('./test/saved_model/')*)
|
| 653 |
+
>>> # image_processor = AutoImageProcessor.from_pretrained("./test/saved_model/")
|
| 654 |
+
```"""
|
| 655 |
+
config = kwargs.pop("config", None)
|
| 656 |
+
use_fast = kwargs.pop("use_fast", None)
|
| 657 |
+
backend_kwarg = kwargs.pop("backend", None)
|
| 658 |
+
trust_remote_code = kwargs.pop("trust_remote_code", None)
|
| 659 |
+
kwargs["_from_auto"] = True
|
| 660 |
+
|
| 661 |
+
# Resolve the image processor config filename
|
| 662 |
+
if "image_processor_filename" in kwargs:
|
| 663 |
+
image_processor_filename = kwargs.pop("image_processor_filename")
|
| 664 |
+
elif is_timm_local_checkpoint(pretrained_model_name_or_path):
|
| 665 |
+
image_processor_filename = CONFIG_NAME
|
| 666 |
+
else:
|
| 667 |
+
image_processor_filename = IMAGE_PROCESSOR_NAME
|
| 668 |
+
|
| 669 |
+
# Load the image processor config
|
| 670 |
+
|
| 671 |
+
try:
|
| 672 |
+
config_dict, _ = ImageProcessingMixin.get_image_processor_dict(
|
| 673 |
+
pretrained_model_name_or_path, image_processor_filename=image_processor_filename, **kwargs
|
| 674 |
+
)
|
| 675 |
+
except Exception as initial_exception:
|
| 676 |
+
# Fallback for Hub TimmWrapper checkpoints (image processing in config.json, not preprocessor_config.json)
|
| 677 |
+
try:
|
| 678 |
+
config_dict, _ = ImageProcessingMixin.get_image_processor_dict(
|
| 679 |
+
pretrained_model_name_or_path, image_processor_filename=CONFIG_NAME, **kwargs
|
| 680 |
+
)
|
| 681 |
+
except Exception:
|
| 682 |
+
raise initial_exception
|
| 683 |
+
|
| 684 |
+
if not is_timm_config_dict(config_dict):
|
| 685 |
+
raise initial_exception
|
| 686 |
+
|
| 687 |
+
image_processor_type = config_dict.get("image_processor_type", None)
|
| 688 |
+
image_processor_auto_map = None
|
| 689 |
+
if "AutoImageProcessor" in config_dict.get("auto_map", {}):
|
| 690 |
+
image_processor_auto_map = config_dict["auto_map"]["AutoImageProcessor"]
|
| 691 |
+
|
| 692 |
+
# Backward compat: infer from feature extractor config
|
| 693 |
+
if image_processor_type is None and image_processor_auto_map is None:
|
| 694 |
+
feature_extractor_class = config_dict.pop("feature_extractor_type", None)
|
| 695 |
+
if feature_extractor_class is not None:
|
| 696 |
+
image_processor_type = feature_extractor_class.replace("FeatureExtractor", "ImageProcessor")
|
| 697 |
+
if "AutoFeatureExtractor" in config_dict.get("auto_map", {}):
|
| 698 |
+
feature_extractor_auto_map = config_dict["auto_map"]["AutoFeatureExtractor"]
|
| 699 |
+
image_processor_auto_map = feature_extractor_auto_map.replace("FeatureExtractor", "ImageProcessor")
|
| 700 |
+
|
| 701 |
+
# If not in image processor config, try the model config
|
| 702 |
+
if image_processor_type is None and image_processor_auto_map is None:
|
| 703 |
+
if not isinstance(config, PreTrainedConfig):
|
| 704 |
+
config = AutoConfig.from_pretrained(
|
| 705 |
+
pretrained_model_name_or_path,
|
| 706 |
+
trust_remote_code=trust_remote_code,
|
| 707 |
+
**kwargs,
|
| 708 |
+
)
|
| 709 |
+
image_processor_type = getattr(config, "image_processor_type", None)
|
| 710 |
+
if hasattr(config, "auto_map") and "AutoImageProcessor" in config.auto_map:
|
| 711 |
+
image_processor_auto_map = config.auto_map["AutoImageProcessor"]
|
| 712 |
+
|
| 713 |
+
# Derive base_class_name from image_processor_type
|
| 714 |
+
is_legacy_fast = False
|
| 715 |
+
base_class_name = None
|
| 716 |
+
if image_processor_type is not None:
|
| 717 |
+
is_legacy_fast = image_processor_type.endswith("Fast")
|
| 718 |
+
base_class_name = image_processor_type[:-4] if is_legacy_fast else image_processor_type
|
| 719 |
+
|
| 720 |
+
backend = _resolve_backend(backend_kwarg, use_fast, base_class_name)
|
| 721 |
+
|
| 722 |
+
image_processor_class = None
|
| 723 |
+
if base_class_name is not None:
|
| 724 |
+
image_processor_class = _load_backend_class(base_class_name, backend, is_legacy_fast)
|
| 725 |
+
|
| 726 |
+
# Handle remote code
|
| 727 |
+
has_remote_code = image_processor_auto_map is not None
|
| 728 |
+
has_local_code = image_processor_class is not None or type(config) in IMAGE_PROCESSOR_MAPPING
|
| 729 |
+
explicit_local_code = has_local_code and not (
|
| 730 |
+
image_processor_class or _load_class_with_fallback(IMAGE_PROCESSOR_MAPPING[type(config)], backend)
|
| 731 |
+
).__module__.startswith("transformers.")
|
| 732 |
+
if has_remote_code:
|
| 733 |
+
class_ref = _resolve_auto_map_class_ref(image_processor_auto_map, backend)
|
| 734 |
+
upstream_repo = class_ref.split("--")[0] if "--" in class_ref else None
|
| 735 |
+
trust_remote_code = resolve_trust_remote_code(
|
| 736 |
+
trust_remote_code, pretrained_model_name_or_path, has_local_code, has_remote_code, upstream_repo
|
| 737 |
+
)
|
| 738 |
+
|
| 739 |
+
if has_remote_code and trust_remote_code and not explicit_local_code:
|
| 740 |
+
image_processor_class = get_class_from_dynamic_module(class_ref, pretrained_model_name_or_path, **kwargs)
|
| 741 |
+
_ = kwargs.pop("code_revision", None)
|
| 742 |
+
image_processor_class.register_for_auto_class()
|
| 743 |
+
return image_processor_class.from_pretrained(pretrained_model_name_or_path, *inputs, **kwargs)
|
| 744 |
+
elif image_processor_class is not None:
|
| 745 |
+
return image_processor_class.from_pretrained(pretrained_model_name_or_path, *inputs, **kwargs)
|
| 746 |
+
# Last try: we use the IMAGE_PROCESSOR_MAPPING.
|
| 747 |
+
elif type(config) in IMAGE_PROCESSOR_MAPPING:
|
| 748 |
+
image_processor_mapping = IMAGE_PROCESSOR_MAPPING[type(config)]
|
| 749 |
+
image_processor_class = _load_class_with_fallback(image_processor_mapping, backend)
|
| 750 |
+
|
| 751 |
+
if image_processor_class is not None:
|
| 752 |
+
return image_processor_class.from_pretrained(pretrained_model_name_or_path, *inputs, **kwargs)
|
| 753 |
+
|
| 754 |
+
available = [k for k, v in image_processor_mapping.items() if v is not None]
|
| 755 |
+
raise ValueError(f"Could not find image processor class. Available backends: {', '.join(available)}")
|
| 756 |
+
raise ValueError(
|
| 757 |
+
f"Unrecognized image processor in {pretrained_model_name_or_path}. Should have a "
|
| 758 |
+
f"`image_processor_type` key in its {IMAGE_PROCESSOR_NAME} of {CONFIG_NAME}, or one of the following "
|
| 759 |
+
f"`model_type` keys in its {CONFIG_NAME}: {', '.join(c for c in IMAGE_PROCESSOR_MAPPING_NAMES)}"
|
| 760 |
+
)
|
| 761 |
+
|
| 762 |
+
@staticmethod
|
| 763 |
+
def register(
|
| 764 |
+
config_class,
|
| 765 |
+
slow_image_processor_class: type | None = None,
|
| 766 |
+
fast_image_processor_class: type | None = None,
|
| 767 |
+
image_processor_classes: dict[str, type] | None = None,
|
| 768 |
+
exist_ok: bool = False,
|
| 769 |
+
):
|
| 770 |
+
"""
|
| 771 |
+
Register a new image processor for this class.
|
| 772 |
+
|
| 773 |
+
Args:
|
| 774 |
+
config_class ([`PreTrainedConfig`]):
|
| 775 |
+
The configuration corresponding to the model to register.
|
| 776 |
+
slow_image_processor_class (`type`, *optional*):
|
| 777 |
+
The PIL backend image processor class (deprecated, use `image_processor_classes={"pil": ...}`).
|
| 778 |
+
fast_image_processor_class (`type`, *optional*):
|
| 779 |
+
The Torchvision backend image processor class (deprecated, use `image_processor_classes={"torchvision": ...}`).
|
| 780 |
+
image_processor_classes (`dict[str, type]`, *optional*):
|
| 781 |
+
Dictionary mapping backend names to image processor classes. Allows registering custom backends.
|
| 782 |
+
Example: `{"pil": MyPilProcessor, "torchvision": MyTorchvisionProcessor, "custom": MyCustomProcessor}`
|
| 783 |
+
exist_ok (`bool`, *optional*, defaults to `False`):
|
| 784 |
+
If `True`, allow overwriting existing registrations.
|
| 785 |
+
"""
|
| 786 |
+
# Handle backward compatibility: convert old parameters to new format
|
| 787 |
+
if image_processor_classes is None:
|
| 788 |
+
image_processor_classes = {}
|
| 789 |
+
if slow_image_processor_class is not None:
|
| 790 |
+
image_processor_classes["pil"] = slow_image_processor_class
|
| 791 |
+
if fast_image_processor_class is not None:
|
| 792 |
+
image_processor_classes["torchvision"] = fast_image_processor_class
|
| 793 |
+
|
| 794 |
+
if not image_processor_classes:
|
| 795 |
+
raise ValueError(
|
| 796 |
+
"You need to specify at least one image processor class. "
|
| 797 |
+
"Use `image_processor_classes={'backend_name': ProcessorClass}` or the deprecated "
|
| 798 |
+
"`slow_image_processor_class`/`fast_image_processor_class` parameters."
|
| 799 |
+
)
|
| 800 |
+
|
| 801 |
+
# Avoid resetting existing processors if we are passing partial updates
|
| 802 |
+
if config_class in IMAGE_PROCESSOR_MAPPING._extra_content:
|
| 803 |
+
existing_mapping = IMAGE_PROCESSOR_MAPPING[config_class]
|
| 804 |
+
existing_mapping.update(image_processor_classes)
|
| 805 |
+
image_processor_classes = existing_mapping
|
| 806 |
+
|
| 807 |
+
# Validate that all classes are proper image processor classes
|
| 808 |
+
from ...image_processing_utils import BaseImageProcessor
|
| 809 |
+
|
| 810 |
+
for backend_key, processor_class in image_processor_classes.items():
|
| 811 |
+
if processor_class is not None and not issubclass(processor_class, BaseImageProcessor):
|
| 812 |
+
raise ValueError(
|
| 813 |
+
f"Image processor class for backend '{backend_key}' must inherit from `BaseImageProcessor`. "
|
| 814 |
+
f"Got: {processor_class}"
|
| 815 |
+
)
|
| 816 |
+
IMAGE_PROCESSOR_MAPPING.register(config_class, image_processor_classes, exist_ok=exist_ok)
|
| 817 |
+
|
| 818 |
+
|
| 819 |
+
__all__ = ["IMAGE_PROCESSOR_MAPPING", "AutoImageProcessor"]
|
third_party/transformers/src/transformers/models/auto/modeling_auto.py
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
third_party/transformers/src/transformers/models/auto/processing_auto.py
ADDED
|
@@ -0,0 +1,465 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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 |
+
"""AutoProcessor class."""
|
| 15 |
+
|
| 16 |
+
import importlib
|
| 17 |
+
import json
|
| 18 |
+
from collections import OrderedDict
|
| 19 |
+
from typing import TYPE_CHECKING
|
| 20 |
+
|
| 21 |
+
# Build the list of all feature extractors
|
| 22 |
+
from ...configuration_utils import PreTrainedConfig
|
| 23 |
+
from ...dynamic_module_utils import get_class_from_dynamic_module, resolve_trust_remote_code
|
| 24 |
+
from ...feature_extraction_utils import FeatureExtractionMixin
|
| 25 |
+
from ...image_processing_utils import ImageProcessingMixin
|
| 26 |
+
from ...processing_utils import ProcessorMixin
|
| 27 |
+
from ...tokenization_python import TOKENIZER_CONFIG_FILE
|
| 28 |
+
from ...utils import FEATURE_EXTRACTOR_NAME, PROCESSOR_NAME, VIDEO_PROCESSOR_NAME, cached_file, logging
|
| 29 |
+
from ...video_processing_utils import BaseVideoProcessor
|
| 30 |
+
from .auto_factory import _LazyAutoMapping
|
| 31 |
+
from .configuration_auto import (
|
| 32 |
+
CONFIG_MAPPING_NAMES,
|
| 33 |
+
AutoConfig,
|
| 34 |
+
model_type_to_module_name,
|
| 35 |
+
replace_list_option_in_docstrings,
|
| 36 |
+
)
|
| 37 |
+
from .feature_extraction_auto import AutoFeatureExtractor
|
| 38 |
+
from .image_processing_auto import AutoImageProcessor
|
| 39 |
+
from .tokenization_auto import AutoTokenizer
|
| 40 |
+
from .video_processing_auto import AutoVideoProcessor
|
| 41 |
+
|
| 42 |
+
|
| 43 |
+
logger = logging.get_logger(__name__)
|
| 44 |
+
if TYPE_CHECKING:
|
| 45 |
+
# This significantly improves completion suggestion performance when
|
| 46 |
+
# the transformers package is used with Microsoft's Pylance language server.
|
| 47 |
+
PROCESSOR_MAPPING_NAMES: OrderedDict[str, str | None] = OrderedDict()
|
| 48 |
+
else:
|
| 49 |
+
PROCESSOR_MAPPING_NAMES = OrderedDict(
|
| 50 |
+
[
|
| 51 |
+
("aimv2", "CLIPProcessor"),
|
| 52 |
+
("align", "AlignProcessor"),
|
| 53 |
+
("altclip", "AltCLIPProcessor"),
|
| 54 |
+
("aria", "AriaProcessor"),
|
| 55 |
+
("audioflamingo3", "AudioFlamingo3Processor"),
|
| 56 |
+
("aya_vision", "AyaVisionProcessor"),
|
| 57 |
+
("bark", "BarkProcessor"),
|
| 58 |
+
("blip", "BlipProcessor"),
|
| 59 |
+
("blip-2", "Blip2Processor"),
|
| 60 |
+
("bridgetower", "BridgeTowerProcessor"),
|
| 61 |
+
("chameleon", "ChameleonProcessor"),
|
| 62 |
+
("chinese_clip", "ChineseCLIPProcessor"),
|
| 63 |
+
("clap", "ClapProcessor"),
|
| 64 |
+
("clip", "CLIPProcessor"),
|
| 65 |
+
("clipseg", "CLIPSegProcessor"),
|
| 66 |
+
("clvp", "ClvpProcessor"),
|
| 67 |
+
("cohere2_vision", "Cohere2VisionProcessor"),
|
| 68 |
+
("cohere_asr", "CohereAsrProcessor"),
|
| 69 |
+
("colmodernvbert", "ColModernVBertProcessor"),
|
| 70 |
+
("colpali", "ColPaliProcessor"),
|
| 71 |
+
("colqwen2", "ColQwen2Processor"),
|
| 72 |
+
("deepseek_vl", "DeepseekVLProcessor"),
|
| 73 |
+
("deepseek_vl_hybrid", "DeepseekVLHybridProcessor"),
|
| 74 |
+
("dia", "DiaProcessor"),
|
| 75 |
+
("edgetam", "Sam2Processor"),
|
| 76 |
+
("emu3", "Emu3Processor"),
|
| 77 |
+
("ernie4_5_vl_moe", "Ernie4_5_VLMoeProcessor"),
|
| 78 |
+
("evolla", "EvollaProcessor"),
|
| 79 |
+
("flava", "FlavaProcessor"),
|
| 80 |
+
("florence2", "Florence2Processor"),
|
| 81 |
+
("fuyu", "FuyuProcessor"),
|
| 82 |
+
("gemma3", "Gemma3Processor"),
|
| 83 |
+
("gemma3n", "Gemma3nProcessor"),
|
| 84 |
+
("gemma4", "Gemma4Processor"),
|
| 85 |
+
("git", "GitProcessor"),
|
| 86 |
+
("glm46v", "Glm46VProcessor"),
|
| 87 |
+
("glm4v", "Glm4vProcessor"),
|
| 88 |
+
("glm4v_moe", "Glm4vProcessor"),
|
| 89 |
+
("glm_image", "Glm4vProcessor"),
|
| 90 |
+
("glmasr", "GlmAsrProcessor"),
|
| 91 |
+
("got_ocr2", "GotOcr2Processor"),
|
| 92 |
+
("granite_speech", "GraniteSpeechProcessor"),
|
| 93 |
+
("grounding-dino", "GroundingDinoProcessor"),
|
| 94 |
+
("groupvit", "CLIPProcessor"),
|
| 95 |
+
("higgs_audio_v2", "HiggsAudioV2Processor"),
|
| 96 |
+
("hubert", "Wav2Vec2Processor"),
|
| 97 |
+
("idefics", "IdeficsProcessor"),
|
| 98 |
+
("idefics2", "Idefics2Processor"),
|
| 99 |
+
("idefics3", "Idefics3Processor"),
|
| 100 |
+
("instructblip", "InstructBlipProcessor"),
|
| 101 |
+
("instructblipvideo", "InstructBlipVideoProcessor"),
|
| 102 |
+
("internvl", "InternVLProcessor"),
|
| 103 |
+
("janus", "JanusProcessor"),
|
| 104 |
+
("kosmos-2", "Kosmos2Processor"),
|
| 105 |
+
("kosmos-2.5", "Kosmos2_5Processor"),
|
| 106 |
+
("kyutai_speech_to_text", "KyutaiSpeechToTextProcessor"),
|
| 107 |
+
("lasr_ctc", "LasrProcessor"),
|
| 108 |
+
("lasr_encoder", "LasrProcessor"),
|
| 109 |
+
("layoutlmv2", "LayoutLMv2Processor"),
|
| 110 |
+
("layoutlmv3", "LayoutLMv3Processor"),
|
| 111 |
+
("layoutxlm", "LayoutXLMProcessor"),
|
| 112 |
+
("lfm2_vl", "Lfm2VlProcessor"),
|
| 113 |
+
("lighton_ocr", "LightOnOcrProcessor"),
|
| 114 |
+
("llama4", "Llama4Processor"),
|
| 115 |
+
("llava", "LlavaProcessor"),
|
| 116 |
+
("llava_next", "LlavaNextProcessor"),
|
| 117 |
+
("llava_next_video", "LlavaNextVideoProcessor"),
|
| 118 |
+
("llava_onevision", "LlavaOnevisionProcessor"),
|
| 119 |
+
("markuplm", "MarkupLMProcessor"),
|
| 120 |
+
("metaclip_2", "CLIPProcessor"),
|
| 121 |
+
("mgp-str", "MgpstrProcessor"),
|
| 122 |
+
("mistral3", "PixtralProcessor"),
|
| 123 |
+
("mllama", "MllamaProcessor"),
|
| 124 |
+
("mm-grounding-dino", "GroundingDinoProcessor"),
|
| 125 |
+
("modernvbert", "Idefics3Processor"),
|
| 126 |
+
("moonshine", "Wav2Vec2Processor"),
|
| 127 |
+
("moonshine_streaming", "MoonshineStreamingProcessor"),
|
| 128 |
+
("musicflamingo", "MusicFlamingoProcessor"),
|
| 129 |
+
("omdet-turbo", "OmDetTurboProcessor"),
|
| 130 |
+
("oneformer", "OneFormerProcessor"),
|
| 131 |
+
("ovis2", "Ovis2Processor"),
|
| 132 |
+
("owlv2", "Owlv2Processor"),
|
| 133 |
+
("owlvit", "OwlViTProcessor"),
|
| 134 |
+
("paddleocr_vl", "PaddleOCRVLProcessor"),
|
| 135 |
+
("paligemma", "PaliGemmaProcessor"),
|
| 136 |
+
("perception_lm", "PerceptionLMProcessor"),
|
| 137 |
+
("phi4_multimodal", "Phi4MultimodalProcessor"),
|
| 138 |
+
("pi0", "PI0Processor"),
|
| 139 |
+
("pix2struct", "Pix2StructProcessor"),
|
| 140 |
+
("pixtral", "PixtralProcessor"),
|
| 141 |
+
("pop2piano", "Pop2PianoProcessor"),
|
| 142 |
+
("pp_chart2table", "PPChart2TableProcessor"),
|
| 143 |
+
("qwen2_5_omni", "Qwen2_5OmniProcessor"),
|
| 144 |
+
("qwen2_5_vl", "Qwen2_5_VLProcessor"),
|
| 145 |
+
("qwen2_audio", "Qwen2AudioProcessor"),
|
| 146 |
+
("qwen2_vl", "Qwen2VLProcessor"),
|
| 147 |
+
("qwen3_5", "Qwen3VLProcessor"),
|
| 148 |
+
("qwen3_5_moe", "Qwen3VLProcessor"),
|
| 149 |
+
("qwen3_omni_moe", "Qwen3OmniMoeProcessor"),
|
| 150 |
+
("qwen3_vl", "Qwen3VLProcessor"),
|
| 151 |
+
("qwen3_vl_moe", "Qwen3VLProcessor"),
|
| 152 |
+
("sam", "SamProcessor"),
|
| 153 |
+
("sam2", "Sam2Processor"),
|
| 154 |
+
("sam3", "Sam3Processor"),
|
| 155 |
+
("sam_hq", "SamHQProcessor"),
|
| 156 |
+
("seamless_m4t", "SeamlessM4TProcessor"),
|
| 157 |
+
("sew", "Wav2Vec2Processor"),
|
| 158 |
+
("sew-d", "Wav2Vec2Processor"),
|
| 159 |
+
("shieldgemma2", "ShieldGemma2Processor"),
|
| 160 |
+
("siglip", "SiglipProcessor"),
|
| 161 |
+
("siglip2", "Siglip2Processor"),
|
| 162 |
+
("smolvlm", "SmolVLMProcessor"),
|
| 163 |
+
("speech_to_text", "Speech2TextProcessor"),
|
| 164 |
+
("speecht5", "SpeechT5Processor"),
|
| 165 |
+
("t5gemma2", "Gemma3Processor"),
|
| 166 |
+
("t5gemma2_encoder", "Gemma3Processor"),
|
| 167 |
+
("trocr", "TrOCRProcessor"),
|
| 168 |
+
("tvp", "TvpProcessor"),
|
| 169 |
+
("udop", "UdopProcessor"),
|
| 170 |
+
("unispeech", "Wav2Vec2Processor"),
|
| 171 |
+
("unispeech-sat", "Wav2Vec2Processor"),
|
| 172 |
+
("vibevoice_asr", "VibeVoiceAsrProcessor"),
|
| 173 |
+
("video_llava", "VideoLlavaProcessor"),
|
| 174 |
+
("vilt", "ViltProcessor"),
|
| 175 |
+
("vipllava", "LlavaProcessor"),
|
| 176 |
+
("vision-text-dual-encoder", "VisionTextDualEncoderProcessor"),
|
| 177 |
+
("voxtral", "VoxtralProcessor"),
|
| 178 |
+
("voxtral_realtime", "VoxtralRealtimeProcessor"),
|
| 179 |
+
("wav2vec2", "Wav2Vec2Processor"),
|
| 180 |
+
("wav2vec2-bert", "Wav2Vec2Processor"),
|
| 181 |
+
("wav2vec2-conformer", "Wav2Vec2Processor"),
|
| 182 |
+
("wavlm", "Wav2Vec2Processor"),
|
| 183 |
+
("whisper", "WhisperProcessor"),
|
| 184 |
+
("xclip", "XCLIPProcessor"),
|
| 185 |
+
]
|
| 186 |
+
)
|
| 187 |
+
|
| 188 |
+
PROCESSOR_MAPPING = _LazyAutoMapping(CONFIG_MAPPING_NAMES, PROCESSOR_MAPPING_NAMES)
|
| 189 |
+
|
| 190 |
+
|
| 191 |
+
def processor_class_from_name(class_name: str):
|
| 192 |
+
for module_name, processors in PROCESSOR_MAPPING_NAMES.items():
|
| 193 |
+
if class_name in processors:
|
| 194 |
+
module_name = model_type_to_module_name(module_name)
|
| 195 |
+
|
| 196 |
+
module = importlib.import_module(f".{module_name}", "transformers.models")
|
| 197 |
+
try:
|
| 198 |
+
return getattr(module, class_name)
|
| 199 |
+
except AttributeError:
|
| 200 |
+
continue
|
| 201 |
+
|
| 202 |
+
for processor in PROCESSOR_MAPPING._extra_content.values():
|
| 203 |
+
if getattr(processor, "__name__", None) == class_name:
|
| 204 |
+
return processor
|
| 205 |
+
|
| 206 |
+
# We did not find the class, but maybe it's because a dep is missing. In that case, the class will be in the main
|
| 207 |
+
# init and we return the proper dummy to get an appropriate error message.
|
| 208 |
+
main_module = importlib.import_module("transformers")
|
| 209 |
+
if hasattr(main_module, class_name):
|
| 210 |
+
return getattr(main_module, class_name)
|
| 211 |
+
|
| 212 |
+
return None
|
| 213 |
+
|
| 214 |
+
|
| 215 |
+
class AutoProcessor:
|
| 216 |
+
r"""
|
| 217 |
+
This is a generic processor class that will be instantiated as one of the processor classes of the library when
|
| 218 |
+
created with the [`AutoProcessor.from_pretrained`] class method.
|
| 219 |
+
|
| 220 |
+
This class cannot be instantiated directly using `__init__()` (throws an error).
|
| 221 |
+
"""
|
| 222 |
+
|
| 223 |
+
def __init__(self):
|
| 224 |
+
raise OSError(
|
| 225 |
+
"AutoProcessor is designed to be instantiated "
|
| 226 |
+
"using the `AutoProcessor.from_pretrained(pretrained_model_name_or_path)` method."
|
| 227 |
+
)
|
| 228 |
+
|
| 229 |
+
@classmethod
|
| 230 |
+
@replace_list_option_in_docstrings(PROCESSOR_MAPPING_NAMES)
|
| 231 |
+
def from_pretrained(cls, pretrained_model_name_or_path, **kwargs):
|
| 232 |
+
r"""
|
| 233 |
+
Instantiate one of the processor classes of the library from a pretrained model vocabulary.
|
| 234 |
+
|
| 235 |
+
The processor class to instantiate is selected based on the `model_type` property of the config object (either
|
| 236 |
+
passed as an argument or loaded from `pretrained_model_name_or_path` if possible):
|
| 237 |
+
|
| 238 |
+
List options
|
| 239 |
+
|
| 240 |
+
Params:
|
| 241 |
+
pretrained_model_name_or_path (`str` or `os.PathLike`):
|
| 242 |
+
This can be either:
|
| 243 |
+
|
| 244 |
+
- a string, the *model id* of a pretrained feature_extractor hosted inside a model repo on
|
| 245 |
+
huggingface.co.
|
| 246 |
+
- a path to a *directory* containing a processor files saved using the `save_pretrained()` method,
|
| 247 |
+
e.g., `./my_model_directory/`.
|
| 248 |
+
cache_dir (`str` or `os.PathLike`, *optional*):
|
| 249 |
+
Path to a directory in which a downloaded pretrained model feature extractor should be cached if the
|
| 250 |
+
standard cache should not be used.
|
| 251 |
+
force_download (`bool`, *optional*, defaults to `False`):
|
| 252 |
+
Whether or not to force to (re-)download the feature extractor files and override the cached versions
|
| 253 |
+
if they exist.
|
| 254 |
+
proxies (`dict[str, str]`, *optional*):
|
| 255 |
+
A dictionary of proxy servers to use by protocol or endpoint, e.g., `{'http': 'foo.bar:3128',
|
| 256 |
+
'http://hostname': 'foo.bar:4012'}.` The proxies are used on each request.
|
| 257 |
+
token (`str` or *bool*, *optional*):
|
| 258 |
+
The token to use as HTTP bearer authorization for remote files. If `True`, will use the token generated
|
| 259 |
+
when running `hf auth login` (stored in `~/.huggingface`).
|
| 260 |
+
revision (`str`, *optional*, defaults to `"main"`):
|
| 261 |
+
The specific model version to use. It can be a branch name, a tag name, or a commit id, since we use a
|
| 262 |
+
git-based system for storing models and other artifacts on huggingface.co, so `revision` can be any
|
| 263 |
+
identifier allowed by git.
|
| 264 |
+
return_unused_kwargs (`bool`, *optional*, defaults to `False`):
|
| 265 |
+
If `False`, then this function returns just the final feature extractor object. If `True`, then this
|
| 266 |
+
functions returns a `Tuple(feature_extractor, unused_kwargs)` where *unused_kwargs* is a dictionary
|
| 267 |
+
consisting of the key/value pairs whose keys are not feature extractor attributes: i.e., the part of
|
| 268 |
+
`kwargs` which has not been used to update `feature_extractor` and is otherwise ignored.
|
| 269 |
+
trust_remote_code (`bool`, *optional*, defaults to `False`):
|
| 270 |
+
Whether or not to allow for custom models defined on the Hub in their own modeling files. This option
|
| 271 |
+
should only be set to `True` for repositories you trust and in which you have read the code, as it will
|
| 272 |
+
execute code present on the Hub on your local machine.
|
| 273 |
+
kwargs (`dict[str, Any]`, *optional*):
|
| 274 |
+
The values in kwargs of any keys which are feature extractor attributes will be used to override the
|
| 275 |
+
loaded values. Behavior concerning key/value pairs whose keys are *not* feature extractor attributes is
|
| 276 |
+
controlled by the `return_unused_kwargs` keyword parameter.
|
| 277 |
+
|
| 278 |
+
<Tip>
|
| 279 |
+
|
| 280 |
+
Passing `token=True` is required when you want to use a private model.
|
| 281 |
+
|
| 282 |
+
</Tip>
|
| 283 |
+
|
| 284 |
+
Examples:
|
| 285 |
+
|
| 286 |
+
```python
|
| 287 |
+
>>> from transformers import AutoProcessor
|
| 288 |
+
|
| 289 |
+
>>> # Download processor from huggingface.co and cache.
|
| 290 |
+
>>> processor = AutoProcessor.from_pretrained("facebook/wav2vec2-base-960h")
|
| 291 |
+
|
| 292 |
+
>>> # If processor files are in a directory (e.g. processor was saved using *save_pretrained('./test/saved_model/')*)
|
| 293 |
+
>>> # processor = AutoProcessor.from_pretrained("./test/saved_model/")
|
| 294 |
+
```"""
|
| 295 |
+
config = kwargs.pop("config", None)
|
| 296 |
+
trust_remote_code = kwargs.pop("trust_remote_code", None)
|
| 297 |
+
kwargs["_from_auto"] = True
|
| 298 |
+
|
| 299 |
+
processor_class = None
|
| 300 |
+
processor_auto_map = None
|
| 301 |
+
|
| 302 |
+
# First, let's see if we have a processor or preprocessor config.
|
| 303 |
+
# Filter the kwargs for `cached_file`.
|
| 304 |
+
_hub_valid_kwargs = (
|
| 305 |
+
"cache_dir",
|
| 306 |
+
"force_download",
|
| 307 |
+
"proxies",
|
| 308 |
+
"token",
|
| 309 |
+
"revision",
|
| 310 |
+
"local_files_only",
|
| 311 |
+
"subfolder",
|
| 312 |
+
"repo_type",
|
| 313 |
+
"user_agent",
|
| 314 |
+
)
|
| 315 |
+
cached_file_kwargs = {key: kwargs[key] for key in _hub_valid_kwargs if key in kwargs}
|
| 316 |
+
# We don't want to raise
|
| 317 |
+
cached_file_kwargs.update(
|
| 318 |
+
{
|
| 319 |
+
"_raise_exceptions_for_gated_repo": False,
|
| 320 |
+
"_raise_exceptions_for_missing_entries": False,
|
| 321 |
+
"_raise_exceptions_for_connection_errors": False,
|
| 322 |
+
}
|
| 323 |
+
)
|
| 324 |
+
|
| 325 |
+
# Let's start by checking whether the processor class is saved in a processor config
|
| 326 |
+
processor_config_file = cached_file(pretrained_model_name_or_path, PROCESSOR_NAME, **cached_file_kwargs)
|
| 327 |
+
if processor_config_file is not None:
|
| 328 |
+
config_dict, _ = ProcessorMixin.get_processor_dict(pretrained_model_name_or_path, **kwargs)
|
| 329 |
+
processor_class = config_dict.get("processor_class")
|
| 330 |
+
if "AutoProcessor" in config_dict.get("auto_map", {}):
|
| 331 |
+
processor_auto_map = config_dict["auto_map"]["AutoProcessor"]
|
| 332 |
+
|
| 333 |
+
if processor_class is None:
|
| 334 |
+
# If not found, let's check whether the processor class is saved in an image processor config
|
| 335 |
+
preprocessor_config_file = cached_file(
|
| 336 |
+
pretrained_model_name_or_path, FEATURE_EXTRACTOR_NAME, **cached_file_kwargs
|
| 337 |
+
)
|
| 338 |
+
if preprocessor_config_file is not None:
|
| 339 |
+
config_dict, _ = ImageProcessingMixin.get_image_processor_dict(pretrained_model_name_or_path, **kwargs)
|
| 340 |
+
processor_class = config_dict.get("processor_class", None)
|
| 341 |
+
if "AutoProcessor" in config_dict.get("auto_map", {}):
|
| 342 |
+
processor_auto_map = config_dict["auto_map"]["AutoProcessor"]
|
| 343 |
+
|
| 344 |
+
# Saved as video processor
|
| 345 |
+
if preprocessor_config_file is None:
|
| 346 |
+
preprocessor_config_file = cached_file(
|
| 347 |
+
pretrained_model_name_or_path, VIDEO_PROCESSOR_NAME, **cached_file_kwargs
|
| 348 |
+
)
|
| 349 |
+
if preprocessor_config_file is not None:
|
| 350 |
+
config_dict, _ = BaseVideoProcessor.get_video_processor_dict(
|
| 351 |
+
pretrained_model_name_or_path, **kwargs
|
| 352 |
+
)
|
| 353 |
+
processor_class = config_dict.get("processor_class", None)
|
| 354 |
+
if "AutoProcessor" in config_dict.get("auto_map", {}):
|
| 355 |
+
processor_auto_map = config_dict["auto_map"]["AutoProcessor"]
|
| 356 |
+
# Saved as feature extractor
|
| 357 |
+
if preprocessor_config_file is None:
|
| 358 |
+
preprocessor_config_file = cached_file(
|
| 359 |
+
pretrained_model_name_or_path, FEATURE_EXTRACTOR_NAME, **cached_file_kwargs
|
| 360 |
+
)
|
| 361 |
+
if preprocessor_config_file is not None and processor_class is None:
|
| 362 |
+
config_dict, _ = FeatureExtractionMixin.get_feature_extractor_dict(
|
| 363 |
+
pretrained_model_name_or_path, **kwargs
|
| 364 |
+
)
|
| 365 |
+
processor_class = config_dict.get("processor_class", None)
|
| 366 |
+
if "AutoProcessor" in config_dict.get("auto_map", {}):
|
| 367 |
+
processor_auto_map = config_dict["auto_map"]["AutoProcessor"]
|
| 368 |
+
|
| 369 |
+
if processor_class is None:
|
| 370 |
+
# Next, let's check whether the processor class is saved in a tokenizer
|
| 371 |
+
tokenizer_config_file = cached_file(
|
| 372 |
+
pretrained_model_name_or_path, TOKENIZER_CONFIG_FILE, **cached_file_kwargs
|
| 373 |
+
)
|
| 374 |
+
if tokenizer_config_file is not None:
|
| 375 |
+
with open(tokenizer_config_file, encoding="utf-8") as reader:
|
| 376 |
+
config_dict = json.load(reader)
|
| 377 |
+
|
| 378 |
+
processor_class = config_dict.get("processor_class", None)
|
| 379 |
+
if "AutoProcessor" in config_dict.get("auto_map", {}):
|
| 380 |
+
processor_auto_map = config_dict["auto_map"]["AutoProcessor"]
|
| 381 |
+
|
| 382 |
+
if processor_class is None:
|
| 383 |
+
# Last resort: try loading the model config to get processor_class.
|
| 384 |
+
# This handles cases where processor info is only in config.json (not in any
|
| 385 |
+
# preprocessor/tokenizer config files). AutoConfig.from_pretrained may raise
|
| 386 |
+
# ValueError if the model_type is unrecognized or the config is invalid -
|
| 387 |
+
# we catch and ignore this to allow fallback to AutoTokenizer/AutoImageProcessor.
|
| 388 |
+
try:
|
| 389 |
+
if not isinstance(config, PreTrainedConfig):
|
| 390 |
+
config = AutoConfig.from_pretrained(
|
| 391 |
+
pretrained_model_name_or_path, trust_remote_code=trust_remote_code, **kwargs
|
| 392 |
+
)
|
| 393 |
+
|
| 394 |
+
processor_class = getattr(config, "processor_class", None)
|
| 395 |
+
if hasattr(config, "auto_map") and "AutoProcessor" in config.auto_map:
|
| 396 |
+
processor_auto_map = config.auto_map["AutoProcessor"]
|
| 397 |
+
except ValueError:
|
| 398 |
+
# Config loading failed (unrecognized model_type, invalid config, etc.)
|
| 399 |
+
# Continue to fallback logic below (AutoTokenizer, AutoImageProcessor, etc.)
|
| 400 |
+
pass
|
| 401 |
+
|
| 402 |
+
if processor_class is not None:
|
| 403 |
+
processor_class = processor_class_from_name(processor_class)
|
| 404 |
+
|
| 405 |
+
has_remote_code = processor_auto_map is not None
|
| 406 |
+
has_local_code = processor_class is not None or type(config) in PROCESSOR_MAPPING
|
| 407 |
+
explicit_local_code = has_local_code and not (
|
| 408 |
+
processor_class or PROCESSOR_MAPPING[type(config)]
|
| 409 |
+
).__module__.startswith("transformers.")
|
| 410 |
+
if has_remote_code:
|
| 411 |
+
if "--" in processor_auto_map:
|
| 412 |
+
upstream_repo = processor_auto_map.split("--")[0]
|
| 413 |
+
else:
|
| 414 |
+
upstream_repo = None
|
| 415 |
+
trust_remote_code = resolve_trust_remote_code(
|
| 416 |
+
trust_remote_code, pretrained_model_name_or_path, has_local_code, has_remote_code, upstream_repo
|
| 417 |
+
)
|
| 418 |
+
|
| 419 |
+
if has_remote_code and trust_remote_code and not explicit_local_code:
|
| 420 |
+
processor_class = get_class_from_dynamic_module(
|
| 421 |
+
processor_auto_map, pretrained_model_name_or_path, **kwargs
|
| 422 |
+
)
|
| 423 |
+
_ = kwargs.pop("code_revision", None)
|
| 424 |
+
processor_class.register_for_auto_class()
|
| 425 |
+
return processor_class.from_pretrained(
|
| 426 |
+
pretrained_model_name_or_path, trust_remote_code=trust_remote_code, **kwargs
|
| 427 |
+
)
|
| 428 |
+
elif processor_class is not None:
|
| 429 |
+
return processor_class.from_pretrained(
|
| 430 |
+
pretrained_model_name_or_path, trust_remote_code=trust_remote_code, **kwargs
|
| 431 |
+
)
|
| 432 |
+
# Last try: we use the PROCESSOR_MAPPING.
|
| 433 |
+
elif type(config) in PROCESSOR_MAPPING:
|
| 434 |
+
return PROCESSOR_MAPPING[type(config)].from_pretrained(pretrained_model_name_or_path, **kwargs)
|
| 435 |
+
|
| 436 |
+
# At this stage, there doesn't seem to be a `Processor` class available for this model.
|
| 437 |
+
# Let's try the commonly available classes
|
| 438 |
+
for klass in (AutoTokenizer, AutoImageProcessor, AutoVideoProcessor, AutoFeatureExtractor):
|
| 439 |
+
try:
|
| 440 |
+
return klass.from_pretrained(
|
| 441 |
+
pretrained_model_name_or_path, trust_remote_code=trust_remote_code, **kwargs
|
| 442 |
+
)
|
| 443 |
+
except Exception:
|
| 444 |
+
continue
|
| 445 |
+
|
| 446 |
+
raise ValueError(
|
| 447 |
+
f"Unrecognized processing class in {pretrained_model_name_or_path}. Can't instantiate a processor, a "
|
| 448 |
+
"tokenizer, an image processor, a video processor or a feature extractor for this model. "
|
| 449 |
+
"Make sure the repository contains the files of at least one of those processing classes."
|
| 450 |
+
)
|
| 451 |
+
|
| 452 |
+
@staticmethod
|
| 453 |
+
def register(config_class, processor_class, exist_ok=False):
|
| 454 |
+
"""
|
| 455 |
+
Register a new processor for this class.
|
| 456 |
+
|
| 457 |
+
Args:
|
| 458 |
+
config_class ([`PreTrainedConfig`]):
|
| 459 |
+
The configuration corresponding to the model to register.
|
| 460 |
+
processor_class ([`ProcessorMixin`]): The processor to register.
|
| 461 |
+
"""
|
| 462 |
+
PROCESSOR_MAPPING.register(config_class, processor_class, exist_ok=exist_ok)
|
| 463 |
+
|
| 464 |
+
|
| 465 |
+
__all__ = ["PROCESSOR_MAPPING", "AutoProcessor"]
|
third_party/transformers/src/transformers/models/auto/tokenization_auto.py
ADDED
|
@@ -0,0 +1,871 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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 |
+
"""Auto Tokenizer class."""
|
| 15 |
+
|
| 16 |
+
import importlib
|
| 17 |
+
import json
|
| 18 |
+
import os
|
| 19 |
+
import sys
|
| 20 |
+
from collections import OrderedDict
|
| 21 |
+
from typing import Any
|
| 22 |
+
|
| 23 |
+
from transformers.utils.import_utils import is_mistral_common_available
|
| 24 |
+
|
| 25 |
+
from ...configuration_utils import PreTrainedConfig
|
| 26 |
+
from ...dynamic_module_utils import get_class_from_dynamic_module, resolve_trust_remote_code
|
| 27 |
+
from ...modeling_gguf_pytorch_utils import load_gguf_checkpoint
|
| 28 |
+
from ...tokenization_utils_base import TOKENIZER_CONFIG_FILE
|
| 29 |
+
from ...utils import (
|
| 30 |
+
extract_commit_hash,
|
| 31 |
+
is_g2p_en_available,
|
| 32 |
+
is_sentencepiece_available,
|
| 33 |
+
is_tokenizers_available,
|
| 34 |
+
logging,
|
| 35 |
+
)
|
| 36 |
+
from ...utils.hub import cached_file
|
| 37 |
+
from ..encoder_decoder import EncoderDecoderConfig
|
| 38 |
+
from .auto_factory import _LazyAutoMapping
|
| 39 |
+
from .configuration_auto import (
|
| 40 |
+
CONFIG_MAPPING_NAMES,
|
| 41 |
+
AutoConfig,
|
| 42 |
+
config_class_to_model_type,
|
| 43 |
+
model_type_to_module_name,
|
| 44 |
+
replace_list_option_in_docstrings,
|
| 45 |
+
)
|
| 46 |
+
|
| 47 |
+
|
| 48 |
+
if is_tokenizers_available():
|
| 49 |
+
from ...tokenization_utils_tokenizers import TokenizersBackend
|
| 50 |
+
else:
|
| 51 |
+
TokenizersBackend = None
|
| 52 |
+
|
| 53 |
+
if is_sentencepiece_available():
|
| 54 |
+
from ...tokenization_utils_sentencepiece import SentencePieceBackend
|
| 55 |
+
else:
|
| 56 |
+
SentencePieceBackend = None
|
| 57 |
+
|
| 58 |
+
logger = logging.get_logger(__name__)
|
| 59 |
+
|
| 60 |
+
# V5: Simplified mapping - single tokenizer class per model type (always prefer tokenizers-based)
|
| 61 |
+
REGISTERED_TOKENIZER_CLASSES: dict[str, type[Any]] = {}
|
| 62 |
+
REGISTERED_FAST_ALIASES: dict[str, type[Any]] = {}
|
| 63 |
+
|
| 64 |
+
TOKENIZER_MAPPING_NAMES = OrderedDict[str, str | None](
|
| 65 |
+
[
|
| 66 |
+
("aimv2", "CLIPTokenizer" if is_tokenizers_available() else None),
|
| 67 |
+
("albert", "AlbertTokenizer" if is_tokenizers_available() else None),
|
| 68 |
+
("align", "BertTokenizer" if is_tokenizers_available() else None),
|
| 69 |
+
("audioflamingo3", "Qwen2Tokenizer" if is_tokenizers_available() else None),
|
| 70 |
+
("aya_vision", "CohereTokenizer" if is_tokenizers_available() else None),
|
| 71 |
+
("bark", "BertTokenizer" if is_tokenizers_available() else None),
|
| 72 |
+
("bart", "RobertaTokenizer" if is_tokenizers_available() else None),
|
| 73 |
+
("barthez", "BarthezTokenizer" if is_tokenizers_available() else None),
|
| 74 |
+
("bartpho", "BartphoTokenizer"),
|
| 75 |
+
("bert", "BertTokenizer" if is_tokenizers_available() else None),
|
| 76 |
+
("bert-generation", "BertGenerationTokenizer" if is_sentencepiece_available() else None),
|
| 77 |
+
("bert-japanese", "BertJapaneseTokenizer"),
|
| 78 |
+
("bertweet", "BertweetTokenizer"),
|
| 79 |
+
("big_bird", "BigBirdTokenizer" if is_tokenizers_available() else None),
|
| 80 |
+
("bigbird_pegasus", "PegasusTokenizer" if is_tokenizers_available() else None),
|
| 81 |
+
("biogpt", "BioGptTokenizer"),
|
| 82 |
+
("blenderbot", "BlenderbotTokenizer" if is_tokenizers_available() else None),
|
| 83 |
+
("blenderbot-small", "BlenderbotSmallTokenizer"),
|
| 84 |
+
("blip", "BertTokenizer" if is_tokenizers_available() else None),
|
| 85 |
+
("blip-2", "GPT2Tokenizer" if is_tokenizers_available() else None),
|
| 86 |
+
("bridgetower", "RobertaTokenizer"),
|
| 87 |
+
("bros", "BertTokenizer" if is_tokenizers_available() else None),
|
| 88 |
+
("byt5", "ByT5Tokenizer"),
|
| 89 |
+
("camembert", "CamembertTokenizer" if is_tokenizers_available() else None),
|
| 90 |
+
("canine", "CanineTokenizer"),
|
| 91 |
+
("chinese_clip", "BertTokenizer" if is_tokenizers_available() else None),
|
| 92 |
+
("clap", "RobertaTokenizer"),
|
| 93 |
+
("clip", "CLIPTokenizer" if is_tokenizers_available() else None),
|
| 94 |
+
("clipseg", "CLIPTokenizer" if is_tokenizers_available() else None),
|
| 95 |
+
("clvp", "ClvpTokenizer"),
|
| 96 |
+
("code_llama", "CodeLlamaTokenizer" if is_tokenizers_available() else None),
|
| 97 |
+
("codegen", "GPT2Tokenizer" if is_tokenizers_available() else None),
|
| 98 |
+
("cohere", "CohereTokenizer" if is_tokenizers_available() else None),
|
| 99 |
+
("cohere2", "CohereTokenizer" if is_tokenizers_available() else None),
|
| 100 |
+
("colqwen2", "Qwen2Tokenizer" if is_tokenizers_available() else None),
|
| 101 |
+
("convbert", "BertTokenizer" if is_tokenizers_available() else None),
|
| 102 |
+
("cpm", "CpmTokenizer" if is_tokenizers_available() else None),
|
| 103 |
+
("cpmant", "CpmAntTokenizer"),
|
| 104 |
+
("ctrl", "CTRLTokenizer"),
|
| 105 |
+
("data2vec-audio", "Wav2Vec2CTCTokenizer"),
|
| 106 |
+
("data2vec-text", "RobertaTokenizer"),
|
| 107 |
+
("dbrx", "GPT2Tokenizer" if is_tokenizers_available() else None),
|
| 108 |
+
("deberta", "DebertaTokenizer" if is_tokenizers_available() else None),
|
| 109 |
+
("deberta-v2", "DebertaV2Tokenizer" if is_tokenizers_available() else None),
|
| 110 |
+
("dia", "DiaTokenizer"),
|
| 111 |
+
("distilbert", "BertTokenizer" if is_tokenizers_available() else None),
|
| 112 |
+
("dpr", "DPRQuestionEncoderTokenizer" if is_tokenizers_available() else None),
|
| 113 |
+
("electra", "BertTokenizer" if is_tokenizers_available() else None),
|
| 114 |
+
("emu3", "GPT2Tokenizer" if is_tokenizers_available() else None),
|
| 115 |
+
("ernie", "BertTokenizer" if is_tokenizers_available() else None),
|
| 116 |
+
("esm", "EsmTokenizer"),
|
| 117 |
+
("falcon_mamba", "GPTNeoXTokenizer" if is_tokenizers_available() else None),
|
| 118 |
+
("fastspeech2_conformer", "FastSpeech2ConformerTokenizer" if is_g2p_en_available() else None),
|
| 119 |
+
("flaubert", "FlaubertTokenizer"),
|
| 120 |
+
("flava", "BertTokenizer" if is_tokenizers_available() else None),
|
| 121 |
+
("flex_olmo", "GPT2Tokenizer" if is_tokenizers_available() else None),
|
| 122 |
+
("florence2", "BartTokenizer" if is_tokenizers_available() else None),
|
| 123 |
+
("fnet", "FNetTokenizer" if is_tokenizers_available() else None),
|
| 124 |
+
("fsmt", "FSMTTokenizer"),
|
| 125 |
+
("funnel", "FunnelTokenizer" if is_tokenizers_available() else None),
|
| 126 |
+
("gemma", "GemmaTokenizer" if is_tokenizers_available() else None),
|
| 127 |
+
("gemma2", "GemmaTokenizer" if is_tokenizers_available() else None),
|
| 128 |
+
("gemma3", "GemmaTokenizer" if is_tokenizers_available() else None),
|
| 129 |
+
("gemma3_text", "GemmaTokenizer" if is_tokenizers_available() else None),
|
| 130 |
+
("gemma3n", "GemmaTokenizer" if is_tokenizers_available() else None),
|
| 131 |
+
("gemma3n_text", "GemmaTokenizer" if is_tokenizers_available() else None),
|
| 132 |
+
("git", "BertTokenizer" if is_tokenizers_available() else None),
|
| 133 |
+
("glm", "TokenizersBackend" if is_tokenizers_available() else None),
|
| 134 |
+
("glm4", "TokenizersBackend" if is_tokenizers_available() else None),
|
| 135 |
+
("glm4_moe", "TokenizersBackend" if is_tokenizers_available() else None),
|
| 136 |
+
("glm4_moe_lite", "TokenizersBackend" if is_tokenizers_available() else None),
|
| 137 |
+
("glm4v", "TokenizersBackend" if is_tokenizers_available() else None),
|
| 138 |
+
("glm4v_moe", "TokenizersBackend" if is_tokenizers_available() else None),
|
| 139 |
+
("glm_image", "TokenizersBackend" if is_tokenizers_available() else None),
|
| 140 |
+
("glmasr", "TokenizersBackend" if is_tokenizers_available() else None),
|
| 141 |
+
("got_ocr2", "TokenizersBackend" if is_tokenizers_available() else None),
|
| 142 |
+
("gpt-sw3", "GPTSw3Tokenizer" if is_sentencepiece_available() else None),
|
| 143 |
+
("gpt2", "GPT2Tokenizer" if is_tokenizers_available() else None),
|
| 144 |
+
("gpt_bigcode", "GPT2Tokenizer" if is_tokenizers_available() else None),
|
| 145 |
+
("gpt_neo", "GPT2Tokenizer" if is_tokenizers_available() else None),
|
| 146 |
+
("gpt_neox", "GPTNeoXTokenizer" if is_tokenizers_available() else None),
|
| 147 |
+
("gpt_neox_japanese", "GPTNeoXJapaneseTokenizer"),
|
| 148 |
+
("gptj", "GPT2Tokenizer" if is_tokenizers_available() else None),
|
| 149 |
+
("granite", "GPT2Tokenizer"),
|
| 150 |
+
("granitemoe", "GPT2Tokenizer"),
|
| 151 |
+
("granitemoehybrid", "GPT2Tokenizer"),
|
| 152 |
+
("granitemoeshared", "GPT2Tokenizer"),
|
| 153 |
+
("grounding-dino", "BertTokenizer" if is_tokenizers_available() else None),
|
| 154 |
+
("groupvit", "CLIPTokenizer" if is_tokenizers_available() else None),
|
| 155 |
+
("herbert", "HerbertTokenizer" if is_tokenizers_available() else None),
|
| 156 |
+
("hubert", "Wav2Vec2CTCTokenizer"),
|
| 157 |
+
("ibert", "RobertaTokenizer"),
|
| 158 |
+
("idefics", "LlamaTokenizer" if is_tokenizers_available() else None),
|
| 159 |
+
("idefics2", "LlamaTokenizer" if is_tokenizers_available() else None),
|
| 160 |
+
("instructblip", "GPT2Tokenizer" if is_tokenizers_available() else None),
|
| 161 |
+
("instructblipvideo", "GPT2Tokenizer" if is_tokenizers_available() else None),
|
| 162 |
+
("internvl", "Qwen2Tokenizer" if is_tokenizers_available() else None),
|
| 163 |
+
("jais2", "GPT2Tokenizer" if is_tokenizers_available() else None),
|
| 164 |
+
("jina_embeddings_v3", "XLMRobertaTokenizer" if is_tokenizers_available() else None),
|
| 165 |
+
("kosmos-2", "XLMRobertaTokenizer" if is_tokenizers_available() else None),
|
| 166 |
+
("lasr_ctc", "LasrTokenizer" if is_tokenizers_available() else None),
|
| 167 |
+
("lasr_encoder", "LasrTokenizer" if is_tokenizers_available() else None),
|
| 168 |
+
("layoutlm", "BertTokenizer" if is_tokenizers_available() else None),
|
| 169 |
+
("layoutlmv2", "LayoutLMv2Tokenizer" if is_tokenizers_available() else None),
|
| 170 |
+
("layoutlmv3", "LayoutLMv3Tokenizer" if is_tokenizers_available() else None),
|
| 171 |
+
("layoutxlm", "LayoutXLMTokenizer" if is_tokenizers_available() else None),
|
| 172 |
+
("led", "LEDTokenizer" if is_tokenizers_available() else None),
|
| 173 |
+
("lighton_ocr", "Qwen2TokenizerFast" if is_tokenizers_available() else None),
|
| 174 |
+
("lilt", "RobertaTokenizer" if is_tokenizers_available() else None),
|
| 175 |
+
("longformer", "RobertaTokenizer" if is_tokenizers_available() else None),
|
| 176 |
+
("luke", "LukeTokenizer"),
|
| 177 |
+
("lxmert", "LxmertTokenizer" if is_tokenizers_available() else None),
|
| 178 |
+
("m2m_100", "M2M100Tokenizer" if is_sentencepiece_available() else None),
|
| 179 |
+
("mamba", "GPTNeoXTokenizer" if is_tokenizers_available() else None),
|
| 180 |
+
("mamba2", "GPTNeoXTokenizer" if is_tokenizers_available() else None),
|
| 181 |
+
("marian", "MarianTokenizer" if is_sentencepiece_available() else None),
|
| 182 |
+
("markuplm", "MarkupLMTokenizer" if is_tokenizers_available() else None),
|
| 183 |
+
("mbart", "MBartTokenizer" if is_tokenizers_available() else None),
|
| 184 |
+
("mbart50", "MBart50Tokenizer" if is_tokenizers_available() else None),
|
| 185 |
+
("mega", "RobertaTokenizer"),
|
| 186 |
+
("megatron-bert", "BertTokenizer" if is_tokenizers_available() else None),
|
| 187 |
+
("metaclip_2", "XLMRobertaTokenizer" if is_tokenizers_available() else None),
|
| 188 |
+
("mgp-str", "MgpstrTokenizer"),
|
| 189 |
+
(
|
| 190 |
+
"ministral",
|
| 191 |
+
"MistralCommonBackend"
|
| 192 |
+
if is_mistral_common_available()
|
| 193 |
+
else ("TokenizersBackend" if is_tokenizers_available() else None),
|
| 194 |
+
),
|
| 195 |
+
(
|
| 196 |
+
"ministral3",
|
| 197 |
+
"MistralCommonBackend"
|
| 198 |
+
if is_mistral_common_available()
|
| 199 |
+
else ("TokenizersBackend" if is_tokenizers_available() else None),
|
| 200 |
+
),
|
| 201 |
+
(
|
| 202 |
+
"mistral",
|
| 203 |
+
"MistralCommonBackend"
|
| 204 |
+
if is_mistral_common_available()
|
| 205 |
+
else ("TokenizersBackend" if is_tokenizers_available() else None),
|
| 206 |
+
),
|
| 207 |
+
(
|
| 208 |
+
"mistral3",
|
| 209 |
+
"MistralCommonBackend"
|
| 210 |
+
if is_mistral_common_available()
|
| 211 |
+
else ("TokenizersBackend" if is_tokenizers_available() else None),
|
| 212 |
+
),
|
| 213 |
+
(
|
| 214 |
+
"mixtral",
|
| 215 |
+
"MistralCommonBackend"
|
| 216 |
+
if is_mistral_common_available()
|
| 217 |
+
else ("TokenizersBackend" if is_tokenizers_available() else None),
|
| 218 |
+
),
|
| 219 |
+
("mluke", "MLukeTokenizer" if is_sentencepiece_available() else None),
|
| 220 |
+
("mm-grounding-dino", "BertTokenizer" if is_tokenizers_available() else None),
|
| 221 |
+
("mobilebert", "MobileBertTokenizer" if is_tokenizers_available() else None),
|
| 222 |
+
("mpnet", "MPNetTokenizer" if is_tokenizers_available() else None),
|
| 223 |
+
("mpt", "GPTNeoXTokenizer" if is_tokenizers_available() else None),
|
| 224 |
+
("mra", "RobertaTokenizer"),
|
| 225 |
+
("mt5", "T5Tokenizer" if is_tokenizers_available() else None),
|
| 226 |
+
("musicgen", "T5Tokenizer" if is_tokenizers_available() else None),
|
| 227 |
+
("musicgen_melody", "T5Tokenizer" if is_tokenizers_available() else None),
|
| 228 |
+
("mvp", "MvpTokenizer" if is_tokenizers_available() else None),
|
| 229 |
+
("myt5", "MyT5Tokenizer"),
|
| 230 |
+
("nezha", "BertTokenizer" if is_tokenizers_available() else None),
|
| 231 |
+
("nllb", "NllbTokenizer" if is_tokenizers_available() else None),
|
| 232 |
+
("nllb-moe", "NllbTokenizer" if is_tokenizers_available() else None),
|
| 233 |
+
("nomic_bert", "BertTokenizer" if is_tokenizers_available() else None),
|
| 234 |
+
("nougat", "NougatTokenizer" if is_tokenizers_available() else None),
|
| 235 |
+
("nystromformer", "AlbertTokenizer" if is_tokenizers_available() else None),
|
| 236 |
+
("olmo", "GPTNeoXTokenizer" if is_tokenizers_available() else None),
|
| 237 |
+
("olmo2", "GPTNeoXTokenizer" if is_tokenizers_available() else None),
|
| 238 |
+
("olmo3", "TokenizersBackend" if is_tokenizers_available() else None),
|
| 239 |
+
("olmo_hybrid", "TokenizersBackend" if is_tokenizers_available() else None),
|
| 240 |
+
("olmoe", "GPTNeoXTokenizer" if is_tokenizers_available() else None),
|
| 241 |
+
("omdet-turbo", "CLIPTokenizer" if is_tokenizers_available() else None),
|
| 242 |
+
("oneformer", "CLIPTokenizer" if is_tokenizers_available() else None),
|
| 243 |
+
("openai-gpt", "OpenAIGPTTokenizer" if is_tokenizers_available() else None),
|
| 244 |
+
("opt", "GPT2Tokenizer" if is_tokenizers_available() else None),
|
| 245 |
+
("ovis2", "Qwen2Tokenizer" if is_tokenizers_available() else None),
|
| 246 |
+
("owlv2", "CLIPTokenizer" if is_tokenizers_available() else None),
|
| 247 |
+
("owlvit", "CLIPTokenizer" if is_tokenizers_available() else None),
|
| 248 |
+
("pegasus", "PegasusTokenizer" if is_tokenizers_available() else None),
|
| 249 |
+
("pegasus_x", "PegasusTokenizer" if is_tokenizers_available() else None),
|
| 250 |
+
("perceiver", "PerceiverTokenizer"),
|
| 251 |
+
("phi", "GPT2Tokenizer" if is_tokenizers_available() else None),
|
| 252 |
+
("phobert", "PhobertTokenizer"),
|
| 253 |
+
("pix2struct", "T5Tokenizer" if is_tokenizers_available() else None),
|
| 254 |
+
(
|
| 255 |
+
"pixtral",
|
| 256 |
+
"MistralCommonBackend"
|
| 257 |
+
if is_mistral_common_available()
|
| 258 |
+
else ("TokenizersBackend" if is_tokenizers_available() else None),
|
| 259 |
+
),
|
| 260 |
+
("plbart", "PLBartTokenizer" if is_tokenizers_available() else None),
|
| 261 |
+
("prophetnet", "ProphetNetTokenizer"),
|
| 262 |
+
("qdqbert", "BertTokenizer" if is_tokenizers_available() else None),
|
| 263 |
+
("qwen2", "Qwen2Tokenizer" if is_tokenizers_available() else None),
|
| 264 |
+
("qwen2_5_omni", "Qwen2Tokenizer" if is_tokenizers_available() else None),
|
| 265 |
+
("qwen2_5_vl", "Qwen2Tokenizer" if is_tokenizers_available() else None),
|
| 266 |
+
("qwen2_audio", "Qwen2Tokenizer" if is_tokenizers_available() else None),
|
| 267 |
+
("qwen2_moe", "Qwen2Tokenizer" if is_tokenizers_available() else None),
|
| 268 |
+
("qwen2_vl", "Qwen2Tokenizer" if is_tokenizers_available() else None),
|
| 269 |
+
("qwen3", "Qwen2Tokenizer" if is_tokenizers_available() else None),
|
| 270 |
+
("qwen3_5", "Qwen3_5Tokenizer" if is_tokenizers_available() else None),
|
| 271 |
+
("qwen3_5_moe", "Qwen3_5Tokenizer" if is_tokenizers_available() else None),
|
| 272 |
+
("qwen3_moe", "Qwen2Tokenizer" if is_tokenizers_available() else None),
|
| 273 |
+
("qwen3_next", "Qwen2Tokenizer" if is_tokenizers_available() else None),
|
| 274 |
+
("qwen3_omni_moe", "Qwen2Tokenizer" if is_tokenizers_available() else None),
|
| 275 |
+
("qwen3_vl", "Qwen2Tokenizer" if is_tokenizers_available() else None),
|
| 276 |
+
("qwen3_vl_moe", "Qwen2Tokenizer" if is_tokenizers_available() else None),
|
| 277 |
+
("rag", "RagTokenizer"),
|
| 278 |
+
("realm", "BertTokenizer" if is_tokenizers_available() else None),
|
| 279 |
+
("recurrent_gemma", "GemmaTokenizer" if is_tokenizers_available() else None),
|
| 280 |
+
("reformer", "ReformerTokenizer" if is_tokenizers_available() else None),
|
| 281 |
+
("rembert", "RemBertTokenizer" if is_tokenizers_available() else None),
|
| 282 |
+
("retribert", "BertTokenizer" if is_tokenizers_available() else None),
|
| 283 |
+
("roberta", "RobertaTokenizer"),
|
| 284 |
+
("roberta-prelayernorm", "RobertaTokenizer"),
|
| 285 |
+
("roc_bert", "RoCBertTokenizer"),
|
| 286 |
+
("roformer", "RoFormerTokenizer" if is_tokenizers_available() else None),
|
| 287 |
+
("rwkv", "GPTNeoXTokenizer" if is_tokenizers_available() else None),
|
| 288 |
+
("sam3", "CLIPTokenizer" if is_tokenizers_available() else None),
|
| 289 |
+
("sam3_video", "CLIPTokenizer" if is_tokenizers_available() else None),
|
| 290 |
+
("seamless_m4t", "SeamlessM4TTokenizer" if is_tokenizers_available() else None),
|
| 291 |
+
("seamless_m4t_v2", "SeamlessM4TTokenizer" if is_tokenizers_available() else None),
|
| 292 |
+
("shieldgemma2", "GemmaTokenizer" if is_tokenizers_available() else None),
|
| 293 |
+
("siglip", "SiglipTokenizer" if is_sentencepiece_available() else None),
|
| 294 |
+
("siglip2", "Siglip2Tokenizer" if is_tokenizers_available() else None),
|
| 295 |
+
("speech_to_text", "Speech2TextTokenizer" if is_sentencepiece_available() else None),
|
| 296 |
+
("speecht5", "SpeechT5Tokenizer" if is_sentencepiece_available() else None),
|
| 297 |
+
("splinter", "SplinterTokenizer"),
|
| 298 |
+
("squeezebert", "BertTokenizer" if is_tokenizers_available() else None),
|
| 299 |
+
("stablelm", "GPTNeoXTokenizer" if is_tokenizers_available() else None),
|
| 300 |
+
("starcoder2", "GPT2Tokenizer" if is_tokenizers_available() else None),
|
| 301 |
+
("switch_transformers", "T5Tokenizer" if is_tokenizers_available() else None),
|
| 302 |
+
("t5", "T5Tokenizer" if is_tokenizers_available() else None),
|
| 303 |
+
("t5gemma", "GemmaTokenizer" if is_tokenizers_available() else None),
|
| 304 |
+
("tapas", "TapasTokenizer"),
|
| 305 |
+
("trocr", "XLMRobertaTokenizer" if is_tokenizers_available() else None),
|
| 306 |
+
("tvp", "BertTokenizer" if is_tokenizers_available() else None),
|
| 307 |
+
("udop", "UdopTokenizer" if is_tokenizers_available() else None),
|
| 308 |
+
("umt5", "T5Tokenizer" if is_tokenizers_available() else None),
|
| 309 |
+
("unispeech", "Wav2Vec2CTCTokenizer"),
|
| 310 |
+
("unispeech-sat", "Wav2Vec2CTCTokenizer"),
|
| 311 |
+
("vilt", "BertTokenizer" if is_tokenizers_available() else None),
|
| 312 |
+
("visual_bert", "BertTokenizer" if is_tokenizers_available() else None),
|
| 313 |
+
("vits", "VitsTokenizer"),
|
| 314 |
+
(
|
| 315 |
+
"voxtral",
|
| 316 |
+
"MistralCommonBackend"
|
| 317 |
+
if is_mistral_common_available()
|
| 318 |
+
else ("TokenizersBackend" if is_tokenizers_available() else None),
|
| 319 |
+
),
|
| 320 |
+
(
|
| 321 |
+
"voxtral_realtime",
|
| 322 |
+
"MistralCommonBackend"
|
| 323 |
+
if is_mistral_common_available()
|
| 324 |
+
else ("TokenizersBackend" if is_tokenizers_available() else None),
|
| 325 |
+
),
|
| 326 |
+
("wav2vec2", "Wav2Vec2CTCTokenizer"),
|
| 327 |
+
("wav2vec2-bert", "Wav2Vec2CTCTokenizer"),
|
| 328 |
+
("wav2vec2-conformer", "Wav2Vec2CTCTokenizer"),
|
| 329 |
+
("wav2vec2_phoneme", "Wav2Vec2PhonemeCTCTokenizer"),
|
| 330 |
+
("whisper", "WhisperTokenizer" if is_tokenizers_available() else None),
|
| 331 |
+
("xclip", "CLIPTokenizer" if is_tokenizers_available() else None),
|
| 332 |
+
("xglm", "XGLMTokenizer" if is_tokenizers_available() else None),
|
| 333 |
+
("xlm", "XLMTokenizer"),
|
| 334 |
+
("xlm-roberta", "XLMRobertaTokenizer" if is_tokenizers_available() else None),
|
| 335 |
+
("xlm-roberta-xl", "XLMRobertaTokenizer" if is_tokenizers_available() else None),
|
| 336 |
+
("xlnet", "XLNetTokenizer" if is_tokenizers_available() else None),
|
| 337 |
+
("xlstm", "GPTNeoXTokenizer" if is_tokenizers_available() else None),
|
| 338 |
+
("xmod", "XLMRobertaTokenizer" if is_tokenizers_available() else None),
|
| 339 |
+
("yoso", "AlbertTokenizer" if is_tokenizers_available() else None),
|
| 340 |
+
]
|
| 341 |
+
)
|
| 342 |
+
|
| 343 |
+
# Models with incorrect tokenizer_class in their Hub tokenizer_config.json files.
|
| 344 |
+
# These models will be forced to use TokenizersBackend.
|
| 345 |
+
MODELS_WITH_INCORRECT_HUB_TOKENIZER_CLASS: set[str] = {
|
| 346 |
+
"arctic",
|
| 347 |
+
"chameleon",
|
| 348 |
+
"chatlm",
|
| 349 |
+
"deepseek_v2",
|
| 350 |
+
"deepseek_v3",
|
| 351 |
+
"deepseek_vl",
|
| 352 |
+
"deepseek_vl_hybrid",
|
| 353 |
+
"deepseek_vl_v2",
|
| 354 |
+
"fuyu",
|
| 355 |
+
"h2ovl_chat",
|
| 356 |
+
"hyperclovax_vlm",
|
| 357 |
+
"internlm2",
|
| 358 |
+
"internvl_chat",
|
| 359 |
+
"jamba",
|
| 360 |
+
"janus",
|
| 361 |
+
"kimi_k25",
|
| 362 |
+
"llava",
|
| 363 |
+
"llava_next",
|
| 364 |
+
"minicpmv",
|
| 365 |
+
"minimax_m2",
|
| 366 |
+
"modernbert",
|
| 367 |
+
"molmo",
|
| 368 |
+
"molmo2",
|
| 369 |
+
"nemotron",
|
| 370 |
+
"nvfp4",
|
| 371 |
+
"opencua",
|
| 372 |
+
"openvla",
|
| 373 |
+
"phi3",
|
| 374 |
+
"phi3_v",
|
| 375 |
+
"phimoe",
|
| 376 |
+
"step3p5",
|
| 377 |
+
"vipllava",
|
| 378 |
+
"cohere_asr",
|
| 379 |
+
}
|
| 380 |
+
|
| 381 |
+
for model_type in MODELS_WITH_INCORRECT_HUB_TOKENIZER_CLASS:
|
| 382 |
+
if model_type not in TOKENIZER_MAPPING_NAMES:
|
| 383 |
+
TOKENIZER_MAPPING_NAMES[model_type] = "TokenizersBackend" if is_tokenizers_available() else None
|
| 384 |
+
|
| 385 |
+
TOKENIZER_MAPPING = _LazyAutoMapping(CONFIG_MAPPING_NAMES, TOKENIZER_MAPPING_NAMES)
|
| 386 |
+
|
| 387 |
+
CONFIG_TO_TYPE = {v: k for k, v in CONFIG_MAPPING_NAMES.items()}
|
| 388 |
+
|
| 389 |
+
|
| 390 |
+
def load_vocab(vocab_file):
|
| 391 |
+
"""Loads a vocabulary file into a dictionary."""
|
| 392 |
+
with open(vocab_file, "r", encoding="utf-8") as reader:
|
| 393 |
+
return json.load(reader)
|
| 394 |
+
|
| 395 |
+
|
| 396 |
+
def load_merges(merges_file):
|
| 397 |
+
"""Loads a merges file into a list."""
|
| 398 |
+
merges = []
|
| 399 |
+
with open(merges_file, "r", encoding="utf-8") as reader:
|
| 400 |
+
for line in reader:
|
| 401 |
+
line = line.strip()
|
| 402 |
+
if line and not line.startswith("#"):
|
| 403 |
+
merges.append(tuple(line.split()))
|
| 404 |
+
return merges
|
| 405 |
+
|
| 406 |
+
|
| 407 |
+
def tokenizer_class_from_name(class_name: str) -> type[Any] | None:
|
| 408 |
+
# Bloom tokenizer classes were removed but should map to the fast backend for BC
|
| 409 |
+
if class_name in {"BloomTokenizer", "BloomTokenizerFast"}:
|
| 410 |
+
return TokenizersBackend
|
| 411 |
+
|
| 412 |
+
if class_name in REGISTERED_FAST_ALIASES:
|
| 413 |
+
return REGISTERED_FAST_ALIASES[class_name]
|
| 414 |
+
|
| 415 |
+
if class_name in REGISTERED_TOKENIZER_CLASSES:
|
| 416 |
+
return REGISTERED_TOKENIZER_CLASSES[class_name]
|
| 417 |
+
|
| 418 |
+
if class_name == "TokenizersBackend":
|
| 419 |
+
return TokenizersBackend
|
| 420 |
+
|
| 421 |
+
# V5: TOKENIZER_MAPPING_NAMES now maps to single strings, not tuples
|
| 422 |
+
for module_name, tokenizer_class in TOKENIZER_MAPPING_NAMES.items():
|
| 423 |
+
if tokenizer_class == class_name:
|
| 424 |
+
module_name = model_type_to_module_name(module_name)
|
| 425 |
+
if (
|
| 426 |
+
module_name in ["mistral", "mistral3", "mixtral", "ministral", "ministral3", "pixtral", "voxtral"]
|
| 427 |
+
and class_name == "MistralCommonBackend"
|
| 428 |
+
):
|
| 429 |
+
module = importlib.import_module(".tokenization_mistral_common", "transformers")
|
| 430 |
+
else:
|
| 431 |
+
module = importlib.import_module(f".{module_name}", "transformers.models")
|
| 432 |
+
try:
|
| 433 |
+
result = getattr(module, class_name)
|
| 434 |
+
# BC v5: expose XxxFast alias and tokenization_*_fast submodule for pre-v5 remote code.
|
| 435 |
+
if (submod := getattr(result, "__module__", None)) and submod in sys.modules:
|
| 436 |
+
base_mod = sys.modules[submod]
|
| 437 |
+
setattr(base_mod, result.__name__ + "Fast", result)
|
| 438 |
+
sys.modules.setdefault(submod + "_fast", base_mod)
|
| 439 |
+
return result
|
| 440 |
+
except AttributeError:
|
| 441 |
+
continue
|
| 442 |
+
|
| 443 |
+
for tokenizer in TOKENIZER_MAPPING._extra_content.values():
|
| 444 |
+
if getattr(tokenizer, "__name__", None) == class_name:
|
| 445 |
+
return tokenizer
|
| 446 |
+
|
| 447 |
+
# We did not find the class, but maybe it's because a dep is missing. In that case, the class will be in the main
|
| 448 |
+
# We did not find the class, but maybe it's because a dep is missing. In that case, the class will be in the main
|
| 449 |
+
# init and we return the proper dummy to get an appropriate error message.
|
| 450 |
+
main_module = importlib.import_module("transformers")
|
| 451 |
+
if hasattr(main_module, class_name):
|
| 452 |
+
return getattr(main_module, class_name)
|
| 453 |
+
|
| 454 |
+
# BC v5: If a XxxFast class is not found, retry without 'Fast' for tokenizers saved pre-v5.
|
| 455 |
+
if class_name.endswith("Fast"):
|
| 456 |
+
return tokenizer_class_from_name(class_name[:-4])
|
| 457 |
+
|
| 458 |
+
return None
|
| 459 |
+
|
| 460 |
+
|
| 461 |
+
def get_tokenizer_config(
|
| 462 |
+
pretrained_model_name_or_path: str | os.PathLike[str],
|
| 463 |
+
cache_dir: str | os.PathLike[str] | None = None,
|
| 464 |
+
force_download: bool = False,
|
| 465 |
+
proxies: dict[str, str] | None = None,
|
| 466 |
+
token: bool | str | None = None,
|
| 467 |
+
revision: str | None = None,
|
| 468 |
+
local_files_only: bool = False,
|
| 469 |
+
subfolder: str = "",
|
| 470 |
+
**kwargs,
|
| 471 |
+
) -> dict[str, Any]:
|
| 472 |
+
"""
|
| 473 |
+
Loads the tokenizer configuration from a pretrained model tokenizer configuration.
|
| 474 |
+
|
| 475 |
+
Args:
|
| 476 |
+
pretrained_model_name_or_path (`str` or `os.PathLike`):
|
| 477 |
+
This can be either:
|
| 478 |
+
|
| 479 |
+
- a string, the *model id* of a pretrained model configuration hosted inside a model repo on
|
| 480 |
+
huggingface.co.
|
| 481 |
+
- a path to a *directory* containing a configuration file saved using the
|
| 482 |
+
[`~PreTrainedTokenizer.save_pretrained`] method, e.g., `./my_model_directory/`.
|
| 483 |
+
|
| 484 |
+
cache_dir (`str` or `os.PathLike`, *optional*):
|
| 485 |
+
Path to a directory in which a downloaded pretrained model configuration should be cached if the standard
|
| 486 |
+
cache should not be used.
|
| 487 |
+
force_download (`bool`, *optional*, defaults to `False`):
|
| 488 |
+
Whether or not to force to (re-)download the configuration files and override the cached versions if they
|
| 489 |
+
exist.
|
| 490 |
+
proxies (`dict[str, str]`, *optional*):
|
| 491 |
+
A dictionary of proxy servers to use by protocol or endpoint, e.g., `{'http': 'foo.bar:3128',
|
| 492 |
+
'http://hostname': 'foo.bar:4012'}.` The proxies are used on each request.
|
| 493 |
+
token (`str` or *bool*, *optional*):
|
| 494 |
+
The token to use as HTTP bearer authorization for remote files. If `True`, will use the token generated
|
| 495 |
+
when running `hf auth login` (stored in `~/.huggingface`).
|
| 496 |
+
revision (`str`, *optional*, defaults to `"main"`):
|
| 497 |
+
The specific model version to use. It can be a branch name, a tag name, or a commit id, since we use a
|
| 498 |
+
git-based system for storing models and other artifacts on huggingface.co, so `revision` can be any
|
| 499 |
+
identifier allowed by git.
|
| 500 |
+
local_files_only (`bool`, *optional*, defaults to `False`):
|
| 501 |
+
If `True`, will only try to load the tokenizer configuration from local files.
|
| 502 |
+
subfolder (`str`, *optional*, defaults to `""`):
|
| 503 |
+
In case the tokenizer config is located inside a subfolder of the model repo on huggingface.co, you can
|
| 504 |
+
specify the folder name here.
|
| 505 |
+
|
| 506 |
+
<Tip>
|
| 507 |
+
|
| 508 |
+
Passing `token=True` is required when you want to use a private model.
|
| 509 |
+
|
| 510 |
+
</Tip>
|
| 511 |
+
|
| 512 |
+
Returns:
|
| 513 |
+
`dict`: The configuration of the tokenizer.
|
| 514 |
+
|
| 515 |
+
Examples:
|
| 516 |
+
|
| 517 |
+
```python
|
| 518 |
+
# Download configuration from huggingface.co and cache.
|
| 519 |
+
tokenizer_config = get_tokenizer_config("google-bert/bert-base-uncased")
|
| 520 |
+
# This model does not have a tokenizer config so the result will be an empty dict.
|
| 521 |
+
tokenizer_config = get_tokenizer_config("FacebookAI/xlm-roberta-base")
|
| 522 |
+
|
| 523 |
+
# Save a pretrained tokenizer locally and you can reload its config
|
| 524 |
+
from transformers import AutoTokenizer
|
| 525 |
+
|
| 526 |
+
tokenizer = AutoTokenizer.from_pretrained("google-bert/bert-base-cased")
|
| 527 |
+
tokenizer.save_pretrained("tokenizer-test")
|
| 528 |
+
tokenizer_config = get_tokenizer_config("tokenizer-test")
|
| 529 |
+
```"""
|
| 530 |
+
commit_hash = kwargs.get("_commit_hash")
|
| 531 |
+
resolved_config_file = cached_file(
|
| 532 |
+
pretrained_model_name_or_path,
|
| 533 |
+
TOKENIZER_CONFIG_FILE,
|
| 534 |
+
cache_dir=cache_dir,
|
| 535 |
+
force_download=force_download,
|
| 536 |
+
proxies=proxies,
|
| 537 |
+
token=token,
|
| 538 |
+
revision=revision,
|
| 539 |
+
local_files_only=local_files_only,
|
| 540 |
+
subfolder=subfolder,
|
| 541 |
+
_raise_exceptions_for_gated_repo=False,
|
| 542 |
+
_raise_exceptions_for_missing_entries=False,
|
| 543 |
+
_raise_exceptions_for_connection_errors=False,
|
| 544 |
+
_commit_hash=commit_hash,
|
| 545 |
+
)
|
| 546 |
+
if resolved_config_file is None:
|
| 547 |
+
logger.info("Could not locate the tokenizer configuration file, will try to use the model config instead.")
|
| 548 |
+
return {}
|
| 549 |
+
commit_hash = extract_commit_hash(resolved_config_file, commit_hash)
|
| 550 |
+
|
| 551 |
+
with open(resolved_config_file, encoding="utf-8") as reader:
|
| 552 |
+
result = json.load(reader)
|
| 553 |
+
result["_commit_hash"] = commit_hash
|
| 554 |
+
return result
|
| 555 |
+
|
| 556 |
+
|
| 557 |
+
class AutoTokenizer:
|
| 558 |
+
r"""
|
| 559 |
+
This is a generic tokenizer class that will be instantiated as one of the tokenizer classes of the library when
|
| 560 |
+
created with the [`AutoTokenizer.from_pretrained`] class method.
|
| 561 |
+
|
| 562 |
+
This class cannot be instantiated directly using `__init__()` (throws an error).
|
| 563 |
+
"""
|
| 564 |
+
|
| 565 |
+
def __init__(self):
|
| 566 |
+
raise OSError(
|
| 567 |
+
"AutoTokenizer is designed to be instantiated "
|
| 568 |
+
"using the `AutoTokenizer.from_pretrained(pretrained_model_name_or_path)` method."
|
| 569 |
+
)
|
| 570 |
+
|
| 571 |
+
@classmethod
|
| 572 |
+
@replace_list_option_in_docstrings(TOKENIZER_MAPPING_NAMES)
|
| 573 |
+
def from_pretrained(
|
| 574 |
+
cls, pretrained_model_name_or_path, *inputs, **kwargs
|
| 575 |
+
) -> TokenizersBackend | SentencePieceBackend:
|
| 576 |
+
r"""
|
| 577 |
+
Instantiate one of the tokenizer classes of the library from a pretrained model vocabulary.
|
| 578 |
+
|
| 579 |
+
The tokenizer class to instantiate is selected based on the `model_type` property of the config object (either
|
| 580 |
+
passed as an argument or loaded from `pretrained_model_name_or_path` if possible), or when it's missing, by
|
| 581 |
+
falling back to using pattern matching on `pretrained_model_name_or_path`:
|
| 582 |
+
|
| 583 |
+
List options
|
| 584 |
+
|
| 585 |
+
Params:
|
| 586 |
+
pretrained_model_name_or_path (`str` or `os.PathLike`):
|
| 587 |
+
Can be either:
|
| 588 |
+
|
| 589 |
+
- A string, the *model id* of a predefined tokenizer hosted inside a model repo on huggingface.co.
|
| 590 |
+
- A path to a *directory* containing vocabulary files required by the tokenizer, for instance saved
|
| 591 |
+
using the [`~PreTrainedTokenizer.save_pretrained`] method, e.g., `./my_model_directory/`.
|
| 592 |
+
- a path to a single saved vocabulary file if and only if the tokenizer only requires a
|
| 593 |
+
single vocabulary file (like Bert or XLNet), e.g.: `./my_model_directory/vocab.txt`. (Not
|
| 594 |
+
applicable to all derived classes)
|
| 595 |
+
inputs (additional positional arguments, *optional*):
|
| 596 |
+
Will be passed along to the Tokenizer `__init__()` method.
|
| 597 |
+
config ([`PreTrainedConfig`], *optional*)
|
| 598 |
+
The configuration object used to determine the tokenizer class to instantiate.
|
| 599 |
+
cache_dir (`str` or `os.PathLike`, *optional*):
|
| 600 |
+
Path to a directory in which a downloaded pretrained model configuration should be cached if the
|
| 601 |
+
standard cache should not be used.
|
| 602 |
+
force_download (`bool`, *optional*, defaults to `False`):
|
| 603 |
+
Whether or not to force the (re-)download the model weights and configuration files and override the
|
| 604 |
+
cached versions if they exist.
|
| 605 |
+
proxies (`dict[str, str]`, *optional*):
|
| 606 |
+
A dictionary of proxy servers to use by protocol or endpoint, e.g., `{'http': 'foo.bar:3128',
|
| 607 |
+
'http://hostname': 'foo.bar:4012'}`. The proxies are used on each request.
|
| 608 |
+
revision (`str`, *optional*, defaults to `"main"`):
|
| 609 |
+
The specific model version to use. It can be a branch name, a tag name, or a commit id, since we use a
|
| 610 |
+
git-based system for storing models and other artifacts on huggingface.co, so `revision` can be any
|
| 611 |
+
identifier allowed by git.
|
| 612 |
+
subfolder (`str`, *optional*):
|
| 613 |
+
In case the relevant files are located inside a subfolder of the model repo on huggingface.co (e.g. for
|
| 614 |
+
facebook/rag-token-base), specify it here.
|
| 615 |
+
tokenizer_type (`str`, *optional*):
|
| 616 |
+
Tokenizer type to be loaded.
|
| 617 |
+
backend (`str`, *optional*, defaults to `"tokenizers"`):
|
| 618 |
+
Backend to use for tokenization. Valid options are:
|
| 619 |
+
- `"tokenizers"`: Use the HuggingFace tokenizers library backend (default)
|
| 620 |
+
- `"sentencepiece"`: Use the SentencePiece backend
|
| 621 |
+
trust_remote_code (`bool`, *optional*, defaults to `False`):
|
| 622 |
+
Whether or not to allow for custom models defined on the Hub in their own modeling files. This option
|
| 623 |
+
should only be set to `True` for repositories you trust and in which you have read the code, as it will
|
| 624 |
+
execute code present on the Hub on your local machine.
|
| 625 |
+
kwargs (additional keyword arguments, *optional*):
|
| 626 |
+
Will be passed to the Tokenizer `__init__()` method. Can be used to set special tokens like
|
| 627 |
+
`bos_token`, `eos_token`, `unk_token`, `sep_token`, `pad_token`, `cls_token`, `mask_token`,
|
| 628 |
+
`additional_special_tokens`. See parameters in the `__init__()` for more details.
|
| 629 |
+
|
| 630 |
+
Examples:
|
| 631 |
+
|
| 632 |
+
```python
|
| 633 |
+
>>> from transformers import AutoTokenizer
|
| 634 |
+
|
| 635 |
+
>>> # Download vocabulary from huggingface.co and cache.
|
| 636 |
+
>>> tokenizer = AutoTokenizer.from_pretrained("google-bert/bert-base-uncased")
|
| 637 |
+
|
| 638 |
+
>>> # Download vocabulary from huggingface.co (user-uploaded) and cache.
|
| 639 |
+
>>> tokenizer = AutoTokenizer.from_pretrained("dbmdz/bert-base-german-cased")
|
| 640 |
+
|
| 641 |
+
>>> # If vocabulary files are in a directory (e.g. tokenizer was saved using *save_pretrained('./test/saved_model/')*)
|
| 642 |
+
>>> # tokenizer = AutoTokenizer.from_pretrained("./test/bert_saved_model/")
|
| 643 |
+
|
| 644 |
+
>>> # Download vocabulary from huggingface.co and define model-specific arguments
|
| 645 |
+
>>> tokenizer = AutoTokenizer.from_pretrained("FacebookAI/roberta-base", add_prefix_space=True)
|
| 646 |
+
|
| 647 |
+
>>> # Explicitly use the tokenizers backend
|
| 648 |
+
>>> tokenizer = AutoTokenizer.from_pretrained("hf-internal-testing/llama-tokenizer", backend="tokenizers")
|
| 649 |
+
|
| 650 |
+
>>> # Explicitly use the sentencepiece backend
|
| 651 |
+
>>> tokenizer = AutoTokenizer.from_pretrained("hf-internal-testing/llama-tokenizer", backend="sentencepiece")
|
| 652 |
+
```"""
|
| 653 |
+
config = kwargs.pop("config", None)
|
| 654 |
+
kwargs["_from_auto"] = True
|
| 655 |
+
|
| 656 |
+
# V5: Always use fast tokenizers, ignore use_fast parameter
|
| 657 |
+
_ = kwargs.pop("use_fast", None)
|
| 658 |
+
tokenizer_type = kwargs.pop("tokenizer_type", None)
|
| 659 |
+
trust_remote_code = kwargs.pop("trust_remote_code", None)
|
| 660 |
+
gguf_file = kwargs.get("gguf_file")
|
| 661 |
+
|
| 662 |
+
# First, let's see whether the tokenizer_type is passed so that we can leverage it
|
| 663 |
+
if tokenizer_type is not None:
|
| 664 |
+
tokenizer_class_name = TOKENIZER_MAPPING_NAMES.get(tokenizer_type, None)
|
| 665 |
+
|
| 666 |
+
if tokenizer_class_name is None:
|
| 667 |
+
raise ValueError(
|
| 668 |
+
f"Passed `tokenizer_type` {tokenizer_type} does not exist. `tokenizer_type` should be one of "
|
| 669 |
+
f"{', '.join(c for c in TOKENIZER_MAPPING_NAMES)}."
|
| 670 |
+
)
|
| 671 |
+
|
| 672 |
+
tokenizer_class = tokenizer_class_from_name(tokenizer_class_name)
|
| 673 |
+
|
| 674 |
+
if tokenizer_class is None:
|
| 675 |
+
raise ValueError(f"Tokenizer class {tokenizer_class_name} is not currently imported.")
|
| 676 |
+
|
| 677 |
+
return tokenizer_class.from_pretrained(pretrained_model_name_or_path, *inputs, **kwargs)
|
| 678 |
+
|
| 679 |
+
if gguf_file:
|
| 680 |
+
gguf_path = cached_file(pretrained_model_name_or_path, gguf_file, **kwargs)
|
| 681 |
+
config_dict = load_gguf_checkpoint(gguf_path, return_tensors=False)["config"]
|
| 682 |
+
config = AutoConfig.for_model(**config_dict)
|
| 683 |
+
elif config is None:
|
| 684 |
+
try:
|
| 685 |
+
config = AutoConfig.from_pretrained(
|
| 686 |
+
pretrained_model_name_or_path, trust_remote_code=trust_remote_code, **kwargs
|
| 687 |
+
)
|
| 688 |
+
except (ValueError, OSError):
|
| 689 |
+
config = PreTrainedConfig.from_pretrained(pretrained_model_name_or_path, **kwargs)
|
| 690 |
+
|
| 691 |
+
config_model_type = config.model_type
|
| 692 |
+
|
| 693 |
+
# Next, let's try to use the tokenizer_config file to get the tokenizer class.
|
| 694 |
+
tokenizer_config = get_tokenizer_config(pretrained_model_name_or_path, **kwargs)
|
| 695 |
+
tokenizer_config_class = tokenizer_config.get("tokenizer_class", None)
|
| 696 |
+
|
| 697 |
+
# Check for auto_map early to handle dynamic tokenizers properly
|
| 698 |
+
tokenizer_auto_map = None
|
| 699 |
+
if "auto_map" in tokenizer_config:
|
| 700 |
+
if isinstance(tokenizer_config["auto_map"], (tuple, list)):
|
| 701 |
+
# Legacy format for dynamic tokenizers
|
| 702 |
+
tokenizer_auto_map = tokenizer_config["auto_map"]
|
| 703 |
+
else:
|
| 704 |
+
tokenizer_auto_map = tokenizer_config["auto_map"].get("AutoTokenizer", None)
|
| 705 |
+
|
| 706 |
+
# if there is a config, we can check that the tokenizer class != than model class and can thus assume we need to use TokenizersBackend
|
| 707 |
+
# Skip this early exit if auto_map is present (custom tokenizer with trust_remote_code)
|
| 708 |
+
if (
|
| 709 |
+
tokenizer_auto_map is None
|
| 710 |
+
and tokenizer_config_class is not None
|
| 711 |
+
and config_model_type is not None
|
| 712 |
+
and config_model_type != ""
|
| 713 |
+
and TOKENIZER_MAPPING_NAMES.get(config_model_type) is not None
|
| 714 |
+
and (TOKENIZER_MAPPING_NAMES.get(config_model_type).removesuffix("Fast"))
|
| 715 |
+
!= (tokenizer_config_class.removesuffix("Fast"))
|
| 716 |
+
):
|
| 717 |
+
# new model, but we ignore it unless the model type is the same
|
| 718 |
+
if TokenizersBackend is not None:
|
| 719 |
+
try:
|
| 720 |
+
return TokenizersBackend.from_pretrained(pretrained_model_name_or_path, *inputs, **kwargs)
|
| 721 |
+
except Exception as e:
|
| 722 |
+
logger.debug(f"Failed to use TokenizersBackend: {e}")
|
| 723 |
+
|
| 724 |
+
return tokenizer_class_from_name(tokenizer_config_class).from_pretrained(
|
| 725 |
+
pretrained_model_name_or_path, *inputs, **kwargs
|
| 726 |
+
)
|
| 727 |
+
|
| 728 |
+
if "_commit_hash" in tokenizer_config:
|
| 729 |
+
kwargs["_commit_hash"] = tokenizer_config["_commit_hash"]
|
| 730 |
+
|
| 731 |
+
if tokenizer_config_class and tokenizer_config_class.endswith("Fast"):
|
| 732 |
+
tokenizer_config_class = tokenizer_config_class[:-4]
|
| 733 |
+
|
| 734 |
+
has_remote_code = tokenizer_auto_map is not None
|
| 735 |
+
has_local_code = type(config) in TOKENIZER_MAPPING or (
|
| 736 |
+
tokenizer_config_class is not None
|
| 737 |
+
and (
|
| 738 |
+
tokenizer_class_from_name(tokenizer_config_class) is not None
|
| 739 |
+
or tokenizer_class_from_name(tokenizer_config_class + "Fast") is not None
|
| 740 |
+
)
|
| 741 |
+
)
|
| 742 |
+
explicit_local_code = (
|
| 743 |
+
has_local_code
|
| 744 |
+
and type(config) not in TOKENIZER_MAPPING
|
| 745 |
+
and (
|
| 746 |
+
tokenizer_config_class is not None
|
| 747 |
+
and not (
|
| 748 |
+
tokenizer_class_from_name(tokenizer_config_class)
|
| 749 |
+
or tokenizer_class_from_name(tokenizer_config_class + "Fast")
|
| 750 |
+
).__module__.startswith("transformers.")
|
| 751 |
+
)
|
| 752 |
+
)
|
| 753 |
+
# V5: Skip remote tokenizer for custom models with incorrect hub tokenizer class
|
| 754 |
+
if has_remote_code and config_model_type in MODELS_WITH_INCORRECT_HUB_TOKENIZER_CLASS:
|
| 755 |
+
has_remote_code = False
|
| 756 |
+
tokenizer_auto_map = None
|
| 757 |
+
|
| 758 |
+
if has_remote_code:
|
| 759 |
+
# V5: Always prefer fast tokenizer (index 1), fallback to slow (index 0)
|
| 760 |
+
if tokenizer_auto_map[1] is not None:
|
| 761 |
+
class_ref = tokenizer_auto_map[1]
|
| 762 |
+
else:
|
| 763 |
+
class_ref = tokenizer_auto_map[0]
|
| 764 |
+
if "--" in class_ref:
|
| 765 |
+
upstream_repo = class_ref.split("--")[0]
|
| 766 |
+
else:
|
| 767 |
+
upstream_repo = None
|
| 768 |
+
trust_remote_code = resolve_trust_remote_code(
|
| 769 |
+
trust_remote_code, pretrained_model_name_or_path, has_local_code, has_remote_code, upstream_repo
|
| 770 |
+
)
|
| 771 |
+
|
| 772 |
+
if has_remote_code and trust_remote_code and not explicit_local_code:
|
| 773 |
+
# BC v5: register *Fast aliases before remote code loads.
|
| 774 |
+
if tokenizer_config_class:
|
| 775 |
+
tokenizer_class_from_name(tokenizer_config_class.removesuffix("Fast"))
|
| 776 |
+
tokenizer_class = get_class_from_dynamic_module(class_ref, pretrained_model_name_or_path, **kwargs)
|
| 777 |
+
_ = kwargs.pop("code_revision", None)
|
| 778 |
+
tokenizer_class.register_for_auto_class()
|
| 779 |
+
return tokenizer_class.from_pretrained(
|
| 780 |
+
pretrained_model_name_or_path, *inputs, trust_remote_code=trust_remote_code, **kwargs
|
| 781 |
+
)
|
| 782 |
+
elif tokenizer_config_class is not None:
|
| 783 |
+
tokenizer_class_candidate = tokenizer_config_class
|
| 784 |
+
tokenizer_class = tokenizer_class_from_name(tokenizer_class_candidate)
|
| 785 |
+
if tokenizer_class is None and not tokenizer_class_candidate.endswith("Fast"):
|
| 786 |
+
tokenizer_class = tokenizer_class_from_name(tokenizer_class_candidate + "Fast")
|
| 787 |
+
if tokenizer_class is not None and tokenizer_class.__name__ == "PythonBackend":
|
| 788 |
+
tokenizer_class = TokenizersBackend
|
| 789 |
+
# Fallback to TokenizersBackend if the class wasn't found
|
| 790 |
+
if tokenizer_class is None:
|
| 791 |
+
tokenizer_class = TokenizersBackend
|
| 792 |
+
|
| 793 |
+
return tokenizer_class.from_pretrained(pretrained_model_name_or_path, *inputs, **kwargs)
|
| 794 |
+
elif getattr(config, "tokenizer_class", None):
|
| 795 |
+
_class = config.tokenizer_class
|
| 796 |
+
if "PreTrainedTokenizerFast" not in _class and _class.endswith("Fast"):
|
| 797 |
+
_class = _class[:-4]
|
| 798 |
+
tokenizer_class = tokenizer_class_from_name(_class)
|
| 799 |
+
return tokenizer_class.from_pretrained(pretrained_model_name_or_path, *inputs, **kwargs)
|
| 800 |
+
|
| 801 |
+
# Otherwise we have to be creative.
|
| 802 |
+
# if model is an encoder decoder, the encoder tokenizer class is used by default
|
| 803 |
+
if isinstance(config, EncoderDecoderConfig):
|
| 804 |
+
if type(config.decoder) is not type(config.encoder):
|
| 805 |
+
logger.warning(
|
| 806 |
+
f"The encoder model config class: {config.encoder.__class__} is different from the decoder model "
|
| 807 |
+
f"config class: {config.decoder.__class__}. It is not recommended to use the "
|
| 808 |
+
"`AutoTokenizer.from_pretrained()` method in this case. Please use the encoder and decoder "
|
| 809 |
+
"specific tokenizer classes."
|
| 810 |
+
)
|
| 811 |
+
config = config.encoder
|
| 812 |
+
|
| 813 |
+
model_type = config_class_to_model_type(type(config).__name__) or getattr(config, "model_type", None)
|
| 814 |
+
if model_type is not None:
|
| 815 |
+
tokenizer_class = TOKENIZER_MAPPING.get(type(config), TokenizersBackend)
|
| 816 |
+
if tokenizer_class is not None:
|
| 817 |
+
return tokenizer_class.from_pretrained(pretrained_model_name_or_path, *inputs, **kwargs)
|
| 818 |
+
|
| 819 |
+
# Fallback: try tokenizer_class from tokenizer_config.json
|
| 820 |
+
tokenizer_config_class = tokenizer_config.get("tokenizer_class", None)
|
| 821 |
+
if tokenizer_config_class is not None:
|
| 822 |
+
if tokenizer_config_class != "TokenizersBackend" and tokenizer_config_class.endswith("Fast"):
|
| 823 |
+
tokenizer_config_class = tokenizer_config_class[:-4]
|
| 824 |
+
tokenizer_class = tokenizer_class_from_name(tokenizer_config_class)
|
| 825 |
+
if tokenizer_class is None and not tokenizer_config_class.endswith("Fast"):
|
| 826 |
+
tokenizer_class = tokenizer_class_from_name(tokenizer_config_class + "Fast")
|
| 827 |
+
if tokenizer_class is not None and tokenizer_class.__name__ == "PythonBackend":
|
| 828 |
+
tokenizer_class = TokenizersBackend
|
| 829 |
+
if tokenizer_class is None:
|
| 830 |
+
tokenizer_class = TokenizersBackend
|
| 831 |
+
return tokenizer_class.from_pretrained(pretrained_model_name_or_path, *inputs, **kwargs)
|
| 832 |
+
|
| 833 |
+
raise ValueError(
|
| 834 |
+
f"Unrecognized configuration class {config.__class__} to build an AutoTokenizer.\n"
|
| 835 |
+
f"Model type should be one of {', '.join(c.__name__ for c in TOKENIZER_MAPPING)}."
|
| 836 |
+
)
|
| 837 |
+
|
| 838 |
+
@staticmethod
|
| 839 |
+
def register(
|
| 840 |
+
config_class, tokenizer_class=None, slow_tokenizer_class=None, fast_tokenizer_class=None, exist_ok=False
|
| 841 |
+
):
|
| 842 |
+
"""
|
| 843 |
+
Register a new tokenizer in this mapping.
|
| 844 |
+
|
| 845 |
+
Args:
|
| 846 |
+
config_class ([`PreTrainedConfig`]):
|
| 847 |
+
The configuration corresponding to the model to register.
|
| 848 |
+
tokenizer_class: The tokenizer class to register (V5 - preferred parameter).
|
| 849 |
+
slow_tokenizer_class: (Deprecated) The slow tokenizer to register.
|
| 850 |
+
fast_tokenizer_class: (Deprecated) The fast tokenizer to register.
|
| 851 |
+
"""
|
| 852 |
+
if tokenizer_class is None:
|
| 853 |
+
# Legacy: prefer fast over slow
|
| 854 |
+
if fast_tokenizer_class is not None:
|
| 855 |
+
tokenizer_class = fast_tokenizer_class
|
| 856 |
+
elif slow_tokenizer_class is not None:
|
| 857 |
+
tokenizer_class = slow_tokenizer_class
|
| 858 |
+
else:
|
| 859 |
+
raise ValueError("You need to pass a `tokenizer_class`")
|
| 860 |
+
|
| 861 |
+
for candidate in (slow_tokenizer_class, fast_tokenizer_class, tokenizer_class):
|
| 862 |
+
if candidate is not None:
|
| 863 |
+
REGISTERED_TOKENIZER_CLASSES[candidate.__name__] = candidate
|
| 864 |
+
|
| 865 |
+
if slow_tokenizer_class is not None and fast_tokenizer_class is not None:
|
| 866 |
+
REGISTERED_FAST_ALIASES[slow_tokenizer_class.__name__] = fast_tokenizer_class
|
| 867 |
+
|
| 868 |
+
TOKENIZER_MAPPING.register(config_class, tokenizer_class, exist_ok=exist_ok)
|
| 869 |
+
|
| 870 |
+
|
| 871 |
+
__all__ = ["TOKENIZER_MAPPING", "AutoTokenizer"]
|
third_party/transformers/src/transformers/models/auto/video_processing_auto.py
ADDED
|
@@ -0,0 +1,424 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright 2025 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 |
+
"""AutoVideoProcessor class."""
|
| 15 |
+
|
| 16 |
+
import importlib
|
| 17 |
+
import os
|
| 18 |
+
from collections import OrderedDict
|
| 19 |
+
from typing import TYPE_CHECKING
|
| 20 |
+
|
| 21 |
+
# Build the list of all video processors
|
| 22 |
+
from ...configuration_utils import PreTrainedConfig
|
| 23 |
+
from ...dynamic_module_utils import get_class_from_dynamic_module, resolve_trust_remote_code
|
| 24 |
+
from ...utils import (
|
| 25 |
+
CONFIG_NAME,
|
| 26 |
+
IMAGE_PROCESSOR_NAME,
|
| 27 |
+
PROCESSOR_NAME,
|
| 28 |
+
VIDEO_PROCESSOR_NAME,
|
| 29 |
+
cached_file,
|
| 30 |
+
is_torchvision_available,
|
| 31 |
+
logging,
|
| 32 |
+
safe_load_json_file,
|
| 33 |
+
)
|
| 34 |
+
from ...utils.import_utils import requires
|
| 35 |
+
from ...video_processing_utils import BaseVideoProcessor
|
| 36 |
+
from .auto_factory import _LazyAutoMapping
|
| 37 |
+
from .configuration_auto import (
|
| 38 |
+
CONFIG_MAPPING_NAMES,
|
| 39 |
+
AutoConfig,
|
| 40 |
+
model_type_to_module_name,
|
| 41 |
+
replace_list_option_in_docstrings,
|
| 42 |
+
)
|
| 43 |
+
|
| 44 |
+
|
| 45 |
+
logger = logging.get_logger(__name__)
|
| 46 |
+
|
| 47 |
+
|
| 48 |
+
if TYPE_CHECKING:
|
| 49 |
+
# This significantly improves completion suggestion performance when
|
| 50 |
+
# the transformers package is used with Microsoft's Pylance language server.
|
| 51 |
+
VIDEO_PROCESSOR_MAPPING_NAMES: OrderedDict[str, tuple[str | None, str | None]] = OrderedDict()
|
| 52 |
+
else:
|
| 53 |
+
VIDEO_PROCESSOR_MAPPING_NAMES = OrderedDict(
|
| 54 |
+
[
|
| 55 |
+
("ernie4_5_vl_moe", "Ernie4_5_VLMoeVideoProcessor"),
|
| 56 |
+
("gemma4", "Gemma4VideoProcessor"),
|
| 57 |
+
("glm46v", "Glm46VVideoProcessor"),
|
| 58 |
+
("glm4v", "Glm4vVideoProcessor"),
|
| 59 |
+
("instructblip", "InstructBlipVideoVideoProcessor"),
|
| 60 |
+
("instructblipvideo", "InstructBlipVideoVideoProcessor"),
|
| 61 |
+
("internvl", "InternVLVideoProcessor"),
|
| 62 |
+
("llava_next_video", "LlavaNextVideoVideoProcessor"),
|
| 63 |
+
("llava_onevision", "LlavaOnevisionVideoProcessor"),
|
| 64 |
+
("pe_audio_video", "PeVideoVideoProcessor"),
|
| 65 |
+
("pe_video", "PeVideoVideoProcessor"),
|
| 66 |
+
("perception_lm", "PerceptionLMVideoProcessor"),
|
| 67 |
+
("qwen2_5_omni", "Qwen2VLVideoProcessor"),
|
| 68 |
+
("qwen2_5_vl", "Qwen2VLVideoProcessor"),
|
| 69 |
+
("qwen2_vl", "Qwen2VLVideoProcessor"),
|
| 70 |
+
("qwen3_5", "Qwen3VLVideoProcessor"),
|
| 71 |
+
("qwen3_5_moe", "Qwen3VLVideoProcessor"),
|
| 72 |
+
("qwen3_omni_moe", "Qwen2VLVideoProcessor"),
|
| 73 |
+
("qwen3_vl", "Qwen3VLVideoProcessor"),
|
| 74 |
+
("qwen3_vl_moe", "Qwen3VLVideoProcessor"),
|
| 75 |
+
("sam2_video", "Sam2VideoVideoProcessor"),
|
| 76 |
+
("sam3_video", "Sam3VideoVideoProcessor"),
|
| 77 |
+
("smolvlm", "SmolVLMVideoProcessor"),
|
| 78 |
+
("video_llama_3", "VideoLlama3VideoProcessor"),
|
| 79 |
+
("video_llava", "VideoLlavaVideoProcessor"),
|
| 80 |
+
("videomae", "VideoMAEVideoProcessor"),
|
| 81 |
+
("videomt", "VideomtVideoProcessor"),
|
| 82 |
+
("vjepa2", "VJEPA2VideoProcessor"),
|
| 83 |
+
]
|
| 84 |
+
)
|
| 85 |
+
|
| 86 |
+
for model_type, video_processors in VIDEO_PROCESSOR_MAPPING_NAMES.items():
|
| 87 |
+
fast_video_processor_class = video_processors
|
| 88 |
+
|
| 89 |
+
# If the torchvision is not available, we set it to None
|
| 90 |
+
if not is_torchvision_available():
|
| 91 |
+
fast_video_processor_class = None
|
| 92 |
+
|
| 93 |
+
VIDEO_PROCESSOR_MAPPING_NAMES[model_type] = fast_video_processor_class
|
| 94 |
+
|
| 95 |
+
VIDEO_PROCESSOR_MAPPING = _LazyAutoMapping(CONFIG_MAPPING_NAMES, VIDEO_PROCESSOR_MAPPING_NAMES)
|
| 96 |
+
|
| 97 |
+
|
| 98 |
+
def video_processor_class_from_name(class_name: str):
|
| 99 |
+
for module_name, extractor in VIDEO_PROCESSOR_MAPPING_NAMES.items():
|
| 100 |
+
if class_name == extractor:
|
| 101 |
+
module_name = model_type_to_module_name(module_name)
|
| 102 |
+
|
| 103 |
+
module = importlib.import_module(f".{module_name}", "transformers.models")
|
| 104 |
+
try:
|
| 105 |
+
return getattr(module, class_name)
|
| 106 |
+
except AttributeError:
|
| 107 |
+
continue
|
| 108 |
+
|
| 109 |
+
for extractor in VIDEO_PROCESSOR_MAPPING._extra_content.values():
|
| 110 |
+
if getattr(extractor, "__name__", None) == class_name:
|
| 111 |
+
return extractor
|
| 112 |
+
|
| 113 |
+
# We did not find the class, but maybe it's because a dep is missing. In that case, the class will be in the main
|
| 114 |
+
# init and we return the proper dummy to get an appropriate error message.
|
| 115 |
+
main_module = importlib.import_module("transformers")
|
| 116 |
+
if hasattr(main_module, class_name):
|
| 117 |
+
return getattr(main_module, class_name)
|
| 118 |
+
|
| 119 |
+
return None
|
| 120 |
+
|
| 121 |
+
|
| 122 |
+
def get_video_processor_config(
|
| 123 |
+
pretrained_model_name_or_path: str | os.PathLike,
|
| 124 |
+
cache_dir: str | os.PathLike | None = None,
|
| 125 |
+
force_download: bool = False,
|
| 126 |
+
proxies: dict[str, str] | None = None,
|
| 127 |
+
token: bool | str | None = None,
|
| 128 |
+
revision: str | None = None,
|
| 129 |
+
local_files_only: bool = False,
|
| 130 |
+
**kwargs,
|
| 131 |
+
):
|
| 132 |
+
"""
|
| 133 |
+
Loads the video processor configuration from a pretrained model video processor configuration.
|
| 134 |
+
|
| 135 |
+
Args:
|
| 136 |
+
pretrained_model_name_or_path (`str` or `os.PathLike`):
|
| 137 |
+
This can be either:
|
| 138 |
+
|
| 139 |
+
- a string, the *model id* of a pretrained model configuration hosted inside a model repo on
|
| 140 |
+
huggingface.co.
|
| 141 |
+
- a path to a *directory* containing a configuration file saved using the
|
| 142 |
+
[`~BaseVideoProcessor.save_pretrained`] method, e.g., `./my_model_directory/`.
|
| 143 |
+
|
| 144 |
+
cache_dir (`str` or `os.PathLike`, *optional*):
|
| 145 |
+
Path to a directory in which a downloaded pretrained model configuration should be cached if the standard
|
| 146 |
+
cache should not be used.
|
| 147 |
+
force_download (`bool`, *optional*, defaults to `False`):
|
| 148 |
+
Whether or not to force to (re-)download the configuration files and override the cached versions if they
|
| 149 |
+
exist.
|
| 150 |
+
proxies (`dict[str, str]`, *optional*):
|
| 151 |
+
A dictionary of proxy servers to use by protocol or endpoint, e.g., `{'http': 'foo.bar:3128',
|
| 152 |
+
'http://hostname': 'foo.bar:4012'}.` The proxies are used on each request.
|
| 153 |
+
token (`str` or *bool*, *optional*):
|
| 154 |
+
The token to use as HTTP bearer authorization for remote files. If `True`, will use the token generated
|
| 155 |
+
when running `hf auth login` (stored in `~/.huggingface`).
|
| 156 |
+
revision (`str`, *optional*, defaults to `"main"`):
|
| 157 |
+
The specific model version to use. It can be a branch name, a tag name, or a commit id, since we use a
|
| 158 |
+
git-based system for storing models and other artifacts on huggingface.co, so `revision` can be any
|
| 159 |
+
identifier allowed by git.
|
| 160 |
+
local_files_only (`bool`, *optional*, defaults to `False`):
|
| 161 |
+
If `True`, will only try to load the video processor configuration from local files.
|
| 162 |
+
|
| 163 |
+
<Tip>
|
| 164 |
+
|
| 165 |
+
Passing `token=True` is required when you want to use a private model.
|
| 166 |
+
|
| 167 |
+
</Tip>
|
| 168 |
+
|
| 169 |
+
Returns:
|
| 170 |
+
`Dict`: The configuration of the video processor.
|
| 171 |
+
|
| 172 |
+
Examples:
|
| 173 |
+
|
| 174 |
+
```python
|
| 175 |
+
# Download configuration from huggingface.co and cache.
|
| 176 |
+
video_processor_config = get_video_processor_config("llava-hf/llava-onevision-qwen2-0.5b-ov-hf")
|
| 177 |
+
# This model does not have a video processor config so the result will be an empty dict.
|
| 178 |
+
video_processor_config = get_video_processor_config("FacebookAI/xlm-roberta-base")
|
| 179 |
+
|
| 180 |
+
# Save a pretrained video processor locally and you can reload its config
|
| 181 |
+
from transformers import AutoVideoProcessor
|
| 182 |
+
|
| 183 |
+
video_processor = AutoVideoProcessor.from_pretrained("llava-hf/llava-onevision-qwen2-0.5b-ov-hf")
|
| 184 |
+
video_processor.save_pretrained("video-processor-test")
|
| 185 |
+
video_processor = get_video_processor_config("video-processor-test")
|
| 186 |
+
```"""
|
| 187 |
+
# Load with a priority given to the nested processor config, if available in repo
|
| 188 |
+
resolved_processor_file = cached_file(
|
| 189 |
+
pretrained_model_name_or_path,
|
| 190 |
+
filename=PROCESSOR_NAME,
|
| 191 |
+
cache_dir=cache_dir,
|
| 192 |
+
force_download=force_download,
|
| 193 |
+
proxies=proxies,
|
| 194 |
+
token=token,
|
| 195 |
+
revision=revision,
|
| 196 |
+
local_files_only=local_files_only,
|
| 197 |
+
_raise_exceptions_for_gated_repo=False,
|
| 198 |
+
_raise_exceptions_for_missing_entries=False,
|
| 199 |
+
)
|
| 200 |
+
resolved_video_processor_files = [
|
| 201 |
+
resolved_file
|
| 202 |
+
for filename in [VIDEO_PROCESSOR_NAME, IMAGE_PROCESSOR_NAME]
|
| 203 |
+
if (
|
| 204 |
+
resolved_file := cached_file(
|
| 205 |
+
pretrained_model_name_or_path,
|
| 206 |
+
filename=filename,
|
| 207 |
+
cache_dir=cache_dir,
|
| 208 |
+
force_download=force_download,
|
| 209 |
+
proxies=proxies,
|
| 210 |
+
token=token,
|
| 211 |
+
revision=revision,
|
| 212 |
+
local_files_only=local_files_only,
|
| 213 |
+
_raise_exceptions_for_gated_repo=False,
|
| 214 |
+
_raise_exceptions_for_missing_entries=False,
|
| 215 |
+
_raise_exceptions_for_connection_errors=False,
|
| 216 |
+
)
|
| 217 |
+
)
|
| 218 |
+
is not None
|
| 219 |
+
]
|
| 220 |
+
resolved_video_processor_file = resolved_video_processor_files[0] if resolved_video_processor_files else None
|
| 221 |
+
|
| 222 |
+
# An empty list if none of the possible files is found in the repo
|
| 223 |
+
if not resolved_video_processor_file and not resolved_processor_file:
|
| 224 |
+
logger.info("Could not locate the video processor configuration file.")
|
| 225 |
+
return {}
|
| 226 |
+
|
| 227 |
+
# Load video_processor dict. Priority goes as (nested config if found -> video processor config -> image processor config)
|
| 228 |
+
# We are downloading both configs because almost all models have a `processor_config.json` but
|
| 229 |
+
# not all of these are nested. We need to check if it was saved recebtly as nested or if it is legacy style
|
| 230 |
+
video_processor_dict = {}
|
| 231 |
+
if resolved_processor_file is not None:
|
| 232 |
+
processor_dict = safe_load_json_file(resolved_processor_file)
|
| 233 |
+
if "video_processor" in processor_dict:
|
| 234 |
+
video_processor_dict = processor_dict["video_processor"]
|
| 235 |
+
|
| 236 |
+
if resolved_video_processor_file is not None and video_processor_dict is None:
|
| 237 |
+
video_processor_dict = safe_load_json_file(resolved_video_processor_file)
|
| 238 |
+
|
| 239 |
+
return video_processor_dict
|
| 240 |
+
|
| 241 |
+
|
| 242 |
+
@requires(backends=("vision", "torchvision"))
|
| 243 |
+
class AutoVideoProcessor:
|
| 244 |
+
r"""
|
| 245 |
+
This is a generic video processor class that will be instantiated as one of the video processor classes of the
|
| 246 |
+
library when created with the [`AutoVideoProcessor.from_pretrained`] class method.
|
| 247 |
+
|
| 248 |
+
This class cannot be instantiated directly using `__init__()` (throws an error).
|
| 249 |
+
"""
|
| 250 |
+
|
| 251 |
+
def __init__(self):
|
| 252 |
+
raise OSError(
|
| 253 |
+
"AutoVideoProcessor is designed to be instantiated "
|
| 254 |
+
"using the `AutoVideoProcessor.from_pretrained(pretrained_model_name_or_path)` method."
|
| 255 |
+
)
|
| 256 |
+
|
| 257 |
+
@classmethod
|
| 258 |
+
@replace_list_option_in_docstrings(VIDEO_PROCESSOR_MAPPING_NAMES)
|
| 259 |
+
def from_pretrained(cls, pretrained_model_name_or_path, *inputs, **kwargs):
|
| 260 |
+
r"""
|
| 261 |
+
Instantiate one of the video processor classes of the library from a pretrained model vocabulary.
|
| 262 |
+
|
| 263 |
+
The video processor class to instantiate is selected based on the `model_type` property of the config object
|
| 264 |
+
(either passed as an argument or loaded from `pretrained_model_name_or_path` if possible), or when it's
|
| 265 |
+
missing, by falling back to using pattern matching on `pretrained_model_name_or_path`:
|
| 266 |
+
|
| 267 |
+
List options
|
| 268 |
+
|
| 269 |
+
Params:
|
| 270 |
+
pretrained_model_name_or_path (`str` or `os.PathLike`):
|
| 271 |
+
This can be either:
|
| 272 |
+
|
| 273 |
+
- a string, the *model id* of a pretrained video_processor hosted inside a model repo on
|
| 274 |
+
huggingface.co.
|
| 275 |
+
- a path to a *directory* containing a video processor file saved using the
|
| 276 |
+
[`~video_processing_utils.BaseVideoProcessor.save_pretrained`] method, e.g.,
|
| 277 |
+
`./my_model_directory/`.
|
| 278 |
+
- a path to a saved video processor JSON *file*, e.g.,
|
| 279 |
+
`./my_model_directory/preprocessor_config.json`.
|
| 280 |
+
cache_dir (`str` or `os.PathLike`, *optional*):
|
| 281 |
+
Path to a directory in which a downloaded pretrained model video processor should be cached if the
|
| 282 |
+
standard cache should not be used.
|
| 283 |
+
force_download (`bool`, *optional*, defaults to `False`):
|
| 284 |
+
Whether or not to force to (re-)download the video processor files and override the cached versions if
|
| 285 |
+
they exist.
|
| 286 |
+
proxies (`dict[str, str]`, *optional*):
|
| 287 |
+
A dictionary of proxy servers to use by protocol or endpoint, e.g., `{'http': 'foo.bar:3128',
|
| 288 |
+
'http://hostname': 'foo.bar:4012'}.` The proxies are used on each request.
|
| 289 |
+
token (`str` or *bool*, *optional*):
|
| 290 |
+
The token to use as HTTP bearer authorization for remote files. If `True`, will use the token generated
|
| 291 |
+
when running `hf auth login` (stored in `~/.huggingface`).
|
| 292 |
+
revision (`str`, *optional*, defaults to `"main"`):
|
| 293 |
+
The specific model version to use. It can be a branch name, a tag name, or a commit id, since we use a
|
| 294 |
+
git-based system for storing models and other artifacts on huggingface.co, so `revision` can be any
|
| 295 |
+
identifier allowed by git.
|
| 296 |
+
return_unused_kwargs (`bool`, *optional*, defaults to `False`):
|
| 297 |
+
If `False`, then this function returns just the final video processor object. If `True`, then this
|
| 298 |
+
functions returns a `Tuple(video_processor, unused_kwargs)` where *unused_kwargs* is a dictionary
|
| 299 |
+
consisting of the key/value pairs whose keys are not video processor attributes: i.e., the part of
|
| 300 |
+
`kwargs` which has not been used to update `video_processor` and is otherwise ignored.
|
| 301 |
+
trust_remote_code (`bool`, *optional*, defaults to `False`):
|
| 302 |
+
Whether or not to allow for custom models defined on the Hub in their own modeling files. This option
|
| 303 |
+
should only be set to `True` for repositories you trust and in which you have read the code, as it will
|
| 304 |
+
execute code present on the Hub on your local machine.
|
| 305 |
+
kwargs (`dict[str, Any]`, *optional*):
|
| 306 |
+
The values in kwargs of any keys which are video processor attributes will be used to override the
|
| 307 |
+
loaded values. Behavior concerning key/value pairs whose keys are *not* video processor attributes is
|
| 308 |
+
controlled by the `return_unused_kwargs` keyword parameter.
|
| 309 |
+
|
| 310 |
+
<Tip>
|
| 311 |
+
|
| 312 |
+
Passing `token=True` is required when you want to use a private model.
|
| 313 |
+
|
| 314 |
+
</Tip>
|
| 315 |
+
|
| 316 |
+
Examples:
|
| 317 |
+
|
| 318 |
+
```python
|
| 319 |
+
>>> from transformers import AutoVideoProcessor
|
| 320 |
+
|
| 321 |
+
>>> # Download video processor from huggingface.co and cache.
|
| 322 |
+
>>> video_processor = AutoVideoProcessor.from_pretrained("llava-hf/llava-onevision-qwen2-0.5b-ov-hf")
|
| 323 |
+
|
| 324 |
+
>>> # If video processor files are in a directory (e.g. video processor was saved using *save_pretrained('./test/saved_model/')*)
|
| 325 |
+
>>> # video_processor = AutoVideoProcessor.from_pretrained("./test/saved_model/")
|
| 326 |
+
```"""
|
| 327 |
+
config = kwargs.pop("config", None)
|
| 328 |
+
trust_remote_code = kwargs.pop("trust_remote_code", None)
|
| 329 |
+
kwargs["_from_auto"] = True
|
| 330 |
+
|
| 331 |
+
config_dict, _ = BaseVideoProcessor.get_video_processor_dict(pretrained_model_name_or_path, **kwargs)
|
| 332 |
+
video_processor_class = config_dict.get("video_processor_type", None)
|
| 333 |
+
video_processor_auto_map = None
|
| 334 |
+
if "AutoVideoProcessor" in config_dict.get("auto_map", {}):
|
| 335 |
+
video_processor_auto_map = config_dict["auto_map"]["AutoVideoProcessor"]
|
| 336 |
+
|
| 337 |
+
# If we still don't have the video processor class, check if we're loading from a previous image processor config
|
| 338 |
+
# and if so, infer the video processor class from there.
|
| 339 |
+
if video_processor_class is None and video_processor_auto_map is None:
|
| 340 |
+
image_processor_class = config_dict.pop("image_processor_type", None)
|
| 341 |
+
if image_processor_class is not None:
|
| 342 |
+
video_processor_class_inferred = image_processor_class.replace("ImageProcessor", "VideoProcessor")
|
| 343 |
+
|
| 344 |
+
# Some models have different image processors, e.g. InternVL uses GotOCRImageProcessor
|
| 345 |
+
# We cannot use GotOCRVideoProcessor when falling back for BC and should try to infer from config later on
|
| 346 |
+
if video_processor_class_from_name(video_processor_class_inferred) is not None:
|
| 347 |
+
video_processor_class = video_processor_class_inferred
|
| 348 |
+
if "AutoImageProcessor" in config_dict.get("auto_map", {}):
|
| 349 |
+
image_processor_auto_map = config_dict["auto_map"]["AutoImageProcessor"]
|
| 350 |
+
video_processor_auto_map = image_processor_auto_map.replace("ImageProcessor", "VideoProcessor")
|
| 351 |
+
|
| 352 |
+
# If we don't find the video processor class in the video processor config, let's try the model config.
|
| 353 |
+
if video_processor_class is None and video_processor_auto_map is None:
|
| 354 |
+
if not isinstance(config, PreTrainedConfig):
|
| 355 |
+
config = AutoConfig.from_pretrained(
|
| 356 |
+
pretrained_model_name_or_path, trust_remote_code=trust_remote_code, **kwargs
|
| 357 |
+
)
|
| 358 |
+
# It could be in `config.video_processor_type``
|
| 359 |
+
video_processor_class = getattr(config, "video_processor_type", None)
|
| 360 |
+
if hasattr(config, "auto_map") and "AutoVideoProcessor" in config.auto_map:
|
| 361 |
+
video_processor_auto_map = config.auto_map["AutoVideoProcessor"]
|
| 362 |
+
|
| 363 |
+
if video_processor_class is not None:
|
| 364 |
+
video_processor_class = video_processor_class_from_name(video_processor_class)
|
| 365 |
+
|
| 366 |
+
has_remote_code = video_processor_auto_map is not None
|
| 367 |
+
has_local_code = video_processor_class is not None or type(config) in VIDEO_PROCESSOR_MAPPING
|
| 368 |
+
explicit_local_code = has_local_code and not (
|
| 369 |
+
video_processor_class or VIDEO_PROCESSOR_MAPPING[type(config)]
|
| 370 |
+
).__module__.startswith("transformers.")
|
| 371 |
+
if has_remote_code:
|
| 372 |
+
if "--" in video_processor_auto_map:
|
| 373 |
+
upstream_repo = video_processor_auto_map.split("--")[0]
|
| 374 |
+
else:
|
| 375 |
+
upstream_repo = None
|
| 376 |
+
trust_remote_code = resolve_trust_remote_code(
|
| 377 |
+
trust_remote_code, pretrained_model_name_or_path, has_local_code, has_remote_code, upstream_repo
|
| 378 |
+
)
|
| 379 |
+
|
| 380 |
+
if has_remote_code and trust_remote_code and not explicit_local_code:
|
| 381 |
+
class_ref = video_processor_auto_map
|
| 382 |
+
video_processor_class = get_class_from_dynamic_module(class_ref, pretrained_model_name_or_path, **kwargs)
|
| 383 |
+
_ = kwargs.pop("code_revision", None)
|
| 384 |
+
video_processor_class.register_for_auto_class()
|
| 385 |
+
return video_processor_class.from_pretrained(pretrained_model_name_or_path, *inputs, **kwargs)
|
| 386 |
+
elif video_processor_class is not None:
|
| 387 |
+
return video_processor_class.from_pretrained(pretrained_model_name_or_path, *inputs, **kwargs)
|
| 388 |
+
# Last try: we use the VIDEO_PROCESSOR_MAPPING.
|
| 389 |
+
elif type(config) in VIDEO_PROCESSOR_MAPPING:
|
| 390 |
+
video_processor_class = VIDEO_PROCESSOR_MAPPING[type(config)]
|
| 391 |
+
if video_processor_class is not None:
|
| 392 |
+
return video_processor_class.from_pretrained(pretrained_model_name_or_path, *inputs, **kwargs)
|
| 393 |
+
|
| 394 |
+
# Raise a more informative error message if torchvision isn't found, otherwise just fallback to default
|
| 395 |
+
if not is_torchvision_available():
|
| 396 |
+
raise ValueError(
|
| 397 |
+
f"{pretrained_model_name_or_path} requires `torchvision` to be installed. Please install `torchvision` and try again."
|
| 398 |
+
)
|
| 399 |
+
|
| 400 |
+
raise ValueError(
|
| 401 |
+
f"Unrecognized video processor in {pretrained_model_name_or_path}. Should have a "
|
| 402 |
+
f"`video_processor_type` key in its {VIDEO_PROCESSOR_NAME} of {CONFIG_NAME}, or one of the following "
|
| 403 |
+
f"`model_type` keys in its {CONFIG_NAME}: {', '.join(c for c in VIDEO_PROCESSOR_MAPPING_NAMES)}"
|
| 404 |
+
)
|
| 405 |
+
|
| 406 |
+
@staticmethod
|
| 407 |
+
def register(
|
| 408 |
+
config_class,
|
| 409 |
+
video_processor_class,
|
| 410 |
+
exist_ok=False,
|
| 411 |
+
):
|
| 412 |
+
"""
|
| 413 |
+
Register a new video processor for this class.
|
| 414 |
+
|
| 415 |
+
Args:
|
| 416 |
+
config_class ([`PreTrainedConfig`]):
|
| 417 |
+
The configuration corresponding to the model to register.
|
| 418 |
+
video_processor_class ([`BaseVideoProcessor`]):
|
| 419 |
+
The video processor to register.
|
| 420 |
+
"""
|
| 421 |
+
VIDEO_PROCESSOR_MAPPING.register(config_class, video_processor_class, exist_ok=exist_ok)
|
| 422 |
+
|
| 423 |
+
|
| 424 |
+
__all__ = ["VIDEO_PROCESSOR_MAPPING", "AutoVideoProcessor"]
|
third_party/transformers/src/transformers/models/autoformer/__init__.py
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright 2023 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_autoformer import *
|
| 22 |
+
from .modeling_autoformer 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/autoformer/configuration_autoformer.py
ADDED
|
@@ -0,0 +1,169 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright 2023 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 |
+
"""Autoformer 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="huggingface/autoformer-tourism-monthly")
|
| 23 |
+
@strict
|
| 24 |
+
class AutoformerConfig(PreTrainedConfig):
|
| 25 |
+
r"""
|
| 26 |
+
prediction_length (`int`):
|
| 27 |
+
The prediction length for the decoder. In other words, the prediction horizon of the model.
|
| 28 |
+
context_length (`int`, *optional*, defaults to `prediction_length`):
|
| 29 |
+
The context length for the encoder. If unset, the context length will be the same as the
|
| 30 |
+
`prediction_length`.
|
| 31 |
+
distribution_output (`string`, *optional*, defaults to `"student_t"`):
|
| 32 |
+
The distribution emission head for the model. Could be either "student_t", "normal" or "negative_binomial".
|
| 33 |
+
loss (`string`, *optional*, defaults to `"nll"`):
|
| 34 |
+
The loss function for the model corresponding to the `distribution_output` head. For parametric
|
| 35 |
+
distributions it is the negative log likelihood (nll) - which currently is the only supported one.
|
| 36 |
+
input_size (`int`, *optional*, defaults to 1):
|
| 37 |
+
The size of the target variable which by default is 1 for univariate targets. Would be > 1 in case of
|
| 38 |
+
multivariate targets.
|
| 39 |
+
lags_sequence (`list[int]`, *optional*, defaults to `[1, 2, 3, 4, 5, 6, 7]`):
|
| 40 |
+
The lags of the input time series as covariates often dictated by the frequency. Default is `[1, 2, 3, 4,
|
| 41 |
+
5, 6, 7]`.
|
| 42 |
+
scaling (`bool`, *optional* defaults to `True`):
|
| 43 |
+
Whether to scale the input targets.
|
| 44 |
+
num_time_features (`int`, *optional*, defaults to 0):
|
| 45 |
+
The number of time features in the input time series.
|
| 46 |
+
num_dynamic_real_features (`int`, *optional*, defaults to 0):
|
| 47 |
+
The number of dynamic real valued features.
|
| 48 |
+
num_static_categorical_features (`int`, *optional*, defaults to 0):
|
| 49 |
+
The number of static categorical features.
|
| 50 |
+
num_static_real_features (`int`, *optional*, defaults to 0):
|
| 51 |
+
The number of static real valued features.
|
| 52 |
+
cardinality (`list[int]`, *optional*):
|
| 53 |
+
The cardinality (number of different values) for each of the static categorical features. Should be a list
|
| 54 |
+
of integers, having the same length as `num_static_categorical_features`. Cannot be `None` if
|
| 55 |
+
`num_static_categorical_features` is > 0.
|
| 56 |
+
num_parallel_samples (`int`, *optional*, defaults to 100):
|
| 57 |
+
The number of samples to generate in parallel for each time step of inference.
|
| 58 |
+
label_length (`int`, *optional*, defaults to 10):
|
| 59 |
+
Start token length of the Autoformer decoder, which is used for direct multi-step prediction (i.e.
|
| 60 |
+
non-autoregressive generation).
|
| 61 |
+
moving_average (`int`, *optional*, defaults to 25):
|
| 62 |
+
The window size of the moving average. In practice, it's the kernel size in AvgPool1d of the Decomposition
|
| 63 |
+
Layer.
|
| 64 |
+
autocorrelation_factor (`int`, *optional*, defaults to 3):
|
| 65 |
+
"Attention" (i.e. AutoCorrelation mechanism) factor which is used to find top k autocorrelations delays.
|
| 66 |
+
It's recommended in the paper to set it to a number between 1 and 5.
|
| 67 |
+
|
| 68 |
+
Example:
|
| 69 |
+
|
| 70 |
+
```python
|
| 71 |
+
>>> from transformers import AutoformerConfig, AutoformerModel
|
| 72 |
+
|
| 73 |
+
>>> # Initializing a default Autoformer configuration
|
| 74 |
+
>>> configuration = AutoformerConfig()
|
| 75 |
+
|
| 76 |
+
>>> # Randomly initializing a model (with random weights) from the configuration
|
| 77 |
+
>>> model = AutoformerModel(configuration)
|
| 78 |
+
|
| 79 |
+
>>> # Accessing the model configuration
|
| 80 |
+
>>> configuration = model.config
|
| 81 |
+
```"""
|
| 82 |
+
|
| 83 |
+
model_type = "autoformer"
|
| 84 |
+
attribute_map = {
|
| 85 |
+
"hidden_size": "d_model",
|
| 86 |
+
"num_attention_heads": "encoder_attention_heads",
|
| 87 |
+
"num_hidden_layers": "encoder_layers",
|
| 88 |
+
}
|
| 89 |
+
|
| 90 |
+
prediction_length: int | None = None
|
| 91 |
+
context_length: int | None = None
|
| 92 |
+
distribution_output: str = "student_t"
|
| 93 |
+
loss: str = "nll"
|
| 94 |
+
input_size: int = 1
|
| 95 |
+
lags_sequence: list[int] | tuple[int, ...] = (1, 2, 3, 4, 5, 6, 7)
|
| 96 |
+
scaling: bool | str = True
|
| 97 |
+
num_time_features: int = 0
|
| 98 |
+
num_dynamic_real_features: int = 0
|
| 99 |
+
num_static_categorical_features: int = 0
|
| 100 |
+
num_static_real_features: int = 0
|
| 101 |
+
cardinality: list[int] | None = None
|
| 102 |
+
embedding_dimension: list[int] | None = None
|
| 103 |
+
d_model: int = 64
|
| 104 |
+
encoder_attention_heads: int = 2
|
| 105 |
+
decoder_attention_heads: int = 2
|
| 106 |
+
encoder_layers: int = 2
|
| 107 |
+
decoder_layers: int = 2
|
| 108 |
+
encoder_ffn_dim: int = 32
|
| 109 |
+
decoder_ffn_dim: int = 32
|
| 110 |
+
activation_function: str = "gelu"
|
| 111 |
+
dropout: float | int = 0.1
|
| 112 |
+
encoder_layerdrop: float | int = 0.1
|
| 113 |
+
decoder_layerdrop: float | int = 0.1
|
| 114 |
+
attention_dropout: float | int = 0.1
|
| 115 |
+
activation_dropout: float | int = 0.1
|
| 116 |
+
num_parallel_samples: int = 100
|
| 117 |
+
init_std: float = 0.02
|
| 118 |
+
use_cache: bool = True
|
| 119 |
+
is_encoder_decoder: bool = True
|
| 120 |
+
label_length: int = 10
|
| 121 |
+
moving_average: int = 25
|
| 122 |
+
autocorrelation_factor: int = 3
|
| 123 |
+
|
| 124 |
+
def __post_init__(self, **kwargs):
|
| 125 |
+
self.context_length = self.context_length if self.context_length is not None else self.prediction_length
|
| 126 |
+
self.lags_sequence = list(self.lags_sequence)
|
| 127 |
+
|
| 128 |
+
if not (self.cardinality is not None and self.num_static_categorical_features > 0):
|
| 129 |
+
self.cardinality = [0]
|
| 130 |
+
|
| 131 |
+
if not (self.embedding_dimension is not None and self.num_static_categorical_features > 0):
|
| 132 |
+
self.embedding_dimension = [min(50, (cat + 1) // 2) for cat in self.cardinality]
|
| 133 |
+
|
| 134 |
+
# Transformer architecture configuration
|
| 135 |
+
self.feature_size = self.input_size * len(self.lags_sequence) + self._number_of_features
|
| 136 |
+
super().__post_init__(**kwargs)
|
| 137 |
+
|
| 138 |
+
@property
|
| 139 |
+
def _number_of_features(self) -> int:
|
| 140 |
+
return (
|
| 141 |
+
sum(self.embedding_dimension)
|
| 142 |
+
+ self.num_dynamic_real_features
|
| 143 |
+
+ self.num_time_features
|
| 144 |
+
+ self.num_static_real_features
|
| 145 |
+
+ self.input_size * 2 # the log1p(abs(loc)) and log(scale) features
|
| 146 |
+
)
|
| 147 |
+
|
| 148 |
+
def validate_architecture(self):
|
| 149 |
+
"""Part of `@strict`-powered validation. Validates the architecture of the config."""
|
| 150 |
+
if (
|
| 151 |
+
self.cardinality is not None
|
| 152 |
+
and self.num_static_categorical_features > 0
|
| 153 |
+
and len(self.cardinality) != self.num_static_categorical_features
|
| 154 |
+
):
|
| 155 |
+
raise ValueError(
|
| 156 |
+
"The cardinality should be a list of the same length as `num_static_categorical_features`"
|
| 157 |
+
)
|
| 158 |
+
|
| 159 |
+
if (
|
| 160 |
+
self.embedding_dimension is not None
|
| 161 |
+
and self.num_static_categorical_features > 0
|
| 162 |
+
and len(self.embedding_dimension) != self.num_static_categorical_features
|
| 163 |
+
):
|
| 164 |
+
raise ValueError(
|
| 165 |
+
"The embedding dimension should be a list of the same length as `num_static_categorical_features`"
|
| 166 |
+
)
|
| 167 |
+
|
| 168 |
+
|
| 169 |
+
__all__ = ["AutoformerConfig"]
|
third_party/transformers/src/transformers/models/autoformer/modeling_autoformer.py
ADDED
|
@@ -0,0 +1,1832 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright (c) 2021 THUML @ Tsinghua University
|
| 2 |
+
# Copyright 2023 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
| 3 |
+
# Copyright 2023 The HuggingFace Inc. team. All rights reserved.
|
| 4 |
+
#
|
| 5 |
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
| 6 |
+
# you may not use this file except in compliance with the License.
|
| 7 |
+
# You may obtain a copy of the License at
|
| 8 |
+
#
|
| 9 |
+
# http://www.apache.org/licenses/LICENSE-2.0
|
| 10 |
+
#
|
| 11 |
+
# Unless required by applicable law or agreed to in writing, software
|
| 12 |
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
| 13 |
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 14 |
+
# See the License for the specific language governing permissions and
|
| 15 |
+
# limitations under the License.
|
| 16 |
+
"""PyTorch Autoformer model."""
|
| 17 |
+
|
| 18 |
+
import math
|
| 19 |
+
from dataclasses import dataclass
|
| 20 |
+
|
| 21 |
+
import numpy as np
|
| 22 |
+
import torch
|
| 23 |
+
from torch import nn
|
| 24 |
+
|
| 25 |
+
from ... import initialization as init
|
| 26 |
+
from ...activations import ACT2FN
|
| 27 |
+
from ...cache_utils import Cache, DynamicCache, EncoderDecoderCache
|
| 28 |
+
from ...masking_utils import create_bidirectional_mask
|
| 29 |
+
from ...modeling_layers import GradientCheckpointingLayer
|
| 30 |
+
from ...modeling_outputs import BaseModelOutput, ModelOutput, SampleTSPredictionOutput, Seq2SeqTSPredictionOutput
|
| 31 |
+
from ...modeling_utils import PreTrainedModel
|
| 32 |
+
from ...processing_utils import Unpack
|
| 33 |
+
from ...time_series_utils import NegativeBinomialOutput, NormalOutput, StudentTOutput
|
| 34 |
+
from ...utils import TransformersKwargs, auto_docstring, can_return_tuple, logging
|
| 35 |
+
from ...utils.generic import merge_with_config_defaults
|
| 36 |
+
from ...utils.output_capturing import OutputRecorder, capture_outputs
|
| 37 |
+
from .configuration_autoformer import AutoformerConfig
|
| 38 |
+
|
| 39 |
+
|
| 40 |
+
logger = logging.get_logger(__name__)
|
| 41 |
+
|
| 42 |
+
|
| 43 |
+
@dataclass
|
| 44 |
+
@auto_docstring(
|
| 45 |
+
custom_intro="""
|
| 46 |
+
Base class for model's outputs that may also contain a past key/values (to speed up sequential decoding).
|
| 47 |
+
"""
|
| 48 |
+
)
|
| 49 |
+
class AutoFormerDecoderOutput(ModelOutput):
|
| 50 |
+
r"""
|
| 51 |
+
last_hidden_state (`torch.FloatTensor` of shape `(batch_size, sequence_length, hidden_size)`):
|
| 52 |
+
Sequence of hidden-states at the output of the last layer of the model.
|
| 53 |
+
|
| 54 |
+
If `past_key_values` is used only the last hidden-state of the sequences of shape `(batch_size, 1,
|
| 55 |
+
hidden_size)` is output.
|
| 56 |
+
trend (`torch.FloatTensor` of shape `(batch_size, sequence_length, hidden_size)`):
|
| 57 |
+
Trend tensor for each time series.
|
| 58 |
+
past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`):
|
| 59 |
+
It is a [`~cache_utils.Cache`] instance. For more details, see our [kv cache guide](https://huggingface.co/docs/transformers/en/kv_cache).
|
| 60 |
+
|
| 61 |
+
Contains pre-computed hidden-states (key and values in the self-attention blocks and optionally if
|
| 62 |
+
`config.is_encoder_decoder=True` in the cross-attention blocks) that can be used (see `past_key_values`
|
| 63 |
+
input) to speed up sequential decoding.
|
| 64 |
+
cross_attentions (`tuple(torch.FloatTensor)`, *optional*, returned when `output_attentions=True` and `config.add_cross_attention=True` is passed or when `config.output_attentions=True`):
|
| 65 |
+
Tuple of `torch.FloatTensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length,
|
| 66 |
+
sequence_length)`.
|
| 67 |
+
|
| 68 |
+
Attentions weights of the decoder's cross-attention layer, after the attention softmax, used to compute the
|
| 69 |
+
weighted average in the cross-attention heads.
|
| 70 |
+
"""
|
| 71 |
+
|
| 72 |
+
last_hidden_state: torch.FloatTensor | None = None
|
| 73 |
+
trend: torch.FloatTensor | None = None
|
| 74 |
+
past_key_values: Cache | None = None
|
| 75 |
+
hidden_states: tuple[torch.FloatTensor] | None = None
|
| 76 |
+
attentions: tuple[torch.FloatTensor] | None = None
|
| 77 |
+
cross_attentions: tuple[torch.FloatTensor] | None = None
|
| 78 |
+
|
| 79 |
+
|
| 80 |
+
@dataclass
|
| 81 |
+
@auto_docstring(
|
| 82 |
+
custom_intro="""
|
| 83 |
+
Autoformer model output that contains the additional trend output.
|
| 84 |
+
"""
|
| 85 |
+
)
|
| 86 |
+
class AutoformerModelOutput(ModelOutput):
|
| 87 |
+
r"""
|
| 88 |
+
last_hidden_state (`torch.FloatTensor` of shape `(batch_size, sequence_length, hidden_size)`):
|
| 89 |
+
Sequence of hidden-states at the output of the last layer of the decoder of the model.
|
| 90 |
+
|
| 91 |
+
If `past_key_values` is used only the last hidden-state of the sequences of shape `(batch_size, 1,
|
| 92 |
+
hidden_size)` is output.
|
| 93 |
+
trend (`torch.FloatTensor` of shape `(batch_size, sequence_length, hidden_size)`):
|
| 94 |
+
Trend tensor for each time series.
|
| 95 |
+
past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`):
|
| 96 |
+
It is a [`~cache_utils.Cache`] instance. For more details, see our [kv cache guide](https://huggingface.co/docs/transformers/en/kv_cache).
|
| 97 |
+
|
| 98 |
+
Contains pre-computed hidden-states (key and values in the self-attention blocks and in the cross-attention
|
| 99 |
+
blocks) that can be used (see `past_key_values` input) to speed up sequential decoding.
|
| 100 |
+
loc (`torch.FloatTensor` of shape `(batch_size,)` or `(batch_size, input_size)`, *optional*):
|
| 101 |
+
Shift values of each time series' context window which is used to give the model inputs of the same
|
| 102 |
+
magnitude and then used to shift back to the original magnitude.
|
| 103 |
+
scale (`torch.FloatTensor` of shape `(batch_size,)` or `(batch_size, input_size)`, *optional*):
|
| 104 |
+
Scaling values of each time series' context window which is used to give the model inputs of the same
|
| 105 |
+
magnitude and then used to rescale back to the original magnitude.
|
| 106 |
+
static_features: (`torch.FloatTensor` of shape `(batch_size, feature size)`, *optional*):
|
| 107 |
+
Static features of each time series' in a batch which are copied to the covariates at inference time.
|
| 108 |
+
"""
|
| 109 |
+
|
| 110 |
+
last_hidden_state: torch.FloatTensor | None = None
|
| 111 |
+
trend: torch.FloatTensor | None = None
|
| 112 |
+
past_key_values: Cache | None = None
|
| 113 |
+
decoder_hidden_states: tuple[torch.FloatTensor] | None = None
|
| 114 |
+
decoder_attentions: tuple[torch.FloatTensor] | None = None
|
| 115 |
+
cross_attentions: tuple[torch.FloatTensor] | None = None
|
| 116 |
+
encoder_last_hidden_state: torch.FloatTensor | None = None
|
| 117 |
+
encoder_hidden_states: tuple[torch.FloatTensor] | None = None
|
| 118 |
+
encoder_attentions: tuple[torch.FloatTensor] | None = None
|
| 119 |
+
loc: torch.FloatTensor | None = None
|
| 120 |
+
scale: torch.FloatTensor | None = None
|
| 121 |
+
static_features: torch.FloatTensor | None = None
|
| 122 |
+
|
| 123 |
+
|
| 124 |
+
# Copied from transformers.models.time_series_transformer.modeling_time_series_transformer.TimeSeriesFeatureEmbedder with TimeSeries->Autoformer
|
| 125 |
+
class AutoformerFeatureEmbedder(nn.Module):
|
| 126 |
+
"""
|
| 127 |
+
Embed a sequence of categorical features.
|
| 128 |
+
|
| 129 |
+
Args:
|
| 130 |
+
cardinalities (`list[int]`):
|
| 131 |
+
List of cardinalities of the categorical features.
|
| 132 |
+
embedding_dims (`list[int]`):
|
| 133 |
+
List of embedding dimensions of the categorical features.
|
| 134 |
+
"""
|
| 135 |
+
|
| 136 |
+
def __init__(self, cardinalities: list[int], embedding_dims: list[int]) -> None:
|
| 137 |
+
super().__init__()
|
| 138 |
+
|
| 139 |
+
self.num_features = len(cardinalities)
|
| 140 |
+
self.embedders = nn.ModuleList([nn.Embedding(c, d) for c, d in zip(cardinalities, embedding_dims)])
|
| 141 |
+
|
| 142 |
+
def forward(self, features: torch.Tensor) -> torch.Tensor:
|
| 143 |
+
if self.num_features > 1:
|
| 144 |
+
# we slice the last dimension, giving an array of length
|
| 145 |
+
# self.num_features with shape (N,T) or (N)
|
| 146 |
+
cat_feature_slices = torch.chunk(features, self.num_features, dim=-1)
|
| 147 |
+
else:
|
| 148 |
+
cat_feature_slices = [features]
|
| 149 |
+
|
| 150 |
+
return torch.cat(
|
| 151 |
+
[
|
| 152 |
+
embed(cat_feature_slice.squeeze(-1))
|
| 153 |
+
for embed, cat_feature_slice in zip(self.embedders, cat_feature_slices)
|
| 154 |
+
],
|
| 155 |
+
dim=-1,
|
| 156 |
+
)
|
| 157 |
+
|
| 158 |
+
|
| 159 |
+
# Copied from transformers.models.time_series_transformer.modeling_time_series_transformer.TimeSeriesStdScaler with TimeSeriesTransformer->Autoformer,TimeSeries->Autoformer
|
| 160 |
+
class AutoformerStdScaler(nn.Module):
|
| 161 |
+
"""
|
| 162 |
+
Standardize features by calculating the mean and scaling along the first dimension, and then normalizes it by
|
| 163 |
+
subtracting from the mean and dividing by the standard deviation.
|
| 164 |
+
"""
|
| 165 |
+
|
| 166 |
+
def __init__(self, config: AutoformerConfig):
|
| 167 |
+
super().__init__()
|
| 168 |
+
self.dim = config.scaling_dim if hasattr(config, "scaling_dim") else 1
|
| 169 |
+
self.keepdim = config.keepdim if hasattr(config, "keepdim") else True
|
| 170 |
+
self.minimum_scale = config.minimum_scale if hasattr(config, "minimum_scale") else 1e-5
|
| 171 |
+
|
| 172 |
+
def forward(
|
| 173 |
+
self, data: torch.Tensor, observed_indicator: torch.Tensor
|
| 174 |
+
) -> tuple[torch.Tensor, torch.Tensor, torch.Tensor]:
|
| 175 |
+
"""
|
| 176 |
+
Parameters:
|
| 177 |
+
data (`torch.Tensor` of shape `(batch_size, sequence_length, num_input_channels)`):
|
| 178 |
+
input for Batch norm calculation
|
| 179 |
+
observed_indicator (`torch.BoolTensor` of shape `(batch_size, sequence_length, num_input_channels)`):
|
| 180 |
+
Calculating the scale on the observed indicator.
|
| 181 |
+
Returns:
|
| 182 |
+
tuple of `torch.Tensor` of shapes
|
| 183 |
+
(`(batch_size, sequence_length, num_input_channels)`,`(batch_size, 1, num_input_channels)`,
|
| 184 |
+
`(batch_size, 1, num_input_channels)`)
|
| 185 |
+
"""
|
| 186 |
+
denominator = observed_indicator.sum(self.dim, keepdim=self.keepdim)
|
| 187 |
+
denominator = denominator.clamp_min(1.0)
|
| 188 |
+
loc = (data * observed_indicator).sum(self.dim, keepdim=self.keepdim) / denominator
|
| 189 |
+
|
| 190 |
+
variance = (((data - loc) * observed_indicator) ** 2).sum(self.dim, keepdim=self.keepdim) / denominator
|
| 191 |
+
scale = torch.sqrt(variance + self.minimum_scale)
|
| 192 |
+
return (data - loc) / scale, loc, scale
|
| 193 |
+
|
| 194 |
+
|
| 195 |
+
# Copied from transformers.models.time_series_transformer.modeling_time_series_transformer.TimeSeriesMeanScaler with TimeSeriesTransformer->Autoformer,TimeSeries->Autoformer
|
| 196 |
+
class AutoformerMeanScaler(nn.Module):
|
| 197 |
+
"""
|
| 198 |
+
Computes a scaling factor as the weighted average absolute value along the first dimension, and scales the data
|
| 199 |
+
accordingly.
|
| 200 |
+
"""
|
| 201 |
+
|
| 202 |
+
def __init__(self, config: AutoformerConfig):
|
| 203 |
+
super().__init__()
|
| 204 |
+
self.dim = config.scaling_dim if hasattr(config, "scaling_dim") else 1
|
| 205 |
+
self.keepdim = config.keepdim if hasattr(config, "keepdim") else True
|
| 206 |
+
self.minimum_scale = config.minimum_scale if hasattr(config, "minimum_scale") else 1e-10
|
| 207 |
+
self.default_scale = config.default_scale if hasattr(config, "default_scale") else None
|
| 208 |
+
|
| 209 |
+
def forward(
|
| 210 |
+
self, data: torch.Tensor, observed_indicator: torch.Tensor
|
| 211 |
+
) -> tuple[torch.Tensor, torch.Tensor, torch.Tensor]:
|
| 212 |
+
"""
|
| 213 |
+
Parameters:
|
| 214 |
+
data (`torch.Tensor` of shape `(batch_size, sequence_length, num_input_channels)`):
|
| 215 |
+
input for Batch norm calculation
|
| 216 |
+
observed_indicator (`torch.BoolTensor` of shape `(batch_size, sequence_length, num_input_channels)`):
|
| 217 |
+
Calculating the scale on the observed indicator.
|
| 218 |
+
Returns:
|
| 219 |
+
tuple of `torch.Tensor` of shapes
|
| 220 |
+
(`(batch_size, sequence_length, num_input_channels)`,`(batch_size, 1, num_input_channels)`,
|
| 221 |
+
`(batch_size, 1, num_input_channels)`)
|
| 222 |
+
"""
|
| 223 |
+
ts_sum = (data * observed_indicator).abs().sum(self.dim, keepdim=True)
|
| 224 |
+
num_observed = observed_indicator.sum(self.dim, keepdim=True)
|
| 225 |
+
|
| 226 |
+
scale = ts_sum / torch.clamp(num_observed, min=1)
|
| 227 |
+
|
| 228 |
+
# If `default_scale` is provided, we use it, otherwise we use the scale
|
| 229 |
+
# of the batch.
|
| 230 |
+
if self.default_scale is None:
|
| 231 |
+
batch_sum = ts_sum.sum(dim=0)
|
| 232 |
+
batch_observations = torch.clamp(num_observed.sum(0), min=1)
|
| 233 |
+
default_scale = torch.squeeze(batch_sum / batch_observations)
|
| 234 |
+
else:
|
| 235 |
+
default_scale = self.default_scale * torch.ones_like(scale)
|
| 236 |
+
|
| 237 |
+
# apply default scale where there are no observations
|
| 238 |
+
scale = torch.where(num_observed > 0, scale, default_scale)
|
| 239 |
+
|
| 240 |
+
# ensure the scale is at least `self.minimum_scale`
|
| 241 |
+
scale = torch.clamp(scale, min=self.minimum_scale)
|
| 242 |
+
scaled_data = data / scale
|
| 243 |
+
|
| 244 |
+
if not self.keepdim:
|
| 245 |
+
scale = scale.squeeze(dim=self.dim)
|
| 246 |
+
|
| 247 |
+
return scaled_data, torch.zeros_like(scale), scale
|
| 248 |
+
|
| 249 |
+
|
| 250 |
+
# Copied from transformers.models.time_series_transformer.modeling_time_series_transformer.TimeSeriesNOPScaler with TimeSeriesTransformer->Autoformer,TimeSeries->Autoformer
|
| 251 |
+
class AutoformerNOPScaler(nn.Module):
|
| 252 |
+
"""
|
| 253 |
+
Assigns a scaling factor equal to 1 along the first dimension, and therefore applies no scaling to the input data.
|
| 254 |
+
"""
|
| 255 |
+
|
| 256 |
+
def __init__(self, config: AutoformerConfig):
|
| 257 |
+
super().__init__()
|
| 258 |
+
self.dim = config.scaling_dim if hasattr(config, "scaling_dim") else 1
|
| 259 |
+
self.keepdim = config.keepdim if hasattr(config, "keepdim") else True
|
| 260 |
+
|
| 261 |
+
def forward(
|
| 262 |
+
self, data: torch.Tensor, observed_indicator: torch.Tensor | None = None
|
| 263 |
+
) -> tuple[torch.Tensor, torch.Tensor, torch.Tensor]:
|
| 264 |
+
"""
|
| 265 |
+
Parameters:
|
| 266 |
+
data (`torch.Tensor` of shape `(batch_size, sequence_length, num_input_channels)`):
|
| 267 |
+
input for Batch norm calculation
|
| 268 |
+
Returns:
|
| 269 |
+
tuple of `torch.Tensor` of shapes
|
| 270 |
+
(`(batch_size, sequence_length, num_input_channels)`,`(batch_size, 1, num_input_channels)`,
|
| 271 |
+
`(batch_size, 1, num_input_channels)`)
|
| 272 |
+
"""
|
| 273 |
+
scale = torch.ones_like(data, requires_grad=False).mean(dim=self.dim, keepdim=self.keepdim)
|
| 274 |
+
loc = torch.zeros_like(data, requires_grad=False).mean(dim=self.dim, keepdim=self.keepdim)
|
| 275 |
+
return data, loc, scale
|
| 276 |
+
|
| 277 |
+
|
| 278 |
+
# Copied from transformers.models.time_series_transformer.modeling_time_series_transformer.weighted_average
|
| 279 |
+
def weighted_average(input_tensor: torch.Tensor, weights: torch.Tensor | None = None, dim=None) -> torch.Tensor:
|
| 280 |
+
"""
|
| 281 |
+
Computes the weighted average of a given tensor across a given `dim`, masking values associated with weight zero,
|
| 282 |
+
meaning instead of `nan * 0 = nan` you will get `0 * 0 = 0`.
|
| 283 |
+
|
| 284 |
+
Args:
|
| 285 |
+
input_tensor (`torch.FloatTensor`):
|
| 286 |
+
Input tensor, of which the average must be computed.
|
| 287 |
+
weights (`torch.FloatTensor`, *optional*):
|
| 288 |
+
Weights tensor, of the same shape as `input_tensor`.
|
| 289 |
+
dim (`int`, *optional*):
|
| 290 |
+
The dim along which to average `input_tensor`.
|
| 291 |
+
|
| 292 |
+
Returns:
|
| 293 |
+
`torch.FloatTensor`: The tensor with values averaged along the specified `dim`.
|
| 294 |
+
"""
|
| 295 |
+
if weights is not None:
|
| 296 |
+
weighted_tensor = torch.where(weights != 0, input_tensor * weights, torch.zeros_like(input_tensor))
|
| 297 |
+
sum_weights = torch.clamp(weights.sum(dim=dim) if dim else weights.sum(), min=1.0)
|
| 298 |
+
return (weighted_tensor.sum(dim=dim) if dim else weighted_tensor.sum()) / sum_weights
|
| 299 |
+
else:
|
| 300 |
+
return input_tensor.mean(dim=dim)
|
| 301 |
+
|
| 302 |
+
|
| 303 |
+
# Copied from transformers.models.time_series_transformer.modeling_time_series_transformer.nll
|
| 304 |
+
def nll(input: torch.distributions.Distribution, target: torch.Tensor) -> torch.Tensor:
|
| 305 |
+
"""
|
| 306 |
+
Computes the negative log likelihood loss from input distribution with respect to target.
|
| 307 |
+
"""
|
| 308 |
+
return -input.log_prob(target)
|
| 309 |
+
|
| 310 |
+
|
| 311 |
+
# Copied from transformers.models.marian.modeling_marian.MarianSinusoidalPositionalEmbedding with Marian->Autoformer
|
| 312 |
+
class AutoformerSinusoidalPositionalEmbedding(nn.Embedding):
|
| 313 |
+
"""This module produces sinusoidal positional embeddings of any length."""
|
| 314 |
+
|
| 315 |
+
def __init__(self, num_positions: int, embedding_dim: int, padding_idx: int | None = None) -> None:
|
| 316 |
+
super().__init__(num_positions, embedding_dim, _freeze=True)
|
| 317 |
+
|
| 318 |
+
def create_weight(self):
|
| 319 |
+
"""
|
| 320 |
+
Identical to the XLM create_sinusoidal_embeddings except features are not interleaved. The cos features are in
|
| 321 |
+
the 2nd half of the vector. [dim // 2:]
|
| 322 |
+
"""
|
| 323 |
+
n_pos, dim = self.weight.shape
|
| 324 |
+
position_enc = np.array(
|
| 325 |
+
[[pos / np.power(10000, 2 * (j // 2) / dim) for j in range(dim)] for pos in range(n_pos)]
|
| 326 |
+
)
|
| 327 |
+
out = torch.empty(n_pos, dim, dtype=self.weight.dtype, requires_grad=False)
|
| 328 |
+
sentinel = dim // 2 if dim % 2 == 0 else (dim // 2) + 1
|
| 329 |
+
out[:, 0:sentinel] = torch.FloatTensor(np.sin(position_enc[:, 0::2]))
|
| 330 |
+
out[:, sentinel:] = torch.FloatTensor(np.cos(position_enc[:, 1::2]))
|
| 331 |
+
return out
|
| 332 |
+
|
| 333 |
+
@torch.no_grad()
|
| 334 |
+
def forward(
|
| 335 |
+
self, input_ids_shape: torch.Size, past_key_values_length: int = 0, position_ids: torch.Tensor | None = None
|
| 336 |
+
) -> torch.Tensor:
|
| 337 |
+
"""`input_ids_shape` is expected to be [bsz x seqlen]."""
|
| 338 |
+
if position_ids is None:
|
| 339 |
+
bsz, seq_len = input_ids_shape[:2]
|
| 340 |
+
position_ids = torch.arange(
|
| 341 |
+
past_key_values_length, past_key_values_length + seq_len, dtype=torch.long, device=self.weight.device
|
| 342 |
+
)
|
| 343 |
+
return super().forward(position_ids)
|
| 344 |
+
|
| 345 |
+
|
| 346 |
+
# Copied from transformers.models.time_series_transformer.modeling_time_series_transformer.TimeSeriesValueEmbedding with TimeSeries->Autoformer
|
| 347 |
+
class AutoformerValueEmbedding(nn.Module):
|
| 348 |
+
def __init__(self, feature_size, d_model):
|
| 349 |
+
super().__init__()
|
| 350 |
+
self.value_projection = nn.Linear(in_features=feature_size, out_features=d_model, bias=False)
|
| 351 |
+
|
| 352 |
+
def forward(self, x):
|
| 353 |
+
return self.value_projection(x)
|
| 354 |
+
|
| 355 |
+
|
| 356 |
+
# Class based on
|
| 357 |
+
# https://github.com/thuml/Autoformer/blob/c6a0694ff484753f2d986cc0bb1f99ee850fc1a8/layers/Autoformer_EncDec.py#L39
|
| 358 |
+
# where AutoformerSeriesDecompositionLayer is series_decomp + moving_average
|
| 359 |
+
class AutoformerSeriesDecompositionLayer(nn.Module):
|
| 360 |
+
"""
|
| 361 |
+
Returns the trend and the seasonal parts of the time series. Calculated as:
|
| 362 |
+
|
| 363 |
+
x_trend = AvgPool(Padding(X)) and x_seasonal = X - x_trend
|
| 364 |
+
"""
|
| 365 |
+
|
| 366 |
+
def __init__(self, config: AutoformerConfig):
|
| 367 |
+
super().__init__()
|
| 368 |
+
self.kernel_size = config.moving_average
|
| 369 |
+
self.avg = nn.AvgPool1d(kernel_size=self.kernel_size, stride=1, padding=0)
|
| 370 |
+
|
| 371 |
+
def forward(self, x):
|
| 372 |
+
"""Input shape: Batch x Time x EMBED_DIM"""
|
| 373 |
+
# padding on the both ends of time series
|
| 374 |
+
num_of_pads = (self.kernel_size - 1) // 2
|
| 375 |
+
front = x[:, 0:1, :].repeat(1, num_of_pads, 1)
|
| 376 |
+
end = x[:, -1:, :].repeat(1, num_of_pads, 1)
|
| 377 |
+
x_padded = torch.cat([front, x, end], dim=1)
|
| 378 |
+
|
| 379 |
+
# calculate the trend and seasonal part of the series
|
| 380 |
+
x_trend = self.avg(x_padded.permute(0, 2, 1)).permute(0, 2, 1)
|
| 381 |
+
x_seasonal = x - x_trend
|
| 382 |
+
return x_seasonal, x_trend
|
| 383 |
+
|
| 384 |
+
|
| 385 |
+
# Class based on
|
| 386 |
+
# https://github.com/thuml/Autoformer/blob/c6a0694ff484753f2d986cc0bb1f99ee850fc1a8/layers/Autoformer_EncDec.py#L6
|
| 387 |
+
# where AutoformerLayernorm is my_Layernorm
|
| 388 |
+
class AutoformerLayernorm(nn.Module):
|
| 389 |
+
"""
|
| 390 |
+
Special designed layer normalization for the seasonal part, calculated as: AutoformerLayernorm(x) = nn.LayerNorm(x)
|
| 391 |
+
- torch.mean(nn.LayerNorm(x))
|
| 392 |
+
"""
|
| 393 |
+
|
| 394 |
+
def __init__(self, config: AutoformerConfig):
|
| 395 |
+
super().__init__()
|
| 396 |
+
self.layernorm = nn.LayerNorm(config.d_model)
|
| 397 |
+
|
| 398 |
+
def forward(self, x):
|
| 399 |
+
x_hat = self.layernorm(x)
|
| 400 |
+
bias = torch.mean(x_hat, dim=1).unsqueeze(1).repeat(1, x.shape[1], 1)
|
| 401 |
+
return x_hat - bias
|
| 402 |
+
|
| 403 |
+
|
| 404 |
+
class AutoformerAttention(nn.Module):
|
| 405 |
+
"""
|
| 406 |
+
AutoCorrelation Mechanism with the following two phases:
|
| 407 |
+
(1) period-based dependencies discovery (2) time delay aggregation
|
| 408 |
+
This block replace the canonical self-attention mechanism.
|
| 409 |
+
"""
|
| 410 |
+
|
| 411 |
+
def __init__(
|
| 412 |
+
self,
|
| 413 |
+
embed_dim: int,
|
| 414 |
+
num_heads: int,
|
| 415 |
+
dropout: float | None = 0.0,
|
| 416 |
+
is_decoder: bool | None = False,
|
| 417 |
+
bias: bool | None = True,
|
| 418 |
+
autocorrelation_factor: int | None = 3,
|
| 419 |
+
layer_idx: int | None = None,
|
| 420 |
+
):
|
| 421 |
+
super().__init__()
|
| 422 |
+
self.embed_dim = embed_dim
|
| 423 |
+
self.num_heads = num_heads
|
| 424 |
+
self.dropout = dropout
|
| 425 |
+
self.head_dim = embed_dim // num_heads
|
| 426 |
+
|
| 427 |
+
if (self.head_dim * num_heads) != self.embed_dim:
|
| 428 |
+
raise ValueError(
|
| 429 |
+
f"embed_dim must be divisible by num_heads (got `embed_dim`: {self.embed_dim}"
|
| 430 |
+
f" and `num_heads`: {num_heads})."
|
| 431 |
+
)
|
| 432 |
+
self.scaling = self.head_dim**-0.5
|
| 433 |
+
self.is_decoder = is_decoder
|
| 434 |
+
self.layer_idx = layer_idx
|
| 435 |
+
|
| 436 |
+
self.k_proj = nn.Linear(embed_dim, embed_dim, bias=bias)
|
| 437 |
+
self.v_proj = nn.Linear(embed_dim, embed_dim, bias=bias)
|
| 438 |
+
self.q_proj = nn.Linear(embed_dim, embed_dim, bias=bias)
|
| 439 |
+
self.out_proj = nn.Linear(embed_dim, embed_dim, bias=bias)
|
| 440 |
+
|
| 441 |
+
self.autocorrelation_factor = autocorrelation_factor
|
| 442 |
+
|
| 443 |
+
def forward(
|
| 444 |
+
self,
|
| 445 |
+
hidden_states: torch.Tensor,
|
| 446 |
+
key_value_states: torch.Tensor | None = None,
|
| 447 |
+
past_key_values: Cache | None = None,
|
| 448 |
+
attention_mask: torch.Tensor | None = None,
|
| 449 |
+
**kwargs: Unpack[TransformersKwargs],
|
| 450 |
+
) -> tuple[torch.Tensor, torch.Tensor | None]:
|
| 451 |
+
"""Input shape: Batch x Time x Channel"""
|
| 452 |
+
|
| 453 |
+
# if key_value_states are provided this layer is used as a cross-attention layer
|
| 454 |
+
# for the decoder
|
| 455 |
+
is_cross_attention = key_value_states is not None
|
| 456 |
+
bsz, tgt_len, _ = hidden_states.size()
|
| 457 |
+
|
| 458 |
+
# get query proj
|
| 459 |
+
query_states = self.q_proj(hidden_states)
|
| 460 |
+
|
| 461 |
+
is_updated = False
|
| 462 |
+
if past_key_values is not None:
|
| 463 |
+
if isinstance(past_key_values, EncoderDecoderCache):
|
| 464 |
+
is_updated = past_key_values.is_updated.get(self.layer_idx)
|
| 465 |
+
if is_cross_attention:
|
| 466 |
+
# after the first generated id, we can subsequently re-use all key/value_layer from cache
|
| 467 |
+
curr_past_key_values = past_key_values.cross_attention_cache
|
| 468 |
+
else:
|
| 469 |
+
curr_past_key_values = past_key_values.self_attention_cache
|
| 470 |
+
else:
|
| 471 |
+
curr_past_key_values = past_key_values
|
| 472 |
+
|
| 473 |
+
current_states = key_value_states if is_cross_attention else hidden_states
|
| 474 |
+
if is_cross_attention and past_key_values is not None and is_updated:
|
| 475 |
+
# reuse k,v, cross_attentions
|
| 476 |
+
key_states = curr_past_key_values.layers[self.layer_idx].keys
|
| 477 |
+
value_states = curr_past_key_values.layers[self.layer_idx].values
|
| 478 |
+
else:
|
| 479 |
+
key_states = self.k_proj(current_states)
|
| 480 |
+
value_states = self.v_proj(current_states)
|
| 481 |
+
key_states = key_states.view(bsz, -1, self.num_heads, self.head_dim).transpose(1, 2)
|
| 482 |
+
value_states = value_states.view(bsz, -1, self.num_heads, self.head_dim).transpose(1, 2)
|
| 483 |
+
|
| 484 |
+
if past_key_values is not None:
|
| 485 |
+
key_states, value_states = curr_past_key_values.update(key_states, value_states, self.layer_idx)
|
| 486 |
+
# set flag that curr layer for cross-attn is already updated so we can re-use in subsequent calls
|
| 487 |
+
if is_cross_attention and isinstance(past_key_values, EncoderDecoderCache):
|
| 488 |
+
past_key_values.is_updated[self.layer_idx] = True
|
| 489 |
+
|
| 490 |
+
proj_shape = (bsz * self.num_heads, -1, self.head_dim)
|
| 491 |
+
query_states = query_states.view(bsz, tgt_len, self.num_heads, self.head_dim).transpose(1, 2)
|
| 492 |
+
query_states = query_states.reshape(*proj_shape)
|
| 493 |
+
key_states = key_states.reshape(*proj_shape)
|
| 494 |
+
value_states = value_states.reshape(*proj_shape)
|
| 495 |
+
|
| 496 |
+
# (1) period-based dependencies discovery
|
| 497 |
+
# Resize (truncation or zero filling)
|
| 498 |
+
queries_time_length = query_states.size(1)
|
| 499 |
+
values_time_length = value_states.size(1)
|
| 500 |
+
if queries_time_length > values_time_length:
|
| 501 |
+
query_states = query_states[:, : (queries_time_length - values_time_length), :]
|
| 502 |
+
zeros = torch.zeros_like(query_states).float()
|
| 503 |
+
value_states = torch.cat([value_states, zeros], dim=1)
|
| 504 |
+
key_states = torch.cat([key_states, zeros], dim=1)
|
| 505 |
+
else:
|
| 506 |
+
value_states = value_states[:, :queries_time_length, :]
|
| 507 |
+
key_states = key_states[:, :queries_time_length, :]
|
| 508 |
+
|
| 509 |
+
query_states_fft = torch.fft.rfft(query_states, n=tgt_len, dim=1)
|
| 510 |
+
key_states_fft = torch.fft.rfft(key_states, n=tgt_len, dim=1)
|
| 511 |
+
attn_weights = query_states_fft * torch.conj(key_states_fft)
|
| 512 |
+
attn_weights = torch.fft.irfft(attn_weights, n=tgt_len, dim=1) # Autocorrelation(Q,K)
|
| 513 |
+
|
| 514 |
+
src_len = key_states.size(1)
|
| 515 |
+
channel = key_states.size(2)
|
| 516 |
+
|
| 517 |
+
if attn_weights.size() != (bsz * self.num_heads, tgt_len, channel):
|
| 518 |
+
raise ValueError(
|
| 519 |
+
f"Attention weights should be of size {(bsz * self.num_heads, tgt_len, channel)}, but is"
|
| 520 |
+
f" {attn_weights.size()}"
|
| 521 |
+
)
|
| 522 |
+
|
| 523 |
+
if attention_mask is not None:
|
| 524 |
+
if attention_mask.size() != (bsz, 1, tgt_len, src_len):
|
| 525 |
+
raise ValueError(
|
| 526 |
+
f"Attention mask should be of size {(bsz, 1, tgt_len, src_len)}, but is {attention_mask.size()}"
|
| 527 |
+
)
|
| 528 |
+
attn_weights = attn_weights.view(bsz, self.num_heads, tgt_len, src_len) + attention_mask
|
| 529 |
+
attn_weights = attn_weights.view(bsz * self.num_heads, tgt_len, src_len)
|
| 530 |
+
|
| 531 |
+
# this operation is a bit awkward, but it's required to
|
| 532 |
+
# make sure that attn_weights keeps its gradient.
|
| 533 |
+
# In order to do so, attn_weights have to be reshaped
|
| 534 |
+
# twice and have to be reused in the following
|
| 535 |
+
attn_weights_reshaped = attn_weights.view(bsz, self.num_heads, tgt_len, channel)
|
| 536 |
+
attn_weights = attn_weights_reshaped.view(bsz * self.num_heads, tgt_len, channel)
|
| 537 |
+
|
| 538 |
+
# time delay aggregation
|
| 539 |
+
time_length = value_states.size(1)
|
| 540 |
+
autocorrelations = attn_weights.view(bsz, self.num_heads, tgt_len, channel)
|
| 541 |
+
|
| 542 |
+
# find top k autocorrelations delays
|
| 543 |
+
top_k = int(self.autocorrelation_factor * math.log(time_length))
|
| 544 |
+
autocorrelations_mean_on_head_channel = torch.mean(autocorrelations, dim=(1, -1)) # bsz x tgt_len
|
| 545 |
+
if self.training:
|
| 546 |
+
autocorrelations_mean_on_bsz = torch.mean(autocorrelations_mean_on_head_channel, dim=0)
|
| 547 |
+
_, top_k_delays_index = torch.topk(autocorrelations_mean_on_bsz, top_k)
|
| 548 |
+
top_k_autocorrelations = torch.stack(
|
| 549 |
+
[autocorrelations_mean_on_head_channel[:, top_k_delays_index[i]] for i in range(top_k)], dim=-1
|
| 550 |
+
)
|
| 551 |
+
else:
|
| 552 |
+
top_k_autocorrelations, top_k_delays_index = torch.topk(
|
| 553 |
+
autocorrelations_mean_on_head_channel, top_k, dim=1
|
| 554 |
+
)
|
| 555 |
+
|
| 556 |
+
top_k_autocorrelations = torch.softmax(top_k_autocorrelations, dim=-1) # bsz x top_k
|
| 557 |
+
|
| 558 |
+
# compute aggregation: value_states.roll(delay) * top_k_autocorrelations(delay)
|
| 559 |
+
if not self.training:
|
| 560 |
+
# used for compute values_states.roll(delay) in inference
|
| 561 |
+
tmp_values = value_states.repeat(1, 2, 1)
|
| 562 |
+
init_index = (
|
| 563 |
+
torch.arange(time_length)
|
| 564 |
+
.view(1, -1, 1)
|
| 565 |
+
.repeat(bsz * self.num_heads, 1, channel)
|
| 566 |
+
.to(value_states.device)
|
| 567 |
+
)
|
| 568 |
+
|
| 569 |
+
delays_agg = torch.zeros_like(value_states).float() # bsz x time_length x channel
|
| 570 |
+
for i in range(top_k):
|
| 571 |
+
# compute value_states roll delay
|
| 572 |
+
if not self.training:
|
| 573 |
+
tmp_delay = init_index + top_k_delays_index[:, i].view(-1, 1, 1).repeat(
|
| 574 |
+
self.num_heads, tgt_len, channel
|
| 575 |
+
)
|
| 576 |
+
value_states_roll_delay = torch.gather(tmp_values, dim=1, index=tmp_delay)
|
| 577 |
+
else:
|
| 578 |
+
value_states_roll_delay = value_states.roll(shifts=-int(top_k_delays_index[i]), dims=1)
|
| 579 |
+
|
| 580 |
+
# aggregation
|
| 581 |
+
top_k_autocorrelations_at_delay = (
|
| 582 |
+
top_k_autocorrelations[:, i].view(-1, 1, 1).repeat(self.num_heads, tgt_len, channel)
|
| 583 |
+
)
|
| 584 |
+
delays_agg += value_states_roll_delay * top_k_autocorrelations_at_delay
|
| 585 |
+
|
| 586 |
+
attn_output = delays_agg.contiguous()
|
| 587 |
+
|
| 588 |
+
if attn_output.size() != (bsz * self.num_heads, tgt_len, self.head_dim):
|
| 589 |
+
raise ValueError(
|
| 590 |
+
f"`attn_output` should be of size {(bsz * self.num_heads, tgt_len, self.head_dim)}, but is"
|
| 591 |
+
f" {attn_output.size()}"
|
| 592 |
+
)
|
| 593 |
+
|
| 594 |
+
attn_output = attn_output.view(bsz, self.num_heads, tgt_len, self.head_dim)
|
| 595 |
+
attn_output = attn_output.transpose(1, 2)
|
| 596 |
+
|
| 597 |
+
# Use the `embed_dim` from the config (stored in the class) rather than `hidden_state` because `attn_output` can be
|
| 598 |
+
# partitioned across GPUs when using tensor-parallelism.
|
| 599 |
+
attn_output = attn_output.reshape(bsz, tgt_len, self.embed_dim)
|
| 600 |
+
|
| 601 |
+
attn_output = self.out_proj(attn_output)
|
| 602 |
+
|
| 603 |
+
return attn_output, attn_weights_reshaped
|
| 604 |
+
|
| 605 |
+
|
| 606 |
+
class AutoformerEncoderLayer(GradientCheckpointingLayer):
|
| 607 |
+
def __init__(self, config: AutoformerConfig):
|
| 608 |
+
super().__init__()
|
| 609 |
+
self.embed_dim = config.d_model
|
| 610 |
+
self.self_attn = AutoformerAttention(
|
| 611 |
+
embed_dim=self.embed_dim,
|
| 612 |
+
num_heads=config.encoder_attention_heads,
|
| 613 |
+
dropout=config.attention_dropout,
|
| 614 |
+
autocorrelation_factor=config.autocorrelation_factor,
|
| 615 |
+
)
|
| 616 |
+
self.self_attn_layer_norm = nn.LayerNorm(self.embed_dim)
|
| 617 |
+
self.dropout = config.dropout
|
| 618 |
+
self.activation_fn = ACT2FN[config.activation_function]
|
| 619 |
+
self.activation_dropout = config.activation_dropout
|
| 620 |
+
self.fc1 = nn.Linear(self.embed_dim, config.encoder_ffn_dim)
|
| 621 |
+
self.fc2 = nn.Linear(config.encoder_ffn_dim, self.embed_dim)
|
| 622 |
+
self.final_layer_norm = AutoformerLayernorm(config)
|
| 623 |
+
self.decomp1 = AutoformerSeriesDecompositionLayer(config)
|
| 624 |
+
self.decomp2 = AutoformerSeriesDecompositionLayer(config)
|
| 625 |
+
|
| 626 |
+
def forward(
|
| 627 |
+
self,
|
| 628 |
+
hidden_states: torch.FloatTensor,
|
| 629 |
+
attention_mask: torch.FloatTensor = None,
|
| 630 |
+
**kwargs: Unpack[TransformersKwargs],
|
| 631 |
+
) -> torch.FloatTensor:
|
| 632 |
+
"""
|
| 633 |
+
Args:
|
| 634 |
+
hidden_states (`torch.FloatTensor`): input to the layer of shape `(batch, seq_len, embed_dim)`
|
| 635 |
+
attention_mask (`torch.FloatTensor`): attention mask of size
|
| 636 |
+
`(batch, 1, tgt_len, src_len)` where padding elements are indicated by very large negative values.
|
| 637 |
+
"""
|
| 638 |
+
residual = hidden_states
|
| 639 |
+
hidden_states, _ = self.self_attn(
|
| 640 |
+
hidden_states,
|
| 641 |
+
attention_mask=attention_mask,
|
| 642 |
+
**kwargs,
|
| 643 |
+
)
|
| 644 |
+
hidden_states = nn.functional.dropout(hidden_states, p=self.dropout, training=self.training)
|
| 645 |
+
hidden_states = residual + hidden_states
|
| 646 |
+
# added layer norm here as an improvement
|
| 647 |
+
hidden_states = self.self_attn_layer_norm(hidden_states)
|
| 648 |
+
hidden_states, _ = self.decomp1(hidden_states)
|
| 649 |
+
|
| 650 |
+
residual = hidden_states
|
| 651 |
+
hidden_states = self.activation_fn(self.fc1(hidden_states))
|
| 652 |
+
hidden_states = nn.functional.dropout(hidden_states, p=self.activation_dropout, training=self.training)
|
| 653 |
+
hidden_states = self.fc2(hidden_states)
|
| 654 |
+
hidden_states = nn.functional.dropout(hidden_states, p=self.dropout, training=self.training)
|
| 655 |
+
hidden_states = residual + hidden_states
|
| 656 |
+
hidden_states, _ = self.decomp2(hidden_states)
|
| 657 |
+
hidden_states = self.final_layer_norm(hidden_states)
|
| 658 |
+
|
| 659 |
+
if hidden_states.dtype == torch.float16 and not torch.isfinite(hidden_states).all():
|
| 660 |
+
clamp_value = torch.finfo(hidden_states.dtype).max - 1000
|
| 661 |
+
hidden_states = torch.clamp(hidden_states, min=-clamp_value, max=clamp_value)
|
| 662 |
+
|
| 663 |
+
return hidden_states
|
| 664 |
+
|
| 665 |
+
|
| 666 |
+
class AutoformerDecoderLayer(GradientCheckpointingLayer):
|
| 667 |
+
def __init__(self, config: AutoformerConfig, layer_idx=None):
|
| 668 |
+
super().__init__()
|
| 669 |
+
self.embed_dim = config.d_model
|
| 670 |
+
|
| 671 |
+
self.self_attn = AutoformerAttention(
|
| 672 |
+
embed_dim=self.embed_dim,
|
| 673 |
+
num_heads=config.decoder_attention_heads,
|
| 674 |
+
dropout=config.attention_dropout,
|
| 675 |
+
is_decoder=True,
|
| 676 |
+
autocorrelation_factor=config.autocorrelation_factor,
|
| 677 |
+
layer_idx=layer_idx,
|
| 678 |
+
)
|
| 679 |
+
self.dropout = config.dropout
|
| 680 |
+
self.activation_fn = ACT2FN[config.activation_function]
|
| 681 |
+
self.activation_dropout = config.activation_dropout
|
| 682 |
+
|
| 683 |
+
self.self_attn_layer_norm = nn.LayerNorm(self.embed_dim)
|
| 684 |
+
self.encoder_attn = AutoformerAttention(
|
| 685 |
+
self.embed_dim,
|
| 686 |
+
config.decoder_attention_heads,
|
| 687 |
+
dropout=config.attention_dropout,
|
| 688 |
+
is_decoder=True,
|
| 689 |
+
autocorrelation_factor=config.autocorrelation_factor,
|
| 690 |
+
layer_idx=layer_idx,
|
| 691 |
+
)
|
| 692 |
+
self.encoder_attn_layer_norm = nn.LayerNorm(self.embed_dim)
|
| 693 |
+
self.fc1 = nn.Linear(self.embed_dim, config.decoder_ffn_dim)
|
| 694 |
+
self.fc2 = nn.Linear(config.decoder_ffn_dim, self.embed_dim)
|
| 695 |
+
self.final_layer_norm = AutoformerLayernorm(config)
|
| 696 |
+
|
| 697 |
+
self.decomp1 = AutoformerSeriesDecompositionLayer(config)
|
| 698 |
+
self.decomp2 = AutoformerSeriesDecompositionLayer(config)
|
| 699 |
+
self.decomp3 = AutoformerSeriesDecompositionLayer(config)
|
| 700 |
+
|
| 701 |
+
# source: https://github.com/thuml/Autoformer/blob/e6371e24f2ae2dd53e472edefdd5814c5176f864/layers/Autoformer_EncDec.py#L128
|
| 702 |
+
self.trend_projection = nn.Conv1d(
|
| 703 |
+
in_channels=self.embed_dim,
|
| 704 |
+
out_channels=config.feature_size,
|
| 705 |
+
kernel_size=3,
|
| 706 |
+
stride=1,
|
| 707 |
+
padding=1,
|
| 708 |
+
padding_mode="circular",
|
| 709 |
+
bias=False,
|
| 710 |
+
)
|
| 711 |
+
|
| 712 |
+
def forward(
|
| 713 |
+
self,
|
| 714 |
+
hidden_states: torch.Tensor,
|
| 715 |
+
attention_mask: torch.Tensor | None = None,
|
| 716 |
+
encoder_hidden_states: torch.Tensor | None = None,
|
| 717 |
+
encoder_attention_mask: torch.Tensor | None = None,
|
| 718 |
+
past_key_values: Cache | None = None,
|
| 719 |
+
use_cache: bool | None = True,
|
| 720 |
+
**kwargs: Unpack[TransformersKwargs],
|
| 721 |
+
) -> tuple[torch.FloatTensor, torch.FloatTensor]:
|
| 722 |
+
"""
|
| 723 |
+
Args:
|
| 724 |
+
hidden_states (`torch.FloatTensor`): input to the layer of shape `(batch, seq_len, embed_dim)`
|
| 725 |
+
attention_mask (`torch.FloatTensor`): attention mask of size
|
| 726 |
+
`(batch, 1, tgt_len, src_len)` where padding elements are indicated by very large negative values.
|
| 727 |
+
encoder_hidden_states (`torch.FloatTensor`):
|
| 728 |
+
cross attention input to the layer of shape `(batch, seq_len, embed_dim)`
|
| 729 |
+
encoder_attention_mask (`torch.FloatTensor`): encoder attention mask of size
|
| 730 |
+
`(batch, 1, tgt_len, src_len)` where padding elements are indicated by very large negative values.
|
| 731 |
+
past_key_values (`Cache`): cached past key and value projection states
|
| 732 |
+
use_cache: (`bool`, *optional*, defaults to `True`):
|
| 733 |
+
Whether or not the model should return the `present_key_value` state to be used for subsequent
|
| 734 |
+
decoding.
|
| 735 |
+
"""
|
| 736 |
+
residual = hidden_states
|
| 737 |
+
|
| 738 |
+
# Self Attention
|
| 739 |
+
hidden_states, _ = self.self_attn(
|
| 740 |
+
hidden_states,
|
| 741 |
+
past_key_values=past_key_values,
|
| 742 |
+
attention_mask=attention_mask,
|
| 743 |
+
**kwargs,
|
| 744 |
+
)
|
| 745 |
+
hidden_states = nn.functional.dropout(hidden_states, p=self.dropout, training=self.training)
|
| 746 |
+
hidden_states = residual + hidden_states
|
| 747 |
+
hidden_states, trend1 = self.decomp1(hidden_states)
|
| 748 |
+
# added layer norm here as an improvement
|
| 749 |
+
hidden_states = self.self_attn_layer_norm(hidden_states)
|
| 750 |
+
|
| 751 |
+
# Cross-Attention Block
|
| 752 |
+
if encoder_hidden_states is not None:
|
| 753 |
+
residual = hidden_states
|
| 754 |
+
|
| 755 |
+
hidden_states, _ = self.encoder_attn(
|
| 756 |
+
hidden_states,
|
| 757 |
+
key_value_states=encoder_hidden_states,
|
| 758 |
+
attention_mask=encoder_attention_mask,
|
| 759 |
+
past_key_values=past_key_values,
|
| 760 |
+
**kwargs,
|
| 761 |
+
)
|
| 762 |
+
hidden_states = nn.functional.dropout(hidden_states, p=self.dropout, training=self.training)
|
| 763 |
+
hidden_states = residual + hidden_states
|
| 764 |
+
hidden_states, trend2 = self.decomp2(hidden_states)
|
| 765 |
+
# added layer norm here as an improvement
|
| 766 |
+
hidden_states = self.encoder_attn_layer_norm(hidden_states)
|
| 767 |
+
|
| 768 |
+
# Fully Connected
|
| 769 |
+
residual = hidden_states
|
| 770 |
+
hidden_states = self.activation_fn(self.fc1(hidden_states))
|
| 771 |
+
hidden_states = nn.functional.dropout(hidden_states, p=self.activation_dropout, training=self.training)
|
| 772 |
+
hidden_states = self.fc2(hidden_states)
|
| 773 |
+
hidden_states = nn.functional.dropout(hidden_states, p=self.dropout, training=self.training)
|
| 774 |
+
hidden_states = residual + hidden_states
|
| 775 |
+
hidden_states, trend3 = self.decomp3(hidden_states)
|
| 776 |
+
hidden_states = self.final_layer_norm(hidden_states)
|
| 777 |
+
|
| 778 |
+
if encoder_hidden_states is not None:
|
| 779 |
+
residual_trend = trend1 + trend2 + trend3
|
| 780 |
+
else:
|
| 781 |
+
residual_trend = trend1 + trend3
|
| 782 |
+
residual_trend = self.trend_projection(residual_trend.permute(0, 2, 1)).transpose(1, 2)
|
| 783 |
+
|
| 784 |
+
return hidden_states, residual_trend
|
| 785 |
+
|
| 786 |
+
|
| 787 |
+
@auto_docstring
|
| 788 |
+
class AutoformerPreTrainedModel(PreTrainedModel):
|
| 789 |
+
config: AutoformerConfig
|
| 790 |
+
base_model_prefix = "model"
|
| 791 |
+
input_modalities = ("time",)
|
| 792 |
+
main_input_name = "past_values"
|
| 793 |
+
supports_gradient_checkpointing = True
|
| 794 |
+
_can_record_outputs = {
|
| 795 |
+
"hidden_states": (AutoformerEncoderLayer, AutoformerDecoderLayer),
|
| 796 |
+
"attentions": AutoformerAttention,
|
| 797 |
+
}
|
| 798 |
+
|
| 799 |
+
@torch.no_grad()
|
| 800 |
+
def _init_weights(self, module: nn.Module):
|
| 801 |
+
std = self.config.init_std
|
| 802 |
+
if isinstance(module, (nn.Linear, nn.Conv1d)):
|
| 803 |
+
init.normal_(module.weight, mean=0.0, std=std)
|
| 804 |
+
if module.bias is not None:
|
| 805 |
+
init.zeros_(module.bias)
|
| 806 |
+
elif isinstance(module, AutoformerSinusoidalPositionalEmbedding):
|
| 807 |
+
init.copy_(module.weight, module.create_weight())
|
| 808 |
+
elif isinstance(module, nn.Embedding):
|
| 809 |
+
init.normal_(module.weight, mean=0.0, std=std)
|
| 810 |
+
# Here we need the check explicitly, as we slice the weight in the `zeros_` call, so it looses the flag
|
| 811 |
+
if module.padding_idx is not None and not getattr(module.weight, "_is_hf_initialized", False):
|
| 812 |
+
init.zeros_(module.weight[module.padding_idx])
|
| 813 |
+
elif isinstance(module, nn.LayerNorm):
|
| 814 |
+
init.ones_(module.weight)
|
| 815 |
+
init.zeros_(module.bias)
|
| 816 |
+
|
| 817 |
+
|
| 818 |
+
# copied from transformers.models.time_series_transformer.modeling_time_series_transformer.TimeSeriesTransformerEncoder with TimeSeriesTransformer->Autoformer,TimeSeries->Autoformer
|
| 819 |
+
class AutoformerEncoder(AutoformerPreTrainedModel):
|
| 820 |
+
"""
|
| 821 |
+
Transformer encoder consisting of *config.encoder_layers* self attention layers. Each layer is a
|
| 822 |
+
[`AutoformerEncoderLayer`].
|
| 823 |
+
|
| 824 |
+
Args:
|
| 825 |
+
config: AutoformerConfig
|
| 826 |
+
"""
|
| 827 |
+
|
| 828 |
+
def __init__(self, config: AutoformerConfig):
|
| 829 |
+
super().__init__(config)
|
| 830 |
+
|
| 831 |
+
self.dropout = config.dropout
|
| 832 |
+
self.layerdrop = config.encoder_layerdrop
|
| 833 |
+
if config.prediction_length is None:
|
| 834 |
+
raise ValueError("The `prediction_length` config needs to be specified.")
|
| 835 |
+
|
| 836 |
+
self.value_embedding = AutoformerValueEmbedding(feature_size=config.feature_size, d_model=config.d_model)
|
| 837 |
+
self.embed_positions = AutoformerSinusoidalPositionalEmbedding(
|
| 838 |
+
config.context_length + config.prediction_length, config.d_model
|
| 839 |
+
)
|
| 840 |
+
self.layers = nn.ModuleList([AutoformerEncoderLayer(config) for _ in range(config.encoder_layers)])
|
| 841 |
+
self.layernorm_embedding = nn.LayerNorm(config.d_model)
|
| 842 |
+
|
| 843 |
+
self.gradient_checkpointing = False
|
| 844 |
+
# Initialize weights and apply final processing
|
| 845 |
+
self.post_init()
|
| 846 |
+
|
| 847 |
+
@merge_with_config_defaults
|
| 848 |
+
@capture_outputs
|
| 849 |
+
def forward(
|
| 850 |
+
self,
|
| 851 |
+
attention_mask: torch.Tensor | None = None,
|
| 852 |
+
inputs_embeds: torch.FloatTensor | None = None,
|
| 853 |
+
**kwargs: Unpack[TransformersKwargs],
|
| 854 |
+
) -> tuple | BaseModelOutput:
|
| 855 |
+
r"""
|
| 856 |
+
Args:
|
| 857 |
+
attention_mask (`torch.Tensor` of shape `(batch_size, sequence_length)`, *optional*):
|
| 858 |
+
Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`:
|
| 859 |
+
|
| 860 |
+
- 1 for tokens that are **not masked**,
|
| 861 |
+
- 0 for tokens that are **masked**.
|
| 862 |
+
|
| 863 |
+
[What are attention masks?](../glossary#attention-mask)
|
| 864 |
+
inputs_embeds (`torch.FloatTensor` of shape `(batch_size, sequence_length, hidden_size)`, *optional*):
|
| 865 |
+
Optionally, instead of passing `input_ids` you can choose to directly pass an embedded representation.
|
| 866 |
+
This is useful if you want more control over how to convert `input_ids` indices into associated vectors
|
| 867 |
+
than the model's internal embedding lookup matrix.
|
| 868 |
+
"""
|
| 869 |
+
hidden_states = self.value_embedding(inputs_embeds)
|
| 870 |
+
embed_pos = self.embed_positions(inputs_embeds.size())
|
| 871 |
+
|
| 872 |
+
hidden_states = self.layernorm_embedding(hidden_states + embed_pos)
|
| 873 |
+
hidden_states = nn.functional.dropout(hidden_states, p=self.dropout, training=self.training)
|
| 874 |
+
|
| 875 |
+
attention_mask = create_bidirectional_mask(
|
| 876 |
+
config=self.config,
|
| 877 |
+
inputs_embeds=inputs_embeds,
|
| 878 |
+
attention_mask=attention_mask,
|
| 879 |
+
)
|
| 880 |
+
|
| 881 |
+
for idx, encoder_layer in enumerate(self.layers):
|
| 882 |
+
# add LayerDrop (see https://huggingface.co/papers/1909.11556 for description)
|
| 883 |
+
to_drop = False
|
| 884 |
+
if self.training:
|
| 885 |
+
dropout_probability = torch.rand([])
|
| 886 |
+
if dropout_probability < self.layerdrop: # skip the layer
|
| 887 |
+
to_drop = True
|
| 888 |
+
|
| 889 |
+
if not to_drop:
|
| 890 |
+
hidden_states = encoder_layer(
|
| 891 |
+
hidden_states,
|
| 892 |
+
attention_mask=attention_mask,
|
| 893 |
+
**kwargs,
|
| 894 |
+
)
|
| 895 |
+
|
| 896 |
+
return BaseModelOutput(
|
| 897 |
+
last_hidden_state=hidden_states,
|
| 898 |
+
)
|
| 899 |
+
|
| 900 |
+
|
| 901 |
+
class AutoformerDecoder(AutoformerPreTrainedModel):
|
| 902 |
+
"""
|
| 903 |
+
Transformer decoder consisting of `config.decoder_layers` layers. Each layer is a [`AutoformerDecoderLayer`]
|
| 904 |
+
|
| 905 |
+
Args:
|
| 906 |
+
config: AutoformerConfig
|
| 907 |
+
"""
|
| 908 |
+
|
| 909 |
+
_can_record_outputs = {
|
| 910 |
+
"hidden_states": AutoformerDecoderLayer,
|
| 911 |
+
"attentions": OutputRecorder(AutoformerAttention, index=1, layer_name="self_attn"),
|
| 912 |
+
"cross_attentions": OutputRecorder(AutoformerAttention, index=1, layer_name="encoder_attn"),
|
| 913 |
+
}
|
| 914 |
+
|
| 915 |
+
def __init__(self, config: AutoformerConfig):
|
| 916 |
+
super().__init__(config)
|
| 917 |
+
self.dropout = config.dropout
|
| 918 |
+
self.layerdrop = config.decoder_layerdrop
|
| 919 |
+
if config.prediction_length is None:
|
| 920 |
+
raise ValueError("The `prediction_length` config needs to be specified.")
|
| 921 |
+
|
| 922 |
+
self.value_embedding = AutoformerValueEmbedding(feature_size=config.feature_size, d_model=config.d_model)
|
| 923 |
+
self.embed_positions = AutoformerSinusoidalPositionalEmbedding(
|
| 924 |
+
config.context_length + config.prediction_length, config.d_model
|
| 925 |
+
)
|
| 926 |
+
self.layers = nn.ModuleList(
|
| 927 |
+
[AutoformerDecoderLayer(config, layer_idx=i) for i in range(config.decoder_layers)]
|
| 928 |
+
)
|
| 929 |
+
self.layernorm_embedding = nn.LayerNorm(config.d_model)
|
| 930 |
+
|
| 931 |
+
# https://github.com/thuml/Autoformer/blob/e6371e24f2ae2dd53e472edefdd5814c5176f864/models/Autoformer.py#L74
|
| 932 |
+
self.seasonality_projection = nn.Linear(config.d_model, config.feature_size)
|
| 933 |
+
|
| 934 |
+
self.gradient_checkpointing = False
|
| 935 |
+
# Initialize weights and apply final processing
|
| 936 |
+
self.post_init()
|
| 937 |
+
|
| 938 |
+
@merge_with_config_defaults
|
| 939 |
+
@capture_outputs
|
| 940 |
+
def forward(
|
| 941 |
+
self,
|
| 942 |
+
trend: torch.Tensor | None = None,
|
| 943 |
+
attention_mask: torch.Tensor | None = None,
|
| 944 |
+
encoder_hidden_states: torch.FloatTensor | None = None,
|
| 945 |
+
encoder_attention_mask: torch.LongTensor | None = None,
|
| 946 |
+
past_key_values: Cache | None = None,
|
| 947 |
+
inputs_embeds: torch.FloatTensor | None = None,
|
| 948 |
+
use_cache: bool | None = None,
|
| 949 |
+
**kwargs: Unpack[TransformersKwargs],
|
| 950 |
+
) -> tuple | AutoFormerDecoderOutput:
|
| 951 |
+
r"""
|
| 952 |
+
Args:
|
| 953 |
+
trend (`torch.FloatTensor` of shape `(batch_size, prediction_length, feature_size)`, *optional*):
|
| 954 |
+
The trend sequence to be fed to the decoder.
|
| 955 |
+
attention_mask (`torch.Tensor` of shape `(batch_size, sequence_length)`, *optional*):
|
| 956 |
+
Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`:
|
| 957 |
+
|
| 958 |
+
- 1 for tokens that are **not masked**,
|
| 959 |
+
- 0 for tokens that are **masked**.
|
| 960 |
+
|
| 961 |
+
[What are attention masks?](../glossary#attention-mask)
|
| 962 |
+
encoder_hidden_states (`torch.FloatTensor` of shape `(batch_size, encoder_sequence_length, hidden_size)`, *optional*):
|
| 963 |
+
Sequence of hidden-states at the output of the last layer of the encoder. Used in the cross-attention
|
| 964 |
+
of the decoder.
|
| 965 |
+
encoder_attention_mask (`torch.LongTensor` of shape `(batch_size, encoder_sequence_length)`, *optional*):
|
| 966 |
+
Mask to avoid performing cross-attention on padding tokens indices of encoder input_ids. Mask values
|
| 967 |
+
selected in `[0, 1]`:
|
| 968 |
+
|
| 969 |
+
- 1 for tokens that are **not masked**,
|
| 970 |
+
- 0 for tokens that are **masked**.
|
| 971 |
+
|
| 972 |
+
[What are attention masks?](../glossary#attention-mask)
|
| 973 |
+
past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`):
|
| 974 |
+
It is a [`~cache_utils.Cache`] instance. For more details, see our [kv cache guide](https://huggingface.co/docs/transformers/en/kv_cache).
|
| 975 |
+
|
| 976 |
+
Contains pre-computed hidden-states (key and values in the self-attention blocks and in the
|
| 977 |
+
cross-attention blocks) that can be used (see `past_key_values` input) to speed up sequential decoding.
|
| 978 |
+
|
| 979 |
+
If `past_key_values` are used, the user can optionally input only the last `decoder_input_ids` (those
|
| 980 |
+
that don't have their past key value states given to this model) of shape `(batch_size, 1)` instead of
|
| 981 |
+
all `decoder_input_ids` of shape `(batch_size, sequence_length)`.
|
| 982 |
+
inputs_embeds (`torch.FloatTensor` of shape `(batch_size, sequence_length, hidden_size)`, *optional*):
|
| 983 |
+
Optionally, instead of passing `input_ids` you can choose to directly pass an embedded representation.
|
| 984 |
+
This is useful if you want more control over how to convert `input_ids` indices into associated vectors
|
| 985 |
+
than the model's internal embedding lookup matrix.
|
| 986 |
+
use_cache (`bool`, *optional*):
|
| 987 |
+
If `use_cache` is True, `past_key_values` key value states are returned and can be used to speed up
|
| 988 |
+
decoding (see `past_key_values`).
|
| 989 |
+
"""
|
| 990 |
+
if use_cache and past_key_values is None:
|
| 991 |
+
past_key_values = EncoderDecoderCache(DynamicCache(config=self.config), DynamicCache(config=self.config))
|
| 992 |
+
|
| 993 |
+
encoder_attention_mask = create_bidirectional_mask(
|
| 994 |
+
config=self.config,
|
| 995 |
+
inputs_embeds=inputs_embeds,
|
| 996 |
+
attention_mask=encoder_attention_mask,
|
| 997 |
+
encoder_hidden_states=encoder_hidden_states,
|
| 998 |
+
)
|
| 999 |
+
|
| 1000 |
+
hidden_states = self.value_embedding(inputs_embeds)
|
| 1001 |
+
embed_pos = self.embed_positions(
|
| 1002 |
+
inputs_embeds.size(), past_key_values_length=self.config.context_length - self.config.label_length
|
| 1003 |
+
)
|
| 1004 |
+
hidden_states = self.layernorm_embedding(hidden_states + embed_pos)
|
| 1005 |
+
hidden_states = nn.functional.dropout(hidden_states, p=self.dropout, training=self.training)
|
| 1006 |
+
|
| 1007 |
+
# decoder layers
|
| 1008 |
+
for idx, decoder_layer in enumerate(self.layers):
|
| 1009 |
+
# add LayerDrop (see https://huggingface.co/papers/1909.11556 for description)
|
| 1010 |
+
if self.training:
|
| 1011 |
+
dropout_probability = torch.rand([])
|
| 1012 |
+
if dropout_probability < self.layerdrop:
|
| 1013 |
+
continue
|
| 1014 |
+
|
| 1015 |
+
hidden_states, residual_trend = decoder_layer(
|
| 1016 |
+
hidden_states,
|
| 1017 |
+
attention_mask=attention_mask,
|
| 1018 |
+
encoder_hidden_states=encoder_hidden_states,
|
| 1019 |
+
encoder_attention_mask=encoder_attention_mask,
|
| 1020 |
+
past_key_values=past_key_values,
|
| 1021 |
+
use_cache=use_cache,
|
| 1022 |
+
**kwargs,
|
| 1023 |
+
)
|
| 1024 |
+
trend = trend + residual_trend
|
| 1025 |
+
|
| 1026 |
+
# project seasonality representation
|
| 1027 |
+
hidden_states = self.seasonality_projection(hidden_states)
|
| 1028 |
+
|
| 1029 |
+
return AutoFormerDecoderOutput(
|
| 1030 |
+
last_hidden_state=hidden_states,
|
| 1031 |
+
trend=trend,
|
| 1032 |
+
past_key_values=past_key_values,
|
| 1033 |
+
)
|
| 1034 |
+
|
| 1035 |
+
|
| 1036 |
+
@auto_docstring
|
| 1037 |
+
class AutoformerModel(AutoformerPreTrainedModel):
|
| 1038 |
+
def __init__(self, config: AutoformerConfig):
|
| 1039 |
+
super().__init__(config)
|
| 1040 |
+
|
| 1041 |
+
if config.scaling == "mean" or config.scaling is True:
|
| 1042 |
+
self.scaler = AutoformerMeanScaler(config)
|
| 1043 |
+
elif config.scaling == "std":
|
| 1044 |
+
self.scaler = AutoformerStdScaler(config)
|
| 1045 |
+
else:
|
| 1046 |
+
self.scaler = AutoformerNOPScaler(config)
|
| 1047 |
+
|
| 1048 |
+
if config.num_static_categorical_features > 0:
|
| 1049 |
+
self.embedder = AutoformerFeatureEmbedder(
|
| 1050 |
+
cardinalities=config.cardinality, embedding_dims=config.embedding_dimension
|
| 1051 |
+
)
|
| 1052 |
+
|
| 1053 |
+
# transformer encoder-decoder and mask initializer
|
| 1054 |
+
self.encoder = AutoformerEncoder(config)
|
| 1055 |
+
self.decoder = AutoformerDecoder(config)
|
| 1056 |
+
|
| 1057 |
+
# used for decoder seasonal and trend initialization
|
| 1058 |
+
self.decomposition_layer = AutoformerSeriesDecompositionLayer(config)
|
| 1059 |
+
|
| 1060 |
+
# Initialize weights and apply final processing
|
| 1061 |
+
self.post_init()
|
| 1062 |
+
|
| 1063 |
+
@property
|
| 1064 |
+
def _past_length(self) -> int:
|
| 1065 |
+
return self.config.context_length + max(self.config.lags_sequence)
|
| 1066 |
+
|
| 1067 |
+
def get_lagged_subsequences(
|
| 1068 |
+
self, sequence: torch.Tensor, subsequences_length: int, shift: int = 0
|
| 1069 |
+
) -> torch.Tensor:
|
| 1070 |
+
"""
|
| 1071 |
+
Returns lagged subsequences of a given sequence. Returns a tensor of shape (batch_size, subsequences_length,
|
| 1072 |
+
feature_size, indices_length), containing lagged subsequences. Specifically, lagged[i, j, :, k] = sequence[i,
|
| 1073 |
+
-indices[k]-subsequences_length+j, :].
|
| 1074 |
+
|
| 1075 |
+
Args:
|
| 1076 |
+
sequence (`torch.Tensor` or shape `(batch_size, context_length,
|
| 1077 |
+
feature_size)`): The sequence from which lagged subsequences should be extracted.
|
| 1078 |
+
subsequences_length (`int`):
|
| 1079 |
+
Length of the subsequences to be extracted.
|
| 1080 |
+
shift (`int`, *optional* defaults to 0):
|
| 1081 |
+
Shift the lags by this amount back in the time index.
|
| 1082 |
+
"""
|
| 1083 |
+
|
| 1084 |
+
# calculates the indices of the lags by subtracting the shift value from the given lags_sequence
|
| 1085 |
+
indices = [lag - shift for lag in self.config.lags_sequence]
|
| 1086 |
+
|
| 1087 |
+
# checks if the maximum lag plus the length of the subsequences exceeds the length of the input sequence
|
| 1088 |
+
sequence_length = sequence.shape[1]
|
| 1089 |
+
if max(indices) + subsequences_length > sequence_length:
|
| 1090 |
+
raise ValueError(
|
| 1091 |
+
f"lags cannot go further than history length, found lag {max(indices)} "
|
| 1092 |
+
f"while history length is only {sequence_length}"
|
| 1093 |
+
)
|
| 1094 |
+
|
| 1095 |
+
# extracts the lagged subsequences from the input sequence using the calculated indices
|
| 1096 |
+
lagged_values = []
|
| 1097 |
+
for lag_index in indices:
|
| 1098 |
+
begin_index = -lag_index - subsequences_length
|
| 1099 |
+
end_index = -lag_index if lag_index > 0 else None
|
| 1100 |
+
lagged_values.append(sequence[:, begin_index:end_index, ...])
|
| 1101 |
+
|
| 1102 |
+
# return as stacked tensor in the feature dimension
|
| 1103 |
+
return torch.stack(lagged_values, dim=-1)
|
| 1104 |
+
|
| 1105 |
+
def create_network_inputs(
|
| 1106 |
+
self,
|
| 1107 |
+
past_values: torch.Tensor,
|
| 1108 |
+
past_time_features: torch.Tensor,
|
| 1109 |
+
static_categorical_features: torch.Tensor | None = None,
|
| 1110 |
+
static_real_features: torch.Tensor | None = None,
|
| 1111 |
+
past_observed_mask: torch.Tensor | None = None,
|
| 1112 |
+
future_values: torch.Tensor | None = None,
|
| 1113 |
+
future_time_features: torch.Tensor | None = None,
|
| 1114 |
+
) -> tuple[torch.Tensor, torch.Tensor, torch.Tensor, torch.Tensor, torch.Tensor]:
|
| 1115 |
+
"""
|
| 1116 |
+
Creates the inputs for the network given the past and future values, time features, and static features.
|
| 1117 |
+
|
| 1118 |
+
Args:
|
| 1119 |
+
past_values (`torch.Tensor`):
|
| 1120 |
+
A tensor of shape `(batch_size, past_length, input_size)` containing the past values.
|
| 1121 |
+
past_time_features (`torch.Tensor`):
|
| 1122 |
+
A tensor of shape `(batch_size, past_length, num_features)` containing the past time features.
|
| 1123 |
+
static_categorical_features (`Optional[torch.Tensor]`):
|
| 1124 |
+
An optional tensor of shape `(batch_size, num_categorical_features)` containing the static categorical
|
| 1125 |
+
features.
|
| 1126 |
+
static_real_features (`Optional[torch.Tensor]`):
|
| 1127 |
+
An optional tensor of shape `(batch_size, num_real_features)` containing the static real features.
|
| 1128 |
+
past_observed_mask (`Optional[torch.Tensor]`):
|
| 1129 |
+
An optional tensor of shape `(batch_size, past_length, input_size)` containing the mask of observed
|
| 1130 |
+
values in the past.
|
| 1131 |
+
future_values (`Optional[torch.Tensor]`):
|
| 1132 |
+
An optional tensor of shape `(batch_size, future_length, input_size)` containing the future values.
|
| 1133 |
+
|
| 1134 |
+
Returns:
|
| 1135 |
+
A tuple containing the following tensors:
|
| 1136 |
+
- reshaped_lagged_sequence (`torch.Tensor`): A tensor of shape `(batch_size, sequence_length, num_lags *
|
| 1137 |
+
input_size)` containing the lagged subsequences of the inputs.
|
| 1138 |
+
- features (`torch.Tensor`): A tensor of shape `(batch_size, sequence_length, num_features)` containing the
|
| 1139 |
+
concatenated static and time features.
|
| 1140 |
+
- loc (`torch.Tensor`): A tensor of shape `(batch_size, input_size)` containing the mean of the input
|
| 1141 |
+
values.
|
| 1142 |
+
- scale (`torch.Tensor`): A tensor of shape `(batch_size, input_size)` containing the std of the input
|
| 1143 |
+
values.
|
| 1144 |
+
- static_feat (`torch.Tensor`): A tensor of shape `(batch_size, num_static_features)` containing the
|
| 1145 |
+
concatenated static features.
|
| 1146 |
+
"""
|
| 1147 |
+
# time feature
|
| 1148 |
+
time_feat = (
|
| 1149 |
+
torch.cat(
|
| 1150 |
+
(
|
| 1151 |
+
past_time_features[:, self._past_length - self.config.context_length :, ...],
|
| 1152 |
+
future_time_features,
|
| 1153 |
+
),
|
| 1154 |
+
dim=1,
|
| 1155 |
+
)
|
| 1156 |
+
if future_values is not None
|
| 1157 |
+
else past_time_features[:, self._past_length - self.config.context_length :, ...]
|
| 1158 |
+
)
|
| 1159 |
+
|
| 1160 |
+
# target
|
| 1161 |
+
if past_observed_mask is None:
|
| 1162 |
+
past_observed_mask = torch.ones_like(past_values)
|
| 1163 |
+
|
| 1164 |
+
context = past_values[:, -self.config.context_length :]
|
| 1165 |
+
observed_context = past_observed_mask[:, -self.config.context_length :]
|
| 1166 |
+
_, loc, scale = self.scaler(context, observed_context)
|
| 1167 |
+
|
| 1168 |
+
inputs = (
|
| 1169 |
+
(torch.cat((past_values, future_values), dim=1) - loc) / scale
|
| 1170 |
+
if future_values is not None
|
| 1171 |
+
else (past_values - loc) / scale
|
| 1172 |
+
)
|
| 1173 |
+
|
| 1174 |
+
# static features
|
| 1175 |
+
log_abs_loc = loc.abs().log1p() if self.config.input_size == 1 else loc.squeeze(1).abs().log1p()
|
| 1176 |
+
log_scale = scale.log() if self.config.input_size == 1 else scale.squeeze(1).log()
|
| 1177 |
+
static_feat = torch.cat((log_abs_loc, log_scale), dim=1)
|
| 1178 |
+
|
| 1179 |
+
if static_real_features is not None:
|
| 1180 |
+
static_feat = torch.cat((static_real_features, static_feat), dim=1)
|
| 1181 |
+
if static_categorical_features is not None:
|
| 1182 |
+
embedded_cat = self.embedder(static_categorical_features)
|
| 1183 |
+
static_feat = torch.cat((embedded_cat, static_feat), dim=1)
|
| 1184 |
+
expanded_static_feat = static_feat.unsqueeze(1).expand(-1, time_feat.shape[1], -1)
|
| 1185 |
+
|
| 1186 |
+
# all features
|
| 1187 |
+
features = torch.cat((expanded_static_feat, time_feat), dim=-1)
|
| 1188 |
+
|
| 1189 |
+
# lagged features
|
| 1190 |
+
subsequences_length = (
|
| 1191 |
+
self.config.context_length + self.config.prediction_length
|
| 1192 |
+
if future_values is not None
|
| 1193 |
+
else self.config.context_length
|
| 1194 |
+
)
|
| 1195 |
+
lagged_sequence = self.get_lagged_subsequences(sequence=inputs, subsequences_length=subsequences_length)
|
| 1196 |
+
lags_shape = lagged_sequence.shape
|
| 1197 |
+
reshaped_lagged_sequence = lagged_sequence.reshape(lags_shape[0], lags_shape[1], -1)
|
| 1198 |
+
|
| 1199 |
+
if reshaped_lagged_sequence.shape[1] != time_feat.shape[1]:
|
| 1200 |
+
raise ValueError(
|
| 1201 |
+
f"input length {reshaped_lagged_sequence.shape[1]} and time feature lengths {time_feat.shape[1]} does not match"
|
| 1202 |
+
)
|
| 1203 |
+
return reshaped_lagged_sequence, features, loc, scale, static_feat
|
| 1204 |
+
|
| 1205 |
+
@can_return_tuple
|
| 1206 |
+
@auto_docstring
|
| 1207 |
+
def forward(
|
| 1208 |
+
self,
|
| 1209 |
+
past_values: torch.Tensor,
|
| 1210 |
+
past_time_features: torch.Tensor,
|
| 1211 |
+
past_observed_mask: torch.Tensor,
|
| 1212 |
+
static_categorical_features: torch.Tensor | None = None,
|
| 1213 |
+
static_real_features: torch.Tensor | None = None,
|
| 1214 |
+
future_values: torch.Tensor | None = None,
|
| 1215 |
+
future_time_features: torch.Tensor | None = None,
|
| 1216 |
+
decoder_attention_mask: torch.LongTensor | None = None,
|
| 1217 |
+
encoder_outputs: list[torch.FloatTensor] | None = None,
|
| 1218 |
+
past_key_values: Cache | None = None,
|
| 1219 |
+
use_cache: bool | None = None,
|
| 1220 |
+
**kwargs: Unpack[TransformersKwargs],
|
| 1221 |
+
) -> AutoformerModelOutput:
|
| 1222 |
+
r"""
|
| 1223 |
+
past_values (`torch.FloatTensor` of shape `(batch_size, sequence_length)`):
|
| 1224 |
+
Past values of the time series, that serve as context in order to predict the future. These values may
|
| 1225 |
+
contain lags, i.e. additional values from the past which are added in order to serve as "extra context".
|
| 1226 |
+
The `past_values` is what the Transformer encoder gets as input (with optional additional features, such as
|
| 1227 |
+
`static_categorical_features`, `static_real_features`, `past_time_features`).
|
| 1228 |
+
|
| 1229 |
+
The sequence length here is equal to `context_length` + `max(config.lags_sequence)`.
|
| 1230 |
+
|
| 1231 |
+
Missing values need to be replaced with zeros.
|
| 1232 |
+
past_time_features (`torch.FloatTensor` of shape `(batch_size, sequence_length, num_features)`, *optional*):
|
| 1233 |
+
Optional time features, which the model internally will add to `past_values`. These could be things like
|
| 1234 |
+
"month of year", "day of the month", etc. encoded as vectors (for instance as Fourier features). These
|
| 1235 |
+
could also be so-called "age" features, which basically help the model know "at which point in life" a
|
| 1236 |
+
time-series is. Age features have small values for distant past time steps and increase monotonically the
|
| 1237 |
+
more we approach the current time step.
|
| 1238 |
+
|
| 1239 |
+
These features serve as the "positional encodings" of the inputs. So contrary to a model like BERT, where
|
| 1240 |
+
the position encodings are learned from scratch internally as parameters of the model, the Time Series
|
| 1241 |
+
Transformer requires to provide additional time features.
|
| 1242 |
+
|
| 1243 |
+
The Autoformer only learns additional embeddings for `static_categorical_features`.
|
| 1244 |
+
past_observed_mask (`torch.BoolTensor` of shape `(batch_size, sequence_length)`, *optional*):
|
| 1245 |
+
Boolean mask to indicate which `past_values` were observed and which were missing. Mask values selected in
|
| 1246 |
+
`[0, 1]`:
|
| 1247 |
+
|
| 1248 |
+
- 1 for values that are **observed**,
|
| 1249 |
+
- 0 for values that are **missing** (i.e. NaNs that were replaced by zeros).
|
| 1250 |
+
static_categorical_features (`torch.LongTensor` of shape `(batch_size, number of static categorical features)`, *optional*):
|
| 1251 |
+
Optional static categorical features for which the model will learn an embedding, which it will add to the
|
| 1252 |
+
values of the time series.
|
| 1253 |
+
|
| 1254 |
+
Static categorical features are features which have the same value for all time steps (static over time).
|
| 1255 |
+
|
| 1256 |
+
A typical example of a static categorical feature is a time series ID.
|
| 1257 |
+
static_real_features (`torch.FloatTensor` of shape `(batch_size, number of static real features)`, *optional*):
|
| 1258 |
+
Optional static real features which the model will add to the values of the time series.
|
| 1259 |
+
|
| 1260 |
+
Static real features are features which have the same value for all time steps (static over time).
|
| 1261 |
+
|
| 1262 |
+
A typical example of a static real feature is promotion information.
|
| 1263 |
+
future_values (`torch.FloatTensor` of shape `(batch_size, prediction_length)`):
|
| 1264 |
+
Future values of the time series, that serve as labels for the model. The `future_values` is what the
|
| 1265 |
+
Transformer needs to learn to output, given the `past_values`.
|
| 1266 |
+
|
| 1267 |
+
See the demo notebook and code snippets for details.
|
| 1268 |
+
|
| 1269 |
+
Missing values need to be replaced with zeros.
|
| 1270 |
+
future_time_features (`torch.FloatTensor` of shape `(batch_size, prediction_length, num_features)`, *optional*):
|
| 1271 |
+
Optional time features, which the model internally will add to `future_values`. These could be things like
|
| 1272 |
+
"month of year", "day of the month", etc. encoded as vectors (for instance as Fourier features). These
|
| 1273 |
+
could also be so-called "age" features, which basically help the model know "at which point in life" a
|
| 1274 |
+
time-series is. Age features have small values for distant past time steps and increase monotonically the
|
| 1275 |
+
more we approach the current time step.
|
| 1276 |
+
|
| 1277 |
+
These features serve as the "positional encodings" of the inputs. So contrary to a model like BERT, where
|
| 1278 |
+
the position encodings are learned from scratch internally as parameters of the model, the Time Series
|
| 1279 |
+
Transformer requires to provide additional features.
|
| 1280 |
+
|
| 1281 |
+
The Autoformer only learns additional embeddings for `static_categorical_features`.
|
| 1282 |
+
encoder_outputs (`tuple(tuple(torch.FloatTensor)`, *optional*):
|
| 1283 |
+
Tuple consists of `last_hidden_state`, `hidden_states` (*optional*) and `attentions` (*optional*)
|
| 1284 |
+
`last_hidden_state` of shape `(batch_size, sequence_length, hidden_size)` (*optional*) is a sequence of
|
| 1285 |
+
hidden-states at the output of the last layer of the encoder. Used in the cross-attention of the decoder.
|
| 1286 |
+
|
| 1287 |
+
Examples:
|
| 1288 |
+
|
| 1289 |
+
```python
|
| 1290 |
+
>>> from huggingface_hub import hf_hub_download
|
| 1291 |
+
>>> import torch
|
| 1292 |
+
>>> from transformers import AutoformerModel
|
| 1293 |
+
|
| 1294 |
+
>>> file = hf_hub_download(
|
| 1295 |
+
... repo_id="hf-internal-testing/tourism-monthly-batch", filename="train-batch.pt", repo_type="dataset"
|
| 1296 |
+
... )
|
| 1297 |
+
>>> batch = torch.load(file)
|
| 1298 |
+
|
| 1299 |
+
>>> model = AutoformerModel.from_pretrained("huggingface/autoformer-tourism-monthly")
|
| 1300 |
+
|
| 1301 |
+
>>> # during training, one provides both past and future values
|
| 1302 |
+
>>> # as well as possible additional features
|
| 1303 |
+
>>> outputs = model(
|
| 1304 |
+
... past_values=batch["past_values"],
|
| 1305 |
+
... past_time_features=batch["past_time_features"],
|
| 1306 |
+
... past_observed_mask=batch["past_observed_mask"],
|
| 1307 |
+
... static_categorical_features=batch["static_categorical_features"],
|
| 1308 |
+
... future_values=batch["future_values"],
|
| 1309 |
+
... future_time_features=batch["future_time_features"],
|
| 1310 |
+
... )
|
| 1311 |
+
|
| 1312 |
+
>>> last_hidden_state = outputs.last_hidden_state
|
| 1313 |
+
```"""
|
| 1314 |
+
transformer_inputs, temporal_features, loc, scale, static_feat = self.create_network_inputs(
|
| 1315 |
+
past_values=past_values,
|
| 1316 |
+
past_time_features=past_time_features,
|
| 1317 |
+
past_observed_mask=past_observed_mask,
|
| 1318 |
+
static_categorical_features=static_categorical_features,
|
| 1319 |
+
static_real_features=static_real_features,
|
| 1320 |
+
future_values=future_values,
|
| 1321 |
+
future_time_features=future_time_features,
|
| 1322 |
+
)
|
| 1323 |
+
|
| 1324 |
+
if encoder_outputs is None:
|
| 1325 |
+
enc_input = torch.cat(
|
| 1326 |
+
(
|
| 1327 |
+
transformer_inputs[:, : self.config.context_length, ...],
|
| 1328 |
+
temporal_features[:, : self.config.context_length, ...],
|
| 1329 |
+
),
|
| 1330 |
+
dim=-1,
|
| 1331 |
+
)
|
| 1332 |
+
encoder_outputs: BaseModelOutput = self.encoder(
|
| 1333 |
+
inputs_embeds=enc_input,
|
| 1334 |
+
**kwargs,
|
| 1335 |
+
)
|
| 1336 |
+
elif not isinstance(encoder_outputs, BaseModelOutput):
|
| 1337 |
+
encoder_outputs = BaseModelOutput(
|
| 1338 |
+
last_hidden_state=encoder_outputs[0],
|
| 1339 |
+
hidden_states=encoder_outputs[1] if len(encoder_outputs) > 1 else None,
|
| 1340 |
+
attentions=encoder_outputs[2] if len(encoder_outputs) > 2 else None,
|
| 1341 |
+
)
|
| 1342 |
+
|
| 1343 |
+
if future_values is not None:
|
| 1344 |
+
# Decoder inputs
|
| 1345 |
+
# seasonality and trend from context length
|
| 1346 |
+
seasonal_input, trend_input = self.decomposition_layer(
|
| 1347 |
+
transformer_inputs[:, : self.config.context_length, ...]
|
| 1348 |
+
)
|
| 1349 |
+
mean = (
|
| 1350 |
+
torch.mean(transformer_inputs[:, : self.config.context_length, ...], dim=1)
|
| 1351 |
+
.unsqueeze(1)
|
| 1352 |
+
.repeat(1, self.config.prediction_length, 1)
|
| 1353 |
+
)
|
| 1354 |
+
zeros = torch.zeros(
|
| 1355 |
+
[transformer_inputs.shape[0], self.config.prediction_length, transformer_inputs.shape[2]],
|
| 1356 |
+
device=enc_input.device,
|
| 1357 |
+
)
|
| 1358 |
+
|
| 1359 |
+
decoder_input = torch.cat(
|
| 1360 |
+
(
|
| 1361 |
+
torch.cat((seasonal_input[:, -self.config.label_length :, ...], zeros), dim=1),
|
| 1362 |
+
temporal_features[:, self.config.context_length - self.config.label_length :, ...],
|
| 1363 |
+
),
|
| 1364 |
+
dim=-1,
|
| 1365 |
+
)
|
| 1366 |
+
trend_init = torch.cat(
|
| 1367 |
+
(
|
| 1368 |
+
torch.cat((trend_input[:, -self.config.label_length :, ...], mean), dim=1),
|
| 1369 |
+
temporal_features[:, self.config.context_length - self.config.label_length :, ...],
|
| 1370 |
+
),
|
| 1371 |
+
dim=-1,
|
| 1372 |
+
)
|
| 1373 |
+
|
| 1374 |
+
decoder_outputs: AutoFormerDecoderOutput = self.decoder(
|
| 1375 |
+
trend=trend_init,
|
| 1376 |
+
inputs_embeds=decoder_input,
|
| 1377 |
+
attention_mask=decoder_attention_mask,
|
| 1378 |
+
encoder_hidden_states=encoder_outputs.last_hidden_state,
|
| 1379 |
+
past_key_values=past_key_values,
|
| 1380 |
+
use_cache=use_cache,
|
| 1381 |
+
**kwargs,
|
| 1382 |
+
)
|
| 1383 |
+
else:
|
| 1384 |
+
decoder_outputs = AutoFormerDecoderOutput()
|
| 1385 |
+
|
| 1386 |
+
return AutoformerModelOutput(
|
| 1387 |
+
last_hidden_state=decoder_outputs.last_hidden_state,
|
| 1388 |
+
trend=decoder_outputs.trend,
|
| 1389 |
+
past_key_values=decoder_outputs.past_key_values,
|
| 1390 |
+
decoder_hidden_states=decoder_outputs.hidden_states,
|
| 1391 |
+
decoder_attentions=decoder_outputs.attentions,
|
| 1392 |
+
cross_attentions=decoder_outputs.cross_attentions,
|
| 1393 |
+
encoder_last_hidden_state=encoder_outputs.last_hidden_state,
|
| 1394 |
+
encoder_hidden_states=encoder_outputs.hidden_states,
|
| 1395 |
+
encoder_attentions=encoder_outputs.attentions,
|
| 1396 |
+
loc=loc,
|
| 1397 |
+
scale=scale,
|
| 1398 |
+
static_features=static_feat,
|
| 1399 |
+
)
|
| 1400 |
+
|
| 1401 |
+
|
| 1402 |
+
@auto_docstring
|
| 1403 |
+
class AutoformerForPrediction(AutoformerPreTrainedModel):
|
| 1404 |
+
def __init__(self, config: AutoformerConfig):
|
| 1405 |
+
super().__init__(config)
|
| 1406 |
+
self.model = AutoformerModel(config)
|
| 1407 |
+
if config.distribution_output == "student_t":
|
| 1408 |
+
self.distribution_output = StudentTOutput(dim=config.input_size)
|
| 1409 |
+
elif config.distribution_output == "normal":
|
| 1410 |
+
self.distribution_output = NormalOutput(dim=config.input_size)
|
| 1411 |
+
elif config.distribution_output == "negative_binomial":
|
| 1412 |
+
self.distribution_output = NegativeBinomialOutput(dim=config.input_size)
|
| 1413 |
+
else:
|
| 1414 |
+
raise ValueError(f"Unknown distribution output {config.distribution_output}")
|
| 1415 |
+
|
| 1416 |
+
self.parameter_projection = self.distribution_output.get_parameter_projection(self.model.config.feature_size)
|
| 1417 |
+
self.target_shape = self.distribution_output.event_shape
|
| 1418 |
+
|
| 1419 |
+
if config.loss == "nll":
|
| 1420 |
+
self.loss = nll
|
| 1421 |
+
else:
|
| 1422 |
+
raise ValueError(f"Unknown loss function {config.loss}")
|
| 1423 |
+
|
| 1424 |
+
# Initialize weights of distribution_output and apply final processing
|
| 1425 |
+
self.post_init()
|
| 1426 |
+
|
| 1427 |
+
def output_params(self, decoder_output):
|
| 1428 |
+
return self.parameter_projection(decoder_output[:, -self.config.prediction_length :, :])
|
| 1429 |
+
|
| 1430 |
+
@torch.jit.ignore
|
| 1431 |
+
def output_distribution(self, params, loc=None, scale=None, trailing_n=None) -> torch.distributions.Distribution:
|
| 1432 |
+
sliced_params = params
|
| 1433 |
+
if trailing_n is not None:
|
| 1434 |
+
sliced_params = [p[:, -trailing_n:] for p in params]
|
| 1435 |
+
return self.distribution_output.distribution(sliced_params, loc=loc, scale=scale)
|
| 1436 |
+
|
| 1437 |
+
@can_return_tuple
|
| 1438 |
+
@auto_docstring
|
| 1439 |
+
def forward(
|
| 1440 |
+
self,
|
| 1441 |
+
past_values: torch.Tensor,
|
| 1442 |
+
past_time_features: torch.Tensor,
|
| 1443 |
+
past_observed_mask: torch.Tensor,
|
| 1444 |
+
static_categorical_features: torch.Tensor | None = None,
|
| 1445 |
+
static_real_features: torch.Tensor | None = None,
|
| 1446 |
+
future_values: torch.Tensor | None = None,
|
| 1447 |
+
future_time_features: torch.Tensor | None = None,
|
| 1448 |
+
future_observed_mask: torch.Tensor | None = None,
|
| 1449 |
+
decoder_attention_mask: torch.LongTensor | None = None,
|
| 1450 |
+
encoder_outputs: list[torch.FloatTensor] | None = None,
|
| 1451 |
+
past_key_values: Cache | None = None,
|
| 1452 |
+
use_cache: bool | None = None,
|
| 1453 |
+
**kwargs: Unpack[TransformersKwargs],
|
| 1454 |
+
) -> Seq2SeqTSPredictionOutput:
|
| 1455 |
+
r"""
|
| 1456 |
+
past_values (`torch.FloatTensor` of shape `(batch_size, sequence_length)`):
|
| 1457 |
+
Past values of the time series, that serve as context in order to predict the future. These values may
|
| 1458 |
+
contain lags, i.e. additional values from the past which are added in order to serve as "extra context".
|
| 1459 |
+
The `past_values` is what the Transformer encoder gets as input (with optional additional features, such as
|
| 1460 |
+
`static_categorical_features`, `static_real_features`, `past_time_features`).
|
| 1461 |
+
|
| 1462 |
+
The sequence length here is equal to `context_length` + `max(config.lags_sequence)`.
|
| 1463 |
+
|
| 1464 |
+
Missing values need to be replaced with zeros.
|
| 1465 |
+
past_time_features (`torch.FloatTensor` of shape `(batch_size, sequence_length, num_features)`, *optional*):
|
| 1466 |
+
Optional time features, which the model internally will add to `past_values`. These could be things like
|
| 1467 |
+
"month of year", "day of the month", etc. encoded as vectors (for instance as Fourier features). These
|
| 1468 |
+
could also be so-called "age" features, which basically help the model know "at which point in life" a
|
| 1469 |
+
time-series is. Age features have small values for distant past time steps and increase monotonically the
|
| 1470 |
+
more we approach the current time step.
|
| 1471 |
+
|
| 1472 |
+
These features serve as the "positional encodings" of the inputs. So contrary to a model like BERT, where
|
| 1473 |
+
the position encodings are learned from scratch internally as parameters of the model, the Time Series
|
| 1474 |
+
Transformer requires to provide additional time features.
|
| 1475 |
+
|
| 1476 |
+
The Autoformer only learns additional embeddings for `static_categorical_features`.
|
| 1477 |
+
past_observed_mask (`torch.BoolTensor` of shape `(batch_size, sequence_length)`, *optional*):
|
| 1478 |
+
Boolean mask to indicate which `past_values` were observed and which were missing. Mask values selected in
|
| 1479 |
+
`[0, 1]`:
|
| 1480 |
+
|
| 1481 |
+
- 1 for values that are **observed**,
|
| 1482 |
+
- 0 for values that are **missing** (i.e. NaNs that were replaced by zeros).
|
| 1483 |
+
static_categorical_features (`torch.LongTensor` of shape `(batch_size, number of static categorical features)`, *optional*):
|
| 1484 |
+
Optional static categorical features for which the model will learn an embedding, which it will add to the
|
| 1485 |
+
values of the time series.
|
| 1486 |
+
|
| 1487 |
+
Static categorical features are features which have the same value for all time steps (static over time).
|
| 1488 |
+
|
| 1489 |
+
A typical example of a static categorical feature is a time series ID.
|
| 1490 |
+
static_real_features (`torch.FloatTensor` of shape `(batch_size, number of static real features)`, *optional*):
|
| 1491 |
+
Optional static real features which the model will add to the values of the time series.
|
| 1492 |
+
|
| 1493 |
+
Static real features are features which have the same value for all time steps (static over time).
|
| 1494 |
+
|
| 1495 |
+
A typical example of a static real feature is promotion information.
|
| 1496 |
+
future_values (`torch.FloatTensor` of shape `(batch_size, prediction_length)`):
|
| 1497 |
+
Future values of the time series, that serve as labels for the model. The `future_values` is what the
|
| 1498 |
+
Transformer needs to learn to output, given the `past_values`.
|
| 1499 |
+
|
| 1500 |
+
See the demo notebook and code snippets for details.
|
| 1501 |
+
|
| 1502 |
+
Missing values need to be replaced with zeros.
|
| 1503 |
+
future_time_features (`torch.FloatTensor` of shape `(batch_size, prediction_length, num_features)`, *optional*):
|
| 1504 |
+
Optional time features, which the model internally will add to `future_values`. These could be things like
|
| 1505 |
+
"month of year", "day of the month", etc. encoded as vectors (for instance as Fourier features). These
|
| 1506 |
+
could also be so-called "age" features, which basically help the model know "at which point in life" a
|
| 1507 |
+
time-series is. Age features have small values for distant past time steps and increase monotonically the
|
| 1508 |
+
more we approach the current time step.
|
| 1509 |
+
|
| 1510 |
+
These features serve as the "positional encodings" of the inputs. So contrary to a model like BERT, where
|
| 1511 |
+
the position encodings are learned from scratch internally as parameters of the model, the Time Series
|
| 1512 |
+
Transformer requires to provide additional features.
|
| 1513 |
+
|
| 1514 |
+
The Autoformer only learns additional embeddings for `static_categorical_features`.
|
| 1515 |
+
future_observed_mask (`torch.BoolTensor` of shape `(batch_size, sequence_length)` or `(batch_size, sequence_length, input_size)`, *optional*):
|
| 1516 |
+
Boolean mask to indicate which `future_values` were observed and which were missing. Mask values selected
|
| 1517 |
+
in `[0, 1]`:
|
| 1518 |
+
|
| 1519 |
+
- 1 for values that are **observed**,
|
| 1520 |
+
- 0 for values that are **missing** (i.e. NaNs that were replaced by zeros).
|
| 1521 |
+
|
| 1522 |
+
This mask is used to filter out missing values for the final loss calculation.
|
| 1523 |
+
encoder_outputs (`tuple(tuple(torch.FloatTensor)`, *optional*):
|
| 1524 |
+
Tuple consists of `last_hidden_state`, `hidden_states` (*optional*) and `attentions` (*optional*)
|
| 1525 |
+
`last_hidden_state` of shape `(batch_size, sequence_length, hidden_size)` (*optional*) is a sequence of
|
| 1526 |
+
hidden-states at the output of the last layer of the encoder. Used in the cross-attention of the decoder.
|
| 1527 |
+
|
| 1528 |
+
Examples:
|
| 1529 |
+
|
| 1530 |
+
```python
|
| 1531 |
+
>>> from huggingface_hub import hf_hub_download
|
| 1532 |
+
>>> import torch
|
| 1533 |
+
>>> from transformers import AutoformerForPrediction
|
| 1534 |
+
|
| 1535 |
+
>>> file = hf_hub_download(
|
| 1536 |
+
... repo_id="hf-internal-testing/tourism-monthly-batch", filename="train-batch.pt", repo_type="dataset"
|
| 1537 |
+
... )
|
| 1538 |
+
>>> batch = torch.load(file)
|
| 1539 |
+
|
| 1540 |
+
>>> model = AutoformerForPrediction.from_pretrained("huggingface/autoformer-tourism-monthly")
|
| 1541 |
+
|
| 1542 |
+
>>> # during training, one provides both past and future values
|
| 1543 |
+
>>> # as well as possible additional features
|
| 1544 |
+
>>> outputs = model(
|
| 1545 |
+
... past_values=batch["past_values"],
|
| 1546 |
+
... past_time_features=batch["past_time_features"],
|
| 1547 |
+
... past_observed_mask=batch["past_observed_mask"],
|
| 1548 |
+
... static_categorical_features=batch["static_categorical_features"],
|
| 1549 |
+
... future_values=batch["future_values"],
|
| 1550 |
+
... future_time_features=batch["future_time_features"],
|
| 1551 |
+
... )
|
| 1552 |
+
|
| 1553 |
+
>>> loss = outputs.loss
|
| 1554 |
+
>>> loss.backward()
|
| 1555 |
+
|
| 1556 |
+
>>> # during inference, one only provides past values
|
| 1557 |
+
>>> # as well as possible additional features
|
| 1558 |
+
>>> # the model autoregressively generates future values
|
| 1559 |
+
>>> outputs = model.generate(
|
| 1560 |
+
... past_values=batch["past_values"],
|
| 1561 |
+
... past_time_features=batch["past_time_features"],
|
| 1562 |
+
... past_observed_mask=batch["past_observed_mask"],
|
| 1563 |
+
... static_categorical_features=batch["static_categorical_features"],
|
| 1564 |
+
... future_time_features=batch["future_time_features"],
|
| 1565 |
+
... )
|
| 1566 |
+
|
| 1567 |
+
>>> mean_prediction = outputs.sequences.mean(dim=1)
|
| 1568 |
+
```
|
| 1569 |
+
|
| 1570 |
+
<Tip>
|
| 1571 |
+
|
| 1572 |
+
The AutoformerForPrediction can also use static_real_features. To do so, set num_static_real_features in
|
| 1573 |
+
AutoformerConfig based on number of such features in the dataset (in case of tourism_monthly dataset it
|
| 1574 |
+
is equal to 1), initialize the model and call as shown below:
|
| 1575 |
+
|
| 1576 |
+
```
|
| 1577 |
+
>>> from huggingface_hub import hf_hub_download
|
| 1578 |
+
>>> import torch
|
| 1579 |
+
>>> from transformers import AutoformerConfig, AutoformerForPrediction
|
| 1580 |
+
|
| 1581 |
+
>>> file = hf_hub_download(
|
| 1582 |
+
... repo_id="hf-internal-testing/tourism-monthly-batch", filename="train-batch.pt", repo_type="dataset"
|
| 1583 |
+
... )
|
| 1584 |
+
>>> batch = torch.load(file)
|
| 1585 |
+
|
| 1586 |
+
>>> # check number of static real features
|
| 1587 |
+
>>> num_static_real_features = batch["static_real_features"].shape[-1]
|
| 1588 |
+
|
| 1589 |
+
>>> # load configuration of pretrained model and override num_static_real_features
|
| 1590 |
+
>>> configuration = AutoformerConfig.from_pretrained(
|
| 1591 |
+
... "huggingface/autoformer-tourism-monthly",
|
| 1592 |
+
... num_static_real_features=num_static_real_features,
|
| 1593 |
+
... )
|
| 1594 |
+
>>> # we also need to update feature_size as it is not recalculated
|
| 1595 |
+
>>> configuration.feature_size += num_static_real_features
|
| 1596 |
+
|
| 1597 |
+
>>> model = AutoformerForPrediction(configuration)
|
| 1598 |
+
|
| 1599 |
+
>>> outputs = model(
|
| 1600 |
+
... past_values=batch["past_values"],
|
| 1601 |
+
... past_time_features=batch["past_time_features"],
|
| 1602 |
+
... past_observed_mask=batch["past_observed_mask"],
|
| 1603 |
+
... static_categorical_features=batch["static_categorical_features"],
|
| 1604 |
+
... static_real_features=batch["static_real_features"],
|
| 1605 |
+
... future_values=batch["future_values"],
|
| 1606 |
+
... future_time_features=batch["future_time_features"],
|
| 1607 |
+
... )
|
| 1608 |
+
```
|
| 1609 |
+
|
| 1610 |
+
</Tip>
|
| 1611 |
+
"""
|
| 1612 |
+
|
| 1613 |
+
if future_values is not None:
|
| 1614 |
+
use_cache = False
|
| 1615 |
+
|
| 1616 |
+
outputs: AutoformerModelOutput = self.model(
|
| 1617 |
+
past_values=past_values,
|
| 1618 |
+
past_time_features=past_time_features,
|
| 1619 |
+
past_observed_mask=past_observed_mask,
|
| 1620 |
+
static_categorical_features=static_categorical_features,
|
| 1621 |
+
static_real_features=static_real_features,
|
| 1622 |
+
future_values=future_values,
|
| 1623 |
+
future_time_features=future_time_features,
|
| 1624 |
+
decoder_attention_mask=decoder_attention_mask,
|
| 1625 |
+
encoder_outputs=encoder_outputs,
|
| 1626 |
+
past_key_values=past_key_values,
|
| 1627 |
+
use_cache=use_cache,
|
| 1628 |
+
**kwargs,
|
| 1629 |
+
)
|
| 1630 |
+
|
| 1631 |
+
prediction_loss = None
|
| 1632 |
+
params = None
|
| 1633 |
+
if future_values is not None:
|
| 1634 |
+
params = self.output_params(outputs.last_hidden_state + outputs.trend)
|
| 1635 |
+
distribution = self.output_distribution(params, loc=outputs.loc, scale=outputs.scale)
|
| 1636 |
+
|
| 1637 |
+
loss = self.loss(distribution, future_values)
|
| 1638 |
+
|
| 1639 |
+
if future_observed_mask is None:
|
| 1640 |
+
future_observed_mask = torch.ones_like(future_values)
|
| 1641 |
+
|
| 1642 |
+
if len(self.target_shape) == 0:
|
| 1643 |
+
loss_weights = future_observed_mask
|
| 1644 |
+
else:
|
| 1645 |
+
loss_weights, _ = future_observed_mask.min(dim=-1, keepdim=False)
|
| 1646 |
+
|
| 1647 |
+
prediction_loss = weighted_average(loss, weights=loss_weights)
|
| 1648 |
+
|
| 1649 |
+
return Seq2SeqTSPredictionOutput(
|
| 1650 |
+
loss=prediction_loss,
|
| 1651 |
+
params=params,
|
| 1652 |
+
past_key_values=outputs.past_key_values,
|
| 1653 |
+
decoder_hidden_states=outputs.decoder_hidden_states,
|
| 1654 |
+
decoder_attentions=outputs.decoder_attentions,
|
| 1655 |
+
cross_attentions=outputs.cross_attentions,
|
| 1656 |
+
encoder_last_hidden_state=outputs.encoder_last_hidden_state,
|
| 1657 |
+
encoder_hidden_states=outputs.encoder_hidden_states,
|
| 1658 |
+
encoder_attentions=outputs.encoder_attentions,
|
| 1659 |
+
loc=outputs.loc,
|
| 1660 |
+
scale=outputs.scale,
|
| 1661 |
+
static_features=outputs.static_features,
|
| 1662 |
+
)
|
| 1663 |
+
|
| 1664 |
+
@torch.no_grad()
|
| 1665 |
+
def generate(
|
| 1666 |
+
self,
|
| 1667 |
+
past_values: torch.Tensor,
|
| 1668 |
+
past_time_features: torch.Tensor,
|
| 1669 |
+
future_time_features: torch.Tensor,
|
| 1670 |
+
past_observed_mask: torch.Tensor | None = None,
|
| 1671 |
+
static_categorical_features: torch.Tensor | None = None,
|
| 1672 |
+
static_real_features: torch.Tensor | None = None,
|
| 1673 |
+
) -> SampleTSPredictionOutput:
|
| 1674 |
+
r"""
|
| 1675 |
+
Greedily generate sequences of sample predictions from a model with a probability distribution head.
|
| 1676 |
+
|
| 1677 |
+
Parameters:
|
| 1678 |
+
past_values (`torch.FloatTensor` of shape `(batch_size, sequence_length)` or `(batch_size, sequence_length, input_size)`):
|
| 1679 |
+
Past values of the time series, that serve as context in order to predict the future. The sequence size
|
| 1680 |
+
of this tensor must be larger than the `context_length` of the model, since the model will use the
|
| 1681 |
+
larger size to construct lag features, i.e. additional values from the past which are added in order to
|
| 1682 |
+
serve as "extra context".
|
| 1683 |
+
|
| 1684 |
+
The `sequence_length` here is equal to `config.context_length` + `max(config.lags_sequence)`, which if
|
| 1685 |
+
no `lags_sequence` is configured, is equal to `config.context_length` + 7 (as by default, the largest
|
| 1686 |
+
look-back index in `config.lags_sequence` is 7). The property `_past_length` returns the actual length
|
| 1687 |
+
of the past.
|
| 1688 |
+
|
| 1689 |
+
The `past_values` is what the Transformer encoder gets as input (with optional additional features,
|
| 1690 |
+
such as `static_categorical_features`, `static_real_features`, `past_time_features` and lags).
|
| 1691 |
+
|
| 1692 |
+
Optionally, missing values need to be replaced with zeros and indicated via the `past_observed_mask`.
|
| 1693 |
+
|
| 1694 |
+
For multivariate time series, the `input_size` > 1 dimension is required and corresponds to the number
|
| 1695 |
+
of variates in the time series per time step.
|
| 1696 |
+
past_time_features (`torch.FloatTensor` of shape `(batch_size, sequence_length, num_features)`):
|
| 1697 |
+
Required time features, which the model internally will add to `past_values`. These could be things
|
| 1698 |
+
like "month of year", "day of the month", etc. encoded as vectors (for instance as Fourier features).
|
| 1699 |
+
These could also be so-called "age" features, which basically help the model know "at which point in
|
| 1700 |
+
life" a time-series is. Age features have small values for distant past time steps and increase
|
| 1701 |
+
monotonically the more we approach the current time step. Holiday features are also a good example of
|
| 1702 |
+
time features.
|
| 1703 |
+
|
| 1704 |
+
These features serve as the "positional encodings" of the inputs. So contrary to a model like BERT,
|
| 1705 |
+
where the position encodings are learned from scratch internally as parameters of the model, the Time
|
| 1706 |
+
Series Transformer requires to provide additional time features. The Time Series Transformer only
|
| 1707 |
+
learns additional embeddings for `static_categorical_features`.
|
| 1708 |
+
|
| 1709 |
+
Additional dynamic real covariates can be concatenated to this tensor, with the caveat that these
|
| 1710 |
+
features must but known at prediction time.
|
| 1711 |
+
|
| 1712 |
+
The `num_features` here is equal to `config.`num_time_features` + `config.num_dynamic_real_features`.
|
| 1713 |
+
future_time_features (`torch.FloatTensor` of shape `(batch_size, prediction_length, num_features)`):
|
| 1714 |
+
Required time features for the prediction window, which the model internally will add to sampled
|
| 1715 |
+
predictions. These could be things like "month of year", "day of the month", etc. encoded as vectors
|
| 1716 |
+
(for instance as Fourier features). These could also be so-called "age" features, which basically help
|
| 1717 |
+
the model know "at which point in life" a time-series is. Age features have small values for distant
|
| 1718 |
+
past time steps and increase monotonically the more we approach the current time step. Holiday features
|
| 1719 |
+
are also a good example of time features.
|
| 1720 |
+
|
| 1721 |
+
These features serve as the "positional encodings" of the inputs. So contrary to a model like BERT,
|
| 1722 |
+
where the position encodings are learned from scratch internally as parameters of the model, the Time
|
| 1723 |
+
Series Transformer requires to provide additional time features. The Time Series Transformer only
|
| 1724 |
+
learns additional embeddings for `static_categorical_features`.
|
| 1725 |
+
|
| 1726 |
+
Additional dynamic real covariates can be concatenated to this tensor, with the caveat that these
|
| 1727 |
+
features must but known at prediction time.
|
| 1728 |
+
|
| 1729 |
+
The `num_features` here is equal to `config.`num_time_features` + `config.num_dynamic_real_features`.
|
| 1730 |
+
past_observed_mask (`torch.BoolTensor` of shape `(batch_size, sequence_length)` or `(batch_size, sequence_length, input_size)`, *optional*):
|
| 1731 |
+
Boolean mask to indicate which `past_values` were observed and which were missing. Mask values selected
|
| 1732 |
+
in `[0, 1]`:
|
| 1733 |
+
|
| 1734 |
+
- 1 for values that are **observed**,
|
| 1735 |
+
- 0 for values that are **missing** (i.e. NaNs that were replaced by zeros).
|
| 1736 |
+
|
| 1737 |
+
static_categorical_features (`torch.LongTensor` of shape `(batch_size, number of static categorical features)`, *optional*):
|
| 1738 |
+
Optional static categorical features for which the model will learn an embedding, which it will add to
|
| 1739 |
+
the values of the time series.
|
| 1740 |
+
|
| 1741 |
+
Static categorical features are features which have the same value for all time steps (static over
|
| 1742 |
+
time).
|
| 1743 |
+
|
| 1744 |
+
A typical example of a static categorical feature is a time series ID.
|
| 1745 |
+
static_real_features (`torch.FloatTensor` of shape `(batch_size, number of static real features)`, *optional*):
|
| 1746 |
+
Optional static real features which the model will add to the values of the time series.
|
| 1747 |
+
|
| 1748 |
+
Static real features are features which have the same value for all time steps (static over time).
|
| 1749 |
+
|
| 1750 |
+
A typical example of a static real feature is promotion information.
|
| 1751 |
+
Return:
|
| 1752 |
+
[`SampleTSPredictionOutput`] where the outputs `sequences` tensor will have shape `(batch_size, number of
|
| 1753 |
+
samples, prediction_length)` or `(batch_size, number of samples, prediction_length, input_size)` for
|
| 1754 |
+
multivariate predictions.
|
| 1755 |
+
"""
|
| 1756 |
+
outputs = self(
|
| 1757 |
+
static_categorical_features=static_categorical_features,
|
| 1758 |
+
static_real_features=static_real_features,
|
| 1759 |
+
past_time_features=past_time_features,
|
| 1760 |
+
past_values=past_values,
|
| 1761 |
+
past_observed_mask=past_observed_mask,
|
| 1762 |
+
future_time_features=None,
|
| 1763 |
+
future_values=None,
|
| 1764 |
+
use_cache=False,
|
| 1765 |
+
)
|
| 1766 |
+
|
| 1767 |
+
decoder = self.model.get_decoder()
|
| 1768 |
+
enc_last_hidden = outputs.encoder_last_hidden_state
|
| 1769 |
+
loc = outputs.loc
|
| 1770 |
+
scale = outputs.scale
|
| 1771 |
+
static_feat = outputs.static_features
|
| 1772 |
+
|
| 1773 |
+
num_parallel_samples = self.config.num_parallel_samples
|
| 1774 |
+
repeated_loc = loc.repeat_interleave(repeats=num_parallel_samples, dim=0)
|
| 1775 |
+
repeated_scale = scale.repeat_interleave(repeats=num_parallel_samples, dim=0)
|
| 1776 |
+
|
| 1777 |
+
repeated_past_values = (
|
| 1778 |
+
past_values.repeat_interleave(repeats=num_parallel_samples, dim=0) - repeated_loc
|
| 1779 |
+
) / repeated_scale
|
| 1780 |
+
|
| 1781 |
+
time_features = torch.cat((past_time_features, future_time_features), dim=1)
|
| 1782 |
+
|
| 1783 |
+
expanded_static_feat = static_feat.unsqueeze(1).expand(-1, time_features.shape[1], -1)
|
| 1784 |
+
features = torch.cat((expanded_static_feat, time_features), dim=-1)
|
| 1785 |
+
repeated_features = features.repeat_interleave(repeats=num_parallel_samples, dim=0)
|
| 1786 |
+
|
| 1787 |
+
repeated_enc_last_hidden = enc_last_hidden.repeat_interleave(repeats=num_parallel_samples, dim=0)
|
| 1788 |
+
|
| 1789 |
+
lagged_sequence = self.model.get_lagged_subsequences(
|
| 1790 |
+
sequence=repeated_past_values, subsequences_length=self.config.context_length
|
| 1791 |
+
)
|
| 1792 |
+
lags_shape = lagged_sequence.shape
|
| 1793 |
+
reshaped_lagged_sequence = lagged_sequence.reshape(lags_shape[0], lags_shape[1], -1)
|
| 1794 |
+
seasonal_input, trend_input = self.model.decomposition_layer(reshaped_lagged_sequence)
|
| 1795 |
+
|
| 1796 |
+
mean = torch.mean(reshaped_lagged_sequence, dim=1).unsqueeze(1).repeat(1, self.config.prediction_length, 1)
|
| 1797 |
+
zeros = torch.zeros(
|
| 1798 |
+
[reshaped_lagged_sequence.shape[0], self.config.prediction_length, reshaped_lagged_sequence.shape[2]],
|
| 1799 |
+
device=reshaped_lagged_sequence.device,
|
| 1800 |
+
)
|
| 1801 |
+
|
| 1802 |
+
decoder_input = torch.cat(
|
| 1803 |
+
(
|
| 1804 |
+
torch.cat((seasonal_input[:, -self.config.label_length :, ...], zeros), dim=1),
|
| 1805 |
+
repeated_features[:, -self.config.prediction_length - self.config.label_length :, ...],
|
| 1806 |
+
),
|
| 1807 |
+
dim=-1,
|
| 1808 |
+
)
|
| 1809 |
+
trend_init = torch.cat(
|
| 1810 |
+
(
|
| 1811 |
+
torch.cat((trend_input[:, -self.config.label_length :, ...], mean), dim=1),
|
| 1812 |
+
repeated_features[:, -self.config.prediction_length - self.config.label_length :, ...],
|
| 1813 |
+
),
|
| 1814 |
+
dim=-1,
|
| 1815 |
+
)
|
| 1816 |
+
decoder_outputs = decoder(
|
| 1817 |
+
trend=trend_init, inputs_embeds=decoder_input, encoder_hidden_states=repeated_enc_last_hidden
|
| 1818 |
+
)
|
| 1819 |
+
decoder_last_hidden = decoder_outputs.last_hidden_state
|
| 1820 |
+
trend = decoder_outputs.trend
|
| 1821 |
+
params = self.output_params(decoder_last_hidden + trend)
|
| 1822 |
+
distr = self.output_distribution(params, loc=repeated_loc, scale=repeated_scale)
|
| 1823 |
+
future_samples = distr.sample()
|
| 1824 |
+
|
| 1825 |
+
return SampleTSPredictionOutput(
|
| 1826 |
+
sequences=future_samples.reshape(
|
| 1827 |
+
(-1, num_parallel_samples, self.config.prediction_length) + self.target_shape,
|
| 1828 |
+
)
|
| 1829 |
+
)
|
| 1830 |
+
|
| 1831 |
+
|
| 1832 |
+
__all__ = ["AutoformerForPrediction", "AutoformerModel", "AutoformerPreTrainedModel"]
|
third_party/transformers/src/transformers/models/bark/__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_bark import *
|
| 22 |
+
from .modeling_bark import *
|
| 23 |
+
from .processing_bark 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/bark/configuration_bark.py
ADDED
|
@@ -0,0 +1,275 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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 configuration"""
|
| 15 |
+
|
| 16 |
+
from huggingface_hub.dataclasses import strict
|
| 17 |
+
|
| 18 |
+
from ...configuration_utils import PreTrainedConfig
|
| 19 |
+
from ...utils import auto_docstring, logging
|
| 20 |
+
from ..auto import CONFIG_MAPPING, AutoConfig
|
| 21 |
+
|
| 22 |
+
|
| 23 |
+
logger = logging.get_logger(__name__)
|
| 24 |
+
|
| 25 |
+
|
| 26 |
+
@auto_docstring(checkpoint="suno/bark")
|
| 27 |
+
@strict
|
| 28 |
+
class BarkSubModelConfig(PreTrainedConfig):
|
| 29 |
+
r"""
|
| 30 |
+
block_size (`int`, *optional*, defaults to 1024):
|
| 31 |
+
The maximum sequence length that this model might ever be used with. Typically set this to something large
|
| 32 |
+
just in case (e.g., 512 or 1024 or 2048).
|
| 33 |
+
input_vocab_size (`int`, *optional*, defaults to 10_048):
|
| 34 |
+
Vocabulary size of a Bark sub-model. Defines the number of different tokens that can be represented by the
|
| 35 |
+
`inputs_ids` passed when calling [`{model}`]. Defaults to 10_048 but should be carefully thought with
|
| 36 |
+
regards to the chosen sub-model.
|
| 37 |
+
output_vocab_size (`int`, *optional*, defaults to 10_048):
|
| 38 |
+
Output vocabulary size of a Bark sub-model. Defines the number of different tokens that can be represented
|
| 39 |
+
by the: `output_ids` when passing forward a [`{model}`]. Defaults to 10_048 but should be carefully thought
|
| 40 |
+
with regards to the chosen sub-model.
|
| 41 |
+
bias (`bool`, *optional*, defaults to `True`):
|
| 42 |
+
Whether or not to use bias in the linear layers and layer norm layers.
|
| 43 |
+
"""
|
| 44 |
+
|
| 45 |
+
keys_to_ignore_at_inference = ["past_key_values"]
|
| 46 |
+
|
| 47 |
+
attribute_map = {
|
| 48 |
+
"num_attention_heads": "num_heads",
|
| 49 |
+
"num_hidden_layers": "num_layers",
|
| 50 |
+
"vocab_size": "input_vocab_size",
|
| 51 |
+
"window_size": "block_size",
|
| 52 |
+
}
|
| 53 |
+
|
| 54 |
+
block_size: int = 1024
|
| 55 |
+
input_vocab_size: int = 10_048
|
| 56 |
+
output_vocab_size: int = 10_048
|
| 57 |
+
num_layers: int = 12
|
| 58 |
+
num_heads: int = 12
|
| 59 |
+
hidden_size: int = 768
|
| 60 |
+
dropout: float | int = 0.0
|
| 61 |
+
bias: bool = True
|
| 62 |
+
initializer_range: float = 0.02
|
| 63 |
+
use_cache: bool = True
|
| 64 |
+
|
| 65 |
+
|
| 66 |
+
@auto_docstring(checkpoint="suno/bark")
|
| 67 |
+
@strict
|
| 68 |
+
class BarkSemanticConfig(BarkSubModelConfig):
|
| 69 |
+
r"""
|
| 70 |
+
block_size (`int`, *optional*, defaults to 1024):
|
| 71 |
+
The maximum sequence length that this model might ever be used with. Typically set this to something large
|
| 72 |
+
just in case (e.g., 512 or 1024 or 2048).
|
| 73 |
+
input_vocab_size (`int`, *optional*, defaults to 10_048):
|
| 74 |
+
Vocabulary size of a Bark sub-model. Defines the number of different tokens that can be represented by the
|
| 75 |
+
`inputs_ids` passed when calling [`{model}`]. Defaults to 10_048 but should be carefully thought with
|
| 76 |
+
regards to the chosen sub-model.
|
| 77 |
+
output_vocab_size (`int`, *optional*, defaults to 10_048):
|
| 78 |
+
Output vocabulary size of a Bark sub-model. Defines the number of different tokens that can be represented
|
| 79 |
+
by the: `output_ids` when passing forward a [`{model}`]. Defaults to 10_048 but should be carefully thought
|
| 80 |
+
with regards to the chosen sub-model.
|
| 81 |
+
bias (`bool`, *optional*, defaults to `True`):
|
| 82 |
+
Whether or not to use bias in the linear layers and layer norm layers
|
| 83 |
+
|
| 84 |
+
Example:
|
| 85 |
+
|
| 86 |
+
```python
|
| 87 |
+
>>> from transformers import BarkSemanticConfig, BarkSemanticModel
|
| 88 |
+
|
| 89 |
+
>>> # Initializing a Bark sub-module style configuration
|
| 90 |
+
>>> configuration = BarkSemanticConfig()
|
| 91 |
+
|
| 92 |
+
>>> # Initializing a model (with random weights) from the suno/bark style configuration
|
| 93 |
+
>>> model = BarkSemanticModel(configuration)
|
| 94 |
+
|
| 95 |
+
>>> # Accessing the model configuration
|
| 96 |
+
>>> configuration = model.config
|
| 97 |
+
```"""
|
| 98 |
+
|
| 99 |
+
model_type = "semantic"
|
| 100 |
+
base_config_key = "semantic_config"
|
| 101 |
+
|
| 102 |
+
|
| 103 |
+
@auto_docstring(checkpoint="suno/bark")
|
| 104 |
+
@strict
|
| 105 |
+
class BarkCoarseConfig(BarkSubModelConfig):
|
| 106 |
+
r"""
|
| 107 |
+
block_size (`int`, *optional*, defaults to 1024):
|
| 108 |
+
The maximum sequence length that this model might ever be used with. Typically set this to something large
|
| 109 |
+
just in case (e.g., 512 or 1024 or 2048).
|
| 110 |
+
input_vocab_size (`int`, *optional*, defaults to 10_048):
|
| 111 |
+
Vocabulary size of a Bark sub-model. Defines the number of different tokens that can be represented by the
|
| 112 |
+
`inputs_ids` passed when calling [`{model}`]. Defaults to 10_048 but should be carefully thought with
|
| 113 |
+
regards to the chosen sub-model.
|
| 114 |
+
output_vocab_size (`int`, *optional*, defaults to 10_048):
|
| 115 |
+
Output vocabulary size of a Bark sub-model. Defines the number of different tokens that can be represented
|
| 116 |
+
by the: `output_ids` when passing forward a [`{model}`]. Defaults to 10_048 but should be carefully thought
|
| 117 |
+
with regards to the chosen sub-model.
|
| 118 |
+
bias (`bool`, *optional*, defaults to `True`):
|
| 119 |
+
Whether or not to use bias in the linear layers and layer norm layers
|
| 120 |
+
|
| 121 |
+
Example:
|
| 122 |
+
|
| 123 |
+
```python
|
| 124 |
+
>>> from transformers import BarkCoarseConfig, BarkCoarseModel
|
| 125 |
+
|
| 126 |
+
>>> # Initializing a Bark sub-module style configuration
|
| 127 |
+
>>> configuration = BarkCoarseConfig()
|
| 128 |
+
|
| 129 |
+
>>> # Initializing a model (with random weights) from the suno/bark style configuration
|
| 130 |
+
>>> model = BarkCoarseModel(configuration)
|
| 131 |
+
|
| 132 |
+
>>> # Accessing the model configuration
|
| 133 |
+
>>> configuration = model.config
|
| 134 |
+
```"""
|
| 135 |
+
|
| 136 |
+
model_type = "coarse_acoustics"
|
| 137 |
+
base_config_key = "coarse_acoustics_config"
|
| 138 |
+
|
| 139 |
+
|
| 140 |
+
@auto_docstring(checkpoint="suno/bark")
|
| 141 |
+
@strict
|
| 142 |
+
class BarkFineConfig(BarkSubModelConfig):
|
| 143 |
+
r"""
|
| 144 |
+
block_size (`int`, *optional*, defaults to 1024):
|
| 145 |
+
The maximum sequence length that this model might ever be used with. Typically set this to something large
|
| 146 |
+
just in case (e.g., 512 or 1024 or 2048).
|
| 147 |
+
input_vocab_size (`int`, *optional*, defaults to 10_048):
|
| 148 |
+
Vocabulary size of a Bark sub-model. Defines the number of different tokens that can be represented by the
|
| 149 |
+
`inputs_ids` passed when calling [`{model}`]. Defaults to 10_048 but should be carefully thought with
|
| 150 |
+
regards to the chosen sub-model.
|
| 151 |
+
output_vocab_size (`int`, *optional*, defaults to 10_048):
|
| 152 |
+
Output vocabulary size of a Bark sub-model. Defines the number of different tokens that can be represented
|
| 153 |
+
by the: `output_ids` when passing forward a [`{model}`]. Defaults to 10_048 but should be carefully thought
|
| 154 |
+
with regards to the chosen sub-model.
|
| 155 |
+
bias (`bool`, *optional*, defaults to `True`):
|
| 156 |
+
Whether or not to use bias in the linear layers and layer norm layers
|
| 157 |
+
n_codes_total (`int`, *optional*, defaults to 8):
|
| 158 |
+
The total number of audio codebooks predicted. Used in the fine acoustics sub-model.
|
| 159 |
+
n_codes_given (`int`, *optional*, defaults to 1):
|
| 160 |
+
The number of audio codebooks predicted in the coarse acoustics sub-model. Used in the acoustics
|
| 161 |
+
sub-models.
|
| 162 |
+
|
| 163 |
+
Example:
|
| 164 |
+
|
| 165 |
+
```python
|
| 166 |
+
>>> from transformers import BarkFineConfig, BarkFineModel
|
| 167 |
+
|
| 168 |
+
>>> # Initializing a Bark sub-module style configuration
|
| 169 |
+
>>> configuration = BarkFineConfig()
|
| 170 |
+
|
| 171 |
+
>>> # Initializing a model (with random weights) from the suno/bark style configuration
|
| 172 |
+
>>> model = BarkFineModel(configuration)
|
| 173 |
+
|
| 174 |
+
>>> # Accessing the model configuration
|
| 175 |
+
>>> configuration = model.config
|
| 176 |
+
```"""
|
| 177 |
+
|
| 178 |
+
model_type = "fine_acoustics"
|
| 179 |
+
base_config_key = "fine_acoustics_config"
|
| 180 |
+
|
| 181 |
+
tie_word_embeddings: bool = True
|
| 182 |
+
n_codes_total: int = 8
|
| 183 |
+
n_codes_given: int = 1
|
| 184 |
+
|
| 185 |
+
|
| 186 |
+
@auto_docstring(checkpoint="suno/bark")
|
| 187 |
+
@strict
|
| 188 |
+
class BarkConfig(PreTrainedConfig):
|
| 189 |
+
r"""
|
| 190 |
+
semantic_config ([`BarkSemanticConfig`], *optional*):
|
| 191 |
+
Configuration of the underlying semantic sub-model.
|
| 192 |
+
coarse_acoustics_config ([`BarkCoarseConfig`], *optional*):
|
| 193 |
+
Configuration of the underlying coarse acoustics sub-model.
|
| 194 |
+
fine_acoustics_config ([`BarkFineConfig`], *optional*):
|
| 195 |
+
Configuration of the underlying fine acoustics sub-model.
|
| 196 |
+
codec_config ([`AutoConfig`], *optional*):
|
| 197 |
+
Configuration of the underlying codec sub-model.
|
| 198 |
+
|
| 199 |
+
Example:
|
| 200 |
+
|
| 201 |
+
```python
|
| 202 |
+
>>> from transformers import (
|
| 203 |
+
... BarkSemanticConfig,
|
| 204 |
+
... BarkCoarseConfig,
|
| 205 |
+
... BarkFineConfig,
|
| 206 |
+
... BarkModel,
|
| 207 |
+
... BarkConfig,
|
| 208 |
+
... AutoConfig,
|
| 209 |
+
... )
|
| 210 |
+
|
| 211 |
+
>>> # Initializing Bark sub-modules configurations.
|
| 212 |
+
>>> semantic_config = BarkSemanticConfig()
|
| 213 |
+
>>> coarse_acoustics_config = BarkCoarseConfig()
|
| 214 |
+
>>> fine_acoustics_config = BarkFineConfig()
|
| 215 |
+
>>> codec_config = AutoConfig.from_pretrained("facebook/encodec_24khz")
|
| 216 |
+
|
| 217 |
+
|
| 218 |
+
>>> # Initializing a Bark module style configuration
|
| 219 |
+
>>> configuration = BarkConfig(
|
| 220 |
+
... semantic_config, coarse_acoustics_config, fine_acoustics_config, codec_config
|
| 221 |
+
... )
|
| 222 |
+
|
| 223 |
+
>>> # Initializing a model (with random weights)
|
| 224 |
+
>>> model = BarkModel(configuration)
|
| 225 |
+
|
| 226 |
+
>>> # Accessing the model configuration
|
| 227 |
+
>>> configuration = model.config
|
| 228 |
+
```
|
| 229 |
+
"""
|
| 230 |
+
|
| 231 |
+
model_type = "bark"
|
| 232 |
+
sub_configs = {
|
| 233 |
+
"semantic_config": BarkSemanticConfig,
|
| 234 |
+
"coarse_acoustics_config": BarkCoarseConfig,
|
| 235 |
+
"fine_acoustics_config": BarkFineConfig,
|
| 236 |
+
"codec_config": AutoConfig,
|
| 237 |
+
}
|
| 238 |
+
semantic_config: dict | PreTrainedConfig | None = None
|
| 239 |
+
coarse_acoustics_config: dict | PreTrainedConfig | None = None
|
| 240 |
+
fine_acoustics_config: dict | PreTrainedConfig | None = None
|
| 241 |
+
codec_config: dict | PreTrainedConfig | None = None
|
| 242 |
+
initializer_range: float = 0.02
|
| 243 |
+
|
| 244 |
+
def __post_init__(self, **kwargs):
|
| 245 |
+
if self.semantic_config is None:
|
| 246 |
+
self.semantic_config = BarkSemanticConfig()
|
| 247 |
+
logger.info("`semantic_config` is `None`. Initializing the `BarkSemanticConfig` with default values.")
|
| 248 |
+
elif isinstance(self.semantic_config, dict):
|
| 249 |
+
self.semantic_config = BarkSemanticConfig(**self.semantic_config)
|
| 250 |
+
|
| 251 |
+
if self.coarse_acoustics_config is None:
|
| 252 |
+
self.coarse_acoustics_config = BarkCoarseConfig()
|
| 253 |
+
logger.info(
|
| 254 |
+
"`coarse_acoustics_config` is `None`. Initializing the `BarkCoarseConfig` with default values."
|
| 255 |
+
)
|
| 256 |
+
elif isinstance(self.coarse_acoustics_config, dict):
|
| 257 |
+
self.coarse_acoustics_config = BarkCoarseConfig(**self.coarse_acoustics_config)
|
| 258 |
+
|
| 259 |
+
if self.fine_acoustics_config is None:
|
| 260 |
+
self.fine_acoustics_config = BarkFineConfig()
|
| 261 |
+
logger.info("`fine_acoustics_config` is `None`. Initializing the `BarkFineConfig` with default values.")
|
| 262 |
+
elif isinstance(self.fine_acoustics_config, dict):
|
| 263 |
+
self.fine_acoustics_config = BarkFineConfig(**self.fine_acoustics_config)
|
| 264 |
+
|
| 265 |
+
if self.codec_config is None:
|
| 266 |
+
self.codec_config = CONFIG_MAPPING["encodec"]()
|
| 267 |
+
logger.info("`codec_config` is `None`. Initializing the `codec_config` with default values.")
|
| 268 |
+
elif isinstance(self.codec_config, dict):
|
| 269 |
+
codec_model_type = self.codec_config.get("model_type", "encodec")
|
| 270 |
+
self.codec_config = CONFIG_MAPPING[codec_model_type](**self.codec_config)
|
| 271 |
+
|
| 272 |
+
super().__post_init__(**kwargs)
|
| 273 |
+
|
| 274 |
+
|
| 275 |
+
__all__ = ["BarkCoarseConfig", "BarkConfig", "BarkFineConfig", "BarkSemanticConfig"]
|
third_party/transformers/src/transformers/models/bark/convert_suno_to_hf.py
ADDED
|
@@ -0,0 +1,261 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Convert Bark checkpoint."""
|
| 2 |
+
|
| 3 |
+
import argparse
|
| 4 |
+
import os
|
| 5 |
+
from pathlib import Path
|
| 6 |
+
|
| 7 |
+
import torch
|
| 8 |
+
from bark.generation import _load_model as _bark_load_model
|
| 9 |
+
from huggingface_hub import hf_hub_download
|
| 10 |
+
|
| 11 |
+
from transformers import EncodecConfig, EncodecModel, set_seed
|
| 12 |
+
from transformers.models.bark.configuration_bark import (
|
| 13 |
+
BarkCoarseConfig,
|
| 14 |
+
BarkConfig,
|
| 15 |
+
BarkFineConfig,
|
| 16 |
+
BarkSemanticConfig,
|
| 17 |
+
)
|
| 18 |
+
from transformers.models.bark.generation_configuration_bark import (
|
| 19 |
+
BarkCoarseGenerationConfig,
|
| 20 |
+
BarkFineGenerationConfig,
|
| 21 |
+
BarkGenerationConfig,
|
| 22 |
+
BarkSemanticGenerationConfig,
|
| 23 |
+
)
|
| 24 |
+
from transformers.models.bark.modeling_bark import BarkCoarseModel, BarkFineModel, BarkModel, BarkSemanticModel
|
| 25 |
+
from transformers.utils import logging
|
| 26 |
+
|
| 27 |
+
|
| 28 |
+
logging.set_verbosity_info()
|
| 29 |
+
logger = logging.get_logger(__name__)
|
| 30 |
+
|
| 31 |
+
set_seed(770)
|
| 32 |
+
|
| 33 |
+
|
| 34 |
+
new_layer_name_dict = {
|
| 35 |
+
"c_attn": "att_proj",
|
| 36 |
+
"c_proj": "out_proj",
|
| 37 |
+
"c_fc": "in_proj",
|
| 38 |
+
"transformer.": "",
|
| 39 |
+
"h.": "layers.",
|
| 40 |
+
"ln_1": "layernorm_1",
|
| 41 |
+
"ln_2": "layernorm_2",
|
| 42 |
+
"ln_f": "layernorm_final",
|
| 43 |
+
"wpe": "position_embeds_layer",
|
| 44 |
+
"wte": "input_embeds_layer",
|
| 45 |
+
}
|
| 46 |
+
|
| 47 |
+
|
| 48 |
+
REMOTE_MODEL_PATHS = {
|
| 49 |
+
"text_small": {
|
| 50 |
+
"repo_id": "suno/bark",
|
| 51 |
+
"file_name": "text.pt",
|
| 52 |
+
},
|
| 53 |
+
"coarse_small": {
|
| 54 |
+
"repo_id": "suno/bark",
|
| 55 |
+
"file_name": "coarse.pt",
|
| 56 |
+
},
|
| 57 |
+
"fine_small": {
|
| 58 |
+
"repo_id": "suno/bark",
|
| 59 |
+
"file_name": "fine.pt",
|
| 60 |
+
},
|
| 61 |
+
"text": {
|
| 62 |
+
"repo_id": "suno/bark",
|
| 63 |
+
"file_name": "text_2.pt",
|
| 64 |
+
},
|
| 65 |
+
"coarse": {
|
| 66 |
+
"repo_id": "suno/bark",
|
| 67 |
+
"file_name": "coarse_2.pt",
|
| 68 |
+
},
|
| 69 |
+
"fine": {
|
| 70 |
+
"repo_id": "suno/bark",
|
| 71 |
+
"file_name": "fine_2.pt",
|
| 72 |
+
},
|
| 73 |
+
}
|
| 74 |
+
|
| 75 |
+
CUR_PATH = os.path.dirname(os.path.abspath(__file__))
|
| 76 |
+
default_cache_dir = os.path.join(os.path.expanduser("~"), ".cache")
|
| 77 |
+
CACHE_DIR = os.path.join(os.getenv("XDG_CACHE_HOME", default_cache_dir), "suno", "bark_v0")
|
| 78 |
+
|
| 79 |
+
|
| 80 |
+
def _get_ckpt_path(model_type, use_small=False):
|
| 81 |
+
key = model_type
|
| 82 |
+
if use_small:
|
| 83 |
+
key += "_small"
|
| 84 |
+
return os.path.join(CACHE_DIR, REMOTE_MODEL_PATHS[key]["file_name"])
|
| 85 |
+
|
| 86 |
+
|
| 87 |
+
def _download(from_hf_path, file_name):
|
| 88 |
+
os.makedirs(CACHE_DIR, exist_ok=True)
|
| 89 |
+
hf_hub_download(repo_id=from_hf_path, filename=file_name, local_dir=CACHE_DIR)
|
| 90 |
+
|
| 91 |
+
|
| 92 |
+
def _load_model(ckpt_path, device, use_small=False, model_type="text"):
|
| 93 |
+
if model_type == "text":
|
| 94 |
+
ModelClass = BarkSemanticModel
|
| 95 |
+
ConfigClass = BarkSemanticConfig
|
| 96 |
+
GenerationConfigClass = BarkSemanticGenerationConfig
|
| 97 |
+
elif model_type == "coarse":
|
| 98 |
+
ModelClass = BarkCoarseModel
|
| 99 |
+
ConfigClass = BarkCoarseConfig
|
| 100 |
+
GenerationConfigClass = BarkCoarseGenerationConfig
|
| 101 |
+
elif model_type == "fine":
|
| 102 |
+
ModelClass = BarkFineModel
|
| 103 |
+
ConfigClass = BarkFineConfig
|
| 104 |
+
GenerationConfigClass = BarkFineGenerationConfig
|
| 105 |
+
else:
|
| 106 |
+
raise NotImplementedError()
|
| 107 |
+
model_key = f"{model_type}_small" if use_small else model_type
|
| 108 |
+
model_info = REMOTE_MODEL_PATHS[model_key]
|
| 109 |
+
if not os.path.exists(ckpt_path):
|
| 110 |
+
logger.info(f"{model_type} model not found, downloading into `{CACHE_DIR}`.")
|
| 111 |
+
_download(model_info["repo_id"], model_info["file_name"])
|
| 112 |
+
checkpoint = torch.load(ckpt_path, map_location=device, weights_only=True)
|
| 113 |
+
# this is a hack
|
| 114 |
+
model_args = checkpoint["model_args"]
|
| 115 |
+
if "input_vocab_size" not in model_args:
|
| 116 |
+
model_args["input_vocab_size"] = model_args["vocab_size"]
|
| 117 |
+
model_args["output_vocab_size"] = model_args["vocab_size"]
|
| 118 |
+
del model_args["vocab_size"]
|
| 119 |
+
|
| 120 |
+
# convert Bark model arguments to HF Bark model arguments
|
| 121 |
+
model_args["num_heads"] = model_args.pop("n_head")
|
| 122 |
+
model_args["hidden_size"] = model_args.pop("n_embd")
|
| 123 |
+
model_args["num_layers"] = model_args.pop("n_layer")
|
| 124 |
+
|
| 125 |
+
model_config = ConfigClass(**checkpoint["model_args"])
|
| 126 |
+
model = ModelClass(config=model_config)
|
| 127 |
+
model_generation_config = GenerationConfigClass()
|
| 128 |
+
|
| 129 |
+
model.generation_config = model_generation_config
|
| 130 |
+
state_dict = checkpoint["model"]
|
| 131 |
+
# fixup checkpoint
|
| 132 |
+
unwanted_prefix = "_orig_mod."
|
| 133 |
+
for k in state_dict:
|
| 134 |
+
if k.startswith(unwanted_prefix):
|
| 135 |
+
# replace part of the key with corresponding layer name in HF implementation
|
| 136 |
+
new_k = k[len(unwanted_prefix) :]
|
| 137 |
+
for old_layer_name, new_layer_name in new_layer_name_dict.items():
|
| 138 |
+
new_k = new_k.replace(old_layer_name, new_layer_name)
|
| 139 |
+
|
| 140 |
+
state_dict[new_k] = state_dict.pop(k)
|
| 141 |
+
|
| 142 |
+
extra_keys = set(state_dict.keys()) - set(model.state_dict().keys())
|
| 143 |
+
extra_keys = {k for k in extra_keys if not k.endswith(".attn.bias")}
|
| 144 |
+
missing_keys = set(model.state_dict().keys()) - set(state_dict.keys())
|
| 145 |
+
missing_keys = {k for k in missing_keys if not k.endswith(".attn.bias")}
|
| 146 |
+
if len(extra_keys) != 0:
|
| 147 |
+
raise ValueError(f"extra keys found: {extra_keys}")
|
| 148 |
+
if len(missing_keys) != 0:
|
| 149 |
+
raise ValueError(f"missing keys: {missing_keys}")
|
| 150 |
+
model.load_state_dict(state_dict, strict=False)
|
| 151 |
+
n_params = model.num_parameters(exclude_embeddings=True)
|
| 152 |
+
val_loss = checkpoint["best_val_loss"].item()
|
| 153 |
+
logger.info(f"model loaded: {round(n_params / 1e6, 1)}M params, {round(val_loss, 3)} loss")
|
| 154 |
+
model.eval()
|
| 155 |
+
model.to(device)
|
| 156 |
+
del checkpoint, state_dict
|
| 157 |
+
|
| 158 |
+
return model
|
| 159 |
+
|
| 160 |
+
|
| 161 |
+
def load_model(pytorch_dump_folder_path, use_small=False, model_type="text"):
|
| 162 |
+
if model_type not in ("text", "coarse", "fine"):
|
| 163 |
+
raise NotImplementedError()
|
| 164 |
+
|
| 165 |
+
device = "cpu" # do conversion on cpu
|
| 166 |
+
|
| 167 |
+
ckpt_path = _get_ckpt_path(model_type, use_small=use_small)
|
| 168 |
+
model = _load_model(ckpt_path, device, model_type=model_type, use_small=use_small)
|
| 169 |
+
|
| 170 |
+
# load bark initial model
|
| 171 |
+
bark_model = _bark_load_model(ckpt_path, "cpu", model_type=model_type, use_small=use_small)
|
| 172 |
+
|
| 173 |
+
if model_type == "text":
|
| 174 |
+
bark_model = bark_model["model"]
|
| 175 |
+
|
| 176 |
+
if model.num_parameters(exclude_embeddings=True) != bark_model.get_num_params():
|
| 177 |
+
raise ValueError("initial and new models don't have the same number of parameters")
|
| 178 |
+
|
| 179 |
+
# check if same output as the bark model
|
| 180 |
+
batch_size = 5
|
| 181 |
+
sequence_length = 10
|
| 182 |
+
|
| 183 |
+
if model_type in ["text", "coarse"]:
|
| 184 |
+
vec = torch.randint(256, (batch_size, sequence_length), dtype=torch.int)
|
| 185 |
+
output_old_model = bark_model(vec)[0]
|
| 186 |
+
|
| 187 |
+
output_new_model_total = model(vec)
|
| 188 |
+
|
| 189 |
+
# take last logits
|
| 190 |
+
output_new_model = output_new_model_total.logits[:, [-1], :]
|
| 191 |
+
|
| 192 |
+
else:
|
| 193 |
+
prediction_codebook_channel = 3
|
| 194 |
+
n_codes_total = 8
|
| 195 |
+
vec = torch.randint(256, (batch_size, sequence_length, n_codes_total), dtype=torch.int)
|
| 196 |
+
|
| 197 |
+
output_new_model_total = model(prediction_codebook_channel, vec)
|
| 198 |
+
output_old_model = bark_model(prediction_codebook_channel, vec)
|
| 199 |
+
|
| 200 |
+
output_new_model = output_new_model_total.logits
|
| 201 |
+
|
| 202 |
+
# output difference should come from the difference of self-attention implementation design
|
| 203 |
+
if output_new_model.shape != output_old_model.shape:
|
| 204 |
+
raise ValueError("initial and new outputs don't have the same shape")
|
| 205 |
+
if (output_new_model - output_old_model).abs().max().item() > 1e-3:
|
| 206 |
+
raise ValueError("initial and new outputs are not equal")
|
| 207 |
+
|
| 208 |
+
Path(pytorch_dump_folder_path).mkdir(exist_ok=True)
|
| 209 |
+
model.save_pretrained(pytorch_dump_folder_path)
|
| 210 |
+
|
| 211 |
+
|
| 212 |
+
def load_whole_bark_model(
|
| 213 |
+
semantic_path,
|
| 214 |
+
coarse_path,
|
| 215 |
+
fine_path,
|
| 216 |
+
append_text,
|
| 217 |
+
hub_path,
|
| 218 |
+
folder_path,
|
| 219 |
+
):
|
| 220 |
+
pytorch_dump_folder_path = os.path.join(folder_path, append_text)
|
| 221 |
+
|
| 222 |
+
semanticConfig = BarkSemanticConfig.from_pretrained(os.path.join(semantic_path, "config.json"))
|
| 223 |
+
coarseAcousticConfig = BarkCoarseConfig.from_pretrained(os.path.join(coarse_path, "config.json"))
|
| 224 |
+
fineAcousticConfig = BarkFineConfig.from_pretrained(os.path.join(fine_path, "config.json"))
|
| 225 |
+
codecConfig = EncodecConfig.from_pretrained("facebook/encodec_24khz")
|
| 226 |
+
|
| 227 |
+
semantic = BarkSemanticModel.from_pretrained(semantic_path)
|
| 228 |
+
coarseAcoustic = BarkCoarseModel.from_pretrained(coarse_path)
|
| 229 |
+
fineAcoustic = BarkFineModel.from_pretrained(fine_path)
|
| 230 |
+
codec = EncodecModel.from_pretrained("facebook/encodec_24khz")
|
| 231 |
+
|
| 232 |
+
bark_config = BarkConfig(semanticConfig, coarseAcousticConfig, fineAcousticConfig, codecConfig)
|
| 233 |
+
|
| 234 |
+
bark_generation_config = BarkGenerationConfig(
|
| 235 |
+
semantic.generation_config, coarseAcoustic.generation_config, fineAcoustic.generation_config
|
| 236 |
+
)
|
| 237 |
+
|
| 238 |
+
bark = BarkModel(bark_config)
|
| 239 |
+
|
| 240 |
+
bark.semantic = semantic
|
| 241 |
+
bark.coarse_acoustics = coarseAcoustic
|
| 242 |
+
bark.fine_acoustics = fineAcoustic
|
| 243 |
+
bark.codec_model = codec
|
| 244 |
+
|
| 245 |
+
bark.generation_config = bark_generation_config
|
| 246 |
+
|
| 247 |
+
Path(pytorch_dump_folder_path).mkdir(exist_ok=True)
|
| 248 |
+
bark.save_pretrained(pytorch_dump_folder_path, repo_id=hub_path, push_to_hub=True)
|
| 249 |
+
|
| 250 |
+
|
| 251 |
+
if __name__ == "__main__":
|
| 252 |
+
parser = argparse.ArgumentParser()
|
| 253 |
+
# Required parameters
|
| 254 |
+
|
| 255 |
+
parser.add_argument("model_type", type=str, help="text, coarse or fine.")
|
| 256 |
+
parser.add_argument("pytorch_dump_folder_path", default=None, type=str, help="Path to the output PyTorch model.")
|
| 257 |
+
parser.add_argument("--is_small", action="store_true", help="convert the small version instead of the large.")
|
| 258 |
+
|
| 259 |
+
args = parser.parse_args()
|
| 260 |
+
|
| 261 |
+
load_model(args.pytorch_dump_folder_path, model_type=args.model_type, use_small=args.is_small)
|
third_party/transformers/src/transformers/models/bark/modeling_bark.py
ADDED
|
@@ -0,0 +1,1521 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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 |
+
"""PyTorch BARK model."""
|
| 15 |
+
|
| 16 |
+
import math
|
| 17 |
+
|
| 18 |
+
import numpy as np
|
| 19 |
+
import torch
|
| 20 |
+
from torch import nn
|
| 21 |
+
from torch.nn import functional as F
|
| 22 |
+
|
| 23 |
+
from ... import initialization as init
|
| 24 |
+
from ...cache_utils import Cache, DynamicCache
|
| 25 |
+
from ...generation import GenerationMixin
|
| 26 |
+
from ...generation.logits_process import (
|
| 27 |
+
AlternatingCodebooksLogitsProcessor,
|
| 28 |
+
BarkEosPrioritizerLogitsProcessor,
|
| 29 |
+
SuppressTokensLogitsProcessor,
|
| 30 |
+
)
|
| 31 |
+
from ...masking_utils import create_bidirectional_mask
|
| 32 |
+
from ...modeling_flash_attention_utils import flash_attn_supports_top_left_mask, is_flash_attn_available
|
| 33 |
+
from ...modeling_layers import GradientCheckpointingLayer
|
| 34 |
+
from ...modeling_outputs import CausalLMOutputWithPast, MaskedLMOutput
|
| 35 |
+
from ...modeling_utils import PreTrainedModel
|
| 36 |
+
from ...utils import (
|
| 37 |
+
auto_docstring,
|
| 38 |
+
is_accelerate_available,
|
| 39 |
+
is_torch_accelerator_available,
|
| 40 |
+
logging,
|
| 41 |
+
)
|
| 42 |
+
from ...utils.deprecation import deprecate_kwarg
|
| 43 |
+
from ..auto import AutoModel
|
| 44 |
+
from .configuration_bark import (
|
| 45 |
+
BarkCoarseConfig,
|
| 46 |
+
BarkConfig,
|
| 47 |
+
BarkFineConfig,
|
| 48 |
+
BarkSemanticConfig,
|
| 49 |
+
BarkSubModelConfig,
|
| 50 |
+
)
|
| 51 |
+
from .generation_configuration_bark import (
|
| 52 |
+
BarkCoarseGenerationConfig,
|
| 53 |
+
BarkFineGenerationConfig,
|
| 54 |
+
BarkSemanticGenerationConfig,
|
| 55 |
+
)
|
| 56 |
+
|
| 57 |
+
|
| 58 |
+
if is_flash_attn_available():
|
| 59 |
+
from ...integrations.flash_attention import get_target_dtype
|
| 60 |
+
from ...modeling_flash_attention_utils import _flash_attention_forward
|
| 61 |
+
|
| 62 |
+
|
| 63 |
+
logger = logging.get_logger(__name__)
|
| 64 |
+
|
| 65 |
+
|
| 66 |
+
class BarkSelfAttention(nn.Module):
|
| 67 |
+
# adapted from GPTNeoSelfAttention and Bark code
|
| 68 |
+
# BarkSelfAttention can have two attention type, i.e full attention or causal attention
|
| 69 |
+
|
| 70 |
+
def __init__(self, config, is_causal=False, layer_idx=None):
|
| 71 |
+
super().__init__()
|
| 72 |
+
|
| 73 |
+
# regularization
|
| 74 |
+
self.dropout = config.dropout
|
| 75 |
+
self.attn_dropout = nn.Dropout(config.dropout)
|
| 76 |
+
self.resid_dropout = nn.Dropout(config.dropout)
|
| 77 |
+
|
| 78 |
+
self.embed_dim = config.hidden_size
|
| 79 |
+
self.num_heads = config.num_heads
|
| 80 |
+
self.head_dim = self.embed_dim // self.num_heads
|
| 81 |
+
self.config = config
|
| 82 |
+
|
| 83 |
+
if config.hidden_size % config.num_heads != 0:
|
| 84 |
+
raise ValueError(
|
| 85 |
+
f"embed_dim must be divisible by num_heads (got `embed_dim`: {self.embed_dim} and `num_heads`:"
|
| 86 |
+
f" {self.num_heads})."
|
| 87 |
+
)
|
| 88 |
+
|
| 89 |
+
# key, query, value projections for all heads, but in a batch
|
| 90 |
+
self.att_proj = nn.Linear(config.hidden_size, 3 * config.hidden_size, bias=config.bias)
|
| 91 |
+
# output projection
|
| 92 |
+
self.out_proj = nn.Linear(config.hidden_size, config.hidden_size, bias=config.bias)
|
| 93 |
+
|
| 94 |
+
self.is_causal = is_causal
|
| 95 |
+
self.layer_idx = layer_idx
|
| 96 |
+
if is_causal:
|
| 97 |
+
block_size = config.block_size
|
| 98 |
+
bias = torch.tril(torch.ones((block_size, block_size), dtype=bool)).view(1, 1, block_size, block_size)
|
| 99 |
+
self.register_buffer("bias", bias)
|
| 100 |
+
|
| 101 |
+
# Copied from transformers.models.gpt_neo.modeling_gpt_neo.GPTNeoSelfAttention._split_heads
|
| 102 |
+
def _split_heads(self, tensor, num_heads, attn_head_size):
|
| 103 |
+
"""
|
| 104 |
+
Splits hidden_size dim into attn_head_size and num_heads
|
| 105 |
+
"""
|
| 106 |
+
new_shape = tensor.size()[:-1] + (num_heads, attn_head_size)
|
| 107 |
+
tensor = tensor.view(new_shape)
|
| 108 |
+
return tensor.permute(0, 2, 1, 3) # (batch, head, seq_length, head_features)
|
| 109 |
+
|
| 110 |
+
def _merge_heads(self, tensor, num_heads, attn_head_size):
|
| 111 |
+
"""
|
| 112 |
+
Merges attn_head_size dim and num_attn_heads dim into hidden_size
|
| 113 |
+
"""
|
| 114 |
+
|
| 115 |
+
# re-assemble all head outputs side by side
|
| 116 |
+
# (batch, num_heads, seq_len, attn_head_size) -> (batch, seq_len, num_heads*attn_head_size)
|
| 117 |
+
tensor = tensor.transpose(1, 2).contiguous()
|
| 118 |
+
tensor = tensor.view(tensor.size()[:-2] + (num_heads * attn_head_size,))
|
| 119 |
+
|
| 120 |
+
return tensor
|
| 121 |
+
|
| 122 |
+
def _attn(self, query, key, value, attention_mask=None):
|
| 123 |
+
# unlike GPTNeo's SelfAttention, divide by the square root of the dimension of the query and the key
|
| 124 |
+
attn_weights = torch.matmul(query, key.transpose(-1, -2)) * (1.0 / math.sqrt(self.head_dim))
|
| 125 |
+
|
| 126 |
+
if self.is_causal:
|
| 127 |
+
query_length, key_length = query.size(-2), key.size(-2)
|
| 128 |
+
|
| 129 |
+
# fill the upper left part of the attention weights with inf
|
| 130 |
+
attn_weights = attn_weights.masked_fill(
|
| 131 |
+
self.bias[:, :, key_length - query_length : key_length, :key_length] == 0,
|
| 132 |
+
torch.finfo(attn_weights.dtype).min,
|
| 133 |
+
)
|
| 134 |
+
|
| 135 |
+
if attention_mask is not None:
|
| 136 |
+
# Apply the attention mask
|
| 137 |
+
attn_weights = attn_weights + attention_mask
|
| 138 |
+
|
| 139 |
+
attn_weights = nn.functional.softmax(attn_weights, dim=-1)
|
| 140 |
+
attn_weights = attn_weights.to(value.dtype)
|
| 141 |
+
attn_weights = self.attn_dropout(attn_weights)
|
| 142 |
+
|
| 143 |
+
# (batch, num_heads, seq_len, seq_len) x (batch, num_heads, seq_len, attn_head_size)
|
| 144 |
+
# -> (batch, num_heads, seq_len, attn_head_size)
|
| 145 |
+
attn_output = torch.matmul(attn_weights, value)
|
| 146 |
+
|
| 147 |
+
return attn_output, attn_weights
|
| 148 |
+
|
| 149 |
+
def forward(
|
| 150 |
+
self,
|
| 151 |
+
hidden_states,
|
| 152 |
+
attention_mask=None,
|
| 153 |
+
past_key_values=None,
|
| 154 |
+
use_cache=False,
|
| 155 |
+
output_attentions=False,
|
| 156 |
+
**kwargs,
|
| 157 |
+
):
|
| 158 |
+
# calculate query, key, values for all heads in batch and move head forward to be the batch dim
|
| 159 |
+
query, key, value = self.att_proj(hidden_states).split(self.embed_dim, dim=2)
|
| 160 |
+
|
| 161 |
+
query = self._split_heads(query, self.num_heads, self.head_dim)
|
| 162 |
+
key = self._split_heads(key, self.num_heads, self.head_dim)
|
| 163 |
+
value = self._split_heads(value, self.num_heads, self.head_dim)
|
| 164 |
+
|
| 165 |
+
if past_key_values is not None:
|
| 166 |
+
key, value = past_key_values.update(key, value, self.layer_idx)
|
| 167 |
+
|
| 168 |
+
attn_output, attn_weights = self._attn(query, key, value, attention_mask)
|
| 169 |
+
|
| 170 |
+
attn_output = self._merge_heads(attn_output, self.num_heads, self.head_dim)
|
| 171 |
+
attn_output = self.out_proj(attn_output)
|
| 172 |
+
attn_output = self.resid_dropout(attn_output)
|
| 173 |
+
|
| 174 |
+
return attn_output, attn_weights
|
| 175 |
+
|
| 176 |
+
|
| 177 |
+
class BarkSelfFlashAttention2(BarkSelfAttention):
|
| 178 |
+
"""
|
| 179 |
+
Bark flash attention module. This module inherits from `BarkSelfAttention` as the weights of the module stays
|
| 180 |
+
untouched. The only required change would be on the forward pass where it needs to correctly call the public API of
|
| 181 |
+
flash attention and deal with padding tokens in case the input contains any of them.
|
| 182 |
+
"""
|
| 183 |
+
|
| 184 |
+
def __init__(self, *args, **kwargs):
|
| 185 |
+
super().__init__(*args, **kwargs)
|
| 186 |
+
|
| 187 |
+
# TODO: Should be removed once Flash Attention for RoCm is bumped to 2.1.
|
| 188 |
+
# flash_attn<2.1 generates top-left aligned causal mask, while what is needed here is bottom-right alignment, that was made default for flash_attn>=2.1. This attribute is used to handle this difference. Reference: https://github.com/Dao-AILab/flash-attention/releases/tag/v2.1.0.
|
| 189 |
+
# Beware that with flash_attn<2.1, using q_seqlen != k_seqlen (except for the case q_seqlen == 1) produces a wrong mask (top-left).
|
| 190 |
+
self._flash_attn_uses_top_left_mask = flash_attn_supports_top_left_mask()
|
| 191 |
+
|
| 192 |
+
def _split_heads(self, tensor, num_heads, attn_head_size):
|
| 193 |
+
"""
|
| 194 |
+
Splits hidden_size dim into attn_head_size and num_heads
|
| 195 |
+
"""
|
| 196 |
+
new_shape = tensor.size()[:-1] + (num_heads, attn_head_size)
|
| 197 |
+
tensor = tensor.view(new_shape)
|
| 198 |
+
# Flash attention requires the input to have the shape
|
| 199 |
+
# batch_size x seq_length x head_dim x hidden_dim - (batch, seq_length, head, head_features)
|
| 200 |
+
return tensor
|
| 201 |
+
|
| 202 |
+
def _merge_heads(self, tensor, num_heads, attn_head_size):
|
| 203 |
+
"""
|
| 204 |
+
Merges attn_head_size dim and num_attn_heads dim into hidden_size
|
| 205 |
+
"""
|
| 206 |
+
# re-assemble all head outputs side by side
|
| 207 |
+
# (batch, seq_len, num_heads, attn_head_size) -> (batch, seq_len, num_heads*attn_head_size)
|
| 208 |
+
tensor = tensor.view(tensor.size()[:-2] + (num_heads * attn_head_size,))
|
| 209 |
+
return tensor
|
| 210 |
+
|
| 211 |
+
def forward(
|
| 212 |
+
self,
|
| 213 |
+
hidden_states,
|
| 214 |
+
attention_mask=None,
|
| 215 |
+
past_key_values=None,
|
| 216 |
+
use_cache=False,
|
| 217 |
+
output_attentions=False,
|
| 218 |
+
**kwargs,
|
| 219 |
+
):
|
| 220 |
+
batch_size, query_len, _ = hidden_states.size()
|
| 221 |
+
|
| 222 |
+
# calculate query, key, values for all heads in batch and move head forward to be the batch dim
|
| 223 |
+
query, key, value = self.att_proj(hidden_states).split(self.embed_dim, dim=2)
|
| 224 |
+
|
| 225 |
+
query = self._split_heads(query, self.num_heads, self.head_dim)
|
| 226 |
+
key = self._split_heads(key, self.num_heads, self.head_dim)
|
| 227 |
+
value = self._split_heads(value, self.num_heads, self.head_dim)
|
| 228 |
+
|
| 229 |
+
if past_key_values is not None:
|
| 230 |
+
key, value = past_key_values.update(key, value, self.layer_idx)
|
| 231 |
+
|
| 232 |
+
target_dtype = get_target_dtype(query, self) # if the query is in float32, this is the dtype to cast to for FA
|
| 233 |
+
|
| 234 |
+
attn_output = _flash_attention_forward(
|
| 235 |
+
query,
|
| 236 |
+
key,
|
| 237 |
+
value,
|
| 238 |
+
attention_mask,
|
| 239 |
+
query_len,
|
| 240 |
+
dropout=self.dropout if self.training else 0.0,
|
| 241 |
+
use_top_left_mask=self._flash_attn_uses_top_left_mask,
|
| 242 |
+
is_causal=self.is_causal,
|
| 243 |
+
target_dtype=target_dtype,
|
| 244 |
+
)
|
| 245 |
+
|
| 246 |
+
attn_output = self._merge_heads(attn_output, self.num_heads, self.head_dim)
|
| 247 |
+
attn_output = self.out_proj(attn_output)
|
| 248 |
+
attn_output = self.resid_dropout(attn_output)
|
| 249 |
+
|
| 250 |
+
return attn_output, None
|
| 251 |
+
|
| 252 |
+
|
| 253 |
+
BARK_ATTENTION_CLASSES = {
|
| 254 |
+
"eager": BarkSelfAttention,
|
| 255 |
+
"flash_attention_2": BarkSelfFlashAttention2,
|
| 256 |
+
}
|
| 257 |
+
|
| 258 |
+
|
| 259 |
+
class BarkMLP(nn.Module):
|
| 260 |
+
def __init__(self, config):
|
| 261 |
+
super().__init__()
|
| 262 |
+
self.in_proj = nn.Linear(config.hidden_size, 4 * config.hidden_size, bias=config.bias)
|
| 263 |
+
self.out_proj = nn.Linear(4 * config.hidden_size, config.hidden_size, bias=config.bias)
|
| 264 |
+
self.dropout = nn.Dropout(config.dropout)
|
| 265 |
+
self.gelu = nn.GELU()
|
| 266 |
+
|
| 267 |
+
def forward(self, hidden_states):
|
| 268 |
+
hidden_states = self.in_proj(hidden_states)
|
| 269 |
+
hidden_states = self.gelu(hidden_states)
|
| 270 |
+
hidden_states = self.out_proj(hidden_states)
|
| 271 |
+
hidden_states = self.dropout(hidden_states)
|
| 272 |
+
return hidden_states
|
| 273 |
+
|
| 274 |
+
|
| 275 |
+
class BarkBlock(GradientCheckpointingLayer):
|
| 276 |
+
def __init__(self, config, is_causal=False, layer_idx=None):
|
| 277 |
+
super().__init__()
|
| 278 |
+
|
| 279 |
+
if is_causal:
|
| 280 |
+
# if causal, the layerNorm bias is optional to stick with Bark choice of leaving optional bias
|
| 281 |
+
# in AutoRegressive models (corresponding to the "Text" and the "Coarse" modules)
|
| 282 |
+
self.layernorm_1 = nn.LayerNorm(config.hidden_size, bias=config.bias)
|
| 283 |
+
self.layernorm_2 = nn.LayerNorm(config.hidden_size, bias=config.bias)
|
| 284 |
+
else:
|
| 285 |
+
self.layernorm_1 = nn.LayerNorm(config.hidden_size)
|
| 286 |
+
self.layernorm_2 = nn.LayerNorm(config.hidden_size)
|
| 287 |
+
|
| 288 |
+
self.attn = BARK_ATTENTION_CLASSES[config._attn_implementation](
|
| 289 |
+
config, is_causal=is_causal, layer_idx=layer_idx
|
| 290 |
+
)
|
| 291 |
+
|
| 292 |
+
self.mlp = BarkMLP(config)
|
| 293 |
+
|
| 294 |
+
def forward(
|
| 295 |
+
self,
|
| 296 |
+
hidden_states,
|
| 297 |
+
past_key_values=None,
|
| 298 |
+
attention_mask=None,
|
| 299 |
+
use_cache=False,
|
| 300 |
+
output_attentions=False,
|
| 301 |
+
**kwargs,
|
| 302 |
+
):
|
| 303 |
+
intermediary_hidden_states = self.layernorm_1(hidden_states)
|
| 304 |
+
|
| 305 |
+
attn_outputs = self.attn(
|
| 306 |
+
intermediary_hidden_states,
|
| 307 |
+
past_key_values=past_key_values,
|
| 308 |
+
attention_mask=attention_mask,
|
| 309 |
+
use_cache=use_cache,
|
| 310 |
+
output_attentions=output_attentions,
|
| 311 |
+
)
|
| 312 |
+
|
| 313 |
+
attn_output = attn_outputs[0] # output_attn: output, present_key_values, (attn_weights)
|
| 314 |
+
outputs = attn_outputs[1:]
|
| 315 |
+
|
| 316 |
+
intermediary_hidden_states = hidden_states + attn_output
|
| 317 |
+
intermediary_hidden_states = intermediary_hidden_states + self.mlp(
|
| 318 |
+
self.layernorm_2(intermediary_hidden_states)
|
| 319 |
+
)
|
| 320 |
+
|
| 321 |
+
return (intermediary_hidden_states,) + outputs
|
| 322 |
+
|
| 323 |
+
|
| 324 |
+
@auto_docstring
|
| 325 |
+
class BarkPreTrainedModel(PreTrainedModel):
|
| 326 |
+
config: BarkConfig
|
| 327 |
+
supports_gradient_checkpointing = False
|
| 328 |
+
_supports_flash_attn = True
|
| 329 |
+
|
| 330 |
+
@property
|
| 331 |
+
def device(self) -> torch.device:
|
| 332 |
+
"""
|
| 333 |
+
`torch.device`: The device on which the module is (assuming that all the module parameters are on the same
|
| 334 |
+
device).
|
| 335 |
+
"""
|
| 336 |
+
|
| 337 |
+
# if has _hf_hook, has been offloaded so the device has to be found in the hook
|
| 338 |
+
if not hasattr(self, "_hf_hook"):
|
| 339 |
+
return super().device
|
| 340 |
+
for module in self.modules():
|
| 341 |
+
if (
|
| 342 |
+
hasattr(module, "_hf_hook")
|
| 343 |
+
and hasattr(module._hf_hook, "execution_device")
|
| 344 |
+
and module._hf_hook.execution_device is not None
|
| 345 |
+
):
|
| 346 |
+
return torch.device(module._hf_hook.execution_device)
|
| 347 |
+
|
| 348 |
+
return super().device
|
| 349 |
+
|
| 350 |
+
def _init_weights(self, module):
|
| 351 |
+
super()._init_weights(module)
|
| 352 |
+
if isinstance(module, BarkSelfAttention):
|
| 353 |
+
if module.is_causal:
|
| 354 |
+
block_size = module.config.block_size
|
| 355 |
+
bias = torch.tril(torch.ones((block_size, block_size), dtype=bool)).view(1, 1, block_size, block_size)
|
| 356 |
+
init.copy_(module.bias, bias)
|
| 357 |
+
|
| 358 |
+
|
| 359 |
+
# GPT2-like autoregressive model
|
| 360 |
+
class BarkCausalModel(BarkPreTrainedModel, GenerationMixin):
|
| 361 |
+
config: BarkSubModelConfig
|
| 362 |
+
output_modalities = ("audio",)
|
| 363 |
+
|
| 364 |
+
def __init__(self, config):
|
| 365 |
+
super().__init__(config)
|
| 366 |
+
self.config = config
|
| 367 |
+
|
| 368 |
+
# initialize as an autoregressive GPT-like model
|
| 369 |
+
self.input_embeds_layer = nn.Embedding(config.input_vocab_size, config.hidden_size)
|
| 370 |
+
self.position_embeds_layer = nn.Embedding(config.block_size, config.hidden_size)
|
| 371 |
+
|
| 372 |
+
self.drop = nn.Dropout(config.dropout)
|
| 373 |
+
|
| 374 |
+
self.layers = nn.ModuleList([BarkBlock(config, is_causal=True, layer_idx=i) for i in range(config.num_layers)])
|
| 375 |
+
|
| 376 |
+
self.layernorm_final = nn.LayerNorm(config.hidden_size, bias=config.bias)
|
| 377 |
+
|
| 378 |
+
self.lm_head = nn.Linear(config.hidden_size, config.output_vocab_size, bias=False)
|
| 379 |
+
self.gradient_checkpointing = False
|
| 380 |
+
|
| 381 |
+
# Initialize weights and apply final processing
|
| 382 |
+
self.post_init()
|
| 383 |
+
|
| 384 |
+
def get_output_embeddings(self):
|
| 385 |
+
# NOTE: get_output_embeddings() must return None to prevent accidental weight tying.
|
| 386 |
+
# See e.g. https://github.com/huggingface/transformers/pull/39339#discussion_r2219126400
|
| 387 |
+
return None
|
| 388 |
+
|
| 389 |
+
def get_input_embeddings(self):
|
| 390 |
+
return self.input_embeds_layer
|
| 391 |
+
|
| 392 |
+
def set_input_embeddings(self, new_embeddings):
|
| 393 |
+
self.input_embeds_layer = new_embeddings
|
| 394 |
+
|
| 395 |
+
@deprecate_kwarg("input_embeds", version="5.6.0", new_name="inputs_embeds")
|
| 396 |
+
@auto_docstring
|
| 397 |
+
def forward(
|
| 398 |
+
self,
|
| 399 |
+
input_ids: torch.Tensor | None = None,
|
| 400 |
+
past_key_values: Cache | None = None,
|
| 401 |
+
attention_mask: torch.Tensor | None = None,
|
| 402 |
+
position_ids: torch.Tensor | None = None,
|
| 403 |
+
labels: torch.LongTensor | None = None,
|
| 404 |
+
inputs_embeds: torch.Tensor | None = None,
|
| 405 |
+
use_cache: bool | None = None,
|
| 406 |
+
output_attentions: bool | None = None,
|
| 407 |
+
output_hidden_states: bool | None = None,
|
| 408 |
+
return_dict: bool | None = None,
|
| 409 |
+
**kwargs,
|
| 410 |
+
) -> tuple[torch.Tensor] | CausalLMOutputWithPast:
|
| 411 |
+
output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions
|
| 412 |
+
output_hidden_states = (
|
| 413 |
+
output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states
|
| 414 |
+
)
|
| 415 |
+
use_cache = use_cache if use_cache is not None else self.config.use_cache
|
| 416 |
+
return_dict = return_dict if return_dict is not None else self.config.return_dict
|
| 417 |
+
|
| 418 |
+
loss = None
|
| 419 |
+
if labels is not None:
|
| 420 |
+
raise NotImplementedError(
|
| 421 |
+
"Training is not implemented yet for Bark - ensure you do not pass `labels` to the model."
|
| 422 |
+
)
|
| 423 |
+
|
| 424 |
+
# Verify if inputs_embeds already exists
|
| 425 |
+
# then compute embeddings.
|
| 426 |
+
if input_ids is not None and inputs_embeds is not None:
|
| 427 |
+
raise ValueError("You cannot specify both input_ids and inputs_embeds at the same time")
|
| 428 |
+
elif inputs_embeds is not None and past_key_values is None:
|
| 429 |
+
# we want to return the inputs_embeds in priority so that it is in line with a weird hack
|
| 430 |
+
# of Bark which concatenate two bits of the inputs_embeds on the first forward pass of the semantic model
|
| 431 |
+
pass
|
| 432 |
+
elif input_ids is not None:
|
| 433 |
+
inputs_embeds = self.input_embeds_layer(input_ids) # token embeddings of shape (b, t, n_embd)
|
| 434 |
+
elif inputs_embeds is not None:
|
| 435 |
+
pass
|
| 436 |
+
else:
|
| 437 |
+
raise ValueError("You have to specify either input_ids or inputs_embeds")
|
| 438 |
+
|
| 439 |
+
input_shape = inputs_embeds.size()[:-1]
|
| 440 |
+
seq_length = input_shape[-1]
|
| 441 |
+
|
| 442 |
+
if self.gradient_checkpointing and self.training:
|
| 443 |
+
if use_cache:
|
| 444 |
+
logger.warning_once(
|
| 445 |
+
"`use_cache=True` is incompatible with gradient checkpointing. Setting `use_cache=False`..."
|
| 446 |
+
)
|
| 447 |
+
use_cache = False
|
| 448 |
+
|
| 449 |
+
if use_cache and past_key_values is None:
|
| 450 |
+
past_key_values = DynamicCache(config=self.config)
|
| 451 |
+
|
| 452 |
+
past_length = past_key_values.get_seq_length() if past_key_values is not None else 0
|
| 453 |
+
inputs_embeds = inputs_embeds.to(self.position_embeds_layer.weight.device)
|
| 454 |
+
|
| 455 |
+
if position_ids is None:
|
| 456 |
+
position_ids = torch.arange(
|
| 457 |
+
past_length,
|
| 458 |
+
seq_length + past_length,
|
| 459 |
+
dtype=torch.long,
|
| 460 |
+
device=self.position_embeds_layer.weight.device,
|
| 461 |
+
)
|
| 462 |
+
position_ids = position_ids.unsqueeze(0) # shape (1, seq_length)
|
| 463 |
+
|
| 464 |
+
position_ids = position_ids.to(self.position_embeds_layer.weight.device)
|
| 465 |
+
position_embeds = self.position_embeds_layer(position_ids) # position embeddings of shape (1, t, n_embd)
|
| 466 |
+
|
| 467 |
+
attention_mask = create_bidirectional_mask(
|
| 468 |
+
config=self.config,
|
| 469 |
+
inputs_embeds=inputs_embeds,
|
| 470 |
+
attention_mask=attention_mask,
|
| 471 |
+
)
|
| 472 |
+
|
| 473 |
+
hidden_states = self.drop(inputs_embeds + position_embeds)
|
| 474 |
+
output_shape = input_shape + (hidden_states.size(-1),)
|
| 475 |
+
|
| 476 |
+
all_self_attentions = () if output_attentions else None
|
| 477 |
+
all_hidden_states = () if output_hidden_states else None
|
| 478 |
+
|
| 479 |
+
for i, block in enumerate(self.layers):
|
| 480 |
+
if output_hidden_states:
|
| 481 |
+
all_hidden_states = all_hidden_states + (hidden_states,)
|
| 482 |
+
|
| 483 |
+
outputs = block(
|
| 484 |
+
hidden_states,
|
| 485 |
+
past_key_values=past_key_values,
|
| 486 |
+
attention_mask=attention_mask,
|
| 487 |
+
use_cache=use_cache,
|
| 488 |
+
output_attentions=output_attentions,
|
| 489 |
+
)
|
| 490 |
+
|
| 491 |
+
hidden_states = outputs[0]
|
| 492 |
+
|
| 493 |
+
if output_attentions:
|
| 494 |
+
all_self_attentions = all_self_attentions + (outputs[1],)
|
| 495 |
+
|
| 496 |
+
hidden_states = self.layernorm_final(hidden_states)
|
| 497 |
+
|
| 498 |
+
hidden_states = hidden_states.view(output_shape)
|
| 499 |
+
|
| 500 |
+
# Add last hidden state
|
| 501 |
+
if output_hidden_states:
|
| 502 |
+
all_hidden_states = all_hidden_states + (hidden_states,)
|
| 503 |
+
|
| 504 |
+
logits = self.lm_head(hidden_states)
|
| 505 |
+
|
| 506 |
+
if not return_dict:
|
| 507 |
+
return tuple(
|
| 508 |
+
v for v in [None, logits, past_key_values, all_hidden_states, all_self_attentions] if v is not None
|
| 509 |
+
)
|
| 510 |
+
|
| 511 |
+
return CausalLMOutputWithPast(
|
| 512 |
+
loss=loss,
|
| 513 |
+
logits=logits,
|
| 514 |
+
past_key_values=past_key_values,
|
| 515 |
+
hidden_states=all_hidden_states,
|
| 516 |
+
attentions=all_self_attentions,
|
| 517 |
+
)
|
| 518 |
+
|
| 519 |
+
|
| 520 |
+
@auto_docstring(
|
| 521 |
+
custom_intro="""
|
| 522 |
+
Bark semantic (or text) model. It shares the same architecture as the coarse model.
|
| 523 |
+
It is a GPT-2 like autoregressive model with a language modeling head on top.
|
| 524 |
+
"""
|
| 525 |
+
)
|
| 526 |
+
class BarkSemanticModel(BarkCausalModel):
|
| 527 |
+
base_model_prefix = "semantic"
|
| 528 |
+
config: BarkSemanticConfig
|
| 529 |
+
|
| 530 |
+
def generate(
|
| 531 |
+
self,
|
| 532 |
+
input_ids: torch.Tensor,
|
| 533 |
+
semantic_generation_config: BarkSemanticGenerationConfig | None = None,
|
| 534 |
+
history_prompt: dict[str, torch.Tensor] | None = None,
|
| 535 |
+
attention_mask: torch.Tensor | None = None,
|
| 536 |
+
**kwargs,
|
| 537 |
+
) -> torch.LongTensor:
|
| 538 |
+
"""
|
| 539 |
+
Generates text semantic tokens from an input prompt and an additional optional `Bark` speaker prompt.
|
| 540 |
+
|
| 541 |
+
Args:
|
| 542 |
+
input_ids (`Optional[torch.Tensor]` of shape (batch_size, seq_len), *optional*):
|
| 543 |
+
Input ids, i.e tokenized input sentences. Will be truncated up to
|
| 544 |
+
semantic_generation_config.max_input_semantic_length tokens. Note that the output audios will be as
|
| 545 |
+
long as the longest generation among the batch.
|
| 546 |
+
semantic_generation_config (`BarkSemanticGenerationConfig`):
|
| 547 |
+
Generation config indicating how to generate the semantic tokens.
|
| 548 |
+
history_prompt (`Optional[dict[str,torch.Tensor]]`, *optional*):
|
| 549 |
+
Optional `Bark` speaker prompt.
|
| 550 |
+
attention_mask (`Optional[torch.Tensor]`, *optional*):
|
| 551 |
+
Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`:
|
| 552 |
+
|
| 553 |
+
- 1 for tokens that are **not masked**,
|
| 554 |
+
- 0 for tokens that are **masked**.
|
| 555 |
+
|
| 556 |
+
[What are attention masks?](../glossary#attention-mask)
|
| 557 |
+
Returns:
|
| 558 |
+
torch.LongTensor: Output semantic tokens.
|
| 559 |
+
"""
|
| 560 |
+
if semantic_generation_config is None:
|
| 561 |
+
raise ValueError("`semantic_generation_config` has to be provided")
|
| 562 |
+
|
| 563 |
+
batch_size = input_ids.shape[0]
|
| 564 |
+
|
| 565 |
+
max_input_semantic_length = semantic_generation_config.max_input_semantic_length
|
| 566 |
+
|
| 567 |
+
input_ids = input_ids + semantic_generation_config.text_encoding_offset
|
| 568 |
+
|
| 569 |
+
if attention_mask is not None:
|
| 570 |
+
input_ids = input_ids.masked_fill((1 - attention_mask).bool(), semantic_generation_config.text_pad_token)
|
| 571 |
+
|
| 572 |
+
if history_prompt is not None:
|
| 573 |
+
semantic_history = history_prompt["semantic_prompt"][-max_input_semantic_length:]
|
| 574 |
+
semantic_history = nn.functional.pad(
|
| 575 |
+
semantic_history,
|
| 576 |
+
(0, max_input_semantic_length - len(semantic_history)),
|
| 577 |
+
value=semantic_generation_config.semantic_pad_token,
|
| 578 |
+
mode="constant",
|
| 579 |
+
)
|
| 580 |
+
else:
|
| 581 |
+
semantic_history = torch.full(
|
| 582 |
+
(max_input_semantic_length,),
|
| 583 |
+
semantic_generation_config.semantic_pad_token,
|
| 584 |
+
device=self.device,
|
| 585 |
+
dtype=torch.int,
|
| 586 |
+
)
|
| 587 |
+
|
| 588 |
+
semantic_history = torch.repeat_interleave(semantic_history[None], batch_size, dim=0)
|
| 589 |
+
|
| 590 |
+
infer_array = torch.tensor(
|
| 591 |
+
[[semantic_generation_config.semantic_infer_token]] * batch_size, dtype=torch.int
|
| 592 |
+
).to(self.device)
|
| 593 |
+
|
| 594 |
+
inputs_embeds = torch.cat(
|
| 595 |
+
[
|
| 596 |
+
self.input_embeds_layer(input_ids[:, :max_input_semantic_length])
|
| 597 |
+
+ self.input_embeds_layer(semantic_history[:, : max_input_semantic_length + 1]),
|
| 598 |
+
self.input_embeds_layer(infer_array),
|
| 599 |
+
],
|
| 600 |
+
dim=1,
|
| 601 |
+
)
|
| 602 |
+
|
| 603 |
+
tokens_to_suppress = list(
|
| 604 |
+
range(semantic_generation_config.semantic_vocab_size, semantic_generation_config.semantic_pad_token)
|
| 605 |
+
)
|
| 606 |
+
tokens_to_suppress.extend(
|
| 607 |
+
list(range(semantic_generation_config.semantic_pad_token + 1, self.config.output_vocab_size))
|
| 608 |
+
)
|
| 609 |
+
|
| 610 |
+
suppress_tokens_logits_processor = SuppressTokensLogitsProcessor(tokens_to_suppress, device=input_ids.device)
|
| 611 |
+
|
| 612 |
+
min_eos_p = kwargs.get("min_eos_p", semantic_generation_config.min_eos_p)
|
| 613 |
+
early_stopping_logits_processor = BarkEosPrioritizerLogitsProcessor(
|
| 614 |
+
eos_token_id=semantic_generation_config.eos_token_id, min_eos_p=min_eos_p, device=input_ids.device
|
| 615 |
+
)
|
| 616 |
+
|
| 617 |
+
# pass input_ids in order to stay consistent with the transformers generate method even though it is not used
|
| 618 |
+
# (except to get the input seq_len - that's why we keep the first 257 tokens)
|
| 619 |
+
semantic_output = super().generate(
|
| 620 |
+
torch.ones((batch_size, max_input_semantic_length + 1), dtype=torch.int, device=self.device),
|
| 621 |
+
inputs_embeds=inputs_embeds,
|
| 622 |
+
logits_processor=[suppress_tokens_logits_processor, early_stopping_logits_processor],
|
| 623 |
+
generation_config=semantic_generation_config,
|
| 624 |
+
**kwargs,
|
| 625 |
+
) # size: 10048
|
| 626 |
+
|
| 627 |
+
# take the generated semantic tokens
|
| 628 |
+
if kwargs.get("return_dict_in_generate", False):
|
| 629 |
+
semantic_output = semantic_output.sequences[:, max_input_semantic_length + 1 :]
|
| 630 |
+
else:
|
| 631 |
+
semantic_output = semantic_output[:, max_input_semantic_length + 1 :]
|
| 632 |
+
return semantic_output
|
| 633 |
+
|
| 634 |
+
|
| 635 |
+
@auto_docstring(
|
| 636 |
+
custom_intro="""
|
| 637 |
+
Bark coarse acoustics model.
|
| 638 |
+
It shares the same architecture as the semantic (or text) model. It is a GPT-2 like autoregressive model with a
|
| 639 |
+
language modeling head on top.
|
| 640 |
+
"""
|
| 641 |
+
)
|
| 642 |
+
class BarkCoarseModel(BarkCausalModel):
|
| 643 |
+
base_model_prefix = "coarse_acoustics"
|
| 644 |
+
config: BarkCoarseConfig
|
| 645 |
+
|
| 646 |
+
def preprocess_histories(
|
| 647 |
+
self,
|
| 648 |
+
max_coarse_history: int,
|
| 649 |
+
semantic_to_coarse_ratio: int,
|
| 650 |
+
batch_size: int,
|
| 651 |
+
semantic_generation_config: int,
|
| 652 |
+
codebook_size: int,
|
| 653 |
+
history_prompt: dict[str, torch.Tensor] | None = None,
|
| 654 |
+
):
|
| 655 |
+
"""
|
| 656 |
+
Preprocess the optional `Bark` speaker prompts before `self.generate`.
|
| 657 |
+
|
| 658 |
+
Args:
|
| 659 |
+
max_coarse_history (`int`):
|
| 660 |
+
Maximum size of coarse tokens used.
|
| 661 |
+
semantic_to_coarse_ratio (`int`):
|
| 662 |
+
Ratio of semantic to coarse frequency
|
| 663 |
+
batch_size (`int`):
|
| 664 |
+
Batch size, i.e the number of samples.
|
| 665 |
+
semantic_generation_config (`BarkSemanticGenerationConfig`):
|
| 666 |
+
Generation config indicating how to generate the semantic tokens.
|
| 667 |
+
codebook_size (`int`):
|
| 668 |
+
Codebook channel size, i.e. the size of the output vocabulary per codebook channel.
|
| 669 |
+
history_prompt (`Optional[dict[str,torch.Tensor]]`):
|
| 670 |
+
Optional `Bark` speaker prompt.
|
| 671 |
+
Returns: Returns:
|
| 672 |
+
`tuple(torch.FloatTensor)`:
|
| 673 |
+
- **x_semantic_history** (`torch.FloatTensor` -- Processed semantic speaker prompt.
|
| 674 |
+
- **x_coarse_history** (`torch.FloatTensor`) -- Processed coarse speaker prompt.
|
| 675 |
+
"""
|
| 676 |
+
if history_prompt is not None:
|
| 677 |
+
x_semantic_history = torch.repeat_interleave(history_prompt["semantic_prompt"][None], batch_size, dim=0)
|
| 678 |
+
# clone to avoid modifying history_prompt.coarse_prompt
|
| 679 |
+
x_coarse_history = history_prompt["coarse_prompt"].clone()
|
| 680 |
+
|
| 681 |
+
# offset x_coarse_history
|
| 682 |
+
if codebook_size is not None:
|
| 683 |
+
for n in range(1, x_coarse_history.shape[0]):
|
| 684 |
+
# offset
|
| 685 |
+
x_coarse_history[n, :] += codebook_size * n
|
| 686 |
+
|
| 687 |
+
# flatten x_coarse_history
|
| 688 |
+
x_coarse_history = torch.transpose(x_coarse_history, 0, 1).reshape(-1)
|
| 689 |
+
|
| 690 |
+
x_coarse_history = x_coarse_history + semantic_generation_config.semantic_vocab_size
|
| 691 |
+
|
| 692 |
+
x_coarse_history = torch.repeat_interleave(x_coarse_history[None], batch_size, dim=0)
|
| 693 |
+
# e.g: after SEMANTIC_VOCAB_SIZE (10000), 1024 tokens dedicated to first codebook, 1024 next tokens
|
| 694 |
+
# dedicated to second codebook.
|
| 695 |
+
|
| 696 |
+
max_semantic_history = int(np.floor(max_coarse_history / semantic_to_coarse_ratio))
|
| 697 |
+
# trim histories correctly
|
| 698 |
+
n_semantic_hist_provided = min(
|
| 699 |
+
[
|
| 700 |
+
max_semantic_history,
|
| 701 |
+
x_semantic_history.shape[1] - x_semantic_history.shape[1] % 2,
|
| 702 |
+
int(np.floor(x_coarse_history.shape[1] / semantic_to_coarse_ratio)),
|
| 703 |
+
]
|
| 704 |
+
)
|
| 705 |
+
|
| 706 |
+
n_coarse_hist_provided = int(round(n_semantic_hist_provided * semantic_to_coarse_ratio))
|
| 707 |
+
|
| 708 |
+
x_semantic_history = x_semantic_history[:, -n_semantic_hist_provided:].int()
|
| 709 |
+
x_coarse_history = x_coarse_history[:, -n_coarse_hist_provided:].int()
|
| 710 |
+
# bit of a hack for time alignment (sounds better) - from Bark original implementation
|
| 711 |
+
x_coarse_history = x_coarse_history[:, :-2]
|
| 712 |
+
|
| 713 |
+
else:
|
| 714 |
+
# shape: (batch_size, 0)
|
| 715 |
+
x_semantic_history = torch.tensor([[]] * batch_size, dtype=torch.int, device=self.device)
|
| 716 |
+
x_coarse_history = torch.tensor([[]] * batch_size, dtype=torch.int, device=self.device)
|
| 717 |
+
|
| 718 |
+
return x_semantic_history, x_coarse_history
|
| 719 |
+
|
| 720 |
+
def generate(
|
| 721 |
+
self,
|
| 722 |
+
semantic_output: torch.Tensor,
|
| 723 |
+
semantic_generation_config: BarkSemanticGenerationConfig | None = None,
|
| 724 |
+
coarse_generation_config: BarkCoarseGenerationConfig | None = None,
|
| 725 |
+
codebook_size: int = 1024,
|
| 726 |
+
history_prompt: dict[str, torch.Tensor] | None = None,
|
| 727 |
+
return_output_lengths: bool | None = None,
|
| 728 |
+
**kwargs,
|
| 729 |
+
) -> torch.LongTensor | tuple[torch.LongTensor, torch.LongTensor]:
|
| 730 |
+
"""
|
| 731 |
+
Generates coarse acoustics tokens from input text semantic tokens and an additional optional `Bark` speaker
|
| 732 |
+
prompt.
|
| 733 |
+
|
| 734 |
+
Args:
|
| 735 |
+
semantic_output (`torch.Tensor` of shape (batch_size, seq_len), *optional*):
|
| 736 |
+
Input text semantic ids, i.e the output of `BarkSemanticModel.generate`.
|
| 737 |
+
semantic_generation_config (`BarkSemanticGenerationConfig`):
|
| 738 |
+
Generation config indicating how to generate the semantic tokens.
|
| 739 |
+
coarse_generation_config (`BarkCoarseGenerationConfig`):
|
| 740 |
+
Generation config indicating how to generate the coarse tokens.
|
| 741 |
+
codebook_size (`int`, *optional*, defaults to 1024):
|
| 742 |
+
Codebook channel size, i.e. the size of the output vocabulary per codebook channel.
|
| 743 |
+
history_prompt (`Optional[dict[str,torch.Tensor]]`, *optional*):
|
| 744 |
+
Optional `Bark` speaker prompt.
|
| 745 |
+
return_output_lengths (`bool`, *optional*):
|
| 746 |
+
Whether or not to return the output lengths. Useful when batching.
|
| 747 |
+
Returns:
|
| 748 |
+
By default:
|
| 749 |
+
torch.LongTensor: Output coarse acoustics tokens.
|
| 750 |
+
If `return_output_lengths=True`:
|
| 751 |
+
`Tuple(torch.Tensor, torch.Tensor): The output coarse acoustics tokens, and the length of each sample
|
| 752 |
+
of the batch.
|
| 753 |
+
"""
|
| 754 |
+
|
| 755 |
+
if semantic_generation_config is None:
|
| 756 |
+
raise ValueError("`semantic_generation_config` has to be provided")
|
| 757 |
+
|
| 758 |
+
if coarse_generation_config is None:
|
| 759 |
+
raise ValueError("`coarse_generation_config` has to be provided")
|
| 760 |
+
|
| 761 |
+
max_coarse_input_length = coarse_generation_config.max_coarse_input_length
|
| 762 |
+
max_coarse_history = coarse_generation_config.max_coarse_history
|
| 763 |
+
sliding_window_len = coarse_generation_config.sliding_window_len
|
| 764 |
+
|
| 765 |
+
# replace semantic_pad_token (eos_tok and pad_tok here) with coarse_semantic_pad_token i.e the pad_token
|
| 766 |
+
# used in the next model
|
| 767 |
+
semantic_output.masked_fill_(
|
| 768 |
+
semantic_output == semantic_generation_config.semantic_pad_token,
|
| 769 |
+
coarse_generation_config.coarse_semantic_pad_token,
|
| 770 |
+
)
|
| 771 |
+
|
| 772 |
+
semantic_to_coarse_ratio = (
|
| 773 |
+
coarse_generation_config.coarse_rate_hz
|
| 774 |
+
/ semantic_generation_config.semantic_rate_hz
|
| 775 |
+
* coarse_generation_config.n_coarse_codebooks
|
| 776 |
+
)
|
| 777 |
+
max_semantic_history = int(np.floor(max_coarse_history / semantic_to_coarse_ratio))
|
| 778 |
+
|
| 779 |
+
output_lengths = (semantic_output != coarse_generation_config.coarse_semantic_pad_token).sum(1)
|
| 780 |
+
output_lengths = torch.floor(
|
| 781 |
+
output_lengths * semantic_to_coarse_ratio / coarse_generation_config.n_coarse_codebooks
|
| 782 |
+
)
|
| 783 |
+
output_lengths = torch.round(output_lengths * coarse_generation_config.n_coarse_codebooks).int()
|
| 784 |
+
|
| 785 |
+
max_generated_len = torch.max(output_lengths).item()
|
| 786 |
+
|
| 787 |
+
batch_size = semantic_output.shape[0]
|
| 788 |
+
|
| 789 |
+
x_semantic_history, x_coarse = self.preprocess_histories(
|
| 790 |
+
history_prompt=history_prompt,
|
| 791 |
+
max_coarse_history=max_coarse_history,
|
| 792 |
+
semantic_to_coarse_ratio=semantic_to_coarse_ratio,
|
| 793 |
+
batch_size=batch_size,
|
| 794 |
+
semantic_generation_config=semantic_generation_config,
|
| 795 |
+
codebook_size=codebook_size,
|
| 796 |
+
)
|
| 797 |
+
base_semantic_idx = x_semantic_history.shape[1]
|
| 798 |
+
|
| 799 |
+
semantic_output = torch.hstack([x_semantic_history, semantic_output])
|
| 800 |
+
|
| 801 |
+
n_window_steps = int(np.ceil(max_generated_len / sliding_window_len))
|
| 802 |
+
|
| 803 |
+
total_generated_len = 0
|
| 804 |
+
|
| 805 |
+
len_coarse_history = x_coarse.shape[1]
|
| 806 |
+
|
| 807 |
+
for _ in range(n_window_steps):
|
| 808 |
+
semantic_idx = base_semantic_idx + int(round(total_generated_len / semantic_to_coarse_ratio))
|
| 809 |
+
|
| 810 |
+
# pad from right side
|
| 811 |
+
input_coarse = semantic_output[:, np.max([0, semantic_idx - max_semantic_history]) :]
|
| 812 |
+
input_coarse = input_coarse[:, :max_coarse_input_length]
|
| 813 |
+
input_coarse = F.pad(
|
| 814 |
+
input_coarse,
|
| 815 |
+
(0, max_coarse_input_length - input_coarse.shape[-1]),
|
| 816 |
+
"constant",
|
| 817 |
+
coarse_generation_config.coarse_semantic_pad_token,
|
| 818 |
+
)
|
| 819 |
+
|
| 820 |
+
input_coarse = torch.hstack(
|
| 821 |
+
[
|
| 822 |
+
input_coarse,
|
| 823 |
+
torch.tensor([[coarse_generation_config.coarse_infer_token]] * batch_size, device=self.device),
|
| 824 |
+
x_coarse[:, -max_coarse_history:],
|
| 825 |
+
]
|
| 826 |
+
)
|
| 827 |
+
|
| 828 |
+
alternatingLogitsProcessor = AlternatingCodebooksLogitsProcessor(
|
| 829 |
+
input_coarse.shape[1],
|
| 830 |
+
semantic_generation_config.semantic_vocab_size,
|
| 831 |
+
codebook_size,
|
| 832 |
+
)
|
| 833 |
+
|
| 834 |
+
output_coarse = super().generate(
|
| 835 |
+
input_coarse,
|
| 836 |
+
logits_processor=[alternatingLogitsProcessor],
|
| 837 |
+
max_new_tokens=min(sliding_window_len, max_generated_len - total_generated_len),
|
| 838 |
+
generation_config=coarse_generation_config,
|
| 839 |
+
**kwargs,
|
| 840 |
+
)
|
| 841 |
+
|
| 842 |
+
input_coarse_len = input_coarse.shape[1]
|
| 843 |
+
|
| 844 |
+
if kwargs.get("return_dict_in_generate", False):
|
| 845 |
+
x_coarse = torch.hstack([x_coarse, output_coarse.sequences[:, input_coarse_len:]])
|
| 846 |
+
else:
|
| 847 |
+
x_coarse = torch.hstack([x_coarse, output_coarse[:, input_coarse_len:]])
|
| 848 |
+
total_generated_len = x_coarse.shape[1] - len_coarse_history
|
| 849 |
+
|
| 850 |
+
del output_coarse
|
| 851 |
+
|
| 852 |
+
coarse_output = x_coarse[:, len_coarse_history:]
|
| 853 |
+
|
| 854 |
+
if return_output_lengths:
|
| 855 |
+
return coarse_output, output_lengths
|
| 856 |
+
|
| 857 |
+
return coarse_output
|
| 858 |
+
|
| 859 |
+
|
| 860 |
+
@auto_docstring(
|
| 861 |
+
custom_intro="""
|
| 862 |
+
Bark fine acoustics model. It is a non-causal GPT-like model with `config.n_codes_total` embedding layers and
|
| 863 |
+
language modeling heads, one for each codebook.
|
| 864 |
+
"""
|
| 865 |
+
)
|
| 866 |
+
class BarkFineModel(BarkPreTrainedModel):
|
| 867 |
+
base_model_prefix = "fine_acoustics"
|
| 868 |
+
config: BarkFineConfig
|
| 869 |
+
main_input_name = "codebook_idx"
|
| 870 |
+
|
| 871 |
+
def __init__(self, config):
|
| 872 |
+
# non-causal gpt-like model with one embedding layer and one lm_head for each codebook of Encodec
|
| 873 |
+
super().__init__(config)
|
| 874 |
+
self.config = config
|
| 875 |
+
self._tied_weights_keys = {}
|
| 876 |
+
for i in range(self.config.n_codes_total - self.config.n_codes_given):
|
| 877 |
+
self._tied_weights_keys[f"lm_heads.{i}.weight"] = f"input_embeds_layers.{i + 1}.weight"
|
| 878 |
+
|
| 879 |
+
# initialize a modified non causal GPT-like model
|
| 880 |
+
# note that for there is one embedding layer and one lm_head for each codebook of Encodec
|
| 881 |
+
self.input_embeds_layers = nn.ModuleList(
|
| 882 |
+
[nn.Embedding(config.input_vocab_size, config.hidden_size) for _ in range(config.n_codes_total)]
|
| 883 |
+
)
|
| 884 |
+
self.position_embeds_layer = nn.Embedding(config.block_size, config.hidden_size)
|
| 885 |
+
|
| 886 |
+
self.drop = nn.Dropout(config.dropout)
|
| 887 |
+
|
| 888 |
+
self.layers = nn.ModuleList(
|
| 889 |
+
[BarkBlock(config, is_causal=False, layer_idx=i) for i in range(config.num_layers)]
|
| 890 |
+
)
|
| 891 |
+
|
| 892 |
+
self.layernorm_final = nn.LayerNorm(config.hidden_size)
|
| 893 |
+
|
| 894 |
+
self.lm_heads = nn.ModuleList(
|
| 895 |
+
[
|
| 896 |
+
nn.Linear(config.hidden_size, config.output_vocab_size, bias=False)
|
| 897 |
+
for _ in range(config.n_codes_given, config.n_codes_total)
|
| 898 |
+
]
|
| 899 |
+
)
|
| 900 |
+
self.gradient_checkpointing = False
|
| 901 |
+
self.n_codes_total = config.n_codes_total
|
| 902 |
+
|
| 903 |
+
# Initialize weights and apply final processing
|
| 904 |
+
self.post_init()
|
| 905 |
+
|
| 906 |
+
def get_input_embeddings(self):
|
| 907 |
+
# one embedding layers for each codebook
|
| 908 |
+
return self.input_embeds_layers
|
| 909 |
+
|
| 910 |
+
def set_input_embeddings(self, new_embeddings):
|
| 911 |
+
# one embedding layers for each codebook
|
| 912 |
+
self.input_embeds_layers = new_embeddings
|
| 913 |
+
|
| 914 |
+
def get_output_embeddings(self):
|
| 915 |
+
# one lm_head for each codebook
|
| 916 |
+
return self.lm_heads
|
| 917 |
+
|
| 918 |
+
def set_output_embeddings(self, new_output_embeddings):
|
| 919 |
+
# one lm_head for each codebook
|
| 920 |
+
self.lm_heads = new_output_embeddings
|
| 921 |
+
|
| 922 |
+
def _resize_token_embeddings(self, new_num_tokens, pad_to_multiple_of=None, mean_resizing=True):
|
| 923 |
+
old_embeddings_list = self.get_input_embeddings()
|
| 924 |
+
new_embeddings_list = nn.ModuleList(
|
| 925 |
+
[
|
| 926 |
+
self._get_resized_embeddings(old_embeddings, new_num_tokens, pad_to_multiple_of, mean_resizing)
|
| 927 |
+
for old_embeddings in old_embeddings_list
|
| 928 |
+
]
|
| 929 |
+
)
|
| 930 |
+
self.set_input_embeddings(new_embeddings_list)
|
| 931 |
+
new_num_tokens = new_embeddings_list[0].weight.shape[0]
|
| 932 |
+
|
| 933 |
+
# if word embeddings are not tied, make sure that lm head is resized as well
|
| 934 |
+
if self.get_output_embeddings() is not None and not self.config.tie_word_embeddings:
|
| 935 |
+
old_lm_head_list = self.get_output_embeddings()
|
| 936 |
+
new_lm_head_list = nn.ModuleList(
|
| 937 |
+
[self._get_resized_lm_head(old_lm_head, new_num_tokens) for old_lm_head in old_lm_head_list]
|
| 938 |
+
)
|
| 939 |
+
self.set_output_embeddings(new_lm_head_list)
|
| 940 |
+
|
| 941 |
+
return self.get_input_embeddings()
|
| 942 |
+
|
| 943 |
+
def resize_token_embeddings(
|
| 944 |
+
self,
|
| 945 |
+
new_num_tokens: int | None = None,
|
| 946 |
+
pad_to_multiple_of: int | None = None,
|
| 947 |
+
mean_resizing: bool = True,
|
| 948 |
+
) -> nn.Embedding:
|
| 949 |
+
"""
|
| 950 |
+
Resizes input token embeddings matrix of the model if `new_num_tokens != config.vocab_size`.
|
| 951 |
+
|
| 952 |
+
Takes care of tying weights embeddings afterwards if the model class has a `tie_weights()` method.
|
| 953 |
+
|
| 954 |
+
Arguments:
|
| 955 |
+
new_num_tokens (`int`, *optional*):
|
| 956 |
+
The number of new tokens in the embedding matrix. Increasing the size will add newly initialized
|
| 957 |
+
vectors at the end. Reducing the size will remove vectors from the end. If not provided or `None`, just
|
| 958 |
+
returns a pointer to the input tokens `torch.nn.Embedding` module of the model without doing anything.
|
| 959 |
+
pad_to_multiple_of (`int`, *optional*):
|
| 960 |
+
If set will pad the embedding matrix to a multiple of the provided value.
|
| 961 |
+
|
| 962 |
+
This is especially useful to enable the use of Tensor Cores on NVIDIA hardware with compute capability
|
| 963 |
+
`>= 7.5` (Volta), or on TPUs which benefit from having sequence lengths be a multiple of 128. For more
|
| 964 |
+
details about this, or help on choosing the correct value for resizing, refer to this guide:
|
| 965 |
+
https://docs.nvidia.com/deeplearning/performance/dl-performance-matrix-multiplication/index.html#requirements-tc
|
| 966 |
+
mean_resizing (`bool`):
|
| 967 |
+
Whether to initialize the added embeddings from a multivariate normal distribution that has old embeddings' mean and
|
| 968 |
+
covariance or to initialize them with a normal distribution that has a mean of zero and std equals `config.initializer_range`.
|
| 969 |
+
|
| 970 |
+
Setting `mean_resizing` to `True` is useful when increasing the size of the embeddings of causal language models,
|
| 971 |
+
where the generated tokens' probabilities won't be affected by the added embeddings because initializing the new embeddings with the
|
| 972 |
+
old embeddings' mean will reduce the kl-divergence between the next token probability before and after adding the new embeddings.
|
| 973 |
+
Refer to this article for more information: https://nlp.stanford.edu/~johnhew/vocab-expansion.html
|
| 974 |
+
|
| 975 |
+
Return:
|
| 976 |
+
`torch.nn.Embedding`: Pointer to the input tokens Embeddings Module of the model.
|
| 977 |
+
"""
|
| 978 |
+
model_embeds = self._resize_token_embeddings(new_num_tokens, pad_to_multiple_of, mean_resizing)
|
| 979 |
+
if new_num_tokens is None and pad_to_multiple_of is None:
|
| 980 |
+
return model_embeds
|
| 981 |
+
|
| 982 |
+
# Update base model and current model config
|
| 983 |
+
self.config.output_vocab_size = model_embeds[0].weight.shape[0]
|
| 984 |
+
self.config.vocab_size = model_embeds[0].weight.shape[0]
|
| 985 |
+
self.output_vocab_size = model_embeds[0].weight.shape[0]
|
| 986 |
+
self.vocab_size = model_embeds[0].weight.shape[0]
|
| 987 |
+
|
| 988 |
+
# Tie weights again if needed
|
| 989 |
+
self.tie_weights()
|
| 990 |
+
|
| 991 |
+
return model_embeds
|
| 992 |
+
|
| 993 |
+
@deprecate_kwarg("input_embeds", version="5.6.0", new_name="inputs_embeds")
|
| 994 |
+
@auto_docstring
|
| 995 |
+
def forward(
|
| 996 |
+
self,
|
| 997 |
+
codebook_idx: int, # an additional idx corresponding to the id of the codebook that will be predicted
|
| 998 |
+
input_ids: torch.Tensor | None = None,
|
| 999 |
+
attention_mask: torch.Tensor | None = None,
|
| 1000 |
+
position_ids: torch.Tensor | None = None,
|
| 1001 |
+
labels: torch.LongTensor | None = None,
|
| 1002 |
+
inputs_embeds: torch.Tensor | None = None,
|
| 1003 |
+
output_attentions: bool | None = None,
|
| 1004 |
+
output_hidden_states: bool | None = None,
|
| 1005 |
+
return_dict: bool | None = None,
|
| 1006 |
+
**kwargs,
|
| 1007 |
+
) -> tuple[torch.Tensor] | MaskedLMOutput:
|
| 1008 |
+
r"""
|
| 1009 |
+
codebook_idx (`int`):
|
| 1010 |
+
Index of the codebook that will be predicted.
|
| 1011 |
+
labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*):
|
| 1012 |
+
NOT IMPLEMENTED YET.
|
| 1013 |
+
"""
|
| 1014 |
+
output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions
|
| 1015 |
+
output_hidden_states = (
|
| 1016 |
+
output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states
|
| 1017 |
+
)
|
| 1018 |
+
return_dict = return_dict if return_dict is not None else self.config.return_dict
|
| 1019 |
+
|
| 1020 |
+
loss = None
|
| 1021 |
+
if labels is not None:
|
| 1022 |
+
raise NotImplementedError("Training is not implemented yet")
|
| 1023 |
+
|
| 1024 |
+
if codebook_idx == 0:
|
| 1025 |
+
raise ValueError("Cannot predict 0th codebook - 0th codebook should be predicted by the coarse model")
|
| 1026 |
+
|
| 1027 |
+
if input_ids is not None and inputs_embeds is not None:
|
| 1028 |
+
raise ValueError("You cannot specify both input_ids and inputs_embeds at the same time")
|
| 1029 |
+
|
| 1030 |
+
if input_ids is None and inputs_embeds is None:
|
| 1031 |
+
raise ValueError("You have to specify either input_ids or inputs_embeds")
|
| 1032 |
+
|
| 1033 |
+
if input_ids is not None:
|
| 1034 |
+
# the input_embeddings are the sum of the j previous codebooks embeddings before
|
| 1035 |
+
# the current codebook_idx codebook
|
| 1036 |
+
|
| 1037 |
+
# forward the GPT model itself
|
| 1038 |
+
inputs_embeds = [
|
| 1039 |
+
input_embeds_layer(input_ids[:, :, i]).unsqueeze(-1)
|
| 1040 |
+
for i, input_embeds_layer in enumerate(self.input_embeds_layers)
|
| 1041 |
+
] # token embeddings of shape (b, t, n_embd)
|
| 1042 |
+
inputs_embeds = torch.cat(inputs_embeds, dim=-1)
|
| 1043 |
+
inputs_embeds = inputs_embeds[:, :, :, : codebook_idx + 1].sum(dim=-1)
|
| 1044 |
+
|
| 1045 |
+
input_shape = inputs_embeds.size()[:-1]
|
| 1046 |
+
seq_length = input_shape[1]
|
| 1047 |
+
|
| 1048 |
+
inputs_embeds = inputs_embeds.to(self.position_embeds_layer.weight.device)
|
| 1049 |
+
|
| 1050 |
+
if position_ids is None:
|
| 1051 |
+
position_ids = torch.arange(
|
| 1052 |
+
0, seq_length, dtype=torch.long, device=self.position_embeds_layer.weight.device
|
| 1053 |
+
)
|
| 1054 |
+
position_ids = position_ids.unsqueeze(0) # shape (1, seq_length)
|
| 1055 |
+
|
| 1056 |
+
position_ids = position_ids.to(self.position_embeds_layer.weight.device)
|
| 1057 |
+
position_embeds = self.position_embeds_layer(position_ids) # position embeddings of shape (1, t, n_embd)
|
| 1058 |
+
|
| 1059 |
+
attention_mask = create_bidirectional_mask(
|
| 1060 |
+
config=self.config,
|
| 1061 |
+
inputs_embeds=inputs_embeds,
|
| 1062 |
+
attention_mask=attention_mask,
|
| 1063 |
+
)
|
| 1064 |
+
|
| 1065 |
+
hidden_states = self.drop(inputs_embeds + position_embeds)
|
| 1066 |
+
output_shape = input_shape + (hidden_states.size(-1),)
|
| 1067 |
+
|
| 1068 |
+
all_self_attentions = () if output_attentions else None
|
| 1069 |
+
all_hidden_states = () if output_hidden_states else None
|
| 1070 |
+
|
| 1071 |
+
for i, block in enumerate(self.layers):
|
| 1072 |
+
if output_hidden_states:
|
| 1073 |
+
all_hidden_states = all_hidden_states + (hidden_states,)
|
| 1074 |
+
|
| 1075 |
+
outputs = block(
|
| 1076 |
+
hidden_states,
|
| 1077 |
+
attention_mask=attention_mask,
|
| 1078 |
+
output_attentions=output_attentions,
|
| 1079 |
+
)
|
| 1080 |
+
|
| 1081 |
+
hidden_states = outputs[0]
|
| 1082 |
+
|
| 1083 |
+
if output_attentions:
|
| 1084 |
+
all_self_attentions = all_self_attentions + (outputs[1],)
|
| 1085 |
+
|
| 1086 |
+
hidden_states = self.layernorm_final(hidden_states)
|
| 1087 |
+
hidden_states = hidden_states.view(output_shape)
|
| 1088 |
+
|
| 1089 |
+
# Add last hidden state
|
| 1090 |
+
if output_hidden_states:
|
| 1091 |
+
all_hidden_states = all_hidden_states + (hidden_states,)
|
| 1092 |
+
|
| 1093 |
+
logits = self.lm_heads[codebook_idx - self.config.n_codes_given](hidden_states)
|
| 1094 |
+
|
| 1095 |
+
if not return_dict:
|
| 1096 |
+
return tuple(v for v in [None, logits, all_hidden_states, all_self_attentions] if v is not None)
|
| 1097 |
+
|
| 1098 |
+
return MaskedLMOutput(
|
| 1099 |
+
loss=loss,
|
| 1100 |
+
logits=logits,
|
| 1101 |
+
hidden_states=all_hidden_states,
|
| 1102 |
+
attentions=all_self_attentions,
|
| 1103 |
+
)
|
| 1104 |
+
|
| 1105 |
+
@torch.no_grad()
|
| 1106 |
+
def generate(
|
| 1107 |
+
self,
|
| 1108 |
+
coarse_output: torch.Tensor,
|
| 1109 |
+
semantic_generation_config: BarkSemanticGenerationConfig | None = None,
|
| 1110 |
+
coarse_generation_config: BarkCoarseGenerationConfig | None = None,
|
| 1111 |
+
fine_generation_config: BarkFineGenerationConfig = None,
|
| 1112 |
+
codebook_size: int = 1024,
|
| 1113 |
+
history_prompt: dict[str, torch.Tensor] | None = None,
|
| 1114 |
+
**kwargs,
|
| 1115 |
+
) -> torch.LongTensor:
|
| 1116 |
+
"""
|
| 1117 |
+
Generates fine acoustics tokens from input coarse acoustics tokens and an additional optional `Bark` speaker
|
| 1118 |
+
prompt.
|
| 1119 |
+
|
| 1120 |
+
Args:
|
| 1121 |
+
coarse_output (`torch.Tensor` of shape (batch_size, seq_len)):
|
| 1122 |
+
Input coarse acoustics ids, i.e the output of `BarkCoarseModel.generate`.
|
| 1123 |
+
semantic_generation_config (`BarkSemanticGenerationConfig`):
|
| 1124 |
+
Generation config indicating how to generate the semantic tokens.
|
| 1125 |
+
coarse_generation_config (`BarkCoarseGenerationConfig`):
|
| 1126 |
+
Generation config indicating how to generate the coarse tokens.
|
| 1127 |
+
fine_generation_config (`BarkFineGenerationConfig`):
|
| 1128 |
+
Generation config indicating how to generate the fine tokens.
|
| 1129 |
+
codebook_size (`int`, *optional*, defaults to 1024):
|
| 1130 |
+
Codebook channel size, i.e. the size of the output vocabulary per codebook channel.
|
| 1131 |
+
history_prompt (`Optional[dict[str,torch.Tensor]]`, *optional*):
|
| 1132 |
+
Optional `Bark` speaker prompt.
|
| 1133 |
+
Returns:
|
| 1134 |
+
torch.LongTensor: Output fine acoustics tokens.
|
| 1135 |
+
"""
|
| 1136 |
+
if semantic_generation_config is None:
|
| 1137 |
+
raise ValueError("`semantic_generation_config` has to be provided")
|
| 1138 |
+
|
| 1139 |
+
if coarse_generation_config is None:
|
| 1140 |
+
raise ValueError("`coarse_generation_config` has to be provided")
|
| 1141 |
+
|
| 1142 |
+
if fine_generation_config is None:
|
| 1143 |
+
raise ValueError("`fine_generation_config` has to be provided")
|
| 1144 |
+
|
| 1145 |
+
# since we don't really use GenerationConfig through the fine model (autoencoder)
|
| 1146 |
+
# and since only temperature is used from the classic GenerationConfig parameters
|
| 1147 |
+
# manually impose the kwargs priority over the generation config
|
| 1148 |
+
temperature = kwargs.get("temperature", fine_generation_config.temperature)
|
| 1149 |
+
|
| 1150 |
+
max_fine_history_length = fine_generation_config.max_fine_history_length
|
| 1151 |
+
max_fine_input_length = fine_generation_config.max_fine_input_length
|
| 1152 |
+
|
| 1153 |
+
# shape: (batch, n_coarse_codebooks * seq_len)
|
| 1154 |
+
# new_shape: (batch, seq_len, n_coarse_codebooks)
|
| 1155 |
+
coarse_output = coarse_output.view(coarse_output.shape[0], -1, coarse_generation_config.n_coarse_codebooks)
|
| 1156 |
+
|
| 1157 |
+
# brings ids into the range [0, codebook_size -1]
|
| 1158 |
+
coarse_output = torch.remainder(coarse_output - semantic_generation_config.semantic_vocab_size, codebook_size)
|
| 1159 |
+
batch_size = coarse_output.shape[0]
|
| 1160 |
+
|
| 1161 |
+
if history_prompt is not None:
|
| 1162 |
+
x_fine_history = torch.repeat_interleave(history_prompt["fine_prompt"].T[None], batch_size, dim=0)
|
| 1163 |
+
# transpose to get to shape (seq_len, n_fine_codebooks)
|
| 1164 |
+
else:
|
| 1165 |
+
x_fine_history = None
|
| 1166 |
+
|
| 1167 |
+
n_coarse = coarse_generation_config.n_coarse_codebooks
|
| 1168 |
+
|
| 1169 |
+
# pad the last 6th codebooks
|
| 1170 |
+
fine_input = F.pad(
|
| 1171 |
+
coarse_output,
|
| 1172 |
+
(0, fine_generation_config.n_fine_codebooks - n_coarse),
|
| 1173 |
+
"constant",
|
| 1174 |
+
codebook_size,
|
| 1175 |
+
)
|
| 1176 |
+
|
| 1177 |
+
# prepend history if available (max max_fine_history_length)
|
| 1178 |
+
if x_fine_history is not None:
|
| 1179 |
+
fine_input = torch.cat([x_fine_history[:, -max_fine_history_length:, :], fine_input], dim=1)
|
| 1180 |
+
|
| 1181 |
+
# len of the fine_history that has been added to fine_input
|
| 1182 |
+
n_history = x_fine_history[:, -max_fine_history_length:, :].shape[1]
|
| 1183 |
+
else:
|
| 1184 |
+
n_history = 0
|
| 1185 |
+
|
| 1186 |
+
n_remove_from_end = 0
|
| 1187 |
+
# need to pad if too short (since non-causal model)
|
| 1188 |
+
if fine_input.shape[1] < max_fine_input_length:
|
| 1189 |
+
n_remove_from_end = max_fine_input_length - fine_input.shape[1]
|
| 1190 |
+
fine_input = F.pad(fine_input, (0, 0, 0, n_remove_from_end), mode="constant", value=codebook_size)
|
| 1191 |
+
|
| 1192 |
+
# we can be lazy about fractional loop and just keep overwriting codebooks.
|
| 1193 |
+
# seems that coarse_output.shape[1] - (max_fine_input_length - n_history) is equal to minus n_remove_from_end
|
| 1194 |
+
# So if we needed to pad because too short, n_loops is always 1 (because n_remove_from_end > 0)
|
| 1195 |
+
# If not, we loop over at least twice.
|
| 1196 |
+
|
| 1197 |
+
n_loops = (coarse_output.shape[1] - (max_fine_input_length - n_history)) / max_fine_history_length
|
| 1198 |
+
n_loops = int(np.ceil(n_loops))
|
| 1199 |
+
n_loops = max(0, n_loops) + 1
|
| 1200 |
+
|
| 1201 |
+
for n_outer in range(n_loops):
|
| 1202 |
+
start_idx = min([n_outer * max_fine_history_length, fine_input.shape[1] - max_fine_input_length])
|
| 1203 |
+
|
| 1204 |
+
start_fill_idx = min(
|
| 1205 |
+
[n_history + n_outer * max_fine_history_length, fine_input.shape[1] - max_fine_history_length]
|
| 1206 |
+
)
|
| 1207 |
+
rel_start_fill_idx = start_fill_idx - start_idx
|
| 1208 |
+
input_buffer = fine_input[:, start_idx : start_idx + max_fine_input_length, :]
|
| 1209 |
+
for n_inner in range(n_coarse, fine_generation_config.n_fine_codebooks):
|
| 1210 |
+
logits = self.forward(n_inner, input_buffer).logits
|
| 1211 |
+
if temperature is None or temperature == 1.0:
|
| 1212 |
+
relevant_logits = logits[:, rel_start_fill_idx:, :codebook_size]
|
| 1213 |
+
codebook_preds = torch.argmax(relevant_logits, -1)
|
| 1214 |
+
else:
|
| 1215 |
+
relevant_logits = logits[:, :, :codebook_size] / temperature
|
| 1216 |
+
# apply softmax
|
| 1217 |
+
probs = F.softmax(relevant_logits, dim=-1)[:, rel_start_fill_idx:max_fine_input_length]
|
| 1218 |
+
# reshape to 2D: (batch_size, seq_len, codebook_size) -> (batch_size*seq_len, codebook_size)
|
| 1219 |
+
probs = probs.reshape((-1, codebook_size))
|
| 1220 |
+
# multinomial then reshape : (batch_size*seq_len)-> (batch_size,seq_len)
|
| 1221 |
+
codebook_preds = torch.multinomial(probs, num_samples=1).view(batch_size, -1)
|
| 1222 |
+
codebook_preds = codebook_preds.to(torch.int32)
|
| 1223 |
+
input_buffer[:, rel_start_fill_idx:, n_inner] = codebook_preds
|
| 1224 |
+
del logits, codebook_preds
|
| 1225 |
+
|
| 1226 |
+
# transfer into fine_input
|
| 1227 |
+
for n_inner in range(n_coarse, fine_generation_config.n_fine_codebooks):
|
| 1228 |
+
fine_input[
|
| 1229 |
+
:, start_fill_idx : start_fill_idx + (max_fine_input_length - rel_start_fill_idx), n_inner
|
| 1230 |
+
] = input_buffer[:, rel_start_fill_idx:, n_inner]
|
| 1231 |
+
del input_buffer
|
| 1232 |
+
|
| 1233 |
+
fine_input = fine_input.transpose(1, 2)[:, :, n_history:]
|
| 1234 |
+
if n_remove_from_end > 0:
|
| 1235 |
+
fine_input = fine_input[:, :, :-n_remove_from_end]
|
| 1236 |
+
|
| 1237 |
+
if fine_input.shape[-1] != coarse_output.shape[-2]:
|
| 1238 |
+
raise ValueError("input and output should have the same seq_len")
|
| 1239 |
+
|
| 1240 |
+
return fine_input
|
| 1241 |
+
|
| 1242 |
+
|
| 1243 |
+
@auto_docstring(
|
| 1244 |
+
custom_intro="""
|
| 1245 |
+
The full Bark model, a text-to-speech model composed of 4 sub-models:
|
| 1246 |
+
- [`BarkSemanticModel`] (also referred to as the 'text' model): a causal auto-regressive transformer model that
|
| 1247 |
+
takes
|
| 1248 |
+
as input tokenized text, and predicts semantic text tokens that capture the meaning of the text.
|
| 1249 |
+
- [`BarkCoarseModel`] (also referred to as the 'coarse acoustics' model), also a causal autoregressive transformer,
|
| 1250 |
+
that takes into input the results of the last model. It aims at regressing the first two audio codebooks necessary
|
| 1251 |
+
to `encodec`.
|
| 1252 |
+
- [`BarkFineModel`] (the 'fine acoustics' model), this time a non-causal autoencoder transformer, which iteratively
|
| 1253 |
+
predicts the last codebooks based on the sum of the previous codebooks embeddings.
|
| 1254 |
+
- having predicted all the codebook channels from the [`EncodecModel`], Bark uses it to decode the output audio
|
| 1255 |
+
array.
|
| 1256 |
+
|
| 1257 |
+
It should be noted that each of the first three modules can support conditional speaker embeddings to condition the
|
| 1258 |
+
output sound according to specific predefined voice.
|
| 1259 |
+
"""
|
| 1260 |
+
)
|
| 1261 |
+
class BarkModel(BarkPreTrainedModel, GenerationMixin):
|
| 1262 |
+
config: BarkConfig
|
| 1263 |
+
|
| 1264 |
+
def __init__(self, config):
|
| 1265 |
+
super().__init__(config)
|
| 1266 |
+
|
| 1267 |
+
self.semantic = BarkSemanticModel(config.semantic_config)
|
| 1268 |
+
self.coarse_acoustics = BarkCoarseModel(config.coarse_acoustics_config)
|
| 1269 |
+
self.fine_acoustics = BarkFineModel(config.fine_acoustics_config)
|
| 1270 |
+
|
| 1271 |
+
self.codec_model = AutoModel.from_config(config.codec_config)
|
| 1272 |
+
|
| 1273 |
+
self.config = config
|
| 1274 |
+
|
| 1275 |
+
self.post_init()
|
| 1276 |
+
|
| 1277 |
+
@classmethod
|
| 1278 |
+
def can_generate(cls) -> bool:
|
| 1279 |
+
# Bark has a unique model structure, where the external class (`BarkModel`) doesn't need to inherit from
|
| 1280 |
+
# `GenerationMixin` (it has a non-standard generation method), but one of the internal models do
|
| 1281 |
+
# (`BarkSemanticModel`). This means that the base `can_generate()` will return `False`, but we need to
|
| 1282 |
+
# override it so as to do `GenerationConfig` handling in multiple parts of the codebase.
|
| 1283 |
+
return True
|
| 1284 |
+
|
| 1285 |
+
@property
|
| 1286 |
+
def device(self) -> torch.device:
|
| 1287 |
+
"""
|
| 1288 |
+
`torch.device`: The device on which the module is (assuming that all the module parameters are on the same
|
| 1289 |
+
device).
|
| 1290 |
+
"""
|
| 1291 |
+
# for bark_model, device must be verified on its sub-models
|
| 1292 |
+
# if has _hf_hook, has been offloaded so the device has to be found in the hook
|
| 1293 |
+
if not hasattr(self.semantic, "_hf_hook"):
|
| 1294 |
+
return super().device
|
| 1295 |
+
for module in self.semantic.modules():
|
| 1296 |
+
if (
|
| 1297 |
+
hasattr(module, "_hf_hook")
|
| 1298 |
+
and hasattr(module._hf_hook, "execution_device")
|
| 1299 |
+
and module._hf_hook.execution_device is not None
|
| 1300 |
+
):
|
| 1301 |
+
return torch.device(module._hf_hook.execution_device)
|
| 1302 |
+
|
| 1303 |
+
def enable_cpu_offload(
|
| 1304 |
+
self,
|
| 1305 |
+
accelerator_id: int | None = 0,
|
| 1306 |
+
**kwargs,
|
| 1307 |
+
):
|
| 1308 |
+
r"""
|
| 1309 |
+
Offloads all sub-models to CPU using accelerate, reducing memory usage with a low impact on performance. This
|
| 1310 |
+
method moves one whole sub-model at a time to the accelerator when it is used, and the sub-model remains in accelerator until the next sub-model runs.
|
| 1311 |
+
|
| 1312 |
+
Args:
|
| 1313 |
+
accelerator_id (`int`, *optional*, defaults to 0):
|
| 1314 |
+
accelerator id on which the sub-models will be loaded and offloaded.
|
| 1315 |
+
"""
|
| 1316 |
+
if is_accelerate_available():
|
| 1317 |
+
from accelerate import cpu_offload_with_hook
|
| 1318 |
+
else:
|
| 1319 |
+
raise ImportError("`enable_model_cpu_offload` requires `accelerate`.")
|
| 1320 |
+
|
| 1321 |
+
device_type = "cuda"
|
| 1322 |
+
if is_torch_accelerator_available():
|
| 1323 |
+
device_type = torch.accelerator.current_accelerator().type
|
| 1324 |
+
device = torch.device(f"{device_type}:{accelerator_id}")
|
| 1325 |
+
|
| 1326 |
+
torch_accelerator_module = getattr(torch, device_type)
|
| 1327 |
+
if self.device.type != "cpu":
|
| 1328 |
+
self.to("cpu")
|
| 1329 |
+
torch_accelerator_module.empty_cache() # otherwise we don't see the memory savings (but they probably exist)
|
| 1330 |
+
|
| 1331 |
+
# this layer is used outside the first forward pass of semantic so need to be loaded before semantic
|
| 1332 |
+
self.semantic.input_embeds_layer, _ = cpu_offload_with_hook(self.semantic.input_embeds_layer, device)
|
| 1333 |
+
|
| 1334 |
+
hook = None
|
| 1335 |
+
for cpu_offloaded_model in [
|
| 1336 |
+
self.semantic,
|
| 1337 |
+
self.coarse_acoustics,
|
| 1338 |
+
self.fine_acoustics,
|
| 1339 |
+
]:
|
| 1340 |
+
_, hook = cpu_offload_with_hook(cpu_offloaded_model, device, prev_module_hook=hook)
|
| 1341 |
+
|
| 1342 |
+
self.fine_acoustics_hook = hook
|
| 1343 |
+
|
| 1344 |
+
_, hook = cpu_offload_with_hook(self.codec_model, device, prev_module_hook=hook)
|
| 1345 |
+
|
| 1346 |
+
# We'll offload the last model manually.
|
| 1347 |
+
self.codec_model_hook = hook
|
| 1348 |
+
|
| 1349 |
+
def codec_decode(self, fine_output, output_lengths=None):
|
| 1350 |
+
"""Turn quantized audio codes into audio array using encodec."""
|
| 1351 |
+
|
| 1352 |
+
fine_output = fine_output.transpose(0, 1)
|
| 1353 |
+
emb = self.codec_model.quantizer.decode(fine_output)
|
| 1354 |
+
|
| 1355 |
+
if output_lengths is not None:
|
| 1356 |
+
# encodec uses LSTMs which behaves differently with appended padding
|
| 1357 |
+
# decoding with encodec takes around 0.1% of the total generation time
|
| 1358 |
+
# to keep generation quality, we break batching
|
| 1359 |
+
out = [sample[:, :l].unsqueeze(0) for (sample, l) in zip(emb, output_lengths)]
|
| 1360 |
+
audio_arr = [self.codec_model.decoder(sample).squeeze() for sample in out]
|
| 1361 |
+
else:
|
| 1362 |
+
out = self.codec_model.decoder(emb)
|
| 1363 |
+
audio_arr = out.squeeze(1) # squeeze the codebook dimension
|
| 1364 |
+
|
| 1365 |
+
return audio_arr
|
| 1366 |
+
|
| 1367 |
+
@torch.no_grad()
|
| 1368 |
+
def generate(
|
| 1369 |
+
self,
|
| 1370 |
+
input_ids: torch.Tensor | None = None,
|
| 1371 |
+
history_prompt: dict[str, torch.Tensor] | None = None,
|
| 1372 |
+
return_output_lengths: bool | None = None,
|
| 1373 |
+
**kwargs,
|
| 1374 |
+
) -> torch.LongTensor:
|
| 1375 |
+
"""
|
| 1376 |
+
Generates audio from an input prompt and an additional optional `Bark` speaker prompt.
|
| 1377 |
+
|
| 1378 |
+
Args:
|
| 1379 |
+
input_ids (`Optional[torch.Tensor]` of shape (batch_size, seq_len), *optional*):
|
| 1380 |
+
Input ids. Will be truncated up to 256 tokens. Note that the output audios will be as long as the
|
| 1381 |
+
longest generation among the batch.
|
| 1382 |
+
history_prompt (`Optional[dict[str,torch.Tensor]]`, *optional*):
|
| 1383 |
+
Optional `Bark` speaker prompt. Note that for now, this model takes only one speaker prompt per batch.
|
| 1384 |
+
kwargs (*optional*): Remaining dictionary of keyword arguments. Keyword arguments are of two types:
|
| 1385 |
+
|
| 1386 |
+
- Without a prefix, they will be entered as `**kwargs` for the `generate` method of each sub-model.
|
| 1387 |
+
- With a *semantic_*, *coarse_*, *fine_* prefix, they will be input for the `generate` method of the
|
| 1388 |
+
semantic, coarse and fine respectively. It has the priority over the keywords without a prefix.
|
| 1389 |
+
|
| 1390 |
+
This means you can, for example, specify a generation strategy for all sub-models except one.
|
| 1391 |
+
return_output_lengths (`bool`, *optional*):
|
| 1392 |
+
Whether or not to return the waveform lengths. Useful when batching.
|
| 1393 |
+
Returns:
|
| 1394 |
+
By default:
|
| 1395 |
+
- **audio_waveform** (`torch.Tensor` of shape (batch_size, seq_len)): Generated audio waveform.
|
| 1396 |
+
When `return_output_lengths=True`:
|
| 1397 |
+
Returns a tuple made of:
|
| 1398 |
+
- **audio_waveform** (`torch.Tensor` of shape (batch_size, seq_len)): Generated audio waveform.
|
| 1399 |
+
- **output_lengths** (`torch.Tensor` of shape (batch_size)): The length of each waveform in the batch
|
| 1400 |
+
Example:
|
| 1401 |
+
|
| 1402 |
+
```python
|
| 1403 |
+
>>> from transformers import AutoProcessor, BarkModel
|
| 1404 |
+
|
| 1405 |
+
>>> processor = AutoProcessor.from_pretrained("suno/bark-small")
|
| 1406 |
+
>>> model = BarkModel.from_pretrained("suno/bark-small")
|
| 1407 |
+
|
| 1408 |
+
>>> # To add a voice preset, you can pass `voice_preset` to `BarkProcessor.__call__(...)`
|
| 1409 |
+
>>> voice_preset = "v2/en_speaker_6"
|
| 1410 |
+
|
| 1411 |
+
>>> inputs = processor("Hello, my dog is cute, I need him in my life", voice_preset=voice_preset)
|
| 1412 |
+
|
| 1413 |
+
>>> audio_array = model.generate(**inputs, semantic_max_new_tokens=100)
|
| 1414 |
+
>>> audio_array = audio_array.cpu().numpy().squeeze()
|
| 1415 |
+
```
|
| 1416 |
+
"""
|
| 1417 |
+
# TODO (joao):workaround until nested generation config is compatible with PreTrained Model
|
| 1418 |
+
# todo: dict
|
| 1419 |
+
semantic_generation_config = BarkSemanticGenerationConfig(**self.generation_config.semantic_config)
|
| 1420 |
+
coarse_generation_config = BarkCoarseGenerationConfig(**self.generation_config.coarse_acoustics_config)
|
| 1421 |
+
fine_generation_config = BarkFineGenerationConfig(**self.generation_config.fine_acoustics_config)
|
| 1422 |
+
|
| 1423 |
+
kwargs_semantic = {
|
| 1424 |
+
# if "attention_mask" is set, it should not be passed to CoarseModel and FineModel
|
| 1425 |
+
"attention_mask": kwargs.pop("attention_mask", None),
|
| 1426 |
+
"min_eos_p": kwargs.pop("min_eos_p", None),
|
| 1427 |
+
}
|
| 1428 |
+
kwargs_coarse = {}
|
| 1429 |
+
kwargs_fine = {}
|
| 1430 |
+
for key, value in kwargs.items():
|
| 1431 |
+
if key.startswith("semantic_"):
|
| 1432 |
+
key = key[len("semantic_") :]
|
| 1433 |
+
kwargs_semantic[key] = value
|
| 1434 |
+
elif key.startswith("coarse_"):
|
| 1435 |
+
key = key[len("coarse_") :]
|
| 1436 |
+
kwargs_coarse[key] = value
|
| 1437 |
+
elif key.startswith("fine_"):
|
| 1438 |
+
key = key[len("fine_") :]
|
| 1439 |
+
kwargs_fine[key] = value
|
| 1440 |
+
else:
|
| 1441 |
+
# If the key is already in a specific config, then it's been set with a
|
| 1442 |
+
# submodules specific value and we don't override
|
| 1443 |
+
if key not in kwargs_semantic:
|
| 1444 |
+
kwargs_semantic[key] = value
|
| 1445 |
+
if key not in kwargs_coarse:
|
| 1446 |
+
kwargs_coarse[key] = value
|
| 1447 |
+
if key not in kwargs_fine:
|
| 1448 |
+
kwargs_fine[key] = value
|
| 1449 |
+
|
| 1450 |
+
# 1. Generate from the semantic model
|
| 1451 |
+
if "generation_config" in kwargs_semantic:
|
| 1452 |
+
kwargs_semantic.pop("generation_config")
|
| 1453 |
+
semantic_output = self.semantic.generate(
|
| 1454 |
+
input_ids,
|
| 1455 |
+
history_prompt=history_prompt,
|
| 1456 |
+
semantic_generation_config=semantic_generation_config,
|
| 1457 |
+
**kwargs_semantic,
|
| 1458 |
+
)
|
| 1459 |
+
|
| 1460 |
+
# 2. Generate from the coarse model
|
| 1461 |
+
if "generation_config" in kwargs_coarse:
|
| 1462 |
+
kwargs_coarse.pop("generation_config")
|
| 1463 |
+
coarse_output = self.coarse_acoustics.generate(
|
| 1464 |
+
semantic_output,
|
| 1465 |
+
history_prompt=history_prompt,
|
| 1466 |
+
semantic_generation_config=semantic_generation_config,
|
| 1467 |
+
coarse_generation_config=coarse_generation_config,
|
| 1468 |
+
codebook_size=self.generation_config.codebook_size,
|
| 1469 |
+
return_output_lengths=return_output_lengths,
|
| 1470 |
+
**kwargs_coarse,
|
| 1471 |
+
)
|
| 1472 |
+
|
| 1473 |
+
output_lengths = None
|
| 1474 |
+
if return_output_lengths:
|
| 1475 |
+
coarse_output, output_lengths = coarse_output
|
| 1476 |
+
# (batch_size, seq_len*coarse_codebooks) -> (batch_size, seq_len)
|
| 1477 |
+
output_lengths = output_lengths // coarse_generation_config.n_coarse_codebooks
|
| 1478 |
+
|
| 1479 |
+
# 3. "generate" from the fine model
|
| 1480 |
+
if "generation_config" in kwargs_fine:
|
| 1481 |
+
kwargs_fine.pop("generation_config")
|
| 1482 |
+
output = self.fine_acoustics.generate(
|
| 1483 |
+
coarse_output,
|
| 1484 |
+
history_prompt=history_prompt,
|
| 1485 |
+
semantic_generation_config=semantic_generation_config,
|
| 1486 |
+
coarse_generation_config=coarse_generation_config,
|
| 1487 |
+
fine_generation_config=fine_generation_config,
|
| 1488 |
+
codebook_size=self.generation_config.codebook_size,
|
| 1489 |
+
**kwargs_fine,
|
| 1490 |
+
)
|
| 1491 |
+
|
| 1492 |
+
if getattr(self, "fine_acoustics_hook", None) is not None:
|
| 1493 |
+
# Manually offload fine_acoustics to CPU
|
| 1494 |
+
# and load codec_model to GPU
|
| 1495 |
+
# since bark doesn't use codec_model forward pass
|
| 1496 |
+
self.fine_acoustics_hook.offload()
|
| 1497 |
+
self.codec_model = self.codec_model.to(self.device)
|
| 1498 |
+
|
| 1499 |
+
# 4. Decode the output and generate audio array
|
| 1500 |
+
audio = self.codec_decode(output, output_lengths)
|
| 1501 |
+
|
| 1502 |
+
if getattr(self, "codec_model_hook", None) is not None:
|
| 1503 |
+
# Offload codec_model to CPU
|
| 1504 |
+
self.codec_model_hook.offload()
|
| 1505 |
+
|
| 1506 |
+
if return_output_lengths:
|
| 1507 |
+
output_lengths = [len(sample) for sample in audio]
|
| 1508 |
+
audio = nn.utils.rnn.pad_sequence(audio, batch_first=True, padding_value=0)
|
| 1509 |
+
return audio, output_lengths
|
| 1510 |
+
|
| 1511 |
+
return audio
|
| 1512 |
+
|
| 1513 |
+
|
| 1514 |
+
__all__ = [
|
| 1515 |
+
"BarkFineModel",
|
| 1516 |
+
"BarkSemanticModel",
|
| 1517 |
+
"BarkCoarseModel",
|
| 1518 |
+
"BarkModel",
|
| 1519 |
+
"BarkPreTrainedModel",
|
| 1520 |
+
"BarkCausalModel",
|
| 1521 |
+
]
|
third_party/transformers/src/transformers/models/bark/processing_bark.py
ADDED
|
@@ -0,0 +1,314 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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 |
+
"""
|
| 15 |
+
Processor class for Bark
|
| 16 |
+
"""
|
| 17 |
+
|
| 18 |
+
import json
|
| 19 |
+
import os
|
| 20 |
+
|
| 21 |
+
import numpy as np
|
| 22 |
+
|
| 23 |
+
from ...feature_extraction_utils import BatchFeature
|
| 24 |
+
from ...processing_utils import ProcessorMixin
|
| 25 |
+
from ...tokenization_utils_base import BatchEncoding
|
| 26 |
+
from ...utils import auto_docstring, logging
|
| 27 |
+
from ...utils.hub import cached_file
|
| 28 |
+
from ..auto import AutoTokenizer
|
| 29 |
+
|
| 30 |
+
|
| 31 |
+
logger = logging.get_logger(__name__)
|
| 32 |
+
|
| 33 |
+
|
| 34 |
+
@auto_docstring
|
| 35 |
+
class BarkProcessor(ProcessorMixin):
|
| 36 |
+
preset_shape = {
|
| 37 |
+
"semantic_prompt": 1, # 1D array of shape (X,)
|
| 38 |
+
"coarse_prompt": 2, # 2D array of shape (2,X)
|
| 39 |
+
"fine_prompt": 2, # 2D array of shape (8,X)
|
| 40 |
+
}
|
| 41 |
+
|
| 42 |
+
def __init__(self, tokenizer, speaker_embeddings=None):
|
| 43 |
+
r"""
|
| 44 |
+
speaker_embeddings (`dict[dict[str]]`, *optional*):
|
| 45 |
+
Optional nested speaker embeddings dictionary. The first level contains voice preset names (e.g
|
| 46 |
+
`"en_speaker_4"`). The second level contains `"semantic_prompt"`, `"coarse_prompt"` and `"fine_prompt"`
|
| 47 |
+
embeddings. The values correspond to the path of the corresponding `np.ndarray`. See
|
| 48 |
+
[here](https://suno-ai.notion.site/8b8e8749ed514b0cbf3f699013548683?v=bc67cff786b04b50b3ceb756fd05f68c) for
|
| 49 |
+
a list of `voice_preset_names`.
|
| 50 |
+
"""
|
| 51 |
+
super().__init__(tokenizer)
|
| 52 |
+
|
| 53 |
+
self.speaker_embeddings = speaker_embeddings
|
| 54 |
+
|
| 55 |
+
@classmethod
|
| 56 |
+
def from_pretrained(
|
| 57 |
+
cls, pretrained_processor_name_or_path, speaker_embeddings_dict_path="speaker_embeddings_path.json", **kwargs
|
| 58 |
+
):
|
| 59 |
+
r"""
|
| 60 |
+
Instantiate a Bark processor associated with a pretrained model.
|
| 61 |
+
|
| 62 |
+
Args:
|
| 63 |
+
pretrained_model_name_or_path (`str` or `os.PathLike`):
|
| 64 |
+
This can be either:
|
| 65 |
+
|
| 66 |
+
- a string, the *model id* of a pretrained [`BarkProcessor`] hosted inside a model repo on
|
| 67 |
+
huggingface.co.
|
| 68 |
+
- a path to a *directory* containing a processor saved using the [`~BarkProcessor.save_pretrained`]
|
| 69 |
+
method, e.g., `./my_model_directory/`.
|
| 70 |
+
speaker_embeddings_dict_path (`str`, *optional*, defaults to `"speaker_embeddings_path.json"`):
|
| 71 |
+
The name of the `.json` file containing the speaker_embeddings dictionary located in
|
| 72 |
+
`pretrained_model_name_or_path`. If `None`, no speaker_embeddings is loaded.
|
| 73 |
+
**kwargs
|
| 74 |
+
Additional keyword arguments passed along to both
|
| 75 |
+
[`~tokenization_utils_base.PreTrainedTokenizer.from_pretrained`].
|
| 76 |
+
"""
|
| 77 |
+
token = kwargs.get("token")
|
| 78 |
+
if speaker_embeddings_dict_path is not None:
|
| 79 |
+
speaker_embeddings_path = cached_file(
|
| 80 |
+
pretrained_processor_name_or_path,
|
| 81 |
+
speaker_embeddings_dict_path,
|
| 82 |
+
subfolder=kwargs.pop("subfolder", None),
|
| 83 |
+
cache_dir=kwargs.pop("cache_dir", None),
|
| 84 |
+
force_download=kwargs.pop("force_download", False),
|
| 85 |
+
proxies=kwargs.pop("proxies", None),
|
| 86 |
+
local_files_only=kwargs.pop("local_files_only", False),
|
| 87 |
+
token=token,
|
| 88 |
+
revision=kwargs.pop("revision", None),
|
| 89 |
+
_raise_exceptions_for_gated_repo=False,
|
| 90 |
+
_raise_exceptions_for_missing_entries=False,
|
| 91 |
+
_raise_exceptions_for_connection_errors=False,
|
| 92 |
+
)
|
| 93 |
+
if speaker_embeddings_path is None:
|
| 94 |
+
logger.warning(
|
| 95 |
+
f"""`{os.path.join(pretrained_processor_name_or_path, speaker_embeddings_dict_path)}` does not exists
|
| 96 |
+
, no preloaded speaker embeddings will be used - Make sure to provide a correct path to the json
|
| 97 |
+
dictionary if wanted, otherwise set `speaker_embeddings_dict_path=None`."""
|
| 98 |
+
)
|
| 99 |
+
speaker_embeddings = None
|
| 100 |
+
else:
|
| 101 |
+
with open(speaker_embeddings_path) as speaker_embeddings_json:
|
| 102 |
+
speaker_embeddings = json.load(speaker_embeddings_json)
|
| 103 |
+
else:
|
| 104 |
+
speaker_embeddings = None
|
| 105 |
+
|
| 106 |
+
if speaker_embeddings is not None:
|
| 107 |
+
if "repo_or_path" in speaker_embeddings:
|
| 108 |
+
speaker_embeddings["repo_or_path"] = pretrained_processor_name_or_path
|
| 109 |
+
tokenizer = AutoTokenizer.from_pretrained(pretrained_processor_name_or_path, **kwargs)
|
| 110 |
+
|
| 111 |
+
return cls(tokenizer=tokenizer, speaker_embeddings=speaker_embeddings)
|
| 112 |
+
|
| 113 |
+
def save_pretrained(
|
| 114 |
+
self,
|
| 115 |
+
save_directory,
|
| 116 |
+
speaker_embeddings_dict_path="speaker_embeddings_path.json",
|
| 117 |
+
speaker_embeddings_directory="speaker_embeddings",
|
| 118 |
+
push_to_hub: bool = False,
|
| 119 |
+
**kwargs,
|
| 120 |
+
):
|
| 121 |
+
"""
|
| 122 |
+
Saves the attributes of this processor (tokenizer...) in the specified directory so that it can be reloaded
|
| 123 |
+
using the [`~BarkProcessor.from_pretrained`] method.
|
| 124 |
+
|
| 125 |
+
Args:
|
| 126 |
+
save_directory (`str` or `os.PathLike`):
|
| 127 |
+
Directory where the tokenizer files and the speaker embeddings will be saved (directory will be created
|
| 128 |
+
if it does not exist).
|
| 129 |
+
speaker_embeddings_dict_path (`str`, *optional*, defaults to `"speaker_embeddings_path.json"`):
|
| 130 |
+
The name of the `.json` file that will contains the speaker_embeddings nested path dictionary, if it
|
| 131 |
+
exists, and that will be located in `pretrained_model_name_or_path/speaker_embeddings_directory`.
|
| 132 |
+
speaker_embeddings_directory (`str`, *optional*, defaults to `"speaker_embeddings/"`):
|
| 133 |
+
The name of the folder in which the speaker_embeddings arrays will be saved.
|
| 134 |
+
push_to_hub (`bool`, *optional*, defaults to `False`):
|
| 135 |
+
Whether or not to push your model to the Hugging Face model hub after saving it. You can specify the
|
| 136 |
+
repository you want to push to with `repo_id` (will default to the name of `save_directory` in your
|
| 137 |
+
namespace).
|
| 138 |
+
kwargs:
|
| 139 |
+
Additional key word arguments passed along to the [`~utils.PushToHubMixin.push_to_hub`] method.
|
| 140 |
+
"""
|
| 141 |
+
if self.speaker_embeddings is not None:
|
| 142 |
+
os.makedirs(os.path.join(save_directory, speaker_embeddings_directory, "v2"), exist_ok=True)
|
| 143 |
+
|
| 144 |
+
embeddings_dict = {}
|
| 145 |
+
|
| 146 |
+
embeddings_dict["repo_or_path"] = save_directory
|
| 147 |
+
|
| 148 |
+
for prompt_key in self.available_voice_presets:
|
| 149 |
+
voice_preset = self._load_voice_preset(prompt_key)
|
| 150 |
+
|
| 151 |
+
tmp_dict = {}
|
| 152 |
+
for key in self.speaker_embeddings[prompt_key]:
|
| 153 |
+
np.save(
|
| 154 |
+
os.path.join(
|
| 155 |
+
embeddings_dict["repo_or_path"], speaker_embeddings_directory, f"{prompt_key}_{key}"
|
| 156 |
+
),
|
| 157 |
+
voice_preset[key],
|
| 158 |
+
allow_pickle=False,
|
| 159 |
+
)
|
| 160 |
+
tmp_dict[key] = os.path.join(speaker_embeddings_directory, f"{prompt_key}_{key}.npy")
|
| 161 |
+
|
| 162 |
+
embeddings_dict[prompt_key] = tmp_dict
|
| 163 |
+
|
| 164 |
+
with open(os.path.join(save_directory, speaker_embeddings_dict_path), "w") as fp:
|
| 165 |
+
json.dump(embeddings_dict, fp)
|
| 166 |
+
|
| 167 |
+
super().save_pretrained(save_directory, push_to_hub, **kwargs)
|
| 168 |
+
|
| 169 |
+
def _load_voice_preset(self, voice_preset: str | None = None, **kwargs):
|
| 170 |
+
voice_preset_paths = self.speaker_embeddings[voice_preset]
|
| 171 |
+
|
| 172 |
+
voice_preset_dict = {}
|
| 173 |
+
token = kwargs.get("token")
|
| 174 |
+
for key in ["semantic_prompt", "coarse_prompt", "fine_prompt"]:
|
| 175 |
+
if key not in voice_preset_paths:
|
| 176 |
+
raise ValueError(
|
| 177 |
+
f"Voice preset unrecognized, missing {key} as a key in self.speaker_embeddings[{voice_preset}]."
|
| 178 |
+
)
|
| 179 |
+
|
| 180 |
+
path = cached_file(
|
| 181 |
+
self.speaker_embeddings.get("repo_or_path", "/"),
|
| 182 |
+
voice_preset_paths[key],
|
| 183 |
+
subfolder=kwargs.pop("subfolder", None),
|
| 184 |
+
cache_dir=kwargs.pop("cache_dir", None),
|
| 185 |
+
force_download=kwargs.pop("force_download", False),
|
| 186 |
+
proxies=kwargs.pop("proxies", None),
|
| 187 |
+
local_files_only=kwargs.pop("local_files_only", False),
|
| 188 |
+
token=token,
|
| 189 |
+
revision=kwargs.pop("revision", None),
|
| 190 |
+
_raise_exceptions_for_gated_repo=False,
|
| 191 |
+
_raise_exceptions_for_missing_entries=False,
|
| 192 |
+
_raise_exceptions_for_connection_errors=False,
|
| 193 |
+
)
|
| 194 |
+
if path is None:
|
| 195 |
+
raise ValueError(
|
| 196 |
+
f"""`{os.path.join(self.speaker_embeddings.get("repo_or_path", "/"), voice_preset_paths[key])}` does not exists
|
| 197 |
+
, no preloaded voice preset will be used - Make sure to provide correct paths to the {voice_preset}
|
| 198 |
+
embeddings."""
|
| 199 |
+
)
|
| 200 |
+
|
| 201 |
+
voice_preset_dict[key] = np.load(path)
|
| 202 |
+
|
| 203 |
+
return voice_preset_dict
|
| 204 |
+
|
| 205 |
+
def _validate_voice_preset_dict(self, voice_preset: dict | None = None):
|
| 206 |
+
for key in ["semantic_prompt", "coarse_prompt", "fine_prompt"]:
|
| 207 |
+
if key not in voice_preset:
|
| 208 |
+
raise ValueError(f"Voice preset unrecognized, missing {key} as a key.")
|
| 209 |
+
|
| 210 |
+
if not isinstance(voice_preset[key], np.ndarray):
|
| 211 |
+
raise TypeError(f"{key} voice preset must be a {str(self.preset_shape[key])}D ndarray.")
|
| 212 |
+
|
| 213 |
+
if len(voice_preset[key].shape) != self.preset_shape[key]:
|
| 214 |
+
raise ValueError(f"{key} voice preset must be a {str(self.preset_shape[key])}D ndarray.")
|
| 215 |
+
|
| 216 |
+
@property
|
| 217 |
+
def available_voice_presets(self) -> list:
|
| 218 |
+
"""
|
| 219 |
+
Returns a list of available voice presets.
|
| 220 |
+
|
| 221 |
+
Returns:
|
| 222 |
+
`list[str]`: A list of voice preset names.
|
| 223 |
+
"""
|
| 224 |
+
if self.speaker_embeddings is None:
|
| 225 |
+
return []
|
| 226 |
+
|
| 227 |
+
voice_presets = list(self.speaker_embeddings.keys())
|
| 228 |
+
if "repo_or_path" in voice_presets:
|
| 229 |
+
voice_presets.remove("repo_or_path")
|
| 230 |
+
return voice_presets
|
| 231 |
+
|
| 232 |
+
def _verify_speaker_embeddings(self, remove_unavailable: bool = True):
|
| 233 |
+
# check which actually downloaded properly / are available
|
| 234 |
+
unavailable_keys = []
|
| 235 |
+
if self.speaker_embeddings is not None:
|
| 236 |
+
for voice_preset in self.available_voice_presets:
|
| 237 |
+
try:
|
| 238 |
+
voice_preset_dict = self._load_voice_preset(voice_preset)
|
| 239 |
+
except ValueError:
|
| 240 |
+
# error from `_load_voice_preset` of path not existing
|
| 241 |
+
unavailable_keys.append(voice_preset)
|
| 242 |
+
continue
|
| 243 |
+
self._validate_voice_preset_dict(voice_preset_dict)
|
| 244 |
+
|
| 245 |
+
if unavailable_keys:
|
| 246 |
+
logger.warning(
|
| 247 |
+
f"The following {len(unavailable_keys)} speaker embeddings are not available: {unavailable_keys} "
|
| 248 |
+
"If you would like to use them, please check the paths or try downloading them again."
|
| 249 |
+
)
|
| 250 |
+
|
| 251 |
+
if remove_unavailable:
|
| 252 |
+
for voice_preset in unavailable_keys:
|
| 253 |
+
del self.speaker_embeddings[voice_preset]
|
| 254 |
+
|
| 255 |
+
@auto_docstring
|
| 256 |
+
def __call__(
|
| 257 |
+
self,
|
| 258 |
+
text=None,
|
| 259 |
+
voice_preset=None,
|
| 260 |
+
return_tensors="pt",
|
| 261 |
+
max_length=256,
|
| 262 |
+
add_special_tokens=False,
|
| 263 |
+
return_attention_mask=True,
|
| 264 |
+
return_token_type_ids=False,
|
| 265 |
+
**kwargs,
|
| 266 |
+
) -> BatchEncoding:
|
| 267 |
+
r"""
|
| 268 |
+
voice_preset (`str`, `dict[np.ndarray]`):
|
| 269 |
+
The voice preset, i.e the speaker embeddings. It can either be a valid voice_preset name, e.g
|
| 270 |
+
`"en_speaker_1"`, or directly a dictionary of `np.ndarray` embeddings for each submodel of `Bark`. Or
|
| 271 |
+
it can be a valid file name of a local `.npz` single voice preset containing the keys
|
| 272 |
+
`"semantic_prompt"`, `"coarse_prompt"` and `"fine_prompt"`.
|
| 273 |
+
|
| 274 |
+
Returns:
|
| 275 |
+
[`BatchEncoding`]: A [`BatchEncoding`] object containing the output of the `tokenizer`.
|
| 276 |
+
If a voice preset is provided, the returned object will include a `"history_prompt"` key
|
| 277 |
+
containing a [`BatchFeature`], i.e the voice preset with the right tensors type.
|
| 278 |
+
"""
|
| 279 |
+
if voice_preset is not None and not isinstance(voice_preset, dict):
|
| 280 |
+
if (
|
| 281 |
+
isinstance(voice_preset, str)
|
| 282 |
+
and self.speaker_embeddings is not None
|
| 283 |
+
and voice_preset in self.speaker_embeddings
|
| 284 |
+
):
|
| 285 |
+
voice_preset = self._load_voice_preset(voice_preset)
|
| 286 |
+
|
| 287 |
+
else:
|
| 288 |
+
if isinstance(voice_preset, str) and not voice_preset.endswith(".npz"):
|
| 289 |
+
voice_preset = voice_preset + ".npz"
|
| 290 |
+
|
| 291 |
+
voice_preset = np.load(voice_preset)
|
| 292 |
+
|
| 293 |
+
if voice_preset is not None:
|
| 294 |
+
self._validate_voice_preset_dict(voice_preset, **kwargs)
|
| 295 |
+
voice_preset = BatchFeature(data=voice_preset, tensor_type=return_tensors)
|
| 296 |
+
|
| 297 |
+
encoded_text = self.tokenizer(
|
| 298 |
+
text,
|
| 299 |
+
return_tensors=return_tensors,
|
| 300 |
+
padding="max_length",
|
| 301 |
+
max_length=max_length,
|
| 302 |
+
return_attention_mask=return_attention_mask,
|
| 303 |
+
return_token_type_ids=return_token_type_ids,
|
| 304 |
+
add_special_tokens=add_special_tokens,
|
| 305 |
+
**kwargs,
|
| 306 |
+
)
|
| 307 |
+
|
| 308 |
+
if voice_preset is not None:
|
| 309 |
+
encoded_text["history_prompt"] = voice_preset
|
| 310 |
+
|
| 311 |
+
return encoded_text
|
| 312 |
+
|
| 313 |
+
|
| 314 |
+
__all__ = ["BarkProcessor"]
|
third_party/transformers/src/transformers/models/bart/__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 ..roberta.tokenization_roberta import RobertaTokenizer as BartTokenizer
|
| 22 |
+
from .configuration_bart import *
|
| 23 |
+
from .modeling_bart 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/bart/configuration_bart.py
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright 2021 The Fairseq 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 |
+
"""BART 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="facebook/bart-large")
|
| 23 |
+
@strict
|
| 24 |
+
class BartConfig(PreTrainedConfig):
|
| 25 |
+
r"""
|
| 26 |
+
Example:
|
| 27 |
+
|
| 28 |
+
```python
|
| 29 |
+
>>> from transformers import BartConfig, BartModel
|
| 30 |
+
|
| 31 |
+
>>> # Initializing a BART facebook/bart-large style configuration
|
| 32 |
+
>>> configuration = BartConfig()
|
| 33 |
+
|
| 34 |
+
>>> # Initializing a model (with random weights) from the facebook/bart-large style configuration
|
| 35 |
+
>>> model = BartModel(configuration)
|
| 36 |
+
|
| 37 |
+
>>> # Accessing the model configuration
|
| 38 |
+
>>> configuration = model.config
|
| 39 |
+
```"""
|
| 40 |
+
|
| 41 |
+
model_type = "bart"
|
| 42 |
+
keys_to_ignore_at_inference = ["past_key_values"]
|
| 43 |
+
attribute_map = {
|
| 44 |
+
"num_attention_heads": "encoder_attention_heads",
|
| 45 |
+
"hidden_size": "d_model",
|
| 46 |
+
"num_hidden_layers": "encoder_layers",
|
| 47 |
+
}
|
| 48 |
+
|
| 49 |
+
vocab_size: int = 50265
|
| 50 |
+
max_position_embeddings: int = 1024
|
| 51 |
+
encoder_layers: int | None = 12
|
| 52 |
+
encoder_ffn_dim: int | None = 4096
|
| 53 |
+
encoder_attention_heads: int | None = 16
|
| 54 |
+
decoder_layers: int | None = 12
|
| 55 |
+
decoder_ffn_dim: int | None = 4096
|
| 56 |
+
decoder_attention_heads: int | None = 16
|
| 57 |
+
encoder_layerdrop: float | None = 0.0
|
| 58 |
+
decoder_layerdrop: float | None = 0.0
|
| 59 |
+
activation_function: str | None = "gelu"
|
| 60 |
+
d_model: int | None = 1024
|
| 61 |
+
dropout: float | int | None = 0.1
|
| 62 |
+
attention_dropout: float | int | None = 0.0
|
| 63 |
+
activation_dropout: float | int | None = 0.0
|
| 64 |
+
init_std: float | None = 0.02
|
| 65 |
+
classifier_dropout: float | int | None = 0.0
|
| 66 |
+
scale_embedding: bool | None = False
|
| 67 |
+
use_cache: bool = True
|
| 68 |
+
pad_token_id: int | None = 1
|
| 69 |
+
bos_token_id: int | None = 0
|
| 70 |
+
eos_token_id: int | list[int] | None = 2
|
| 71 |
+
is_encoder_decoder: bool | None = True
|
| 72 |
+
decoder_start_token_id: int | None = 2
|
| 73 |
+
forced_eos_token_id: int | list[int] | None = 2
|
| 74 |
+
is_decoder: bool | None = False
|
| 75 |
+
tie_word_embeddings: bool = True
|
| 76 |
+
|
| 77 |
+
def __post_init__(self, **kwargs):
|
| 78 |
+
# Set the default `num_labels` only if `id2label` is not
|
| 79 |
+
# yet set, i.e. user didn't pass `id2label/lable2id` in kwargs
|
| 80 |
+
if self.id2label is None:
|
| 81 |
+
self.num_labels = kwargs.pop("num_labels", 3)
|
| 82 |
+
|
| 83 |
+
super().__post_init__(**kwargs)
|
| 84 |
+
|
| 85 |
+
|
| 86 |
+
__all__ = ["BartConfig"]
|
third_party/transformers/src/transformers/models/bart/convert_bart_original_pytorch_checkpoint_to_pytorch.py
ADDED
|
@@ -0,0 +1,155 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright 2020 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 BART checkpoint."""
|
| 15 |
+
|
| 16 |
+
import argparse
|
| 17 |
+
import os
|
| 18 |
+
from pathlib import Path
|
| 19 |
+
|
| 20 |
+
import fairseq
|
| 21 |
+
import torch
|
| 22 |
+
from packaging import version
|
| 23 |
+
from torch import nn
|
| 24 |
+
|
| 25 |
+
from transformers import (
|
| 26 |
+
BartConfig,
|
| 27 |
+
BartForConditionalGeneration,
|
| 28 |
+
BartForSequenceClassification,
|
| 29 |
+
BartModel,
|
| 30 |
+
BartTokenizer,
|
| 31 |
+
)
|
| 32 |
+
from transformers.utils import logging
|
| 33 |
+
|
| 34 |
+
|
| 35 |
+
FAIRSEQ_MODELS = ["bart.large", "bart.large.mnli", "bart.large.cnn", "bart_xsum/model.pt"]
|
| 36 |
+
extra_arch = {"bart.large": BartModel, "bart.large.mnli": BartForSequenceClassification}
|
| 37 |
+
if version.parse(fairseq.__version__) < version.parse("0.9.0"):
|
| 38 |
+
raise Exception("requires fairseq >= 0.9.0")
|
| 39 |
+
|
| 40 |
+
|
| 41 |
+
logging.set_verbosity_info()
|
| 42 |
+
logger = logging.get_logger(__name__)
|
| 43 |
+
|
| 44 |
+
SAMPLE_TEXT = " Hello world! cécé herlolip"
|
| 45 |
+
|
| 46 |
+
mnli_rename_keys = [
|
| 47 |
+
("model.classification_heads.mnli.dense.weight", "classification_head.dense.weight"),
|
| 48 |
+
("model.classification_heads.mnli.dense.bias", "classification_head.dense.bias"),
|
| 49 |
+
("model.classification_heads.mnli.out_proj.weight", "classification_head.out_proj.weight"),
|
| 50 |
+
("model.classification_heads.mnli.out_proj.bias", "classification_head.out_proj.bias"),
|
| 51 |
+
]
|
| 52 |
+
|
| 53 |
+
|
| 54 |
+
def remove_ignore_keys_(state_dict):
|
| 55 |
+
ignore_keys = [
|
| 56 |
+
"encoder.version",
|
| 57 |
+
"decoder.version",
|
| 58 |
+
"model.encoder.version",
|
| 59 |
+
"model.decoder.version",
|
| 60 |
+
"_float_tensor",
|
| 61 |
+
]
|
| 62 |
+
for k in ignore_keys:
|
| 63 |
+
state_dict.pop(k, None)
|
| 64 |
+
|
| 65 |
+
|
| 66 |
+
def rename_key(dct, old, new):
|
| 67 |
+
val = dct.pop(old)
|
| 68 |
+
dct[new] = val
|
| 69 |
+
|
| 70 |
+
|
| 71 |
+
def load_xsum_checkpoint(checkpoint_path):
|
| 72 |
+
"""Checkpoint path should end in model.pt"""
|
| 73 |
+
sd = torch.load(checkpoint_path, map_location="cpu", weights_only=True)
|
| 74 |
+
hub_interface = torch.hub.load("pytorch/fairseq", "bart.large.cnn").eval()
|
| 75 |
+
hub_interface.model.load_state_dict(sd["model"])
|
| 76 |
+
return hub_interface
|
| 77 |
+
|
| 78 |
+
|
| 79 |
+
def make_linear_from_emb(emb):
|
| 80 |
+
vocab_size, emb_size = emb.weight.shape
|
| 81 |
+
lin_layer = nn.Linear(vocab_size, emb_size, bias=False)
|
| 82 |
+
lin_layer.weight.data = emb.weight.data
|
| 83 |
+
return lin_layer
|
| 84 |
+
|
| 85 |
+
|
| 86 |
+
@torch.no_grad()
|
| 87 |
+
def convert_bart_checkpoint(checkpoint_path, pytorch_dump_folder_path, hf_checkpoint_name=None):
|
| 88 |
+
"""
|
| 89 |
+
Copy/paste/tweak model's weights to our BERT structure.
|
| 90 |
+
"""
|
| 91 |
+
if not os.path.exists(checkpoint_path):
|
| 92 |
+
bart = torch.hub.load("pytorch/fairseq", checkpoint_path).eval()
|
| 93 |
+
else:
|
| 94 |
+
bart = load_xsum_checkpoint(checkpoint_path)
|
| 95 |
+
|
| 96 |
+
bart.model.upgrade_state_dict(bart.model.state_dict())
|
| 97 |
+
if hf_checkpoint_name is None:
|
| 98 |
+
hf_checkpoint_name = checkpoint_path.replace(".", "-")
|
| 99 |
+
config = BartConfig.from_pretrained(hf_checkpoint_name)
|
| 100 |
+
tokens = bart.encode(SAMPLE_TEXT).unsqueeze(0)
|
| 101 |
+
tokens2 = BartTokenizer.from_pretrained(hf_checkpoint_name).encode(SAMPLE_TEXT, return_tensors="pt").unsqueeze(0)
|
| 102 |
+
if not torch.eq(tokens, tokens2).all():
|
| 103 |
+
raise ValueError(
|
| 104 |
+
f"converted tokenizer and pretrained tokenizer returned different output: {tokens} != {tokens2}"
|
| 105 |
+
)
|
| 106 |
+
|
| 107 |
+
if checkpoint_path == "bart.large.mnli":
|
| 108 |
+
state_dict = bart.state_dict()
|
| 109 |
+
remove_ignore_keys_(state_dict)
|
| 110 |
+
state_dict["model.shared.weight"] = state_dict["model.decoder.embed_tokens.weight"]
|
| 111 |
+
for src, dest in mnli_rename_keys:
|
| 112 |
+
rename_key(state_dict, src, dest)
|
| 113 |
+
model = BartForSequenceClassification(config).eval()
|
| 114 |
+
model.load_state_dict(state_dict)
|
| 115 |
+
fairseq_output = bart.predict("mnli", tokens, return_logits=True)
|
| 116 |
+
new_model_outputs = model(tokens)[0] # logits
|
| 117 |
+
else: # no classification heads to worry about
|
| 118 |
+
state_dict = bart.model.state_dict()
|
| 119 |
+
remove_ignore_keys_(state_dict)
|
| 120 |
+
state_dict["shared.weight"] = state_dict["decoder.embed_tokens.weight"]
|
| 121 |
+
fairseq_output = bart.extract_features(tokens)
|
| 122 |
+
if hf_checkpoint_name == "facebook/bart-large":
|
| 123 |
+
model = BartModel(config).eval()
|
| 124 |
+
model.load_state_dict(state_dict)
|
| 125 |
+
new_model_outputs = model(tokens).model[0]
|
| 126 |
+
else:
|
| 127 |
+
model = BartForConditionalGeneration(config).eval() # an existing summarization ckpt
|
| 128 |
+
model.model.load_state_dict(state_dict)
|
| 129 |
+
if hasattr(model, "lm_head"):
|
| 130 |
+
model.lm_head = make_linear_from_emb(model.model.shared)
|
| 131 |
+
new_model_outputs = model.model(tokens)[0]
|
| 132 |
+
|
| 133 |
+
# Check results
|
| 134 |
+
if fairseq_output.shape != new_model_outputs.shape:
|
| 135 |
+
raise ValueError(
|
| 136 |
+
f"`fairseq_output` shape and `new_model_output` shape are different: {fairseq_output.shape=}, {new_model_outputs.shape}"
|
| 137 |
+
)
|
| 138 |
+
if (fairseq_output != new_model_outputs).any().item():
|
| 139 |
+
raise ValueError("Some values in `fairseq_output` are different from `new_model_outputs`")
|
| 140 |
+
Path(pytorch_dump_folder_path).mkdir(exist_ok=True)
|
| 141 |
+
model.save_pretrained(pytorch_dump_folder_path)
|
| 142 |
+
|
| 143 |
+
|
| 144 |
+
if __name__ == "__main__":
|
| 145 |
+
parser = argparse.ArgumentParser()
|
| 146 |
+
# Required parameters
|
| 147 |
+
parser.add_argument(
|
| 148 |
+
"fairseq_path", type=str, help="bart.large, bart.large.cnn or a path to a model.pt on local filesystem."
|
| 149 |
+
)
|
| 150 |
+
parser.add_argument("pytorch_dump_folder_path", default=None, type=str, help="Path to the output PyTorch model.")
|
| 151 |
+
parser.add_argument(
|
| 152 |
+
"--hf_config", default=None, type=str, help="Which huggingface architecture to use: bart-large-xsum"
|
| 153 |
+
)
|
| 154 |
+
args = parser.parse_args()
|
| 155 |
+
convert_bart_checkpoint(args.fairseq_path, args.pytorch_dump_folder_path, hf_checkpoint_name=args.hf_config)
|
third_party/transformers/src/transformers/models/bart/modeling_bart.py
ADDED
|
@@ -0,0 +1,1322 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright 2021 The Fairseq 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 |
+
"""PyTorch BART model."""
|
| 15 |
+
|
| 16 |
+
import math
|
| 17 |
+
import warnings
|
| 18 |
+
from collections.abc import Callable
|
| 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 ...cache_utils import Cache, DynamicCache, EncoderDecoderCache
|
| 27 |
+
from ...generation import GenerationMixin
|
| 28 |
+
from ...masking_utils import create_bidirectional_mask, create_causal_mask
|
| 29 |
+
from ...modeling_flash_attention_utils import FlashAttentionKwargs
|
| 30 |
+
from ...modeling_layers import GradientCheckpointingLayer
|
| 31 |
+
from ...modeling_outputs import (
|
| 32 |
+
BaseModelOutput,
|
| 33 |
+
BaseModelOutputWithPastAndCrossAttentions,
|
| 34 |
+
CausalLMOutputWithCrossAttentions,
|
| 35 |
+
Seq2SeqLMOutput,
|
| 36 |
+
Seq2SeqModelOutput,
|
| 37 |
+
Seq2SeqQuestionAnsweringModelOutput,
|
| 38 |
+
Seq2SeqSequenceClassifierOutput,
|
| 39 |
+
)
|
| 40 |
+
from ...modeling_utils import ALL_ATTENTION_FUNCTIONS, PreTrainedModel
|
| 41 |
+
from ...processing_utils import Unpack
|
| 42 |
+
from ...utils import (
|
| 43 |
+
TransformersKwargs,
|
| 44 |
+
auto_docstring,
|
| 45 |
+
can_return_tuple,
|
| 46 |
+
is_torchdynamo_compiling,
|
| 47 |
+
logging,
|
| 48 |
+
torch_compilable_check,
|
| 49 |
+
)
|
| 50 |
+
from ...utils.generic import merge_with_config_defaults
|
| 51 |
+
from ...utils.output_capturing import OutputRecorder, capture_outputs
|
| 52 |
+
from .configuration_bart import BartConfig
|
| 53 |
+
|
| 54 |
+
|
| 55 |
+
logger = logging.get_logger(__name__)
|
| 56 |
+
|
| 57 |
+
|
| 58 |
+
def shift_tokens_right(input_ids: torch.Tensor, pad_token_id: int, decoder_start_token_id: int):
|
| 59 |
+
"""
|
| 60 |
+
Shift input ids one token to the right.
|
| 61 |
+
"""
|
| 62 |
+
shifted_input_ids = input_ids.new_zeros(input_ids.shape)
|
| 63 |
+
shifted_input_ids[:, 1:] = input_ids[:, :-1].clone()
|
| 64 |
+
shifted_input_ids[:, 0] = decoder_start_token_id
|
| 65 |
+
|
| 66 |
+
if pad_token_id is None:
|
| 67 |
+
raise ValueError("self.model.config.pad_token_id has to be defined.")
|
| 68 |
+
# replace possible -100 values in labels by `pad_token_id`
|
| 69 |
+
shifted_input_ids.masked_fill_(shifted_input_ids == -100, pad_token_id)
|
| 70 |
+
|
| 71 |
+
return shifted_input_ids
|
| 72 |
+
|
| 73 |
+
|
| 74 |
+
class BartLearnedPositionalEmbedding(nn.Embedding):
|
| 75 |
+
"""
|
| 76 |
+
This module learns positional embeddings up to a fixed maximum size.
|
| 77 |
+
"""
|
| 78 |
+
|
| 79 |
+
def __init__(self, num_embeddings: int, embedding_dim: int):
|
| 80 |
+
# Bart is set up so that if padding_idx is specified then offset the embedding ids by 2
|
| 81 |
+
# and adjust num_embeddings appropriately. Other models don't have this hack
|
| 82 |
+
self.offset = 2
|
| 83 |
+
super().__init__(num_embeddings + self.offset, embedding_dim)
|
| 84 |
+
|
| 85 |
+
def forward(
|
| 86 |
+
self, input_ids: torch.Tensor, past_key_values_length: int = 0, position_ids: torch.Tensor | None = None
|
| 87 |
+
):
|
| 88 |
+
"""`input_ids' shape is expected to be [bsz x seqlen]."""
|
| 89 |
+
|
| 90 |
+
if position_ids is None:
|
| 91 |
+
bsz, seq_len = input_ids.shape[:2]
|
| 92 |
+
position_ids = torch.arange(
|
| 93 |
+
past_key_values_length, past_key_values_length + seq_len, dtype=torch.long, device=self.weight.device
|
| 94 |
+
).expand(bsz, -1)
|
| 95 |
+
else:
|
| 96 |
+
position_ids = position_ids.unsqueeze(0)
|
| 97 |
+
|
| 98 |
+
return super().forward(position_ids + self.offset)
|
| 99 |
+
|
| 100 |
+
|
| 101 |
+
class BartScaledWordEmbedding(nn.Embedding):
|
| 102 |
+
"""
|
| 103 |
+
This module overrides nn.Embeddings' forward by multiplying with embeddings scale.
|
| 104 |
+
"""
|
| 105 |
+
|
| 106 |
+
def __init__(self, num_embeddings: int, embedding_dim: int, padding_idx: int, embed_scale: float | None = 1.0):
|
| 107 |
+
super().__init__(num_embeddings, embedding_dim, padding_idx)
|
| 108 |
+
self.embed_scale = embed_scale
|
| 109 |
+
|
| 110 |
+
def forward(self, input_ids: torch.Tensor):
|
| 111 |
+
return super().forward(input_ids) * self.embed_scale
|
| 112 |
+
|
| 113 |
+
|
| 114 |
+
# Copied from transformers.models.bert.modeling_bert.eager_attention_forward
|
| 115 |
+
def eager_attention_forward(
|
| 116 |
+
module: nn.Module,
|
| 117 |
+
query: torch.Tensor,
|
| 118 |
+
key: torch.Tensor,
|
| 119 |
+
value: torch.Tensor,
|
| 120 |
+
attention_mask: torch.Tensor | None,
|
| 121 |
+
scaling: float | None = None,
|
| 122 |
+
dropout: float = 0.0,
|
| 123 |
+
**kwargs: Unpack[TransformersKwargs],
|
| 124 |
+
):
|
| 125 |
+
if scaling is None:
|
| 126 |
+
scaling = query.size(-1) ** -0.5
|
| 127 |
+
|
| 128 |
+
# Take the dot product between "query" and "key" to get the raw attention scores.
|
| 129 |
+
attn_weights = torch.matmul(query, key.transpose(2, 3)) * scaling
|
| 130 |
+
|
| 131 |
+
if attention_mask is not None:
|
| 132 |
+
attn_weights = attn_weights + attention_mask
|
| 133 |
+
|
| 134 |
+
attn_weights = nn.functional.softmax(attn_weights, dim=-1)
|
| 135 |
+
attn_weights = nn.functional.dropout(attn_weights, p=dropout, training=module.training)
|
| 136 |
+
|
| 137 |
+
attn_output = torch.matmul(attn_weights, value)
|
| 138 |
+
attn_output = attn_output.transpose(1, 2).contiguous()
|
| 139 |
+
|
| 140 |
+
return attn_output, attn_weights
|
| 141 |
+
|
| 142 |
+
|
| 143 |
+
class BartAttention(nn.Module):
|
| 144 |
+
"""Multi-headed attention from 'Attention Is All You Need' paper"""
|
| 145 |
+
|
| 146 |
+
def __init__(
|
| 147 |
+
self,
|
| 148 |
+
embed_dim: int,
|
| 149 |
+
num_heads: int,
|
| 150 |
+
dropout: float = 0.0,
|
| 151 |
+
is_decoder: bool = False,
|
| 152 |
+
bias: bool = True,
|
| 153 |
+
is_causal: bool = False,
|
| 154 |
+
config: BartConfig | None = None,
|
| 155 |
+
layer_idx: int | None = None,
|
| 156 |
+
):
|
| 157 |
+
super().__init__()
|
| 158 |
+
self.embed_dim = embed_dim
|
| 159 |
+
self.num_heads = num_heads
|
| 160 |
+
self.dropout = dropout
|
| 161 |
+
self.head_dim = embed_dim // num_heads
|
| 162 |
+
self.config = config
|
| 163 |
+
|
| 164 |
+
if (self.head_dim * num_heads) != self.embed_dim:
|
| 165 |
+
raise ValueError(
|
| 166 |
+
f"embed_dim must be divisible by num_heads (got `embed_dim`: {self.embed_dim}"
|
| 167 |
+
f" and `num_heads`: {num_heads})."
|
| 168 |
+
)
|
| 169 |
+
self.scaling = self.head_dim**-0.5
|
| 170 |
+
self.is_decoder = is_decoder
|
| 171 |
+
self.is_causal = is_causal
|
| 172 |
+
self.layer_idx = layer_idx
|
| 173 |
+
if layer_idx is None and self.is_decoder:
|
| 174 |
+
logger.warning_once(
|
| 175 |
+
f"Instantiating a decoder {self.__class__.__name__} without passing `layer_idx` is not recommended and "
|
| 176 |
+
"will lead to errors during the forward call, if caching is used. Please make sure to provide a `layer_idx` "
|
| 177 |
+
"when creating this class."
|
| 178 |
+
)
|
| 179 |
+
|
| 180 |
+
self.k_proj = nn.Linear(embed_dim, embed_dim, bias=bias)
|
| 181 |
+
self.v_proj = nn.Linear(embed_dim, embed_dim, bias=bias)
|
| 182 |
+
self.q_proj = nn.Linear(embed_dim, embed_dim, bias=bias)
|
| 183 |
+
self.out_proj = nn.Linear(embed_dim, embed_dim, bias=bias)
|
| 184 |
+
|
| 185 |
+
def forward(
|
| 186 |
+
self,
|
| 187 |
+
hidden_states: torch.Tensor,
|
| 188 |
+
key_value_states: torch.Tensor | None = None,
|
| 189 |
+
past_key_values: Cache | None = None,
|
| 190 |
+
attention_mask: torch.Tensor | None = None,
|
| 191 |
+
# TODO: we need a refactor so that the different attention modules can get their specific kwargs
|
| 192 |
+
# ATM, we have mixed things encoder, decoder, and encoder-decoder attn
|
| 193 |
+
**kwargs: Unpack[FlashAttentionKwargs],
|
| 194 |
+
) -> tuple[torch.Tensor, torch.Tensor | None]:
|
| 195 |
+
"""Input shape: Batch x Time x Channel"""
|
| 196 |
+
|
| 197 |
+
# if key_value_states are provided this layer is used as a cross-attention layer
|
| 198 |
+
# for the decoder
|
| 199 |
+
is_cross_attention = key_value_states is not None
|
| 200 |
+
|
| 201 |
+
# determine input shapes
|
| 202 |
+
bsz, tgt_len = hidden_states.shape[:-1]
|
| 203 |
+
src_len = key_value_states.shape[1] if is_cross_attention else tgt_len
|
| 204 |
+
|
| 205 |
+
q_input_shape = (bsz, tgt_len, -1, self.head_dim)
|
| 206 |
+
kv_input_shape = (bsz, src_len, -1, self.head_dim)
|
| 207 |
+
|
| 208 |
+
# get query proj
|
| 209 |
+
query_states = self.q_proj(hidden_states).view(*q_input_shape).transpose(1, 2)
|
| 210 |
+
|
| 211 |
+
is_updated = False
|
| 212 |
+
if past_key_values is not None:
|
| 213 |
+
if isinstance(past_key_values, EncoderDecoderCache):
|
| 214 |
+
is_updated = past_key_values.is_updated.get(self.layer_idx)
|
| 215 |
+
if is_cross_attention:
|
| 216 |
+
# after the first generated id, we can subsequently re-use all key/value_states from cache
|
| 217 |
+
curr_past_key_values = past_key_values.cross_attention_cache
|
| 218 |
+
else:
|
| 219 |
+
curr_past_key_values = past_key_values.self_attention_cache
|
| 220 |
+
else:
|
| 221 |
+
curr_past_key_values = past_key_values
|
| 222 |
+
|
| 223 |
+
current_states = key_value_states if is_cross_attention else hidden_states
|
| 224 |
+
if is_cross_attention and past_key_values is not None and is_updated:
|
| 225 |
+
# reuse k,v, cross_attentions
|
| 226 |
+
key_states = curr_past_key_values.layers[self.layer_idx].keys
|
| 227 |
+
value_states = curr_past_key_values.layers[self.layer_idx].values
|
| 228 |
+
else:
|
| 229 |
+
key_states = self.k_proj(current_states)
|
| 230 |
+
value_states = self.v_proj(current_states)
|
| 231 |
+
key_states = key_states.view(*kv_input_shape).transpose(1, 2)
|
| 232 |
+
value_states = value_states.view(*kv_input_shape).transpose(1, 2)
|
| 233 |
+
|
| 234 |
+
if past_key_values is not None:
|
| 235 |
+
key_states, value_states = curr_past_key_values.update(key_states, value_states, self.layer_idx)
|
| 236 |
+
# set flag that curr layer for cross-attn is already updated so we can re-use in subsequent calls
|
| 237 |
+
if is_cross_attention and isinstance(past_key_values, EncoderDecoderCache):
|
| 238 |
+
past_key_values.is_updated[self.layer_idx] = True
|
| 239 |
+
|
| 240 |
+
attention_interface: Callable = ALL_ATTENTION_FUNCTIONS.get_interface(
|
| 241 |
+
self.config._attn_implementation, eager_attention_forward
|
| 242 |
+
)
|
| 243 |
+
|
| 244 |
+
attn_output, attn_weights = attention_interface(
|
| 245 |
+
self,
|
| 246 |
+
query_states,
|
| 247 |
+
key_states,
|
| 248 |
+
value_states,
|
| 249 |
+
attention_mask,
|
| 250 |
+
dropout=0.0 if not self.training else self.dropout,
|
| 251 |
+
scaling=self.scaling,
|
| 252 |
+
**kwargs,
|
| 253 |
+
)
|
| 254 |
+
|
| 255 |
+
attn_output = attn_output.reshape(bsz, tgt_len, -1).contiguous()
|
| 256 |
+
attn_output = self.out_proj(attn_output)
|
| 257 |
+
|
| 258 |
+
return attn_output, attn_weights
|
| 259 |
+
|
| 260 |
+
|
| 261 |
+
class BartEncoderLayer(GradientCheckpointingLayer):
|
| 262 |
+
def __init__(self, config: BartConfig, layer_idx: int | None = None):
|
| 263 |
+
super().__init__()
|
| 264 |
+
self.embed_dim = config.d_model
|
| 265 |
+
|
| 266 |
+
self.self_attn = BartAttention(
|
| 267 |
+
embed_dim=self.embed_dim,
|
| 268 |
+
num_heads=config.encoder_attention_heads,
|
| 269 |
+
dropout=config.attention_dropout,
|
| 270 |
+
config=config,
|
| 271 |
+
layer_idx=layer_idx,
|
| 272 |
+
)
|
| 273 |
+
self.self_attn_layer_norm = nn.LayerNorm(self.embed_dim)
|
| 274 |
+
self.dropout = config.dropout
|
| 275 |
+
self.activation_fn = ACT2FN[config.activation_function]
|
| 276 |
+
self.activation_dropout = config.activation_dropout
|
| 277 |
+
self.fc1 = nn.Linear(self.embed_dim, config.encoder_ffn_dim)
|
| 278 |
+
self.fc2 = nn.Linear(config.encoder_ffn_dim, self.embed_dim)
|
| 279 |
+
self.final_layer_norm = nn.LayerNorm(self.embed_dim)
|
| 280 |
+
|
| 281 |
+
def forward(
|
| 282 |
+
self,
|
| 283 |
+
hidden_states: torch.FloatTensor,
|
| 284 |
+
attention_mask: torch.FloatTensor,
|
| 285 |
+
**kwargs: Unpack[TransformersKwargs],
|
| 286 |
+
) -> torch.Tensor:
|
| 287 |
+
residual = hidden_states
|
| 288 |
+
hidden_states, _ = self.self_attn(
|
| 289 |
+
hidden_states,
|
| 290 |
+
attention_mask=attention_mask,
|
| 291 |
+
**kwargs,
|
| 292 |
+
)
|
| 293 |
+
hidden_states = nn.functional.dropout(hidden_states, p=self.dropout, training=self.training)
|
| 294 |
+
hidden_states = residual + hidden_states
|
| 295 |
+
hidden_states = self.self_attn_layer_norm(hidden_states)
|
| 296 |
+
|
| 297 |
+
residual = hidden_states
|
| 298 |
+
hidden_states = self.activation_fn(self.fc1(hidden_states))
|
| 299 |
+
hidden_states = nn.functional.dropout(hidden_states, p=self.activation_dropout, training=self.training)
|
| 300 |
+
hidden_states = self.fc2(hidden_states)
|
| 301 |
+
hidden_states = nn.functional.dropout(hidden_states, p=self.dropout, training=self.training)
|
| 302 |
+
hidden_states = residual + hidden_states
|
| 303 |
+
hidden_states = self.final_layer_norm(hidden_states)
|
| 304 |
+
|
| 305 |
+
if hidden_states.dtype == torch.float16 and not torch.isfinite(hidden_states).all():
|
| 306 |
+
clamp_value = torch.finfo(hidden_states.dtype).max - 1000
|
| 307 |
+
hidden_states = torch.clamp(hidden_states, min=-clamp_value, max=clamp_value)
|
| 308 |
+
|
| 309 |
+
return hidden_states
|
| 310 |
+
|
| 311 |
+
|
| 312 |
+
class BartDecoderLayer(GradientCheckpointingLayer):
|
| 313 |
+
def __init__(self, config: BartConfig, layer_idx: int | None = None):
|
| 314 |
+
super().__init__()
|
| 315 |
+
self.embed_dim = config.d_model
|
| 316 |
+
|
| 317 |
+
self.self_attn = BartAttention(
|
| 318 |
+
embed_dim=self.embed_dim,
|
| 319 |
+
num_heads=config.decoder_attention_heads,
|
| 320 |
+
dropout=config.attention_dropout,
|
| 321 |
+
is_decoder=True,
|
| 322 |
+
is_causal=True,
|
| 323 |
+
config=config,
|
| 324 |
+
layer_idx=layer_idx,
|
| 325 |
+
)
|
| 326 |
+
self.dropout = config.dropout
|
| 327 |
+
self.activation_fn = ACT2FN[config.activation_function]
|
| 328 |
+
self.activation_dropout = config.activation_dropout
|
| 329 |
+
|
| 330 |
+
self.self_attn_layer_norm = nn.LayerNorm(self.embed_dim)
|
| 331 |
+
self.encoder_attn = BartAttention(
|
| 332 |
+
self.embed_dim,
|
| 333 |
+
config.decoder_attention_heads,
|
| 334 |
+
dropout=config.attention_dropout,
|
| 335 |
+
is_decoder=True,
|
| 336 |
+
config=config,
|
| 337 |
+
layer_idx=layer_idx,
|
| 338 |
+
)
|
| 339 |
+
self.encoder_attn_layer_norm = nn.LayerNorm(self.embed_dim)
|
| 340 |
+
self.fc1 = nn.Linear(self.embed_dim, config.decoder_ffn_dim)
|
| 341 |
+
self.fc2 = nn.Linear(config.decoder_ffn_dim, self.embed_dim)
|
| 342 |
+
self.final_layer_norm = nn.LayerNorm(self.embed_dim)
|
| 343 |
+
|
| 344 |
+
def forward(
|
| 345 |
+
self,
|
| 346 |
+
hidden_states: torch.Tensor,
|
| 347 |
+
attention_mask: torch.Tensor | None = None,
|
| 348 |
+
encoder_hidden_states: torch.Tensor | None = None,
|
| 349 |
+
encoder_attention_mask: torch.Tensor | None = None,
|
| 350 |
+
past_key_values: Cache | None = None,
|
| 351 |
+
use_cache: bool | None = True,
|
| 352 |
+
**kwargs: Unpack[TransformersKwargs],
|
| 353 |
+
) -> torch.Tensor:
|
| 354 |
+
residual = hidden_states
|
| 355 |
+
|
| 356 |
+
# Self Attention
|
| 357 |
+
hidden_states, _ = self.self_attn(
|
| 358 |
+
hidden_states,
|
| 359 |
+
past_key_values=past_key_values,
|
| 360 |
+
attention_mask=attention_mask,
|
| 361 |
+
**kwargs,
|
| 362 |
+
)
|
| 363 |
+
hidden_states = nn.functional.dropout(hidden_states, p=self.dropout, training=self.training)
|
| 364 |
+
hidden_states = residual + hidden_states
|
| 365 |
+
hidden_states = self.self_attn_layer_norm(hidden_states)
|
| 366 |
+
|
| 367 |
+
# Cross-Attention Block
|
| 368 |
+
if encoder_hidden_states is not None:
|
| 369 |
+
residual = hidden_states
|
| 370 |
+
|
| 371 |
+
hidden_states, _ = self.encoder_attn(
|
| 372 |
+
hidden_states,
|
| 373 |
+
key_value_states=encoder_hidden_states,
|
| 374 |
+
attention_mask=encoder_attention_mask,
|
| 375 |
+
past_key_values=past_key_values,
|
| 376 |
+
**kwargs,
|
| 377 |
+
)
|
| 378 |
+
hidden_states = nn.functional.dropout(hidden_states, p=self.dropout, training=self.training)
|
| 379 |
+
hidden_states = residual + hidden_states
|
| 380 |
+
hidden_states = self.encoder_attn_layer_norm(hidden_states)
|
| 381 |
+
|
| 382 |
+
# Fully Connected
|
| 383 |
+
residual = hidden_states
|
| 384 |
+
hidden_states = self.activation_fn(self.fc1(hidden_states))
|
| 385 |
+
hidden_states = nn.functional.dropout(hidden_states, p=self.activation_dropout, training=self.training)
|
| 386 |
+
hidden_states = self.fc2(hidden_states)
|
| 387 |
+
hidden_states = nn.functional.dropout(hidden_states, p=self.dropout, training=self.training)
|
| 388 |
+
hidden_states = residual + hidden_states
|
| 389 |
+
hidden_states = self.final_layer_norm(hidden_states)
|
| 390 |
+
|
| 391 |
+
return hidden_states
|
| 392 |
+
|
| 393 |
+
|
| 394 |
+
class BartClassificationHead(nn.Module):
|
| 395 |
+
"""Head for sentence-level classification tasks."""
|
| 396 |
+
|
| 397 |
+
def __init__(
|
| 398 |
+
self,
|
| 399 |
+
input_dim: int,
|
| 400 |
+
inner_dim: int,
|
| 401 |
+
num_classes: int,
|
| 402 |
+
pooler_dropout: float,
|
| 403 |
+
):
|
| 404 |
+
super().__init__()
|
| 405 |
+
self.dense = nn.Linear(input_dim, inner_dim)
|
| 406 |
+
self.dropout = nn.Dropout(p=pooler_dropout)
|
| 407 |
+
self.out_proj = nn.Linear(inner_dim, num_classes)
|
| 408 |
+
|
| 409 |
+
def forward(self, hidden_states: torch.Tensor) -> torch.Tensor:
|
| 410 |
+
hidden_states = self.dropout(hidden_states)
|
| 411 |
+
hidden_states = self.dense(hidden_states)
|
| 412 |
+
hidden_states = torch.tanh(hidden_states)
|
| 413 |
+
hidden_states = self.dropout(hidden_states)
|
| 414 |
+
hidden_states = self.out_proj(hidden_states)
|
| 415 |
+
return hidden_states
|
| 416 |
+
|
| 417 |
+
|
| 418 |
+
@auto_docstring
|
| 419 |
+
class BartPreTrainedModel(PreTrainedModel):
|
| 420 |
+
config: BartConfig
|
| 421 |
+
base_model_prefix = "model"
|
| 422 |
+
supports_gradient_checkpointing = True
|
| 423 |
+
_keys_to_ignore_on_load_unexpected = ["encoder.version", "decoder.version"]
|
| 424 |
+
_no_split_modules = [r"BartEncoderLayer", r"BartDecoderLayer"]
|
| 425 |
+
_skip_keys_device_placement = "past_key_values"
|
| 426 |
+
_supports_flash_attn = True
|
| 427 |
+
_supports_sdpa = True
|
| 428 |
+
_supports_flex_attn = True
|
| 429 |
+
|
| 430 |
+
_can_compile_fullgraph = True
|
| 431 |
+
|
| 432 |
+
def _init_weights(self, module):
|
| 433 |
+
super()._init_weights(module)
|
| 434 |
+
if isinstance(module, BartForConditionalGeneration):
|
| 435 |
+
init.zeros_(module.final_logits_bias)
|
| 436 |
+
|
| 437 |
+
@property
|
| 438 |
+
def dummy_inputs(self):
|
| 439 |
+
pad_token = self.config.pad_token_id
|
| 440 |
+
input_ids = torch.tensor([[0, 6, 10, 4, 2], [0, 8, 12, 2, pad_token]], device=self.device)
|
| 441 |
+
dummy_inputs = {
|
| 442 |
+
"attention_mask": input_ids.ne(pad_token),
|
| 443 |
+
"input_ids": input_ids,
|
| 444 |
+
}
|
| 445 |
+
return dummy_inputs
|
| 446 |
+
|
| 447 |
+
|
| 448 |
+
class PretrainedBartModel(BartPreTrainedModel):
|
| 449 |
+
def __init_subclass__(self):
|
| 450 |
+
warnings.warn(
|
| 451 |
+
"The class `PretrainedBartModel` has been depreciated, please use `BartPreTrainedModel` instead.",
|
| 452 |
+
FutureWarning,
|
| 453 |
+
)
|
| 454 |
+
|
| 455 |
+
|
| 456 |
+
class BartPretrainedModel(BartPreTrainedModel):
|
| 457 |
+
def __init_subclass__(self):
|
| 458 |
+
warnings.warn(
|
| 459 |
+
"The class `PretrainedBartModel` has been depreciated, please use `BartPreTrainedModel` instead.",
|
| 460 |
+
FutureWarning,
|
| 461 |
+
)
|
| 462 |
+
|
| 463 |
+
|
| 464 |
+
class BartEncoder(BartPreTrainedModel):
|
| 465 |
+
"""
|
| 466 |
+
Transformer encoder consisting of *config.encoder_layers* self attention layers. Each layer is a
|
| 467 |
+
[`BartEncoderLayer`].
|
| 468 |
+
|
| 469 |
+
Args:
|
| 470 |
+
config: BartConfig
|
| 471 |
+
embed_tokens (nn.Embedding): output embedding
|
| 472 |
+
"""
|
| 473 |
+
|
| 474 |
+
_can_record_outputs = {
|
| 475 |
+
"hidden_states": BartEncoderLayer,
|
| 476 |
+
"attentions": BartAttention,
|
| 477 |
+
}
|
| 478 |
+
|
| 479 |
+
def __init__(self, config: BartConfig):
|
| 480 |
+
super().__init__(config)
|
| 481 |
+
|
| 482 |
+
self.dropout = config.dropout
|
| 483 |
+
self.layerdrop = config.encoder_layerdrop
|
| 484 |
+
|
| 485 |
+
embed_dim = config.d_model
|
| 486 |
+
self.padding_idx = config.pad_token_id
|
| 487 |
+
self.max_source_positions = config.max_position_embeddings
|
| 488 |
+
embed_scale = math.sqrt(embed_dim) if config.scale_embedding else 1.0
|
| 489 |
+
|
| 490 |
+
self.embed_tokens = BartScaledWordEmbedding(
|
| 491 |
+
config.vocab_size, embed_dim, self.padding_idx, embed_scale=embed_scale
|
| 492 |
+
)
|
| 493 |
+
|
| 494 |
+
self.embed_positions = BartLearnedPositionalEmbedding(
|
| 495 |
+
config.max_position_embeddings,
|
| 496 |
+
embed_dim,
|
| 497 |
+
)
|
| 498 |
+
self.layers = nn.ModuleList([BartEncoderLayer(config, layer_idx=i) for i in range(config.encoder_layers)])
|
| 499 |
+
self.layernorm_embedding = nn.LayerNorm(embed_dim)
|
| 500 |
+
|
| 501 |
+
self.gradient_checkpointing = False
|
| 502 |
+
# Initialize weights and apply final processing
|
| 503 |
+
self.post_init()
|
| 504 |
+
|
| 505 |
+
@merge_with_config_defaults
|
| 506 |
+
@capture_outputs
|
| 507 |
+
@auto_docstring
|
| 508 |
+
def forward(
|
| 509 |
+
self,
|
| 510 |
+
input_ids: torch.LongTensor | None = None,
|
| 511 |
+
attention_mask: torch.Tensor | None = None,
|
| 512 |
+
inputs_embeds: torch.FloatTensor | None = None,
|
| 513 |
+
**kwargs: Unpack[TransformersKwargs],
|
| 514 |
+
) -> BaseModelOutput:
|
| 515 |
+
if (input_ids is None) ^ (inputs_embeds is not None):
|
| 516 |
+
raise ValueError("You must specify exactly one of input_ids or inputs_embeds")
|
| 517 |
+
|
| 518 |
+
if inputs_embeds is None:
|
| 519 |
+
inputs_embeds = self.embed_tokens(input_ids)
|
| 520 |
+
|
| 521 |
+
embed_pos = self.embed_positions(inputs_embeds[:, :, -1]) # needed for the shape only
|
| 522 |
+
embed_pos = embed_pos.to(inputs_embeds.device)
|
| 523 |
+
|
| 524 |
+
hidden_states = inputs_embeds + embed_pos
|
| 525 |
+
hidden_states = self.layernorm_embedding(hidden_states)
|
| 526 |
+
hidden_states = nn.functional.dropout(hidden_states, p=self.dropout, training=self.training)
|
| 527 |
+
|
| 528 |
+
attention_mask = create_bidirectional_mask(
|
| 529 |
+
config=self.config,
|
| 530 |
+
inputs_embeds=inputs_embeds,
|
| 531 |
+
attention_mask=attention_mask,
|
| 532 |
+
)
|
| 533 |
+
for idx, encoder_layer in enumerate(self.layers):
|
| 534 |
+
# add LayerDrop (see https://huggingface.co/papers/1909.11556 for description)
|
| 535 |
+
to_drop = False
|
| 536 |
+
if self.training:
|
| 537 |
+
dropout_probability = torch.rand([])
|
| 538 |
+
if dropout_probability < self.layerdrop: # skip the layer
|
| 539 |
+
to_drop = True
|
| 540 |
+
|
| 541 |
+
if not to_drop:
|
| 542 |
+
hidden_states = encoder_layer(
|
| 543 |
+
hidden_states,
|
| 544 |
+
attention_mask,
|
| 545 |
+
**kwargs,
|
| 546 |
+
)
|
| 547 |
+
|
| 548 |
+
return BaseModelOutput(
|
| 549 |
+
last_hidden_state=hidden_states,
|
| 550 |
+
)
|
| 551 |
+
|
| 552 |
+
|
| 553 |
+
class BartDecoder(BartPreTrainedModel):
|
| 554 |
+
"""
|
| 555 |
+
Transformer decoder consisting of *config.decoder_layers* layers. Each layer is a [`BartDecoderLayer`]
|
| 556 |
+
|
| 557 |
+
Args:
|
| 558 |
+
config: BartConfig
|
| 559 |
+
embed_tokens (nn.Embedding): output embedding
|
| 560 |
+
"""
|
| 561 |
+
|
| 562 |
+
_can_record_outputs = {
|
| 563 |
+
"hidden_states": BartDecoderLayer,
|
| 564 |
+
"attentions": OutputRecorder(BartAttention, index=1, layer_name="self_attn"),
|
| 565 |
+
"cross_attentions": OutputRecorder(BartAttention, index=1, layer_name="encoder_attn"),
|
| 566 |
+
}
|
| 567 |
+
|
| 568 |
+
def __init__(self, config: BartConfig):
|
| 569 |
+
super().__init__(config)
|
| 570 |
+
self.dropout = config.dropout
|
| 571 |
+
self.layerdrop = config.decoder_layerdrop
|
| 572 |
+
self.padding_idx = config.pad_token_id
|
| 573 |
+
self.max_target_positions = config.max_position_embeddings
|
| 574 |
+
embed_scale = math.sqrt(config.d_model) if config.scale_embedding else 1.0
|
| 575 |
+
|
| 576 |
+
self.embed_tokens = BartScaledWordEmbedding(
|
| 577 |
+
config.vocab_size, config.d_model, self.padding_idx, embed_scale=embed_scale
|
| 578 |
+
)
|
| 579 |
+
|
| 580 |
+
self.embed_positions = BartLearnedPositionalEmbedding(
|
| 581 |
+
config.max_position_embeddings,
|
| 582 |
+
config.d_model,
|
| 583 |
+
)
|
| 584 |
+
self.layers = nn.ModuleList([BartDecoderLayer(config, layer_idx=i) for i in range(config.decoder_layers)])
|
| 585 |
+
|
| 586 |
+
self.layernorm_embedding = nn.LayerNorm(config.d_model)
|
| 587 |
+
|
| 588 |
+
self.gradient_checkpointing = False
|
| 589 |
+
# Initialize weights and apply final processing
|
| 590 |
+
self.post_init()
|
| 591 |
+
|
| 592 |
+
@merge_with_config_defaults
|
| 593 |
+
@capture_outputs
|
| 594 |
+
@auto_docstring
|
| 595 |
+
def forward(
|
| 596 |
+
self,
|
| 597 |
+
input_ids: torch.LongTensor | None = None,
|
| 598 |
+
attention_mask: torch.Tensor | None = None,
|
| 599 |
+
encoder_hidden_states: torch.FloatTensor | None = None,
|
| 600 |
+
encoder_attention_mask: torch.LongTensor | None = None,
|
| 601 |
+
past_key_values: Cache | None = None,
|
| 602 |
+
inputs_embeds: torch.FloatTensor | None = None,
|
| 603 |
+
use_cache: bool | None = None,
|
| 604 |
+
**kwargs: Unpack[TransformersKwargs],
|
| 605 |
+
) -> BaseModelOutputWithPastAndCrossAttentions:
|
| 606 |
+
if (input_ids is None) ^ (inputs_embeds is not None):
|
| 607 |
+
raise ValueError("You must specify exactly one of decoder_input_ids or decoder_inputs_embeds")
|
| 608 |
+
|
| 609 |
+
if inputs_embeds is None:
|
| 610 |
+
inputs_embeds = self.embed_tokens(input_ids)
|
| 611 |
+
|
| 612 |
+
# initialize `past_key_values`
|
| 613 |
+
if use_cache and past_key_values is None:
|
| 614 |
+
past_key_values = (
|
| 615 |
+
EncoderDecoderCache(DynamicCache(config=self.config), DynamicCache(config=self.config))
|
| 616 |
+
if encoder_hidden_states is not None or self.config.is_encoder_decoder
|
| 617 |
+
else DynamicCache(config=self.config)
|
| 618 |
+
)
|
| 619 |
+
|
| 620 |
+
batch_size, seq_length = inputs_embeds.size()[:-1]
|
| 621 |
+
past_key_values_length = past_key_values.get_seq_length() if past_key_values is not None else 0
|
| 622 |
+
position_ids = torch.arange(seq_length, device=inputs_embeds.device) + past_key_values_length
|
| 623 |
+
|
| 624 |
+
if attention_mask is None and not is_torchdynamo_compiling():
|
| 625 |
+
# required mask seq length can be calculated via length of past cache
|
| 626 |
+
mask_seq_length = past_key_values_length + seq_length
|
| 627 |
+
attention_mask = torch.ones(batch_size, mask_seq_length, device=inputs_embeds.device)
|
| 628 |
+
|
| 629 |
+
self_attn_cache = (
|
| 630 |
+
past_key_values.self_attention_cache
|
| 631 |
+
if isinstance(past_key_values, EncoderDecoderCache)
|
| 632 |
+
else past_key_values
|
| 633 |
+
)
|
| 634 |
+
|
| 635 |
+
attention_mask = create_causal_mask(
|
| 636 |
+
config=self.config,
|
| 637 |
+
inputs_embeds=inputs_embeds,
|
| 638 |
+
attention_mask=attention_mask,
|
| 639 |
+
past_key_values=self_attn_cache,
|
| 640 |
+
)
|
| 641 |
+
encoder_attention_mask = create_bidirectional_mask(
|
| 642 |
+
config=self.config,
|
| 643 |
+
inputs_embeds=inputs_embeds,
|
| 644 |
+
attention_mask=encoder_attention_mask,
|
| 645 |
+
encoder_hidden_states=encoder_hidden_states,
|
| 646 |
+
)
|
| 647 |
+
|
| 648 |
+
# embed positions
|
| 649 |
+
positions = self.embed_positions(input, past_key_values_length, position_ids=position_ids)
|
| 650 |
+
positions = positions.to(inputs_embeds.device)
|
| 651 |
+
|
| 652 |
+
hidden_states = inputs_embeds + positions
|
| 653 |
+
hidden_states = self.layernorm_embedding(hidden_states)
|
| 654 |
+
|
| 655 |
+
hidden_states = nn.functional.dropout(hidden_states, p=self.dropout, training=self.training)
|
| 656 |
+
|
| 657 |
+
for idx, decoder_layer in enumerate(self.layers):
|
| 658 |
+
# add LayerDrop (see https://huggingface.co/papers/1909.11556 for description)
|
| 659 |
+
if self.training:
|
| 660 |
+
dropout_probability = torch.rand([])
|
| 661 |
+
if dropout_probability < self.layerdrop:
|
| 662 |
+
continue
|
| 663 |
+
|
| 664 |
+
hidden_states = decoder_layer(
|
| 665 |
+
hidden_states,
|
| 666 |
+
attention_mask,
|
| 667 |
+
encoder_hidden_states, # as a positional argument for gradient checkpointing
|
| 668 |
+
encoder_attention_mask=encoder_attention_mask,
|
| 669 |
+
past_key_values=past_key_values,
|
| 670 |
+
use_cache=use_cache,
|
| 671 |
+
**kwargs,
|
| 672 |
+
)
|
| 673 |
+
|
| 674 |
+
return BaseModelOutputWithPastAndCrossAttentions(
|
| 675 |
+
last_hidden_state=hidden_states,
|
| 676 |
+
past_key_values=past_key_values,
|
| 677 |
+
)
|
| 678 |
+
|
| 679 |
+
|
| 680 |
+
@auto_docstring
|
| 681 |
+
class BartModel(BartPreTrainedModel):
|
| 682 |
+
_tied_weights_keys = {
|
| 683 |
+
"decoder.embed_tokens.weight": "shared.weight",
|
| 684 |
+
"encoder.embed_tokens.weight": "shared.weight",
|
| 685 |
+
}
|
| 686 |
+
|
| 687 |
+
def __init__(self, config: BartConfig):
|
| 688 |
+
super().__init__(config)
|
| 689 |
+
|
| 690 |
+
padding_idx, vocab_size = config.pad_token_id, config.vocab_size
|
| 691 |
+
embed_scale = math.sqrt(config.d_model) if config.scale_embedding else 1.0
|
| 692 |
+
self.shared = BartScaledWordEmbedding(vocab_size, config.d_model, padding_idx, embed_scale=embed_scale)
|
| 693 |
+
|
| 694 |
+
self.encoder = BartEncoder(config)
|
| 695 |
+
self.decoder = BartDecoder(config)
|
| 696 |
+
|
| 697 |
+
# Initialize weights and apply final processing
|
| 698 |
+
self.post_init()
|
| 699 |
+
|
| 700 |
+
def get_input_embeddings(self):
|
| 701 |
+
return self.shared
|
| 702 |
+
|
| 703 |
+
def set_input_embeddings(self, value):
|
| 704 |
+
self.shared = value
|
| 705 |
+
self.encoder.embed_tokens = self.shared
|
| 706 |
+
self.decoder.embed_tokens = self.shared
|
| 707 |
+
|
| 708 |
+
@can_return_tuple
|
| 709 |
+
@auto_docstring
|
| 710 |
+
def forward(
|
| 711 |
+
self,
|
| 712 |
+
input_ids: torch.LongTensor | None = None,
|
| 713 |
+
attention_mask: torch.Tensor | None = None,
|
| 714 |
+
decoder_input_ids: torch.LongTensor | None = None,
|
| 715 |
+
decoder_attention_mask: torch.LongTensor | None = None,
|
| 716 |
+
encoder_outputs: list[torch.FloatTensor] | None = None,
|
| 717 |
+
past_key_values: Cache | None = None,
|
| 718 |
+
inputs_embeds: torch.FloatTensor | None = None,
|
| 719 |
+
decoder_inputs_embeds: torch.FloatTensor | None = None,
|
| 720 |
+
use_cache: bool | None = None,
|
| 721 |
+
**kwargs: Unpack[TransformersKwargs],
|
| 722 |
+
) -> tuple | Seq2SeqModelOutput:
|
| 723 |
+
r"""
|
| 724 |
+
decoder_input_ids (`torch.LongTensor` of shape `(batch_size, target_sequence_length)`, *optional*):
|
| 725 |
+
Indices of decoder input sequence tokens in the vocabulary.
|
| 726 |
+
|
| 727 |
+
Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and
|
| 728 |
+
[`PreTrainedTokenizer.__call__`] for details.
|
| 729 |
+
|
| 730 |
+
[What are decoder input IDs?](../glossary#decoder-input-ids)
|
| 731 |
+
|
| 732 |
+
Bart uses the `eos_token_id` as the starting token for `decoder_input_ids` generation. If `past_key_values`
|
| 733 |
+
is used, optionally only the last `decoder_input_ids` have to be input (see `past_key_values`).
|
| 734 |
+
|
| 735 |
+
For translation and summarization training, `decoder_input_ids` should be provided. If no
|
| 736 |
+
`decoder_input_ids` is provided, the model will create this tensor by shifting the `input_ids` to the right
|
| 737 |
+
for denoising pre-training following the paper.
|
| 738 |
+
decoder_attention_mask (`torch.LongTensor` of shape `(batch_size, target_sequence_length)`, *optional*):
|
| 739 |
+
Default behavior: generate a tensor that ignores pad tokens in `decoder_input_ids`. Causal mask will also
|
| 740 |
+
be used by default.
|
| 741 |
+
|
| 742 |
+
If you want to change padding behavior, you should read [`modeling_bart._prepare_decoder_attention_mask`]
|
| 743 |
+
and modify to your needs. See diagram 1 in [the paper](https://huggingface.co/papers/1910.13461) for more
|
| 744 |
+
information on the default strategy.
|
| 745 |
+
"""
|
| 746 |
+
# different to other models, Bart automatically creates decoder_input_ids from
|
| 747 |
+
# input_ids if no decoder_input_ids are provided
|
| 748 |
+
if decoder_input_ids is None and decoder_inputs_embeds is None:
|
| 749 |
+
if input_ids is None:
|
| 750 |
+
raise ValueError(
|
| 751 |
+
"If no `decoder_input_ids` or `decoder_inputs_embeds` are "
|
| 752 |
+
"passed, `input_ids` cannot be `None`. Please pass either "
|
| 753 |
+
"`input_ids` or `decoder_input_ids` or `decoder_inputs_embeds`."
|
| 754 |
+
)
|
| 755 |
+
|
| 756 |
+
decoder_input_ids = shift_tokens_right(
|
| 757 |
+
input_ids, self.config.pad_token_id, self.config.decoder_start_token_id
|
| 758 |
+
)
|
| 759 |
+
|
| 760 |
+
if encoder_outputs is None:
|
| 761 |
+
encoder_outputs: BaseModelOutput = self.encoder(
|
| 762 |
+
input_ids=input_ids,
|
| 763 |
+
attention_mask=attention_mask,
|
| 764 |
+
inputs_embeds=inputs_embeds,
|
| 765 |
+
**kwargs,
|
| 766 |
+
)
|
| 767 |
+
elif not isinstance(encoder_outputs, BaseModelOutput):
|
| 768 |
+
encoder_outputs = BaseModelOutput(
|
| 769 |
+
last_hidden_state=encoder_outputs[0],
|
| 770 |
+
hidden_states=encoder_outputs[1] if len(encoder_outputs) > 1 else None,
|
| 771 |
+
attentions=encoder_outputs[2] if len(encoder_outputs) > 2 else None,
|
| 772 |
+
)
|
| 773 |
+
|
| 774 |
+
decoder_outputs: BaseModelOutputWithPastAndCrossAttentions = self.decoder(
|
| 775 |
+
input_ids=decoder_input_ids,
|
| 776 |
+
attention_mask=decoder_attention_mask,
|
| 777 |
+
encoder_hidden_states=encoder_outputs[0],
|
| 778 |
+
encoder_attention_mask=attention_mask,
|
| 779 |
+
past_key_values=past_key_values,
|
| 780 |
+
inputs_embeds=decoder_inputs_embeds,
|
| 781 |
+
use_cache=use_cache,
|
| 782 |
+
**kwargs,
|
| 783 |
+
)
|
| 784 |
+
|
| 785 |
+
return Seq2SeqModelOutput(
|
| 786 |
+
last_hidden_state=decoder_outputs.last_hidden_state,
|
| 787 |
+
past_key_values=decoder_outputs.past_key_values,
|
| 788 |
+
decoder_hidden_states=decoder_outputs.hidden_states,
|
| 789 |
+
decoder_attentions=decoder_outputs.attentions,
|
| 790 |
+
cross_attentions=decoder_outputs.cross_attentions,
|
| 791 |
+
encoder_last_hidden_state=encoder_outputs.last_hidden_state,
|
| 792 |
+
encoder_hidden_states=encoder_outputs.hidden_states,
|
| 793 |
+
encoder_attentions=encoder_outputs.attentions,
|
| 794 |
+
)
|
| 795 |
+
|
| 796 |
+
|
| 797 |
+
@auto_docstring(
|
| 798 |
+
custom_intro="""
|
| 799 |
+
The BART Model with a language modeling head. Can be used for summarization.
|
| 800 |
+
"""
|
| 801 |
+
)
|
| 802 |
+
class BartForConditionalGeneration(BartPreTrainedModel, GenerationMixin):
|
| 803 |
+
base_model_prefix = "model"
|
| 804 |
+
_tied_weights_keys = {
|
| 805 |
+
"lm_head.weight": "model.shared.weight",
|
| 806 |
+
}
|
| 807 |
+
_keys_to_ignore_on_load_missing = ["final_logits_bias"]
|
| 808 |
+
|
| 809 |
+
def __init__(self, config: BartConfig):
|
| 810 |
+
super().__init__(config)
|
| 811 |
+
self.model = BartModel(config)
|
| 812 |
+
self.register_buffer("final_logits_bias", torch.zeros((1, self.model.shared.num_embeddings)))
|
| 813 |
+
self.lm_head = nn.Linear(config.d_model, self.model.shared.num_embeddings, bias=False)
|
| 814 |
+
|
| 815 |
+
# Initialize weights and apply final processing
|
| 816 |
+
self.post_init()
|
| 817 |
+
|
| 818 |
+
def resize_token_embeddings(
|
| 819 |
+
self, new_num_tokens: int, pad_to_multiple_of: int | None = None, mean_resizing: bool = True
|
| 820 |
+
) -> nn.Embedding:
|
| 821 |
+
new_embeddings = super().resize_token_embeddings(new_num_tokens, pad_to_multiple_of, mean_resizing)
|
| 822 |
+
self._resize_final_logits_bias(new_embeddings.weight.shape[0])
|
| 823 |
+
return new_embeddings
|
| 824 |
+
|
| 825 |
+
def _resize_final_logits_bias(self, new_num_tokens: int) -> None:
|
| 826 |
+
old_num_tokens = self.final_logits_bias.shape[-1]
|
| 827 |
+
if new_num_tokens <= old_num_tokens:
|
| 828 |
+
new_bias = self.final_logits_bias[:, :new_num_tokens]
|
| 829 |
+
else:
|
| 830 |
+
extra_bias = torch.zeros((1, new_num_tokens - old_num_tokens), device=self.final_logits_bias.device)
|
| 831 |
+
new_bias = torch.cat([self.final_logits_bias, extra_bias], dim=1)
|
| 832 |
+
self.register_buffer("final_logits_bias", new_bias)
|
| 833 |
+
|
| 834 |
+
@can_return_tuple
|
| 835 |
+
@auto_docstring
|
| 836 |
+
def forward(
|
| 837 |
+
self,
|
| 838 |
+
input_ids: torch.LongTensor | None = None,
|
| 839 |
+
attention_mask: torch.Tensor | None = None,
|
| 840 |
+
decoder_input_ids: torch.LongTensor | None = None,
|
| 841 |
+
decoder_attention_mask: torch.LongTensor | None = None,
|
| 842 |
+
encoder_outputs: list[torch.FloatTensor] | None = None,
|
| 843 |
+
past_key_values: Cache | None = None,
|
| 844 |
+
inputs_embeds: torch.FloatTensor | None = None,
|
| 845 |
+
decoder_inputs_embeds: torch.FloatTensor | None = None,
|
| 846 |
+
labels: torch.LongTensor | None = None,
|
| 847 |
+
use_cache: bool | None = None,
|
| 848 |
+
**kwargs: Unpack[TransformersKwargs],
|
| 849 |
+
) -> tuple | Seq2SeqLMOutput:
|
| 850 |
+
r"""
|
| 851 |
+
decoder_input_ids (`torch.LongTensor` of shape `(batch_size, target_sequence_length)`, *optional*):
|
| 852 |
+
Indices of decoder input sequence tokens in the vocabulary.
|
| 853 |
+
|
| 854 |
+
Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and
|
| 855 |
+
[`PreTrainedTokenizer.__call__`] for details.
|
| 856 |
+
|
| 857 |
+
[What are decoder input IDs?](../glossary#decoder-input-ids)
|
| 858 |
+
|
| 859 |
+
Bart uses the `eos_token_id` as the starting token for `decoder_input_ids` generation. If `past_key_values`
|
| 860 |
+
is used, optionally only the last `decoder_input_ids` have to be input (see `past_key_values`).
|
| 861 |
+
|
| 862 |
+
For translation and summarization training, `decoder_input_ids` should be provided. If no
|
| 863 |
+
`decoder_input_ids` is provided, the model will create this tensor by shifting the `input_ids` to the right
|
| 864 |
+
for denoising pre-training following the paper.
|
| 865 |
+
decoder_attention_mask (`torch.LongTensor` of shape `(batch_size, target_sequence_length)`, *optional*):
|
| 866 |
+
Default behavior: generate a tensor that ignores pad tokens in `decoder_input_ids`. Causal mask will also
|
| 867 |
+
be used by default.
|
| 868 |
+
|
| 869 |
+
If you want to change padding behavior, you should read [`modeling_bart._prepare_decoder_attention_mask`]
|
| 870 |
+
and modify to your needs. See diagram 1 in [the paper](https://huggingface.co/papers/1910.13461) for more
|
| 871 |
+
information on the default strategy.
|
| 872 |
+
labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*):
|
| 873 |
+
Labels for computing the masked language modeling loss. Indices should either be in `[0, ...,
|
| 874 |
+
config.vocab_size]` or -100 (see `input_ids` docstring). Tokens with indices set to `-100` are ignored
|
| 875 |
+
(masked), the loss is only computed for the tokens with labels in `[0, ..., config.vocab_size]`.
|
| 876 |
+
|
| 877 |
+
Example summarization:
|
| 878 |
+
|
| 879 |
+
```python
|
| 880 |
+
>>> from transformers import AutoTokenizer, BartForConditionalGeneration
|
| 881 |
+
|
| 882 |
+
>>> model = BartForConditionalGeneration.from_pretrained("facebook/bart-large-cnn")
|
| 883 |
+
>>> tokenizer = AutoTokenizer.from_pretrained("facebook/bart-large-cnn")
|
| 884 |
+
|
| 885 |
+
>>> ARTICLE_TO_SUMMARIZE = (
|
| 886 |
+
... "PG&E stated it scheduled the blackouts in response to forecasts for high winds "
|
| 887 |
+
... "amid dry conditions. The aim is to reduce the risk of wildfires. Nearly 800 thousand customers were "
|
| 888 |
+
... "scheduled to be affected by the shutoffs which were expected to last through at least midday tomorrow."
|
| 889 |
+
... )
|
| 890 |
+
>>> inputs = tokenizer([ARTICLE_TO_SUMMARIZE], max_length=1024, return_tensors="pt")
|
| 891 |
+
|
| 892 |
+
>>> # Generate Summary
|
| 893 |
+
>>> summary_ids = model.generate(inputs["input_ids"], num_beams=2, min_length=0, max_length=20)
|
| 894 |
+
>>> tokenizer.batch_decode(summary_ids, skip_special_tokens=True, clean_up_tokenization_spaces=False)[0]
|
| 895 |
+
'PG&E scheduled the blackouts in response to forecasts for high winds amid dry conditions'
|
| 896 |
+
```
|
| 897 |
+
|
| 898 |
+
Mask filling example:
|
| 899 |
+
|
| 900 |
+
```python
|
| 901 |
+
>>> from transformers import AutoTokenizer, BartForConditionalGeneration
|
| 902 |
+
|
| 903 |
+
>>> tokenizer = AutoTokenizer.from_pretrained("facebook/bart-base")
|
| 904 |
+
>>> model = BartForConditionalGeneration.from_pretrained("facebook/bart-base")
|
| 905 |
+
|
| 906 |
+
>>> TXT = "My friends are <mask> but they eat too many carbs."
|
| 907 |
+
>>> input_ids = tokenizer([TXT], return_tensors="pt")["input_ids"]
|
| 908 |
+
>>> logits = model(input_ids).logits
|
| 909 |
+
|
| 910 |
+
>>> masked_index = (input_ids[0] == tokenizer.mask_token_id).nonzero().item()
|
| 911 |
+
>>> probs = logits[0, masked_index].softmax(dim=0)
|
| 912 |
+
>>> values, predictions = probs.topk(5)
|
| 913 |
+
|
| 914 |
+
>>> tokenizer.decode(predictions).split()
|
| 915 |
+
['not', 'good', 'healthy', 'great', 'very']
|
| 916 |
+
```
|
| 917 |
+
"""
|
| 918 |
+
if labels is not None:
|
| 919 |
+
if use_cache:
|
| 920 |
+
logger.warning("The `use_cache` argument is changed to `False` since `labels` is provided.")
|
| 921 |
+
use_cache = False
|
| 922 |
+
if decoder_input_ids is None and decoder_inputs_embeds is None:
|
| 923 |
+
decoder_input_ids = shift_tokens_right(
|
| 924 |
+
labels, self.config.pad_token_id, self.config.decoder_start_token_id
|
| 925 |
+
)
|
| 926 |
+
|
| 927 |
+
outputs: Seq2SeqModelOutput = self.model(
|
| 928 |
+
input_ids,
|
| 929 |
+
attention_mask=attention_mask,
|
| 930 |
+
decoder_input_ids=decoder_input_ids,
|
| 931 |
+
encoder_outputs=encoder_outputs,
|
| 932 |
+
decoder_attention_mask=decoder_attention_mask,
|
| 933 |
+
past_key_values=past_key_values,
|
| 934 |
+
inputs_embeds=inputs_embeds,
|
| 935 |
+
decoder_inputs_embeds=decoder_inputs_embeds,
|
| 936 |
+
use_cache=use_cache,
|
| 937 |
+
**kwargs,
|
| 938 |
+
)
|
| 939 |
+
|
| 940 |
+
lm_logits = self.lm_head(outputs[0])
|
| 941 |
+
lm_logits = lm_logits + self.final_logits_bias.to(lm_logits.device)
|
| 942 |
+
|
| 943 |
+
masked_lm_loss = None
|
| 944 |
+
if labels is not None:
|
| 945 |
+
labels = labels.to(lm_logits.device)
|
| 946 |
+
loss_fct = CrossEntropyLoss()
|
| 947 |
+
masked_lm_loss = loss_fct(lm_logits.view(-1, self.config.vocab_size), labels.view(-1))
|
| 948 |
+
|
| 949 |
+
return Seq2SeqLMOutput(
|
| 950 |
+
loss=masked_lm_loss,
|
| 951 |
+
logits=lm_logits,
|
| 952 |
+
past_key_values=outputs.past_key_values,
|
| 953 |
+
decoder_hidden_states=outputs.decoder_hidden_states,
|
| 954 |
+
decoder_attentions=outputs.decoder_attentions,
|
| 955 |
+
cross_attentions=outputs.cross_attentions,
|
| 956 |
+
encoder_last_hidden_state=outputs.encoder_last_hidden_state,
|
| 957 |
+
encoder_hidden_states=outputs.encoder_hidden_states,
|
| 958 |
+
encoder_attentions=outputs.encoder_attentions,
|
| 959 |
+
)
|
| 960 |
+
|
| 961 |
+
def prepare_decoder_input_ids_from_labels(self, labels: torch.Tensor):
|
| 962 |
+
return shift_tokens_right(labels, self.config.pad_token_id, self.config.decoder_start_token_id)
|
| 963 |
+
|
| 964 |
+
|
| 965 |
+
@auto_docstring(
|
| 966 |
+
custom_intro="""
|
| 967 |
+
Bart model with a sequence classification/head on top (a linear layer on top of the pooled output) e.g. for GLUE
|
| 968 |
+
tasks.
|
| 969 |
+
"""
|
| 970 |
+
)
|
| 971 |
+
class BartForSequenceClassification(BartPreTrainedModel):
|
| 972 |
+
def __init__(self, config: BartConfig, **kwargs):
|
| 973 |
+
super().__init__(config, **kwargs)
|
| 974 |
+
self.model = BartModel(config)
|
| 975 |
+
self.classification_head = BartClassificationHead(
|
| 976 |
+
config.d_model,
|
| 977 |
+
config.d_model,
|
| 978 |
+
config.num_labels,
|
| 979 |
+
config.classifier_dropout,
|
| 980 |
+
)
|
| 981 |
+
|
| 982 |
+
# Initialize weights and apply final processing
|
| 983 |
+
self.post_init()
|
| 984 |
+
|
| 985 |
+
@can_return_tuple
|
| 986 |
+
@auto_docstring
|
| 987 |
+
def forward(
|
| 988 |
+
self,
|
| 989 |
+
input_ids: torch.LongTensor | None = None,
|
| 990 |
+
attention_mask: torch.Tensor | None = None,
|
| 991 |
+
decoder_input_ids: torch.LongTensor | None = None,
|
| 992 |
+
decoder_attention_mask: torch.LongTensor | None = None,
|
| 993 |
+
encoder_outputs: list[torch.FloatTensor] | None = None,
|
| 994 |
+
inputs_embeds: torch.FloatTensor | None = None,
|
| 995 |
+
decoder_inputs_embeds: torch.FloatTensor | None = None,
|
| 996 |
+
labels: torch.LongTensor | None = None,
|
| 997 |
+
use_cache: bool | None = None,
|
| 998 |
+
**kwargs: Unpack[TransformersKwargs],
|
| 999 |
+
) -> tuple | Seq2SeqSequenceClassifierOutput:
|
| 1000 |
+
r"""
|
| 1001 |
+
decoder_input_ids (`torch.LongTensor` of shape `(batch_size, target_sequence_length)`, *optional*):
|
| 1002 |
+
Indices of decoder input sequence tokens in the vocabulary.
|
| 1003 |
+
|
| 1004 |
+
Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and
|
| 1005 |
+
[`PreTrainedTokenizer.__call__`] for details.
|
| 1006 |
+
|
| 1007 |
+
[What are decoder input IDs?](../glossary#decoder-input-ids)
|
| 1008 |
+
|
| 1009 |
+
Bart uses the `eos_token_id` as the starting token for `decoder_input_ids` generation. If `past_key_values`
|
| 1010 |
+
is used, optionally only the last `decoder_input_ids` have to be input (see `past_key_values`).
|
| 1011 |
+
|
| 1012 |
+
For translation and summarization training, `decoder_input_ids` should be provided. If no
|
| 1013 |
+
`decoder_input_ids` is provided, the model will create this tensor by shifting the `input_ids` to the right
|
| 1014 |
+
for denoising pre-training following the paper.
|
| 1015 |
+
decoder_attention_mask (`torch.LongTensor` of shape `(batch_size, target_sequence_length)`, *optional*):
|
| 1016 |
+
Default behavior: generate a tensor that ignores pad tokens in `decoder_input_ids`. Causal mask will also
|
| 1017 |
+
be used by default.
|
| 1018 |
+
|
| 1019 |
+
If you want to change padding behavior, you should read [`modeling_bart._prepare_decoder_attention_mask`]
|
| 1020 |
+
and modify to your needs. See diagram 1 in [the paper](https://huggingface.co/papers/1910.13461) for more
|
| 1021 |
+
information on the default strategy.
|
| 1022 |
+
labels (`torch.LongTensor` of shape `(batch_size,)`, *optional*):
|
| 1023 |
+
Labels for computing the sequence classification/regression loss. Indices should be in `[0, ...,
|
| 1024 |
+
config.num_labels - 1]`. If `config.num_labels > 1` a classification loss is computed (Cross-Entropy).
|
| 1025 |
+
"""
|
| 1026 |
+
if labels is not None:
|
| 1027 |
+
use_cache = False
|
| 1028 |
+
|
| 1029 |
+
if input_ids is None and inputs_embeds is not None:
|
| 1030 |
+
raise NotImplementedError(
|
| 1031 |
+
f"Passing input embeddings is currently not supported for {self.__class__.__name__}"
|
| 1032 |
+
)
|
| 1033 |
+
|
| 1034 |
+
outputs: Seq2SeqModelOutput = self.model(
|
| 1035 |
+
input_ids,
|
| 1036 |
+
attention_mask=attention_mask,
|
| 1037 |
+
decoder_input_ids=decoder_input_ids,
|
| 1038 |
+
decoder_attention_mask=decoder_attention_mask,
|
| 1039 |
+
encoder_outputs=encoder_outputs,
|
| 1040 |
+
inputs_embeds=inputs_embeds,
|
| 1041 |
+
decoder_inputs_embeds=decoder_inputs_embeds,
|
| 1042 |
+
use_cache=use_cache,
|
| 1043 |
+
**kwargs,
|
| 1044 |
+
)
|
| 1045 |
+
hidden_states = outputs[0] # last hidden state
|
| 1046 |
+
|
| 1047 |
+
eos_mask = input_ids.eq(self.config.eos_token_id).to(hidden_states.device)
|
| 1048 |
+
|
| 1049 |
+
torch_compilable_check(
|
| 1050 |
+
torch.unique_consecutive(eos_mask.sum(1)).numel() == 1,
|
| 1051 |
+
"All examples must have the same number of <eos> tokens.",
|
| 1052 |
+
)
|
| 1053 |
+
sentence_representation = hidden_states[eos_mask, :].view(hidden_states.size(0), -1, hidden_states.size(-1))[
|
| 1054 |
+
:, -1, :
|
| 1055 |
+
]
|
| 1056 |
+
logits = self.classification_head(sentence_representation)
|
| 1057 |
+
|
| 1058 |
+
loss = None
|
| 1059 |
+
if labels is not None:
|
| 1060 |
+
labels = labels.to(logits.device)
|
| 1061 |
+
if self.config.problem_type is None:
|
| 1062 |
+
if self.config.num_labels == 1:
|
| 1063 |
+
self.config.problem_type = "regression"
|
| 1064 |
+
elif self.config.num_labels > 1 and (labels.dtype == torch.long or labels.dtype == torch.int):
|
| 1065 |
+
self.config.problem_type = "single_label_classification"
|
| 1066 |
+
else:
|
| 1067 |
+
self.config.problem_type = "multi_label_classification"
|
| 1068 |
+
|
| 1069 |
+
if self.config.problem_type == "regression":
|
| 1070 |
+
loss_fct = MSELoss()
|
| 1071 |
+
if self.config.num_labels == 1:
|
| 1072 |
+
loss = loss_fct(logits.squeeze(), labels.squeeze())
|
| 1073 |
+
else:
|
| 1074 |
+
loss = loss_fct(logits, labels)
|
| 1075 |
+
elif self.config.problem_type == "single_label_classification":
|
| 1076 |
+
loss_fct = CrossEntropyLoss()
|
| 1077 |
+
loss = loss_fct(logits.view(-1, self.config.num_labels), labels.view(-1))
|
| 1078 |
+
elif self.config.problem_type == "multi_label_classification":
|
| 1079 |
+
loss_fct = BCEWithLogitsLoss()
|
| 1080 |
+
loss = loss_fct(logits, labels)
|
| 1081 |
+
|
| 1082 |
+
return Seq2SeqSequenceClassifierOutput(
|
| 1083 |
+
loss=loss,
|
| 1084 |
+
logits=logits,
|
| 1085 |
+
past_key_values=outputs.past_key_values,
|
| 1086 |
+
decoder_hidden_states=outputs.decoder_hidden_states,
|
| 1087 |
+
decoder_attentions=outputs.decoder_attentions,
|
| 1088 |
+
cross_attentions=outputs.cross_attentions,
|
| 1089 |
+
encoder_last_hidden_state=outputs.encoder_last_hidden_state,
|
| 1090 |
+
encoder_hidden_states=outputs.encoder_hidden_states,
|
| 1091 |
+
encoder_attentions=outputs.encoder_attentions,
|
| 1092 |
+
)
|
| 1093 |
+
|
| 1094 |
+
|
| 1095 |
+
@auto_docstring
|
| 1096 |
+
class BartForQuestionAnswering(BartPreTrainedModel):
|
| 1097 |
+
def __init__(self, config):
|
| 1098 |
+
super().__init__(config)
|
| 1099 |
+
|
| 1100 |
+
config.num_labels = 2
|
| 1101 |
+
self.num_labels = config.num_labels
|
| 1102 |
+
|
| 1103 |
+
self.model = BartModel(config)
|
| 1104 |
+
self.qa_outputs = nn.Linear(config.hidden_size, config.num_labels)
|
| 1105 |
+
|
| 1106 |
+
# Initialize weights and apply final processing
|
| 1107 |
+
self.post_init()
|
| 1108 |
+
|
| 1109 |
+
@can_return_tuple
|
| 1110 |
+
@auto_docstring
|
| 1111 |
+
def forward(
|
| 1112 |
+
self,
|
| 1113 |
+
input_ids: torch.Tensor | None = None,
|
| 1114 |
+
attention_mask: torch.Tensor | None = None,
|
| 1115 |
+
decoder_input_ids: torch.LongTensor | None = None,
|
| 1116 |
+
decoder_attention_mask: torch.LongTensor | None = None,
|
| 1117 |
+
encoder_outputs: list[torch.FloatTensor] | None = None,
|
| 1118 |
+
start_positions: torch.LongTensor | None = None,
|
| 1119 |
+
end_positions: torch.LongTensor | None = None,
|
| 1120 |
+
inputs_embeds: torch.FloatTensor | None = None,
|
| 1121 |
+
decoder_inputs_embeds: torch.FloatTensor | None = None,
|
| 1122 |
+
use_cache: bool | None = None,
|
| 1123 |
+
**kwargs: Unpack[TransformersKwargs],
|
| 1124 |
+
) -> tuple | Seq2SeqQuestionAnsweringModelOutput:
|
| 1125 |
+
r"""
|
| 1126 |
+
decoder_input_ids (`torch.LongTensor` of shape `(batch_size, target_sequence_length)`, *optional*):
|
| 1127 |
+
Indices of decoder input sequence tokens in the vocabulary.
|
| 1128 |
+
|
| 1129 |
+
Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and
|
| 1130 |
+
[`PreTrainedTokenizer.__call__`] for details.
|
| 1131 |
+
|
| 1132 |
+
[What are decoder input IDs?](../glossary#decoder-input-ids)
|
| 1133 |
+
|
| 1134 |
+
Bart uses the `eos_token_id` as the starting token for `decoder_input_ids` generation. If `past_key_values`
|
| 1135 |
+
is used, optionally only the last `decoder_input_ids` have to be input (see `past_key_values`).
|
| 1136 |
+
|
| 1137 |
+
For translation and summarization training, `decoder_input_ids` should be provided. If no
|
| 1138 |
+
`decoder_input_ids` is provided, the model will create this tensor by shifting the `input_ids` to the right
|
| 1139 |
+
for denoising pre-training following the paper.
|
| 1140 |
+
decoder_attention_mask (`torch.LongTensor` of shape `(batch_size, target_sequence_length)`, *optional*):
|
| 1141 |
+
Default behavior: generate a tensor that ignores pad tokens in `decoder_input_ids`. Causal mask will also
|
| 1142 |
+
be used by default.
|
| 1143 |
+
|
| 1144 |
+
If you want to change padding behavior, you should read [`modeling_bart._prepare_decoder_attention_mask`]
|
| 1145 |
+
and modify to your needs. See diagram 1 in [the paper](https://huggingface.co/papers/1910.13461) for more
|
| 1146 |
+
information on the default strategy.
|
| 1147 |
+
"""
|
| 1148 |
+
if start_positions is not None and end_positions is not None:
|
| 1149 |
+
use_cache = False
|
| 1150 |
+
|
| 1151 |
+
outputs: Seq2SeqModelOutput = self.model(
|
| 1152 |
+
input_ids,
|
| 1153 |
+
attention_mask=attention_mask,
|
| 1154 |
+
decoder_input_ids=decoder_input_ids,
|
| 1155 |
+
decoder_attention_mask=decoder_attention_mask,
|
| 1156 |
+
encoder_outputs=encoder_outputs,
|
| 1157 |
+
inputs_embeds=inputs_embeds,
|
| 1158 |
+
decoder_inputs_embeds=decoder_inputs_embeds,
|
| 1159 |
+
use_cache=use_cache,
|
| 1160 |
+
**kwargs,
|
| 1161 |
+
)
|
| 1162 |
+
|
| 1163 |
+
sequence_output = outputs[0]
|
| 1164 |
+
|
| 1165 |
+
logits = self.qa_outputs(sequence_output)
|
| 1166 |
+
start_logits, end_logits = logits.split(1, dim=-1)
|
| 1167 |
+
start_logits = start_logits.squeeze(-1).contiguous()
|
| 1168 |
+
end_logits = end_logits.squeeze(-1).contiguous()
|
| 1169 |
+
|
| 1170 |
+
total_loss = None
|
| 1171 |
+
if start_positions is not None and end_positions is not None:
|
| 1172 |
+
# If we are on multi-GPU, split add a dimension
|
| 1173 |
+
if len(start_positions.size()) > 1:
|
| 1174 |
+
start_positions = start_positions.squeeze(-1)
|
| 1175 |
+
if len(end_positions.size()) > 1:
|
| 1176 |
+
end_positions = end_positions.squeeze(-1)
|
| 1177 |
+
# sometimes the start/end positions are outside our model inputs, we ignore these terms
|
| 1178 |
+
ignored_index = start_logits.size(1)
|
| 1179 |
+
start_positions = start_positions.clamp(0, ignored_index)
|
| 1180 |
+
end_positions = end_positions.clamp(0, ignored_index)
|
| 1181 |
+
|
| 1182 |
+
loss_fct = CrossEntropyLoss(ignore_index=ignored_index)
|
| 1183 |
+
start_loss = loss_fct(start_logits, start_positions)
|
| 1184 |
+
end_loss = loss_fct(end_logits, end_positions)
|
| 1185 |
+
total_loss = (start_loss + end_loss) / 2
|
| 1186 |
+
|
| 1187 |
+
return Seq2SeqQuestionAnsweringModelOutput(
|
| 1188 |
+
loss=total_loss,
|
| 1189 |
+
start_logits=start_logits,
|
| 1190 |
+
end_logits=end_logits,
|
| 1191 |
+
past_key_values=outputs.past_key_values,
|
| 1192 |
+
decoder_hidden_states=outputs.decoder_hidden_states,
|
| 1193 |
+
decoder_attentions=outputs.decoder_attentions,
|
| 1194 |
+
cross_attentions=outputs.cross_attentions,
|
| 1195 |
+
encoder_last_hidden_state=outputs.encoder_last_hidden_state,
|
| 1196 |
+
encoder_hidden_states=outputs.encoder_hidden_states,
|
| 1197 |
+
encoder_attentions=outputs.encoder_attentions,
|
| 1198 |
+
)
|
| 1199 |
+
|
| 1200 |
+
|
| 1201 |
+
class BartDecoderWrapper(BartPreTrainedModel):
|
| 1202 |
+
"""
|
| 1203 |
+
This wrapper class is a helper class to correctly load pretrained checkpoints when the causal language model is
|
| 1204 |
+
used in combination with the [`EncoderDecoderModel`] framework.
|
| 1205 |
+
"""
|
| 1206 |
+
|
| 1207 |
+
def __init__(self, config):
|
| 1208 |
+
super().__init__(config)
|
| 1209 |
+
self.decoder = BartDecoder(config)
|
| 1210 |
+
self.post_init()
|
| 1211 |
+
|
| 1212 |
+
def forward(self, *args, **kwargs):
|
| 1213 |
+
return self.decoder(*args, **kwargs)
|
| 1214 |
+
|
| 1215 |
+
|
| 1216 |
+
@auto_docstring(
|
| 1217 |
+
custom_intro="""
|
| 1218 |
+
BART decoder with a language modeling head on top (linear layer with weights tied to the input embeddings).
|
| 1219 |
+
"""
|
| 1220 |
+
)
|
| 1221 |
+
class BartForCausalLM(BartPreTrainedModel, GenerationMixin):
|
| 1222 |
+
_tied_weights_keys = {
|
| 1223 |
+
"lm_head.weight": "model.decoder.embed_tokens.weight",
|
| 1224 |
+
}
|
| 1225 |
+
|
| 1226 |
+
def __init__(self, config):
|
| 1227 |
+
config.is_decoder = True
|
| 1228 |
+
config.is_encoder_decoder = False
|
| 1229 |
+
super().__init__(config)
|
| 1230 |
+
self.model = BartDecoderWrapper(config)
|
| 1231 |
+
|
| 1232 |
+
self.lm_head = nn.Linear(config.hidden_size, config.vocab_size, bias=False)
|
| 1233 |
+
|
| 1234 |
+
# Initialize weights and apply final processing
|
| 1235 |
+
self.post_init()
|
| 1236 |
+
|
| 1237 |
+
def get_input_embeddings(self):
|
| 1238 |
+
return self.model.decoder.embed_tokens
|
| 1239 |
+
|
| 1240 |
+
def set_input_embeddings(self, value):
|
| 1241 |
+
self.model.decoder.embed_tokens = value
|
| 1242 |
+
|
| 1243 |
+
@can_return_tuple
|
| 1244 |
+
@auto_docstring
|
| 1245 |
+
def forward(
|
| 1246 |
+
self,
|
| 1247 |
+
input_ids: torch.LongTensor | None = None,
|
| 1248 |
+
attention_mask: torch.Tensor | None = None,
|
| 1249 |
+
encoder_hidden_states: torch.FloatTensor | None = None,
|
| 1250 |
+
encoder_attention_mask: torch.FloatTensor | None = None,
|
| 1251 |
+
past_key_values: Cache | None = None,
|
| 1252 |
+
inputs_embeds: torch.FloatTensor | None = None,
|
| 1253 |
+
labels: torch.LongTensor | None = None,
|
| 1254 |
+
use_cache: bool | None = None,
|
| 1255 |
+
logits_to_keep: int | torch.Tensor = 0,
|
| 1256 |
+
**kwargs: Unpack[TransformersKwargs],
|
| 1257 |
+
) -> tuple | CausalLMOutputWithCrossAttentions:
|
| 1258 |
+
r"""
|
| 1259 |
+
labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*):
|
| 1260 |
+
Labels for computing the masked language modeling loss. Indices should either be in `[0, ...,
|
| 1261 |
+
config.vocab_size]` or -100 (see `input_ids` docstring). Tokens with indices set to `-100` are ignored
|
| 1262 |
+
(masked), the loss is only computed for the tokens with labels in `[0, ..., config.vocab_size]`.
|
| 1263 |
+
|
| 1264 |
+
Example:
|
| 1265 |
+
|
| 1266 |
+
```python
|
| 1267 |
+
>>> from transformers import AutoTokenizer, BartForCausalLM
|
| 1268 |
+
|
| 1269 |
+
>>> tokenizer = AutoTokenizer.from_pretrained("facebook/bart-base")
|
| 1270 |
+
>>> model = BartForCausalLM.from_pretrained("facebook/bart-base")
|
| 1271 |
+
>>> assert model.config.is_decoder, f"{model.__class__} has to be configured as a decoder."
|
| 1272 |
+
>>> inputs = tokenizer("Hello, my dog is cute", return_tensors="pt")
|
| 1273 |
+
>>> outputs = model(**inputs)
|
| 1274 |
+
|
| 1275 |
+
>>> logits = outputs.logits
|
| 1276 |
+
>>> expected_shape = [1, inputs.input_ids.shape[-1], model.config.vocab_size]
|
| 1277 |
+
>>> list(logits.shape) == expected_shape
|
| 1278 |
+
True
|
| 1279 |
+
```"""
|
| 1280 |
+
|
| 1281 |
+
outputs: BaseModelOutputWithPastAndCrossAttentions = self.model.decoder(
|
| 1282 |
+
input_ids=input_ids,
|
| 1283 |
+
attention_mask=attention_mask,
|
| 1284 |
+
encoder_hidden_states=encoder_hidden_states,
|
| 1285 |
+
encoder_attention_mask=encoder_attention_mask,
|
| 1286 |
+
past_key_values=past_key_values,
|
| 1287 |
+
inputs_embeds=inputs_embeds,
|
| 1288 |
+
use_cache=use_cache,
|
| 1289 |
+
**kwargs,
|
| 1290 |
+
)
|
| 1291 |
+
|
| 1292 |
+
hidden_states = outputs[0]
|
| 1293 |
+
# Only compute necessary logits
|
| 1294 |
+
slice_indices = slice(-logits_to_keep, None) if isinstance(logits_to_keep, int) else logits_to_keep
|
| 1295 |
+
logits = self.lm_head(hidden_states[:, slice_indices, :])
|
| 1296 |
+
|
| 1297 |
+
loss = None
|
| 1298 |
+
if labels is not None:
|
| 1299 |
+
labels = labels.to(logits.device)
|
| 1300 |
+
loss_fct = CrossEntropyLoss()
|
| 1301 |
+
loss = loss_fct(logits.view(-1, self.config.vocab_size), labels.view(-1))
|
| 1302 |
+
|
| 1303 |
+
return CausalLMOutputWithCrossAttentions(
|
| 1304 |
+
loss=loss,
|
| 1305 |
+
logits=logits,
|
| 1306 |
+
past_key_values=outputs.past_key_values,
|
| 1307 |
+
hidden_states=outputs.hidden_states,
|
| 1308 |
+
attentions=outputs.attentions,
|
| 1309 |
+
cross_attentions=outputs.cross_attentions,
|
| 1310 |
+
)
|
| 1311 |
+
|
| 1312 |
+
|
| 1313 |
+
__all__ = [
|
| 1314 |
+
"BartForCausalLM",
|
| 1315 |
+
"BartForConditionalGeneration",
|
| 1316 |
+
"BartForQuestionAnswering",
|
| 1317 |
+
"BartForSequenceClassification",
|
| 1318 |
+
"BartModel",
|
| 1319 |
+
"BartPreTrainedModel",
|
| 1320 |
+
"BartPretrainedModel",
|
| 1321 |
+
"PretrainedBartModel",
|
| 1322 |
+
]
|
third_party/transformers/src/transformers/models/bart/tokenization_bart.py
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright 2024 The HuggingFace Team. All rights reserved.
|
| 2 |
+
#
|
| 3 |
+
# This source code is licensed under the Apache 2.0 license found in the
|
| 4 |
+
# LICENSE file in the root directory of this source tree.
|
| 5 |
+
|
| 6 |
+
"""
|
| 7 |
+
Compatibility shims for BART tokenizers in v5.
|
| 8 |
+
|
| 9 |
+
In v5 we consolidate on the tokenizers-library backend and remove separate
|
| 10 |
+
"slow" vs "fast" implementations. BART uses the same byte-level BPE
|
| 11 |
+
tokenizer as RoBERTa, so we expose `BartTokenizer` and `BartTokenizerFast`
|
| 12 |
+
as aliases to `RobertaTokenizer` to preserve the public API expected by
|
| 13 |
+
existing code and tests.
|
| 14 |
+
"""
|
| 15 |
+
|
| 16 |
+
from ..roberta.tokenization_roberta import RobertaTokenizer as _RobertaTokenizer
|
| 17 |
+
|
| 18 |
+
|
| 19 |
+
# Public aliases maintained for backwards compatibility
|
| 20 |
+
BartTokenizer = _RobertaTokenizer
|
| 21 |
+
BartTokenizerFast = _RobertaTokenizer
|
| 22 |
+
|
| 23 |
+
__all__ = ["BartTokenizer", "BartTokenizerFast"]
|
third_party/transformers/src/transformers/models/bert/__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_bert import *
|
| 22 |
+
from .modeling_bert import *
|
| 23 |
+
from .tokenization_bert 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/bert/configuration_bert.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 |
+
"""BERT 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="google-bert/bert-base-uncased")
|
| 24 |
+
@strict
|
| 25 |
+
class BertConfig(PreTrainedConfig):
|
| 26 |
+
r"""
|
| 27 |
+
Examples:
|
| 28 |
+
|
| 29 |
+
```python
|
| 30 |
+
>>> from transformers import BertConfig, BertModel
|
| 31 |
+
|
| 32 |
+
>>> # Initializing a BERT google-bert/bert-base-uncased style configuration
|
| 33 |
+
>>> configuration = BertConfig()
|
| 34 |
+
|
| 35 |
+
>>> # Initializing a model (with random weights) from the google-bert/bert-base-uncased style configuration
|
| 36 |
+
>>> model = BertModel(configuration)
|
| 37 |
+
|
| 38 |
+
>>> # Accessing the model configuration
|
| 39 |
+
>>> configuration = model.config
|
| 40 |
+
```"""
|
| 41 |
+
|
| 42 |
+
model_type = "bert"
|
| 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 = 0
|
| 57 |
+
use_cache: bool = True
|
| 58 |
+
classifier_dropout: float | int | None = None
|
| 59 |
+
is_decoder: bool = False
|
| 60 |
+
add_cross_attention: bool = False
|
| 61 |
+
bos_token_id: int | None = None
|
| 62 |
+
eos_token_id: int | list[int] | None = None
|
| 63 |
+
tie_word_embeddings: bool = True
|
| 64 |
+
|
| 65 |
+
|
| 66 |
+
__all__ = ["BertConfig"]
|
third_party/transformers/src/transformers/models/bert/convert_bert_original_tf2_checkpoint_to_pytorch.py
ADDED
|
@@ -0,0 +1,246 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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 |
+
|
| 15 |
+
"""
|
| 16 |
+
This script can be used to convert a head-less TF2.x Bert model to PyTorch, as published on the official (now
|
| 17 |
+
deprecated) GitHub: https://github.com/tensorflow/models/tree/v2.3.0/official/nlp/bert
|
| 18 |
+
|
| 19 |
+
TF2.x uses different variable names from the original BERT (TF 1.4) implementation. The script re-maps the TF2.x Bert
|
| 20 |
+
weight names to the original names, so the model can be imported with Huggingface/transformer.
|
| 21 |
+
|
| 22 |
+
You may adapt this script to include classification/MLM/NSP/etc. heads.
|
| 23 |
+
|
| 24 |
+
Note: This script is only working with an older version of the TensorFlow models repository (<= v2.3.0).
|
| 25 |
+
Models trained with never versions are not compatible with this script.
|
| 26 |
+
"""
|
| 27 |
+
|
| 28 |
+
import argparse
|
| 29 |
+
import os
|
| 30 |
+
import re
|
| 31 |
+
|
| 32 |
+
import tensorflow as tf
|
| 33 |
+
import torch
|
| 34 |
+
|
| 35 |
+
from transformers import BertConfig, BertModel
|
| 36 |
+
from transformers.utils import logging
|
| 37 |
+
|
| 38 |
+
|
| 39 |
+
logging.set_verbosity_info()
|
| 40 |
+
logger = logging.get_logger(__name__)
|
| 41 |
+
|
| 42 |
+
|
| 43 |
+
def load_tf2_weights_in_bert(model, tf_checkpoint_path, config):
|
| 44 |
+
tf_path = os.path.abspath(tf_checkpoint_path)
|
| 45 |
+
logger.info(f"Converting TensorFlow checkpoint from {tf_path}")
|
| 46 |
+
# Load weights from TF model
|
| 47 |
+
init_vars = tf.train.list_variables(tf_path)
|
| 48 |
+
names = []
|
| 49 |
+
arrays = []
|
| 50 |
+
layer_depth = []
|
| 51 |
+
for full_name, shape in init_vars:
|
| 52 |
+
# logger.info(f"Loading TF weight {name} with shape {shape}")
|
| 53 |
+
name = full_name.split("/")
|
| 54 |
+
if full_name == "_CHECKPOINTABLE_OBJECT_GRAPH" or name[0] in ["global_step", "save_counter"]:
|
| 55 |
+
logger.info(f"Skipping non-model layer {full_name}")
|
| 56 |
+
continue
|
| 57 |
+
if "optimizer" in full_name:
|
| 58 |
+
logger.info(f"Skipping optimization layer {full_name}")
|
| 59 |
+
continue
|
| 60 |
+
if name[0] == "model":
|
| 61 |
+
# ignore initial 'model'
|
| 62 |
+
name = name[1:]
|
| 63 |
+
# figure out how many levels deep the name is
|
| 64 |
+
depth = 0
|
| 65 |
+
for _name in name:
|
| 66 |
+
if _name.startswith("layer_with_weights"):
|
| 67 |
+
depth += 1
|
| 68 |
+
else:
|
| 69 |
+
break
|
| 70 |
+
layer_depth.append(depth)
|
| 71 |
+
# read data
|
| 72 |
+
array = tf.train.load_variable(tf_path, full_name)
|
| 73 |
+
names.append("/".join(name))
|
| 74 |
+
arrays.append(array)
|
| 75 |
+
logger.info(f"Read a total of {len(arrays):,} layers")
|
| 76 |
+
|
| 77 |
+
# Sanity check
|
| 78 |
+
if len(set(layer_depth)) != 1:
|
| 79 |
+
raise ValueError(f"Found layer names with different depths (layer depth {list(set(layer_depth))})")
|
| 80 |
+
layer_depth = list(set(layer_depth))[0]
|
| 81 |
+
if layer_depth != 1:
|
| 82 |
+
raise ValueError(
|
| 83 |
+
"The model contains more than just the embedding/encoder layers. This script does not handle MLM/NSP"
|
| 84 |
+
" heads."
|
| 85 |
+
)
|
| 86 |
+
|
| 87 |
+
# convert layers
|
| 88 |
+
logger.info("Converting weights...")
|
| 89 |
+
for full_name, array in zip(names, arrays):
|
| 90 |
+
name = full_name.split("/")
|
| 91 |
+
pointer = model
|
| 92 |
+
trace = []
|
| 93 |
+
for i, m_name in enumerate(name):
|
| 94 |
+
if m_name == ".ATTRIBUTES":
|
| 95 |
+
# variable names end with .ATTRIBUTES/VARIABLE_VALUE
|
| 96 |
+
break
|
| 97 |
+
if m_name.startswith("layer_with_weights"):
|
| 98 |
+
layer_num = int(m_name.split("-")[-1])
|
| 99 |
+
if layer_num <= 2:
|
| 100 |
+
# embedding layers
|
| 101 |
+
# layer_num 0: word_embeddings
|
| 102 |
+
# layer_num 1: position_embeddings
|
| 103 |
+
# layer_num 2: token_type_embeddings
|
| 104 |
+
continue
|
| 105 |
+
elif layer_num == 3:
|
| 106 |
+
# embedding LayerNorm
|
| 107 |
+
trace.extend(["embeddings", "LayerNorm"])
|
| 108 |
+
pointer = getattr(pointer, "embeddings")
|
| 109 |
+
pointer = getattr(pointer, "LayerNorm")
|
| 110 |
+
elif layer_num > 3 and layer_num < config.num_hidden_layers + 4:
|
| 111 |
+
# encoder layers
|
| 112 |
+
trace.extend(["encoder", "layer", str(layer_num - 4)])
|
| 113 |
+
pointer = getattr(pointer, "encoder")
|
| 114 |
+
pointer = getattr(pointer, "layer")
|
| 115 |
+
pointer = pointer[layer_num - 4]
|
| 116 |
+
elif layer_num == config.num_hidden_layers + 4:
|
| 117 |
+
# pooler layer
|
| 118 |
+
trace.extend(["pooler", "dense"])
|
| 119 |
+
pointer = getattr(pointer, "pooler")
|
| 120 |
+
pointer = getattr(pointer, "dense")
|
| 121 |
+
elif m_name == "embeddings":
|
| 122 |
+
trace.append("embeddings")
|
| 123 |
+
pointer = getattr(pointer, "embeddings")
|
| 124 |
+
if layer_num == 0:
|
| 125 |
+
trace.append("word_embeddings")
|
| 126 |
+
pointer = getattr(pointer, "word_embeddings")
|
| 127 |
+
elif layer_num == 1:
|
| 128 |
+
trace.append("position_embeddings")
|
| 129 |
+
pointer = getattr(pointer, "position_embeddings")
|
| 130 |
+
elif layer_num == 2:
|
| 131 |
+
trace.append("token_type_embeddings")
|
| 132 |
+
pointer = getattr(pointer, "token_type_embeddings")
|
| 133 |
+
else:
|
| 134 |
+
raise ValueError(f"Unknown embedding layer with name {full_name}")
|
| 135 |
+
trace.append("weight")
|
| 136 |
+
pointer = getattr(pointer, "weight")
|
| 137 |
+
elif m_name == "_attention_layer":
|
| 138 |
+
# self-attention layer
|
| 139 |
+
trace.extend(["attention", "self"])
|
| 140 |
+
pointer = getattr(pointer, "attention")
|
| 141 |
+
pointer = getattr(pointer, "self")
|
| 142 |
+
elif m_name == "_attention_layer_norm":
|
| 143 |
+
# output attention norm
|
| 144 |
+
trace.extend(["attention", "output", "LayerNorm"])
|
| 145 |
+
pointer = getattr(pointer, "attention")
|
| 146 |
+
pointer = getattr(pointer, "output")
|
| 147 |
+
pointer = getattr(pointer, "LayerNorm")
|
| 148 |
+
elif m_name == "_attention_output_dense":
|
| 149 |
+
# output attention dense
|
| 150 |
+
trace.extend(["attention", "output", "dense"])
|
| 151 |
+
pointer = getattr(pointer, "attention")
|
| 152 |
+
pointer = getattr(pointer, "output")
|
| 153 |
+
pointer = getattr(pointer, "dense")
|
| 154 |
+
elif m_name == "_output_dense":
|
| 155 |
+
# output dense
|
| 156 |
+
trace.extend(["output", "dense"])
|
| 157 |
+
pointer = getattr(pointer, "output")
|
| 158 |
+
pointer = getattr(pointer, "dense")
|
| 159 |
+
elif m_name == "_output_layer_norm":
|
| 160 |
+
# output dense
|
| 161 |
+
trace.extend(["output", "LayerNorm"])
|
| 162 |
+
pointer = getattr(pointer, "output")
|
| 163 |
+
pointer = getattr(pointer, "LayerNorm")
|
| 164 |
+
elif m_name == "_key_dense":
|
| 165 |
+
# attention key
|
| 166 |
+
trace.append("key")
|
| 167 |
+
pointer = getattr(pointer, "key")
|
| 168 |
+
elif m_name == "_query_dense":
|
| 169 |
+
# attention query
|
| 170 |
+
trace.append("query")
|
| 171 |
+
pointer = getattr(pointer, "query")
|
| 172 |
+
elif m_name == "_value_dense":
|
| 173 |
+
# attention value
|
| 174 |
+
trace.append("value")
|
| 175 |
+
pointer = getattr(pointer, "value")
|
| 176 |
+
elif m_name == "_intermediate_dense":
|
| 177 |
+
# attention intermediate dense
|
| 178 |
+
trace.extend(["intermediate", "dense"])
|
| 179 |
+
pointer = getattr(pointer, "intermediate")
|
| 180 |
+
pointer = getattr(pointer, "dense")
|
| 181 |
+
elif m_name == "_output_layer_norm":
|
| 182 |
+
# output layer norm
|
| 183 |
+
trace.append("output")
|
| 184 |
+
pointer = getattr(pointer, "output")
|
| 185 |
+
# weights & biases
|
| 186 |
+
elif m_name in ["bias", "beta"]:
|
| 187 |
+
trace.append("bias")
|
| 188 |
+
pointer = getattr(pointer, "bias")
|
| 189 |
+
elif m_name in ["kernel", "gamma"]:
|
| 190 |
+
trace.append("weight")
|
| 191 |
+
pointer = getattr(pointer, "weight")
|
| 192 |
+
else:
|
| 193 |
+
logger.warning(f"Ignored {m_name}")
|
| 194 |
+
# for certain layers reshape is necessary
|
| 195 |
+
trace = ".".join(trace)
|
| 196 |
+
if re.match(r"(\S+)\.attention\.self\.(key|value|query)\.(bias|weight)", trace) or re.match(
|
| 197 |
+
r"(\S+)\.attention\.output\.dense\.weight", trace
|
| 198 |
+
):
|
| 199 |
+
array = array.reshape(pointer.data.shape)
|
| 200 |
+
if "kernel" in full_name:
|
| 201 |
+
array = array.transpose()
|
| 202 |
+
if pointer.shape == array.shape:
|
| 203 |
+
pointer.data = torch.from_numpy(array)
|
| 204 |
+
else:
|
| 205 |
+
raise ValueError(
|
| 206 |
+
f"Shape mismatch in layer {full_name}: Model expects shape {pointer.shape} but layer contains shape:"
|
| 207 |
+
f" {array.shape}"
|
| 208 |
+
)
|
| 209 |
+
logger.info(f"Successfully set variable {full_name} to PyTorch layer {trace}")
|
| 210 |
+
return model
|
| 211 |
+
|
| 212 |
+
|
| 213 |
+
def convert_tf2_checkpoint_to_pytorch(tf_checkpoint_path, config_path, pytorch_dump_path):
|
| 214 |
+
# Instantiate model
|
| 215 |
+
logger.info(f"Loading model based on config from {config_path}...")
|
| 216 |
+
config = BertConfig.from_json_file(config_path)
|
| 217 |
+
model = BertModel(config)
|
| 218 |
+
|
| 219 |
+
# Load weights from checkpoint
|
| 220 |
+
logger.info(f"Loading weights from checkpoint {tf_checkpoint_path}...")
|
| 221 |
+
load_tf2_weights_in_bert(model, tf_checkpoint_path, config)
|
| 222 |
+
|
| 223 |
+
# Save pytorch-model
|
| 224 |
+
logger.info(f"Saving PyTorch model to {pytorch_dump_path}...")
|
| 225 |
+
torch.save(model.state_dict(), pytorch_dump_path)
|
| 226 |
+
|
| 227 |
+
|
| 228 |
+
if __name__ == "__main__":
|
| 229 |
+
parser = argparse.ArgumentParser()
|
| 230 |
+
parser.add_argument(
|
| 231 |
+
"--tf_checkpoint_path", type=str, required=True, help="Path to the TensorFlow 2.x checkpoint path."
|
| 232 |
+
)
|
| 233 |
+
parser.add_argument(
|
| 234 |
+
"--bert_config_file",
|
| 235 |
+
type=str,
|
| 236 |
+
required=True,
|
| 237 |
+
help="The config json file corresponding to the BERT model. This specifies the model architecture.",
|
| 238 |
+
)
|
| 239 |
+
parser.add_argument(
|
| 240 |
+
"--pytorch_dump_path",
|
| 241 |
+
type=str,
|
| 242 |
+
required=True,
|
| 243 |
+
help="Path to the output PyTorch model (must include filename).",
|
| 244 |
+
)
|
| 245 |
+
args = parser.parse_args()
|
| 246 |
+
convert_tf2_checkpoint_to_pytorch(args.tf_checkpoint_path, args.bert_config_file, args.pytorch_dump_path)
|
third_party/transformers/src/transformers/models/bert/convert_bert_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 BERT checkpoint."""
|
| 15 |
+
|
| 16 |
+
import argparse
|
| 17 |
+
|
| 18 |
+
import torch
|
| 19 |
+
|
| 20 |
+
from transformers import BertConfig, BertForPreTraining, load_tf_weights_in_bert
|
| 21 |
+
from transformers.utils import logging
|
| 22 |
+
|
| 23 |
+
|
| 24 |
+
logging.set_verbosity_info()
|
| 25 |
+
|
| 26 |
+
|
| 27 |
+
def convert_tf_checkpoint_to_pytorch(tf_checkpoint_path, bert_config_file, pytorch_dump_path):
|
| 28 |
+
# Initialise PyTorch model
|
| 29 |
+
config = BertConfig.from_json_file(bert_config_file)
|
| 30 |
+
print(f"Building PyTorch model from configuration: {config}")
|
| 31 |
+
model = BertForPreTraining(config)
|
| 32 |
+
|
| 33 |
+
# Load weights from tf checkpoint
|
| 34 |
+
load_tf_weights_in_bert(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 |
+
"--bert_config_file",
|
| 49 |
+
default=None,
|
| 50 |
+
type=str,
|
| 51 |
+
required=True,
|
| 52 |
+
help=(
|
| 53 |
+
"The config json file corresponding to the pre-trained BERT 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.bert_config_file, args.pytorch_dump_path)
|
third_party/transformers/src/transformers/models/bert/convert_bert_token_dropping_original_tf2_checkpoint_to_pytorch.py
ADDED
|
@@ -0,0 +1,188 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright 2022 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 |
+
|
| 15 |
+
"""
|
| 16 |
+
This script converts a lm-head checkpoint from the "Token Dropping" implementation into a PyTorch-compatible BERT
|
| 17 |
+
model. The official implementation of "Token Dropping" can be found in the TensorFlow Models repository:
|
| 18 |
+
|
| 19 |
+
https://github.com/tensorflow/models/tree/master/official/projects/token_dropping
|
| 20 |
+
"""
|
| 21 |
+
|
| 22 |
+
import argparse
|
| 23 |
+
|
| 24 |
+
import tensorflow as tf
|
| 25 |
+
import torch
|
| 26 |
+
|
| 27 |
+
from transformers import BertConfig, BertForMaskedLM
|
| 28 |
+
from transformers.models.bert.modeling_bert import (
|
| 29 |
+
BertIntermediate,
|
| 30 |
+
BertLayer,
|
| 31 |
+
BertOutput,
|
| 32 |
+
BertPooler,
|
| 33 |
+
BertSelfAttention,
|
| 34 |
+
BertSelfOutput,
|
| 35 |
+
)
|
| 36 |
+
from transformers.utils import logging
|
| 37 |
+
|
| 38 |
+
|
| 39 |
+
logging.set_verbosity_info()
|
| 40 |
+
|
| 41 |
+
|
| 42 |
+
def convert_checkpoint_to_pytorch(tf_checkpoint_path: str, config_path: str, pytorch_dump_path: str):
|
| 43 |
+
def get_masked_lm_array(name: str):
|
| 44 |
+
full_name = f"masked_lm/{name}/.ATTRIBUTES/VARIABLE_VALUE"
|
| 45 |
+
array = tf.train.load_variable(tf_checkpoint_path, full_name)
|
| 46 |
+
|
| 47 |
+
if "kernel" in name:
|
| 48 |
+
array = array.transpose()
|
| 49 |
+
|
| 50 |
+
return torch.from_numpy(array)
|
| 51 |
+
|
| 52 |
+
def get_encoder_array(name: str):
|
| 53 |
+
full_name = f"encoder/{name}/.ATTRIBUTES/VARIABLE_VALUE"
|
| 54 |
+
array = tf.train.load_variable(tf_checkpoint_path, full_name)
|
| 55 |
+
|
| 56 |
+
if "kernel" in name:
|
| 57 |
+
array = array.transpose()
|
| 58 |
+
|
| 59 |
+
return torch.from_numpy(array)
|
| 60 |
+
|
| 61 |
+
def get_encoder_layer_array(layer_index: int, name: str):
|
| 62 |
+
full_name = f"encoder/_transformer_layers/{layer_index}/{name}/.ATTRIBUTES/VARIABLE_VALUE"
|
| 63 |
+
array = tf.train.load_variable(tf_checkpoint_path, full_name)
|
| 64 |
+
|
| 65 |
+
if "kernel" in name:
|
| 66 |
+
array = array.transpose()
|
| 67 |
+
|
| 68 |
+
return torch.from_numpy(array)
|
| 69 |
+
|
| 70 |
+
def get_encoder_attention_layer_array(layer_index: int, name: str, original_shape):
|
| 71 |
+
full_name = f"encoder/_transformer_layers/{layer_index}/_attention_layer/{name}/.ATTRIBUTES/VARIABLE_VALUE"
|
| 72 |
+
array = tf.train.load_variable(tf_checkpoint_path, full_name)
|
| 73 |
+
array = array.reshape(original_shape)
|
| 74 |
+
|
| 75 |
+
if "kernel" in name:
|
| 76 |
+
array = array.transpose()
|
| 77 |
+
|
| 78 |
+
return torch.from_numpy(array)
|
| 79 |
+
|
| 80 |
+
print(f"Loading model based on config from {config_path}...")
|
| 81 |
+
config = BertConfig.from_json_file(config_path)
|
| 82 |
+
model = BertForMaskedLM(config)
|
| 83 |
+
|
| 84 |
+
# Layers
|
| 85 |
+
for layer_index in range(0, config.num_hidden_layers):
|
| 86 |
+
layer: BertLayer = model.bert.encoder.layer[layer_index]
|
| 87 |
+
|
| 88 |
+
# Self-attention
|
| 89 |
+
self_attn: BertSelfAttention = layer.attention.self
|
| 90 |
+
|
| 91 |
+
self_attn.query.weight.data = get_encoder_attention_layer_array(
|
| 92 |
+
layer_index, "_query_dense/kernel", self_attn.query.weight.data.shape
|
| 93 |
+
)
|
| 94 |
+
self_attn.query.bias.data = get_encoder_attention_layer_array(
|
| 95 |
+
layer_index, "_query_dense/bias", self_attn.query.bias.data.shape
|
| 96 |
+
)
|
| 97 |
+
self_attn.key.weight.data = get_encoder_attention_layer_array(
|
| 98 |
+
layer_index, "_key_dense/kernel", self_attn.key.weight.data.shape
|
| 99 |
+
)
|
| 100 |
+
self_attn.key.bias.data = get_encoder_attention_layer_array(
|
| 101 |
+
layer_index, "_key_dense/bias", self_attn.key.bias.data.shape
|
| 102 |
+
)
|
| 103 |
+
self_attn.value.weight.data = get_encoder_attention_layer_array(
|
| 104 |
+
layer_index, "_value_dense/kernel", self_attn.value.weight.data.shape
|
| 105 |
+
)
|
| 106 |
+
self_attn.value.bias.data = get_encoder_attention_layer_array(
|
| 107 |
+
layer_index, "_value_dense/bias", self_attn.value.bias.data.shape
|
| 108 |
+
)
|
| 109 |
+
|
| 110 |
+
# Self-attention Output
|
| 111 |
+
self_output: BertSelfOutput = layer.attention.output
|
| 112 |
+
|
| 113 |
+
self_output.dense.weight.data = get_encoder_attention_layer_array(
|
| 114 |
+
layer_index, "_output_dense/kernel", self_output.dense.weight.data.shape
|
| 115 |
+
)
|
| 116 |
+
self_output.dense.bias.data = get_encoder_attention_layer_array(
|
| 117 |
+
layer_index, "_output_dense/bias", self_output.dense.bias.data.shape
|
| 118 |
+
)
|
| 119 |
+
|
| 120 |
+
self_output.LayerNorm.weight.data = get_encoder_layer_array(layer_index, "_attention_layer_norm/gamma")
|
| 121 |
+
self_output.LayerNorm.bias.data = get_encoder_layer_array(layer_index, "_attention_layer_norm/beta")
|
| 122 |
+
|
| 123 |
+
# Intermediate
|
| 124 |
+
intermediate: BertIntermediate = layer.intermediate
|
| 125 |
+
|
| 126 |
+
intermediate.dense.weight.data = get_encoder_layer_array(layer_index, "_intermediate_dense/kernel")
|
| 127 |
+
intermediate.dense.bias.data = get_encoder_layer_array(layer_index, "_intermediate_dense/bias")
|
| 128 |
+
|
| 129 |
+
# Output
|
| 130 |
+
bert_output: BertOutput = layer.output
|
| 131 |
+
|
| 132 |
+
bert_output.dense.weight.data = get_encoder_layer_array(layer_index, "_output_dense/kernel")
|
| 133 |
+
bert_output.dense.bias.data = get_encoder_layer_array(layer_index, "_output_dense/bias")
|
| 134 |
+
|
| 135 |
+
bert_output.LayerNorm.weight.data = get_encoder_layer_array(layer_index, "_output_layer_norm/gamma")
|
| 136 |
+
bert_output.LayerNorm.bias.data = get_encoder_layer_array(layer_index, "_output_layer_norm/beta")
|
| 137 |
+
|
| 138 |
+
# Embeddings
|
| 139 |
+
model.bert.embeddings.position_embeddings.weight.data = get_encoder_array("_position_embedding_layer/embeddings")
|
| 140 |
+
model.bert.embeddings.token_type_embeddings.weight.data = get_encoder_array("_type_embedding_layer/embeddings")
|
| 141 |
+
model.bert.embeddings.LayerNorm.weight.data = get_encoder_array("_embedding_norm_layer/gamma")
|
| 142 |
+
model.bert.embeddings.LayerNorm.bias.data = get_encoder_array("_embedding_norm_layer/beta")
|
| 143 |
+
|
| 144 |
+
# LM Head
|
| 145 |
+
lm_head = model.cls.predictions.transform
|
| 146 |
+
|
| 147 |
+
lm_head.dense.weight.data = get_masked_lm_array("dense/kernel")
|
| 148 |
+
lm_head.dense.bias.data = get_masked_lm_array("dense/bias")
|
| 149 |
+
|
| 150 |
+
lm_head.LayerNorm.weight.data = get_masked_lm_array("layer_norm/gamma")
|
| 151 |
+
lm_head.LayerNorm.bias.data = get_masked_lm_array("layer_norm/beta")
|
| 152 |
+
|
| 153 |
+
model.bert.embeddings.word_embeddings.weight.data = get_masked_lm_array("embedding_table")
|
| 154 |
+
|
| 155 |
+
# Pooling
|
| 156 |
+
model.bert.pooler = BertPooler(config=config)
|
| 157 |
+
model.bert.pooler.dense.weight.data: BertPooler = get_encoder_array("_pooler_layer/kernel")
|
| 158 |
+
model.bert.pooler.dense.bias.data: BertPooler = get_encoder_array("_pooler_layer/bias")
|
| 159 |
+
|
| 160 |
+
# Export final model
|
| 161 |
+
model.save_pretrained(pytorch_dump_path)
|
| 162 |
+
|
| 163 |
+
# Integration test - should load without any errors ;)
|
| 164 |
+
new_model = BertForMaskedLM.from_pretrained(pytorch_dump_path)
|
| 165 |
+
print(new_model.eval())
|
| 166 |
+
|
| 167 |
+
print("Model conversion was done successfully!")
|
| 168 |
+
|
| 169 |
+
|
| 170 |
+
if __name__ == "__main__":
|
| 171 |
+
parser = argparse.ArgumentParser()
|
| 172 |
+
parser.add_argument(
|
| 173 |
+
"--tf_checkpoint_path", type=str, required=True, help="Path to the TensorFlow Token Dropping checkpoint path."
|
| 174 |
+
)
|
| 175 |
+
parser.add_argument(
|
| 176 |
+
"--bert_config_file",
|
| 177 |
+
type=str,
|
| 178 |
+
required=True,
|
| 179 |
+
help="The config json file corresponding to the BERT model. This specifies the model architecture.",
|
| 180 |
+
)
|
| 181 |
+
parser.add_argument(
|
| 182 |
+
"--pytorch_dump_path",
|
| 183 |
+
type=str,
|
| 184 |
+
required=True,
|
| 185 |
+
help="Path to the output PyTorch model.",
|
| 186 |
+
)
|
| 187 |
+
args = parser.parse_args()
|
| 188 |
+
convert_checkpoint_to_pytorch(args.tf_checkpoint_path, args.bert_config_file, args.pytorch_dump_path)
|
third_party/transformers/src/transformers/models/bert/modeling_bert.py
ADDED
|
@@ -0,0 +1,1395 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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 |
+
"""PyTorch BERT model."""
|
| 16 |
+
|
| 17 |
+
from collections.abc import Callable
|
| 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 ...cache_utils import Cache, DynamicCache, EncoderDecoderCache
|
| 27 |
+
from ...generation import GenerationMixin
|
| 28 |
+
from ...masking_utils import create_bidirectional_mask, create_causal_mask
|
| 29 |
+
from ...modeling_layers import GradientCheckpointingLayer
|
| 30 |
+
from ...modeling_outputs import (
|
| 31 |
+
BaseModelOutputWithPastAndCrossAttentions,
|
| 32 |
+
BaseModelOutputWithPoolingAndCrossAttentions,
|
| 33 |
+
CausalLMOutputWithCrossAttentions,
|
| 34 |
+
MaskedLMOutput,
|
| 35 |
+
MultipleChoiceModelOutput,
|
| 36 |
+
NextSentencePredictorOutput,
|
| 37 |
+
QuestionAnsweringModelOutput,
|
| 38 |
+
SequenceClassifierOutput,
|
| 39 |
+
TokenClassifierOutput,
|
| 40 |
+
)
|
| 41 |
+
from ...modeling_utils import ALL_ATTENTION_FUNCTIONS, PreTrainedModel
|
| 42 |
+
from ...processing_utils import Unpack
|
| 43 |
+
from ...pytorch_utils import apply_chunking_to_forward
|
| 44 |
+
from ...utils import ModelOutput, TransformersKwargs, auto_docstring, logging
|
| 45 |
+
from ...utils.generic import can_return_tuple, merge_with_config_defaults
|
| 46 |
+
from ...utils.output_capturing import capture_outputs
|
| 47 |
+
from .configuration_bert import BertConfig
|
| 48 |
+
|
| 49 |
+
|
| 50 |
+
logger = logging.get_logger(__name__)
|
| 51 |
+
|
| 52 |
+
|
| 53 |
+
class BertEmbeddings(nn.Module):
|
| 54 |
+
"""Construct the embeddings from word, position and token_type embeddings."""
|
| 55 |
+
|
| 56 |
+
def __init__(self, config):
|
| 57 |
+
super().__init__()
|
| 58 |
+
self.word_embeddings = nn.Embedding(config.vocab_size, config.hidden_size, padding_idx=config.pad_token_id)
|
| 59 |
+
self.position_embeddings = nn.Embedding(config.max_position_embeddings, config.hidden_size)
|
| 60 |
+
self.token_type_embeddings = nn.Embedding(config.type_vocab_size, config.hidden_size)
|
| 61 |
+
|
| 62 |
+
self.LayerNorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps)
|
| 63 |
+
self.dropout = nn.Dropout(config.hidden_dropout_prob)
|
| 64 |
+
# position_ids (1, len position emb) is contiguous in memory and exported when serialized
|
| 65 |
+
self.register_buffer(
|
| 66 |
+
"position_ids", torch.arange(config.max_position_embeddings).expand((1, -1)), persistent=False
|
| 67 |
+
)
|
| 68 |
+
self.register_buffer(
|
| 69 |
+
"token_type_ids", torch.zeros(self.position_ids.size(), dtype=torch.long), persistent=False
|
| 70 |
+
)
|
| 71 |
+
|
| 72 |
+
def forward(
|
| 73 |
+
self,
|
| 74 |
+
input_ids: torch.LongTensor | None = None,
|
| 75 |
+
token_type_ids: torch.LongTensor | None = None,
|
| 76 |
+
position_ids: torch.LongTensor | None = None,
|
| 77 |
+
inputs_embeds: torch.FloatTensor | None = None,
|
| 78 |
+
past_key_values_length: int = 0,
|
| 79 |
+
) -> torch.Tensor:
|
| 80 |
+
if input_ids is not None:
|
| 81 |
+
input_shape = input_ids.size()
|
| 82 |
+
else:
|
| 83 |
+
input_shape = inputs_embeds.size()[:-1]
|
| 84 |
+
|
| 85 |
+
batch_size, seq_length = input_shape
|
| 86 |
+
|
| 87 |
+
if position_ids is None:
|
| 88 |
+
position_ids = self.position_ids[:, past_key_values_length : seq_length + past_key_values_length]
|
| 89 |
+
|
| 90 |
+
# Setting the token_type_ids to the registered buffer in constructor where it is all zeros, which usually occurs
|
| 91 |
+
# when its auto-generated, registered buffer helps users when tracing the model without passing token_type_ids, solves
|
| 92 |
+
# issue #5664
|
| 93 |
+
if token_type_ids is None:
|
| 94 |
+
if hasattr(self, "token_type_ids"):
|
| 95 |
+
# NOTE: We assume either pos ids to have bsz == 1 (broadcastable) or bsz == effective bsz (input_shape[0])
|
| 96 |
+
buffered_token_type_ids = self.token_type_ids.expand(position_ids.shape[0], -1)
|
| 97 |
+
buffered_token_type_ids = torch.gather(buffered_token_type_ids, dim=1, index=position_ids)
|
| 98 |
+
token_type_ids = buffered_token_type_ids.expand(batch_size, seq_length)
|
| 99 |
+
else:
|
| 100 |
+
token_type_ids = torch.zeros(input_shape, dtype=torch.long, device=self.position_ids.device)
|
| 101 |
+
|
| 102 |
+
if inputs_embeds is None:
|
| 103 |
+
inputs_embeds = self.word_embeddings(input_ids)
|
| 104 |
+
token_type_embeddings = self.token_type_embeddings(token_type_ids)
|
| 105 |
+
embeddings = inputs_embeds + token_type_embeddings
|
| 106 |
+
|
| 107 |
+
position_embeddings = self.position_embeddings(position_ids)
|
| 108 |
+
embeddings = embeddings + position_embeddings
|
| 109 |
+
|
| 110 |
+
embeddings = self.LayerNorm(embeddings)
|
| 111 |
+
embeddings = self.dropout(embeddings)
|
| 112 |
+
return embeddings
|
| 113 |
+
|
| 114 |
+
|
| 115 |
+
def eager_attention_forward(
|
| 116 |
+
module: nn.Module,
|
| 117 |
+
query: torch.Tensor,
|
| 118 |
+
key: torch.Tensor,
|
| 119 |
+
value: torch.Tensor,
|
| 120 |
+
attention_mask: torch.Tensor | None,
|
| 121 |
+
scaling: float | None = None,
|
| 122 |
+
dropout: float = 0.0,
|
| 123 |
+
**kwargs: Unpack[TransformersKwargs],
|
| 124 |
+
):
|
| 125 |
+
if scaling is None:
|
| 126 |
+
scaling = query.size(-1) ** -0.5
|
| 127 |
+
|
| 128 |
+
# Take the dot product between "query" and "key" to get the raw attention scores.
|
| 129 |
+
attn_weights = torch.matmul(query, key.transpose(2, 3)) * scaling
|
| 130 |
+
|
| 131 |
+
if attention_mask is not None:
|
| 132 |
+
attn_weights = attn_weights + attention_mask
|
| 133 |
+
|
| 134 |
+
attn_weights = nn.functional.softmax(attn_weights, dim=-1)
|
| 135 |
+
attn_weights = nn.functional.dropout(attn_weights, p=dropout, training=module.training)
|
| 136 |
+
|
| 137 |
+
attn_output = torch.matmul(attn_weights, value)
|
| 138 |
+
attn_output = attn_output.transpose(1, 2).contiguous()
|
| 139 |
+
|
| 140 |
+
return attn_output, attn_weights
|
| 141 |
+
|
| 142 |
+
|
| 143 |
+
class BertSelfAttention(nn.Module):
|
| 144 |
+
def __init__(self, config, is_causal=False, layer_idx=None):
|
| 145 |
+
super().__init__()
|
| 146 |
+
if config.hidden_size % config.num_attention_heads != 0 and not hasattr(config, "embedding_size"):
|
| 147 |
+
raise ValueError(
|
| 148 |
+
f"The hidden size ({config.hidden_size}) is not a multiple of the number of attention "
|
| 149 |
+
f"heads ({config.num_attention_heads})"
|
| 150 |
+
)
|
| 151 |
+
self.config = config
|
| 152 |
+
|
| 153 |
+
self.num_attention_heads = config.num_attention_heads
|
| 154 |
+
self.attention_head_size = int(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.query = nn.Linear(config.hidden_size, self.all_head_size)
|
| 159 |
+
self.key = nn.Linear(config.hidden_size, self.all_head_size)
|
| 160 |
+
self.value = nn.Linear(config.hidden_size, self.all_head_size)
|
| 161 |
+
|
| 162 |
+
self.dropout = nn.Dropout(config.attention_probs_dropout_prob)
|
| 163 |
+
|
| 164 |
+
self.is_decoder = config.is_decoder
|
| 165 |
+
self.is_causal = is_causal
|
| 166 |
+
self.layer_idx = layer_idx
|
| 167 |
+
|
| 168 |
+
def forward(
|
| 169 |
+
self,
|
| 170 |
+
hidden_states: torch.Tensor,
|
| 171 |
+
attention_mask: torch.FloatTensor | None = None,
|
| 172 |
+
past_key_values: Cache | None = None,
|
| 173 |
+
**kwargs: Unpack[TransformersKwargs],
|
| 174 |
+
) -> tuple[torch.Tensor]:
|
| 175 |
+
input_shape = hidden_states.shape[:-1]
|
| 176 |
+
hidden_shape = (*input_shape, -1, self.attention_head_size)
|
| 177 |
+
|
| 178 |
+
# get all proj
|
| 179 |
+
query_layer = self.query(hidden_states).view(*hidden_shape).transpose(1, 2)
|
| 180 |
+
key_layer = self.key(hidden_states).view(*hidden_shape).transpose(1, 2)
|
| 181 |
+
value_layer = self.value(hidden_states).view(*hidden_shape).transpose(1, 2)
|
| 182 |
+
|
| 183 |
+
if past_key_values is not None:
|
| 184 |
+
# decoder-only bert can have a simple dynamic cache for example
|
| 185 |
+
current_past_key_values = past_key_values
|
| 186 |
+
if isinstance(past_key_values, EncoderDecoderCache):
|
| 187 |
+
current_past_key_values = past_key_values.self_attention_cache
|
| 188 |
+
|
| 189 |
+
# save all key/value_layer to cache to be re-used for fast auto-regressive generation
|
| 190 |
+
key_layer, value_layer = current_past_key_values.update(key_layer, value_layer, self.layer_idx)
|
| 191 |
+
|
| 192 |
+
attention_interface: Callable = ALL_ATTENTION_FUNCTIONS.get_interface(
|
| 193 |
+
self.config._attn_implementation, eager_attention_forward
|
| 194 |
+
)
|
| 195 |
+
|
| 196 |
+
attn_output, attn_weights = attention_interface(
|
| 197 |
+
self,
|
| 198 |
+
query_layer,
|
| 199 |
+
key_layer,
|
| 200 |
+
value_layer,
|
| 201 |
+
attention_mask,
|
| 202 |
+
dropout=0.0 if not self.training else self.dropout.p,
|
| 203 |
+
scaling=self.scaling,
|
| 204 |
+
**kwargs,
|
| 205 |
+
)
|
| 206 |
+
attn_output = attn_output.reshape(*input_shape, -1).contiguous()
|
| 207 |
+
return attn_output, attn_weights
|
| 208 |
+
|
| 209 |
+
|
| 210 |
+
class BertCrossAttention(nn.Module):
|
| 211 |
+
def __init__(self, config, is_causal=False, layer_idx=None):
|
| 212 |
+
super().__init__()
|
| 213 |
+
if config.hidden_size % config.num_attention_heads != 0 and not hasattr(config, "embedding_size"):
|
| 214 |
+
raise ValueError(
|
| 215 |
+
f"The hidden size ({config.hidden_size}) is not a multiple of the number of attention "
|
| 216 |
+
f"heads ({config.num_attention_heads})"
|
| 217 |
+
)
|
| 218 |
+
self.config = config
|
| 219 |
+
|
| 220 |
+
self.num_attention_heads = config.num_attention_heads
|
| 221 |
+
self.attention_head_size = int(config.hidden_size / config.num_attention_heads)
|
| 222 |
+
self.all_head_size = self.num_attention_heads * self.attention_head_size
|
| 223 |
+
self.scaling = self.attention_head_size**-0.5
|
| 224 |
+
|
| 225 |
+
self.query = nn.Linear(config.hidden_size, self.all_head_size)
|
| 226 |
+
self.key = nn.Linear(config.hidden_size, self.all_head_size)
|
| 227 |
+
self.value = nn.Linear(config.hidden_size, self.all_head_size)
|
| 228 |
+
|
| 229 |
+
self.dropout = nn.Dropout(config.attention_probs_dropout_prob)
|
| 230 |
+
|
| 231 |
+
self.is_causal = is_causal
|
| 232 |
+
self.layer_idx = layer_idx
|
| 233 |
+
|
| 234 |
+
def forward(
|
| 235 |
+
self,
|
| 236 |
+
hidden_states: torch.Tensor,
|
| 237 |
+
encoder_hidden_states: torch.FloatTensor | None = None,
|
| 238 |
+
attention_mask: torch.FloatTensor | None = None,
|
| 239 |
+
past_key_values: EncoderDecoderCache | None = None,
|
| 240 |
+
**kwargs: Unpack[TransformersKwargs],
|
| 241 |
+
) -> tuple[torch.Tensor]:
|
| 242 |
+
# determine input shapes
|
| 243 |
+
bsz, tgt_len = hidden_states.shape[:-1]
|
| 244 |
+
src_len = encoder_hidden_states.shape[1]
|
| 245 |
+
|
| 246 |
+
q_input_shape = (bsz, tgt_len, -1, self.attention_head_size)
|
| 247 |
+
kv_input_shape = (bsz, src_len, -1, self.attention_head_size)
|
| 248 |
+
|
| 249 |
+
# get query proj
|
| 250 |
+
query_layer = self.query(hidden_states).view(*q_input_shape).transpose(1, 2)
|
| 251 |
+
|
| 252 |
+
is_updated = past_key_values.is_updated.get(self.layer_idx) if past_key_values is not None else False
|
| 253 |
+
if past_key_values is not None and is_updated:
|
| 254 |
+
# reuse k,v, cross_attentions
|
| 255 |
+
key_layer = past_key_values.cross_attention_cache.layers[self.layer_idx].keys
|
| 256 |
+
value_layer = past_key_values.cross_attention_cache.layers[self.layer_idx].values
|
| 257 |
+
else:
|
| 258 |
+
key_layer = self.key(encoder_hidden_states).view(*kv_input_shape).transpose(1, 2)
|
| 259 |
+
value_layer = self.value(encoder_hidden_states).view(*kv_input_shape).transpose(1, 2)
|
| 260 |
+
|
| 261 |
+
if past_key_values is not None:
|
| 262 |
+
# save all states to the cache
|
| 263 |
+
key_layer, value_layer = past_key_values.cross_attention_cache.update(
|
| 264 |
+
key_layer, value_layer, self.layer_idx
|
| 265 |
+
)
|
| 266 |
+
# set flag that curr layer for cross-attn is already updated so we can re-use in subsequent calls
|
| 267 |
+
past_key_values.is_updated[self.layer_idx] = True
|
| 268 |
+
|
| 269 |
+
attention_interface: Callable = ALL_ATTENTION_FUNCTIONS.get_interface(
|
| 270 |
+
self.config._attn_implementation, eager_attention_forward
|
| 271 |
+
)
|
| 272 |
+
|
| 273 |
+
attn_output, attn_weights = attention_interface(
|
| 274 |
+
self,
|
| 275 |
+
query_layer,
|
| 276 |
+
key_layer,
|
| 277 |
+
value_layer,
|
| 278 |
+
attention_mask,
|
| 279 |
+
dropout=0.0 if not self.training else self.dropout.p,
|
| 280 |
+
scaling=self.scaling,
|
| 281 |
+
**kwargs,
|
| 282 |
+
)
|
| 283 |
+
attn_output = attn_output.reshape(bsz, tgt_len, -1).contiguous()
|
| 284 |
+
return attn_output, attn_weights
|
| 285 |
+
|
| 286 |
+
|
| 287 |
+
class BertSelfOutput(nn.Module):
|
| 288 |
+
def __init__(self, config):
|
| 289 |
+
super().__init__()
|
| 290 |
+
self.dense = nn.Linear(config.hidden_size, config.hidden_size)
|
| 291 |
+
self.LayerNorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps)
|
| 292 |
+
self.dropout = nn.Dropout(config.hidden_dropout_prob)
|
| 293 |
+
|
| 294 |
+
def forward(self, hidden_states: torch.Tensor, input_tensor: torch.Tensor) -> torch.Tensor:
|
| 295 |
+
hidden_states = self.dense(hidden_states)
|
| 296 |
+
hidden_states = self.dropout(hidden_states)
|
| 297 |
+
hidden_states = self.LayerNorm(hidden_states + input_tensor)
|
| 298 |
+
return hidden_states
|
| 299 |
+
|
| 300 |
+
|
| 301 |
+
class BertAttention(nn.Module):
|
| 302 |
+
def __init__(self, config, is_causal=False, layer_idx=None, is_cross_attention=False):
|
| 303 |
+
super().__init__()
|
| 304 |
+
self.is_cross_attention = is_cross_attention
|
| 305 |
+
attention_class = BertCrossAttention if is_cross_attention else BertSelfAttention
|
| 306 |
+
self.self = attention_class(config, is_causal=is_causal, layer_idx=layer_idx)
|
| 307 |
+
self.output = BertSelfOutput(config)
|
| 308 |
+
|
| 309 |
+
def forward(
|
| 310 |
+
self,
|
| 311 |
+
hidden_states: torch.Tensor,
|
| 312 |
+
attention_mask: torch.FloatTensor | None = None,
|
| 313 |
+
encoder_hidden_states: torch.FloatTensor | None = None,
|
| 314 |
+
encoder_attention_mask: torch.FloatTensor | None = None,
|
| 315 |
+
past_key_values: Cache | None = None,
|
| 316 |
+
**kwargs: Unpack[TransformersKwargs],
|
| 317 |
+
) -> tuple[torch.Tensor]:
|
| 318 |
+
attention_mask = attention_mask if not self.is_cross_attention else encoder_attention_mask
|
| 319 |
+
attention_output, attn_weights = self.self(
|
| 320 |
+
hidden_states,
|
| 321 |
+
encoder_hidden_states=encoder_hidden_states,
|
| 322 |
+
attention_mask=attention_mask,
|
| 323 |
+
past_key_values=past_key_values,
|
| 324 |
+
**kwargs,
|
| 325 |
+
)
|
| 326 |
+
attention_output = self.output(attention_output, hidden_states)
|
| 327 |
+
return attention_output, attn_weights
|
| 328 |
+
|
| 329 |
+
|
| 330 |
+
class BertIntermediate(nn.Module):
|
| 331 |
+
def __init__(self, config):
|
| 332 |
+
super().__init__()
|
| 333 |
+
self.dense = nn.Linear(config.hidden_size, config.intermediate_size)
|
| 334 |
+
if isinstance(config.hidden_act, str):
|
| 335 |
+
self.intermediate_act_fn = ACT2FN[config.hidden_act]
|
| 336 |
+
else:
|
| 337 |
+
self.intermediate_act_fn = config.hidden_act
|
| 338 |
+
|
| 339 |
+
def forward(self, hidden_states: torch.Tensor) -> torch.Tensor:
|
| 340 |
+
hidden_states = self.dense(hidden_states)
|
| 341 |
+
hidden_states = self.intermediate_act_fn(hidden_states)
|
| 342 |
+
return hidden_states
|
| 343 |
+
|
| 344 |
+
|
| 345 |
+
class BertOutput(nn.Module):
|
| 346 |
+
def __init__(self, config):
|
| 347 |
+
super().__init__()
|
| 348 |
+
self.dense = nn.Linear(config.intermediate_size, config.hidden_size)
|
| 349 |
+
self.LayerNorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps)
|
| 350 |
+
self.dropout = nn.Dropout(config.hidden_dropout_prob)
|
| 351 |
+
|
| 352 |
+
def forward(self, hidden_states: torch.Tensor, input_tensor: torch.Tensor) -> torch.Tensor:
|
| 353 |
+
hidden_states = self.dense(hidden_states)
|
| 354 |
+
hidden_states = self.dropout(hidden_states)
|
| 355 |
+
hidden_states = self.LayerNorm(hidden_states + input_tensor)
|
| 356 |
+
return hidden_states
|
| 357 |
+
|
| 358 |
+
|
| 359 |
+
class BertLayer(GradientCheckpointingLayer):
|
| 360 |
+
def __init__(self, config, layer_idx=None):
|
| 361 |
+
super().__init__()
|
| 362 |
+
self.chunk_size_feed_forward = config.chunk_size_feed_forward
|
| 363 |
+
self.seq_len_dim = 1
|
| 364 |
+
self.attention = BertAttention(config, is_causal=config.is_decoder, layer_idx=layer_idx)
|
| 365 |
+
self.is_decoder = config.is_decoder
|
| 366 |
+
self.add_cross_attention = config.add_cross_attention
|
| 367 |
+
if self.add_cross_attention:
|
| 368 |
+
if not self.is_decoder:
|
| 369 |
+
raise ValueError(f"{self} should be used as a decoder model if cross attention is added")
|
| 370 |
+
self.crossattention = BertAttention(
|
| 371 |
+
config,
|
| 372 |
+
is_causal=False,
|
| 373 |
+
layer_idx=layer_idx,
|
| 374 |
+
is_cross_attention=True,
|
| 375 |
+
)
|
| 376 |
+
self.intermediate = BertIntermediate(config)
|
| 377 |
+
self.output = BertOutput(config)
|
| 378 |
+
|
| 379 |
+
def forward(
|
| 380 |
+
self,
|
| 381 |
+
hidden_states: torch.Tensor,
|
| 382 |
+
attention_mask: torch.FloatTensor | None = None,
|
| 383 |
+
encoder_hidden_states: torch.FloatTensor | None = None,
|
| 384 |
+
encoder_attention_mask: torch.FloatTensor | None = None,
|
| 385 |
+
past_key_values: Cache | None = None,
|
| 386 |
+
**kwargs: Unpack[TransformersKwargs],
|
| 387 |
+
) -> torch.Tensor:
|
| 388 |
+
self_attention_output, _ = self.attention(
|
| 389 |
+
hidden_states,
|
| 390 |
+
attention_mask,
|
| 391 |
+
past_key_values=past_key_values,
|
| 392 |
+
**kwargs,
|
| 393 |
+
)
|
| 394 |
+
attention_output = self_attention_output
|
| 395 |
+
|
| 396 |
+
if self.is_decoder and encoder_hidden_states is not None:
|
| 397 |
+
if not hasattr(self, "crossattention"):
|
| 398 |
+
raise ValueError(
|
| 399 |
+
f"If `encoder_hidden_states` are passed, {self} has to be instantiated with cross-attention layers"
|
| 400 |
+
" by setting `config.add_cross_attention=True`"
|
| 401 |
+
)
|
| 402 |
+
|
| 403 |
+
cross_attention_output, _ = self.crossattention(
|
| 404 |
+
self_attention_output,
|
| 405 |
+
None, # attention_mask
|
| 406 |
+
encoder_hidden_states,
|
| 407 |
+
encoder_attention_mask,
|
| 408 |
+
past_key_values=past_key_values,
|
| 409 |
+
**kwargs,
|
| 410 |
+
)
|
| 411 |
+
attention_output = cross_attention_output
|
| 412 |
+
|
| 413 |
+
layer_output = apply_chunking_to_forward(
|
| 414 |
+
self.feed_forward_chunk, self.chunk_size_feed_forward, self.seq_len_dim, attention_output
|
| 415 |
+
)
|
| 416 |
+
return layer_output
|
| 417 |
+
|
| 418 |
+
def feed_forward_chunk(self, attention_output):
|
| 419 |
+
intermediate_output = self.intermediate(attention_output)
|
| 420 |
+
layer_output = self.output(intermediate_output, attention_output)
|
| 421 |
+
return layer_output
|
| 422 |
+
|
| 423 |
+
|
| 424 |
+
class BertEncoder(nn.Module):
|
| 425 |
+
def __init__(self, config):
|
| 426 |
+
super().__init__()
|
| 427 |
+
self.config = config
|
| 428 |
+
self.layer = nn.ModuleList([BertLayer(config, layer_idx=i) for i in range(config.num_hidden_layers)])
|
| 429 |
+
|
| 430 |
+
def forward(
|
| 431 |
+
self,
|
| 432 |
+
hidden_states: torch.Tensor,
|
| 433 |
+
attention_mask: torch.FloatTensor | None = None,
|
| 434 |
+
encoder_hidden_states: torch.FloatTensor | None = None,
|
| 435 |
+
encoder_attention_mask: torch.FloatTensor | None = None,
|
| 436 |
+
past_key_values: Cache | None = None,
|
| 437 |
+
use_cache: bool | None = None,
|
| 438 |
+
**kwargs: Unpack[TransformersKwargs],
|
| 439 |
+
) -> tuple[torch.Tensor] | BaseModelOutputWithPastAndCrossAttentions:
|
| 440 |
+
for i, layer_module in enumerate(self.layer):
|
| 441 |
+
hidden_states = layer_module(
|
| 442 |
+
hidden_states,
|
| 443 |
+
attention_mask,
|
| 444 |
+
encoder_hidden_states, # as a positional argument for gradient checkpointing
|
| 445 |
+
encoder_attention_mask=encoder_attention_mask,
|
| 446 |
+
past_key_values=past_key_values,
|
| 447 |
+
**kwargs,
|
| 448 |
+
)
|
| 449 |
+
|
| 450 |
+
return BaseModelOutputWithPastAndCrossAttentions(
|
| 451 |
+
last_hidden_state=hidden_states,
|
| 452 |
+
past_key_values=past_key_values if use_cache else None,
|
| 453 |
+
)
|
| 454 |
+
|
| 455 |
+
|
| 456 |
+
class BertPooler(nn.Module):
|
| 457 |
+
def __init__(self, config):
|
| 458 |
+
super().__init__()
|
| 459 |
+
self.dense = nn.Linear(config.hidden_size, config.hidden_size)
|
| 460 |
+
self.activation = nn.Tanh()
|
| 461 |
+
|
| 462 |
+
def forward(self, hidden_states: torch.Tensor) -> torch.Tensor:
|
| 463 |
+
# We "pool" the model by simply taking the hidden state corresponding
|
| 464 |
+
# to the first token.
|
| 465 |
+
first_token_tensor = hidden_states[:, 0]
|
| 466 |
+
pooled_output = self.dense(first_token_tensor)
|
| 467 |
+
pooled_output = self.activation(pooled_output)
|
| 468 |
+
return pooled_output
|
| 469 |
+
|
| 470 |
+
|
| 471 |
+
class BertPredictionHeadTransform(nn.Module):
|
| 472 |
+
def __init__(self, config):
|
| 473 |
+
super().__init__()
|
| 474 |
+
self.dense = nn.Linear(config.hidden_size, config.hidden_size)
|
| 475 |
+
if isinstance(config.hidden_act, str):
|
| 476 |
+
self.transform_act_fn = ACT2FN[config.hidden_act]
|
| 477 |
+
else:
|
| 478 |
+
self.transform_act_fn = config.hidden_act
|
| 479 |
+
self.LayerNorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps)
|
| 480 |
+
|
| 481 |
+
def forward(self, hidden_states: torch.Tensor) -> torch.Tensor:
|
| 482 |
+
hidden_states = self.dense(hidden_states)
|
| 483 |
+
hidden_states = self.transform_act_fn(hidden_states)
|
| 484 |
+
hidden_states = self.LayerNorm(hidden_states)
|
| 485 |
+
return hidden_states
|
| 486 |
+
|
| 487 |
+
|
| 488 |
+
class BertLMPredictionHead(nn.Module):
|
| 489 |
+
def __init__(self, config):
|
| 490 |
+
super().__init__()
|
| 491 |
+
self.transform = BertPredictionHeadTransform(config)
|
| 492 |
+
|
| 493 |
+
# The output weights are the same as the input embeddings, but there is
|
| 494 |
+
# an output-only bias for each token.
|
| 495 |
+
self.decoder = nn.Linear(config.hidden_size, config.vocab_size, bias=True)
|
| 496 |
+
self.bias = nn.Parameter(torch.zeros(config.vocab_size))
|
| 497 |
+
|
| 498 |
+
def forward(self, hidden_states):
|
| 499 |
+
hidden_states = self.transform(hidden_states)
|
| 500 |
+
hidden_states = self.decoder(hidden_states)
|
| 501 |
+
return hidden_states
|
| 502 |
+
|
| 503 |
+
|
| 504 |
+
class BertOnlyMLMHead(nn.Module):
|
| 505 |
+
def __init__(self, config):
|
| 506 |
+
super().__init__()
|
| 507 |
+
self.predictions = BertLMPredictionHead(config)
|
| 508 |
+
|
| 509 |
+
def forward(self, sequence_output: torch.Tensor) -> torch.Tensor:
|
| 510 |
+
prediction_scores = self.predictions(sequence_output)
|
| 511 |
+
return prediction_scores
|
| 512 |
+
|
| 513 |
+
|
| 514 |
+
class BertOnlyNSPHead(nn.Module):
|
| 515 |
+
def __init__(self, config):
|
| 516 |
+
super().__init__()
|
| 517 |
+
self.seq_relationship = nn.Linear(config.hidden_size, 2)
|
| 518 |
+
|
| 519 |
+
def forward(self, pooled_output):
|
| 520 |
+
seq_relationship_score = self.seq_relationship(pooled_output)
|
| 521 |
+
return seq_relationship_score
|
| 522 |
+
|
| 523 |
+
|
| 524 |
+
class BertPreTrainingHeads(nn.Module):
|
| 525 |
+
def __init__(self, config):
|
| 526 |
+
super().__init__()
|
| 527 |
+
self.predictions = BertLMPredictionHead(config)
|
| 528 |
+
self.seq_relationship = nn.Linear(config.hidden_size, 2)
|
| 529 |
+
|
| 530 |
+
def forward(self, sequence_output, pooled_output):
|
| 531 |
+
prediction_scores = self.predictions(sequence_output)
|
| 532 |
+
seq_relationship_score = self.seq_relationship(pooled_output)
|
| 533 |
+
return prediction_scores, seq_relationship_score
|
| 534 |
+
|
| 535 |
+
|
| 536 |
+
@auto_docstring
|
| 537 |
+
class BertPreTrainedModel(PreTrainedModel):
|
| 538 |
+
config_class = BertConfig
|
| 539 |
+
base_model_prefix = "bert"
|
| 540 |
+
supports_gradient_checkpointing = True
|
| 541 |
+
_supports_flash_attn = True
|
| 542 |
+
_supports_sdpa = True
|
| 543 |
+
_supports_flex_attn = True
|
| 544 |
+
_supports_attention_backend = True
|
| 545 |
+
_can_record_outputs = {
|
| 546 |
+
"hidden_states": BertLayer,
|
| 547 |
+
"attentions": BertSelfAttention,
|
| 548 |
+
"cross_attentions": BertCrossAttention,
|
| 549 |
+
}
|
| 550 |
+
|
| 551 |
+
@torch.no_grad()
|
| 552 |
+
def _init_weights(self, module):
|
| 553 |
+
"""Initialize the weights"""
|
| 554 |
+
super()._init_weights(module)
|
| 555 |
+
if isinstance(module, BertLMPredictionHead):
|
| 556 |
+
init.zeros_(module.bias)
|
| 557 |
+
elif isinstance(module, BertEmbeddings):
|
| 558 |
+
init.copy_(module.position_ids, torch.arange(module.position_ids.shape[-1]).expand((1, -1)))
|
| 559 |
+
init.zeros_(module.token_type_ids)
|
| 560 |
+
|
| 561 |
+
|
| 562 |
+
@dataclass
|
| 563 |
+
@auto_docstring(
|
| 564 |
+
custom_intro="""
|
| 565 |
+
Output type of [`BertForPreTraining`].
|
| 566 |
+
"""
|
| 567 |
+
)
|
| 568 |
+
class BertForPreTrainingOutput(ModelOutput):
|
| 569 |
+
r"""
|
| 570 |
+
loss (*optional*, returned when `labels` is provided, `torch.FloatTensor` of shape `(1,)`):
|
| 571 |
+
Total loss as the sum of the masked language modeling loss and the next sequence prediction
|
| 572 |
+
(classification) loss.
|
| 573 |
+
prediction_logits (`torch.FloatTensor` of shape `(batch_size, sequence_length, config.vocab_size)`):
|
| 574 |
+
Prediction scores of the language modeling head (scores for each vocabulary token before SoftMax).
|
| 575 |
+
seq_relationship_logits (`torch.FloatTensor` of shape `(batch_size, 2)`):
|
| 576 |
+
Prediction scores of the next sequence prediction (classification) head (scores of True/False continuation
|
| 577 |
+
before SoftMax).
|
| 578 |
+
"""
|
| 579 |
+
|
| 580 |
+
loss: torch.FloatTensor | None = None
|
| 581 |
+
prediction_logits: torch.FloatTensor | None = None
|
| 582 |
+
seq_relationship_logits: torch.FloatTensor | None = None
|
| 583 |
+
hidden_states: tuple[torch.FloatTensor] | None = None
|
| 584 |
+
attentions: tuple[torch.FloatTensor] | None = None
|
| 585 |
+
|
| 586 |
+
|
| 587 |
+
@auto_docstring(
|
| 588 |
+
custom_intro="""
|
| 589 |
+
The model can behave as an encoder (with only self-attention) as well as a decoder, in which case a layer of
|
| 590 |
+
cross-attention is added between the self-attention layers, following the architecture described in [Attention is
|
| 591 |
+
all you need](https://huggingface.co/papers/1706.03762) by Ashish Vaswani, Noam Shazeer, Niki Parmar, Jakob Uszkoreit,
|
| 592 |
+
Llion Jones, Aidan N. Gomez, Lukasz Kaiser and Illia Polosukhin.
|
| 593 |
+
|
| 594 |
+
To behave as an decoder the model needs to be initialized with the `is_decoder` argument of the configuration set
|
| 595 |
+
to `True`. To be used in a Seq2Seq model, the model needs to initialized with both `is_decoder` argument and
|
| 596 |
+
`add_cross_attention` set to `True`; an `encoder_hidden_states` is then expected as an input to the forward pass.
|
| 597 |
+
"""
|
| 598 |
+
)
|
| 599 |
+
class BertModel(BertPreTrainedModel):
|
| 600 |
+
_no_split_modules = ["BertEmbeddings", "BertLayer"]
|
| 601 |
+
|
| 602 |
+
def __init__(self, config, add_pooling_layer=True):
|
| 603 |
+
r"""
|
| 604 |
+
add_pooling_layer (bool, *optional*, defaults to `True`):
|
| 605 |
+
Whether to add a pooling layer
|
| 606 |
+
"""
|
| 607 |
+
super().__init__(config)
|
| 608 |
+
self.config = config
|
| 609 |
+
self.gradient_checkpointing = False
|
| 610 |
+
|
| 611 |
+
self.embeddings = BertEmbeddings(config)
|
| 612 |
+
self.encoder = BertEncoder(config)
|
| 613 |
+
|
| 614 |
+
self.pooler = BertPooler(config) if add_pooling_layer else None
|
| 615 |
+
|
| 616 |
+
# Initialize weights and apply final processing
|
| 617 |
+
self.post_init()
|
| 618 |
+
|
| 619 |
+
def get_input_embeddings(self):
|
| 620 |
+
return self.embeddings.word_embeddings
|
| 621 |
+
|
| 622 |
+
def set_input_embeddings(self, value):
|
| 623 |
+
self.embeddings.word_embeddings = value
|
| 624 |
+
|
| 625 |
+
@merge_with_config_defaults
|
| 626 |
+
@capture_outputs
|
| 627 |
+
@auto_docstring
|
| 628 |
+
def forward(
|
| 629 |
+
self,
|
| 630 |
+
input_ids: torch.Tensor | None = None,
|
| 631 |
+
attention_mask: torch.Tensor | None = None,
|
| 632 |
+
token_type_ids: torch.Tensor | None = None,
|
| 633 |
+
position_ids: torch.Tensor | None = None,
|
| 634 |
+
inputs_embeds: torch.Tensor | None = None,
|
| 635 |
+
encoder_hidden_states: torch.Tensor | None = None,
|
| 636 |
+
encoder_attention_mask: torch.Tensor | None = None,
|
| 637 |
+
past_key_values: Cache | None = None,
|
| 638 |
+
use_cache: bool | None = None,
|
| 639 |
+
**kwargs: Unpack[TransformersKwargs],
|
| 640 |
+
) -> tuple[torch.Tensor] | BaseModelOutputWithPoolingAndCrossAttentions:
|
| 641 |
+
if (input_ids is None) ^ (inputs_embeds is not None):
|
| 642 |
+
raise ValueError("You must specify exactly one of input_ids or inputs_embeds")
|
| 643 |
+
|
| 644 |
+
if self.config.is_decoder:
|
| 645 |
+
use_cache = use_cache if use_cache is not None else self.config.use_cache
|
| 646 |
+
else:
|
| 647 |
+
use_cache = False
|
| 648 |
+
|
| 649 |
+
if use_cache and past_key_values is None:
|
| 650 |
+
past_key_values = (
|
| 651 |
+
EncoderDecoderCache(DynamicCache(config=self.config), DynamicCache(config=self.config))
|
| 652 |
+
if encoder_hidden_states is not None or self.config.is_encoder_decoder
|
| 653 |
+
else DynamicCache(config=self.config)
|
| 654 |
+
)
|
| 655 |
+
|
| 656 |
+
past_key_values_length = past_key_values.get_seq_length() if past_key_values is not None else 0
|
| 657 |
+
|
| 658 |
+
embedding_output = self.embeddings(
|
| 659 |
+
input_ids=input_ids,
|
| 660 |
+
position_ids=position_ids,
|
| 661 |
+
token_type_ids=token_type_ids,
|
| 662 |
+
inputs_embeds=inputs_embeds,
|
| 663 |
+
past_key_values_length=past_key_values_length,
|
| 664 |
+
)
|
| 665 |
+
|
| 666 |
+
attention_mask, encoder_attention_mask = self._create_attention_masks(
|
| 667 |
+
attention_mask=attention_mask,
|
| 668 |
+
encoder_attention_mask=encoder_attention_mask,
|
| 669 |
+
embedding_output=embedding_output,
|
| 670 |
+
encoder_hidden_states=encoder_hidden_states,
|
| 671 |
+
past_key_values=past_key_values,
|
| 672 |
+
)
|
| 673 |
+
|
| 674 |
+
encoder_outputs = self.encoder(
|
| 675 |
+
embedding_output,
|
| 676 |
+
attention_mask=attention_mask,
|
| 677 |
+
encoder_hidden_states=encoder_hidden_states,
|
| 678 |
+
encoder_attention_mask=encoder_attention_mask,
|
| 679 |
+
past_key_values=past_key_values,
|
| 680 |
+
use_cache=use_cache,
|
| 681 |
+
position_ids=position_ids,
|
| 682 |
+
**kwargs,
|
| 683 |
+
)
|
| 684 |
+
sequence_output = encoder_outputs.last_hidden_state
|
| 685 |
+
pooled_output = self.pooler(sequence_output) if self.pooler is not None else None
|
| 686 |
+
|
| 687 |
+
return BaseModelOutputWithPoolingAndCrossAttentions(
|
| 688 |
+
last_hidden_state=sequence_output,
|
| 689 |
+
pooler_output=pooled_output,
|
| 690 |
+
past_key_values=encoder_outputs.past_key_values,
|
| 691 |
+
)
|
| 692 |
+
|
| 693 |
+
def _create_attention_masks(
|
| 694 |
+
self,
|
| 695 |
+
attention_mask,
|
| 696 |
+
encoder_attention_mask,
|
| 697 |
+
embedding_output,
|
| 698 |
+
encoder_hidden_states,
|
| 699 |
+
past_key_values,
|
| 700 |
+
):
|
| 701 |
+
if self.config.is_decoder:
|
| 702 |
+
attention_mask = create_causal_mask(
|
| 703 |
+
config=self.config,
|
| 704 |
+
inputs_embeds=embedding_output,
|
| 705 |
+
attention_mask=attention_mask,
|
| 706 |
+
past_key_values=past_key_values,
|
| 707 |
+
)
|
| 708 |
+
else:
|
| 709 |
+
attention_mask = create_bidirectional_mask(
|
| 710 |
+
config=self.config,
|
| 711 |
+
inputs_embeds=embedding_output,
|
| 712 |
+
attention_mask=attention_mask,
|
| 713 |
+
)
|
| 714 |
+
|
| 715 |
+
if encoder_attention_mask is not None:
|
| 716 |
+
encoder_attention_mask = create_bidirectional_mask(
|
| 717 |
+
config=self.config,
|
| 718 |
+
inputs_embeds=embedding_output,
|
| 719 |
+
attention_mask=encoder_attention_mask,
|
| 720 |
+
encoder_hidden_states=encoder_hidden_states,
|
| 721 |
+
)
|
| 722 |
+
|
| 723 |
+
return attention_mask, encoder_attention_mask
|
| 724 |
+
|
| 725 |
+
|
| 726 |
+
@auto_docstring(
|
| 727 |
+
custom_intro="""
|
| 728 |
+
Bert Model with two heads on top as done during the pretraining: a `masked language modeling` head and a `next
|
| 729 |
+
sentence prediction (classification)` head.
|
| 730 |
+
"""
|
| 731 |
+
)
|
| 732 |
+
class BertForPreTraining(BertPreTrainedModel):
|
| 733 |
+
_tied_weights_keys = {
|
| 734 |
+
"cls.predictions.decoder.weight": "bert.embeddings.word_embeddings.weight",
|
| 735 |
+
"cls.predictions.decoder.bias": "cls.predictions.bias",
|
| 736 |
+
}
|
| 737 |
+
|
| 738 |
+
def __init__(self, config):
|
| 739 |
+
super().__init__(config)
|
| 740 |
+
|
| 741 |
+
self.bert = BertModel(config)
|
| 742 |
+
self.cls = BertPreTrainingHeads(config)
|
| 743 |
+
|
| 744 |
+
# Initialize weights and apply final processing
|
| 745 |
+
self.post_init()
|
| 746 |
+
|
| 747 |
+
def get_output_embeddings(self):
|
| 748 |
+
return self.cls.predictions.decoder
|
| 749 |
+
|
| 750 |
+
def set_output_embeddings(self, new_embeddings):
|
| 751 |
+
self.cls.predictions.decoder = new_embeddings
|
| 752 |
+
self.cls.predictions.bias = new_embeddings.bias
|
| 753 |
+
|
| 754 |
+
@can_return_tuple
|
| 755 |
+
@auto_docstring
|
| 756 |
+
def forward(
|
| 757 |
+
self,
|
| 758 |
+
input_ids: torch.Tensor | None = None,
|
| 759 |
+
attention_mask: torch.Tensor | None = None,
|
| 760 |
+
token_type_ids: torch.Tensor | None = None,
|
| 761 |
+
position_ids: torch.Tensor | None = None,
|
| 762 |
+
inputs_embeds: torch.Tensor | None = None,
|
| 763 |
+
labels: torch.Tensor | None = None,
|
| 764 |
+
next_sentence_label: torch.Tensor | None = None,
|
| 765 |
+
**kwargs: Unpack[TransformersKwargs],
|
| 766 |
+
) -> tuple[torch.Tensor] | BertForPreTrainingOutput:
|
| 767 |
+
r"""
|
| 768 |
+
labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*):
|
| 769 |
+
Labels for computing the masked language modeling loss. Indices should be in `[-100, 0, ...,
|
| 770 |
+
config.vocab_size]` (see `input_ids` docstring) Tokens with indices set to `-100` are ignored (masked),
|
| 771 |
+
the loss is only computed for the tokens with labels in `[0, ..., config.vocab_size]`
|
| 772 |
+
next_sentence_label (`torch.LongTensor` of shape `(batch_size,)`, *optional*):
|
| 773 |
+
Labels for computing the next sequence prediction (classification) loss. Input should be a sequence
|
| 774 |
+
pair (see `input_ids` docstring) Indices should be in `[0, 1]`:
|
| 775 |
+
|
| 776 |
+
- 0 indicates sequence B is a continuation of sequence A,
|
| 777 |
+
- 1 indicates sequence B is a random sequence.
|
| 778 |
+
|
| 779 |
+
Example:
|
| 780 |
+
|
| 781 |
+
```python
|
| 782 |
+
>>> from transformers import AutoTokenizer, BertForPreTraining
|
| 783 |
+
>>> import torch
|
| 784 |
+
|
| 785 |
+
>>> tokenizer = AutoTokenizer.from_pretrained("google-bert/bert-base-uncased")
|
| 786 |
+
>>> model = BertForPreTraining.from_pretrained("google-bert/bert-base-uncased")
|
| 787 |
+
|
| 788 |
+
>>> inputs = tokenizer("Hello, my dog is cute", return_tensors="pt")
|
| 789 |
+
>>> outputs = model(**inputs)
|
| 790 |
+
|
| 791 |
+
>>> prediction_logits = outputs.prediction_logits
|
| 792 |
+
>>> seq_relationship_logits = outputs.seq_relationship_logits
|
| 793 |
+
```
|
| 794 |
+
"""
|
| 795 |
+
outputs = self.bert(
|
| 796 |
+
input_ids,
|
| 797 |
+
attention_mask=attention_mask,
|
| 798 |
+
token_type_ids=token_type_ids,
|
| 799 |
+
position_ids=position_ids,
|
| 800 |
+
inputs_embeds=inputs_embeds,
|
| 801 |
+
return_dict=True,
|
| 802 |
+
**kwargs,
|
| 803 |
+
)
|
| 804 |
+
|
| 805 |
+
sequence_output, pooled_output = outputs[:2]
|
| 806 |
+
prediction_scores, seq_relationship_score = self.cls(sequence_output, pooled_output)
|
| 807 |
+
|
| 808 |
+
total_loss = None
|
| 809 |
+
if labels is not None and next_sentence_label is not None:
|
| 810 |
+
loss_fct = CrossEntropyLoss()
|
| 811 |
+
masked_lm_loss = loss_fct(prediction_scores.view(-1, self.config.vocab_size), labels.view(-1))
|
| 812 |
+
next_sentence_loss = loss_fct(seq_relationship_score.view(-1, 2), next_sentence_label.view(-1))
|
| 813 |
+
total_loss = masked_lm_loss + next_sentence_loss
|
| 814 |
+
|
| 815 |
+
return BertForPreTrainingOutput(
|
| 816 |
+
loss=total_loss,
|
| 817 |
+
prediction_logits=prediction_scores,
|
| 818 |
+
seq_relationship_logits=seq_relationship_score,
|
| 819 |
+
hidden_states=outputs.hidden_states,
|
| 820 |
+
attentions=outputs.attentions,
|
| 821 |
+
)
|
| 822 |
+
|
| 823 |
+
|
| 824 |
+
@auto_docstring(
|
| 825 |
+
custom_intro="""
|
| 826 |
+
Bert Model with a `language modeling` head on top for CLM fine-tuning.
|
| 827 |
+
"""
|
| 828 |
+
)
|
| 829 |
+
class BertLMHeadModel(BertPreTrainedModel, GenerationMixin):
|
| 830 |
+
_tied_weights_keys = {
|
| 831 |
+
"cls.predictions.decoder.weight": "bert.embeddings.word_embeddings.weight",
|
| 832 |
+
"cls.predictions.decoder.bias": "cls.predictions.bias",
|
| 833 |
+
}
|
| 834 |
+
|
| 835 |
+
def __init__(self, config):
|
| 836 |
+
super().__init__(config)
|
| 837 |
+
|
| 838 |
+
if not config.is_decoder:
|
| 839 |
+
logger.warning("If you want to use `BertLMHeadModel` as a standalone, add `is_decoder=True.`")
|
| 840 |
+
|
| 841 |
+
self.bert = BertModel(config, add_pooling_layer=False)
|
| 842 |
+
self.cls = BertOnlyMLMHead(config)
|
| 843 |
+
|
| 844 |
+
# Initialize weights and apply final processing
|
| 845 |
+
self.post_init()
|
| 846 |
+
|
| 847 |
+
def get_output_embeddings(self):
|
| 848 |
+
return self.cls.predictions.decoder
|
| 849 |
+
|
| 850 |
+
def set_output_embeddings(self, new_embeddings):
|
| 851 |
+
self.cls.predictions.decoder = new_embeddings
|
| 852 |
+
self.cls.predictions.bias = new_embeddings.bias
|
| 853 |
+
|
| 854 |
+
@can_return_tuple
|
| 855 |
+
@auto_docstring
|
| 856 |
+
def forward(
|
| 857 |
+
self,
|
| 858 |
+
input_ids: torch.Tensor | None = None,
|
| 859 |
+
attention_mask: torch.Tensor | None = None,
|
| 860 |
+
token_type_ids: torch.Tensor | None = None,
|
| 861 |
+
position_ids: torch.Tensor | None = None,
|
| 862 |
+
inputs_embeds: torch.Tensor | None = None,
|
| 863 |
+
encoder_hidden_states: torch.Tensor | None = None,
|
| 864 |
+
encoder_attention_mask: torch.Tensor | None = None,
|
| 865 |
+
labels: torch.Tensor | None = None,
|
| 866 |
+
past_key_values: Cache | None = None,
|
| 867 |
+
use_cache: bool | None = None,
|
| 868 |
+
logits_to_keep: int | torch.Tensor = 0,
|
| 869 |
+
**kwargs: Unpack[TransformersKwargs],
|
| 870 |
+
) -> tuple[torch.Tensor] | CausalLMOutputWithCrossAttentions:
|
| 871 |
+
r"""
|
| 872 |
+
labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*):
|
| 873 |
+
Labels for computing the left-to-right language modeling loss (next word prediction). Indices should be in
|
| 874 |
+
`[-100, 0, ..., config.vocab_size]` (see `input_ids` docstring) Tokens with indices set to `-100` are
|
| 875 |
+
ignored (masked), the loss is only computed for the tokens with labels n `[0, ..., config.vocab_size]`
|
| 876 |
+
"""
|
| 877 |
+
if labels is not None:
|
| 878 |
+
use_cache = False
|
| 879 |
+
|
| 880 |
+
outputs: BaseModelOutputWithPoolingAndCrossAttentions = self.bert(
|
| 881 |
+
input_ids,
|
| 882 |
+
attention_mask=attention_mask,
|
| 883 |
+
token_type_ids=token_type_ids,
|
| 884 |
+
position_ids=position_ids,
|
| 885 |
+
inputs_embeds=inputs_embeds,
|
| 886 |
+
encoder_hidden_states=encoder_hidden_states,
|
| 887 |
+
encoder_attention_mask=encoder_attention_mask,
|
| 888 |
+
past_key_values=past_key_values,
|
| 889 |
+
use_cache=use_cache,
|
| 890 |
+
return_dict=True,
|
| 891 |
+
**kwargs,
|
| 892 |
+
)
|
| 893 |
+
|
| 894 |
+
hidden_states = outputs.last_hidden_state
|
| 895 |
+
# Only compute necessary logits, and do not upcast them to float if we are not computing the loss
|
| 896 |
+
slice_indices = slice(-logits_to_keep, None) if isinstance(logits_to_keep, int) else logits_to_keep
|
| 897 |
+
logits = self.cls(hidden_states[:, slice_indices, :])
|
| 898 |
+
|
| 899 |
+
loss = None
|
| 900 |
+
if labels is not None:
|
| 901 |
+
loss = self.loss_function(logits=logits, labels=labels, vocab_size=self.config.vocab_size, **kwargs)
|
| 902 |
+
|
| 903 |
+
return CausalLMOutputWithCrossAttentions(
|
| 904 |
+
loss=loss,
|
| 905 |
+
logits=logits,
|
| 906 |
+
past_key_values=outputs.past_key_values,
|
| 907 |
+
hidden_states=outputs.hidden_states,
|
| 908 |
+
attentions=outputs.attentions,
|
| 909 |
+
cross_attentions=outputs.cross_attentions,
|
| 910 |
+
)
|
| 911 |
+
|
| 912 |
+
|
| 913 |
+
@auto_docstring
|
| 914 |
+
class BertForMaskedLM(BertPreTrainedModel):
|
| 915 |
+
_tied_weights_keys = {
|
| 916 |
+
"cls.predictions.decoder.weight": "bert.embeddings.word_embeddings.weight",
|
| 917 |
+
"cls.predictions.decoder.bias": "cls.predictions.bias",
|
| 918 |
+
}
|
| 919 |
+
|
| 920 |
+
def __init__(self, config):
|
| 921 |
+
super().__init__(config)
|
| 922 |
+
|
| 923 |
+
if config.is_decoder:
|
| 924 |
+
logger.warning(
|
| 925 |
+
"If you want to use `BertForMaskedLM` make sure `config.is_decoder=False` for "
|
| 926 |
+
"bi-directional self-attention."
|
| 927 |
+
)
|
| 928 |
+
|
| 929 |
+
self.bert = BertModel(config, add_pooling_layer=False)
|
| 930 |
+
self.cls = BertOnlyMLMHead(config)
|
| 931 |
+
|
| 932 |
+
# Initialize weights and apply final processing
|
| 933 |
+
self.post_init()
|
| 934 |
+
|
| 935 |
+
def get_output_embeddings(self):
|
| 936 |
+
return self.cls.predictions.decoder
|
| 937 |
+
|
| 938 |
+
def set_output_embeddings(self, new_embeddings):
|
| 939 |
+
self.cls.predictions.decoder = new_embeddings
|
| 940 |
+
self.cls.predictions.bias = new_embeddings.bias
|
| 941 |
+
|
| 942 |
+
@can_return_tuple
|
| 943 |
+
@auto_docstring
|
| 944 |
+
def forward(
|
| 945 |
+
self,
|
| 946 |
+
input_ids: torch.Tensor | None = None,
|
| 947 |
+
attention_mask: torch.Tensor | None = None,
|
| 948 |
+
token_type_ids: torch.Tensor | None = None,
|
| 949 |
+
position_ids: torch.Tensor | None = None,
|
| 950 |
+
inputs_embeds: torch.Tensor | None = None,
|
| 951 |
+
encoder_hidden_states: torch.Tensor | None = None,
|
| 952 |
+
encoder_attention_mask: torch.Tensor | None = None,
|
| 953 |
+
labels: torch.Tensor | None = None,
|
| 954 |
+
**kwargs: Unpack[TransformersKwargs],
|
| 955 |
+
) -> tuple[torch.Tensor] | MaskedLMOutput:
|
| 956 |
+
r"""
|
| 957 |
+
labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*):
|
| 958 |
+
Labels for computing the masked language modeling loss. Indices should be in `[-100, 0, ...,
|
| 959 |
+
config.vocab_size]` (see `input_ids` docstring) Tokens with indices set to `-100` are ignored (masked), the
|
| 960 |
+
loss is only computed for the tokens with labels in `[0, ..., config.vocab_size]`
|
| 961 |
+
"""
|
| 962 |
+
outputs = self.bert(
|
| 963 |
+
input_ids,
|
| 964 |
+
attention_mask=attention_mask,
|
| 965 |
+
token_type_ids=token_type_ids,
|
| 966 |
+
position_ids=position_ids,
|
| 967 |
+
inputs_embeds=inputs_embeds,
|
| 968 |
+
encoder_hidden_states=encoder_hidden_states,
|
| 969 |
+
encoder_attention_mask=encoder_attention_mask,
|
| 970 |
+
return_dict=True,
|
| 971 |
+
**kwargs,
|
| 972 |
+
)
|
| 973 |
+
|
| 974 |
+
sequence_output = outputs[0]
|
| 975 |
+
prediction_scores = self.cls(sequence_output)
|
| 976 |
+
|
| 977 |
+
masked_lm_loss = None
|
| 978 |
+
if labels is not None:
|
| 979 |
+
loss_fct = CrossEntropyLoss() # -100 index = padding token
|
| 980 |
+
masked_lm_loss = loss_fct(prediction_scores.view(-1, self.config.vocab_size), labels.view(-1))
|
| 981 |
+
|
| 982 |
+
return MaskedLMOutput(
|
| 983 |
+
loss=masked_lm_loss,
|
| 984 |
+
logits=prediction_scores,
|
| 985 |
+
hidden_states=outputs.hidden_states,
|
| 986 |
+
attentions=outputs.attentions,
|
| 987 |
+
)
|
| 988 |
+
|
| 989 |
+
|
| 990 |
+
@auto_docstring(
|
| 991 |
+
custom_intro="""
|
| 992 |
+
Bert Model with a `next sentence prediction (classification)` head on top.
|
| 993 |
+
"""
|
| 994 |
+
)
|
| 995 |
+
class BertForNextSentencePrediction(BertPreTrainedModel):
|
| 996 |
+
def __init__(self, config):
|
| 997 |
+
super().__init__(config)
|
| 998 |
+
|
| 999 |
+
self.bert = BertModel(config)
|
| 1000 |
+
self.cls = BertOnlyNSPHead(config)
|
| 1001 |
+
|
| 1002 |
+
# Initialize weights and apply final processing
|
| 1003 |
+
self.post_init()
|
| 1004 |
+
|
| 1005 |
+
@can_return_tuple
|
| 1006 |
+
@auto_docstring
|
| 1007 |
+
def forward(
|
| 1008 |
+
self,
|
| 1009 |
+
input_ids: torch.Tensor | None = None,
|
| 1010 |
+
attention_mask: torch.Tensor | None = None,
|
| 1011 |
+
token_type_ids: torch.Tensor | None = None,
|
| 1012 |
+
position_ids: torch.Tensor | None = None,
|
| 1013 |
+
inputs_embeds: torch.Tensor | None = None,
|
| 1014 |
+
labels: torch.Tensor | None = None,
|
| 1015 |
+
**kwargs: Unpack[TransformersKwargs],
|
| 1016 |
+
) -> tuple[torch.Tensor] | NextSentencePredictorOutput:
|
| 1017 |
+
r"""
|
| 1018 |
+
labels (`torch.LongTensor` of shape `(batch_size,)`, *optional*):
|
| 1019 |
+
Labels for computing the next sequence prediction (classification) loss. Input should be a sequence pair
|
| 1020 |
+
(see `input_ids` docstring). Indices should be in `[0, 1]`:
|
| 1021 |
+
|
| 1022 |
+
- 0 indicates sequence B is a continuation of sequence A,
|
| 1023 |
+
- 1 indicates sequence B is a random sequence.
|
| 1024 |
+
|
| 1025 |
+
Example:
|
| 1026 |
+
|
| 1027 |
+
```python
|
| 1028 |
+
>>> from transformers import AutoTokenizer, BertForNextSentencePrediction
|
| 1029 |
+
>>> import torch
|
| 1030 |
+
|
| 1031 |
+
>>> tokenizer = AutoTokenizer.from_pretrained("google-bert/bert-base-uncased")
|
| 1032 |
+
>>> model = BertForNextSentencePrediction.from_pretrained("google-bert/bert-base-uncased")
|
| 1033 |
+
|
| 1034 |
+
>>> prompt = "In Italy, pizza served in formal settings, such as at a restaurant, is presented unsliced."
|
| 1035 |
+
>>> next_sentence = "The sky is blue due to the shorter wavelength of blue light."
|
| 1036 |
+
>>> encoding = tokenizer(prompt, next_sentence, return_tensors="pt")
|
| 1037 |
+
|
| 1038 |
+
>>> outputs = model(**encoding, labels=torch.LongTensor([1]))
|
| 1039 |
+
>>> logits = outputs.logits
|
| 1040 |
+
>>> assert logits[0, 0] < logits[0, 1] # next sentence was random
|
| 1041 |
+
```
|
| 1042 |
+
"""
|
| 1043 |
+
|
| 1044 |
+
outputs = self.bert(
|
| 1045 |
+
input_ids,
|
| 1046 |
+
attention_mask=attention_mask,
|
| 1047 |
+
token_type_ids=token_type_ids,
|
| 1048 |
+
position_ids=position_ids,
|
| 1049 |
+
inputs_embeds=inputs_embeds,
|
| 1050 |
+
return_dict=True,
|
| 1051 |
+
**kwargs,
|
| 1052 |
+
)
|
| 1053 |
+
|
| 1054 |
+
pooled_output = outputs[1]
|
| 1055 |
+
|
| 1056 |
+
seq_relationship_scores = self.cls(pooled_output)
|
| 1057 |
+
|
| 1058 |
+
next_sentence_loss = None
|
| 1059 |
+
if labels is not None:
|
| 1060 |
+
loss_fct = CrossEntropyLoss()
|
| 1061 |
+
next_sentence_loss = loss_fct(seq_relationship_scores.view(-1, 2), labels.view(-1))
|
| 1062 |
+
|
| 1063 |
+
return NextSentencePredictorOutput(
|
| 1064 |
+
loss=next_sentence_loss,
|
| 1065 |
+
logits=seq_relationship_scores,
|
| 1066 |
+
hidden_states=outputs.hidden_states,
|
| 1067 |
+
attentions=outputs.attentions,
|
| 1068 |
+
)
|
| 1069 |
+
|
| 1070 |
+
|
| 1071 |
+
@auto_docstring(
|
| 1072 |
+
custom_intro="""
|
| 1073 |
+
Bert Model transformer with a sequence classification/regression head on top (a linear layer on top of the pooled
|
| 1074 |
+
output) e.g. for GLUE tasks.
|
| 1075 |
+
"""
|
| 1076 |
+
)
|
| 1077 |
+
class BertForSequenceClassification(BertPreTrainedModel):
|
| 1078 |
+
def __init__(self, config):
|
| 1079 |
+
super().__init__(config)
|
| 1080 |
+
self.num_labels = config.num_labels
|
| 1081 |
+
self.config = config
|
| 1082 |
+
|
| 1083 |
+
self.bert = BertModel(config)
|
| 1084 |
+
classifier_dropout = (
|
| 1085 |
+
config.classifier_dropout if config.classifier_dropout is not None else config.hidden_dropout_prob
|
| 1086 |
+
)
|
| 1087 |
+
self.dropout = nn.Dropout(classifier_dropout)
|
| 1088 |
+
self.classifier = nn.Linear(config.hidden_size, config.num_labels)
|
| 1089 |
+
|
| 1090 |
+
# Initialize weights and apply final processing
|
| 1091 |
+
self.post_init()
|
| 1092 |
+
|
| 1093 |
+
@can_return_tuple
|
| 1094 |
+
@auto_docstring
|
| 1095 |
+
def forward(
|
| 1096 |
+
self,
|
| 1097 |
+
input_ids: torch.Tensor | None = None,
|
| 1098 |
+
attention_mask: torch.Tensor | None = None,
|
| 1099 |
+
token_type_ids: torch.Tensor | None = None,
|
| 1100 |
+
position_ids: torch.Tensor | None = None,
|
| 1101 |
+
inputs_embeds: torch.Tensor | None = None,
|
| 1102 |
+
labels: torch.Tensor | None = None,
|
| 1103 |
+
**kwargs: Unpack[TransformersKwargs],
|
| 1104 |
+
) -> tuple[torch.Tensor] | SequenceClassifierOutput:
|
| 1105 |
+
r"""
|
| 1106 |
+
labels (`torch.LongTensor` of shape `(batch_size,)`, *optional*):
|
| 1107 |
+
Labels for computing the sequence classification/regression loss. Indices should be in `[0, ...,
|
| 1108 |
+
config.num_labels - 1]`. If `config.num_labels == 1` a regression loss is computed (Mean-Square loss), If
|
| 1109 |
+
`config.num_labels > 1` a classification loss is computed (Cross-Entropy).
|
| 1110 |
+
"""
|
| 1111 |
+
outputs = self.bert(
|
| 1112 |
+
input_ids,
|
| 1113 |
+
attention_mask=attention_mask,
|
| 1114 |
+
token_type_ids=token_type_ids,
|
| 1115 |
+
position_ids=position_ids,
|
| 1116 |
+
inputs_embeds=inputs_embeds,
|
| 1117 |
+
return_dict=True,
|
| 1118 |
+
**kwargs,
|
| 1119 |
+
)
|
| 1120 |
+
|
| 1121 |
+
pooled_output = outputs[1]
|
| 1122 |
+
|
| 1123 |
+
pooled_output = self.dropout(pooled_output)
|
| 1124 |
+
logits = self.classifier(pooled_output)
|
| 1125 |
+
|
| 1126 |
+
loss = None
|
| 1127 |
+
if labels is not None:
|
| 1128 |
+
if self.config.problem_type is None:
|
| 1129 |
+
if self.num_labels == 1:
|
| 1130 |
+
self.config.problem_type = "regression"
|
| 1131 |
+
elif self.num_labels > 1 and (labels.dtype == torch.long or labels.dtype == torch.int):
|
| 1132 |
+
self.config.problem_type = "single_label_classification"
|
| 1133 |
+
else:
|
| 1134 |
+
self.config.problem_type = "multi_label_classification"
|
| 1135 |
+
|
| 1136 |
+
if self.config.problem_type == "regression":
|
| 1137 |
+
loss_fct = MSELoss()
|
| 1138 |
+
if self.num_labels == 1:
|
| 1139 |
+
loss = loss_fct(logits.squeeze(), labels.squeeze())
|
| 1140 |
+
else:
|
| 1141 |
+
loss = loss_fct(logits, labels)
|
| 1142 |
+
elif self.config.problem_type == "single_label_classification":
|
| 1143 |
+
loss_fct = CrossEntropyLoss()
|
| 1144 |
+
loss = loss_fct(logits.view(-1, self.num_labels), labels.view(-1))
|
| 1145 |
+
elif self.config.problem_type == "multi_label_classification":
|
| 1146 |
+
loss_fct = BCEWithLogitsLoss()
|
| 1147 |
+
loss = loss_fct(logits, labels)
|
| 1148 |
+
|
| 1149 |
+
return SequenceClassifierOutput(
|
| 1150 |
+
loss=loss,
|
| 1151 |
+
logits=logits,
|
| 1152 |
+
hidden_states=outputs.hidden_states,
|
| 1153 |
+
attentions=outputs.attentions,
|
| 1154 |
+
)
|
| 1155 |
+
|
| 1156 |
+
|
| 1157 |
+
@auto_docstring
|
| 1158 |
+
class BertForMultipleChoice(BertPreTrainedModel):
|
| 1159 |
+
def __init__(self, config):
|
| 1160 |
+
super().__init__(config)
|
| 1161 |
+
|
| 1162 |
+
self.bert = BertModel(config)
|
| 1163 |
+
classifier_dropout = (
|
| 1164 |
+
config.classifier_dropout if config.classifier_dropout is not None else config.hidden_dropout_prob
|
| 1165 |
+
)
|
| 1166 |
+
self.dropout = nn.Dropout(classifier_dropout)
|
| 1167 |
+
self.classifier = nn.Linear(config.hidden_size, 1)
|
| 1168 |
+
|
| 1169 |
+
# Initialize weights and apply final processing
|
| 1170 |
+
self.post_init()
|
| 1171 |
+
|
| 1172 |
+
@can_return_tuple
|
| 1173 |
+
@auto_docstring
|
| 1174 |
+
def forward(
|
| 1175 |
+
self,
|
| 1176 |
+
input_ids: torch.Tensor | None = None,
|
| 1177 |
+
attention_mask: torch.Tensor | None = None,
|
| 1178 |
+
token_type_ids: torch.Tensor | None = None,
|
| 1179 |
+
position_ids: torch.Tensor | None = None,
|
| 1180 |
+
inputs_embeds: torch.Tensor | None = None,
|
| 1181 |
+
labels: torch.Tensor | None = None,
|
| 1182 |
+
**kwargs: Unpack[TransformersKwargs],
|
| 1183 |
+
) -> tuple[torch.Tensor] | MultipleChoiceModelOutput:
|
| 1184 |
+
r"""
|
| 1185 |
+
input_ids (`torch.LongTensor` of shape `(batch_size, num_choices, sequence_length)`):
|
| 1186 |
+
Indices of input sequence tokens in the vocabulary.
|
| 1187 |
+
|
| 1188 |
+
Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and
|
| 1189 |
+
[`PreTrainedTokenizer.__call__`] for details.
|
| 1190 |
+
|
| 1191 |
+
[What are input IDs?](../glossary#input-ids)
|
| 1192 |
+
token_type_ids (`torch.LongTensor` of shape `(batch_size, num_choices, sequence_length)`, *optional*):
|
| 1193 |
+
Segment token indices to indicate first and second portions of the inputs. Indices are selected in `[0,
|
| 1194 |
+
1]`:
|
| 1195 |
+
|
| 1196 |
+
- 0 corresponds to a *sentence A* token,
|
| 1197 |
+
- 1 corresponds to a *sentence B* token.
|
| 1198 |
+
|
| 1199 |
+
[What are token type IDs?](../glossary#token-type-ids)
|
| 1200 |
+
position_ids (`torch.LongTensor` of shape `(batch_size, num_choices, sequence_length)`, *optional*):
|
| 1201 |
+
Indices of positions of each input sequence tokens in the position embeddings. Selected in the range `[0,
|
| 1202 |
+
config.max_position_embeddings - 1]`.
|
| 1203 |
+
|
| 1204 |
+
[What are position IDs?](../glossary#position-ids)
|
| 1205 |
+
inputs_embeds (`torch.FloatTensor` of shape `(batch_size, num_choices, sequence_length, hidden_size)`, *optional*):
|
| 1206 |
+
Optionally, instead of passing `input_ids` you can choose to directly pass an embedded representation. This
|
| 1207 |
+
is useful if you want more control over how to convert `input_ids` indices into associated vectors than the
|
| 1208 |
+
model's internal embedding lookup matrix.
|
| 1209 |
+
labels (`torch.LongTensor` of shape `(batch_size,)`, *optional*):
|
| 1210 |
+
Labels for computing the multiple choice classification loss. Indices should be in `[0, ...,
|
| 1211 |
+
num_choices-1]` where `num_choices` is the size of the second dimension of the input tensors. (See
|
| 1212 |
+
`input_ids` above)
|
| 1213 |
+
"""
|
| 1214 |
+
num_choices = input_ids.shape[1] if input_ids is not None else inputs_embeds.shape[1]
|
| 1215 |
+
|
| 1216 |
+
input_ids = input_ids.view(-1, input_ids.size(-1)) if input_ids is not None else None
|
| 1217 |
+
attention_mask = attention_mask.view(-1, attention_mask.size(-1)) if attention_mask is not None else None
|
| 1218 |
+
token_type_ids = token_type_ids.view(-1, token_type_ids.size(-1)) if token_type_ids is not None else None
|
| 1219 |
+
position_ids = position_ids.view(-1, position_ids.size(-1)) if position_ids is not None else None
|
| 1220 |
+
inputs_embeds = (
|
| 1221 |
+
inputs_embeds.view(-1, inputs_embeds.size(-2), inputs_embeds.size(-1))
|
| 1222 |
+
if inputs_embeds is not None
|
| 1223 |
+
else None
|
| 1224 |
+
)
|
| 1225 |
+
|
| 1226 |
+
outputs = self.bert(
|
| 1227 |
+
input_ids,
|
| 1228 |
+
attention_mask=attention_mask,
|
| 1229 |
+
token_type_ids=token_type_ids,
|
| 1230 |
+
position_ids=position_ids,
|
| 1231 |
+
inputs_embeds=inputs_embeds,
|
| 1232 |
+
return_dict=True,
|
| 1233 |
+
**kwargs,
|
| 1234 |
+
)
|
| 1235 |
+
|
| 1236 |
+
pooled_output = outputs[1]
|
| 1237 |
+
|
| 1238 |
+
pooled_output = self.dropout(pooled_output)
|
| 1239 |
+
logits = self.classifier(pooled_output)
|
| 1240 |
+
reshaped_logits = logits.view(-1, num_choices)
|
| 1241 |
+
|
| 1242 |
+
loss = None
|
| 1243 |
+
if labels is not None:
|
| 1244 |
+
loss_fct = CrossEntropyLoss()
|
| 1245 |
+
loss = loss_fct(reshaped_logits, labels)
|
| 1246 |
+
|
| 1247 |
+
return MultipleChoiceModelOutput(
|
| 1248 |
+
loss=loss,
|
| 1249 |
+
logits=reshaped_logits,
|
| 1250 |
+
hidden_states=outputs.hidden_states,
|
| 1251 |
+
attentions=outputs.attentions,
|
| 1252 |
+
)
|
| 1253 |
+
|
| 1254 |
+
|
| 1255 |
+
@auto_docstring
|
| 1256 |
+
class BertForTokenClassification(BertPreTrainedModel):
|
| 1257 |
+
def __init__(self, config):
|
| 1258 |
+
super().__init__(config)
|
| 1259 |
+
self.num_labels = config.num_labels
|
| 1260 |
+
|
| 1261 |
+
self.bert = BertModel(config, add_pooling_layer=False)
|
| 1262 |
+
classifier_dropout = (
|
| 1263 |
+
config.classifier_dropout if config.classifier_dropout is not None else config.hidden_dropout_prob
|
| 1264 |
+
)
|
| 1265 |
+
self.dropout = nn.Dropout(classifier_dropout)
|
| 1266 |
+
self.classifier = nn.Linear(config.hidden_size, config.num_labels)
|
| 1267 |
+
|
| 1268 |
+
# Initialize weights and apply final processing
|
| 1269 |
+
self.post_init()
|
| 1270 |
+
|
| 1271 |
+
@can_return_tuple
|
| 1272 |
+
@auto_docstring
|
| 1273 |
+
def forward(
|
| 1274 |
+
self,
|
| 1275 |
+
input_ids: torch.Tensor | None = None,
|
| 1276 |
+
attention_mask: torch.Tensor | None = None,
|
| 1277 |
+
token_type_ids: torch.Tensor | None = None,
|
| 1278 |
+
position_ids: torch.Tensor | None = None,
|
| 1279 |
+
inputs_embeds: torch.Tensor | None = None,
|
| 1280 |
+
labels: torch.Tensor | None = None,
|
| 1281 |
+
**kwargs: Unpack[TransformersKwargs],
|
| 1282 |
+
) -> tuple[torch.Tensor] | TokenClassifierOutput:
|
| 1283 |
+
r"""
|
| 1284 |
+
labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*):
|
| 1285 |
+
Labels for computing the token classification loss. Indices should be in `[0, ..., config.num_labels - 1]`.
|
| 1286 |
+
"""
|
| 1287 |
+
outputs = self.bert(
|
| 1288 |
+
input_ids,
|
| 1289 |
+
attention_mask=attention_mask,
|
| 1290 |
+
token_type_ids=token_type_ids,
|
| 1291 |
+
position_ids=position_ids,
|
| 1292 |
+
inputs_embeds=inputs_embeds,
|
| 1293 |
+
return_dict=True,
|
| 1294 |
+
**kwargs,
|
| 1295 |
+
)
|
| 1296 |
+
|
| 1297 |
+
sequence_output = outputs[0]
|
| 1298 |
+
|
| 1299 |
+
sequence_output = self.dropout(sequence_output)
|
| 1300 |
+
logits = self.classifier(sequence_output)
|
| 1301 |
+
|
| 1302 |
+
loss = None
|
| 1303 |
+
if labels is not None:
|
| 1304 |
+
loss_fct = CrossEntropyLoss()
|
| 1305 |
+
loss = loss_fct(logits.view(-1, self.num_labels), labels.view(-1))
|
| 1306 |
+
|
| 1307 |
+
return TokenClassifierOutput(
|
| 1308 |
+
loss=loss,
|
| 1309 |
+
logits=logits,
|
| 1310 |
+
hidden_states=outputs.hidden_states,
|
| 1311 |
+
attentions=outputs.attentions,
|
| 1312 |
+
)
|
| 1313 |
+
|
| 1314 |
+
|
| 1315 |
+
@auto_docstring
|
| 1316 |
+
class BertForQuestionAnswering(BertPreTrainedModel):
|
| 1317 |
+
def __init__(self, config):
|
| 1318 |
+
super().__init__(config)
|
| 1319 |
+
self.num_labels = config.num_labels
|
| 1320 |
+
|
| 1321 |
+
self.bert = BertModel(config, add_pooling_layer=False)
|
| 1322 |
+
self.qa_outputs = nn.Linear(config.hidden_size, config.num_labels)
|
| 1323 |
+
|
| 1324 |
+
# Initialize weights and apply final processing
|
| 1325 |
+
self.post_init()
|
| 1326 |
+
|
| 1327 |
+
@can_return_tuple
|
| 1328 |
+
@auto_docstring
|
| 1329 |
+
def forward(
|
| 1330 |
+
self,
|
| 1331 |
+
input_ids: torch.Tensor | None = None,
|
| 1332 |
+
attention_mask: torch.Tensor | None = None,
|
| 1333 |
+
token_type_ids: torch.Tensor | None = None,
|
| 1334 |
+
position_ids: torch.Tensor | None = None,
|
| 1335 |
+
inputs_embeds: torch.Tensor | None = None,
|
| 1336 |
+
start_positions: torch.Tensor | None = None,
|
| 1337 |
+
end_positions: torch.Tensor | None = None,
|
| 1338 |
+
**kwargs: Unpack[TransformersKwargs],
|
| 1339 |
+
) -> tuple[torch.Tensor] | QuestionAnsweringModelOutput:
|
| 1340 |
+
outputs = self.bert(
|
| 1341 |
+
input_ids,
|
| 1342 |
+
attention_mask=attention_mask,
|
| 1343 |
+
token_type_ids=token_type_ids,
|
| 1344 |
+
position_ids=position_ids,
|
| 1345 |
+
inputs_embeds=inputs_embeds,
|
| 1346 |
+
return_dict=True,
|
| 1347 |
+
**kwargs,
|
| 1348 |
+
)
|
| 1349 |
+
|
| 1350 |
+
sequence_output = outputs[0]
|
| 1351 |
+
|
| 1352 |
+
logits = self.qa_outputs(sequence_output)
|
| 1353 |
+
start_logits, end_logits = logits.split(1, dim=-1)
|
| 1354 |
+
start_logits = start_logits.squeeze(-1).contiguous()
|
| 1355 |
+
end_logits = end_logits.squeeze(-1).contiguous()
|
| 1356 |
+
|
| 1357 |
+
total_loss = None
|
| 1358 |
+
if start_positions is not None and end_positions is not None:
|
| 1359 |
+
# If we are on multi-GPU, split add a dimension
|
| 1360 |
+
if len(start_positions.size()) > 1:
|
| 1361 |
+
start_positions = start_positions.squeeze(-1)
|
| 1362 |
+
if len(end_positions.size()) > 1:
|
| 1363 |
+
end_positions = end_positions.squeeze(-1)
|
| 1364 |
+
# sometimes the start/end positions are outside our model inputs, we ignore these terms
|
| 1365 |
+
ignored_index = start_logits.size(1)
|
| 1366 |
+
start_positions = start_positions.clamp(0, ignored_index)
|
| 1367 |
+
end_positions = end_positions.clamp(0, ignored_index)
|
| 1368 |
+
|
| 1369 |
+
loss_fct = CrossEntropyLoss(ignore_index=ignored_index)
|
| 1370 |
+
start_loss = loss_fct(start_logits, start_positions)
|
| 1371 |
+
end_loss = loss_fct(end_logits, end_positions)
|
| 1372 |
+
total_loss = (start_loss + end_loss) / 2
|
| 1373 |
+
|
| 1374 |
+
return QuestionAnsweringModelOutput(
|
| 1375 |
+
loss=total_loss,
|
| 1376 |
+
start_logits=start_logits,
|
| 1377 |
+
end_logits=end_logits,
|
| 1378 |
+
hidden_states=outputs.hidden_states,
|
| 1379 |
+
attentions=outputs.attentions,
|
| 1380 |
+
)
|
| 1381 |
+
|
| 1382 |
+
|
| 1383 |
+
__all__ = [
|
| 1384 |
+
"BertForMaskedLM",
|
| 1385 |
+
"BertForMultipleChoice",
|
| 1386 |
+
"BertForNextSentencePrediction",
|
| 1387 |
+
"BertForPreTraining",
|
| 1388 |
+
"BertForQuestionAnswering",
|
| 1389 |
+
"BertForSequenceClassification",
|
| 1390 |
+
"BertForTokenClassification",
|
| 1391 |
+
"BertLayer",
|
| 1392 |
+
"BertLMHeadModel",
|
| 1393 |
+
"BertModel",
|
| 1394 |
+
"BertPreTrainedModel",
|
| 1395 |
+
]
|
third_party/transformers/src/transformers/models/bert/tokenization_bert.py
ADDED
|
@@ -0,0 +1,140 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright 2018 The Google AI Language Team 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 Bert."""
|
| 15 |
+
|
| 16 |
+
import collections
|
| 17 |
+
|
| 18 |
+
from tokenizers import Tokenizer, decoders, normalizers, pre_tokenizers, processors
|
| 19 |
+
from tokenizers.models import WordPiece
|
| 20 |
+
|
| 21 |
+
from ...tokenization_utils_tokenizers import TokenizersBackend
|
| 22 |
+
from ...utils import logging
|
| 23 |
+
|
| 24 |
+
|
| 25 |
+
logger = logging.get_logger(__name__)
|
| 26 |
+
|
| 27 |
+
VOCAB_FILES_NAMES = {"vocab_file": "vocab.txt", "tokenizer_file": "tokenizer.json"}
|
| 28 |
+
|
| 29 |
+
|
| 30 |
+
def load_vocab(vocab_file):
|
| 31 |
+
"""Loads a vocabulary file into a dictionary."""
|
| 32 |
+
vocab = collections.OrderedDict()
|
| 33 |
+
with open(vocab_file, "r", encoding="utf-8") as reader:
|
| 34 |
+
tokens = reader.readlines()
|
| 35 |
+
for index, token in enumerate(tokens):
|
| 36 |
+
token = token.rstrip("\n")
|
| 37 |
+
vocab[token] = index
|
| 38 |
+
return vocab
|
| 39 |
+
|
| 40 |
+
|
| 41 |
+
class BertTokenizer(TokenizersBackend):
|
| 42 |
+
r"""
|
| 43 |
+
Construct a BERT tokenizer (backed by HuggingFace's tokenizers library). Based on WordPiece.
|
| 44 |
+
|
| 45 |
+
This tokenizer inherits from [`TokenizersBackend`] which contains most of the main methods. Users should refer to
|
| 46 |
+
this superclass for more information regarding those methods.
|
| 47 |
+
|
| 48 |
+
Args:
|
| 49 |
+
vocab (`str` or `dict[str, int]`, *optional*):
|
| 50 |
+
Custom vocabulary dictionary. If not provided, vocabulary is loaded from `vocab_file`.
|
| 51 |
+
do_lower_case (`bool`, *optional*, defaults to `True`):
|
| 52 |
+
Whether or not to lowercase the input when tokenizing.
|
| 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 |
+
tokenize_chinese_chars (`bool`, *optional*, defaults to `True`):
|
| 69 |
+
Whether or not to tokenize Chinese characters.
|
| 70 |
+
strip_accents (`bool`, *optional*):
|
| 71 |
+
Whether or not to strip all accents. If this option is not specified, then it will be determined by the
|
| 72 |
+
value for `lowercase` (as in the original BERT).
|
| 73 |
+
"""
|
| 74 |
+
|
| 75 |
+
vocab_files_names = VOCAB_FILES_NAMES
|
| 76 |
+
model_input_names = ["input_ids", "token_type_ids", "attention_mask"]
|
| 77 |
+
model = WordPiece
|
| 78 |
+
|
| 79 |
+
def __init__(
|
| 80 |
+
self,
|
| 81 |
+
vocab: str | dict[str, int] | None = None,
|
| 82 |
+
do_lower_case: bool = True,
|
| 83 |
+
unk_token: str = "[UNK]",
|
| 84 |
+
sep_token: str = "[SEP]",
|
| 85 |
+
pad_token: str = "[PAD]",
|
| 86 |
+
cls_token: str = "[CLS]",
|
| 87 |
+
mask_token: str = "[MASK]",
|
| 88 |
+
tokenize_chinese_chars: bool = True,
|
| 89 |
+
strip_accents: bool | None = None,
|
| 90 |
+
**kwargs,
|
| 91 |
+
):
|
| 92 |
+
self.do_lower_case = do_lower_case
|
| 93 |
+
self.tokenize_chinese_chars = tokenize_chinese_chars
|
| 94 |
+
self.strip_accents = strip_accents
|
| 95 |
+
if vocab is None:
|
| 96 |
+
vocab = {
|
| 97 |
+
str(pad_token): 0,
|
| 98 |
+
str(unk_token): 1,
|
| 99 |
+
str(cls_token): 2,
|
| 100 |
+
str(sep_token): 3,
|
| 101 |
+
str(mask_token): 4,
|
| 102 |
+
}
|
| 103 |
+
self._vocab = vocab
|
| 104 |
+
self._tokenizer = Tokenizer(WordPiece(self._vocab, unk_token=str(unk_token)))
|
| 105 |
+
self._tokenizer.normalizer = normalizers.BertNormalizer(
|
| 106 |
+
clean_text=True,
|
| 107 |
+
handle_chinese_chars=tokenize_chinese_chars,
|
| 108 |
+
strip_accents=strip_accents,
|
| 109 |
+
lowercase=do_lower_case,
|
| 110 |
+
)
|
| 111 |
+
self._tokenizer.pre_tokenizer = pre_tokenizers.BertPreTokenizer()
|
| 112 |
+
self._tokenizer.decoder = decoders.WordPiece(prefix="##")
|
| 113 |
+
super().__init__(
|
| 114 |
+
do_lower_case=do_lower_case,
|
| 115 |
+
unk_token=unk_token,
|
| 116 |
+
sep_token=sep_token,
|
| 117 |
+
pad_token=pad_token,
|
| 118 |
+
cls_token=cls_token,
|
| 119 |
+
mask_token=mask_token,
|
| 120 |
+
tokenize_chinese_chars=tokenize_chinese_chars,
|
| 121 |
+
strip_accents=strip_accents,
|
| 122 |
+
**kwargs,
|
| 123 |
+
)
|
| 124 |
+
|
| 125 |
+
cls_token_id = self.cls_token_id if self.cls_token_id is not None else 2
|
| 126 |
+
sep_token_id = self.sep_token_id if self.sep_token_id is not None else 3
|
| 127 |
+
|
| 128 |
+
self._tokenizer.post_processor = processors.TemplateProcessing(
|
| 129 |
+
single=f"{str(self.cls_token)}:0 $A:0 {str(self.sep_token)}:0",
|
| 130 |
+
pair=f"{str(self.cls_token)}:0 $A:0 {str(self.sep_token)}:0 $B:1 {str(self.sep_token)}:1",
|
| 131 |
+
special_tokens=[
|
| 132 |
+
(str(self.cls_token), cls_token_id),
|
| 133 |
+
(str(self.sep_token), sep_token_id),
|
| 134 |
+
],
|
| 135 |
+
)
|
| 136 |
+
|
| 137 |
+
|
| 138 |
+
__all__ = ["BertTokenizer"]
|
| 139 |
+
|
| 140 |
+
BertTokenizerFast = BertTokenizer
|
third_party/transformers/src/transformers/models/bert/tokenization_bert_legacy.py
ADDED
|
@@ -0,0 +1,476 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright 2018 The Google AI Language Team 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 Bert."""
|
| 15 |
+
|
| 16 |
+
import collections
|
| 17 |
+
import os
|
| 18 |
+
import unicodedata
|
| 19 |
+
|
| 20 |
+
from ...tokenization_python import PreTrainedTokenizer, _is_control, _is_punctuation, _is_whitespace
|
| 21 |
+
from ...utils import logging
|
| 22 |
+
|
| 23 |
+
|
| 24 |
+
logger = logging.get_logger(__name__)
|
| 25 |
+
|
| 26 |
+
VOCAB_FILES_NAMES = {"vocab_file": "vocab.txt"}
|
| 27 |
+
|
| 28 |
+
|
| 29 |
+
def load_vocab(vocab_file):
|
| 30 |
+
"""Loads a vocabulary file into a dictionary."""
|
| 31 |
+
vocab = collections.OrderedDict()
|
| 32 |
+
with open(vocab_file, "r", encoding="utf-8") as reader:
|
| 33 |
+
tokens = reader.readlines()
|
| 34 |
+
for index, token in enumerate(tokens):
|
| 35 |
+
token = token.rstrip("\n")
|
| 36 |
+
vocab[token] = index
|
| 37 |
+
return vocab
|
| 38 |
+
|
| 39 |
+
|
| 40 |
+
def whitespace_tokenize(text):
|
| 41 |
+
"""Runs basic whitespace cleaning and splitting on a piece of text."""
|
| 42 |
+
text = text.strip()
|
| 43 |
+
if not text:
|
| 44 |
+
return []
|
| 45 |
+
tokens = text.split()
|
| 46 |
+
return tokens
|
| 47 |
+
|
| 48 |
+
|
| 49 |
+
class BertTokenizerLegacy(PreTrainedTokenizer):
|
| 50 |
+
r"""
|
| 51 |
+
Construct a BERT tokenizer. Based on WordPiece.
|
| 52 |
+
|
| 53 |
+
This tokenizer inherits from [`PreTrainedTokenizer`] which contains most of the main methods. Users should refer to
|
| 54 |
+
this superclass for more information regarding those methods.
|
| 55 |
+
|
| 56 |
+
Args:
|
| 57 |
+
vocab_file (`str`):
|
| 58 |
+
File containing the vocabulary.
|
| 59 |
+
do_lower_case (`bool`, *optional*, defaults to `True`):
|
| 60 |
+
Whether or not to lowercase the input when tokenizing.
|
| 61 |
+
do_basic_tokenize (`bool`, *optional*, defaults to `True`):
|
| 62 |
+
Whether or not to do basic tokenization before WordPiece.
|
| 63 |
+
never_split (`Iterable`, *optional*):
|
| 64 |
+
Collection of tokens which will never be split during tokenization. Only has an effect when
|
| 65 |
+
`do_basic_tokenize=True`
|
| 66 |
+
unk_token (`str`, *optional*, defaults to `"[UNK]"`):
|
| 67 |
+
The unknown token. A token that is not in the vocabulary cannot be converted to an ID and is set to be this
|
| 68 |
+
token instead.
|
| 69 |
+
sep_token (`str`, *optional*, defaults to `"[SEP]"`):
|
| 70 |
+
The separator token, which is used when building a sequence from multiple sequences, e.g. two sequences for
|
| 71 |
+
sequence classification or for a text and a question for question answering. It is also used as the last
|
| 72 |
+
token of a sequence built with special tokens.
|
| 73 |
+
pad_token (`str`, *optional*, defaults to `"[PAD]"`):
|
| 74 |
+
The token used for padding, for example when batching sequences of different lengths.
|
| 75 |
+
cls_token (`str`, *optional*, defaults to `"[CLS]"`):
|
| 76 |
+
The classifier token which is used when doing sequence classification (classification of the whole sequence
|
| 77 |
+
instead of per-token classification). It is the first token of the sequence when built with special tokens.
|
| 78 |
+
mask_token (`str`, *optional*, defaults to `"[MASK]"`):
|
| 79 |
+
The token used for masking values. This is the token used when training this model with masked language
|
| 80 |
+
modeling. This is the token which the model will try to predict.
|
| 81 |
+
tokenize_chinese_chars (`bool`, *optional*, defaults to `True`):
|
| 82 |
+
Whether or not to tokenize Chinese characters.
|
| 83 |
+
|
| 84 |
+
This should likely be deactivated for Japanese (see this
|
| 85 |
+
[issue](https://github.com/huggingface/transformers/issues/328)).
|
| 86 |
+
strip_accents (`bool`, *optional*):
|
| 87 |
+
Whether or not to strip all accents. If this option is not specified, then it will be determined by the
|
| 88 |
+
value for `lowercase` (as in the original BERT).
|
| 89 |
+
clean_up_tokenization_spaces (`bool`, *optional*, defaults to `True`):
|
| 90 |
+
Whether or not to cleanup spaces after decoding, cleanup consists in removing potential artifacts like
|
| 91 |
+
extra spaces.
|
| 92 |
+
"""
|
| 93 |
+
|
| 94 |
+
vocab_files_names = VOCAB_FILES_NAMES
|
| 95 |
+
|
| 96 |
+
def __init__(
|
| 97 |
+
self,
|
| 98 |
+
vocab_file,
|
| 99 |
+
do_lower_case=True,
|
| 100 |
+
do_basic_tokenize=True,
|
| 101 |
+
never_split=None,
|
| 102 |
+
unk_token="[UNK]",
|
| 103 |
+
sep_token="[SEP]",
|
| 104 |
+
pad_token="[PAD]",
|
| 105 |
+
cls_token="[CLS]",
|
| 106 |
+
mask_token="[MASK]",
|
| 107 |
+
tokenize_chinese_chars=True,
|
| 108 |
+
strip_accents=None,
|
| 109 |
+
clean_up_tokenization_spaces=True,
|
| 110 |
+
**kwargs,
|
| 111 |
+
):
|
| 112 |
+
if not os.path.isfile(vocab_file):
|
| 113 |
+
raise ValueError(
|
| 114 |
+
f"Can't find a vocabulary file at path '{vocab_file}'. To load the vocabulary from a Google pretrained"
|
| 115 |
+
" model use `tokenizer = BertTokenizer.from_pretrained(PRETRAINED_MODEL_NAME)`"
|
| 116 |
+
)
|
| 117 |
+
self.vocab = load_vocab(vocab_file)
|
| 118 |
+
self.ids_to_tokens = collections.OrderedDict([(ids, tok) for tok, ids in self.vocab.items()])
|
| 119 |
+
self.do_basic_tokenize = do_basic_tokenize
|
| 120 |
+
if do_basic_tokenize:
|
| 121 |
+
self.basic_tokenizer = BasicTokenizer(
|
| 122 |
+
do_lower_case=do_lower_case,
|
| 123 |
+
never_split=never_split,
|
| 124 |
+
tokenize_chinese_chars=tokenize_chinese_chars,
|
| 125 |
+
strip_accents=strip_accents,
|
| 126 |
+
)
|
| 127 |
+
|
| 128 |
+
self.wordpiece_tokenizer = WordpieceTokenizer(vocab=self.vocab, unk_token=str(unk_token))
|
| 129 |
+
|
| 130 |
+
super().__init__(
|
| 131 |
+
do_lower_case=do_lower_case,
|
| 132 |
+
do_basic_tokenize=do_basic_tokenize,
|
| 133 |
+
never_split=never_split,
|
| 134 |
+
unk_token=unk_token,
|
| 135 |
+
sep_token=sep_token,
|
| 136 |
+
pad_token=pad_token,
|
| 137 |
+
cls_token=cls_token,
|
| 138 |
+
mask_token=mask_token,
|
| 139 |
+
tokenize_chinese_chars=tokenize_chinese_chars,
|
| 140 |
+
strip_accents=strip_accents,
|
| 141 |
+
clean_up_tokenization_spaces=clean_up_tokenization_spaces,
|
| 142 |
+
**kwargs,
|
| 143 |
+
)
|
| 144 |
+
|
| 145 |
+
@property
|
| 146 |
+
def do_lower_case(self):
|
| 147 |
+
return self.basic_tokenizer.do_lower_case
|
| 148 |
+
|
| 149 |
+
@property
|
| 150 |
+
def vocab_size(self):
|
| 151 |
+
return len(self.vocab)
|
| 152 |
+
|
| 153 |
+
def get_vocab(self):
|
| 154 |
+
return dict(self.vocab, **self.added_tokens_encoder)
|
| 155 |
+
|
| 156 |
+
def _tokenize(self, text, split_special_tokens=False):
|
| 157 |
+
split_tokens = []
|
| 158 |
+
if self.do_basic_tokenize:
|
| 159 |
+
for token in self.basic_tokenizer.tokenize(
|
| 160 |
+
text, never_split=self.all_special_tokens if not split_special_tokens else None
|
| 161 |
+
):
|
| 162 |
+
# If the token is part of the never_split set
|
| 163 |
+
if token in self.basic_tokenizer.never_split:
|
| 164 |
+
split_tokens.append(token)
|
| 165 |
+
else:
|
| 166 |
+
split_tokens += self.wordpiece_tokenizer.tokenize(token)
|
| 167 |
+
else:
|
| 168 |
+
split_tokens = self.wordpiece_tokenizer.tokenize(text)
|
| 169 |
+
return split_tokens
|
| 170 |
+
|
| 171 |
+
def _convert_token_to_id(self, token):
|
| 172 |
+
"""Converts a token (str) in an id using the vocab."""
|
| 173 |
+
return self.vocab.get(token, self.vocab.get(self.unk_token))
|
| 174 |
+
|
| 175 |
+
def _convert_id_to_token(self, index):
|
| 176 |
+
"""Converts an index (integer) in a token (str) using the vocab."""
|
| 177 |
+
return self.ids_to_tokens.get(index, self.unk_token)
|
| 178 |
+
|
| 179 |
+
def convert_tokens_to_string(self, tokens):
|
| 180 |
+
"""Converts a sequence of tokens (string) in a single string."""
|
| 181 |
+
out_string = " ".join(tokens).replace(" ##", "").strip()
|
| 182 |
+
return out_string
|
| 183 |
+
|
| 184 |
+
def build_inputs_with_special_tokens(
|
| 185 |
+
self, token_ids_0: list[int], token_ids_1: list[int] | None = None
|
| 186 |
+
) -> list[int]:
|
| 187 |
+
"""
|
| 188 |
+
Build model inputs from a sequence or a pair of sequence for sequence classification tasks by concatenating and
|
| 189 |
+
adding special tokens. A BERT sequence has the following format:
|
| 190 |
+
|
| 191 |
+
- single sequence: `[CLS] X [SEP]`
|
| 192 |
+
- pair of sequences: `[CLS] A [SEP] B [SEP]`
|
| 193 |
+
|
| 194 |
+
Args:
|
| 195 |
+
token_ids_0 (`List[int]`):
|
| 196 |
+
List of IDs to which the special tokens will be added.
|
| 197 |
+
token_ids_1 (`List[int]`, *optional*):
|
| 198 |
+
Optional second list of IDs for sequence pairs.
|
| 199 |
+
|
| 200 |
+
Returns:
|
| 201 |
+
`List[int]`: List of [input IDs](../glossary#input-ids) with the appropriate special tokens.
|
| 202 |
+
"""
|
| 203 |
+
if token_ids_1 is None:
|
| 204 |
+
return [self.cls_token_id] + token_ids_0 + [self.sep_token_id]
|
| 205 |
+
cls = [self.cls_token_id]
|
| 206 |
+
sep = [self.sep_token_id]
|
| 207 |
+
return cls + token_ids_0 + sep + token_ids_1 + sep
|
| 208 |
+
|
| 209 |
+
def get_special_tokens_mask(
|
| 210 |
+
self, token_ids_0: list[int], token_ids_1: list[int] | None = None, already_has_special_tokens: bool = False
|
| 211 |
+
) -> list[int]:
|
| 212 |
+
"""
|
| 213 |
+
Retrieve sequence ids from a token list that has no special tokens added. This method is called when adding
|
| 214 |
+
special tokens using the tokenizer `prepare_for_model` method.
|
| 215 |
+
|
| 216 |
+
Args:
|
| 217 |
+
token_ids_0 (`List[int]`):
|
| 218 |
+
List of IDs.
|
| 219 |
+
token_ids_1 (`List[int]`, *optional*):
|
| 220 |
+
Optional second list of IDs for sequence pairs.
|
| 221 |
+
already_has_special_tokens (`bool`, *optional*, defaults to `False`):
|
| 222 |
+
Whether or not the token list is already formatted with special tokens for the model.
|
| 223 |
+
|
| 224 |
+
Returns:
|
| 225 |
+
`List[int]`: A list of integers in the range [0, 1]: 1 for a special token, 0 for a sequence token.
|
| 226 |
+
"""
|
| 227 |
+
|
| 228 |
+
if already_has_special_tokens:
|
| 229 |
+
return super().get_special_tokens_mask(
|
| 230 |
+
token_ids_0=token_ids_0, token_ids_1=token_ids_1, already_has_special_tokens=True
|
| 231 |
+
)
|
| 232 |
+
|
| 233 |
+
if token_ids_1 is not None:
|
| 234 |
+
return [1] + ([0] * len(token_ids_0)) + [1] + ([0] * len(token_ids_1)) + [1]
|
| 235 |
+
return [1] + ([0] * len(token_ids_0)) + [1]
|
| 236 |
+
|
| 237 |
+
def save_vocabulary(self, save_directory: str, filename_prefix: str | None = None) -> tuple[str]:
|
| 238 |
+
index = 0
|
| 239 |
+
if os.path.isdir(save_directory):
|
| 240 |
+
vocab_file = os.path.join(
|
| 241 |
+
save_directory, (filename_prefix + "-" if filename_prefix else "") + VOCAB_FILES_NAMES["vocab_file"]
|
| 242 |
+
)
|
| 243 |
+
else:
|
| 244 |
+
vocab_file = (filename_prefix + "-" if filename_prefix else "") + save_directory
|
| 245 |
+
with open(vocab_file, "w", encoding="utf-8") as writer:
|
| 246 |
+
for token, token_index in sorted(self.vocab.items(), key=lambda kv: kv[1]):
|
| 247 |
+
if index != token_index:
|
| 248 |
+
logger.warning(
|
| 249 |
+
f"Saving vocabulary to {vocab_file}: vocabulary indices are not consecutive."
|
| 250 |
+
" Please check that the vocabulary is not corrupted!"
|
| 251 |
+
)
|
| 252 |
+
index = token_index
|
| 253 |
+
writer.write(token + "\n")
|
| 254 |
+
index += 1
|
| 255 |
+
return (vocab_file,)
|
| 256 |
+
|
| 257 |
+
|
| 258 |
+
class BasicTokenizer:
|
| 259 |
+
"""
|
| 260 |
+
Constructs a BasicTokenizer that will run basic tokenization (punctuation splitting, lower casing, etc.).
|
| 261 |
+
|
| 262 |
+
Args:
|
| 263 |
+
do_lower_case (`bool`, *optional*, defaults to `True`):
|
| 264 |
+
Whether or not to lowercase the input when tokenizing.
|
| 265 |
+
never_split (`Iterable`, *optional*):
|
| 266 |
+
Collection of tokens which will never be split during tokenization. Only has an effect when
|
| 267 |
+
`do_basic_tokenize=True`
|
| 268 |
+
tokenize_chinese_chars (`bool`, *optional*, defaults to `True`):
|
| 269 |
+
Whether or not to tokenize Chinese characters.
|
| 270 |
+
|
| 271 |
+
This should likely be deactivated for Japanese (see this
|
| 272 |
+
[issue](https://github.com/huggingface/transformers/issues/328)).
|
| 273 |
+
strip_accents (`bool`, *optional*):
|
| 274 |
+
Whether or not to strip all accents. If this option is not specified, then it will be determined by the
|
| 275 |
+
value for `lowercase` (as in the original BERT).
|
| 276 |
+
do_split_on_punc (`bool`, *optional*, defaults to `True`):
|
| 277 |
+
In some instances we want to skip the basic punctuation splitting so that later tokenization can capture
|
| 278 |
+
the full context of the words, such as contractions.
|
| 279 |
+
"""
|
| 280 |
+
|
| 281 |
+
def __init__(
|
| 282 |
+
self,
|
| 283 |
+
do_lower_case=True,
|
| 284 |
+
never_split=None,
|
| 285 |
+
tokenize_chinese_chars=True,
|
| 286 |
+
strip_accents=None,
|
| 287 |
+
do_split_on_punc=True,
|
| 288 |
+
):
|
| 289 |
+
if never_split is None:
|
| 290 |
+
never_split = []
|
| 291 |
+
self.do_lower_case = do_lower_case
|
| 292 |
+
self.never_split = set(never_split)
|
| 293 |
+
self.tokenize_chinese_chars = tokenize_chinese_chars
|
| 294 |
+
self.strip_accents = strip_accents
|
| 295 |
+
self.do_split_on_punc = do_split_on_punc
|
| 296 |
+
|
| 297 |
+
def tokenize(self, text, never_split=None):
|
| 298 |
+
"""
|
| 299 |
+
Basic Tokenization of a piece of text. For sub-word tokenization, see WordPieceTokenizer.
|
| 300 |
+
|
| 301 |
+
Args:
|
| 302 |
+
never_split (`List[str]`, *optional*)
|
| 303 |
+
Kept for backward compatibility purposes. Now implemented directly at the base class level (see
|
| 304 |
+
[`PreTrainedTokenizer.tokenize`]) List of token not to split.
|
| 305 |
+
"""
|
| 306 |
+
# union() returns a new set by concatenating the two sets.
|
| 307 |
+
never_split = self.never_split.union(set(never_split)) if never_split else self.never_split
|
| 308 |
+
text = self._clean_text(text)
|
| 309 |
+
|
| 310 |
+
# This was added on November 1st, 2018 for the multilingual and Chinese
|
| 311 |
+
# models. This is also applied to the English models now, but it doesn't
|
| 312 |
+
# matter since the English models were not trained on any Chinese data
|
| 313 |
+
# and generally don't have any Chinese data in them (there are Chinese
|
| 314 |
+
# characters in the vocabulary because Wikipedia does have some Chinese
|
| 315 |
+
# words in the English Wikipedia.).
|
| 316 |
+
if self.tokenize_chinese_chars:
|
| 317 |
+
text = self._tokenize_chinese_chars(text)
|
| 318 |
+
# prevents treating the same character with different unicode codepoints as different characters
|
| 319 |
+
unicode_normalized_text = unicodedata.normalize("NFC", text)
|
| 320 |
+
orig_tokens = whitespace_tokenize(unicode_normalized_text)
|
| 321 |
+
split_tokens = []
|
| 322 |
+
for token in orig_tokens:
|
| 323 |
+
if token not in never_split:
|
| 324 |
+
if self.do_lower_case:
|
| 325 |
+
token = token.lower()
|
| 326 |
+
if self.strip_accents is not False:
|
| 327 |
+
token = self._run_strip_accents(token)
|
| 328 |
+
elif self.strip_accents:
|
| 329 |
+
token = self._run_strip_accents(token)
|
| 330 |
+
split_tokens.extend(self._run_split_on_punc(token, never_split))
|
| 331 |
+
|
| 332 |
+
output_tokens = whitespace_tokenize(" ".join(split_tokens))
|
| 333 |
+
return output_tokens
|
| 334 |
+
|
| 335 |
+
def _run_strip_accents(self, text):
|
| 336 |
+
"""Strips accents from a piece of text."""
|
| 337 |
+
text = unicodedata.normalize("NFD", text)
|
| 338 |
+
output = []
|
| 339 |
+
for char in text:
|
| 340 |
+
cat = unicodedata.category(char)
|
| 341 |
+
if cat == "Mn":
|
| 342 |
+
continue
|
| 343 |
+
output.append(char)
|
| 344 |
+
return "".join(output)
|
| 345 |
+
|
| 346 |
+
def _run_split_on_punc(self, text, never_split=None):
|
| 347 |
+
"""Splits punctuation on a piece of text."""
|
| 348 |
+
if not self.do_split_on_punc or (never_split is not None and text in never_split):
|
| 349 |
+
return [text]
|
| 350 |
+
chars = list(text)
|
| 351 |
+
i = 0
|
| 352 |
+
start_new_word = True
|
| 353 |
+
output = []
|
| 354 |
+
while i < len(chars):
|
| 355 |
+
char = chars[i]
|
| 356 |
+
if _is_punctuation(char):
|
| 357 |
+
output.append([char])
|
| 358 |
+
start_new_word = True
|
| 359 |
+
else:
|
| 360 |
+
if start_new_word:
|
| 361 |
+
output.append([])
|
| 362 |
+
start_new_word = False
|
| 363 |
+
output[-1].append(char)
|
| 364 |
+
i += 1
|
| 365 |
+
|
| 366 |
+
return ["".join(x) for x in output]
|
| 367 |
+
|
| 368 |
+
def _tokenize_chinese_chars(self, text):
|
| 369 |
+
"""Adds whitespace around any CJK character."""
|
| 370 |
+
output = []
|
| 371 |
+
for char in text:
|
| 372 |
+
cp = ord(char)
|
| 373 |
+
if self._is_chinese_char(cp):
|
| 374 |
+
output.append(" ")
|
| 375 |
+
output.append(char)
|
| 376 |
+
output.append(" ")
|
| 377 |
+
else:
|
| 378 |
+
output.append(char)
|
| 379 |
+
return "".join(output)
|
| 380 |
+
|
| 381 |
+
def _is_chinese_char(self, cp):
|
| 382 |
+
"""Checks whether CP is the codepoint of a CJK character."""
|
| 383 |
+
# This defines a "chinese character" as anything in the CJK Unicode block:
|
| 384 |
+
# https://en.wikipedia.org/wiki/CJK_Unified_Ideographs_(Unicode_block)
|
| 385 |
+
#
|
| 386 |
+
# Note that the CJK Unicode block is NOT all Japanese and Korean characters,
|
| 387 |
+
# despite its name. The modern Korean Hangul alphabet is a different block,
|
| 388 |
+
# as is Japanese Hiragana and Katakana. Those alphabets are used to write
|
| 389 |
+
# space-separated words, so they are not treated specially and handled
|
| 390 |
+
# like the all of the other languages.
|
| 391 |
+
if (
|
| 392 |
+
(cp >= 0x4E00 and cp <= 0x9FFF)
|
| 393 |
+
or (cp >= 0x3400 and cp <= 0x4DBF)
|
| 394 |
+
or (cp >= 0x20000 and cp <= 0x2A6DF)
|
| 395 |
+
or (cp >= 0x2A700 and cp <= 0x2B73F)
|
| 396 |
+
or (cp >= 0x2B740 and cp <= 0x2B81F)
|
| 397 |
+
or (cp >= 0x2B820 and cp <= 0x2CEAF)
|
| 398 |
+
or (cp >= 0xF900 and cp <= 0xFAFF)
|
| 399 |
+
or (cp >= 0x2F800 and cp <= 0x2FA1F)
|
| 400 |
+
):
|
| 401 |
+
return True
|
| 402 |
+
|
| 403 |
+
return False
|
| 404 |
+
|
| 405 |
+
def _clean_text(self, text):
|
| 406 |
+
"""Performs invalid character removal and whitespace cleanup on text."""
|
| 407 |
+
output = []
|
| 408 |
+
for char in text:
|
| 409 |
+
cp = ord(char)
|
| 410 |
+
if cp == 0 or cp == 0xFFFD or _is_control(char):
|
| 411 |
+
continue
|
| 412 |
+
if _is_whitespace(char):
|
| 413 |
+
output.append(" ")
|
| 414 |
+
else:
|
| 415 |
+
output.append(char)
|
| 416 |
+
return "".join(output)
|
| 417 |
+
|
| 418 |
+
|
| 419 |
+
class WordpieceTokenizer:
|
| 420 |
+
"""Runs WordPiece tokenization."""
|
| 421 |
+
|
| 422 |
+
def __init__(self, vocab, unk_token, max_input_chars_per_word=100):
|
| 423 |
+
self.vocab = vocab
|
| 424 |
+
self.unk_token = unk_token
|
| 425 |
+
self.max_input_chars_per_word = max_input_chars_per_word
|
| 426 |
+
|
| 427 |
+
def tokenize(self, text):
|
| 428 |
+
"""
|
| 429 |
+
Tokenizes a piece of text into its word pieces. This uses a greedy longest-match-first algorithm to perform
|
| 430 |
+
tokenization using the given vocabulary.
|
| 431 |
+
|
| 432 |
+
For example, `input = "unaffable"` will return as output `["un", "##aff", "##able"]`.
|
| 433 |
+
|
| 434 |
+
Args:
|
| 435 |
+
text: A single token or whitespace separated tokens. This should have
|
| 436 |
+
already been passed through *BasicTokenizer*.
|
| 437 |
+
|
| 438 |
+
Returns:
|
| 439 |
+
A list of wordpiece tokens.
|
| 440 |
+
"""
|
| 441 |
+
|
| 442 |
+
output_tokens = []
|
| 443 |
+
for token in whitespace_tokenize(text):
|
| 444 |
+
chars = list(token)
|
| 445 |
+
if len(chars) > self.max_input_chars_per_word:
|
| 446 |
+
output_tokens.append(self.unk_token)
|
| 447 |
+
continue
|
| 448 |
+
|
| 449 |
+
is_bad = False
|
| 450 |
+
start = 0
|
| 451 |
+
sub_tokens = []
|
| 452 |
+
while start < len(chars):
|
| 453 |
+
end = len(chars)
|
| 454 |
+
cur_substr = None
|
| 455 |
+
while start < end:
|
| 456 |
+
substr = "".join(chars[start:end])
|
| 457 |
+
if start > 0:
|
| 458 |
+
substr = "##" + substr
|
| 459 |
+
if substr in self.vocab:
|
| 460 |
+
cur_substr = substr
|
| 461 |
+
break
|
| 462 |
+
end -= 1
|
| 463 |
+
if cur_substr is None:
|
| 464 |
+
is_bad = True
|
| 465 |
+
break
|
| 466 |
+
sub_tokens.append(cur_substr)
|
| 467 |
+
start = end
|
| 468 |
+
|
| 469 |
+
if is_bad:
|
| 470 |
+
output_tokens.append(self.unk_token)
|
| 471 |
+
else:
|
| 472 |
+
output_tokens.extend(sub_tokens)
|
| 473 |
+
return output_tokens
|
| 474 |
+
|
| 475 |
+
|
| 476 |
+
__all__ = ["BasicTokenizer", "BertTokenizerLegacy", "WordpieceTokenizer"]
|
third_party/transformers/src/transformers/models/bertweet/__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_bertweet 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/bertweet/tokenization_bertweet.py
ADDED
|
@@ -0,0 +1,698 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright (c) 2020, VinAI Research and the HuggingFace Inc. team.
|
| 2 |
+
# Copyright 2018 The Open AI Team Authors and The HuggingFace Inc. team.
|
| 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 |
+
"""Tokenization classes for BERTweet"""
|
| 16 |
+
|
| 17 |
+
import html
|
| 18 |
+
import os
|
| 19 |
+
import re
|
| 20 |
+
|
| 21 |
+
import regex
|
| 22 |
+
|
| 23 |
+
from ...tokenization_python import PreTrainedTokenizer
|
| 24 |
+
from ...utils import logging
|
| 25 |
+
|
| 26 |
+
|
| 27 |
+
logger = logging.get_logger(__name__)
|
| 28 |
+
|
| 29 |
+
VOCAB_FILES_NAMES = {
|
| 30 |
+
"vocab_file": "vocab.txt",
|
| 31 |
+
"merges_file": "bpe.codes",
|
| 32 |
+
}
|
| 33 |
+
|
| 34 |
+
|
| 35 |
+
def get_pairs(word):
|
| 36 |
+
"""
|
| 37 |
+
Return set of symbol pairs in a word.
|
| 38 |
+
|
| 39 |
+
Word is represented as tuple of symbols (symbols being variable-length strings).
|
| 40 |
+
"""
|
| 41 |
+
pairs = set()
|
| 42 |
+
prev_char = word[0]
|
| 43 |
+
for char in word[1:]:
|
| 44 |
+
pairs.add((prev_char, char))
|
| 45 |
+
prev_char = char
|
| 46 |
+
|
| 47 |
+
pairs = set(pairs)
|
| 48 |
+
return pairs
|
| 49 |
+
|
| 50 |
+
|
| 51 |
+
class BertweetTokenizer(PreTrainedTokenizer):
|
| 52 |
+
"""
|
| 53 |
+
Constructs a BERTweet tokenizer, using Byte-Pair-Encoding.
|
| 54 |
+
|
| 55 |
+
This tokenizer inherits from [`PreTrainedTokenizer`] which contains most of the main methods. Users should refer to
|
| 56 |
+
this superclass for more information regarding those methods.
|
| 57 |
+
|
| 58 |
+
Args:
|
| 59 |
+
vocab_file (`str`):
|
| 60 |
+
Path to the vocabulary file.
|
| 61 |
+
merges_file (`str`):
|
| 62 |
+
Path to the merges file.
|
| 63 |
+
normalization (`bool`, *optional*, defaults to `False`):
|
| 64 |
+
Whether or not to apply a normalization preprocess.
|
| 65 |
+
bos_token (`str`, *optional*, defaults to `"<s>"`):
|
| 66 |
+
The beginning of sequence token that was used during pretraining. Can be used a sequence classifier token.
|
| 67 |
+
|
| 68 |
+
<Tip>
|
| 69 |
+
|
| 70 |
+
When building a sequence using special tokens, this is not the token that is used for the beginning of
|
| 71 |
+
sequence. The token used is the `cls_token`.
|
| 72 |
+
|
| 73 |
+
</Tip>
|
| 74 |
+
|
| 75 |
+
eos_token (`str`, *optional*, defaults to `"</s>"`):
|
| 76 |
+
The end of sequence token.
|
| 77 |
+
|
| 78 |
+
<Tip>
|
| 79 |
+
|
| 80 |
+
When building a sequence using special tokens, this is not the token that is used for the end of sequence.
|
| 81 |
+
The token used is the `sep_token`.
|
| 82 |
+
|
| 83 |
+
</Tip>
|
| 84 |
+
|
| 85 |
+
sep_token (`str`, *optional*, defaults to `"</s>"`):
|
| 86 |
+
The separator token, which is used when building a sequence from multiple sequences, e.g. two sequences for
|
| 87 |
+
sequence classification or for a text and a question for question answering. It is also used as the last
|
| 88 |
+
token of a sequence built with special tokens.
|
| 89 |
+
cls_token (`str`, *optional*, defaults to `"<s>"`):
|
| 90 |
+
The classifier token which is used when doing sequence classification (classification of the whole sequence
|
| 91 |
+
instead of per-token classification). It is the first token of the sequence when built with special tokens.
|
| 92 |
+
unk_token (`str`, *optional*, defaults to `"<unk>"`):
|
| 93 |
+
The unknown token. A token that is not in the vocabulary cannot be converted to an ID and is set to be this
|
| 94 |
+
token instead.
|
| 95 |
+
pad_token (`str`, *optional*, defaults to `"<pad>"`):
|
| 96 |
+
The token used for padding, for example when batching sequences of different lengths.
|
| 97 |
+
mask_token (`str`, *optional*, defaults to `"<mask>"`):
|
| 98 |
+
The token used for masking values. This is the token used when training this model with masked language
|
| 99 |
+
modeling. This is the token which the model will try to predict.
|
| 100 |
+
"""
|
| 101 |
+
|
| 102 |
+
vocab_files_names = VOCAB_FILES_NAMES
|
| 103 |
+
|
| 104 |
+
def __init__(
|
| 105 |
+
self,
|
| 106 |
+
vocab_file,
|
| 107 |
+
merges_file,
|
| 108 |
+
normalization=False,
|
| 109 |
+
bos_token="<s>",
|
| 110 |
+
eos_token="</s>",
|
| 111 |
+
sep_token="</s>",
|
| 112 |
+
cls_token="<s>",
|
| 113 |
+
unk_token="<unk>",
|
| 114 |
+
pad_token="<pad>",
|
| 115 |
+
mask_token="<mask>",
|
| 116 |
+
**kwargs,
|
| 117 |
+
):
|
| 118 |
+
try:
|
| 119 |
+
from emoji import demojize
|
| 120 |
+
|
| 121 |
+
self.demojizer = demojize
|
| 122 |
+
except ImportError:
|
| 123 |
+
logger.warning(
|
| 124 |
+
"emoji is not installed, thus not converting emoticons or emojis into text. Install emoji: pip3"
|
| 125 |
+
" install emoji==0.6.0"
|
| 126 |
+
)
|
| 127 |
+
self.demojizer = None
|
| 128 |
+
|
| 129 |
+
self.vocab_file = vocab_file
|
| 130 |
+
self.merges_file = merges_file
|
| 131 |
+
|
| 132 |
+
self.encoder = {}
|
| 133 |
+
self.encoder[str(bos_token)] = 0
|
| 134 |
+
self.encoder[str(pad_token)] = 1
|
| 135 |
+
self.encoder[str(eos_token)] = 2
|
| 136 |
+
self.encoder[str(unk_token)] = 3
|
| 137 |
+
|
| 138 |
+
self.add_from_file(vocab_file)
|
| 139 |
+
|
| 140 |
+
self.decoder = {v: k for k, v in self.encoder.items()}
|
| 141 |
+
|
| 142 |
+
with open(merges_file, encoding="utf-8") as merges_handle:
|
| 143 |
+
merges = merges_handle.read().split("\n")[:-1]
|
| 144 |
+
merges = [tuple(merge.split()[:-1]) for merge in merges]
|
| 145 |
+
self.bpe_ranks = dict(zip(merges, range(len(merges))))
|
| 146 |
+
self.cache = {}
|
| 147 |
+
|
| 148 |
+
self.normalization = normalization
|
| 149 |
+
self.tweetPreprocessor = TweetTokenizer()
|
| 150 |
+
self.special_puncts = {"’": "'", "…": "..."}
|
| 151 |
+
|
| 152 |
+
super().__init__(
|
| 153 |
+
normalization=normalization,
|
| 154 |
+
bos_token=bos_token,
|
| 155 |
+
eos_token=eos_token,
|
| 156 |
+
sep_token=sep_token,
|
| 157 |
+
cls_token=cls_token,
|
| 158 |
+
unk_token=unk_token,
|
| 159 |
+
pad_token=pad_token,
|
| 160 |
+
mask_token=mask_token,
|
| 161 |
+
# Configure patterns instead of overriding methods
|
| 162 |
+
token_type_ids_pattern="all_zeros", # BERTweet doesn't use token type IDs
|
| 163 |
+
token_type_ids_include_special_tokens=True,
|
| 164 |
+
special_tokens_pattern="cls_double_sep", # <s> X </s></s> Y </s>
|
| 165 |
+
**kwargs,
|
| 166 |
+
)
|
| 167 |
+
|
| 168 |
+
@property
|
| 169 |
+
def vocab_size(self):
|
| 170 |
+
return len(self.encoder)
|
| 171 |
+
|
| 172 |
+
def get_vocab(self):
|
| 173 |
+
return dict(self.encoder, **self.added_tokens_encoder)
|
| 174 |
+
|
| 175 |
+
def bpe(self, token):
|
| 176 |
+
if token in self.cache:
|
| 177 |
+
return self.cache[token]
|
| 178 |
+
word = tuple(token)
|
| 179 |
+
word = tuple(list(word[:-1]) + [word[-1] + "</w>"])
|
| 180 |
+
pairs = get_pairs(word)
|
| 181 |
+
|
| 182 |
+
if not pairs:
|
| 183 |
+
return token
|
| 184 |
+
|
| 185 |
+
while True:
|
| 186 |
+
bigram = min(pairs, key=lambda pair: self.bpe_ranks.get(pair, float("inf")))
|
| 187 |
+
if bigram not in self.bpe_ranks:
|
| 188 |
+
break
|
| 189 |
+
first, second = bigram
|
| 190 |
+
new_word = []
|
| 191 |
+
i = 0
|
| 192 |
+
while i < len(word):
|
| 193 |
+
try:
|
| 194 |
+
j = word.index(first, i)
|
| 195 |
+
except ValueError:
|
| 196 |
+
new_word.extend(word[i:])
|
| 197 |
+
break
|
| 198 |
+
else:
|
| 199 |
+
new_word.extend(word[i:j])
|
| 200 |
+
i = j
|
| 201 |
+
|
| 202 |
+
if word[i] == first and i < len(word) - 1 and word[i + 1] == second:
|
| 203 |
+
new_word.append(first + second)
|
| 204 |
+
i += 2
|
| 205 |
+
else:
|
| 206 |
+
new_word.append(word[i])
|
| 207 |
+
i += 1
|
| 208 |
+
new_word = tuple(new_word)
|
| 209 |
+
word = new_word
|
| 210 |
+
if len(word) == 1:
|
| 211 |
+
break
|
| 212 |
+
else:
|
| 213 |
+
pairs = get_pairs(word)
|
| 214 |
+
word = "@@ ".join(word)
|
| 215 |
+
word = word[:-4]
|
| 216 |
+
self.cache[token] = word
|
| 217 |
+
return word
|
| 218 |
+
|
| 219 |
+
def _tokenize(self, text):
|
| 220 |
+
"""Tokenize a string."""
|
| 221 |
+
if self.normalization: # Perform Tweet normalization before performing BPE
|
| 222 |
+
text = self.normalizeTweet(text)
|
| 223 |
+
|
| 224 |
+
split_tokens = []
|
| 225 |
+
words = re.findall(r"\S+\n?", text)
|
| 226 |
+
for token in words:
|
| 227 |
+
split_tokens.extend(list(self.bpe(token).split(" ")))
|
| 228 |
+
return split_tokens
|
| 229 |
+
|
| 230 |
+
def normalizeTweet(self, tweet):
|
| 231 |
+
"""
|
| 232 |
+
Normalize a raw Tweet
|
| 233 |
+
"""
|
| 234 |
+
for punct in self.special_puncts:
|
| 235 |
+
tweet = tweet.replace(punct, self.special_puncts[punct])
|
| 236 |
+
|
| 237 |
+
tokens = self.tweetPreprocessor.tokenize(tweet)
|
| 238 |
+
normTweet = " ".join([self.normalizeToken(token) for token in tokens])
|
| 239 |
+
|
| 240 |
+
normTweet = (
|
| 241 |
+
normTweet.replace("cannot ", "can not ")
|
| 242 |
+
.replace("n't ", " n't ")
|
| 243 |
+
.replace("n 't ", " n't ")
|
| 244 |
+
.replace("ca n't", "can't")
|
| 245 |
+
.replace("ai n't", "ain't")
|
| 246 |
+
)
|
| 247 |
+
normTweet = (
|
| 248 |
+
normTweet.replace("'m ", " 'm ")
|
| 249 |
+
.replace("'re ", " 're ")
|
| 250 |
+
.replace("'s ", " 's ")
|
| 251 |
+
.replace("'ll ", " 'll ")
|
| 252 |
+
.replace("'d ", " 'd ")
|
| 253 |
+
.replace("'ve ", " 've ")
|
| 254 |
+
)
|
| 255 |
+
normTweet = (
|
| 256 |
+
normTweet.replace(" p . m .", " p.m.")
|
| 257 |
+
.replace(" p . m ", " p.m ")
|
| 258 |
+
.replace(" a . m .", " a.m.")
|
| 259 |
+
.replace(" a . m ", " a.m ")
|
| 260 |
+
)
|
| 261 |
+
|
| 262 |
+
return " ".join(normTweet.split())
|
| 263 |
+
|
| 264 |
+
def normalizeToken(self, token):
|
| 265 |
+
"""
|
| 266 |
+
Normalize tokens in a Tweet
|
| 267 |
+
"""
|
| 268 |
+
lowercased_token = token.lower()
|
| 269 |
+
if token.startswith("@"):
|
| 270 |
+
return "@USER"
|
| 271 |
+
elif lowercased_token.startswith("http") or lowercased_token.startswith("www"):
|
| 272 |
+
return "HTTPURL"
|
| 273 |
+
elif len(token) == 1:
|
| 274 |
+
if token in self.special_puncts:
|
| 275 |
+
return self.special_puncts[token]
|
| 276 |
+
if self.demojizer is not None:
|
| 277 |
+
return self.demojizer(token)
|
| 278 |
+
else:
|
| 279 |
+
return token
|
| 280 |
+
else:
|
| 281 |
+
return token
|
| 282 |
+
|
| 283 |
+
def _convert_token_to_id(self, token):
|
| 284 |
+
"""Converts a token (str) in an id using the vocab."""
|
| 285 |
+
return self.encoder.get(token, self.encoder.get(self.unk_token))
|
| 286 |
+
|
| 287 |
+
def _convert_id_to_token(self, index):
|
| 288 |
+
"""Converts an index (integer) in a token (str) using the vocab."""
|
| 289 |
+
return self.decoder.get(index, self.unk_token)
|
| 290 |
+
|
| 291 |
+
def convert_tokens_to_string(self, tokens):
|
| 292 |
+
"""Converts a sequence of tokens (string) in a single string."""
|
| 293 |
+
out_string = " ".join(tokens).replace("@@ ", "").strip()
|
| 294 |
+
return out_string
|
| 295 |
+
|
| 296 |
+
# def decode(self, token_ids, skip_special_tokens=False, clean_up_tokenization_spaces=True):
|
| 297 |
+
# filtered_tokens = ' '.join(self.convert_ids_to_tokens(token_ids, skip_special_tokens=skip_special_tokens))
|
| 298 |
+
# tokens_generated_so_far = re.sub('(@@ )', '', string=filtered_tokens)
|
| 299 |
+
# tokens_generated_so_far = re.sub('(@@ ?$)', '', string=tokens_generated_so_far)
|
| 300 |
+
# return ''.join(tokens_generated_so_far)
|
| 301 |
+
|
| 302 |
+
def save_vocabulary(self, save_directory: str, filename_prefix: str | None = None) -> tuple[str, ...]:
|
| 303 |
+
"""
|
| 304 |
+
Save the vocabulary and merges files to a directory.
|
| 305 |
+
"""
|
| 306 |
+
if not os.path.isdir(save_directory):
|
| 307 |
+
logger.error(f"Vocabulary path ({save_directory}) should be a directory")
|
| 308 |
+
return ()
|
| 309 |
+
|
| 310 |
+
vocab_files_names = getattr(self, "vocab_files_names", {})
|
| 311 |
+
prefix = f"{filename_prefix}-" if filename_prefix else ""
|
| 312 |
+
|
| 313 |
+
# Save vocabulary in the format expected by add_from_file: <token> <id>
|
| 314 |
+
# Exclude special tokens (IDs 0-3) as they are added in __init__ before add_from_file
|
| 315 |
+
vocab_file = os.path.join(save_directory, prefix + vocab_files_names.get("vocab_file", "vocab.txt"))
|
| 316 |
+
with open(vocab_file, "w", encoding="utf-8") as f:
|
| 317 |
+
for token, token_id in sorted(self.encoder.items(), key=lambda kv: kv[1]):
|
| 318 |
+
# Only save tokens with ID >= 4, as IDs 0-3 are reserved for special tokens
|
| 319 |
+
if token_id >= 4:
|
| 320 |
+
f.write(f"{token} {token_id}\n")
|
| 321 |
+
|
| 322 |
+
# Save BPE merges
|
| 323 |
+
merge_file = os.path.join(save_directory, prefix + vocab_files_names.get("merges_file", "bpe.codes"))
|
| 324 |
+
with open(merge_file, "w", encoding="utf-8") as writer:
|
| 325 |
+
writer.writelines(
|
| 326 |
+
" ".join(bpe_tokens) + "\n"
|
| 327 |
+
for bpe_tokens, token_index in sorted(self.bpe_ranks.items(), key=lambda kv: kv[1])
|
| 328 |
+
)
|
| 329 |
+
|
| 330 |
+
return (vocab_file, merge_file)
|
| 331 |
+
|
| 332 |
+
def add_from_file(self, f):
|
| 333 |
+
"""
|
| 334 |
+
Loads a pre-existing dictionary from a text file and adds its symbols to this instance.
|
| 335 |
+
"""
|
| 336 |
+
if isinstance(f, str):
|
| 337 |
+
try:
|
| 338 |
+
with open(f, "r", encoding="utf-8") as fd:
|
| 339 |
+
self.add_from_file(fd)
|
| 340 |
+
except FileNotFoundError as fnfe:
|
| 341 |
+
raise fnfe
|
| 342 |
+
except UnicodeError:
|
| 343 |
+
raise Exception(f"Incorrect encoding detected in {f}, please rebuild the dataset")
|
| 344 |
+
return
|
| 345 |
+
|
| 346 |
+
lines = f.readlines()
|
| 347 |
+
for lineTmp in lines:
|
| 348 |
+
line = lineTmp.strip()
|
| 349 |
+
idx = line.rfind(" ")
|
| 350 |
+
if idx == -1:
|
| 351 |
+
raise ValueError("Incorrect dictionary format, expected '<token> <cnt>'")
|
| 352 |
+
word = line[:idx]
|
| 353 |
+
self.encoder[word] = len(self.encoder)
|
| 354 |
+
|
| 355 |
+
|
| 356 |
+
# Natural Language Toolkit: Twitter Tokenizer
|
| 357 |
+
#
|
| 358 |
+
# Copyright (C) 2001-2020 NLTK Project
|
| 359 |
+
# Author: Christopher Potts <cgpotts@stanford.edu>
|
| 360 |
+
# Ewan Klein <ewan@inf.ed.ac.uk> (modifications)
|
| 361 |
+
# Pierpaolo Pantone <> (modifications)
|
| 362 |
+
# URL: http://nltk.org/
|
| 363 |
+
# For license information, see LICENSE.TXT
|
| 364 |
+
#
|
| 365 |
+
|
| 366 |
+
|
| 367 |
+
"""
|
| 368 |
+
Twitter-aware tokenizer, designed to be flexible and easy to adapt to new domains and tasks. The basic logic is this:
|
| 369 |
+
|
| 370 |
+
1. The tuple regex_strings defines a list of regular expression strings.
|
| 371 |
+
|
| 372 |
+
2. The regex_strings strings are put, in order, into a compiled regular expression object called word_re.
|
| 373 |
+
|
| 374 |
+
3. The tokenization is done by word_re.findall(s), where s is the user-supplied string, inside the tokenize() method of
|
| 375 |
+
the class Tokenizer.
|
| 376 |
+
|
| 377 |
+
4. When instantiating Tokenizer objects, there is a single option: preserve_case. By default, it is set to True. If it
|
| 378 |
+
is set to False, then the tokenizer will lowercase everything except for emoticons.
|
| 379 |
+
|
| 380 |
+
"""
|
| 381 |
+
|
| 382 |
+
|
| 383 |
+
######################################################################
|
| 384 |
+
#
|
| 385 |
+
# import regex # https://github.com/nltk/nltk/issues/2409
|
| 386 |
+
# import html
|
| 387 |
+
#
|
| 388 |
+
######################################################################
|
| 389 |
+
# The following strings are components in the regular expression
|
| 390 |
+
# that is used for tokenizing. It's important that phone_number
|
| 391 |
+
# appears first in the final regex (since it can contain whitespace).
|
| 392 |
+
# It also could matter that tags comes after emoticons, due to the
|
| 393 |
+
# possibility of having text like
|
| 394 |
+
#
|
| 395 |
+
# <:| and some text >:)
|
| 396 |
+
#
|
| 397 |
+
# Most importantly, the final element should always be last, since it
|
| 398 |
+
# does a last ditch whitespace-based tokenization of whatever is left.
|
| 399 |
+
|
| 400 |
+
# ToDo: Update with http://en.wikipedia.org/wiki/List_of_emoticons ?
|
| 401 |
+
|
| 402 |
+
# This particular element is used in a couple ways, so we define it
|
| 403 |
+
# with a name:
|
| 404 |
+
# docstyle-ignore
|
| 405 |
+
EMOTICONS = r"""
|
| 406 |
+
(?:
|
| 407 |
+
[<>]?
|
| 408 |
+
[:;=8] # eyes
|
| 409 |
+
[\-o\*\']? # optional nose
|
| 410 |
+
[\)\]\(\[dDpP/\:\}\{@\|\\] # mouth
|
| 411 |
+
|
|
| 412 |
+
[\)\]\(\[dDpP/\:\}\{@\|\\] # mouth
|
| 413 |
+
[\-o\*\']? # optional nose
|
| 414 |
+
[:;=8] # eyes
|
| 415 |
+
[<>]?
|
| 416 |
+
|
|
| 417 |
+
<3 # heart
|
| 418 |
+
)"""
|
| 419 |
+
|
| 420 |
+
# URL pattern due to John Gruber, modified by Tom Winzig. See
|
| 421 |
+
# https://gist.github.com/winzig/8894715
|
| 422 |
+
# docstyle-ignore
|
| 423 |
+
URLS = r""" # Capture 1: entire matched URL
|
| 424 |
+
(?:
|
| 425 |
+
https?: # URL protocol and colon
|
| 426 |
+
(?:
|
| 427 |
+
/{1,3} # 1-3 slashes
|
| 428 |
+
| # or
|
| 429 |
+
[a-z0-9%] # Single letter or digit or '%'
|
| 430 |
+
# (Trying not to match e.g. "URI::Escape")
|
| 431 |
+
)
|
| 432 |
+
| # or
|
| 433 |
+
# looks like domain name followed by a slash:
|
| 434 |
+
[a-z0-9.\-]+[.]
|
| 435 |
+
(?:[a-z]{2,13})
|
| 436 |
+
/
|
| 437 |
+
)
|
| 438 |
+
(?: # One or more:
|
| 439 |
+
[^\s()<>{}\[\]]+ # Run of non-space, non-()<>{}[]
|
| 440 |
+
| # or
|
| 441 |
+
\([^\s()]*?\([^\s()]+\)[^\s()]*?\) # balanced parens, one level deep: (...(...)...)
|
| 442 |
+
|
|
| 443 |
+
\([^\s]+?\) # balanced parens, non-recursive: (...)
|
| 444 |
+
)+
|
| 445 |
+
(?: # End with:
|
| 446 |
+
\([^\s()]*?\([^\s()]+\)[^\s()]*?\) # balanced parens, one level deep: (...(...)...)
|
| 447 |
+
|
|
| 448 |
+
\([^\s]+?\) # balanced parens, non-recursive: (...)
|
| 449 |
+
| # or
|
| 450 |
+
[^\s`!()\[\]{};:'".,<>?«»“”‘’] # not a space or one of these punct chars
|
| 451 |
+
)
|
| 452 |
+
| # OR, the following to match naked domains:
|
| 453 |
+
(?:
|
| 454 |
+
(?<!@) # not preceded by a @, avoid matching foo@_gmail.com_
|
| 455 |
+
[a-z0-9]+
|
| 456 |
+
(?:[.\-][a-z0-9]+)*
|
| 457 |
+
[.]
|
| 458 |
+
(?:[a-z]{2,13})
|
| 459 |
+
\b
|
| 460 |
+
/?
|
| 461 |
+
(?!@) # not succeeded by a @,
|
| 462 |
+
# avoid matching "foo.na" in "foo.na@example.com"
|
| 463 |
+
)
|
| 464 |
+
"""
|
| 465 |
+
|
| 466 |
+
# docstyle-ignore
|
| 467 |
+
# The components of the tokenizer:
|
| 468 |
+
REGEXPS = (
|
| 469 |
+
URLS,
|
| 470 |
+
# Phone numbers:
|
| 471 |
+
r"""
|
| 472 |
+
(?:
|
| 473 |
+
(?: # (international)
|
| 474 |
+
\+?[01]
|
| 475 |
+
[ *\-.\)]*
|
| 476 |
+
)?
|
| 477 |
+
(?: # (area code)
|
| 478 |
+
[\(]?
|
| 479 |
+
\d{3}
|
| 480 |
+
[ *\-.\)]*
|
| 481 |
+
)?
|
| 482 |
+
\d{3} # exchange
|
| 483 |
+
[ *\-.\)]*
|
| 484 |
+
\d{4} # base
|
| 485 |
+
)""",
|
| 486 |
+
# ASCII Emoticons
|
| 487 |
+
EMOTICONS,
|
| 488 |
+
# HTML tags:
|
| 489 |
+
r"""<[^>\s]+>""",
|
| 490 |
+
# ASCII Arrows
|
| 491 |
+
r"""[\-]+>|<[\-]+""",
|
| 492 |
+
# Twitter username:
|
| 493 |
+
r"""(?:@[\w_]+)""",
|
| 494 |
+
# Twitter hashtags:
|
| 495 |
+
r"""(?:\#+[\w_]+[\w\'_\-]*[\w_]+)""",
|
| 496 |
+
# email addresses
|
| 497 |
+
r"""[\w.+-]+@[\w-]+\.(?:[\w-]\.?)+[\w-]""",
|
| 498 |
+
# docstyle-ignore
|
| 499 |
+
# Remaining word types:
|
| 500 |
+
r"""
|
| 501 |
+
(?:[^\W\d_](?:[^\W\d_]|['\-_])+[^\W\d_]) # Words with apostrophes or dashes.
|
| 502 |
+
|
|
| 503 |
+
(?:[+\-]?\d+[,/.:-]\d+[+\-]?) # Numbers, including fractions, decimals.
|
| 504 |
+
|
|
| 505 |
+
(?:[\w_]+) # Words without apostrophes or dashes.
|
| 506 |
+
|
|
| 507 |
+
(?:\.(?:\s*\.){1,}) # Ellipsis dots.
|
| 508 |
+
|
|
| 509 |
+
(?:\S) # Everything else that isn't whitespace.
|
| 510 |
+
""",
|
| 511 |
+
)
|
| 512 |
+
|
| 513 |
+
######################################################################
|
| 514 |
+
# This is the core tokenizing regex:
|
| 515 |
+
|
| 516 |
+
WORD_RE = regex.compile(r"""(%s)""" % "|".join(REGEXPS), regex.VERBOSE | regex.I | regex.UNICODE)
|
| 517 |
+
|
| 518 |
+
# WORD_RE performs poorly on these patterns:
|
| 519 |
+
HANG_RE = regex.compile(r"([^a-zA-Z0-9])\1{3,}")
|
| 520 |
+
|
| 521 |
+
# The emoticon string gets its own regex so that we can preserve case for
|
| 522 |
+
# them as needed:
|
| 523 |
+
EMOTICON_RE = regex.compile(EMOTICONS, regex.VERBOSE | regex.I | regex.UNICODE)
|
| 524 |
+
|
| 525 |
+
# These are for regularizing HTML entities to Unicode:
|
| 526 |
+
ENT_RE = regex.compile(r"&(#?(x?))([^&;\s]+);")
|
| 527 |
+
|
| 528 |
+
|
| 529 |
+
######################################################################
|
| 530 |
+
# Functions for converting html entities
|
| 531 |
+
######################################################################
|
| 532 |
+
|
| 533 |
+
|
| 534 |
+
def _str_to_unicode(text, encoding=None, errors="strict"):
|
| 535 |
+
if encoding is None:
|
| 536 |
+
encoding = "utf-8"
|
| 537 |
+
if isinstance(text, bytes):
|
| 538 |
+
return text.decode(encoding, errors)
|
| 539 |
+
return text
|
| 540 |
+
|
| 541 |
+
|
| 542 |
+
def _replace_html_entities(text, keep=(), remove_illegal=True, encoding="utf-8"):
|
| 543 |
+
"""
|
| 544 |
+
Remove entities from text by converting them to their corresponding unicode character.
|
| 545 |
+
|
| 546 |
+
Args:
|
| 547 |
+
text:
|
| 548 |
+
A unicode string or a byte string encoded in the given *encoding* (which defaults to 'utf-8').
|
| 549 |
+
keep (list):
|
| 550 |
+
List of entity names which should not be replaced. This supports both numeric entities (`&#nnnn;` and
|
| 551 |
+
`&#hhhh;`) and named entities (such as ` ` or `>`).
|
| 552 |
+
remove_illegal (bool):
|
| 553 |
+
If `True`, entities that can't be converted are removed. Otherwise, entities that can't be converted are
|
| 554 |
+
kept "as is".
|
| 555 |
+
Returns: A unicode string with the entities removed.
|
| 556 |
+
|
| 557 |
+
See https://github.com/scrapy/w3lib/blob/master/w3lib/html.py
|
| 558 |
+
|
| 559 |
+
Examples:
|
| 560 |
+
|
| 561 |
+
```python
|
| 562 |
+
>>> from nltk.tokenize.casual import _replace_html_entities
|
| 563 |
+
|
| 564 |
+
>>> _replace_html_entities(b"Price: £100")
|
| 565 |
+
'Price: \\xa3100'
|
| 566 |
+
|
| 567 |
+
>>> print(_replace_html_entities(b"Price: £100"))
|
| 568 |
+
Price: £100
|
| 569 |
+
```"""
|
| 570 |
+
|
| 571 |
+
def _convert_entity(match):
|
| 572 |
+
entity_body = match.group(3)
|
| 573 |
+
if match.group(1):
|
| 574 |
+
try:
|
| 575 |
+
if match.group(2):
|
| 576 |
+
number = int(entity_body, 16)
|
| 577 |
+
else:
|
| 578 |
+
number = int(entity_body, 10)
|
| 579 |
+
# Numeric character references in the 80-9F range are typically
|
| 580 |
+
# interpreted by browsers as representing the characters mapped
|
| 581 |
+
# to bytes 80-9F in the Windows-1252 encoding. For more info
|
| 582 |
+
# see: https://en.wikipedia.org/wiki/ISO/IEC_8859-1#Similar_character_sets
|
| 583 |
+
if 0x80 <= number <= 0x9F:
|
| 584 |
+
return bytes((number,)).decode("cp1252")
|
| 585 |
+
except ValueError:
|
| 586 |
+
number = None
|
| 587 |
+
else:
|
| 588 |
+
if entity_body in keep:
|
| 589 |
+
return match.group(0)
|
| 590 |
+
else:
|
| 591 |
+
number = html.entities.name2codepoint.get(entity_body)
|
| 592 |
+
if number is not None:
|
| 593 |
+
try:
|
| 594 |
+
return chr(number)
|
| 595 |
+
except (ValueError, OverflowError):
|
| 596 |
+
pass
|
| 597 |
+
|
| 598 |
+
return "" if remove_illegal else match.group(0)
|
| 599 |
+
|
| 600 |
+
return ENT_RE.sub(_convert_entity, _str_to_unicode(text, encoding))
|
| 601 |
+
|
| 602 |
+
|
| 603 |
+
######################################################################
|
| 604 |
+
|
| 605 |
+
|
| 606 |
+
class TweetTokenizer:
|
| 607 |
+
r"""
|
| 608 |
+
Examples:
|
| 609 |
+
|
| 610 |
+
```python
|
| 611 |
+
>>> # Tokenizer for tweets.
|
| 612 |
+
>>> from nltk.tokenize import TweetTokenizer
|
| 613 |
+
|
| 614 |
+
>>> tknzr = TweetTokenizer()
|
| 615 |
+
>>> s0 = "This is a cooool #dummysmiley: :-) :-P <3 and some arrows < > -> <--"
|
| 616 |
+
>>> tknzr.tokenize(s0)
|
| 617 |
+
['This', 'is', 'a', 'cooool', '#dummysmiley', ':', ':-)', ':-P', '<3', 'and', 'some', 'arrows', '<', '>', '->', '<--']
|
| 618 |
+
|
| 619 |
+
>>> # Examples using *strip_handles* and *reduce_len parameters*:
|
| 620 |
+
>>> tknzr = TweetTokenizer(strip_handles=True, reduce_len=True)
|
| 621 |
+
>>> s1 = "@remy: This is waaaaayyyy too much for you!!!!!!"
|
| 622 |
+
>>> tknzr.tokenize(s1)
|
| 623 |
+
[':', 'This', 'is', 'waaayyy', 'too', 'much', 'for', 'you', '!', '!', '!']
|
| 624 |
+
```"""
|
| 625 |
+
|
| 626 |
+
def __init__(self, preserve_case=True, reduce_len=False, strip_handles=False):
|
| 627 |
+
self.preserve_case = preserve_case
|
| 628 |
+
self.reduce_len = reduce_len
|
| 629 |
+
self.strip_handles = strip_handles
|
| 630 |
+
|
| 631 |
+
def tokenize(self, text):
|
| 632 |
+
"""
|
| 633 |
+
Args:
|
| 634 |
+
text: str
|
| 635 |
+
|
| 636 |
+
Returns: list(str) A tokenized list of strings; concatenating this list returns the original string if
|
| 637 |
+
`preserve_case=False`
|
| 638 |
+
"""
|
| 639 |
+
# Fix HTML character entities:
|
| 640 |
+
text = _replace_html_entities(text)
|
| 641 |
+
# Remove username handles
|
| 642 |
+
if self.strip_handles:
|
| 643 |
+
text = remove_handles(text)
|
| 644 |
+
# Normalize word lengthening
|
| 645 |
+
if self.reduce_len:
|
| 646 |
+
text = reduce_lengthening(text)
|
| 647 |
+
# Shorten problematic sequences of characters
|
| 648 |
+
safe_text = HANG_RE.sub(r"\1\1\1", text)
|
| 649 |
+
# Tokenize:
|
| 650 |
+
words = WORD_RE.findall(safe_text)
|
| 651 |
+
# Possibly alter the case, but avoid changing emoticons like :D into :d:
|
| 652 |
+
if not self.preserve_case:
|
| 653 |
+
words = [x if EMOTICON_RE.search(x) else x.lower() for x in words]
|
| 654 |
+
return words
|
| 655 |
+
|
| 656 |
+
|
| 657 |
+
######################################################################
|
| 658 |
+
# Normalization Functions
|
| 659 |
+
######################################################################
|
| 660 |
+
|
| 661 |
+
|
| 662 |
+
def reduce_lengthening(text):
|
| 663 |
+
"""
|
| 664 |
+
Replace repeated character sequences of length 3 or greater with sequences of length 3.
|
| 665 |
+
"""
|
| 666 |
+
pattern = regex.compile(r"(.)\1{2,}")
|
| 667 |
+
return pattern.sub(r"\1\1\1", text)
|
| 668 |
+
|
| 669 |
+
|
| 670 |
+
def remove_handles(text):
|
| 671 |
+
"""
|
| 672 |
+
Remove Twitter username handles from text.
|
| 673 |
+
"""
|
| 674 |
+
pattern = regex.compile(
|
| 675 |
+
r"(?<![A-Za-z0-9_!@#\$%&*])@(([A-Za-z0-9_]){20}(?!@))|(?<![A-Za-z0-9_!@#\$%&*])@(([A-Za-z0-9_]){1,19})(?![A-Za-z0-9_]*@)"
|
| 676 |
+
)
|
| 677 |
+
# Substitute handles with ' ' to ensure that text on either side of removed handles are tokenized correctly
|
| 678 |
+
return pattern.sub(" ", text)
|
| 679 |
+
|
| 680 |
+
|
| 681 |
+
######################################################################
|
| 682 |
+
# Tokenization Function
|
| 683 |
+
######################################################################
|
| 684 |
+
|
| 685 |
+
|
| 686 |
+
def casual_tokenize(text, preserve_case=True, reduce_len=False, strip_handles=False):
|
| 687 |
+
"""
|
| 688 |
+
Convenience function for wrapping the tokenizer.
|
| 689 |
+
"""
|
| 690 |
+
return TweetTokenizer(preserve_case=preserve_case, reduce_len=reduce_len, strip_handles=strip_handles).tokenize(
|
| 691 |
+
text
|
| 692 |
+
)
|
| 693 |
+
|
| 694 |
+
|
| 695 |
+
###############################################################################
|
| 696 |
+
|
| 697 |
+
|
| 698 |
+
__all__ = ["BertweetTokenizer"]
|
third_party/transformers/src/transformers/models/biogpt/__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_biogpt import *
|
| 22 |
+
from .modeling_biogpt import *
|
| 23 |
+
from .tokenization_biogpt 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/biogpt/configuration_biogpt.py
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright 2022 The HuggingFace Team and Microsoft Research AI4Science 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 |
+
"""BioGPT 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="microsoft/biogpt")
|
| 23 |
+
@strict
|
| 24 |
+
class BioGptConfig(PreTrainedConfig):
|
| 25 |
+
r"""
|
| 26 |
+
Example:
|
| 27 |
+
|
| 28 |
+
```python
|
| 29 |
+
>>> from transformers import BioGptModel, BioGptConfig
|
| 30 |
+
|
| 31 |
+
>>> # Initializing a BioGPT microsoft/biogpt style configuration
|
| 32 |
+
>>> configuration = BioGptConfig()
|
| 33 |
+
|
| 34 |
+
>>> # Initializing a model from the microsoft/biogpt style configuration
|
| 35 |
+
>>> model = BioGptModel(configuration)
|
| 36 |
+
|
| 37 |
+
>>> # Accessing the model configuration
|
| 38 |
+
>>> configuration = model.config
|
| 39 |
+
```"""
|
| 40 |
+
|
| 41 |
+
model_type = "biogpt"
|
| 42 |
+
|
| 43 |
+
vocab_size: int = 42384
|
| 44 |
+
hidden_size: int = 1024
|
| 45 |
+
num_hidden_layers: int = 24
|
| 46 |
+
num_attention_heads: int = 16
|
| 47 |
+
intermediate_size: int = 4096
|
| 48 |
+
hidden_act: str = "gelu"
|
| 49 |
+
hidden_dropout_prob: float | int = 0.1
|
| 50 |
+
attention_probs_dropout_prob: float | int = 0.1
|
| 51 |
+
max_position_embeddings: int = 1024
|
| 52 |
+
initializer_range: float = 0.02
|
| 53 |
+
layer_norm_eps: float = 1e-12
|
| 54 |
+
scale_embedding: bool = True
|
| 55 |
+
use_cache: bool = True
|
| 56 |
+
layerdrop: float | int = 0.0
|
| 57 |
+
activation_dropout: float | int = 0.0
|
| 58 |
+
pad_token_id: int | None = 1
|
| 59 |
+
bos_token_id: int | None = 0
|
| 60 |
+
eos_token_id: int | list[int] | None = 2
|
| 61 |
+
tie_word_embeddings: bool = True
|
| 62 |
+
|
| 63 |
+
|
| 64 |
+
__all__ = ["BioGptConfig"]
|
third_party/transformers/src/transformers/models/biogpt/convert_biogpt_original_pytorch_checkpoint_to_pytorch.py
ADDED
|
@@ -0,0 +1,291 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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 |
+
|
| 16 |
+
import argparse
|
| 17 |
+
import json
|
| 18 |
+
import os
|
| 19 |
+
import re
|
| 20 |
+
import shutil
|
| 21 |
+
|
| 22 |
+
import torch
|
| 23 |
+
|
| 24 |
+
from transformers import BioGptConfig, BioGptForCausalLM
|
| 25 |
+
from transformers.models.biogpt.tokenization_biogpt import VOCAB_FILES_NAMES
|
| 26 |
+
from transformers.tokenization_utils_base import TOKENIZER_CONFIG_FILE
|
| 27 |
+
from transformers.utils import WEIGHTS_NAME, logging
|
| 28 |
+
|
| 29 |
+
|
| 30 |
+
logging.set_verbosity_warning()
|
| 31 |
+
|
| 32 |
+
json_indent = 2
|
| 33 |
+
|
| 34 |
+
|
| 35 |
+
# modified from https://github.com/facebookresearch/fairseq/blob/dd74992d0d143155998e9ed4076826bcea80fb06/fairseq/data/dictionary.py#L18
|
| 36 |
+
class Dictionary:
|
| 37 |
+
"""A mapping from symbols to consecutive integers"""
|
| 38 |
+
|
| 39 |
+
def __init__(
|
| 40 |
+
self,
|
| 41 |
+
*, # begin keyword-only arguments
|
| 42 |
+
bos="<s>",
|
| 43 |
+
pad="<pad>",
|
| 44 |
+
eos="</s>",
|
| 45 |
+
unk="<unk>",
|
| 46 |
+
extra_special_symbols=None,
|
| 47 |
+
):
|
| 48 |
+
self.bos_word, self.unk_word, self.pad_word, self.eos_word = bos, unk, pad, eos
|
| 49 |
+
self.symbols = []
|
| 50 |
+
self.count = []
|
| 51 |
+
self.indices = {}
|
| 52 |
+
self.bos_index = self.add_symbol(bos)
|
| 53 |
+
self.pad_index = self.add_symbol(pad)
|
| 54 |
+
self.eos_index = self.add_symbol(eos)
|
| 55 |
+
self.unk_index = self.add_symbol(unk)
|
| 56 |
+
if extra_special_symbols:
|
| 57 |
+
for s in extra_special_symbols:
|
| 58 |
+
self.add_symbol(s)
|
| 59 |
+
self.nspecial = len(self.symbols)
|
| 60 |
+
|
| 61 |
+
def __eq__(self, other):
|
| 62 |
+
return self.indices == other.indices
|
| 63 |
+
|
| 64 |
+
def __getitem__(self, idx):
|
| 65 |
+
if idx < len(self.symbols):
|
| 66 |
+
return self.symbols[idx]
|
| 67 |
+
return self.unk_word
|
| 68 |
+
|
| 69 |
+
def __len__(self):
|
| 70 |
+
"""Returns the number of symbols in the dictionary"""
|
| 71 |
+
return len(self.symbols)
|
| 72 |
+
|
| 73 |
+
def __contains__(self, sym):
|
| 74 |
+
return sym in self.indices
|
| 75 |
+
|
| 76 |
+
@classmethod
|
| 77 |
+
def load(cls, f):
|
| 78 |
+
"""Loads the dictionary from a text file with the format:
|
| 79 |
+
|
| 80 |
+
```
|
| 81 |
+
<symbol0> <count0>
|
| 82 |
+
<symbol1> <count1>
|
| 83 |
+
...
|
| 84 |
+
```
|
| 85 |
+
"""
|
| 86 |
+
d = cls()
|
| 87 |
+
d.add_from_file(f)
|
| 88 |
+
return d
|
| 89 |
+
|
| 90 |
+
def add_symbol(self, word, n=1, overwrite=False):
|
| 91 |
+
"""Adds a word to the dictionary"""
|
| 92 |
+
if word in self.indices and not overwrite:
|
| 93 |
+
idx = self.indices[word]
|
| 94 |
+
self.count[idx] = self.count[idx] + n
|
| 95 |
+
return idx
|
| 96 |
+
else:
|
| 97 |
+
idx = len(self.symbols)
|
| 98 |
+
self.indices[word] = idx
|
| 99 |
+
self.symbols.append(word)
|
| 100 |
+
self.count.append(n)
|
| 101 |
+
return idx
|
| 102 |
+
|
| 103 |
+
def _load_meta(self, lines):
|
| 104 |
+
return 0
|
| 105 |
+
|
| 106 |
+
def add_from_file(self, f):
|
| 107 |
+
"""
|
| 108 |
+
Loads a pre-existing dictionary from a text file and adds its symbols to this instance.
|
| 109 |
+
"""
|
| 110 |
+
if isinstance(f, str):
|
| 111 |
+
try:
|
| 112 |
+
with open(f, "r", encoding="utf-8") as fd:
|
| 113 |
+
self.add_from_file(fd)
|
| 114 |
+
except FileNotFoundError as fnfe:
|
| 115 |
+
raise fnfe
|
| 116 |
+
except UnicodeError:
|
| 117 |
+
raise Exception(f"Incorrect encoding detected in {f}, please rebuild the dataset")
|
| 118 |
+
return
|
| 119 |
+
|
| 120 |
+
lines = f.readlines()
|
| 121 |
+
indices_start_line = self._load_meta(lines)
|
| 122 |
+
|
| 123 |
+
for line in lines[indices_start_line:]:
|
| 124 |
+
try:
|
| 125 |
+
line, field = line.rstrip().rsplit(" ", 1)
|
| 126 |
+
if field == "#fairseq:overwrite":
|
| 127 |
+
overwrite = True
|
| 128 |
+
line, field = line.rsplit(" ", 1)
|
| 129 |
+
else:
|
| 130 |
+
overwrite = False
|
| 131 |
+
count = int(field)
|
| 132 |
+
word = line
|
| 133 |
+
if word in self and not overwrite:
|
| 134 |
+
raise RuntimeError(
|
| 135 |
+
f"Duplicate word found when loading Dictionary: '{word}'. "
|
| 136 |
+
"Duplicate words can overwrite earlier ones by adding the "
|
| 137 |
+
"#fairseq:overwrite flag at the end of the corresponding row "
|
| 138 |
+
"in the dictionary file. If using the Camembert model, please "
|
| 139 |
+
"download an updated copy of the model file."
|
| 140 |
+
)
|
| 141 |
+
self.add_symbol(word, n=count, overwrite=overwrite)
|
| 142 |
+
except ValueError:
|
| 143 |
+
raise ValueError("Incorrect dictionary format, expected '<token> <cnt> [flags]'")
|
| 144 |
+
|
| 145 |
+
|
| 146 |
+
def rewrite_dict_keys(d):
|
| 147 |
+
# (1) remove word breaking symbol, (2) add word ending symbol where the word is not broken up,
|
| 148 |
+
# e.g.: d = {'le@@': 5, 'tt@@': 6, 'er': 7} => {'le': 5, 'tt': 6, 'er</w>': 7}
|
| 149 |
+
d2 = dict((re.sub(r"@@$", "", k), v) if k.endswith("@@") else (re.sub(r"$", "</w>", k), v) for k, v in d.items())
|
| 150 |
+
keep_keys = ["<s>", "<pad>", "</s>", "<unk>"]
|
| 151 |
+
# restore the special tokens
|
| 152 |
+
for k in keep_keys:
|
| 153 |
+
del d2[f"{k}</w>"]
|
| 154 |
+
d2[k] = d[k] # restore
|
| 155 |
+
return d2
|
| 156 |
+
|
| 157 |
+
|
| 158 |
+
def convert_biogpt_checkpoint_to_pytorch(biogpt_checkpoint_path, pytorch_dump_folder_path):
|
| 159 |
+
# prep
|
| 160 |
+
if not os.path.exists(biogpt_checkpoint_path):
|
| 161 |
+
raise ValueError(f"path {biogpt_checkpoint_path} does not exist!")
|
| 162 |
+
os.makedirs(pytorch_dump_folder_path, exist_ok=True)
|
| 163 |
+
print(f"Writing results to {pytorch_dump_folder_path}")
|
| 164 |
+
|
| 165 |
+
# handle various types of models
|
| 166 |
+
|
| 167 |
+
checkpoint_file = os.path.join(biogpt_checkpoint_path, "checkpoint.pt")
|
| 168 |
+
if not os.path.isfile(checkpoint_file):
|
| 169 |
+
raise ValueError(f"path to the file {checkpoint_file} does not exist!")
|
| 170 |
+
chkpt = torch.load(checkpoint_file, map_location="cpu", weights_only=True)
|
| 171 |
+
|
| 172 |
+
args = chkpt["cfg"]["model"]
|
| 173 |
+
|
| 174 |
+
# dicts
|
| 175 |
+
dict_file = os.path.join(biogpt_checkpoint_path, "dict.txt")
|
| 176 |
+
if not os.path.isfile(dict_file):
|
| 177 |
+
raise ValueError(f"path to the file {dict_file} does not exist!")
|
| 178 |
+
src_dict = Dictionary.load(dict_file)
|
| 179 |
+
src_vocab = rewrite_dict_keys(src_dict.indices)
|
| 180 |
+
src_vocab_size = len(src_vocab)
|
| 181 |
+
src_vocab_file = os.path.join(pytorch_dump_folder_path, VOCAB_FILES_NAMES["vocab_file"])
|
| 182 |
+
print(f"Generating {src_vocab_file} of {src_vocab_size} records")
|
| 183 |
+
with open(src_vocab_file, "w", encoding="utf-8") as f:
|
| 184 |
+
f.write(json.dumps(src_vocab, ensure_ascii=False, indent=json_indent))
|
| 185 |
+
|
| 186 |
+
# merges_file (bpecodes)
|
| 187 |
+
bpecodes_file = os.path.join(biogpt_checkpoint_path, "bpecodes")
|
| 188 |
+
if not os.path.isfile(bpecodes_file):
|
| 189 |
+
raise ValueError(f"path to the file {bpecodes_file} does not exist!")
|
| 190 |
+
|
| 191 |
+
merges_file = os.path.join(pytorch_dump_folder_path, VOCAB_FILES_NAMES["merges_file"])
|
| 192 |
+
shutil.copyfile(bpecodes_file, merges_file)
|
| 193 |
+
|
| 194 |
+
# model config
|
| 195 |
+
biogpt_model_config_file = os.path.join(pytorch_dump_folder_path, "config.json")
|
| 196 |
+
|
| 197 |
+
model_conf = {
|
| 198 |
+
"activation_dropout": args["activation_dropout"],
|
| 199 |
+
"architectures": ["BioGptForCausalLM"],
|
| 200 |
+
"attention_probs_dropout_prob": args["attention_dropout"],
|
| 201 |
+
"bos_token_id": 0,
|
| 202 |
+
"eos_token_id": 2,
|
| 203 |
+
"hidden_act": args["activation_fn"],
|
| 204 |
+
"hidden_dropout_prob": args["dropout"],
|
| 205 |
+
"hidden_size": args["decoder_embed_dim"],
|
| 206 |
+
"initializer_range": 0.02,
|
| 207 |
+
"intermediate_size": args["decoder_ffn_embed_dim"],
|
| 208 |
+
"layer_norm_eps": 1e-12,
|
| 209 |
+
"layerdrop": args["decoder_layerdrop"],
|
| 210 |
+
"max_position_embeddings": args["max_target_positions"],
|
| 211 |
+
"model_type": "biogpt",
|
| 212 |
+
"num_attention_heads": args["decoder_attention_heads"],
|
| 213 |
+
"num_hidden_layers": args["decoder_layers"],
|
| 214 |
+
"pad_token_id": 1,
|
| 215 |
+
"scale_embedding": not args["no_scale_embedding"],
|
| 216 |
+
"tie_word_embeddings": args["share_decoder_input_output_embed"],
|
| 217 |
+
"vocab_size": src_vocab_size,
|
| 218 |
+
}
|
| 219 |
+
|
| 220 |
+
# good hparam defaults to start with
|
| 221 |
+
|
| 222 |
+
print(f"Generating {biogpt_model_config_file}")
|
| 223 |
+
with open(biogpt_model_config_file, "w", encoding="utf-8") as f:
|
| 224 |
+
f.write(json.dumps(model_conf, ensure_ascii=False, indent=json_indent))
|
| 225 |
+
|
| 226 |
+
# tokenizer config
|
| 227 |
+
biogpt_tokenizer_config_file = os.path.join(pytorch_dump_folder_path, TOKENIZER_CONFIG_FILE)
|
| 228 |
+
|
| 229 |
+
tokenizer_conf = {
|
| 230 |
+
"bos_token": "<s>",
|
| 231 |
+
"eos_token": "</s>",
|
| 232 |
+
"model_max_length": 1024,
|
| 233 |
+
"pad_token": "<pad>",
|
| 234 |
+
"special_tokens_map_file": None,
|
| 235 |
+
"tokenizer_class": "BioGptTokenizer",
|
| 236 |
+
"unk_token": "<unk>",
|
| 237 |
+
}
|
| 238 |
+
|
| 239 |
+
print(f"Generating {biogpt_tokenizer_config_file}")
|
| 240 |
+
with open(biogpt_tokenizer_config_file, "w", encoding="utf-8") as f:
|
| 241 |
+
f.write(json.dumps(tokenizer_conf, ensure_ascii=False, indent=json_indent))
|
| 242 |
+
|
| 243 |
+
# model
|
| 244 |
+
model_state_dict = chkpt["model"]
|
| 245 |
+
|
| 246 |
+
# remove unneeded keys
|
| 247 |
+
ignore_keys = [
|
| 248 |
+
"decoder.version",
|
| 249 |
+
]
|
| 250 |
+
for k in ignore_keys:
|
| 251 |
+
model_state_dict.pop(k, None)
|
| 252 |
+
|
| 253 |
+
layer_names = list(model_state_dict.keys())
|
| 254 |
+
for layer_name in layer_names:
|
| 255 |
+
if layer_name.endswith("output_projection.weight"):
|
| 256 |
+
model_state_dict[layer_name.replace("decoder.", "")] = model_state_dict.pop(layer_name)
|
| 257 |
+
else:
|
| 258 |
+
model_state_dict[layer_name.replace("decoder", "biogpt")] = model_state_dict.pop(layer_name)
|
| 259 |
+
|
| 260 |
+
config = BioGptConfig.from_pretrained(pytorch_dump_folder_path)
|
| 261 |
+
model_new = BioGptForCausalLM(config)
|
| 262 |
+
|
| 263 |
+
# check that it loads ok
|
| 264 |
+
model_new.load_state_dict(model_state_dict)
|
| 265 |
+
|
| 266 |
+
# save
|
| 267 |
+
pytorch_weights_dump_path = os.path.join(pytorch_dump_folder_path, WEIGHTS_NAME)
|
| 268 |
+
print(f"Generating {pytorch_weights_dump_path}")
|
| 269 |
+
torch.save(model_state_dict, pytorch_weights_dump_path)
|
| 270 |
+
|
| 271 |
+
print("Conversion is done!")
|
| 272 |
+
|
| 273 |
+
|
| 274 |
+
if __name__ == "__main__":
|
| 275 |
+
parser = argparse.ArgumentParser()
|
| 276 |
+
# Required parameters
|
| 277 |
+
parser.add_argument(
|
| 278 |
+
"--biogpt_checkpoint_path",
|
| 279 |
+
default=None,
|
| 280 |
+
type=str,
|
| 281 |
+
required=True,
|
| 282 |
+
help=(
|
| 283 |
+
"Path to the official PyTorch checkpoint file which is expected to reside in the dump dir with dicts,"
|
| 284 |
+
" bpecodes, etc."
|
| 285 |
+
),
|
| 286 |
+
)
|
| 287 |
+
parser.add_argument(
|
| 288 |
+
"--pytorch_dump_folder_path", default=None, type=str, required=True, help="Path to the output PyTorch model."
|
| 289 |
+
)
|
| 290 |
+
args = parser.parse_args()
|
| 291 |
+
convert_biogpt_checkpoint_to_pytorch(args.biogpt_checkpoint_path, args.pytorch_dump_folder_path)
|
third_party/transformers/src/transformers/models/biogpt/modeling_biogpt.py
ADDED
|
@@ -0,0 +1,678 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨
|
| 2 |
+
# This file was automatically generated from src/transformers/models/biogpt/modular_biogpt.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_biogpt.py file directly. One of our CI enforces this.
|
| 6 |
+
# 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨
|
| 7 |
+
# Copyright 2022 The HuggingFace Team and Microsoft Research AI4Science 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 |
+
import math
|
| 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 ...activations import ACT2FN
|
| 29 |
+
from ...cache_utils import Cache, DynamicCache, EncoderDecoderCache
|
| 30 |
+
from ...generation import GenerationMixin
|
| 31 |
+
from ...masking_utils import create_causal_mask
|
| 32 |
+
from ...modeling_flash_attention_utils import FlashAttentionKwargs
|
| 33 |
+
from ...modeling_layers import GradientCheckpointingLayer
|
| 34 |
+
from ...modeling_outputs import (
|
| 35 |
+
BaseModelOutputWithPastAndCrossAttentions,
|
| 36 |
+
CausalLMOutputWithCrossAttentions,
|
| 37 |
+
SequenceClassifierOutputWithPast,
|
| 38 |
+
TokenClassifierOutput,
|
| 39 |
+
)
|
| 40 |
+
from ...modeling_utils import ALL_ATTENTION_FUNCTIONS, PreTrainedModel
|
| 41 |
+
from ...processing_utils import Unpack
|
| 42 |
+
from ...utils import TransformersKwargs, auto_docstring, can_return_tuple, logging
|
| 43 |
+
from ...utils.generic import merge_with_config_defaults
|
| 44 |
+
from ...utils.output_capturing import capture_outputs
|
| 45 |
+
from .configuration_biogpt import BioGptConfig
|
| 46 |
+
|
| 47 |
+
|
| 48 |
+
logger = logging.get_logger(__name__)
|
| 49 |
+
|
| 50 |
+
|
| 51 |
+
class BioGptLearnedPositionalEmbedding(nn.Embedding):
|
| 52 |
+
"""
|
| 53 |
+
This module learns positional embeddings up to a fixed maximum size.
|
| 54 |
+
"""
|
| 55 |
+
|
| 56 |
+
def __init__(self, num_embeddings: int, embedding_dim: int):
|
| 57 |
+
# BIOGPT is set up so that if padding_idx is specified then offset the embedding ids by 2
|
| 58 |
+
# and adjust num_embeddings appropriately. Other models don't have this hack
|
| 59 |
+
self.offset = 2
|
| 60 |
+
super().__init__(num_embeddings + self.offset, embedding_dim)
|
| 61 |
+
|
| 62 |
+
def forward(
|
| 63 |
+
self,
|
| 64 |
+
attention_mask: torch.LongTensor,
|
| 65 |
+
past_key_values_length: int = 0,
|
| 66 |
+
position_ids: torch.LongTensor | None = None,
|
| 67 |
+
):
|
| 68 |
+
"""`input_ids_shape` is expected to be [bsz x seqlen]."""
|
| 69 |
+
|
| 70 |
+
if position_ids is None:
|
| 71 |
+
position_ids = torch.cumsum(attention_mask, dim=1)
|
| 72 |
+
position_ids = (position_ids * attention_mask - 1).long()
|
| 73 |
+
# cut positions if `past_key_values_length` is > 0
|
| 74 |
+
position_ids = position_ids[:, past_key_values_length:]
|
| 75 |
+
|
| 76 |
+
return super().forward(position_ids + self.offset)
|
| 77 |
+
|
| 78 |
+
|
| 79 |
+
class BioGptScaledWordEmbedding(nn.Embedding):
|
| 80 |
+
"""
|
| 81 |
+
This module overrides nn.Embeddings' forward by multiplying with embeddings scale.
|
| 82 |
+
"""
|
| 83 |
+
|
| 84 |
+
def __init__(self, num_embeddings: int, embedding_dim: int, padding_idx: int, embed_scale: float | None = 1.0):
|
| 85 |
+
super().__init__(num_embeddings, embedding_dim, padding_idx)
|
| 86 |
+
self.embed_scale = embed_scale
|
| 87 |
+
|
| 88 |
+
def forward(self, input_ids: torch.Tensor):
|
| 89 |
+
return super().forward(input_ids) * self.embed_scale
|
| 90 |
+
|
| 91 |
+
|
| 92 |
+
def eager_attention_forward(
|
| 93 |
+
module: nn.Module,
|
| 94 |
+
query: torch.Tensor,
|
| 95 |
+
key: torch.Tensor,
|
| 96 |
+
value: torch.Tensor,
|
| 97 |
+
attention_mask: torch.Tensor | None,
|
| 98 |
+
scaling: float | None = None,
|
| 99 |
+
dropout: float = 0.0,
|
| 100 |
+
**kwargs: Unpack[TransformersKwargs],
|
| 101 |
+
):
|
| 102 |
+
if scaling is None:
|
| 103 |
+
scaling = query.size(-1) ** -0.5
|
| 104 |
+
|
| 105 |
+
# Take the dot product between "query" and "key" to get the raw attention scores.
|
| 106 |
+
attn_weights = torch.matmul(query, key.transpose(2, 3)) * scaling
|
| 107 |
+
|
| 108 |
+
if attention_mask is not None:
|
| 109 |
+
attn_weights = attn_weights + attention_mask
|
| 110 |
+
|
| 111 |
+
attn_weights = nn.functional.softmax(attn_weights, dim=-1)
|
| 112 |
+
attn_weights = nn.functional.dropout(attn_weights, p=dropout, training=module.training)
|
| 113 |
+
|
| 114 |
+
attn_output = torch.matmul(attn_weights, value)
|
| 115 |
+
attn_output = attn_output.transpose(1, 2).contiguous()
|
| 116 |
+
|
| 117 |
+
return attn_output, attn_weights
|
| 118 |
+
|
| 119 |
+
|
| 120 |
+
class BioGptAttention(nn.Module):
|
| 121 |
+
"""Multi-headed attention from 'Attention Is All You Need' paper"""
|
| 122 |
+
|
| 123 |
+
def __init__(
|
| 124 |
+
self,
|
| 125 |
+
embed_dim: int,
|
| 126 |
+
num_heads: int,
|
| 127 |
+
dropout: float = 0.0,
|
| 128 |
+
is_decoder: bool = False,
|
| 129 |
+
bias: bool = True,
|
| 130 |
+
is_causal: bool = False,
|
| 131 |
+
config: BioGptConfig | None = None,
|
| 132 |
+
layer_idx: int | None = None,
|
| 133 |
+
):
|
| 134 |
+
super().__init__()
|
| 135 |
+
self.embed_dim = embed_dim
|
| 136 |
+
self.num_heads = num_heads
|
| 137 |
+
self.dropout = dropout
|
| 138 |
+
self.head_dim = embed_dim // num_heads
|
| 139 |
+
self.config = config
|
| 140 |
+
|
| 141 |
+
if (self.head_dim * num_heads) != self.embed_dim:
|
| 142 |
+
raise ValueError(
|
| 143 |
+
f"embed_dim must be divisible by num_heads (got `embed_dim`: {self.embed_dim}"
|
| 144 |
+
f" and `num_heads`: {num_heads})."
|
| 145 |
+
)
|
| 146 |
+
self.scaling = self.head_dim**-0.5
|
| 147 |
+
self.is_decoder = is_decoder
|
| 148 |
+
self.is_causal = is_causal
|
| 149 |
+
self.layer_idx = layer_idx
|
| 150 |
+
if layer_idx is None and self.is_decoder:
|
| 151 |
+
logger.warning_once(
|
| 152 |
+
f"Instantiating a decoder {self.__class__.__name__} without passing `layer_idx` is not recommended and "
|
| 153 |
+
"will lead to errors during the forward call, if caching is used. Please make sure to provide a `layer_idx` "
|
| 154 |
+
"when creating this class."
|
| 155 |
+
)
|
| 156 |
+
|
| 157 |
+
self.k_proj = nn.Linear(embed_dim, embed_dim, bias=bias)
|
| 158 |
+
self.v_proj = nn.Linear(embed_dim, embed_dim, bias=bias)
|
| 159 |
+
self.q_proj = nn.Linear(embed_dim, embed_dim, bias=bias)
|
| 160 |
+
self.out_proj = nn.Linear(embed_dim, embed_dim, bias=bias)
|
| 161 |
+
|
| 162 |
+
def forward(
|
| 163 |
+
self,
|
| 164 |
+
hidden_states: torch.Tensor,
|
| 165 |
+
key_value_states: torch.Tensor | None = None,
|
| 166 |
+
past_key_values: Cache | None = None,
|
| 167 |
+
attention_mask: torch.Tensor | None = None,
|
| 168 |
+
# TODO: we need a refactor so that the different attention modules can get their specific kwargs
|
| 169 |
+
# ATM, we have mixed things encoder, decoder, and encoder-decoder attn
|
| 170 |
+
**kwargs: Unpack[FlashAttentionKwargs],
|
| 171 |
+
) -> tuple[torch.Tensor, torch.Tensor | None]:
|
| 172 |
+
"""Input shape: Batch x Time x Channel"""
|
| 173 |
+
|
| 174 |
+
# if key_value_states are provided this layer is used as a cross-attention layer
|
| 175 |
+
# for the decoder
|
| 176 |
+
is_cross_attention = key_value_states is not None
|
| 177 |
+
|
| 178 |
+
# determine input shapes
|
| 179 |
+
bsz, tgt_len = hidden_states.shape[:-1]
|
| 180 |
+
src_len = key_value_states.shape[1] if is_cross_attention else tgt_len
|
| 181 |
+
|
| 182 |
+
q_input_shape = (bsz, tgt_len, -1, self.head_dim)
|
| 183 |
+
kv_input_shape = (bsz, src_len, -1, self.head_dim)
|
| 184 |
+
|
| 185 |
+
# get query proj
|
| 186 |
+
query_states = self.q_proj(hidden_states).view(*q_input_shape).transpose(1, 2)
|
| 187 |
+
|
| 188 |
+
is_updated = False
|
| 189 |
+
if past_key_values is not None:
|
| 190 |
+
if isinstance(past_key_values, EncoderDecoderCache):
|
| 191 |
+
is_updated = past_key_values.is_updated.get(self.layer_idx)
|
| 192 |
+
if is_cross_attention:
|
| 193 |
+
# after the first generated id, we can subsequently re-use all key/value_states from cache
|
| 194 |
+
curr_past_key_values = past_key_values.cross_attention_cache
|
| 195 |
+
else:
|
| 196 |
+
curr_past_key_values = past_key_values.self_attention_cache
|
| 197 |
+
else:
|
| 198 |
+
curr_past_key_values = past_key_values
|
| 199 |
+
|
| 200 |
+
current_states = key_value_states if is_cross_attention else hidden_states
|
| 201 |
+
if is_cross_attention and past_key_values is not None and is_updated:
|
| 202 |
+
# reuse k,v, cross_attentions
|
| 203 |
+
key_states = curr_past_key_values.layers[self.layer_idx].keys
|
| 204 |
+
value_states = curr_past_key_values.layers[self.layer_idx].values
|
| 205 |
+
else:
|
| 206 |
+
key_states = self.k_proj(current_states)
|
| 207 |
+
value_states = self.v_proj(current_states)
|
| 208 |
+
key_states = key_states.view(*kv_input_shape).transpose(1, 2)
|
| 209 |
+
value_states = value_states.view(*kv_input_shape).transpose(1, 2)
|
| 210 |
+
|
| 211 |
+
if past_key_values is not None:
|
| 212 |
+
key_states, value_states = curr_past_key_values.update(key_states, value_states, self.layer_idx)
|
| 213 |
+
# set flag that curr layer for cross-attn is already updated so we can re-use in subsequent calls
|
| 214 |
+
if is_cross_attention and isinstance(past_key_values, EncoderDecoderCache):
|
| 215 |
+
past_key_values.is_updated[self.layer_idx] = True
|
| 216 |
+
|
| 217 |
+
attention_interface: Callable = ALL_ATTENTION_FUNCTIONS.get_interface(
|
| 218 |
+
self.config._attn_implementation, eager_attention_forward
|
| 219 |
+
)
|
| 220 |
+
|
| 221 |
+
attn_output, attn_weights = attention_interface(
|
| 222 |
+
self,
|
| 223 |
+
query_states,
|
| 224 |
+
key_states,
|
| 225 |
+
value_states,
|
| 226 |
+
attention_mask,
|
| 227 |
+
dropout=0.0 if not self.training else self.dropout,
|
| 228 |
+
scaling=self.scaling,
|
| 229 |
+
**kwargs,
|
| 230 |
+
)
|
| 231 |
+
|
| 232 |
+
attn_output = attn_output.reshape(bsz, tgt_len, -1).contiguous()
|
| 233 |
+
attn_output = self.out_proj(attn_output)
|
| 234 |
+
|
| 235 |
+
return attn_output, attn_weights
|
| 236 |
+
|
| 237 |
+
|
| 238 |
+
class BioGptDecoderLayer(GradientCheckpointingLayer):
|
| 239 |
+
def __init__(self, config: BioGptConfig, layer_idx: int | None = None):
|
| 240 |
+
super().__init__()
|
| 241 |
+
self.embed_dim = config.hidden_size
|
| 242 |
+
|
| 243 |
+
self.self_attn = BioGptAttention(
|
| 244 |
+
embed_dim=self.embed_dim,
|
| 245 |
+
num_heads=config.num_attention_heads,
|
| 246 |
+
dropout=config.attention_probs_dropout_prob,
|
| 247 |
+
is_decoder=True,
|
| 248 |
+
is_causal=True,
|
| 249 |
+
config=config,
|
| 250 |
+
layer_idx=layer_idx,
|
| 251 |
+
)
|
| 252 |
+
self.dropout = config.hidden_dropout_prob
|
| 253 |
+
self.activation_fn = ACT2FN[config.hidden_act]
|
| 254 |
+
self.activation_dropout = config.activation_dropout
|
| 255 |
+
|
| 256 |
+
self.self_attn_layer_norm = nn.LayerNorm(self.embed_dim)
|
| 257 |
+
|
| 258 |
+
self.fc1 = nn.Linear(self.embed_dim, config.intermediate_size)
|
| 259 |
+
self.fc2 = nn.Linear(config.intermediate_size, self.embed_dim)
|
| 260 |
+
self.final_layer_norm = nn.LayerNorm(self.embed_dim)
|
| 261 |
+
|
| 262 |
+
def forward(
|
| 263 |
+
self,
|
| 264 |
+
hidden_states: torch.Tensor,
|
| 265 |
+
attention_mask: torch.Tensor | None = None,
|
| 266 |
+
past_key_values: Cache | None = None,
|
| 267 |
+
use_cache: bool | None = True,
|
| 268 |
+
position_ids: torch.LongTensor | None = None,
|
| 269 |
+
**kwargs: Unpack[TransformersKwargs],
|
| 270 |
+
) -> torch.Tensor:
|
| 271 |
+
"""
|
| 272 |
+
Args:
|
| 273 |
+
hidden_states (`torch.FloatTensor`): input to the layer of shape `(batch, seq_len, embed_dim)`
|
| 274 |
+
attention_mask (`torch.FloatTensor`): attention mask of size
|
| 275 |
+
`(batch, 1, tgt_len, src_len)` where padding elements are indicated by very large negative values.
|
| 276 |
+
past_key_values (`Cache`): cached past key and value projection states
|
| 277 |
+
"""
|
| 278 |
+
residual = hidden_states
|
| 279 |
+
|
| 280 |
+
hidden_states = self.self_attn_layer_norm(hidden_states)
|
| 281 |
+
|
| 282 |
+
# Self Attention
|
| 283 |
+
hidden_states, _ = self.self_attn(
|
| 284 |
+
hidden_states=hidden_states,
|
| 285 |
+
past_key_values=past_key_values,
|
| 286 |
+
attention_mask=attention_mask,
|
| 287 |
+
position_ids=position_ids,
|
| 288 |
+
**kwargs,
|
| 289 |
+
)
|
| 290 |
+
hidden_states = nn.functional.dropout(hidden_states, p=self.dropout, training=self.training)
|
| 291 |
+
hidden_states = residual + hidden_states
|
| 292 |
+
|
| 293 |
+
# Fully Connected
|
| 294 |
+
residual = hidden_states
|
| 295 |
+
hidden_states = self.final_layer_norm(hidden_states)
|
| 296 |
+
hidden_states = self.fc1(hidden_states)
|
| 297 |
+
hidden_states = self.activation_fn(hidden_states)
|
| 298 |
+
hidden_states = nn.functional.dropout(hidden_states, p=self.activation_dropout, training=self.training)
|
| 299 |
+
hidden_states = self.fc2(hidden_states)
|
| 300 |
+
hidden_states = nn.functional.dropout(hidden_states, p=self.dropout, training=self.training)
|
| 301 |
+
hidden_states = residual + hidden_states
|
| 302 |
+
|
| 303 |
+
return hidden_states
|
| 304 |
+
|
| 305 |
+
|
| 306 |
+
@auto_docstring
|
| 307 |
+
class BioGptPreTrainedModel(PreTrainedModel):
|
| 308 |
+
config: BioGptConfig
|
| 309 |
+
base_model_prefix = "biogpt"
|
| 310 |
+
supports_gradient_checkpointing = True
|
| 311 |
+
_supports_flash_attn = True
|
| 312 |
+
_supports_sdpa = True
|
| 313 |
+
_supports_flex_attn = True
|
| 314 |
+
_can_compile_fullgraph = True
|
| 315 |
+
_can_record_outputs = {
|
| 316 |
+
"hidden_states": BioGptDecoderLayer,
|
| 317 |
+
"attentions": BioGptAttention,
|
| 318 |
+
}
|
| 319 |
+
|
| 320 |
+
|
| 321 |
+
@auto_docstring
|
| 322 |
+
class BioGptModel(BioGptPreTrainedModel):
|
| 323 |
+
def __init__(self, config: BioGptConfig):
|
| 324 |
+
super().__init__(config)
|
| 325 |
+
self.config = config
|
| 326 |
+
self.layerdrop = config.layerdrop
|
| 327 |
+
self.dropout = config.hidden_dropout_prob
|
| 328 |
+
self.embed_dim = config.hidden_size
|
| 329 |
+
self.padding_idx = config.pad_token_id
|
| 330 |
+
embed_scale = math.sqrt(config.hidden_size) if config.scale_embedding else 1.0
|
| 331 |
+
|
| 332 |
+
self.embed_tokens = BioGptScaledWordEmbedding(
|
| 333 |
+
config.vocab_size, self.embed_dim, self.padding_idx, embed_scale=embed_scale
|
| 334 |
+
)
|
| 335 |
+
self.embed_positions = BioGptLearnedPositionalEmbedding(config.max_position_embeddings, self.embed_dim)
|
| 336 |
+
|
| 337 |
+
self.layers = nn.ModuleList([BioGptDecoderLayer(config, layer_idx=i) for i in range(config.num_hidden_layers)])
|
| 338 |
+
self.layer_norm = nn.LayerNorm(self.embed_dim)
|
| 339 |
+
|
| 340 |
+
self.gradient_checkpointing = False
|
| 341 |
+
# Initialize weights and apply final processing
|
| 342 |
+
self.post_init()
|
| 343 |
+
|
| 344 |
+
@merge_with_config_defaults
|
| 345 |
+
@capture_outputs
|
| 346 |
+
@auto_docstring
|
| 347 |
+
def forward(
|
| 348 |
+
self,
|
| 349 |
+
input_ids: torch.LongTensor | None = None,
|
| 350 |
+
attention_mask: torch.FloatTensor | None = None,
|
| 351 |
+
inputs_embeds: torch.FloatTensor | None = None,
|
| 352 |
+
past_key_values: Cache | None = None,
|
| 353 |
+
use_cache: bool | None = None,
|
| 354 |
+
position_ids: torch.LongTensor | None = None,
|
| 355 |
+
**kwargs: Unpack[TransformersKwargs],
|
| 356 |
+
) -> tuple | BaseModelOutputWithPastAndCrossAttentions:
|
| 357 |
+
if (input_ids is None) ^ (inputs_embeds is not None):
|
| 358 |
+
raise ValueError("You cannot specify both decoder_input_ids and decoder_inputs_embeds at the same time")
|
| 359 |
+
|
| 360 |
+
if inputs_embeds is None:
|
| 361 |
+
inputs_embeds = self.embed_tokens(input_ids)
|
| 362 |
+
|
| 363 |
+
# initialize past_key_values
|
| 364 |
+
if use_cache and past_key_values is None:
|
| 365 |
+
past_key_values = DynamicCache(config=self.config)
|
| 366 |
+
|
| 367 |
+
batch_size, seq_length = inputs_embeds.size()[:-1]
|
| 368 |
+
past_key_values_length = past_key_values.get_seq_length() if past_key_values is not None else 0
|
| 369 |
+
|
| 370 |
+
if attention_mask is None:
|
| 371 |
+
# required mask seq length can be calculated via length of past cache
|
| 372 |
+
mask_seq_length = past_key_values_length + seq_length
|
| 373 |
+
attention_mask = torch.ones(batch_size, mask_seq_length, device=inputs_embeds.device)
|
| 374 |
+
|
| 375 |
+
self_attn_cache = past_key_values
|
| 376 |
+
|
| 377 |
+
causal_mask = create_causal_mask(
|
| 378 |
+
config=self.config,
|
| 379 |
+
input_embeds=inputs_embeds,
|
| 380 |
+
attention_mask=attention_mask,
|
| 381 |
+
past_key_values=self_attn_cache,
|
| 382 |
+
)
|
| 383 |
+
|
| 384 |
+
# embed positions
|
| 385 |
+
if position_ids is None:
|
| 386 |
+
position_ids = torch.arange(seq_length, device=inputs_embeds.device) + past_key_values_length
|
| 387 |
+
position_ids = position_ids.unsqueeze(0)
|
| 388 |
+
|
| 389 |
+
positions = self.embed_positions(attention_mask, past_key_values_length, position_ids=position_ids)
|
| 390 |
+
hidden_states = inputs_embeds + positions
|
| 391 |
+
hidden_states = nn.functional.dropout(hidden_states, p=self.dropout, training=self.training)
|
| 392 |
+
|
| 393 |
+
for idx, decoder_layer in enumerate(self.layers):
|
| 394 |
+
if self.training:
|
| 395 |
+
dropout_probability = torch.rand([])
|
| 396 |
+
if dropout_probability < self.layerdrop:
|
| 397 |
+
continue
|
| 398 |
+
|
| 399 |
+
hidden_states = decoder_layer(
|
| 400 |
+
hidden_states,
|
| 401 |
+
attention_mask=causal_mask,
|
| 402 |
+
past_key_values=past_key_values,
|
| 403 |
+
use_cache=use_cache,
|
| 404 |
+
position_ids=position_ids,
|
| 405 |
+
**kwargs,
|
| 406 |
+
)
|
| 407 |
+
|
| 408 |
+
hidden_states = self.layer_norm(hidden_states)
|
| 409 |
+
|
| 410 |
+
return BaseModelOutputWithPastAndCrossAttentions(
|
| 411 |
+
last_hidden_state=hidden_states,
|
| 412 |
+
past_key_values=past_key_values,
|
| 413 |
+
)
|
| 414 |
+
|
| 415 |
+
|
| 416 |
+
@auto_docstring(
|
| 417 |
+
custom_intro="""
|
| 418 |
+
BioGPT Model with a `language modeling` head on top for CLM fine-tuning.
|
| 419 |
+
"""
|
| 420 |
+
)
|
| 421 |
+
class BioGptForCausalLM(BioGptPreTrainedModel, GenerationMixin):
|
| 422 |
+
_tied_weights_keys = {"output_projection.weight": "biogpt.embed_tokens.weight"}
|
| 423 |
+
|
| 424 |
+
def __init__(self, config):
|
| 425 |
+
super().__init__(config)
|
| 426 |
+
|
| 427 |
+
self.biogpt = BioGptModel(config)
|
| 428 |
+
self.output_projection = nn.Linear(config.hidden_size, config.vocab_size, bias=False)
|
| 429 |
+
|
| 430 |
+
# Initialize weights and apply final processing
|
| 431 |
+
self.post_init()
|
| 432 |
+
|
| 433 |
+
def get_output_embeddings(self):
|
| 434 |
+
return self.output_projection
|
| 435 |
+
|
| 436 |
+
def set_output_embeddings(self, new_embeddings):
|
| 437 |
+
self.output_projection = new_embeddings
|
| 438 |
+
|
| 439 |
+
@can_return_tuple
|
| 440 |
+
@auto_docstring
|
| 441 |
+
def forward(
|
| 442 |
+
self,
|
| 443 |
+
input_ids: torch.LongTensor | None = None,
|
| 444 |
+
attention_mask: torch.FloatTensor | None = None,
|
| 445 |
+
inputs_embeds: torch.FloatTensor | None = None,
|
| 446 |
+
past_key_values: Cache | None = None,
|
| 447 |
+
labels: torch.LongTensor | None = None,
|
| 448 |
+
use_cache: bool | None = None,
|
| 449 |
+
position_ids: torch.LongTensor | None = None,
|
| 450 |
+
logits_to_keep: int | torch.Tensor = 0,
|
| 451 |
+
**kwargs: Unpack[TransformersKwargs],
|
| 452 |
+
) -> tuple | CausalLMOutputWithCrossAttentions:
|
| 453 |
+
r"""
|
| 454 |
+
labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*):
|
| 455 |
+
Labels for language modeling. Note that the labels **are shifted** inside the model, i.e. you can set
|
| 456 |
+
`labels = input_ids` Indices are selected in `[-100, 0, ..., config.vocab_size]` All labels set to `-100`
|
| 457 |
+
are ignored (masked), the loss is only computed for labels in `[0, ..., config.vocab_size]`
|
| 458 |
+
"""
|
| 459 |
+
outputs = self.biogpt(
|
| 460 |
+
input_ids,
|
| 461 |
+
attention_mask=attention_mask,
|
| 462 |
+
inputs_embeds=inputs_embeds,
|
| 463 |
+
past_key_values=past_key_values,
|
| 464 |
+
use_cache=use_cache,
|
| 465 |
+
position_ids=position_ids,
|
| 466 |
+
**kwargs,
|
| 467 |
+
)
|
| 468 |
+
|
| 469 |
+
hidden_states = outputs[0]
|
| 470 |
+
slice_indices = slice(-logits_to_keep, None) if isinstance(logits_to_keep, int) else logits_to_keep
|
| 471 |
+
logits = self.output_projection(hidden_states[:, slice_indices, :])
|
| 472 |
+
|
| 473 |
+
loss = None
|
| 474 |
+
if labels is not None:
|
| 475 |
+
loss = self.loss_function(logits=logits, labels=labels, vocab_size=self.config.vocab_size, **kwargs)
|
| 476 |
+
|
| 477 |
+
return CausalLMOutputWithCrossAttentions(
|
| 478 |
+
loss=loss,
|
| 479 |
+
logits=logits,
|
| 480 |
+
past_key_values=outputs.past_key_values,
|
| 481 |
+
hidden_states=outputs.hidden_states,
|
| 482 |
+
attentions=outputs.attentions,
|
| 483 |
+
cross_attentions=outputs.cross_attentions,
|
| 484 |
+
)
|
| 485 |
+
|
| 486 |
+
|
| 487 |
+
@auto_docstring
|
| 488 |
+
class BioGptForTokenClassification(BioGptPreTrainedModel):
|
| 489 |
+
def __init__(self, config):
|
| 490 |
+
super().__init__(config)
|
| 491 |
+
self.num_labels = config.num_labels
|
| 492 |
+
|
| 493 |
+
self.biogpt = BioGptModel(config)
|
| 494 |
+
if hasattr(config, "classifier_dropout") and config.classifier_dropout is not None:
|
| 495 |
+
classifier_dropout = config.classifier_dropout
|
| 496 |
+
else:
|
| 497 |
+
classifier_dropout = config.hidden_dropout_prob
|
| 498 |
+
self.dropout = nn.Dropout(classifier_dropout)
|
| 499 |
+
self.classifier = nn.Linear(config.hidden_size, config.num_labels)
|
| 500 |
+
|
| 501 |
+
self.post_init()
|
| 502 |
+
|
| 503 |
+
@can_return_tuple
|
| 504 |
+
@auto_docstring
|
| 505 |
+
def forward(
|
| 506 |
+
self,
|
| 507 |
+
input_ids: torch.LongTensor | None = None,
|
| 508 |
+
token_type_ids: torch.LongTensor | None = None,
|
| 509 |
+
attention_mask: torch.FloatTensor | None = None,
|
| 510 |
+
past_key_values: Cache | None = None,
|
| 511 |
+
inputs_embeds: torch.FloatTensor | None = None,
|
| 512 |
+
labels: torch.LongTensor | None = None,
|
| 513 |
+
use_cache: bool | None = None,
|
| 514 |
+
position_ids: torch.LongTensor | None = None,
|
| 515 |
+
**kwargs,
|
| 516 |
+
) -> tuple | TokenClassifierOutput:
|
| 517 |
+
r"""
|
| 518 |
+
labels (`torch.LongTensor` of shape `(batch_size,)`, *optional*):
|
| 519 |
+
Labels for computing the sequence classification/regression loss. Indices should be in `[0, ...,
|
| 520 |
+
config.num_labels - 1]`. If `config.num_labels == 1` a regression loss is computed (Mean-Square loss), If
|
| 521 |
+
`config.num_labels > 1` a classification loss is computed (Cross-Entropy).
|
| 522 |
+
"""
|
| 523 |
+
transformer_outputs = self.biogpt(
|
| 524 |
+
input_ids,
|
| 525 |
+
past_key_values=past_key_values,
|
| 526 |
+
attention_mask=attention_mask,
|
| 527 |
+
inputs_embeds=inputs_embeds,
|
| 528 |
+
use_cache=use_cache,
|
| 529 |
+
position_ids=position_ids,
|
| 530 |
+
**kwargs,
|
| 531 |
+
)
|
| 532 |
+
|
| 533 |
+
hidden_states = transformer_outputs[0]
|
| 534 |
+
hidden_states = self.dropout(hidden_states)
|
| 535 |
+
logits = self.classifier(hidden_states)
|
| 536 |
+
|
| 537 |
+
loss = None
|
| 538 |
+
if labels is not None:
|
| 539 |
+
loss_fct = CrossEntropyLoss()
|
| 540 |
+
if attention_mask is not None:
|
| 541 |
+
active_loss = attention_mask.view(-1) == 1
|
| 542 |
+
active_logits = logits.view(-1, self.num_labels)
|
| 543 |
+
active_labels = torch.where(
|
| 544 |
+
active_loss, labels.view(-1), torch.tensor(loss_fct.ignore_index).type_as(labels)
|
| 545 |
+
)
|
| 546 |
+
loss = loss_fct(active_logits, active_labels)
|
| 547 |
+
else:
|
| 548 |
+
loss = loss_fct(logits.view(-1, self.num_labels), labels.view(-1))
|
| 549 |
+
|
| 550 |
+
return TokenClassifierOutput(
|
| 551 |
+
loss=loss,
|
| 552 |
+
logits=logits,
|
| 553 |
+
hidden_states=transformer_outputs.hidden_states,
|
| 554 |
+
attentions=transformer_outputs.attentions,
|
| 555 |
+
)
|
| 556 |
+
|
| 557 |
+
|
| 558 |
+
@auto_docstring(
|
| 559 |
+
custom_intro="""
|
| 560 |
+
The BioGpt Model transformer with a sequence classification head on top (linear layer).
|
| 561 |
+
|
| 562 |
+
[`BioGptForSequenceClassification`] uses the last token in order to do the classification, as other causal models
|
| 563 |
+
(e.g. GPT-2) do.
|
| 564 |
+
|
| 565 |
+
Since it does classification on the last token, it is required to know the position of the last token. If a
|
| 566 |
+
`pad_token_id` is defined in the configuration, it finds the last token that is not a padding token in each row. If
|
| 567 |
+
no `pad_token_id` is defined, it simply takes the last value in each row of the batch. Since it cannot guess the
|
| 568 |
+
padding tokens when `inputs_embeds` are passed instead of `input_ids`, it does the same (take the last value in
|
| 569 |
+
each row of the batch).
|
| 570 |
+
"""
|
| 571 |
+
)
|
| 572 |
+
class BioGptForSequenceClassification(BioGptPreTrainedModel):
|
| 573 |
+
def __init__(self, config: BioGptConfig):
|
| 574 |
+
super().__init__(config)
|
| 575 |
+
self.num_labels = config.num_labels
|
| 576 |
+
self.biogpt = BioGptModel(config)
|
| 577 |
+
self.score = nn.Linear(config.hidden_size, self.num_labels, bias=False)
|
| 578 |
+
|
| 579 |
+
# Initialize weights and apply final processing
|
| 580 |
+
self.post_init()
|
| 581 |
+
|
| 582 |
+
@can_return_tuple
|
| 583 |
+
@auto_docstring
|
| 584 |
+
def forward(
|
| 585 |
+
self,
|
| 586 |
+
input_ids: torch.LongTensor | None = None,
|
| 587 |
+
attention_mask: torch.FloatTensor | None = None,
|
| 588 |
+
past_key_values: Cache | None = None,
|
| 589 |
+
inputs_embeds: torch.FloatTensor | None = None,
|
| 590 |
+
labels: torch.LongTensor | None = None,
|
| 591 |
+
use_cache: bool | None = None,
|
| 592 |
+
position_ids: torch.LongTensor | None = None,
|
| 593 |
+
logits_to_keep: int | torch.Tensor = 0,
|
| 594 |
+
**kwargs,
|
| 595 |
+
) -> tuple | SequenceClassifierOutputWithPast:
|
| 596 |
+
r"""
|
| 597 |
+
labels (`torch.LongTensor` of shape `(batch_size,)`, *optional*):
|
| 598 |
+
Labels for computing the sequence classification/regression loss. Indices should be in `[0, ...,
|
| 599 |
+
config.num_labels - 1]`. If `config.num_labels == 1` a regression loss is computed (Mean-Square loss), If
|
| 600 |
+
`config.num_labels > 1` a classification loss is computed (Cross-Entropy).
|
| 601 |
+
"""
|
| 602 |
+
transformer_outputs = self.biogpt(
|
| 603 |
+
input_ids,
|
| 604 |
+
past_key_values=past_key_values,
|
| 605 |
+
attention_mask=attention_mask,
|
| 606 |
+
inputs_embeds=inputs_embeds,
|
| 607 |
+
use_cache=use_cache,
|
| 608 |
+
position_ids=position_ids,
|
| 609 |
+
**kwargs,
|
| 610 |
+
)
|
| 611 |
+
hidden_states = transformer_outputs[0]
|
| 612 |
+
slice_indices = slice(-logits_to_keep, None) if isinstance(logits_to_keep, int) else logits_to_keep
|
| 613 |
+
logits = self.score(hidden_states[:, slice_indices, :])
|
| 614 |
+
|
| 615 |
+
if input_ids is not None:
|
| 616 |
+
batch_size, sequence_length = input_ids.shape[:2]
|
| 617 |
+
else:
|
| 618 |
+
batch_size, sequence_length = inputs_embeds.shape[:2]
|
| 619 |
+
|
| 620 |
+
if self.config.pad_token_id is None:
|
| 621 |
+
sequence_length = -1
|
| 622 |
+
else:
|
| 623 |
+
if input_ids is not None:
|
| 624 |
+
sequence_length = (torch.ne(input_ids, self.config.pad_token_id).sum(-1) - 1).to(logits.device)
|
| 625 |
+
else:
|
| 626 |
+
sequence_length = -1
|
| 627 |
+
logger.warning_once(
|
| 628 |
+
f"{self.__class__.__name__} will not detect padding tokens in `inputs_embeds`. Results may be "
|
| 629 |
+
"unexpected if using padding tokens in conjunction with `inputs_embeds.`"
|
| 630 |
+
)
|
| 631 |
+
|
| 632 |
+
pooled_logits = logits[torch.arange(batch_size, device=logits.device), sequence_length]
|
| 633 |
+
|
| 634 |
+
loss = None
|
| 635 |
+
if labels is not None:
|
| 636 |
+
if self.config.problem_type is None:
|
| 637 |
+
if self.num_labels == 1:
|
| 638 |
+
self.config.problem_type = "regression"
|
| 639 |
+
elif self.num_labels > 1 and (labels.dtype == torch.long or labels.dtype == torch.int):
|
| 640 |
+
self.config.problem_type = "single_label_classification"
|
| 641 |
+
else:
|
| 642 |
+
self.config.problem_type = "multi_label_classification"
|
| 643 |
+
|
| 644 |
+
if self.config.problem_type == "regression":
|
| 645 |
+
loss_fct = MSELoss()
|
| 646 |
+
if self.num_labels == 1:
|
| 647 |
+
loss = loss_fct(pooled_logits.squeeze(), labels.squeeze())
|
| 648 |
+
else:
|
| 649 |
+
loss = loss_fct(pooled_logits, labels)
|
| 650 |
+
elif self.config.problem_type == "single_label_classification":
|
| 651 |
+
loss_fct = CrossEntropyLoss()
|
| 652 |
+
loss = loss_fct(pooled_logits.view(-1, self.num_labels), labels.view(-1))
|
| 653 |
+
elif self.config.problem_type == "multi_label_classification":
|
| 654 |
+
loss_fct = BCEWithLogitsLoss()
|
| 655 |
+
loss = loss_fct(pooled_logits, labels)
|
| 656 |
+
|
| 657 |
+
return SequenceClassifierOutputWithPast(
|
| 658 |
+
loss=loss,
|
| 659 |
+
logits=pooled_logits,
|
| 660 |
+
past_key_values=transformer_outputs.past_key_values,
|
| 661 |
+
hidden_states=transformer_outputs.hidden_states,
|
| 662 |
+
attentions=transformer_outputs.attentions,
|
| 663 |
+
)
|
| 664 |
+
|
| 665 |
+
def get_input_embeddings(self):
|
| 666 |
+
return self.biogpt.embed_tokens
|
| 667 |
+
|
| 668 |
+
def set_input_embeddings(self, value):
|
| 669 |
+
self.biogpt.embed_tokens = value
|
| 670 |
+
|
| 671 |
+
|
| 672 |
+
__all__ = [
|
| 673 |
+
"BioGptForCausalLM",
|
| 674 |
+
"BioGptForTokenClassification",
|
| 675 |
+
"BioGptForSequenceClassification",
|
| 676 |
+
"BioGptModel",
|
| 677 |
+
"BioGptPreTrainedModel",
|
| 678 |
+
]
|
third_party/transformers/src/transformers/models/biogpt/modular_biogpt.py
ADDED
|
@@ -0,0 +1,509 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright 2022 The HuggingFace Team and Microsoft Research AI4Science 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 BioGPT model."""
|
| 15 |
+
|
| 16 |
+
import math
|
| 17 |
+
|
| 18 |
+
import torch
|
| 19 |
+
import torch.nn as nn
|
| 20 |
+
from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss
|
| 21 |
+
|
| 22 |
+
from ...activations import ACT2FN
|
| 23 |
+
from ...cache_utils import Cache, DynamicCache
|
| 24 |
+
from ...generation import GenerationMixin
|
| 25 |
+
from ...masking_utils import create_causal_mask
|
| 26 |
+
from ...modeling_outputs import (
|
| 27 |
+
BaseModelOutputWithPastAndCrossAttentions,
|
| 28 |
+
CausalLMOutputWithCrossAttentions,
|
| 29 |
+
SequenceClassifierOutputWithPast,
|
| 30 |
+
TokenClassifierOutput,
|
| 31 |
+
)
|
| 32 |
+
from ...modeling_utils import PreTrainedModel
|
| 33 |
+
from ...processing_utils import Unpack
|
| 34 |
+
from ...utils import (
|
| 35 |
+
TransformersKwargs,
|
| 36 |
+
auto_docstring,
|
| 37 |
+
can_return_tuple,
|
| 38 |
+
logger,
|
| 39 |
+
)
|
| 40 |
+
from ...utils.generic import merge_with_config_defaults
|
| 41 |
+
from ...utils.output_capturing import capture_outputs
|
| 42 |
+
from ..bart.modeling_bart import (
|
| 43 |
+
BartAttention,
|
| 44 |
+
BartDecoderLayer,
|
| 45 |
+
BartScaledWordEmbedding,
|
| 46 |
+
)
|
| 47 |
+
from ..opt.modeling_opt import OPTLearnedPositionalEmbedding
|
| 48 |
+
from .configuration_biogpt import BioGptConfig
|
| 49 |
+
|
| 50 |
+
|
| 51 |
+
class BioGptLearnedPositionalEmbedding(OPTLearnedPositionalEmbedding):
|
| 52 |
+
def forward(
|
| 53 |
+
self,
|
| 54 |
+
attention_mask: torch.LongTensor,
|
| 55 |
+
past_key_values_length: int = 0,
|
| 56 |
+
position_ids: torch.LongTensor | None = None,
|
| 57 |
+
):
|
| 58 |
+
"""`input_ids_shape` is expected to be [bsz x seqlen]."""
|
| 59 |
+
return super().forward(attention_mask, past_key_values_length, position_ids)
|
| 60 |
+
|
| 61 |
+
|
| 62 |
+
class BioGptScaledWordEmbedding(BartScaledWordEmbedding):
|
| 63 |
+
pass
|
| 64 |
+
|
| 65 |
+
|
| 66 |
+
class BioGptAttention(BartAttention):
|
| 67 |
+
pass
|
| 68 |
+
|
| 69 |
+
|
| 70 |
+
class BioGptDecoderLayer(BartDecoderLayer):
|
| 71 |
+
def __init__(self, config: BioGptConfig, layer_idx: int | None = None):
|
| 72 |
+
super().__init__(config)
|
| 73 |
+
self.embed_dim = config.hidden_size
|
| 74 |
+
|
| 75 |
+
self.self_attn = BioGptAttention(
|
| 76 |
+
embed_dim=self.embed_dim,
|
| 77 |
+
num_heads=config.num_attention_heads,
|
| 78 |
+
dropout=config.attention_probs_dropout_prob,
|
| 79 |
+
is_decoder=True,
|
| 80 |
+
is_causal=True,
|
| 81 |
+
config=config,
|
| 82 |
+
layer_idx=layer_idx,
|
| 83 |
+
)
|
| 84 |
+
self.dropout = config.hidden_dropout_prob
|
| 85 |
+
self.activation_fn = ACT2FN[config.hidden_act]
|
| 86 |
+
|
| 87 |
+
self.fc1 = nn.Linear(self.embed_dim, config.intermediate_size)
|
| 88 |
+
self.fc2 = nn.Linear(config.intermediate_size, self.embed_dim)
|
| 89 |
+
|
| 90 |
+
del self.encoder_attn
|
| 91 |
+
del self.encoder_attn_layer_norm
|
| 92 |
+
|
| 93 |
+
def forward(
|
| 94 |
+
self,
|
| 95 |
+
hidden_states: torch.Tensor,
|
| 96 |
+
attention_mask: torch.Tensor | None = None,
|
| 97 |
+
past_key_values: Cache | None = None,
|
| 98 |
+
use_cache: bool | None = True,
|
| 99 |
+
position_ids: torch.LongTensor | None = None,
|
| 100 |
+
**kwargs: Unpack[TransformersKwargs],
|
| 101 |
+
) -> torch.Tensor:
|
| 102 |
+
"""
|
| 103 |
+
Args:
|
| 104 |
+
hidden_states (`torch.FloatTensor`): input to the layer of shape `(batch, seq_len, embed_dim)`
|
| 105 |
+
attention_mask (`torch.FloatTensor`): attention mask of size
|
| 106 |
+
`(batch, 1, tgt_len, src_len)` where padding elements are indicated by very large negative values.
|
| 107 |
+
past_key_values (`Cache`): cached past key and value projection states
|
| 108 |
+
"""
|
| 109 |
+
residual = hidden_states
|
| 110 |
+
|
| 111 |
+
hidden_states = self.self_attn_layer_norm(hidden_states)
|
| 112 |
+
|
| 113 |
+
# Self Attention
|
| 114 |
+
hidden_states, _ = self.self_attn(
|
| 115 |
+
hidden_states=hidden_states,
|
| 116 |
+
past_key_values=past_key_values,
|
| 117 |
+
attention_mask=attention_mask,
|
| 118 |
+
position_ids=position_ids,
|
| 119 |
+
**kwargs,
|
| 120 |
+
)
|
| 121 |
+
hidden_states = nn.functional.dropout(hidden_states, p=self.dropout, training=self.training)
|
| 122 |
+
hidden_states = residual + hidden_states
|
| 123 |
+
|
| 124 |
+
# Fully Connected
|
| 125 |
+
residual = hidden_states
|
| 126 |
+
hidden_states = self.final_layer_norm(hidden_states)
|
| 127 |
+
hidden_states = self.fc1(hidden_states)
|
| 128 |
+
hidden_states = self.activation_fn(hidden_states)
|
| 129 |
+
hidden_states = nn.functional.dropout(hidden_states, p=self.activation_dropout, training=self.training)
|
| 130 |
+
hidden_states = self.fc2(hidden_states)
|
| 131 |
+
hidden_states = nn.functional.dropout(hidden_states, p=self.dropout, training=self.training)
|
| 132 |
+
hidden_states = residual + hidden_states
|
| 133 |
+
|
| 134 |
+
return hidden_states
|
| 135 |
+
|
| 136 |
+
|
| 137 |
+
@auto_docstring
|
| 138 |
+
class BioGptPreTrainedModel(PreTrainedModel):
|
| 139 |
+
config: BioGptConfig
|
| 140 |
+
base_model_prefix = "biogpt"
|
| 141 |
+
supports_gradient_checkpointing = True
|
| 142 |
+
_supports_flash_attn = True
|
| 143 |
+
_supports_sdpa = True
|
| 144 |
+
_supports_flex_attn = True
|
| 145 |
+
_can_compile_fullgraph = True
|
| 146 |
+
_can_record_outputs = {
|
| 147 |
+
"hidden_states": BioGptDecoderLayer,
|
| 148 |
+
"attentions": BioGptAttention,
|
| 149 |
+
}
|
| 150 |
+
|
| 151 |
+
|
| 152 |
+
@auto_docstring
|
| 153 |
+
class BioGptModel(BioGptPreTrainedModel):
|
| 154 |
+
def __init__(self, config: BioGptConfig):
|
| 155 |
+
super().__init__(config)
|
| 156 |
+
self.config = config
|
| 157 |
+
self.layerdrop = config.layerdrop
|
| 158 |
+
self.dropout = config.hidden_dropout_prob
|
| 159 |
+
self.embed_dim = config.hidden_size
|
| 160 |
+
self.padding_idx = config.pad_token_id
|
| 161 |
+
embed_scale = math.sqrt(config.hidden_size) if config.scale_embedding else 1.0
|
| 162 |
+
|
| 163 |
+
self.embed_tokens = BioGptScaledWordEmbedding(
|
| 164 |
+
config.vocab_size, self.embed_dim, self.padding_idx, embed_scale=embed_scale
|
| 165 |
+
)
|
| 166 |
+
self.embed_positions = BioGptLearnedPositionalEmbedding(config.max_position_embeddings, self.embed_dim)
|
| 167 |
+
|
| 168 |
+
self.layers = nn.ModuleList([BioGptDecoderLayer(config, layer_idx=i) for i in range(config.num_hidden_layers)])
|
| 169 |
+
self.layer_norm = nn.LayerNorm(self.embed_dim)
|
| 170 |
+
|
| 171 |
+
self.gradient_checkpointing = False
|
| 172 |
+
# Initialize weights and apply final processing
|
| 173 |
+
self.post_init()
|
| 174 |
+
|
| 175 |
+
@merge_with_config_defaults
|
| 176 |
+
@capture_outputs
|
| 177 |
+
@auto_docstring
|
| 178 |
+
def forward(
|
| 179 |
+
self,
|
| 180 |
+
input_ids: torch.LongTensor | None = None,
|
| 181 |
+
attention_mask: torch.FloatTensor | None = None,
|
| 182 |
+
inputs_embeds: torch.FloatTensor | None = None,
|
| 183 |
+
past_key_values: Cache | None = None,
|
| 184 |
+
use_cache: bool | None = None,
|
| 185 |
+
position_ids: torch.LongTensor | None = None,
|
| 186 |
+
**kwargs: Unpack[TransformersKwargs],
|
| 187 |
+
) -> tuple | BaseModelOutputWithPastAndCrossAttentions:
|
| 188 |
+
if (input_ids is None) ^ (inputs_embeds is not None):
|
| 189 |
+
raise ValueError("You cannot specify both decoder_input_ids and decoder_inputs_embeds at the same time")
|
| 190 |
+
|
| 191 |
+
if inputs_embeds is None:
|
| 192 |
+
inputs_embeds = self.embed_tokens(input_ids)
|
| 193 |
+
|
| 194 |
+
# initialize past_key_values
|
| 195 |
+
if use_cache and past_key_values is None:
|
| 196 |
+
past_key_values = DynamicCache(config=self.config)
|
| 197 |
+
|
| 198 |
+
batch_size, seq_length = inputs_embeds.size()[:-1]
|
| 199 |
+
past_key_values_length = past_key_values.get_seq_length() if past_key_values is not None else 0
|
| 200 |
+
|
| 201 |
+
if attention_mask is None:
|
| 202 |
+
# required mask seq length can be calculated via length of past cache
|
| 203 |
+
mask_seq_length = past_key_values_length + seq_length
|
| 204 |
+
attention_mask = torch.ones(batch_size, mask_seq_length, device=inputs_embeds.device)
|
| 205 |
+
|
| 206 |
+
self_attn_cache = past_key_values
|
| 207 |
+
|
| 208 |
+
causal_mask = create_causal_mask(
|
| 209 |
+
config=self.config,
|
| 210 |
+
input_embeds=inputs_embeds,
|
| 211 |
+
attention_mask=attention_mask,
|
| 212 |
+
past_key_values=self_attn_cache,
|
| 213 |
+
)
|
| 214 |
+
|
| 215 |
+
# embed positions
|
| 216 |
+
if position_ids is None:
|
| 217 |
+
position_ids = torch.arange(seq_length, device=inputs_embeds.device) + past_key_values_length
|
| 218 |
+
position_ids = position_ids.unsqueeze(0)
|
| 219 |
+
|
| 220 |
+
positions = self.embed_positions(attention_mask, past_key_values_length, position_ids=position_ids)
|
| 221 |
+
hidden_states = inputs_embeds + positions
|
| 222 |
+
hidden_states = nn.functional.dropout(hidden_states, p=self.dropout, training=self.training)
|
| 223 |
+
|
| 224 |
+
for idx, decoder_layer in enumerate(self.layers):
|
| 225 |
+
if self.training:
|
| 226 |
+
dropout_probability = torch.rand([])
|
| 227 |
+
if dropout_probability < self.layerdrop:
|
| 228 |
+
continue
|
| 229 |
+
|
| 230 |
+
hidden_states = decoder_layer(
|
| 231 |
+
hidden_states,
|
| 232 |
+
attention_mask=causal_mask,
|
| 233 |
+
past_key_values=past_key_values,
|
| 234 |
+
use_cache=use_cache,
|
| 235 |
+
position_ids=position_ids,
|
| 236 |
+
**kwargs,
|
| 237 |
+
)
|
| 238 |
+
|
| 239 |
+
hidden_states = self.layer_norm(hidden_states)
|
| 240 |
+
|
| 241 |
+
return BaseModelOutputWithPastAndCrossAttentions(
|
| 242 |
+
last_hidden_state=hidden_states,
|
| 243 |
+
past_key_values=past_key_values,
|
| 244 |
+
)
|
| 245 |
+
|
| 246 |
+
|
| 247 |
+
@auto_docstring(
|
| 248 |
+
custom_intro="""
|
| 249 |
+
BioGPT Model with a `language modeling` head on top for CLM fine-tuning.
|
| 250 |
+
"""
|
| 251 |
+
)
|
| 252 |
+
class BioGptForCausalLM(BioGptPreTrainedModel, GenerationMixin):
|
| 253 |
+
_tied_weights_keys = {"output_projection.weight": "biogpt.embed_tokens.weight"}
|
| 254 |
+
|
| 255 |
+
def __init__(self, config):
|
| 256 |
+
super().__init__(config)
|
| 257 |
+
|
| 258 |
+
self.biogpt = BioGptModel(config)
|
| 259 |
+
self.output_projection = nn.Linear(config.hidden_size, config.vocab_size, bias=False)
|
| 260 |
+
|
| 261 |
+
# Initialize weights and apply final processing
|
| 262 |
+
self.post_init()
|
| 263 |
+
|
| 264 |
+
def get_output_embeddings(self):
|
| 265 |
+
return self.output_projection
|
| 266 |
+
|
| 267 |
+
def set_output_embeddings(self, new_embeddings):
|
| 268 |
+
self.output_projection = new_embeddings
|
| 269 |
+
|
| 270 |
+
@can_return_tuple
|
| 271 |
+
@auto_docstring
|
| 272 |
+
def forward(
|
| 273 |
+
self,
|
| 274 |
+
input_ids: torch.LongTensor | None = None,
|
| 275 |
+
attention_mask: torch.FloatTensor | None = None,
|
| 276 |
+
inputs_embeds: torch.FloatTensor | None = None,
|
| 277 |
+
past_key_values: Cache | None = None,
|
| 278 |
+
labels: torch.LongTensor | None = None,
|
| 279 |
+
use_cache: bool | None = None,
|
| 280 |
+
position_ids: torch.LongTensor | None = None,
|
| 281 |
+
logits_to_keep: int | torch.Tensor = 0,
|
| 282 |
+
**kwargs: Unpack[TransformersKwargs],
|
| 283 |
+
) -> tuple | CausalLMOutputWithCrossAttentions:
|
| 284 |
+
r"""
|
| 285 |
+
labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*):
|
| 286 |
+
Labels for language modeling. Note that the labels **are shifted** inside the model, i.e. you can set
|
| 287 |
+
`labels = input_ids` Indices are selected in `[-100, 0, ..., config.vocab_size]` All labels set to `-100`
|
| 288 |
+
are ignored (masked), the loss is only computed for labels in `[0, ..., config.vocab_size]`
|
| 289 |
+
"""
|
| 290 |
+
outputs = self.biogpt(
|
| 291 |
+
input_ids,
|
| 292 |
+
attention_mask=attention_mask,
|
| 293 |
+
inputs_embeds=inputs_embeds,
|
| 294 |
+
past_key_values=past_key_values,
|
| 295 |
+
use_cache=use_cache,
|
| 296 |
+
position_ids=position_ids,
|
| 297 |
+
**kwargs,
|
| 298 |
+
)
|
| 299 |
+
|
| 300 |
+
hidden_states = outputs[0]
|
| 301 |
+
slice_indices = slice(-logits_to_keep, None) if isinstance(logits_to_keep, int) else logits_to_keep
|
| 302 |
+
logits = self.output_projection(hidden_states[:, slice_indices, :])
|
| 303 |
+
|
| 304 |
+
loss = None
|
| 305 |
+
if labels is not None:
|
| 306 |
+
loss = self.loss_function(logits=logits, labels=labels, vocab_size=self.config.vocab_size, **kwargs)
|
| 307 |
+
|
| 308 |
+
return CausalLMOutputWithCrossAttentions(
|
| 309 |
+
loss=loss,
|
| 310 |
+
logits=logits,
|
| 311 |
+
past_key_values=outputs.past_key_values,
|
| 312 |
+
hidden_states=outputs.hidden_states,
|
| 313 |
+
attentions=outputs.attentions,
|
| 314 |
+
cross_attentions=outputs.cross_attentions,
|
| 315 |
+
)
|
| 316 |
+
|
| 317 |
+
|
| 318 |
+
@auto_docstring
|
| 319 |
+
class BioGptForTokenClassification(BioGptPreTrainedModel):
|
| 320 |
+
def __init__(self, config):
|
| 321 |
+
super().__init__(config)
|
| 322 |
+
self.num_labels = config.num_labels
|
| 323 |
+
|
| 324 |
+
self.biogpt = BioGptModel(config)
|
| 325 |
+
if hasattr(config, "classifier_dropout") and config.classifier_dropout is not None:
|
| 326 |
+
classifier_dropout = config.classifier_dropout
|
| 327 |
+
else:
|
| 328 |
+
classifier_dropout = config.hidden_dropout_prob
|
| 329 |
+
self.dropout = nn.Dropout(classifier_dropout)
|
| 330 |
+
self.classifier = nn.Linear(config.hidden_size, config.num_labels)
|
| 331 |
+
|
| 332 |
+
self.post_init()
|
| 333 |
+
|
| 334 |
+
@can_return_tuple
|
| 335 |
+
@auto_docstring
|
| 336 |
+
def forward(
|
| 337 |
+
self,
|
| 338 |
+
input_ids: torch.LongTensor | None = None,
|
| 339 |
+
token_type_ids: torch.LongTensor | None = None,
|
| 340 |
+
attention_mask: torch.FloatTensor | None = None,
|
| 341 |
+
past_key_values: Cache | None = None,
|
| 342 |
+
inputs_embeds: torch.FloatTensor | None = None,
|
| 343 |
+
labels: torch.LongTensor | None = None,
|
| 344 |
+
use_cache: bool | None = None,
|
| 345 |
+
position_ids: torch.LongTensor | None = None,
|
| 346 |
+
**kwargs,
|
| 347 |
+
) -> tuple | TokenClassifierOutput:
|
| 348 |
+
r"""
|
| 349 |
+
labels (`torch.LongTensor` of shape `(batch_size,)`, *optional*):
|
| 350 |
+
Labels for computing the sequence classification/regression loss. Indices should be in `[0, ...,
|
| 351 |
+
config.num_labels - 1]`. If `config.num_labels == 1` a regression loss is computed (Mean-Square loss), If
|
| 352 |
+
`config.num_labels > 1` a classification loss is computed (Cross-Entropy).
|
| 353 |
+
"""
|
| 354 |
+
transformer_outputs = self.biogpt(
|
| 355 |
+
input_ids,
|
| 356 |
+
past_key_values=past_key_values,
|
| 357 |
+
attention_mask=attention_mask,
|
| 358 |
+
inputs_embeds=inputs_embeds,
|
| 359 |
+
use_cache=use_cache,
|
| 360 |
+
position_ids=position_ids,
|
| 361 |
+
**kwargs,
|
| 362 |
+
)
|
| 363 |
+
|
| 364 |
+
hidden_states = transformer_outputs[0]
|
| 365 |
+
hidden_states = self.dropout(hidden_states)
|
| 366 |
+
logits = self.classifier(hidden_states)
|
| 367 |
+
|
| 368 |
+
loss = None
|
| 369 |
+
if labels is not None:
|
| 370 |
+
loss_fct = CrossEntropyLoss()
|
| 371 |
+
if attention_mask is not None:
|
| 372 |
+
active_loss = attention_mask.view(-1) == 1
|
| 373 |
+
active_logits = logits.view(-1, self.num_labels)
|
| 374 |
+
active_labels = torch.where(
|
| 375 |
+
active_loss, labels.view(-1), torch.tensor(loss_fct.ignore_index).type_as(labels)
|
| 376 |
+
)
|
| 377 |
+
loss = loss_fct(active_logits, active_labels)
|
| 378 |
+
else:
|
| 379 |
+
loss = loss_fct(logits.view(-1, self.num_labels), labels.view(-1))
|
| 380 |
+
|
| 381 |
+
return TokenClassifierOutput(
|
| 382 |
+
loss=loss,
|
| 383 |
+
logits=logits,
|
| 384 |
+
hidden_states=transformer_outputs.hidden_states,
|
| 385 |
+
attentions=transformer_outputs.attentions,
|
| 386 |
+
)
|
| 387 |
+
|
| 388 |
+
|
| 389 |
+
@auto_docstring(
|
| 390 |
+
custom_intro="""
|
| 391 |
+
The BioGpt Model transformer with a sequence classification head on top (linear layer).
|
| 392 |
+
|
| 393 |
+
[`BioGptForSequenceClassification`] uses the last token in order to do the classification, as other causal models
|
| 394 |
+
(e.g. GPT-2) do.
|
| 395 |
+
|
| 396 |
+
Since it does classification on the last token, it is required to know the position of the last token. If a
|
| 397 |
+
`pad_token_id` is defined in the configuration, it finds the last token that is not a padding token in each row. If
|
| 398 |
+
no `pad_token_id` is defined, it simply takes the last value in each row of the batch. Since it cannot guess the
|
| 399 |
+
padding tokens when `inputs_embeds` are passed instead of `input_ids`, it does the same (take the last value in
|
| 400 |
+
each row of the batch).
|
| 401 |
+
"""
|
| 402 |
+
)
|
| 403 |
+
class BioGptForSequenceClassification(BioGptPreTrainedModel):
|
| 404 |
+
def __init__(self, config: BioGptConfig):
|
| 405 |
+
super().__init__(config)
|
| 406 |
+
self.num_labels = config.num_labels
|
| 407 |
+
self.biogpt = BioGptModel(config)
|
| 408 |
+
self.score = nn.Linear(config.hidden_size, self.num_labels, bias=False)
|
| 409 |
+
|
| 410 |
+
# Initialize weights and apply final processing
|
| 411 |
+
self.post_init()
|
| 412 |
+
|
| 413 |
+
@can_return_tuple
|
| 414 |
+
@auto_docstring
|
| 415 |
+
def forward(
|
| 416 |
+
self,
|
| 417 |
+
input_ids: torch.LongTensor | None = None,
|
| 418 |
+
attention_mask: torch.FloatTensor | None = None,
|
| 419 |
+
past_key_values: Cache | None = None,
|
| 420 |
+
inputs_embeds: torch.FloatTensor | None = None,
|
| 421 |
+
labels: torch.LongTensor | None = None,
|
| 422 |
+
use_cache: bool | None = None,
|
| 423 |
+
position_ids: torch.LongTensor | None = None,
|
| 424 |
+
logits_to_keep: int | torch.Tensor = 0,
|
| 425 |
+
**kwargs,
|
| 426 |
+
) -> tuple | SequenceClassifierOutputWithPast:
|
| 427 |
+
r"""
|
| 428 |
+
labels (`torch.LongTensor` of shape `(batch_size,)`, *optional*):
|
| 429 |
+
Labels for computing the sequence classification/regression loss. Indices should be in `[0, ...,
|
| 430 |
+
config.num_labels - 1]`. If `config.num_labels == 1` a regression loss is computed (Mean-Square loss), If
|
| 431 |
+
`config.num_labels > 1` a classification loss is computed (Cross-Entropy).
|
| 432 |
+
"""
|
| 433 |
+
transformer_outputs = self.biogpt(
|
| 434 |
+
input_ids,
|
| 435 |
+
past_key_values=past_key_values,
|
| 436 |
+
attention_mask=attention_mask,
|
| 437 |
+
inputs_embeds=inputs_embeds,
|
| 438 |
+
use_cache=use_cache,
|
| 439 |
+
position_ids=position_ids,
|
| 440 |
+
**kwargs,
|
| 441 |
+
)
|
| 442 |
+
hidden_states = transformer_outputs[0]
|
| 443 |
+
slice_indices = slice(-logits_to_keep, None) if isinstance(logits_to_keep, int) else logits_to_keep
|
| 444 |
+
logits = self.score(hidden_states[:, slice_indices, :])
|
| 445 |
+
|
| 446 |
+
if input_ids is not None:
|
| 447 |
+
batch_size, sequence_length = input_ids.shape[:2]
|
| 448 |
+
else:
|
| 449 |
+
batch_size, sequence_length = inputs_embeds.shape[:2]
|
| 450 |
+
|
| 451 |
+
if self.config.pad_token_id is None:
|
| 452 |
+
sequence_length = -1
|
| 453 |
+
else:
|
| 454 |
+
if input_ids is not None:
|
| 455 |
+
sequence_length = (torch.ne(input_ids, self.config.pad_token_id).sum(-1) - 1).to(logits.device)
|
| 456 |
+
else:
|
| 457 |
+
sequence_length = -1
|
| 458 |
+
logger.warning_once(
|
| 459 |
+
f"{self.__class__.__name__} will not detect padding tokens in `inputs_embeds`. Results may be "
|
| 460 |
+
"unexpected if using padding tokens in conjunction with `inputs_embeds.`"
|
| 461 |
+
)
|
| 462 |
+
|
| 463 |
+
pooled_logits = logits[torch.arange(batch_size, device=logits.device), sequence_length]
|
| 464 |
+
|
| 465 |
+
loss = None
|
| 466 |
+
if labels is not None:
|
| 467 |
+
if self.config.problem_type is None:
|
| 468 |
+
if self.num_labels == 1:
|
| 469 |
+
self.config.problem_type = "regression"
|
| 470 |
+
elif self.num_labels > 1 and (labels.dtype == torch.long or labels.dtype == torch.int):
|
| 471 |
+
self.config.problem_type = "single_label_classification"
|
| 472 |
+
else:
|
| 473 |
+
self.config.problem_type = "multi_label_classification"
|
| 474 |
+
|
| 475 |
+
if self.config.problem_type == "regression":
|
| 476 |
+
loss_fct = MSELoss()
|
| 477 |
+
if self.num_labels == 1:
|
| 478 |
+
loss = loss_fct(pooled_logits.squeeze(), labels.squeeze())
|
| 479 |
+
else:
|
| 480 |
+
loss = loss_fct(pooled_logits, labels)
|
| 481 |
+
elif self.config.problem_type == "single_label_classification":
|
| 482 |
+
loss_fct = CrossEntropyLoss()
|
| 483 |
+
loss = loss_fct(pooled_logits.view(-1, self.num_labels), labels.view(-1))
|
| 484 |
+
elif self.config.problem_type == "multi_label_classification":
|
| 485 |
+
loss_fct = BCEWithLogitsLoss()
|
| 486 |
+
loss = loss_fct(pooled_logits, labels)
|
| 487 |
+
|
| 488 |
+
return SequenceClassifierOutputWithPast(
|
| 489 |
+
loss=loss,
|
| 490 |
+
logits=pooled_logits,
|
| 491 |
+
past_key_values=transformer_outputs.past_key_values,
|
| 492 |
+
hidden_states=transformer_outputs.hidden_states,
|
| 493 |
+
attentions=transformer_outputs.attentions,
|
| 494 |
+
)
|
| 495 |
+
|
| 496 |
+
def get_input_embeddings(self):
|
| 497 |
+
return self.biogpt.embed_tokens
|
| 498 |
+
|
| 499 |
+
def set_input_embeddings(self, value):
|
| 500 |
+
self.biogpt.embed_tokens = value
|
| 501 |
+
|
| 502 |
+
|
| 503 |
+
__all__ = [
|
| 504 |
+
"BioGptForCausalLM",
|
| 505 |
+
"BioGptForTokenClassification",
|
| 506 |
+
"BioGptForSequenceClassification",
|
| 507 |
+
"BioGptModel",
|
| 508 |
+
"BioGptPreTrainedModel",
|
| 509 |
+
]
|
third_party/transformers/src/transformers/models/biogpt/tokenization_biogpt.py
ADDED
|
@@ -0,0 +1,329 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright 2022 The HuggingFace Team and Microsoft Research AI4Science. 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 BioGPT."""
|
| 15 |
+
|
| 16 |
+
import json
|
| 17 |
+
import os
|
| 18 |
+
|
| 19 |
+
from ...tokenization_python import PreTrainedTokenizer
|
| 20 |
+
from ...utils import logging
|
| 21 |
+
|
| 22 |
+
|
| 23 |
+
logger = logging.get_logger(__name__)
|
| 24 |
+
|
| 25 |
+
VOCAB_FILES_NAMES = {
|
| 26 |
+
"vocab_file": "vocab.json",
|
| 27 |
+
"merges_file": "merges.txt",
|
| 28 |
+
}
|
| 29 |
+
|
| 30 |
+
|
| 31 |
+
def get_pairs(word):
|
| 32 |
+
"""
|
| 33 |
+
Return set of symbol pairs in a word. word is represented as tuple of symbols (symbols being variable-length
|
| 34 |
+
strings)
|
| 35 |
+
"""
|
| 36 |
+
pairs = set()
|
| 37 |
+
prev_char = word[0]
|
| 38 |
+
for char in word[1:]:
|
| 39 |
+
pairs.add((prev_char, char))
|
| 40 |
+
prev_char = char
|
| 41 |
+
return pairs
|
| 42 |
+
|
| 43 |
+
|
| 44 |
+
class BioGptTokenizer(PreTrainedTokenizer):
|
| 45 |
+
"""
|
| 46 |
+
Construct an FAIRSEQ Transformer tokenizer. Moses tokenization followed by Byte-Pair Encoding.
|
| 47 |
+
|
| 48 |
+
This tokenizer inherits from [`PreTrainedTokenizer`] which contains most of the main methods. Users should refer to
|
| 49 |
+
this superclass for more information regarding those methods.
|
| 50 |
+
|
| 51 |
+
Args:
|
| 52 |
+
vocab_file (`str`):
|
| 53 |
+
Path to the vocabulary file.
|
| 54 |
+
merges_file (`str`):
|
| 55 |
+
Merges file.
|
| 56 |
+
unk_token (`str`, *optional*, defaults to `"<unk>"`):
|
| 57 |
+
The unknown token. A token that is not in the vocabulary cannot be converted to an ID and is set to be this
|
| 58 |
+
token instead.
|
| 59 |
+
bos_token (`str`, *optional*, defaults to `"<s>"`):
|
| 60 |
+
The beginning of sequence token that was used during pretraining. Can be used a sequence classifier token.
|
| 61 |
+
|
| 62 |
+
<Tip>
|
| 63 |
+
|
| 64 |
+
When building a sequence using special tokens, this is not the token that is used for the beginning of
|
| 65 |
+
sequence. The token used is the `cls_token`.
|
| 66 |
+
|
| 67 |
+
</Tip>
|
| 68 |
+
|
| 69 |
+
eos_token (`str`, *optional*, defaults to `"</s>"`):
|
| 70 |
+
The end of sequence token.
|
| 71 |
+
|
| 72 |
+
<Tip>
|
| 73 |
+
|
| 74 |
+
When building a sequence using special tokens, this is not the token that is used for the end of sequence.
|
| 75 |
+
The token used is the `sep_token`.
|
| 76 |
+
|
| 77 |
+
</Tip>
|
| 78 |
+
|
| 79 |
+
sep_token (`str`, *optional*, defaults to `"</s>"`):
|
| 80 |
+
The separator token, which is used when building a sequence from multiple sequences, e.g. two sequences for
|
| 81 |
+
sequence classification or for a text and a question for question answering. It is also used as the last
|
| 82 |
+
token of a sequence built with special tokens.
|
| 83 |
+
pad_token (`str`, *optional*, defaults to `"<pad>"`):
|
| 84 |
+
The token used for padding, for example when batching sequences of different lengths.
|
| 85 |
+
"""
|
| 86 |
+
|
| 87 |
+
vocab_files_names = VOCAB_FILES_NAMES
|
| 88 |
+
model_input_names = ["input_ids", "attention_mask"]
|
| 89 |
+
|
| 90 |
+
def __init__(
|
| 91 |
+
self,
|
| 92 |
+
vocab_file,
|
| 93 |
+
merges_file,
|
| 94 |
+
unk_token="<unk>",
|
| 95 |
+
bos_token="<s>",
|
| 96 |
+
eos_token="</s>",
|
| 97 |
+
sep_token="</s>",
|
| 98 |
+
pad_token="<pad>",
|
| 99 |
+
**kwargs,
|
| 100 |
+
):
|
| 101 |
+
try:
|
| 102 |
+
import sacremoses
|
| 103 |
+
except ImportError:
|
| 104 |
+
raise ImportError(
|
| 105 |
+
"You need to install sacremoses to use BioGptTokenizer. "
|
| 106 |
+
"See https://pypi.org/project/sacremoses/ for installation."
|
| 107 |
+
)
|
| 108 |
+
|
| 109 |
+
self.lang = "en"
|
| 110 |
+
self.sm = sacremoses
|
| 111 |
+
# cache of sm.MosesTokenizer instance
|
| 112 |
+
self.cache_moses_tokenizer = {}
|
| 113 |
+
self.cache_moses_detokenizer = {}
|
| 114 |
+
|
| 115 |
+
""" Initialisation"""
|
| 116 |
+
with open(vocab_file, encoding="utf-8") as vocab_handle:
|
| 117 |
+
self.encoder = json.load(vocab_handle)
|
| 118 |
+
self.decoder = {v: k for k, v in self.encoder.items()}
|
| 119 |
+
with open(merges_file, encoding="utf-8") as merges_handle:
|
| 120 |
+
merges = merges_handle.read().split("\n")[:-1]
|
| 121 |
+
merges = [tuple(merge.split()[:2]) for merge in merges]
|
| 122 |
+
self.bpe_ranks = dict(zip(merges, range(len(merges))))
|
| 123 |
+
self.cache = {}
|
| 124 |
+
|
| 125 |
+
super().__init__(
|
| 126 |
+
bos_token=bos_token,
|
| 127 |
+
eos_token=eos_token,
|
| 128 |
+
sep_token=sep_token,
|
| 129 |
+
unk_token=unk_token,
|
| 130 |
+
pad_token=pad_token,
|
| 131 |
+
**kwargs,
|
| 132 |
+
)
|
| 133 |
+
|
| 134 |
+
@property
|
| 135 |
+
def vocab_size(self):
|
| 136 |
+
"""Returns vocab size"""
|
| 137 |
+
return len(self.encoder)
|
| 138 |
+
|
| 139 |
+
def get_vocab(self):
|
| 140 |
+
return dict(self.encoder, **self.added_tokens_encoder)
|
| 141 |
+
|
| 142 |
+
def moses_tokenize(self, text, lang):
|
| 143 |
+
if lang not in self.cache_moses_tokenizer:
|
| 144 |
+
moses_tokenizer = self.sm.MosesTokenizer(lang=lang)
|
| 145 |
+
self.cache_moses_tokenizer[lang] = moses_tokenizer
|
| 146 |
+
return self.cache_moses_tokenizer[lang].tokenize(
|
| 147 |
+
text, aggressive_dash_splits=True, return_str=False, escape=True
|
| 148 |
+
)
|
| 149 |
+
|
| 150 |
+
def moses_detokenize(self, tokens, lang):
|
| 151 |
+
if lang not in self.cache_moses_detokenizer:
|
| 152 |
+
moses_detokenizer = self.sm.MosesDetokenizer(lang=lang)
|
| 153 |
+
self.cache_moses_detokenizer[lang] = moses_detokenizer
|
| 154 |
+
return self.cache_moses_detokenizer[lang].detokenize(tokens)
|
| 155 |
+
|
| 156 |
+
def bpe(self, token):
|
| 157 |
+
word = tuple(token[:-1]) + (token[-1] + "</w>",)
|
| 158 |
+
if token in self.cache:
|
| 159 |
+
return self.cache[token]
|
| 160 |
+
pairs = get_pairs(word)
|
| 161 |
+
|
| 162 |
+
if not pairs:
|
| 163 |
+
return token + "</w>"
|
| 164 |
+
|
| 165 |
+
while True:
|
| 166 |
+
bigram = min(pairs, key=lambda pair: self.bpe_ranks.get(pair, float("inf")))
|
| 167 |
+
if bigram not in self.bpe_ranks:
|
| 168 |
+
break
|
| 169 |
+
first, second = bigram
|
| 170 |
+
new_word = []
|
| 171 |
+
i = 0
|
| 172 |
+
while i < len(word):
|
| 173 |
+
try:
|
| 174 |
+
j = word.index(first, i)
|
| 175 |
+
except ValueError:
|
| 176 |
+
new_word.extend(word[i:])
|
| 177 |
+
break
|
| 178 |
+
else:
|
| 179 |
+
new_word.extend(word[i:j])
|
| 180 |
+
i = j
|
| 181 |
+
|
| 182 |
+
if word[i] == first and i < len(word) - 1 and word[i + 1] == second:
|
| 183 |
+
new_word.append(first + second)
|
| 184 |
+
i += 2
|
| 185 |
+
else:
|
| 186 |
+
new_word.append(word[i])
|
| 187 |
+
i += 1
|
| 188 |
+
new_word = tuple(new_word)
|
| 189 |
+
word = new_word
|
| 190 |
+
if len(word) == 1:
|
| 191 |
+
break
|
| 192 |
+
else:
|
| 193 |
+
pairs = get_pairs(word)
|
| 194 |
+
word = " ".join(word)
|
| 195 |
+
if word == "\n </w>":
|
| 196 |
+
word = "\n</w>"
|
| 197 |
+
self.cache[token] = word
|
| 198 |
+
return word
|
| 199 |
+
|
| 200 |
+
def _tokenize(self, text, bypass_tokenizer=False):
|
| 201 |
+
"""Returns a tokenized string."""
|
| 202 |
+
if bypass_tokenizer:
|
| 203 |
+
text = text.split()
|
| 204 |
+
else:
|
| 205 |
+
text = self.moses_tokenize(text, self.lang)
|
| 206 |
+
|
| 207 |
+
split_tokens = []
|
| 208 |
+
for token in text:
|
| 209 |
+
if token:
|
| 210 |
+
split_tokens.extend(list(self.bpe(token).split(" ")))
|
| 211 |
+
|
| 212 |
+
return split_tokens
|
| 213 |
+
|
| 214 |
+
def _convert_token_to_id(self, token):
|
| 215 |
+
"""Converts a token (str) in an id using the vocab."""
|
| 216 |
+
return self.encoder.get(token, self.encoder.get(self.unk_token))
|
| 217 |
+
|
| 218 |
+
def _convert_id_to_token(self, index):
|
| 219 |
+
"""Converts an index (integer) in a token (str) using the vocab."""
|
| 220 |
+
return self.decoder.get(index, self.unk_token)
|
| 221 |
+
|
| 222 |
+
def convert_tokens_to_string(self, tokens):
|
| 223 |
+
"""Converts a sequence of tokens (string) in a single string."""
|
| 224 |
+
# remove BPE
|
| 225 |
+
tokens = [t.replace(" ", "").replace("</w>", " ") for t in tokens]
|
| 226 |
+
tokens = "".join(tokens).split()
|
| 227 |
+
# detokenize
|
| 228 |
+
text = self.moses_detokenize(tokens, self.lang)
|
| 229 |
+
return text
|
| 230 |
+
|
| 231 |
+
def build_inputs_with_special_tokens(
|
| 232 |
+
self, token_ids_0: list[int], token_ids_1: list[int] | None = None
|
| 233 |
+
) -> list[int]:
|
| 234 |
+
"""
|
| 235 |
+
Build model inputs from a sequence or a pair of sequence for sequence classification tasks by concatenating and
|
| 236 |
+
adding special tokens. A BioGPT sequence has the following format:
|
| 237 |
+
|
| 238 |
+
- single sequence: `</s> X `
|
| 239 |
+
- pair of sequences: `</s> A </s> B `
|
| 240 |
+
|
| 241 |
+
Args:
|
| 242 |
+
token_ids_0 (`List[int]`):
|
| 243 |
+
List of IDs to which the special tokens will be added.
|
| 244 |
+
token_ids_1 (`List[int]`, *optional*):
|
| 245 |
+
Optional second list of IDs for sequence pairs.
|
| 246 |
+
|
| 247 |
+
Returns:
|
| 248 |
+
`List[int]`: List of [input IDs](../glossary#input-ids) with the appropriate special tokens.
|
| 249 |
+
"""
|
| 250 |
+
if token_ids_1 is None:
|
| 251 |
+
return [self.sep_token_id] + token_ids_0
|
| 252 |
+
sep = [self.sep_token_id]
|
| 253 |
+
return sep + token_ids_0 + sep + token_ids_1
|
| 254 |
+
|
| 255 |
+
def get_special_tokens_mask(
|
| 256 |
+
self, token_ids_0: list[int], token_ids_1: list[int] | None = None, already_has_special_tokens: bool = False
|
| 257 |
+
) -> list[int]:
|
| 258 |
+
"""
|
| 259 |
+
Retrieve sequence ids from a token list that has no special tokens added. This method is called when adding
|
| 260 |
+
special tokens using the tokenizer `prepare_for_model` method.
|
| 261 |
+
|
| 262 |
+
Args:
|
| 263 |
+
token_ids_0 (`List[int]`):
|
| 264 |
+
List of IDs.
|
| 265 |
+
token_ids_1 (`List[int]`, *optional*):
|
| 266 |
+
Optional second list of IDs for sequence pairs.
|
| 267 |
+
already_has_special_tokens (`bool`, *optional*, defaults to `False`):
|
| 268 |
+
Whether or not the token list is already formatted with special tokens for the model.
|
| 269 |
+
|
| 270 |
+
Returns:
|
| 271 |
+
`List[int]`: A list of integers in the range [0, 1]: 1 for a special token, 0 for a sequence token.
|
| 272 |
+
"""
|
| 273 |
+
if already_has_special_tokens:
|
| 274 |
+
return super().get_special_tokens_mask(
|
| 275 |
+
token_ids_0=token_ids_0, token_ids_1=token_ids_1, already_has_special_tokens=True
|
| 276 |
+
)
|
| 277 |
+
# no bos used in fairseq
|
| 278 |
+
if token_ids_1 is not None:
|
| 279 |
+
return [1] + ([0] * len(token_ids_0)) + [1] + ([0] * len(token_ids_1))
|
| 280 |
+
return [1] + ([0] * len(token_ids_0))
|
| 281 |
+
|
| 282 |
+
def save_vocabulary(self, save_directory: str, filename_prefix: str | None = None) -> tuple[str]:
|
| 283 |
+
if not os.path.isdir(save_directory):
|
| 284 |
+
logger.error(f"Vocabulary path ({save_directory}) should be a directory")
|
| 285 |
+
return
|
| 286 |
+
vocab_file = os.path.join(
|
| 287 |
+
save_directory, (filename_prefix + "-" if filename_prefix else "") + VOCAB_FILES_NAMES["vocab_file"]
|
| 288 |
+
)
|
| 289 |
+
merge_file = os.path.join(
|
| 290 |
+
save_directory, (filename_prefix + "-" if filename_prefix else "") + VOCAB_FILES_NAMES["merges_file"]
|
| 291 |
+
)
|
| 292 |
+
|
| 293 |
+
with open(vocab_file, "w", encoding="utf-8") as f:
|
| 294 |
+
f.write(json.dumps(self.encoder, indent=2, sort_keys=True, ensure_ascii=False) + "\n")
|
| 295 |
+
|
| 296 |
+
index = 0
|
| 297 |
+
with open(merge_file, "w", encoding="utf-8") as writer:
|
| 298 |
+
for bpe_tokens, token_index in sorted(self.bpe_ranks.items(), key=lambda kv: kv[1]):
|
| 299 |
+
if index != token_index:
|
| 300 |
+
logger.warning(
|
| 301 |
+
f"Saving vocabulary to {merge_file}: BPE merge indices are not consecutive."
|
| 302 |
+
" Please check that the tokenizer is not corrupted!"
|
| 303 |
+
)
|
| 304 |
+
index = token_index
|
| 305 |
+
writer.write(" ".join(bpe_tokens) + "\n")
|
| 306 |
+
index += 1
|
| 307 |
+
|
| 308 |
+
return vocab_file, merge_file
|
| 309 |
+
|
| 310 |
+
def __getstate__(self):
|
| 311 |
+
state = self.__dict__.copy()
|
| 312 |
+
state["sm"] = None
|
| 313 |
+
return state
|
| 314 |
+
|
| 315 |
+
def __setstate__(self, d):
|
| 316 |
+
self.__dict__ = d
|
| 317 |
+
|
| 318 |
+
try:
|
| 319 |
+
import sacremoses
|
| 320 |
+
except ImportError:
|
| 321 |
+
raise ImportError(
|
| 322 |
+
"You need to install sacremoses to use XLMTokenizer. "
|
| 323 |
+
"See https://pypi.org/project/sacremoses/ for installation."
|
| 324 |
+
)
|
| 325 |
+
|
| 326 |
+
self.sm = sacremoses
|
| 327 |
+
|
| 328 |
+
|
| 329 |
+
__all__ = ["BioGptTokenizer"]
|
third_party/transformers/src/transformers/models/bit/__init__.py
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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_bit import *
|
| 22 |
+
from .image_processing_bit import *
|
| 23 |
+
from .image_processing_pil_bit import *
|
| 24 |
+
from .modeling_bit 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/bit/configuration_bit.py
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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 |
+
"""BiT model configuration"""
|
| 15 |
+
|
| 16 |
+
from huggingface_hub.dataclasses import strict
|
| 17 |
+
|
| 18 |
+
from ...backbone_utils import BackboneConfigMixin
|
| 19 |
+
from ...configuration_utils import PreTrainedConfig
|
| 20 |
+
from ...utils import auto_docstring
|
| 21 |
+
|
| 22 |
+
|
| 23 |
+
@auto_docstring(checkpoint="google/bit-50")
|
| 24 |
+
@strict
|
| 25 |
+
class BitConfig(BackboneConfigMixin, PreTrainedConfig):
|
| 26 |
+
r"""
|
| 27 |
+
layer_type (`str`, *optional*, defaults to `"preactivation"`):
|
| 28 |
+
The layer to use, it can be either `"preactivation"` or `"bottleneck"`.
|
| 29 |
+
global_padding (`str`, *optional*):
|
| 30 |
+
Padding strategy to use for the convolutional layers. Can be either `"valid"`, `"same"`, or `None`.
|
| 31 |
+
num_groups (`int`, *optional*, defaults to 32):
|
| 32 |
+
Number of groups used for the `BitGroupNormActivation` layers.
|
| 33 |
+
embedding_dynamic_padding (`bool`, *optional*, defaults to `False`):
|
| 34 |
+
Whether or not to make use of dynamic padding for the embedding layer.
|
| 35 |
+
width_factor (`int`, *optional*, defaults to 1):
|
| 36 |
+
The width factor for the model.
|
| 37 |
+
|
| 38 |
+
Example:
|
| 39 |
+
```python
|
| 40 |
+
>>> from transformers import BitConfig, BitModel
|
| 41 |
+
|
| 42 |
+
>>> # Initializing a BiT bit-50 style configuration
|
| 43 |
+
>>> configuration = BitConfig()
|
| 44 |
+
|
| 45 |
+
>>> # Initializing a model (with random weights) from the bit-50 style configuration
|
| 46 |
+
>>> model = BitModel(configuration)
|
| 47 |
+
|
| 48 |
+
>>> # Accessing the model configuration
|
| 49 |
+
>>> configuration = model.config
|
| 50 |
+
```
|
| 51 |
+
"""
|
| 52 |
+
|
| 53 |
+
model_type = "bit"
|
| 54 |
+
layer_types = ["preactivation", "bottleneck"]
|
| 55 |
+
supported_padding = [None, "SAME", "VALID"]
|
| 56 |
+
|
| 57 |
+
num_channels: int = 3
|
| 58 |
+
embedding_size: int = 64
|
| 59 |
+
hidden_sizes: list[int] | tuple[int, ...] = (256, 512, 1024, 2048)
|
| 60 |
+
depths: list[int] | tuple[int, ...] = (3, 4, 6, 3)
|
| 61 |
+
layer_type: str = "preactivation"
|
| 62 |
+
hidden_act: str = "relu"
|
| 63 |
+
global_padding: str | None = None
|
| 64 |
+
num_groups: int = 32
|
| 65 |
+
drop_path_rate: float | int = 0.0
|
| 66 |
+
embedding_dynamic_padding: bool = False
|
| 67 |
+
output_stride: int = 32
|
| 68 |
+
width_factor: int = 1
|
| 69 |
+
_out_features: list[str] | None = None
|
| 70 |
+
_out_indices: list[int] | None = None
|
| 71 |
+
|
| 72 |
+
def __post_init__(self, **kwargs):
|
| 73 |
+
self.hidden_sizes = list(self.hidden_sizes)
|
| 74 |
+
self.depths = list(self.depths)
|
| 75 |
+
|
| 76 |
+
if self.global_padding is not None:
|
| 77 |
+
self.global_padding = self.global_padding.upper()
|
| 78 |
+
|
| 79 |
+
self.stage_names = ["stem"] + [f"stage{idx}" for idx in range(1, len(self.depths) + 1)]
|
| 80 |
+
self.set_output_features_output_indices(
|
| 81 |
+
out_indices=kwargs.pop("out_indices", None), out_features=kwargs.pop("out_features", None)
|
| 82 |
+
)
|
| 83 |
+
|
| 84 |
+
super().__post_init__(**kwargs)
|
| 85 |
+
|
| 86 |
+
def validate_architecture(self):
|
| 87 |
+
"""Part of `@strict`-powered validation. Validates the architecture of the config."""
|
| 88 |
+
if self.layer_type not in self.layer_types:
|
| 89 |
+
raise ValueError(f"layer_type={self.layer_type} is not one of {','.join(self.layer_types)}")
|
| 90 |
+
|
| 91 |
+
if self.global_padding not in self.supported_padding:
|
| 92 |
+
raise ValueError(f"Padding strategy {self.global_padding} not supported")
|
| 93 |
+
|
| 94 |
+
|
| 95 |
+
__all__ = ["BitConfig"]
|
third_party/transformers/src/transformers/models/bit/convert_bit_to_pytorch.py
ADDED
|
@@ -0,0 +1,178 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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 |
+
"""Convert BiT checkpoints from the timm library."""
|
| 15 |
+
|
| 16 |
+
import argparse
|
| 17 |
+
import json
|
| 18 |
+
from io import BytesIO
|
| 19 |
+
from pathlib import Path
|
| 20 |
+
|
| 21 |
+
import httpx
|
| 22 |
+
import torch
|
| 23 |
+
from huggingface_hub import hf_hub_download
|
| 24 |
+
from PIL import Image
|
| 25 |
+
from timm import create_model
|
| 26 |
+
from timm.data import resolve_data_config
|
| 27 |
+
from timm.data.transforms_factory import create_transform
|
| 28 |
+
|
| 29 |
+
from transformers import BitConfig, BitForImageClassification, BitImageProcessor
|
| 30 |
+
from transformers.image_utils import PILImageResampling
|
| 31 |
+
from transformers.utils import logging
|
| 32 |
+
|
| 33 |
+
|
| 34 |
+
logging.set_verbosity_info()
|
| 35 |
+
logger = logging.get_logger(__name__)
|
| 36 |
+
|
| 37 |
+
|
| 38 |
+
def get_config(model_name):
|
| 39 |
+
repo_id = "huggingface/label-files"
|
| 40 |
+
filename = "imagenet-1k-id2label.json"
|
| 41 |
+
id2label = json.load(open(hf_hub_download(repo_id, filename, repo_type="dataset"), "r"))
|
| 42 |
+
id2label = {int(k): v for k, v in id2label.items()}
|
| 43 |
+
label2id = {v: k for k, v in id2label.items()}
|
| 44 |
+
|
| 45 |
+
conv_layer = "std_conv" if "bit" in model_name else False
|
| 46 |
+
|
| 47 |
+
# note that when using BiT as backbone for ViT-hybrid checkpoints,
|
| 48 |
+
# one needs to additionally set config.layer_type = "bottleneck", config.stem_type = "same",
|
| 49 |
+
# config.conv_layer = "std_conv_same"
|
| 50 |
+
config = BitConfig(
|
| 51 |
+
conv_layer=conv_layer,
|
| 52 |
+
num_labels=1000,
|
| 53 |
+
id2label=id2label,
|
| 54 |
+
label2id=label2id,
|
| 55 |
+
)
|
| 56 |
+
|
| 57 |
+
return config
|
| 58 |
+
|
| 59 |
+
|
| 60 |
+
def rename_key(name):
|
| 61 |
+
if "stem.conv" in name:
|
| 62 |
+
name = name.replace("stem.conv", "bit.embedder.convolution")
|
| 63 |
+
if "blocks" in name:
|
| 64 |
+
name = name.replace("blocks", "layers")
|
| 65 |
+
if "head.fc" in name:
|
| 66 |
+
name = name.replace("head.fc", "classifier.1")
|
| 67 |
+
if name.startswith("norm"):
|
| 68 |
+
name = "bit." + name
|
| 69 |
+
if "bit" not in name and "classifier" not in name:
|
| 70 |
+
name = "bit.encoder." + name
|
| 71 |
+
|
| 72 |
+
return name
|
| 73 |
+
|
| 74 |
+
|
| 75 |
+
# We will verify our results on an image of cute cats
|
| 76 |
+
def prepare_img():
|
| 77 |
+
url = "http://images.cocodataset.org/val2017/000000039769.jpg"
|
| 78 |
+
with httpx.stream("GET", url) as response:
|
| 79 |
+
image = Image.open(BytesIO(response.read()))
|
| 80 |
+
return image
|
| 81 |
+
|
| 82 |
+
|
| 83 |
+
@torch.no_grad()
|
| 84 |
+
def convert_bit_checkpoint(model_name, pytorch_dump_folder_path, push_to_hub=False):
|
| 85 |
+
"""
|
| 86 |
+
Copy/paste/tweak model's weights to our BiT structure.
|
| 87 |
+
"""
|
| 88 |
+
|
| 89 |
+
# define default BiT configuration
|
| 90 |
+
config = get_config(model_name)
|
| 91 |
+
|
| 92 |
+
# load original model from timm
|
| 93 |
+
timm_model = create_model(model_name, pretrained=True)
|
| 94 |
+
timm_model.eval()
|
| 95 |
+
|
| 96 |
+
# load state_dict of original model
|
| 97 |
+
state_dict = timm_model.state_dict()
|
| 98 |
+
for key in state_dict.copy():
|
| 99 |
+
val = state_dict.pop(key)
|
| 100 |
+
state_dict[rename_key(key)] = val.squeeze() if "head" in key else val
|
| 101 |
+
|
| 102 |
+
# load HuggingFace model
|
| 103 |
+
model = BitForImageClassification(config)
|
| 104 |
+
model.eval()
|
| 105 |
+
model.load_state_dict(state_dict)
|
| 106 |
+
|
| 107 |
+
# create image processor
|
| 108 |
+
transform = create_transform(**resolve_data_config({}, model=timm_model))
|
| 109 |
+
timm_transforms = transform.transforms
|
| 110 |
+
|
| 111 |
+
pillow_resamplings = {
|
| 112 |
+
"bilinear": PILImageResampling.BILINEAR,
|
| 113 |
+
"bicubic": PILImageResampling.BICUBIC,
|
| 114 |
+
"nearest": PILImageResampling.NEAREST,
|
| 115 |
+
}
|
| 116 |
+
|
| 117 |
+
processor = BitImageProcessor(
|
| 118 |
+
do_resize=True,
|
| 119 |
+
size={"shortest_edge": timm_transforms[0].size},
|
| 120 |
+
resample=pillow_resamplings[timm_transforms[0].interpolation.value],
|
| 121 |
+
do_center_crop=True,
|
| 122 |
+
crop_size={"height": timm_transforms[1].size[0], "width": timm_transforms[1].size[1]},
|
| 123 |
+
do_normalize=True,
|
| 124 |
+
image_mean=timm_transforms[-1].mean.tolist(),
|
| 125 |
+
image_std=timm_transforms[-1].std.tolist(),
|
| 126 |
+
)
|
| 127 |
+
|
| 128 |
+
image = prepare_img()
|
| 129 |
+
timm_pixel_values = transform(image).unsqueeze(0)
|
| 130 |
+
pixel_values = processor(image, return_tensors="pt").pixel_values
|
| 131 |
+
|
| 132 |
+
# verify pixel values
|
| 133 |
+
assert torch.allclose(timm_pixel_values, pixel_values)
|
| 134 |
+
|
| 135 |
+
# verify logits
|
| 136 |
+
with torch.no_grad():
|
| 137 |
+
outputs = model(pixel_values)
|
| 138 |
+
logits = outputs.logits
|
| 139 |
+
|
| 140 |
+
print("Logits:", logits[0, :3])
|
| 141 |
+
print("Predicted class:", model.config.id2label[logits.argmax(-1).item()])
|
| 142 |
+
timm_logits = timm_model(pixel_values)
|
| 143 |
+
assert timm_logits.shape == outputs.logits.shape
|
| 144 |
+
assert torch.allclose(timm_logits, outputs.logits, atol=1e-3)
|
| 145 |
+
print("Looks ok!")
|
| 146 |
+
|
| 147 |
+
if pytorch_dump_folder_path is not None:
|
| 148 |
+
Path(pytorch_dump_folder_path).mkdir(exist_ok=True)
|
| 149 |
+
print(f"Saving model {model_name} and processor to {pytorch_dump_folder_path}")
|
| 150 |
+
model.save_pretrained(pytorch_dump_folder_path)
|
| 151 |
+
processor.save_pretrained(pytorch_dump_folder_path)
|
| 152 |
+
|
| 153 |
+
if push_to_hub:
|
| 154 |
+
print(f"Pushing model {model_name} and processor to the hub")
|
| 155 |
+
model.push_to_hub(f"ybelkada/{model_name}")
|
| 156 |
+
processor.push_to_hub(f"ybelkada/{model_name}")
|
| 157 |
+
|
| 158 |
+
|
| 159 |
+
if __name__ == "__main__":
|
| 160 |
+
parser = argparse.ArgumentParser()
|
| 161 |
+
# Required parameters
|
| 162 |
+
parser.add_argument(
|
| 163 |
+
"--model_name",
|
| 164 |
+
default="resnetv2_50x1_bitm",
|
| 165 |
+
type=str,
|
| 166 |
+
help="Name of the BiT timm model you'd like to convert.",
|
| 167 |
+
)
|
| 168 |
+
parser.add_argument(
|
| 169 |
+
"--pytorch_dump_folder_path", default=None, type=str, help="Path to the output PyTorch model directory."
|
| 170 |
+
)
|
| 171 |
+
parser.add_argument(
|
| 172 |
+
"--push_to_hub",
|
| 173 |
+
action="store_true",
|
| 174 |
+
help="Whether to push the model to the hub.",
|
| 175 |
+
)
|
| 176 |
+
|
| 177 |
+
args = parser.parse_args()
|
| 178 |
+
convert_bit_checkpoint(args.model_name, args.pytorch_dump_folder_path, args.push_to_hub)
|
third_party/transformers/src/transformers/models/bit/image_processing_bit.py
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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 BiT."""
|
| 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 BitImageProcessor(TorchvisionBackend):
|
| 23 |
+
resample = PILImageResampling.BICUBIC
|
| 24 |
+
image_mean = OPENAI_CLIP_MEAN
|
| 25 |
+
image_std = OPENAI_CLIP_STD
|
| 26 |
+
size = {"shortest_edge": 224}
|
| 27 |
+
default_to_square = False
|
| 28 |
+
crop_size = {"height": 224, "width": 224}
|
| 29 |
+
do_resize = True
|
| 30 |
+
do_center_crop = True
|
| 31 |
+
do_rescale = True
|
| 32 |
+
do_normalize = True
|
| 33 |
+
do_convert_rgb = True
|
| 34 |
+
|
| 35 |
+
|
| 36 |
+
__all__ = ["BitImageProcessor"]
|
third_party/transformers/src/transformers/models/bit/image_processing_pil_bit.py
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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 BiT."""
|
| 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 BitImageProcessorPil(PilBackend):
|
| 23 |
+
resample = PILImageResampling.BICUBIC
|
| 24 |
+
image_mean = OPENAI_CLIP_MEAN
|
| 25 |
+
image_std = OPENAI_CLIP_STD
|
| 26 |
+
size = {"shortest_edge": 224}
|
| 27 |
+
default_to_square = False
|
| 28 |
+
crop_size = {"height": 224, "width": 224}
|
| 29 |
+
do_resize = True
|
| 30 |
+
do_center_crop = True
|
| 31 |
+
do_rescale = True
|
| 32 |
+
do_normalize = True
|
| 33 |
+
do_convert_rgb = True
|
| 34 |
+
|
| 35 |
+
|
| 36 |
+
__all__ = ["BitImageProcessorPil"]
|
third_party/transformers/src/transformers/models/bit/modeling_bit.py
ADDED
|
@@ -0,0 +1,832 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright 2022 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 |
+
"""PyTorch BiT model. Also supports backbone for ViT hybrid."""
|
| 15 |
+
|
| 16 |
+
import collections
|
| 17 |
+
import math
|
| 18 |
+
|
| 19 |
+
import numpy as np
|
| 20 |
+
import torch
|
| 21 |
+
from torch import Tensor, nn
|
| 22 |
+
|
| 23 |
+
from ... import initialization as init
|
| 24 |
+
from ...activations import ACT2FN
|
| 25 |
+
from ...backbone_utils import BackboneMixin, filter_output_hidden_states
|
| 26 |
+
from ...modeling_outputs import (
|
| 27 |
+
BackboneOutput,
|
| 28 |
+
BaseModelOutputWithNoAttention,
|
| 29 |
+
BaseModelOutputWithPoolingAndNoAttention,
|
| 30 |
+
ImageClassifierOutputWithNoAttention,
|
| 31 |
+
)
|
| 32 |
+
from ...modeling_utils import PreTrainedModel
|
| 33 |
+
from ...utils import auto_docstring, logging
|
| 34 |
+
from ...utils.generic import can_return_tuple
|
| 35 |
+
from .configuration_bit import BitConfig
|
| 36 |
+
|
| 37 |
+
|
| 38 |
+
logger = logging.get_logger(__name__)
|
| 39 |
+
|
| 40 |
+
|
| 41 |
+
def get_padding_value(padding=None, kernel_size=7, stride=1, dilation=1) -> tuple[tuple, bool]:
|
| 42 |
+
r"""
|
| 43 |
+
Utility function to get the tuple padding value given the kernel_size and padding.
|
| 44 |
+
|
| 45 |
+
Args:
|
| 46 |
+
padding (Union[`str`, `int`], *optional*):
|
| 47 |
+
Padding value, can be either `"same"`, `"valid"`. If a different value is provided the default padding from
|
| 48 |
+
PyTorch is used.
|
| 49 |
+
kernel_size (`int`, *optional*, defaults to 7):
|
| 50 |
+
Kernel size of the convolution layers.
|
| 51 |
+
stride (`int`, *optional*, defaults to 1):
|
| 52 |
+
Stride value of the convolution layers.
|
| 53 |
+
dilation (`int`, *optional*, defaults to 1):
|
| 54 |
+
Dilation value of the convolution layers.
|
| 55 |
+
"""
|
| 56 |
+
dynamic = False
|
| 57 |
+
if padding is None:
|
| 58 |
+
padding = ((stride - 1) + dilation * (kernel_size - 1)) // 2
|
| 59 |
+
return padding, dynamic
|
| 60 |
+
|
| 61 |
+
if isinstance(padding, str):
|
| 62 |
+
# for any string padding, the padding will be calculated for you, one of three ways
|
| 63 |
+
padding = padding.lower()
|
| 64 |
+
if padding == "same":
|
| 65 |
+
# TF compatible 'SAME' padding, has a performance and GPU memory allocation impact
|
| 66 |
+
if stride == 1 and (dilation * (kernel_size - 1)) % 2 == 0:
|
| 67 |
+
# static case, no extra overhead
|
| 68 |
+
padding = ((stride - 1) + dilation * (kernel_size - 1)) // 2
|
| 69 |
+
else:
|
| 70 |
+
# dynamic 'SAME' padding, has runtime/GPU memory overhead
|
| 71 |
+
padding = 0
|
| 72 |
+
dynamic = True
|
| 73 |
+
elif padding == "valid":
|
| 74 |
+
# 'VALID' padding, same as padding=0
|
| 75 |
+
padding = 0
|
| 76 |
+
else:
|
| 77 |
+
# Default to PyTorch style 'same'-ish symmetric padding
|
| 78 |
+
padding = ((stride - 1) + dilation * (kernel_size - 1)) // 2
|
| 79 |
+
return padding, dynamic
|
| 80 |
+
|
| 81 |
+
|
| 82 |
+
class WeightStandardizedConv2d(nn.Conv2d):
|
| 83 |
+
"""Conv2d with Weight Standardization. Used for ViT Hybrid model.
|
| 84 |
+
|
| 85 |
+
Paper: [Micro-Batch Training with Batch-Channel Normalization and Weight
|
| 86 |
+
Standardization](https://huggingface.co/papers/1903.10520)
|
| 87 |
+
"""
|
| 88 |
+
|
| 89 |
+
def __init__(
|
| 90 |
+
self,
|
| 91 |
+
in_channel,
|
| 92 |
+
out_channels,
|
| 93 |
+
kernel_size,
|
| 94 |
+
stride=1,
|
| 95 |
+
padding="SAME",
|
| 96 |
+
dilation=1,
|
| 97 |
+
groups=1,
|
| 98 |
+
bias=False,
|
| 99 |
+
eps=1e-6,
|
| 100 |
+
):
|
| 101 |
+
padding, is_dynamic = get_padding_value(padding, kernel_size, stride=stride, dilation=dilation)
|
| 102 |
+
super().__init__(
|
| 103 |
+
in_channel,
|
| 104 |
+
out_channels,
|
| 105 |
+
kernel_size,
|
| 106 |
+
stride=stride,
|
| 107 |
+
padding=padding,
|
| 108 |
+
dilation=dilation,
|
| 109 |
+
groups=groups,
|
| 110 |
+
bias=bias,
|
| 111 |
+
)
|
| 112 |
+
if is_dynamic:
|
| 113 |
+
self.pad = DynamicPad2d(kernel_size, stride, dilation)
|
| 114 |
+
else:
|
| 115 |
+
self.pad = None
|
| 116 |
+
self.eps = eps
|
| 117 |
+
|
| 118 |
+
def forward(self, hidden_state):
|
| 119 |
+
if self.pad is not None:
|
| 120 |
+
hidden_state = self.pad(hidden_state)
|
| 121 |
+
weight = nn.functional.batch_norm(
|
| 122 |
+
self.weight.reshape(1, self.out_channels, -1), None, None, training=True, momentum=0.0, eps=self.eps
|
| 123 |
+
).reshape_as(self.weight)
|
| 124 |
+
hidden_state = nn.functional.conv2d(
|
| 125 |
+
hidden_state, weight, self.bias, self.stride, self.padding, self.dilation, self.groups
|
| 126 |
+
)
|
| 127 |
+
return hidden_state
|
| 128 |
+
|
| 129 |
+
|
| 130 |
+
class BitGroupNormActivation(nn.GroupNorm):
|
| 131 |
+
r"""
|
| 132 |
+
A module that combines group normalization with an activation function.
|
| 133 |
+
"""
|
| 134 |
+
|
| 135 |
+
def __init__(self, config, num_channels, eps=1e-5, affine=True, apply_activation=True):
|
| 136 |
+
super().__init__(config.num_groups, num_channels, eps=eps, affine=affine)
|
| 137 |
+
if apply_activation:
|
| 138 |
+
self.activation = ACT2FN[config.hidden_act]
|
| 139 |
+
else:
|
| 140 |
+
self.activation = nn.Identity()
|
| 141 |
+
|
| 142 |
+
def forward(self, hidden_state):
|
| 143 |
+
hidden_state = nn.functional.group_norm(hidden_state, self.num_groups, self.weight, self.bias, self.eps)
|
| 144 |
+
hidden_state = self.activation(hidden_state)
|
| 145 |
+
return hidden_state
|
| 146 |
+
|
| 147 |
+
|
| 148 |
+
class DynamicPad2d(nn.Module):
|
| 149 |
+
r"""
|
| 150 |
+
A module that wraps dynamic padding of any input, given the parameters of the convolutional layer and the input
|
| 151 |
+
hidden states.
|
| 152 |
+
"""
|
| 153 |
+
|
| 154 |
+
def __init__(self, kernel_size, stride, dilation, value=0):
|
| 155 |
+
super().__init__()
|
| 156 |
+
# Safety checkers
|
| 157 |
+
if isinstance(kernel_size, int):
|
| 158 |
+
kernel_size = (kernel_size, kernel_size)
|
| 159 |
+
|
| 160 |
+
if isinstance(stride, int):
|
| 161 |
+
stride = (stride, stride)
|
| 162 |
+
|
| 163 |
+
if isinstance(dilation, int):
|
| 164 |
+
dilation = (dilation, dilation)
|
| 165 |
+
|
| 166 |
+
self.kernel_size = kernel_size
|
| 167 |
+
self.stride = stride
|
| 168 |
+
self.dilation = dilation
|
| 169 |
+
self.value = value
|
| 170 |
+
|
| 171 |
+
def compute_padding(x, kernel_size, stride, dilation):
|
| 172 |
+
return max((math.ceil(x / stride) - 1) * stride + (kernel_size - 1) * dilation + 1 - x, 0)
|
| 173 |
+
|
| 174 |
+
self.compute_padding = compute_padding
|
| 175 |
+
|
| 176 |
+
def forward(self, input):
|
| 177 |
+
# Get width and height
|
| 178 |
+
input_height, input_width = input.size()[-2:]
|
| 179 |
+
|
| 180 |
+
# Compute the padding values
|
| 181 |
+
padding_height = self.compute_padding(input_height, self.kernel_size[0], self.stride[0], self.dilation[0])
|
| 182 |
+
padding_width = self.compute_padding(input_width, self.kernel_size[1], self.stride[1], self.dilation[1])
|
| 183 |
+
|
| 184 |
+
# apply pad
|
| 185 |
+
if padding_height > 0 or padding_width > 0:
|
| 186 |
+
input = nn.functional.pad(
|
| 187 |
+
input,
|
| 188 |
+
[
|
| 189 |
+
padding_width // 2,
|
| 190 |
+
padding_width - padding_width // 2,
|
| 191 |
+
padding_height // 2,
|
| 192 |
+
padding_height - padding_height // 2,
|
| 193 |
+
],
|
| 194 |
+
value=self.value,
|
| 195 |
+
)
|
| 196 |
+
return input
|
| 197 |
+
|
| 198 |
+
|
| 199 |
+
class BitMaxPool2d(nn.MaxPool2d):
|
| 200 |
+
def __init__(
|
| 201 |
+
self,
|
| 202 |
+
kernel_size: int,
|
| 203 |
+
stride=None,
|
| 204 |
+
dilation=1,
|
| 205 |
+
ceil_mode=False,
|
| 206 |
+
padding=(0, 0),
|
| 207 |
+
padding_value=0,
|
| 208 |
+
use_dynamic_padding=True,
|
| 209 |
+
):
|
| 210 |
+
kernel_size = kernel_size if isinstance(kernel_size, collections.abc.Iterable) else (kernel_size, kernel_size)
|
| 211 |
+
stride = stride if isinstance(stride, collections.abc.Iterable) else (stride, stride)
|
| 212 |
+
dilation = dilation if isinstance(dilation, collections.abc.Iterable) else (dilation, dilation)
|
| 213 |
+
super().__init__(kernel_size, stride, padding, dilation, ceil_mode)
|
| 214 |
+
if use_dynamic_padding:
|
| 215 |
+
self.pad = DynamicPad2d(kernel_size, stride, dilation, padding_value)
|
| 216 |
+
else:
|
| 217 |
+
self.pad = nn.Identity()
|
| 218 |
+
|
| 219 |
+
def forward(self, hidden_states):
|
| 220 |
+
hidden_states = self.pad(hidden_states)
|
| 221 |
+
return nn.functional.max_pool2d(
|
| 222 |
+
hidden_states, self.kernel_size, self.stride, self.padding, self.dilation, self.ceil_mode
|
| 223 |
+
)
|
| 224 |
+
|
| 225 |
+
|
| 226 |
+
class BitEmbeddings(nn.Module):
|
| 227 |
+
"""
|
| 228 |
+
BiT Embeddings (stem) composed of a single aggressive convolution.
|
| 229 |
+
"""
|
| 230 |
+
|
| 231 |
+
def __init__(self, config: BitConfig):
|
| 232 |
+
super().__init__()
|
| 233 |
+
|
| 234 |
+
self.convolution = WeightStandardizedConv2d(
|
| 235 |
+
config.num_channels,
|
| 236 |
+
config.embedding_size,
|
| 237 |
+
kernel_size=7,
|
| 238 |
+
stride=2,
|
| 239 |
+
eps=1e-8,
|
| 240 |
+
padding=config.global_padding,
|
| 241 |
+
)
|
| 242 |
+
|
| 243 |
+
self.pooler = BitMaxPool2d(kernel_size=3, stride=2, use_dynamic_padding=config.embedding_dynamic_padding)
|
| 244 |
+
|
| 245 |
+
# Use the same padding strategy as convolutional layers
|
| 246 |
+
if config.global_padding is not None and config.global_padding.upper() == "SAME":
|
| 247 |
+
self.pad = nn.Identity()
|
| 248 |
+
else:
|
| 249 |
+
self.pad = nn.ConstantPad2d(padding=(1, 1, 1, 1), value=0.0)
|
| 250 |
+
|
| 251 |
+
if config.layer_type != "preactivation":
|
| 252 |
+
self.norm = BitGroupNormActivation(config, num_channels=config.embedding_size)
|
| 253 |
+
else:
|
| 254 |
+
self.norm = nn.Identity()
|
| 255 |
+
|
| 256 |
+
self.num_channels = config.num_channels
|
| 257 |
+
|
| 258 |
+
def forward(self, pixel_values: Tensor) -> Tensor:
|
| 259 |
+
num_channels = pixel_values.shape[1]
|
| 260 |
+
if num_channels != self.num_channels:
|
| 261 |
+
raise ValueError(
|
| 262 |
+
"Make sure that the channel dimension of the pixel values match with the one set in the configuration."
|
| 263 |
+
)
|
| 264 |
+
|
| 265 |
+
embedding = self.convolution(pixel_values)
|
| 266 |
+
|
| 267 |
+
embedding = self.pad(embedding)
|
| 268 |
+
|
| 269 |
+
embedding = self.norm(embedding)
|
| 270 |
+
|
| 271 |
+
embedding = self.pooler(embedding)
|
| 272 |
+
|
| 273 |
+
return embedding
|
| 274 |
+
|
| 275 |
+
|
| 276 |
+
# Copied from transformers.models.convnext.modeling_convnext.drop_path
|
| 277 |
+
def drop_path(input: torch.Tensor, drop_prob: float = 0.0, training: bool = False) -> torch.Tensor:
|
| 278 |
+
"""
|
| 279 |
+
Drop paths (Stochastic Depth) per sample (when applied in main path of residual blocks).
|
| 280 |
+
|
| 281 |
+
"""
|
| 282 |
+
if drop_prob == 0.0 or not training:
|
| 283 |
+
return input
|
| 284 |
+
keep_prob = 1 - drop_prob
|
| 285 |
+
shape = (input.shape[0],) + (1,) * (input.ndim - 1) # work with diff dim tensors, not just 2D ConvNets
|
| 286 |
+
random_tensor = keep_prob + torch.rand(shape, dtype=input.dtype, device=input.device)
|
| 287 |
+
random_tensor.floor_() # binarize
|
| 288 |
+
output = input.div(keep_prob) * random_tensor
|
| 289 |
+
return output
|
| 290 |
+
|
| 291 |
+
|
| 292 |
+
# Copied from transformers.models.beit.modeling_beit.BeitDropPath with Beit->Bit
|
| 293 |
+
class BitDropPath(nn.Module):
|
| 294 |
+
"""Drop paths (Stochastic Depth) per sample (when applied in main path of residual blocks)."""
|
| 295 |
+
|
| 296 |
+
def __init__(self, drop_prob: float | None = None) -> None:
|
| 297 |
+
super().__init__()
|
| 298 |
+
self.drop_prob = drop_prob
|
| 299 |
+
|
| 300 |
+
def forward(self, hidden_states: torch.Tensor) -> torch.Tensor:
|
| 301 |
+
return drop_path(hidden_states, self.drop_prob, self.training)
|
| 302 |
+
|
| 303 |
+
def extra_repr(self) -> str:
|
| 304 |
+
return f"p={self.drop_prob}"
|
| 305 |
+
|
| 306 |
+
|
| 307 |
+
def make_div(value, divisor=8):
|
| 308 |
+
min_value = divisor
|
| 309 |
+
new_value = max(min_value, int(value + divisor / 2) // divisor * divisor)
|
| 310 |
+
if new_value < 0.9 * value:
|
| 311 |
+
new_value += divisor
|
| 312 |
+
return new_value
|
| 313 |
+
|
| 314 |
+
|
| 315 |
+
class BitPreActivationBottleneckLayer(nn.Module):
|
| 316 |
+
"""Pre-activation (v2) bottleneck block.
|
| 317 |
+
Follows the implementation of "Identity Mappings in Deep Residual Networks":
|
| 318 |
+
https://github.com/KaimingHe/resnet-1k-layers/blob/master/resnet-pre-act.lua
|
| 319 |
+
|
| 320 |
+
Except it puts the stride on 3x3 conv when available.
|
| 321 |
+
"""
|
| 322 |
+
|
| 323 |
+
def __init__(
|
| 324 |
+
self,
|
| 325 |
+
config,
|
| 326 |
+
in_channels,
|
| 327 |
+
out_channels=None,
|
| 328 |
+
bottle_ratio=0.25,
|
| 329 |
+
stride=1,
|
| 330 |
+
dilation=1,
|
| 331 |
+
first_dilation=None,
|
| 332 |
+
groups=1,
|
| 333 |
+
drop_path_rate=0.0,
|
| 334 |
+
is_first_layer=False,
|
| 335 |
+
):
|
| 336 |
+
super().__init__()
|
| 337 |
+
|
| 338 |
+
first_dilation = first_dilation or dilation
|
| 339 |
+
|
| 340 |
+
out_channels = out_channels or in_channels
|
| 341 |
+
mid_channels = make_div(out_channels * bottle_ratio)
|
| 342 |
+
|
| 343 |
+
if is_first_layer:
|
| 344 |
+
self.downsample = BitDownsampleConv(
|
| 345 |
+
config,
|
| 346 |
+
in_channels,
|
| 347 |
+
out_channels,
|
| 348 |
+
stride=stride,
|
| 349 |
+
preact=True,
|
| 350 |
+
)
|
| 351 |
+
else:
|
| 352 |
+
self.downsample = None
|
| 353 |
+
|
| 354 |
+
self.norm1 = BitGroupNormActivation(config, in_channels)
|
| 355 |
+
self.conv1 = WeightStandardizedConv2d(in_channels, mid_channels, 1, eps=1e-8, padding=config.global_padding)
|
| 356 |
+
|
| 357 |
+
self.norm2 = BitGroupNormActivation(config, num_channels=mid_channels)
|
| 358 |
+
self.conv2 = WeightStandardizedConv2d(
|
| 359 |
+
mid_channels, mid_channels, 3, stride=stride, groups=groups, eps=1e-8, padding=config.global_padding
|
| 360 |
+
)
|
| 361 |
+
|
| 362 |
+
self.norm3 = BitGroupNormActivation(config, mid_channels)
|
| 363 |
+
self.conv3 = WeightStandardizedConv2d(mid_channels, out_channels, 1, eps=1e-8, padding=config.global_padding)
|
| 364 |
+
|
| 365 |
+
self.drop_path = BitDropPath(drop_path_rate) if drop_path_rate > 0 else nn.Identity()
|
| 366 |
+
|
| 367 |
+
def forward(self, hidden_states):
|
| 368 |
+
hidden_states_preact = self.norm1(hidden_states)
|
| 369 |
+
|
| 370 |
+
# shortcut branch
|
| 371 |
+
shortcut = hidden_states
|
| 372 |
+
if self.downsample is not None:
|
| 373 |
+
shortcut = self.downsample(hidden_states_preact)
|
| 374 |
+
|
| 375 |
+
# residual branch
|
| 376 |
+
hidden_states = self.conv1(hidden_states_preact)
|
| 377 |
+
hidden_states = self.conv2(self.norm2(hidden_states))
|
| 378 |
+
hidden_states = self.conv3(self.norm3(hidden_states))
|
| 379 |
+
hidden_states = self.drop_path(hidden_states)
|
| 380 |
+
return hidden_states + shortcut
|
| 381 |
+
|
| 382 |
+
|
| 383 |
+
class BitBottleneckLayer(nn.Module):
|
| 384 |
+
"""Non Pre-activation bottleneck block, equivalent to V1.5/V1b bottleneck. Used for ViT Hybrid."""
|
| 385 |
+
|
| 386 |
+
def __init__(
|
| 387 |
+
self,
|
| 388 |
+
config,
|
| 389 |
+
in_channels,
|
| 390 |
+
out_channels=None,
|
| 391 |
+
bottle_ratio=0.25,
|
| 392 |
+
stride=1,
|
| 393 |
+
dilation=1,
|
| 394 |
+
first_dilation=None,
|
| 395 |
+
groups=1,
|
| 396 |
+
drop_path_rate=0.0,
|
| 397 |
+
is_first_layer=False,
|
| 398 |
+
):
|
| 399 |
+
super().__init__()
|
| 400 |
+
first_dilation = first_dilation or dilation
|
| 401 |
+
|
| 402 |
+
out_channels = out_channels or in_channels
|
| 403 |
+
mid_chs = make_div(out_channels * bottle_ratio)
|
| 404 |
+
|
| 405 |
+
if is_first_layer:
|
| 406 |
+
self.downsample = BitDownsampleConv(
|
| 407 |
+
config,
|
| 408 |
+
in_channels,
|
| 409 |
+
out_channels,
|
| 410 |
+
stride=stride,
|
| 411 |
+
preact=False,
|
| 412 |
+
)
|
| 413 |
+
else:
|
| 414 |
+
self.downsample = None
|
| 415 |
+
|
| 416 |
+
self.conv1 = WeightStandardizedConv2d(in_channels, mid_chs, 1, eps=1e-8, padding=config.global_padding)
|
| 417 |
+
self.norm1 = BitGroupNormActivation(config, num_channels=mid_chs)
|
| 418 |
+
self.conv2 = WeightStandardizedConv2d(
|
| 419 |
+
mid_chs,
|
| 420 |
+
mid_chs,
|
| 421 |
+
3,
|
| 422 |
+
stride=stride,
|
| 423 |
+
dilation=first_dilation,
|
| 424 |
+
groups=groups,
|
| 425 |
+
eps=1e-8,
|
| 426 |
+
padding=config.global_padding,
|
| 427 |
+
)
|
| 428 |
+
self.norm2 = BitGroupNormActivation(config, num_channels=mid_chs)
|
| 429 |
+
self.conv3 = WeightStandardizedConv2d(mid_chs, out_channels, 1, eps=1e-8, padding=config.global_padding)
|
| 430 |
+
self.norm3 = BitGroupNormActivation(config, num_channels=out_channels, apply_activation=False)
|
| 431 |
+
self.drop_path = BitDropPath(drop_path_rate) if drop_path_rate > 0 else nn.Identity()
|
| 432 |
+
|
| 433 |
+
self.activation = ACT2FN[config.hidden_act]
|
| 434 |
+
|
| 435 |
+
def forward(self, hidden_states):
|
| 436 |
+
# shortcut branch
|
| 437 |
+
shortcut = hidden_states
|
| 438 |
+
if self.downsample is not None:
|
| 439 |
+
shortcut = self.downsample(hidden_states)
|
| 440 |
+
|
| 441 |
+
# residual
|
| 442 |
+
hidden_states = self.conv1(hidden_states)
|
| 443 |
+
hidden_states = self.norm1(hidden_states)
|
| 444 |
+
|
| 445 |
+
hidden_states = self.conv2(hidden_states)
|
| 446 |
+
hidden_states = self.norm2(hidden_states)
|
| 447 |
+
|
| 448 |
+
hidden_states = self.conv3(hidden_states)
|
| 449 |
+
hidden_states = self.norm3(hidden_states)
|
| 450 |
+
|
| 451 |
+
hidden_states = self.drop_path(hidden_states)
|
| 452 |
+
hidden_states = self.activation(hidden_states + shortcut)
|
| 453 |
+
return hidden_states
|
| 454 |
+
|
| 455 |
+
|
| 456 |
+
class BitDownsampleConv(nn.Module):
|
| 457 |
+
def __init__(
|
| 458 |
+
self,
|
| 459 |
+
config,
|
| 460 |
+
in_channels,
|
| 461 |
+
out_channels,
|
| 462 |
+
stride=1,
|
| 463 |
+
preact=True,
|
| 464 |
+
):
|
| 465 |
+
super().__init__()
|
| 466 |
+
self.conv = WeightStandardizedConv2d(
|
| 467 |
+
in_channels, out_channels, 1, stride=stride, eps=1e-8, padding=config.global_padding
|
| 468 |
+
)
|
| 469 |
+
self.norm = (
|
| 470 |
+
nn.Identity()
|
| 471 |
+
if preact
|
| 472 |
+
else BitGroupNormActivation(config, num_channels=out_channels, apply_activation=False)
|
| 473 |
+
)
|
| 474 |
+
|
| 475 |
+
def forward(self, x):
|
| 476 |
+
return self.norm(self.conv(x))
|
| 477 |
+
|
| 478 |
+
|
| 479 |
+
class BitStage(nn.Module):
|
| 480 |
+
"""
|
| 481 |
+
A ResNet v2 stage composed by stacked layers.
|
| 482 |
+
"""
|
| 483 |
+
|
| 484 |
+
def __init__(
|
| 485 |
+
self,
|
| 486 |
+
config,
|
| 487 |
+
in_channels,
|
| 488 |
+
out_channels,
|
| 489 |
+
stride,
|
| 490 |
+
dilation,
|
| 491 |
+
depth,
|
| 492 |
+
bottle_ratio=0.25,
|
| 493 |
+
layer_dropout=None,
|
| 494 |
+
):
|
| 495 |
+
super().__init__()
|
| 496 |
+
|
| 497 |
+
first_dilation = 1 if dilation in (1, 2) else 2
|
| 498 |
+
|
| 499 |
+
# Get the layer type
|
| 500 |
+
if config.layer_type == "bottleneck":
|
| 501 |
+
layer_cls = BitBottleneckLayer
|
| 502 |
+
else:
|
| 503 |
+
layer_cls = BitPreActivationBottleneckLayer
|
| 504 |
+
|
| 505 |
+
prev_chs = in_channels
|
| 506 |
+
self.layers = nn.Sequential()
|
| 507 |
+
for layer_idx in range(depth):
|
| 508 |
+
# Get the current hyper-parameters
|
| 509 |
+
stride, drop_path_rate, is_first_layer = self._get_updated_hyperparameters(
|
| 510 |
+
layer_idx, stride, layer_dropout
|
| 511 |
+
)
|
| 512 |
+
|
| 513 |
+
self.layers.add_module(
|
| 514 |
+
str(layer_idx),
|
| 515 |
+
layer_cls(
|
| 516 |
+
config,
|
| 517 |
+
prev_chs,
|
| 518 |
+
out_channels,
|
| 519 |
+
stride=stride,
|
| 520 |
+
dilation=dilation,
|
| 521 |
+
bottle_ratio=bottle_ratio,
|
| 522 |
+
first_dilation=first_dilation,
|
| 523 |
+
drop_path_rate=drop_path_rate,
|
| 524 |
+
is_first_layer=is_first_layer,
|
| 525 |
+
),
|
| 526 |
+
)
|
| 527 |
+
prev_chs = out_channels
|
| 528 |
+
first_dilation = dilation
|
| 529 |
+
|
| 530 |
+
def _get_updated_hyperparameters(self, layer_idx, stride, layer_dropout):
|
| 531 |
+
r"""
|
| 532 |
+
Get the new hyper-parameters with respect to the previous ones and the index of the current layer.
|
| 533 |
+
"""
|
| 534 |
+
if layer_dropout:
|
| 535 |
+
drop_path_rate = layer_dropout[layer_idx]
|
| 536 |
+
else:
|
| 537 |
+
drop_path_rate = 0.0
|
| 538 |
+
|
| 539 |
+
if layer_idx != 0:
|
| 540 |
+
stride = 1
|
| 541 |
+
|
| 542 |
+
is_first_layer = layer_idx == 0
|
| 543 |
+
|
| 544 |
+
return stride, drop_path_rate, is_first_layer
|
| 545 |
+
|
| 546 |
+
def forward(self, input: Tensor) -> Tensor:
|
| 547 |
+
hidden_state = input
|
| 548 |
+
for _, layer in enumerate(self.layers):
|
| 549 |
+
hidden_state = layer(hidden_state)
|
| 550 |
+
return hidden_state
|
| 551 |
+
|
| 552 |
+
|
| 553 |
+
class BitEncoder(nn.Module):
|
| 554 |
+
def __init__(self, config: BitConfig):
|
| 555 |
+
super().__init__()
|
| 556 |
+
self.stages = nn.ModuleList([])
|
| 557 |
+
|
| 558 |
+
prev_chs = config.embedding_size
|
| 559 |
+
|
| 560 |
+
# These needs to stay hardcoded
|
| 561 |
+
current_stride = 4
|
| 562 |
+
dilation = 1
|
| 563 |
+
|
| 564 |
+
layer_dropouts = [
|
| 565 |
+
x.tolist()
|
| 566 |
+
for x in torch.Tensor(np.linspace(0, config.drop_path_rate, sum(config.depths))).split(config.depths)
|
| 567 |
+
]
|
| 568 |
+
|
| 569 |
+
for stage_idx, (current_depth, current_hidden_size, layer_dropout) in enumerate(
|
| 570 |
+
zip(config.depths, config.hidden_sizes, layer_dropouts)
|
| 571 |
+
):
|
| 572 |
+
# Get the updated hyper params
|
| 573 |
+
out_channels, stride, dilation = self._get_updated_hyperparameters(
|
| 574 |
+
stage_idx, current_stride, current_hidden_size, dilation, config
|
| 575 |
+
)
|
| 576 |
+
|
| 577 |
+
stage = BitStage(
|
| 578 |
+
config,
|
| 579 |
+
prev_chs,
|
| 580 |
+
out_channels,
|
| 581 |
+
stride=stride,
|
| 582 |
+
dilation=dilation,
|
| 583 |
+
depth=current_depth,
|
| 584 |
+
layer_dropout=layer_dropout,
|
| 585 |
+
)
|
| 586 |
+
|
| 587 |
+
prev_chs = out_channels
|
| 588 |
+
current_stride *= stride
|
| 589 |
+
|
| 590 |
+
self.stages.add_module(str(stage_idx), stage)
|
| 591 |
+
|
| 592 |
+
def _get_updated_hyperparameters(self, stage_idx, current_stride, current_hidden_size, dilation, config):
|
| 593 |
+
out_channels = make_div(current_hidden_size * config.width_factor)
|
| 594 |
+
stride = 1 if stage_idx == 0 else 2
|
| 595 |
+
if current_stride >= config.output_stride:
|
| 596 |
+
dilation *= stride
|
| 597 |
+
stride = 1
|
| 598 |
+
return out_channels, stride, dilation
|
| 599 |
+
|
| 600 |
+
def forward(
|
| 601 |
+
self, hidden_state: Tensor, output_hidden_states: bool = False, return_dict: bool = True
|
| 602 |
+
) -> BaseModelOutputWithNoAttention:
|
| 603 |
+
hidden_states = () if output_hidden_states else None
|
| 604 |
+
|
| 605 |
+
for stage_module in self.stages:
|
| 606 |
+
if output_hidden_states:
|
| 607 |
+
hidden_states = hidden_states + (hidden_state,)
|
| 608 |
+
|
| 609 |
+
hidden_state = stage_module(hidden_state)
|
| 610 |
+
|
| 611 |
+
if output_hidden_states:
|
| 612 |
+
hidden_states = hidden_states + (hidden_state,)
|
| 613 |
+
|
| 614 |
+
if not return_dict:
|
| 615 |
+
return tuple(v for v in [hidden_state, hidden_states] if v is not None)
|
| 616 |
+
|
| 617 |
+
return BaseModelOutputWithNoAttention(
|
| 618 |
+
last_hidden_state=hidden_state,
|
| 619 |
+
hidden_states=hidden_states,
|
| 620 |
+
)
|
| 621 |
+
|
| 622 |
+
|
| 623 |
+
@auto_docstring
|
| 624 |
+
class BitPreTrainedModel(PreTrainedModel):
|
| 625 |
+
config: BitConfig
|
| 626 |
+
base_model_prefix = "bit"
|
| 627 |
+
input_modalities = ("image",)
|
| 628 |
+
main_input_name = "pixel_values"
|
| 629 |
+
_no_split_modules = ["BitEmbeddings"]
|
| 630 |
+
|
| 631 |
+
@torch.no_grad()
|
| 632 |
+
def _init_weights(self, module):
|
| 633 |
+
if isinstance(module, nn.Conv2d):
|
| 634 |
+
init.kaiming_normal_(module.weight, mode="fan_out", nonlinearity="relu")
|
| 635 |
+
# copied from the `reset_parameters` method of `class Linear(Module)` in `torch`.
|
| 636 |
+
elif isinstance(module, nn.Linear):
|
| 637 |
+
init.kaiming_uniform_(module.weight, a=math.sqrt(5))
|
| 638 |
+
if module.bias is not None:
|
| 639 |
+
fan_in, _ = torch.nn.init._calculate_fan_in_and_fan_out(module.weight)
|
| 640 |
+
bound = 1 / math.sqrt(fan_in) if fan_in > 0 else 0
|
| 641 |
+
init.uniform_(module.bias, -bound, bound)
|
| 642 |
+
elif isinstance(module, (nn.BatchNorm2d, nn.GroupNorm)):
|
| 643 |
+
init.constant_(module.weight, 1)
|
| 644 |
+
init.constant_(module.bias, 0)
|
| 645 |
+
if getattr(module, "running_mean", None) is not None:
|
| 646 |
+
init.zeros_(module.running_mean)
|
| 647 |
+
init.ones_(module.running_var)
|
| 648 |
+
init.zeros_(module.num_batches_tracked)
|
| 649 |
+
|
| 650 |
+
|
| 651 |
+
@auto_docstring
|
| 652 |
+
class BitModel(BitPreTrainedModel):
|
| 653 |
+
def __init__(self, config):
|
| 654 |
+
super().__init__(config)
|
| 655 |
+
self.config = config
|
| 656 |
+
|
| 657 |
+
self.embedder = BitEmbeddings(config)
|
| 658 |
+
|
| 659 |
+
self.encoder = BitEncoder(config)
|
| 660 |
+
self.norm = (
|
| 661 |
+
BitGroupNormActivation(config, num_channels=config.hidden_sizes[-1])
|
| 662 |
+
if config.layer_type == "preactivation"
|
| 663 |
+
else nn.Identity()
|
| 664 |
+
)
|
| 665 |
+
|
| 666 |
+
self.pooler = nn.AdaptiveAvgPool2d((1, 1))
|
| 667 |
+
# Initialize weights and apply final processing
|
| 668 |
+
self.post_init()
|
| 669 |
+
|
| 670 |
+
@auto_docstring
|
| 671 |
+
def forward(
|
| 672 |
+
self,
|
| 673 |
+
pixel_values: Tensor,
|
| 674 |
+
output_hidden_states: bool | None = None,
|
| 675 |
+
return_dict: bool | None = None,
|
| 676 |
+
**kwargs,
|
| 677 |
+
) -> BaseModelOutputWithPoolingAndNoAttention:
|
| 678 |
+
output_hidden_states = (
|
| 679 |
+
output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states
|
| 680 |
+
)
|
| 681 |
+
return_dict = return_dict if return_dict is not None else self.config.return_dict
|
| 682 |
+
|
| 683 |
+
embedding_output = self.embedder(pixel_values)
|
| 684 |
+
|
| 685 |
+
encoder_outputs = self.encoder(
|
| 686 |
+
embedding_output, output_hidden_states=output_hidden_states, return_dict=return_dict
|
| 687 |
+
)
|
| 688 |
+
|
| 689 |
+
last_hidden_state = encoder_outputs[0]
|
| 690 |
+
|
| 691 |
+
last_hidden_state = self.norm(last_hidden_state)
|
| 692 |
+
|
| 693 |
+
pooled_output = self.pooler(last_hidden_state)
|
| 694 |
+
|
| 695 |
+
if not return_dict:
|
| 696 |
+
return (last_hidden_state, pooled_output) + encoder_outputs[1:]
|
| 697 |
+
|
| 698 |
+
return BaseModelOutputWithPoolingAndNoAttention(
|
| 699 |
+
last_hidden_state=last_hidden_state,
|
| 700 |
+
pooler_output=pooled_output,
|
| 701 |
+
hidden_states=encoder_outputs.hidden_states,
|
| 702 |
+
)
|
| 703 |
+
|
| 704 |
+
|
| 705 |
+
@auto_docstring(
|
| 706 |
+
custom_intro="""
|
| 707 |
+
BiT Model with an image classification head on top (a linear layer on top of the pooled features), e.g. for
|
| 708 |
+
ImageNet.
|
| 709 |
+
"""
|
| 710 |
+
)
|
| 711 |
+
class BitForImageClassification(BitPreTrainedModel):
|
| 712 |
+
def __init__(self, config):
|
| 713 |
+
super().__init__(config)
|
| 714 |
+
self.num_labels = config.num_labels
|
| 715 |
+
self.bit = BitModel(config)
|
| 716 |
+
# classification head
|
| 717 |
+
self.classifier = nn.Sequential(
|
| 718 |
+
nn.Flatten(),
|
| 719 |
+
nn.Linear(config.hidden_sizes[-1], config.num_labels) if config.num_labels > 0 else nn.Identity(),
|
| 720 |
+
)
|
| 721 |
+
# initialize weights and apply final processing
|
| 722 |
+
self.post_init()
|
| 723 |
+
|
| 724 |
+
@auto_docstring
|
| 725 |
+
def forward(
|
| 726 |
+
self,
|
| 727 |
+
pixel_values: torch.FloatTensor | None = None,
|
| 728 |
+
labels: torch.LongTensor | None = None,
|
| 729 |
+
output_hidden_states: bool | None = None,
|
| 730 |
+
return_dict: bool | None = None,
|
| 731 |
+
**kwargs,
|
| 732 |
+
) -> ImageClassifierOutputWithNoAttention:
|
| 733 |
+
r"""
|
| 734 |
+
labels (`torch.LongTensor` of shape `(batch_size,)`, *optional*):
|
| 735 |
+
Labels for computing the image classification/regression loss. Indices should be in `[0, ...,
|
| 736 |
+
config.num_labels - 1]`. If `config.num_labels > 1` a classification loss is computed (Cross-Entropy).
|
| 737 |
+
"""
|
| 738 |
+
return_dict = return_dict if return_dict is not None else self.config.return_dict
|
| 739 |
+
|
| 740 |
+
outputs = self.bit(pixel_values, output_hidden_states=output_hidden_states, return_dict=return_dict)
|
| 741 |
+
|
| 742 |
+
pooled_output = outputs.pooler_output if return_dict else outputs[1]
|
| 743 |
+
|
| 744 |
+
logits = self.classifier(pooled_output)
|
| 745 |
+
|
| 746 |
+
loss = None
|
| 747 |
+
|
| 748 |
+
if labels is not None:
|
| 749 |
+
loss = self.loss_function(labels, logits, self.config)
|
| 750 |
+
|
| 751 |
+
if not return_dict:
|
| 752 |
+
output = (logits,) + outputs[2:]
|
| 753 |
+
return (loss,) + output if loss is not None else output
|
| 754 |
+
|
| 755 |
+
return ImageClassifierOutputWithNoAttention(loss=loss, logits=logits, hidden_states=outputs.hidden_states)
|
| 756 |
+
|
| 757 |
+
|
| 758 |
+
@auto_docstring(
|
| 759 |
+
custom_intro="""
|
| 760 |
+
BiT backbone, to be used with frameworks like DETR and MaskFormer.
|
| 761 |
+
"""
|
| 762 |
+
)
|
| 763 |
+
class BitBackbone(BackboneMixin, BitPreTrainedModel):
|
| 764 |
+
has_attentions = False
|
| 765 |
+
|
| 766 |
+
def __init__(self, config):
|
| 767 |
+
super().__init__(config)
|
| 768 |
+
|
| 769 |
+
self.bit = BitModel(config)
|
| 770 |
+
self.num_features = [config.embedding_size] + config.hidden_sizes
|
| 771 |
+
|
| 772 |
+
# initialize weights and apply final processing
|
| 773 |
+
self.post_init()
|
| 774 |
+
|
| 775 |
+
@can_return_tuple
|
| 776 |
+
@filter_output_hidden_states
|
| 777 |
+
@auto_docstring
|
| 778 |
+
def forward(
|
| 779 |
+
self,
|
| 780 |
+
pixel_values: Tensor,
|
| 781 |
+
output_hidden_states: bool | None = None,
|
| 782 |
+
return_dict: bool | None = None,
|
| 783 |
+
**kwargs,
|
| 784 |
+
) -> BackboneOutput:
|
| 785 |
+
r"""
|
| 786 |
+
Examples:
|
| 787 |
+
|
| 788 |
+
```python
|
| 789 |
+
>>> from transformers import AutoImageProcessor, AutoBackbone
|
| 790 |
+
>>> import torch
|
| 791 |
+
>>> from PIL import Image
|
| 792 |
+
>>> import httpx
|
| 793 |
+
>>> from io import BytesIO
|
| 794 |
+
|
| 795 |
+
>>> url = "http://images.cocodataset.org/val2017/000000039769.jpg"
|
| 796 |
+
>>> with httpx.stream("GET", url) as response:
|
| 797 |
+
... image = Image.open(BytesIO(response.read()))
|
| 798 |
+
|
| 799 |
+
>>> processor = AutoImageProcessor.from_pretrained("google/bit-50")
|
| 800 |
+
>>> model = AutoBackbone.from_pretrained("google/bit-50")
|
| 801 |
+
|
| 802 |
+
>>> inputs = processor(image, return_tensors="pt")
|
| 803 |
+
>>> outputs = model(**inputs)
|
| 804 |
+
```"""
|
| 805 |
+
return_dict = return_dict if return_dict is not None else self.config.return_dict
|
| 806 |
+
output_hidden_states = (
|
| 807 |
+
output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states
|
| 808 |
+
)
|
| 809 |
+
|
| 810 |
+
outputs = self.bit(pixel_values, output_hidden_states=True, return_dict=True)
|
| 811 |
+
|
| 812 |
+
hidden_states = outputs.hidden_states
|
| 813 |
+
|
| 814 |
+
feature_maps = ()
|
| 815 |
+
for idx, stage in enumerate(self.stage_names):
|
| 816 |
+
if stage in self.out_features:
|
| 817 |
+
feature_maps += (hidden_states[idx],)
|
| 818 |
+
|
| 819 |
+
if not return_dict:
|
| 820 |
+
output = (feature_maps,)
|
| 821 |
+
if output_hidden_states:
|
| 822 |
+
output += (outputs.hidden_states,)
|
| 823 |
+
return output
|
| 824 |
+
|
| 825 |
+
return BackboneOutput(
|
| 826 |
+
feature_maps=feature_maps,
|
| 827 |
+
hidden_states=outputs.hidden_states if output_hidden_states else None,
|
| 828 |
+
attentions=None,
|
| 829 |
+
)
|
| 830 |
+
|
| 831 |
+
|
| 832 |
+
__all__ = ["BitForImageClassification", "BitModel", "BitPreTrainedModel", "BitBackbone"]
|
third_party/transformers/src/transformers/models/blenderbot/__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_blenderbot import *
|
| 22 |
+
from .modeling_blenderbot import *
|
| 23 |
+
from .tokenization_blenderbot 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/blenderbot/configuration_blenderbot.py
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright 2021 The Facebook, Inc. 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 |
+
"""Blenderbot 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="facebook/blenderbot-3B")
|
| 23 |
+
@strict
|
| 24 |
+
class BlenderbotConfig(PreTrainedConfig):
|
| 25 |
+
r"""
|
| 26 |
+
encoder_no_repeat_ngram_size (`int`, *optional*, defaults to 3):
|
| 27 |
+
Number of ngrams to not be repeated in the encoder.
|
| 28 |
+
|
| 29 |
+
Example:
|
| 30 |
+
|
| 31 |
+
```python
|
| 32 |
+
>>> from transformers import BlenderbotConfig, BlenderbotModel
|
| 33 |
+
|
| 34 |
+
>>> # Initializing a Blenderbot facebook/blenderbot-3B style configuration
|
| 35 |
+
>>> configuration = BlenderbotConfig()
|
| 36 |
+
|
| 37 |
+
>>> # Initializing a model (with random weights) from the facebook/blenderbot-3B style configuration
|
| 38 |
+
>>> model = BlenderbotModel(configuration)
|
| 39 |
+
|
| 40 |
+
>>> # Accessing the model configuration
|
| 41 |
+
>>> configuration = model.config
|
| 42 |
+
```"""
|
| 43 |
+
|
| 44 |
+
model_type = "blenderbot"
|
| 45 |
+
keys_to_ignore_at_inference = ["past_key_values"]
|
| 46 |
+
attribute_map = {
|
| 47 |
+
"num_attention_heads": "encoder_attention_heads",
|
| 48 |
+
"hidden_size": "d_model",
|
| 49 |
+
"num_hidden_layers": "encoder_layers",
|
| 50 |
+
}
|
| 51 |
+
|
| 52 |
+
vocab_size: int = 8008
|
| 53 |
+
max_position_embeddings: int = 128
|
| 54 |
+
encoder_layers: int = 2
|
| 55 |
+
encoder_ffn_dim: int = 10240
|
| 56 |
+
encoder_attention_heads: int = 32
|
| 57 |
+
decoder_layers: int = 24
|
| 58 |
+
decoder_ffn_dim: int = 10240
|
| 59 |
+
decoder_attention_heads: int = 32
|
| 60 |
+
encoder_layerdrop: float | int = 0.0
|
| 61 |
+
decoder_layerdrop: float | int = 0.0
|
| 62 |
+
use_cache: bool = True
|
| 63 |
+
is_encoder_decoder: bool = True
|
| 64 |
+
activation_function: str = "gelu"
|
| 65 |
+
d_model: int = 2560
|
| 66 |
+
dropout: float | int = 0.1
|
| 67 |
+
attention_dropout: float | int = 0.0
|
| 68 |
+
activation_dropout: float | int = 0.0
|
| 69 |
+
init_std: float = 0.02
|
| 70 |
+
decoder_start_token_id: int = 1
|
| 71 |
+
scale_embedding: bool = False
|
| 72 |
+
pad_token_id: int | None = 0
|
| 73 |
+
bos_token_id: int | None = 1
|
| 74 |
+
eos_token_id: int | list[int] | None = 2
|
| 75 |
+
encoder_no_repeat_ngram_size: int = 3
|
| 76 |
+
forced_eos_token_id: int | list[int] | None = 2
|
| 77 |
+
is_decoder: bool = False
|
| 78 |
+
tie_word_embeddings: bool = True
|
| 79 |
+
|
| 80 |
+
|
| 81 |
+
__all__ = ["BlenderbotConfig"]
|