RyanDDD commited on
Commit
8c4351d
·
verified ·
1 Parent(s): 7980b2b

Upload folder using huggingface_hub

Browse files
config.json CHANGED
@@ -3,6 +3,10 @@
3
  "EmpathyModel"
4
  ],
5
  "attn_heads": 1,
 
 
 
 
6
  "empathy_num_labels": 3,
7
  "empathy_type": "ER",
8
  "hidden_dropout_prob": 0.2,
 
3
  "EmpathyModel"
4
  ],
5
  "attn_heads": 1,
6
+ "auto_map": {
7
+ "AutoConfig": "modeling_empathy.EmpathyModelConfig",
8
+ "AutoModel": "modeling_empathy.EmpathyModel"
9
+ },
10
  "empathy_num_labels": 3,
11
  "empathy_type": "ER",
12
  "hidden_dropout_prob": 0.2,
modeling_empathy.py ADDED
@@ -0,0 +1,59 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Custom modeling file for Empathy Classification Model"""
2
+ import torch
3
+ from transformers import PreTrainedModel, PretrainedConfig
4
+ from .models.models import BiEncoderAttentionWithRationaleClassification
5
+
6
+
7
+ class EmpathyModelConfig(PretrainedConfig):
8
+ """Configuration for Empathy Model"""
9
+ model_type = "empathy_classifier"
10
+
11
+ def __init__(
12
+ self,
13
+ hidden_dropout_prob=0.2,
14
+ rationale_num_labels=2,
15
+ empathy_num_labels=3,
16
+ hidden_size=768,
17
+ attn_heads=1,
18
+ max_length=64,
19
+ **kwargs
20
+ ):
21
+ super().__init__(**kwargs)
22
+ self.hidden_dropout_prob = hidden_dropout_prob
23
+ self.rationale_num_labels = rationale_num_labels
24
+ self.empathy_num_labels = empathy_num_labels
25
+ self.hidden_size = hidden_size
26
+ self.attn_heads = attn_heads
27
+ self.max_length = max_length
28
+
29
+
30
+ class EmpathyModel(PreTrainedModel):
31
+ """HuggingFace wrapper for Empathy Model"""
32
+ config_class = EmpathyModelConfig
33
+
34
+ def __init__(self, config):
35
+ super().__init__(config)
36
+ self.config = config
37
+ self.model = BiEncoderAttentionWithRationaleClassification(
38
+ hidden_dropout_prob=config.hidden_dropout_prob,
39
+ rationale_num_labels=config.rationale_num_labels,
40
+ empathy_num_labels=config.empathy_num_labels,
41
+ hidden_size=config.hidden_size,
42
+ attn_heads=config.attn_heads
43
+ )
44
+
45
+ def forward(
46
+ self,
47
+ input_ids_SP=None,
48
+ input_ids_RP=None,
49
+ attention_mask_SP=None,
50
+ attention_mask_RP=None,
51
+ **kwargs
52
+ ):
53
+ return self.model(
54
+ input_ids_SP=input_ids_SP,
55
+ input_ids_RP=input_ids_RP,
56
+ attention_mask_SP=attention_mask_SP,
57
+ attention_mask_RP=attention_mask_RP,
58
+ **kwargs
59
+ )
models/__init__.py ADDED
@@ -0,0 +1 @@
 
 
1
+ __version__ = "2.8.0"
models/__pycache__/__init__.cpython-310.pyc ADDED
Binary file (174 Bytes). View file
 
models/__pycache__/activations.cpython-310.pyc ADDED
Binary file (1.99 kB). View file
 
models/__pycache__/configuration_bert.cpython-310.pyc ADDED
Binary file (7.48 kB). View file
 
models/__pycache__/configuration_roberta.cpython-310.pyc ADDED
Binary file (2.87 kB). View file
 
models/__pycache__/configuration_utils.cpython-310.pyc ADDED
Binary file (16.4 kB). View file
 
models/__pycache__/file_utils.cpython-310.pyc ADDED
Binary file (13.5 kB). View file
 
models/__pycache__/modeling_bert.cpython-310.pyc ADDED
Binary file (52 kB). View file
 
models/__pycache__/modeling_utils.cpython-310.pyc ADDED
Binary file (66.6 kB). View file
 
models/__pycache__/models.cpython-310.pyc ADDED
Binary file (8.51 kB). View file
 
models/__pycache__/roberta.cpython-310.pyc ADDED
Binary file (26 kB). View file
 
models/activations.py ADDED
@@ -0,0 +1,59 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import logging
2
+ import math
3
+
4
+ import torch
5
+ import torch.nn.functional as F
6
+
7
+
8
+ logger = logging.getLogger(__name__)
9
+
10
+
11
+ def swish(x):
12
+ return x * torch.sigmoid(x)
13
+
14
+
15
+ def _gelu_python(x):
16
+ """ Original Implementation of the gelu activation function in Google Bert repo when initially created.
17
+ For information: OpenAI GPT's gelu is slightly different (and gives slightly different results):
18
+ 0.5 * x * (1 + torch.tanh(math.sqrt(2 / math.pi) * (x + 0.044715 * torch.pow(x, 3))))
19
+ This is now written in C in torch.nn.functional
20
+ Also see https://arxiv.org/abs/1606.08415
21
+ """
22
+ return x * 0.5 * (1.0 + torch.erf(x / math.sqrt(2.0)))
23
+
24
+
25
+ def gelu_new(x):
26
+ """ Implementation of the gelu activation function currently in Google Bert repo (identical to OpenAI GPT).
27
+ Also see https://arxiv.org/abs/1606.08415
28
+ """
29
+ return 0.5 * x * (1 + torch.tanh(math.sqrt(2 / math.pi) * (x + 0.044715 * torch.pow(x, 3.0))))
30
+
31
+
32
+ if torch.__version__ < "1.4.0":
33
+ gelu = _gelu_python
34
+ else:
35
+ gelu = F.gelu
36
+ try:
37
+ import torch_xla # noqa F401
38
+
39
+ logger.warning(
40
+ "The torch_xla package was detected in the python environment. PyTorch/XLA and JIT is untested,"
41
+ " no activation function will be traced with JIT."
42
+ )
43
+ except ImportError:
44
+ gelu_new = torch.jit.script(gelu_new)
45
+
46
+ ACT2FN = {
47
+ "relu": F.relu,
48
+ "swish": swish,
49
+ "gelu": gelu,
50
+ "tanh": torch.tanh,
51
+ "gelu_new": gelu_new,
52
+ }
53
+
54
+
55
+ def get_activation(activation_string):
56
+ if activation_string in ACT2FN:
57
+ return ACT2FN[activation_string]
58
+ else:
59
+ raise KeyError("function {} not found in ACT2FN mapping {}".format(activation_string, list(ACT2FN.keys())))
models/configuration_bert.py ADDED
@@ -0,0 +1,143 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # coding=utf-8
2
+ # Copyright 2018 The Google AI Language Team Authors and The HuggingFace Inc. team.
3
+ # Copyright (c) 2018, NVIDIA CORPORATION. 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
+ """ BERT model configuration """
17
+
18
+
19
+ import logging
20
+
21
+ from .configuration_utils import PretrainedConfig
22
+
23
+
24
+ logger = logging.getLogger(__name__)
25
+
26
+ BERT_PRETRAINED_CONFIG_ARCHIVE_MAP = {
27
+ "bert-base-uncased": "https://s3.amazonaws.com/models.huggingface.co/bert/bert-base-uncased-config.json",
28
+ "bert-large-uncased": "https://s3.amazonaws.com/models.huggingface.co/bert/bert-large-uncased-config.json",
29
+ "bert-base-cased": "https://s3.amazonaws.com/models.huggingface.co/bert/bert-base-cased-config.json",
30
+ "bert-large-cased": "https://s3.amazonaws.com/models.huggingface.co/bert/bert-large-cased-config.json",
31
+ "bert-base-multilingual-uncased": "https://s3.amazonaws.com/models.huggingface.co/bert/bert-base-multilingual-uncased-config.json",
32
+ "bert-base-multilingual-cased": "https://s3.amazonaws.com/models.huggingface.co/bert/bert-base-multilingual-cased-config.json",
33
+ "bert-base-chinese": "https://s3.amazonaws.com/models.huggingface.co/bert/bert-base-chinese-config.json",
34
+ "bert-base-german-cased": "https://s3.amazonaws.com/models.huggingface.co/bert/bert-base-german-cased-config.json",
35
+ "bert-large-uncased-whole-word-masking": "https://s3.amazonaws.com/models.huggingface.co/bert/bert-large-uncased-whole-word-masking-config.json",
36
+ "bert-large-cased-whole-word-masking": "https://s3.amazonaws.com/models.huggingface.co/bert/bert-large-cased-whole-word-masking-config.json",
37
+ "bert-large-uncased-whole-word-masking-finetuned-squad": "https://s3.amazonaws.com/models.huggingface.co/bert/bert-large-uncased-whole-word-masking-finetuned-squad-config.json",
38
+ "bert-large-cased-whole-word-masking-finetuned-squad": "https://s3.amazonaws.com/models.huggingface.co/bert/bert-large-cased-whole-word-masking-finetuned-squad-config.json",
39
+ "bert-base-cased-finetuned-mrpc": "https://s3.amazonaws.com/models.huggingface.co/bert/bert-base-cased-finetuned-mrpc-config.json",
40
+ "bert-base-german-dbmdz-cased": "https://s3.amazonaws.com/models.huggingface.co/bert/bert-base-german-dbmdz-cased-config.json",
41
+ "bert-base-german-dbmdz-uncased": "https://s3.amazonaws.com/models.huggingface.co/bert/bert-base-german-dbmdz-uncased-config.json",
42
+ "bert-base-japanese": "https://s3.amazonaws.com/models.huggingface.co/bert/cl-tohoku/bert-base-japanese-config.json",
43
+ "bert-base-japanese-whole-word-masking": "https://s3.amazonaws.com/models.huggingface.co/bert/cl-tohoku/bert-base-japanese-whole-word-masking-config.json",
44
+ "bert-base-japanese-char": "https://s3.amazonaws.com/models.huggingface.co/bert/cl-tohoku/bert-base-japanese-char-config.json",
45
+ "bert-base-japanese-char-whole-word-masking": "https://s3.amazonaws.com/models.huggingface.co/bert/cl-tohoku/bert-base-japanese-char-whole-word-masking-config.json",
46
+ "bert-base-finnish-cased-v1": "https://s3.amazonaws.com/models.huggingface.co/bert/TurkuNLP/bert-base-finnish-cased-v1/config.json",
47
+ "bert-base-finnish-uncased-v1": "https://s3.amazonaws.com/models.huggingface.co/bert/TurkuNLP/bert-base-finnish-uncased-v1/config.json",
48
+ "bert-base-dutch-cased": "https://s3.amazonaws.com/models.huggingface.co/bert/wietsedv/bert-base-dutch-cased/config.json",
49
+ }
50
+
51
+
52
+ class BertConfig(PretrainedConfig):
53
+ r"""
54
+ This is the configuration class to store the configuration of a :class:`~transformers.BertModel`.
55
+ It is used to instantiate an BERT model according to the specified arguments, defining the model
56
+ architecture. Instantiating a configuration with the defaults will yield a similar configuration to that of
57
+ the BERT `bert-base-uncased <https://huggingface.co/bert-base-uncased>`__ architecture.
58
+
59
+ Configuration objects inherit from :class:`~transformers.PretrainedConfig` and can be used
60
+ to control the model outputs. Read the documentation from :class:`~transformers.PretrainedConfig`
61
+ for more information.
62
+
63
+
64
+ Args:
65
+ vocab_size (:obj:`int`, optional, defaults to 30522):
66
+ Vocabulary size of the BERT model. Defines the different tokens that
67
+ can be represented by the `inputs_ids` passed to the forward method of :class:`~transformers.BertModel`.
68
+ hidden_size (:obj:`int`, optional, defaults to 768):
69
+ Dimensionality of the encoder layers and the pooler layer.
70
+ num_hidden_layers (:obj:`int`, optional, defaults to 12):
71
+ Number of hidden layers in the Transformer encoder.
72
+ num_attention_heads (:obj:`int`, optional, defaults to 12):
73
+ Number of attention heads for each attention layer in the Transformer encoder.
74
+ intermediate_size (:obj:`int`, optional, defaults to 3072):
75
+ Dimensionality of the "intermediate" (i.e., feed-forward) layer in the Transformer encoder.
76
+ hidden_act (:obj:`str` or :obj:`function`, optional, defaults to "gelu"):
77
+ The non-linear activation function (function or string) in the encoder and pooler.
78
+ If string, "gelu", "relu", "swish" and "gelu_new" are supported.
79
+ hidden_dropout_prob (:obj:`float`, optional, defaults to 0.1):
80
+ The dropout probabilitiy for all fully connected layers in the embeddings, encoder, and pooler.
81
+ attention_probs_dropout_prob (:obj:`float`, optional, defaults to 0.1):
82
+ The dropout ratio for the attention probabilities.
83
+ max_position_embeddings (:obj:`int`, optional, defaults to 512):
84
+ The maximum sequence length that this model might ever be used with.
85
+ Typically set this to something large just in case (e.g., 512 or 1024 or 2048).
86
+ type_vocab_size (:obj:`int`, optional, defaults to 2):
87
+ The vocabulary size of the `token_type_ids` passed into :class:`~transformers.BertModel`.
88
+ initializer_range (:obj:`float`, optional, defaults to 0.02):
89
+ The standard deviation of the truncated_normal_initializer for initializing all weight matrices.
90
+ layer_norm_eps (:obj:`float`, optional, defaults to 1e-12):
91
+ The epsilon used by the layer normalization layers.
92
+
93
+ Example::
94
+
95
+ from transformers import BertModel, BertConfig
96
+
97
+ # Initializing a BERT bert-base-uncased style configuration
98
+ configuration = BertConfig()
99
+
100
+ # Initializing a model from the bert-base-uncased style configuration
101
+ model = BertModel(configuration)
102
+
103
+ # Accessing the model configuration
104
+ configuration = model.config
105
+
106
+ Attributes:
107
+ pretrained_config_archive_map (Dict[str, str]):
108
+ A dictionary containing all the available pre-trained checkpoints.
109
+ """
110
+ pretrained_config_archive_map = BERT_PRETRAINED_CONFIG_ARCHIVE_MAP
111
+ model_type = "bert"
112
+
113
+ def __init__(
114
+ self,
115
+ vocab_size=30522,
116
+ hidden_size=768,
117
+ num_hidden_layers=12,
118
+ num_attention_heads=12,
119
+ intermediate_size=3072,
120
+ hidden_act="gelu",
121
+ hidden_dropout_prob=0.1,
122
+ attention_probs_dropout_prob=0.1,
123
+ max_position_embeddings=512,
124
+ type_vocab_size=2,
125
+ initializer_range=0.02,
126
+ layer_norm_eps=1e-12,
127
+ pad_token_id=0,
128
+ **kwargs
129
+ ):
130
+ super().__init__(pad_token_id=pad_token_id, **kwargs)
131
+
132
+ self.vocab_size = vocab_size
133
+ self.hidden_size = hidden_size
134
+ self.num_hidden_layers = num_hidden_layers
135
+ self.num_attention_heads = num_attention_heads
136
+ self.hidden_act = hidden_act
137
+ self.intermediate_size = intermediate_size
138
+ self.hidden_dropout_prob = hidden_dropout_prob
139
+ self.attention_probs_dropout_prob = attention_probs_dropout_prob
140
+ self.max_position_embeddings = max_position_embeddings
141
+ self.type_vocab_size = type_vocab_size
142
+ self.initializer_range = initializer_range
143
+ self.layer_norm_eps = layer_norm_eps
models/configuration_roberta.py ADDED
@@ -0,0 +1,73 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # coding=utf-8
2
+ # Copyright 2018 The Google AI Language Team Authors and The HuggingFace Inc. team.
3
+ # Copyright (c) 2018, NVIDIA CORPORATION. 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
+ """ RoBERTa configuration """
17
+
18
+
19
+ import logging
20
+
21
+ from .configuration_bert import BertConfig
22
+
23
+
24
+ logger = logging.getLogger(__name__)
25
+
26
+ ROBERTA_PRETRAINED_CONFIG_ARCHIVE_MAP = {
27
+ "roberta-base": "https://s3.amazonaws.com/models.huggingface.co/bert/roberta-base-config.json",
28
+ "roberta-large": "https://s3.amazonaws.com/models.huggingface.co/bert/roberta-large-config.json",
29
+ "roberta-large-mnli": "https://s3.amazonaws.com/models.huggingface.co/bert/roberta-large-mnli-config.json",
30
+ "distilroberta-base": "https://s3.amazonaws.com/models.huggingface.co/bert/distilroberta-base-config.json",
31
+ "roberta-base-openai-detector": "https://s3.amazonaws.com/models.huggingface.co/bert/roberta-base-openai-detector-config.json",
32
+ "roberta-large-openai-detector": "https://s3.amazonaws.com/models.huggingface.co/bert/roberta-large-openai-detector-config.json",
33
+ }
34
+
35
+
36
+ class RobertaConfig(BertConfig):
37
+ r"""
38
+ This is the configuration class to store the configuration of an :class:`~transformers.RobertaModel`.
39
+ It is used to instantiate an RoBERTa model according to the specified arguments, defining the model
40
+ architecture. Instantiating a configuration with the defaults will yield a similar configuration to that of
41
+ the BERT `bert-base-uncased <https://huggingface.co/bert-base-uncased>`__ architecture.
42
+
43
+ Configuration objects inherit from :class:`~transformers.PretrainedConfig` and can be used
44
+ to control the model outputs. Read the documentation from :class:`~transformers.PretrainedConfig`
45
+ for more information.
46
+
47
+ The :class:`~transformers.RobertaConfig` class directly inherits :class:`~transformers.BertConfig`.
48
+ It reuses the same defaults. Please check the parent class for more information.
49
+
50
+ Example::
51
+
52
+ from transformers import RobertaConfig, RobertaModel
53
+
54
+ # Initializing a RoBERTa configuration
55
+ configuration = RobertaConfig()
56
+
57
+ # Initializing a model from the configuration
58
+ model = RobertaModel(configuration)
59
+
60
+ # Accessing the model configuration
61
+ configuration = model.config
62
+
63
+ Attributes:
64
+ pretrained_config_archive_map (Dict[str, str]):
65
+ A dictionary containing all the available pre-trained checkpoints.
66
+ """
67
+ pretrained_config_archive_map = ROBERTA_PRETRAINED_CONFIG_ARCHIVE_MAP
68
+ model_type = "roberta"
69
+
70
+ def __init__(self, pad_token_id=1, bos_token_id=0, eos_token_id=2, **kwargs):
71
+ """Constructs FlaubertConfig.
72
+ """
73
+ super().__init__(pad_token_id=pad_token_id, bos_token_id=bos_token_id, eos_token_id=eos_token_id, **kwargs)
models/configuration_utils.py ADDED
@@ -0,0 +1,432 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # coding=utf-8
2
+ # Copyright 2018 The Google AI Language Team Authors and The HuggingFace Inc. team.
3
+ # Copyright (c) 2018, NVIDIA CORPORATION. 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
+ """ Configuration base class and utilities."""
17
+
18
+
19
+ import copy
20
+ import json
21
+ import logging
22
+ import os
23
+ from typing import Dict, Optional, Tuple
24
+
25
+ from .file_utils import CONFIG_NAME, cached_path, hf_bucket_url, is_remote_url
26
+
27
+
28
+ logger = logging.getLogger(__name__)
29
+
30
+
31
+ class PretrainedConfig(object):
32
+ r""" Base class for all configuration classes.
33
+ Handles a few parameters common to all models' configurations as well as methods for loading/downloading/saving configurations.
34
+
35
+ Note:
36
+ A configuration file can be loaded and saved to disk. Loading the configuration file and using this file to initialize a model does **not** load the model weights.
37
+ It only affects the model's configuration.
38
+
39
+ Class attributes (overridden by derived classes):
40
+ - ``pretrained_config_archive_map``: a python ``dict`` with `shortcut names` (string) as keys and `url` (string) of associated pretrained model configurations as values.
41
+ - ``model_type``: a string that identifies the model type, that we serialize into the JSON file, and that we use to recreate the correct object in :class:`~transformers.AutoConfig`.
42
+
43
+ Args:
44
+ finetuning_task (:obj:`string` or :obj:`None`, `optional`, defaults to :obj:`None`):
45
+ Name of the task used to fine-tune the model. This can be used when converting from an original (TensorFlow or PyTorch) checkpoint.
46
+ num_labels (:obj:`int`, `optional`, defaults to `2`):
47
+ Number of classes to use when the model is a classification model (sequences/tokens)
48
+ output_attentions (:obj:`bool`, `optional`, defaults to :obj:`False`):
49
+ Should the model returns attentions weights.
50
+ output_hidden_states (:obj:`string`, `optional`, defaults to :obj:`False`):
51
+ Should the model returns all hidden-states.
52
+ torchscript (:obj:`bool`, `optional`, defaults to :obj:`False`):
53
+ Is the model used with Torchscript (for PyTorch models).
54
+ """
55
+ pretrained_config_archive_map: Dict[str, str] = {}
56
+ model_type: str = ""
57
+
58
+ def __init__(self, **kwargs):
59
+ # Attributes with defaults
60
+ self.output_attentions = kwargs.pop("output_attentions", False)
61
+ self.output_hidden_states = kwargs.pop("output_hidden_states", False)
62
+ self.use_cache = kwargs.pop("use_cache", True) # Not used by all models
63
+ self.torchscript = kwargs.pop("torchscript", False) # Only used by PyTorch models
64
+ self.use_bfloat16 = kwargs.pop("use_bfloat16", False)
65
+ self.pruned_heads = kwargs.pop("pruned_heads", {})
66
+
67
+ # Is decoder is used in encoder-decoder models to differentiate encoder from decoder
68
+ self.is_encoder_decoder = kwargs.pop("is_encoder_decoder", False)
69
+ self.is_decoder = kwargs.pop("is_decoder", False)
70
+
71
+ # Parameters for sequence generation
72
+ self.max_length = kwargs.pop("max_length", 20)
73
+ self.min_length = kwargs.pop("min_length", 0)
74
+ self.do_sample = kwargs.pop("do_sample", False)
75
+ self.early_stopping = kwargs.pop("early_stopping", False)
76
+ self.num_beams = kwargs.pop("num_beams", 1)
77
+ self.temperature = kwargs.pop("temperature", 1.0)
78
+ self.top_k = kwargs.pop("top_k", 50)
79
+ self.top_p = kwargs.pop("top_p", 1.0)
80
+ self.repetition_penalty = kwargs.pop("repetition_penalty", 1.0)
81
+ self.length_penalty = kwargs.pop("length_penalty", 1.0)
82
+ self.no_repeat_ngram_size = kwargs.pop("no_repeat_ngram_size", 0)
83
+ self.bad_words_ids = kwargs.pop("bad_words_ids", None)
84
+ self.num_return_sequences = kwargs.pop("num_return_sequences", 1)
85
+
86
+ # Fine-tuning task arguments
87
+ self.architectures = kwargs.pop("architectures", None)
88
+ self.finetuning_task = kwargs.pop("finetuning_task", None)
89
+ self.num_labels = kwargs.pop("num_labels", 2)
90
+ self.empathy_num_labels = kwargs.pop("empathy_num_labels", 2)
91
+ self.rationale_num_labels = kwargs.pop("rationale_num_labels", 2)
92
+ self.id2label = kwargs.pop("id2label", {i: f"LABEL_{i}" for i in range(self.num_labels)})
93
+ self.id2label = dict((int(key), value) for key, value in self.id2label.items())
94
+ self.label2id = kwargs.pop("label2id", dict(zip(self.id2label.values(), self.id2label.keys())))
95
+ self.label2id = dict((key, int(value)) for key, value in self.label2id.items())
96
+
97
+ # Tokenizer arguments TODO: eventually tokenizer and models should share the same config
98
+ self.prefix = kwargs.pop("prefix", None)
99
+ self.bos_token_id = kwargs.pop("bos_token_id", None)
100
+ self.pad_token_id = kwargs.pop("pad_token_id", None)
101
+ self.eos_token_id = kwargs.pop("eos_token_id", None)
102
+ self.decoder_start_token_id = kwargs.pop("decoder_start_token_id", None)
103
+
104
+ # task specific arguments
105
+ self.task_specific_params = kwargs.pop("task_specific_params", None)
106
+
107
+ # TPU arguments
108
+ self.xla_device = kwargs.pop("xla_device", None)
109
+
110
+ # Additional attributes without default values
111
+ for key, value in kwargs.items():
112
+ try:
113
+ setattr(self, key, value)
114
+ except AttributeError as err:
115
+ logger.error("Can't set {} with value {} for {}".format(key, value, self))
116
+ raise err
117
+
118
+ @property
119
+ def num_labels(self):
120
+ return self._num_labels
121
+
122
+ @num_labels.setter
123
+ def num_labels(self, num_labels):
124
+ self._num_labels = num_labels
125
+ self.id2label = {i: "LABEL_{}".format(i) for i in range(self.num_labels)}
126
+ self.id2label = dict((int(key), value) for key, value in self.id2label.items())
127
+ self.label2id = dict(zip(self.id2label.values(), self.id2label.keys()))
128
+ self.label2id = dict((key, int(value)) for key, value in self.label2id.items())
129
+
130
+ def save_pretrained(self, save_directory):
131
+ """
132
+ Save a configuration object to the directory `save_directory`, so that it
133
+ can be re-loaded using the :func:`~transformers.PretrainedConfig.from_pretrained` class method.
134
+
135
+ Args:
136
+ save_directory (:obj:`string`):
137
+ Directory where the configuration JSON file will be saved.
138
+ """
139
+ assert os.path.isdir(
140
+ save_directory
141
+ ), "Saving path should be a directory where the model and configuration can be saved"
142
+
143
+ # If we save using the predefined names, we can load using `from_pretrained`
144
+ output_config_file = os.path.join(save_directory, CONFIG_NAME)
145
+
146
+ self.to_json_file(output_config_file, use_diff=True)
147
+ logger.info("Configuration saved in {}".format(output_config_file))
148
+
149
+ @classmethod
150
+ def from_pretrained(cls, pretrained_model_name_or_path, **kwargs) -> "PretrainedConfig":
151
+ r"""
152
+
153
+ Instantiate a :class:`~transformers.PretrainedConfig` (or a derived class) from a pre-trained model configuration.
154
+
155
+ Args:
156
+ pretrained_model_name_or_path (:obj:`string`):
157
+ either:
158
+ - a string with the `shortcut name` of a pre-trained model configuration to load from cache or
159
+ download, e.g.: ``bert-base-uncased``.
160
+ - a string with the `identifier name` of a pre-trained model configuration that was user-uploaded to
161
+ our S3, e.g.: ``dbmdz/bert-base-german-cased``.
162
+ - a path to a `directory` containing a configuration file saved using the
163
+ :func:`~transformers.PretrainedConfig.save_pretrained` method, e.g.: ``./my_model_directory/``.
164
+ - a path or url to a saved configuration JSON `file`, e.g.:
165
+ ``./my_model_directory/configuration.json``.
166
+ cache_dir (:obj:`string`, `optional`):
167
+ Path to a directory in which a downloaded pre-trained model
168
+ configuration should be cached if the standard cache should not be used.
169
+ kwargs (:obj:`Dict[str, any]`, `optional`):
170
+ The values in kwargs of any keys which are configuration attributes will be used to override the loaded
171
+ values. Behavior concerning key/value pairs whose keys are *not* configuration attributes is
172
+ controlled by the `return_unused_kwargs` keyword parameter.
173
+ force_download (:obj:`bool`, `optional`, defaults to :obj:`False`):
174
+ Force to (re-)download the model weights and configuration files and override the cached versions if they exist.
175
+ resume_download (:obj:`bool`, `optional`, defaults to :obj:`False`):
176
+ Do not delete incompletely recieved file. Attempt to resume the download if such a file exists.
177
+ proxies (:obj:`Dict`, `optional`):
178
+ A dictionary of proxy servers to use by protocol or endpoint, e.g.:
179
+ :obj:`{'http': 'foo.bar:3128', 'http://hostname': 'foo.bar:4012'}.`
180
+ The proxies are used on each request.
181
+ return_unused_kwargs: (`optional`) bool:
182
+ If False, then this function returns just the final configuration object.
183
+ If True, then this functions returns a :obj:`Tuple(config, unused_kwargs)` where `unused_kwargs` is a
184
+ dictionary consisting of the key/value pairs whose keys are not configuration attributes: ie the part
185
+ of kwargs which has not been used to update `config` and is otherwise ignored.
186
+
187
+ Returns:
188
+ :class:`PretrainedConfig`: An instance of a configuration object
189
+
190
+ Examples::
191
+
192
+ # We can't instantiate directly the base class `PretrainedConfig` so let's show the examples on a
193
+ # derived class: BertConfig
194
+ config = BertConfig.from_pretrained('bert-base-uncased') # Download configuration from S3 and cache.
195
+ config = BertConfig.from_pretrained('./test/saved_model/') # E.g. config (or model) was saved using `save_pretrained('./test/saved_model/')`
196
+ config = BertConfig.from_pretrained('./test/saved_model/my_configuration.json')
197
+ config = BertConfig.from_pretrained('bert-base-uncased', output_attention=True, foo=False)
198
+ assert config.output_attention == True
199
+ config, unused_kwargs = BertConfig.from_pretrained('bert-base-uncased', output_attention=True,
200
+ foo=False, return_unused_kwargs=True)
201
+ assert config.output_attention == True
202
+ assert unused_kwargs == {'foo': False}
203
+
204
+ """
205
+ config_dict, kwargs = cls.get_config_dict(pretrained_model_name_or_path, **kwargs)
206
+ return cls.from_dict(config_dict, **kwargs)
207
+
208
+ @classmethod
209
+ def get_config_dict(
210
+ cls, pretrained_model_name_or_path: str, pretrained_config_archive_map: Optional[Dict] = None, **kwargs
211
+ ) -> Tuple[Dict, Dict]:
212
+ """
213
+ From a `pretrained_model_name_or_path`, resolve to a dictionary of parameters, to be used
214
+ for instantiating a Config using `from_dict`.
215
+
216
+ Parameters:
217
+ pretrained_model_name_or_path (:obj:`string`):
218
+ The identifier of the pre-trained checkpoint from which we want the dictionary of parameters.
219
+ pretrained_config_archive_map: (:obj:`Dict[str, str]`, `optional`) Dict:
220
+ A map of `shortcut names` to `url`. By default, will use the current class attribute.
221
+
222
+ Returns:
223
+ :obj:`Tuple[Dict, Dict]`: The dictionary that will be used to instantiate the configuration object.
224
+
225
+ """
226
+ cache_dir = kwargs.pop("cache_dir", None)
227
+ force_download = kwargs.pop("force_download", False)
228
+ resume_download = kwargs.pop("resume_download", False)
229
+ proxies = kwargs.pop("proxies", None)
230
+ local_files_only = kwargs.pop("local_files_only", False)
231
+
232
+ if pretrained_config_archive_map is None:
233
+ pretrained_config_archive_map = cls.pretrained_config_archive_map
234
+
235
+ if pretrained_model_name_or_path in pretrained_config_archive_map:
236
+ config_file = pretrained_config_archive_map[pretrained_model_name_or_path]
237
+ elif os.path.isdir(pretrained_model_name_or_path):
238
+ config_file = os.path.join(pretrained_model_name_or_path, CONFIG_NAME)
239
+ elif os.path.isfile(pretrained_model_name_or_path) or is_remote_url(pretrained_model_name_or_path):
240
+ config_file = pretrained_model_name_or_path
241
+ else:
242
+ config_file = hf_bucket_url(pretrained_model_name_or_path, postfix=CONFIG_NAME)
243
+
244
+ try:
245
+ # Load from URL or cache if already cached
246
+ resolved_config_file = cached_path(
247
+ config_file,
248
+ cache_dir=cache_dir,
249
+ force_download=force_download,
250
+ proxies=proxies,
251
+ resume_download=resume_download,
252
+ local_files_only=local_files_only,
253
+ )
254
+ # Load config dict
255
+ if resolved_config_file is None:
256
+ raise EnvironmentError
257
+ config_dict = cls._dict_from_json_file(resolved_config_file)
258
+
259
+ except EnvironmentError:
260
+ if pretrained_model_name_or_path in pretrained_config_archive_map:
261
+ msg = "Couldn't reach server at '{}' to download pretrained model configuration file.".format(
262
+ config_file
263
+ )
264
+ else:
265
+ msg = (
266
+ "Can't load '{}'. Make sure that:\n\n"
267
+ "- '{}' is a correct model identifier listed on 'https://huggingface.co/models'\n\n"
268
+ "- or '{}' is the correct path to a directory containing a '{}' file\n\n".format(
269
+ pretrained_model_name_or_path,
270
+ pretrained_model_name_or_path,
271
+ pretrained_model_name_or_path,
272
+ CONFIG_NAME,
273
+ )
274
+ )
275
+ raise EnvironmentError(msg)
276
+
277
+ except json.JSONDecodeError:
278
+ msg = (
279
+ "Couldn't reach server at '{}' to download configuration file or "
280
+ "configuration file is not a valid JSON file. "
281
+ "Please check network or file content here: {}.".format(config_file, resolved_config_file)
282
+ )
283
+ raise EnvironmentError(msg)
284
+
285
+ if resolved_config_file == config_file:
286
+ logger.info("loading configuration file {}".format(config_file))
287
+ else:
288
+ logger.info("loading configuration file {} from cache at {}".format(config_file, resolved_config_file))
289
+
290
+ return config_dict, kwargs
291
+
292
+ @classmethod
293
+ def from_dict(cls, config_dict: Dict, **kwargs) -> "PretrainedConfig":
294
+ """
295
+ Constructs a `Config` from a Python dictionary of parameters.
296
+
297
+ Args:
298
+ config_dict (:obj:`Dict[str, any]`):
299
+ Dictionary that will be used to instantiate the configuration object. Such a dictionary can be retrieved
300
+ from a pre-trained checkpoint by leveraging the :func:`~transformers.PretrainedConfig.get_config_dict`
301
+ method.
302
+ kwargs (:obj:`Dict[str, any]`):
303
+ Additional parameters from which to initialize the configuration object.
304
+
305
+ Returns:
306
+ :class:`PretrainedConfig`: An instance of a configuration object
307
+ """
308
+ return_unused_kwargs = kwargs.pop("return_unused_kwargs", False)
309
+
310
+ config = cls(**config_dict)
311
+
312
+ if hasattr(config, "pruned_heads"):
313
+ config.pruned_heads = dict((int(key), value) for key, value in config.pruned_heads.items())
314
+
315
+ # Update config with kwargs if needed
316
+ to_remove = []
317
+ for key, value in kwargs.items():
318
+ if hasattr(config, key):
319
+ setattr(config, key, value)
320
+ to_remove.append(key)
321
+ for key in to_remove:
322
+ kwargs.pop(key, None)
323
+
324
+ logger.info("Model config %s", str(config))
325
+ if return_unused_kwargs:
326
+ return config, kwargs
327
+ else:
328
+ return config
329
+
330
+ @classmethod
331
+ def from_json_file(cls, json_file: str) -> "PretrainedConfig":
332
+ """
333
+ Constructs a `Config` from the path to a json file of parameters.
334
+
335
+ Args:
336
+ json_file (:obj:`string`):
337
+ Path to the JSON file containing the parameters.
338
+
339
+ Returns:
340
+ :class:`PretrainedConfig`: An instance of a configuration object
341
+
342
+ """
343
+ config_dict = cls._dict_from_json_file(json_file)
344
+ return cls(**config_dict)
345
+
346
+ @classmethod
347
+ def _dict_from_json_file(cls, json_file: str):
348
+ with open(json_file, "r", encoding="utf-8") as reader:
349
+ text = reader.read()
350
+ return json.loads(text)
351
+
352
+ def __eq__(self, other):
353
+ return self.__dict__ == other.__dict__
354
+
355
+ def __repr__(self):
356
+ return "{} {}".format(self.__class__.__name__, self.to_json_string())
357
+
358
+ def to_diff_dict(self):
359
+ """
360
+ Removes all attributes from config which correspond to the default
361
+ config attributes for better readability and serializes to a Python
362
+ dictionary.
363
+
364
+ Returns:
365
+ :obj:`Dict[str, any]`: Dictionary of all the attributes that make up this configuration instance,
366
+ """
367
+ config_dict = self.to_dict()
368
+
369
+ # get the default config dict
370
+ default_config_dict = PretrainedConfig().to_dict()
371
+
372
+ serializable_config_dict = {}
373
+
374
+ # only serialize values that differ from the default config
375
+ for key, value in config_dict.items():
376
+ if key not in default_config_dict or value != default_config_dict[key]:
377
+ serializable_config_dict[key] = value
378
+
379
+ return serializable_config_dict
380
+
381
+ def to_dict(self):
382
+ """
383
+ Serializes this instance to a Python dictionary.
384
+
385
+ Returns:
386
+ :obj:`Dict[str, any]`: Dictionary of all the attributes that make up this configuration instance,
387
+ """
388
+ output = copy.deepcopy(self.__dict__)
389
+ if hasattr(self.__class__, "model_type"):
390
+ output["model_type"] = self.__class__.model_type
391
+ return output
392
+
393
+ def to_json_string(self, use_diff=True):
394
+ """
395
+ Serializes this instance to a JSON string.
396
+
397
+ Args:
398
+ use_diff (:obj:`bool`):
399
+ If set to True, only the difference between the config instance and the default PretrainedConfig() is serialized to JSON string.
400
+
401
+ Returns:
402
+ :obj:`string`: String containing all the attributes that make up this configuration instance in JSON format.
403
+ """
404
+ if use_diff is True:
405
+ config_dict = self.to_diff_dict()
406
+ else:
407
+ config_dict = self.to_dict()
408
+ return json.dumps(config_dict, indent=2, sort_keys=True) + "\n"
409
+
410
+ def to_json_file(self, json_file_path, use_diff=True):
411
+ """
412
+ Save this instance to a json file.
413
+
414
+ Args:
415
+ json_file_path (:obj:`string`):
416
+ Path to the JSON file in which this configuration instance's parameters will be saved.
417
+ use_diff (:obj:`bool`):
418
+ If set to True, only the difference between the config instance and the default PretrainedConfig() is serialized to JSON file.
419
+ """
420
+ with open(json_file_path, "w", encoding="utf-8") as writer:
421
+ writer.write(self.to_json_string(use_diff=use_diff))
422
+
423
+ def update(self, config_dict: Dict):
424
+ """
425
+ Updates attributes of this class
426
+ with attributes from `config_dict`.
427
+
428
+ Args:
429
+ :obj:`Dict[str, any]`: Dictionary of attributes that shall be updated for this class.
430
+ """
431
+ for key, value in config_dict.items():
432
+ setattr(self, key, value)
models/file_utils.py ADDED
@@ -0,0 +1,488 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Utilities for working with the local dataset cache.
3
+ This file is adapted from the AllenNLP library at https://github.com/allenai/allennlp
4
+ Copyright by the AllenNLP authors.
5
+ """
6
+
7
+ import fnmatch
8
+ import json
9
+ import logging
10
+ import os
11
+ import shutil
12
+ import sys
13
+ import tarfile
14
+ import tempfile
15
+ from contextlib import contextmanager
16
+ from functools import partial, wraps
17
+ from hashlib import sha256
18
+ from typing import Optional
19
+ from urllib.parse import urlparse
20
+ from zipfile import ZipFile, is_zipfile
21
+
22
+ import requests
23
+ from filelock import FileLock
24
+ from tqdm.auto import tqdm
25
+
26
+ # from . import __version__
27
+ __version__ = "2.8.0"
28
+
29
+ logger = logging.getLogger(__name__) # pylint: disable=invalid-name
30
+
31
+ try:
32
+ USE_TF = os.environ.get("USE_TF", "AUTO").upper()
33
+ USE_TORCH = os.environ.get("USE_TORCH", "AUTO").upper()
34
+ if USE_TORCH in ("1", "ON", "YES", "AUTO") and USE_TF not in ("1", "ON", "YES"):
35
+ import torch
36
+
37
+ _torch_available = True # pylint: disable=invalid-name
38
+ logger.info("PyTorch version {} available.".format(torch.__version__))
39
+ else:
40
+ logger.info("Disabling PyTorch because USE_TF is set")
41
+ _torch_available = False
42
+ except ImportError:
43
+ _torch_available = False # pylint: disable=invalid-name
44
+
45
+ try:
46
+ USE_TF = os.environ.get("USE_TF", "AUTO").upper()
47
+ USE_TORCH = os.environ.get("USE_TORCH", "AUTO").upper()
48
+
49
+ if USE_TF in ("1", "ON", "YES", "AUTO") and USE_TORCH not in ("1", "ON", "YES"):
50
+ import tensorflow as tf
51
+
52
+ assert hasattr(tf, "__version__") and int(tf.__version__[0]) >= 2
53
+ _tf_available = True # pylint: disable=invalid-name
54
+ logger.info("TensorFlow version {} available.".format(tf.__version__))
55
+ else:
56
+ logger.info("Disabling Tensorflow because USE_TORCH is set")
57
+ _tf_available = False
58
+ except (ImportError, AssertionError):
59
+ _tf_available = False # pylint: disable=invalid-name
60
+
61
+ try:
62
+ from torch.hub import _get_torch_home
63
+
64
+ torch_cache_home = _get_torch_home()
65
+ except ImportError:
66
+ torch_cache_home = os.path.expanduser(
67
+ os.getenv("TORCH_HOME", os.path.join(os.getenv("XDG_CACHE_HOME", "~/.cache"), "torch"))
68
+ )
69
+ default_cache_path = os.path.join(torch_cache_home, "transformers")
70
+
71
+ try:
72
+ from pathlib import Path
73
+
74
+ PYTORCH_PRETRAINED_BERT_CACHE = Path(
75
+ os.getenv("PYTORCH_TRANSFORMERS_CACHE", os.getenv("PYTORCH_PRETRAINED_BERT_CACHE", default_cache_path))
76
+ )
77
+ except (AttributeError, ImportError):
78
+ PYTORCH_PRETRAINED_BERT_CACHE = os.getenv(
79
+ "PYTORCH_TRANSFORMERS_CACHE", os.getenv("PYTORCH_PRETRAINED_BERT_CACHE", default_cache_path)
80
+ )
81
+
82
+ PYTORCH_TRANSFORMERS_CACHE = PYTORCH_PRETRAINED_BERT_CACHE # Kept for backward compatibility
83
+ TRANSFORMERS_CACHE = PYTORCH_PRETRAINED_BERT_CACHE # Kept for backward compatibility
84
+
85
+ WEIGHTS_NAME = "pytorch_model.bin"
86
+ TF2_WEIGHTS_NAME = "tf_model.h5"
87
+ TF_WEIGHTS_NAME = "model.ckpt"
88
+ CONFIG_NAME = "config.json"
89
+ MODEL_CARD_NAME = "modelcard.json"
90
+
91
+
92
+ MULTIPLE_CHOICE_DUMMY_INPUTS = [[[0], [1]], [[0], [1]]]
93
+ DUMMY_INPUTS = [[7, 6, 0, 0, 1], [1, 2, 3, 0, 0], [0, 0, 0, 4, 5]]
94
+ DUMMY_MASK = [[1, 1, 1, 1, 1], [1, 1, 1, 0, 0], [0, 0, 0, 1, 1]]
95
+
96
+ S3_BUCKET_PREFIX = "https://s3.amazonaws.com/models.huggingface.co/bert"
97
+ CLOUDFRONT_DISTRIB_PREFIX = "https://d2ws9o8vfrpkyk.cloudfront.net"
98
+
99
+
100
+ def is_torch_available():
101
+ return _torch_available
102
+
103
+
104
+ def is_tf_available():
105
+ return _tf_available
106
+
107
+
108
+ def add_start_docstrings(*docstr):
109
+ def docstring_decorator(fn):
110
+ fn.__doc__ = "".join(docstr) + (fn.__doc__ if fn.__doc__ is not None else "")
111
+ return fn
112
+
113
+ return docstring_decorator
114
+
115
+
116
+ def add_start_docstrings_to_callable(*docstr):
117
+ def docstring_decorator(fn):
118
+ class_name = ":class:`~transformers.{}`".format(fn.__qualname__.split(".")[0])
119
+ intro = " The {} forward method, overrides the :func:`__call__` special method.".format(class_name)
120
+ note = r"""
121
+
122
+ .. note::
123
+ Although the recipe for forward pass needs to be defined within
124
+ this function, one should call the :class:`Module` instance afterwards
125
+ instead of this since the former takes care of running the
126
+ pre and post processing steps while the latter silently ignores them.
127
+ """
128
+ fn.__doc__ = intro + note + "".join(docstr) + (fn.__doc__ if fn.__doc__ is not None else "")
129
+ return fn
130
+
131
+ return docstring_decorator
132
+
133
+
134
+ def add_end_docstrings(*docstr):
135
+ def docstring_decorator(fn):
136
+ fn.__doc__ = fn.__doc__ + "".join(docstr)
137
+ return fn
138
+
139
+ return docstring_decorator
140
+
141
+
142
+ def is_remote_url(url_or_filename):
143
+ parsed = urlparse(url_or_filename)
144
+ return parsed.scheme in ("http", "https")
145
+
146
+
147
+ def hf_bucket_url(identifier, postfix=None, cdn=False) -> str:
148
+ endpoint = CLOUDFRONT_DISTRIB_PREFIX if cdn else S3_BUCKET_PREFIX
149
+ if postfix is None:
150
+ return "/".join((endpoint, identifier))
151
+ else:
152
+ return "/".join((endpoint, identifier, postfix))
153
+
154
+
155
+ def url_to_filename(url, etag=None):
156
+ """
157
+ Convert `url` into a hashed filename in a repeatable way.
158
+ If `etag` is specified, append its hash to the url's, delimited
159
+ by a period.
160
+ If the url ends with .h5 (Keras HDF5 weights) adds '.h5' to the name
161
+ so that TF 2.0 can identify it as a HDF5 file
162
+ (see https://github.com/tensorflow/tensorflow/blob/00fad90125b18b80fe054de1055770cfb8fe4ba3/tensorflow/python/keras/engine/network.py#L1380)
163
+ """
164
+ url_bytes = url.encode("utf-8")
165
+ url_hash = sha256(url_bytes)
166
+ filename = url_hash.hexdigest()
167
+
168
+ if etag:
169
+ etag_bytes = etag.encode("utf-8")
170
+ etag_hash = sha256(etag_bytes)
171
+ filename += "." + etag_hash.hexdigest()
172
+
173
+ if url.endswith(".h5"):
174
+ filename += ".h5"
175
+
176
+ return filename
177
+
178
+
179
+ def filename_to_url(filename, cache_dir=None):
180
+ """
181
+ Return the url and etag (which may be ``None``) stored for `filename`.
182
+ Raise ``EnvironmentError`` if `filename` or its stored metadata do not exist.
183
+ """
184
+ if cache_dir is None:
185
+ cache_dir = TRANSFORMERS_CACHE
186
+ if isinstance(cache_dir, Path):
187
+ cache_dir = str(cache_dir)
188
+
189
+ cache_path = os.path.join(cache_dir, filename)
190
+ if not os.path.exists(cache_path):
191
+ raise EnvironmentError("file {} not found".format(cache_path))
192
+
193
+ meta_path = cache_path + ".json"
194
+ if not os.path.exists(meta_path):
195
+ raise EnvironmentError("file {} not found".format(meta_path))
196
+
197
+ with open(meta_path, encoding="utf-8") as meta_file:
198
+ metadata = json.load(meta_file)
199
+ url = metadata["url"]
200
+ etag = metadata["etag"]
201
+
202
+ return url, etag
203
+
204
+
205
+ def cached_path(
206
+ url_or_filename,
207
+ cache_dir=None,
208
+ force_download=False,
209
+ proxies=None,
210
+ resume_download=False,
211
+ user_agent=None,
212
+ extract_compressed_file=False,
213
+ force_extract=False,
214
+ local_files_only=False,
215
+ ) -> Optional[str]:
216
+ """
217
+ Given something that might be a URL (or might be a local path),
218
+ determine which. If it's a URL, download the file and cache it, and
219
+ return the path to the cached file. If it's already a local path,
220
+ make sure the file exists and then return the path.
221
+ Args:
222
+ cache_dir: specify a cache directory to save the file to (overwrite the default cache dir).
223
+ force_download: if True, re-dowload the file even if it's already cached in the cache dir.
224
+ resume_download: if True, resume the download if incompletly recieved file is found.
225
+ user_agent: Optional string or dict that will be appended to the user-agent on remote requests.
226
+ extract_compressed_file: if True and the path point to a zip or tar file, extract the compressed
227
+ file in a folder along the archive.
228
+ force_extract: if True when extract_compressed_file is True and the archive was already extracted,
229
+ re-extract the archive and overide the folder where it was extracted.
230
+
231
+ Return:
232
+ None in case of non-recoverable file (non-existent or inaccessible url + no cache on disk).
233
+ Local path (string) otherwise
234
+ """
235
+ if cache_dir is None:
236
+ cache_dir = TRANSFORMERS_CACHE
237
+ if isinstance(url_or_filename, Path):
238
+ url_or_filename = str(url_or_filename)
239
+ if isinstance(cache_dir, Path):
240
+ cache_dir = str(cache_dir)
241
+
242
+ if is_remote_url(url_or_filename):
243
+ # URL, so get it from the cache (downloading if necessary)
244
+ output_path = get_from_cache(
245
+ url_or_filename,
246
+ cache_dir=cache_dir,
247
+ force_download=force_download,
248
+ proxies=proxies,
249
+ resume_download=resume_download,
250
+ user_agent=user_agent,
251
+ local_files_only=local_files_only,
252
+ )
253
+ elif os.path.exists(url_or_filename):
254
+ # File, and it exists.
255
+ output_path = url_or_filename
256
+ elif urlparse(url_or_filename).scheme == "":
257
+ # File, but it doesn't exist.
258
+ raise EnvironmentError("file {} not found".format(url_or_filename))
259
+ else:
260
+ # Something unknown
261
+ raise ValueError("unable to parse {} as a URL or as a local path".format(url_or_filename))
262
+
263
+ if extract_compressed_file:
264
+ if not is_zipfile(output_path) and not tarfile.is_tarfile(output_path):
265
+ return output_path
266
+
267
+ # Path where we extract compressed archives
268
+ # We avoid '.' in dir name and add "-extracted" at the end: "./model.zip" => "./model-zip-extracted/"
269
+ output_dir, output_file = os.path.split(output_path)
270
+ output_extract_dir_name = output_file.replace(".", "-") + "-extracted"
271
+ output_path_extracted = os.path.join(output_dir, output_extract_dir_name)
272
+
273
+ if os.path.isdir(output_path_extracted) and os.listdir(output_path_extracted) and not force_extract:
274
+ return output_path_extracted
275
+
276
+ # Prevent parallel extractions
277
+ lock_path = output_path + ".lock"
278
+ with FileLock(lock_path):
279
+ shutil.rmtree(output_path_extracted, ignore_errors=True)
280
+ os.makedirs(output_path_extracted)
281
+ if is_zipfile(output_path):
282
+ with ZipFile(output_path, "r") as zip_file:
283
+ zip_file.extractall(output_path_extracted)
284
+ zip_file.close()
285
+ elif tarfile.is_tarfile(output_path):
286
+ tar_file = tarfile.open(output_path)
287
+ tar_file.extractall(output_path_extracted)
288
+ tar_file.close()
289
+ else:
290
+ raise EnvironmentError("Archive format of {} could not be identified".format(output_path))
291
+
292
+ return output_path_extracted
293
+
294
+ return output_path
295
+
296
+
297
+ def http_get(url, temp_file, proxies=None, resume_size=0, user_agent=None):
298
+ ua = "transformers/{}; python/{}".format(__version__, sys.version.split()[0])
299
+ if is_torch_available():
300
+ ua += "; torch/{}".format(torch.__version__)
301
+ if is_tf_available():
302
+ ua += "; tensorflow/{}".format(tf.__version__)
303
+ if isinstance(user_agent, dict):
304
+ ua += "; " + "; ".join("{}/{}".format(k, v) for k, v in user_agent.items())
305
+ elif isinstance(user_agent, str):
306
+ ua += "; " + user_agent
307
+ headers = {"user-agent": ua}
308
+ if resume_size > 0:
309
+ headers["Range"] = "bytes=%d-" % (resume_size,)
310
+ response = requests.get(url, stream=True, proxies=proxies, headers=headers)
311
+ if response.status_code == 416: # Range not satisfiable
312
+ return
313
+ content_length = response.headers.get("Content-Length")
314
+ total = resume_size + int(content_length) if content_length is not None else None
315
+ progress = tqdm(
316
+ unit="B",
317
+ unit_scale=True,
318
+ total=total,
319
+ initial=resume_size,
320
+ desc="Downloading",
321
+ disable=bool(logger.getEffectiveLevel() == logging.NOTSET),
322
+ )
323
+ for chunk in response.iter_content(chunk_size=1024):
324
+ if chunk: # filter out keep-alive new chunks
325
+ progress.update(len(chunk))
326
+ temp_file.write(chunk)
327
+ progress.close()
328
+
329
+
330
+ def get_from_cache(
331
+ url,
332
+ cache_dir=None,
333
+ force_download=False,
334
+ proxies=None,
335
+ etag_timeout=10,
336
+ resume_download=False,
337
+ user_agent=None,
338
+ local_files_only=False,
339
+ ) -> Optional[str]:
340
+ """
341
+ Given a URL, look for the corresponding file in the local cache.
342
+ If it's not there, download it. Then return the path to the cached file.
343
+
344
+ Return:
345
+ None in case of non-recoverable file (non-existent or inaccessible url + no cache on disk).
346
+ Local path (string) otherwise
347
+ """
348
+ if cache_dir is None:
349
+ cache_dir = TRANSFORMERS_CACHE
350
+ if isinstance(cache_dir, Path):
351
+ cache_dir = str(cache_dir)
352
+
353
+ os.makedirs(cache_dir, exist_ok=True)
354
+
355
+ etag = None
356
+ if not local_files_only:
357
+ try:
358
+ response = requests.head(url, allow_redirects=True, proxies=proxies, timeout=etag_timeout)
359
+ if response.status_code == 200:
360
+ etag = response.headers.get("ETag")
361
+ except (EnvironmentError, requests.exceptions.Timeout):
362
+ # etag is already None
363
+ pass
364
+
365
+ filename = url_to_filename(url, etag)
366
+
367
+ # get cache path to put the file
368
+ cache_path = os.path.join(cache_dir, filename)
369
+
370
+ # etag is None = we don't have a connection, or url doesn't exist, or is otherwise inaccessible.
371
+ # try to get the last downloaded one
372
+ if etag is None:
373
+ if os.path.exists(cache_path):
374
+ return cache_path
375
+ else:
376
+ matching_files = [
377
+ file
378
+ for file in fnmatch.filter(os.listdir(cache_dir), filename + ".*")
379
+ if not file.endswith(".json") and not file.endswith(".lock")
380
+ ]
381
+ if len(matching_files) > 0:
382
+ return os.path.join(cache_dir, matching_files[-1])
383
+ else:
384
+ # If files cannot be found and local_files_only=True,
385
+ # the models might've been found if local_files_only=False
386
+ # Notify the user about that
387
+ if local_files_only:
388
+ raise ValueError(
389
+ "Cannot find the requested files in the cached path and outgoing traffic has been"
390
+ " disabled. To enable model look-ups and downloads online, set 'local_files_only'"
391
+ " to False."
392
+ )
393
+ return None
394
+
395
+ # From now on, etag is not None.
396
+ if os.path.exists(cache_path) and not force_download:
397
+ return cache_path
398
+
399
+ # Prevent parallel downloads of the same file with a lock.
400
+ lock_path = cache_path + ".lock"
401
+ with FileLock(lock_path):
402
+
403
+ # If the download just completed while the lock was activated.
404
+ if os.path.exists(cache_path) and not force_download:
405
+ # Even if returning early like here, the lock will be released.
406
+ return cache_path
407
+
408
+ if resume_download:
409
+ incomplete_path = cache_path + ".incomplete"
410
+
411
+ @contextmanager
412
+ def _resumable_file_manager():
413
+ with open(incomplete_path, "a+b") as f:
414
+ yield f
415
+
416
+ temp_file_manager = _resumable_file_manager
417
+ if os.path.exists(incomplete_path):
418
+ resume_size = os.stat(incomplete_path).st_size
419
+ else:
420
+ resume_size = 0
421
+ else:
422
+ temp_file_manager = partial(tempfile.NamedTemporaryFile, dir=cache_dir, delete=False)
423
+ resume_size = 0
424
+
425
+ # Download to temporary file, then copy to cache dir once finished.
426
+ # Otherwise you get corrupt cache entries if the download gets interrupted.
427
+ with temp_file_manager() as temp_file:
428
+ logger.info("%s not found in cache or force_download set to True, downloading to %s", url, temp_file.name)
429
+
430
+ http_get(url, temp_file, proxies=proxies, resume_size=resume_size, user_agent=user_agent)
431
+
432
+ logger.info("storing %s in cache at %s", url, cache_path)
433
+ os.replace(temp_file.name, cache_path)
434
+
435
+ logger.info("creating metadata file for %s", cache_path)
436
+ meta = {"url": url, "etag": etag}
437
+ meta_path = cache_path + ".json"
438
+ with open(meta_path, "w") as meta_file:
439
+ json.dump(meta, meta_file)
440
+
441
+ return cache_path
442
+
443
+
444
+ class cached_property(property):
445
+ """
446
+ Descriptor that mimics @property but caches output in member variable.
447
+
448
+ From tensorflow_datasets
449
+
450
+ Built-in in functools from Python 3.8.
451
+ """
452
+
453
+ def __get__(self, obj, objtype=None):
454
+ # See docs.python.org/3/howto/descriptor.html#properties
455
+ if obj is None:
456
+ return self
457
+ if self.fget is None:
458
+ raise AttributeError("unreadable attribute")
459
+ attr = "__cached_" + self.fget.__name__
460
+ cached = getattr(obj, attr, None)
461
+ if cached is None:
462
+ cached = self.fget(obj)
463
+ setattr(obj, attr, cached)
464
+ return cached
465
+
466
+
467
+ def torch_required(func):
468
+ # Chose a different decorator name than in tests so it's clear they are not the same.
469
+ @wraps(func)
470
+ def wrapper(*args, **kwargs):
471
+ if is_torch_available():
472
+ return func(*args, **kwargs)
473
+ else:
474
+ raise ImportError(f"Method `{func.__name__}` requires PyTorch.")
475
+
476
+ return wrapper
477
+
478
+
479
+ def tf_required(func):
480
+ # Chose a different decorator name than in tests so it's clear they are not the same.
481
+ @wraps(func)
482
+ def wrapper(*args, **kwargs):
483
+ if is_tf_available():
484
+ return func(*args, **kwargs)
485
+ else:
486
+ raise ImportError(f"Method `{func.__name__}` requires TF.")
487
+
488
+ return wrapper
models/modeling_bert.py ADDED
@@ -0,0 +1,1476 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # coding=utf-8
2
+ # Copyright 2018 The Google AI Language Team Authors and The HuggingFace Inc. team.
3
+ # Copyright (c) 2018, NVIDIA CORPORATION. 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 BERT model. """
17
+
18
+
19
+ import logging
20
+ import math
21
+ import os
22
+
23
+ import torch
24
+ from torch import nn
25
+ from torch.nn import CrossEntropyLoss, MSELoss
26
+
27
+ from .activations import gelu, gelu_new, swish
28
+ from .configuration_bert import BertConfig
29
+ from .file_utils import add_start_docstrings, add_start_docstrings_to_callable
30
+ from .modeling_utils import PreTrainedModel, prune_linear_layer
31
+
32
+
33
+ logger = logging.getLogger(__name__)
34
+
35
+ BERT_PRETRAINED_MODEL_ARCHIVE_MAP = {
36
+ "bert-base-uncased": "https://s3.amazonaws.com/models.huggingface.co/bert/bert-base-uncased-pytorch_model.bin",
37
+ "bert-large-uncased": "https://s3.amazonaws.com/models.huggingface.co/bert/bert-large-uncased-pytorch_model.bin",
38
+ "bert-base-cased": "https://s3.amazonaws.com/models.huggingface.co/bert/bert-base-cased-pytorch_model.bin",
39
+ "bert-large-cased": "https://s3.amazonaws.com/models.huggingface.co/bert/bert-large-cased-pytorch_model.bin",
40
+ "bert-base-multilingual-uncased": "https://s3.amazonaws.com/models.huggingface.co/bert/bert-base-multilingual-uncased-pytorch_model.bin",
41
+ "bert-base-multilingual-cased": "https://s3.amazonaws.com/models.huggingface.co/bert/bert-base-multilingual-cased-pytorch_model.bin",
42
+ "bert-base-chinese": "https://s3.amazonaws.com/models.huggingface.co/bert/bert-base-chinese-pytorch_model.bin",
43
+ "bert-base-german-cased": "https://s3.amazonaws.com/models.huggingface.co/bert/bert-base-german-cased-pytorch_model.bin",
44
+ "bert-large-uncased-whole-word-masking": "https://s3.amazonaws.com/models.huggingface.co/bert/bert-large-uncased-whole-word-masking-pytorch_model.bin",
45
+ "bert-large-cased-whole-word-masking": "https://s3.amazonaws.com/models.huggingface.co/bert/bert-large-cased-whole-word-masking-pytorch_model.bin",
46
+ "bert-large-uncased-whole-word-masking-finetuned-squad": "https://s3.amazonaws.com/models.huggingface.co/bert/bert-large-uncased-whole-word-masking-finetuned-squad-pytorch_model.bin",
47
+ "bert-large-cased-whole-word-masking-finetuned-squad": "https://s3.amazonaws.com/models.huggingface.co/bert/bert-large-cased-whole-word-masking-finetuned-squad-pytorch_model.bin",
48
+ "bert-base-cased-finetuned-mrpc": "https://s3.amazonaws.com/models.huggingface.co/bert/bert-base-cased-finetuned-mrpc-pytorch_model.bin",
49
+ "bert-base-german-dbmdz-cased": "https://s3.amazonaws.com/models.huggingface.co/bert/bert-base-german-dbmdz-cased-pytorch_model.bin",
50
+ "bert-base-german-dbmdz-uncased": "https://s3.amazonaws.com/models.huggingface.co/bert/bert-base-german-dbmdz-uncased-pytorch_model.bin",
51
+ "bert-base-japanese": "https://s3.amazonaws.com/models.huggingface.co/bert/cl-tohoku/bert-base-japanese-pytorch_model.bin",
52
+ "bert-base-japanese-whole-word-masking": "https://s3.amazonaws.com/models.huggingface.co/bert/cl-tohoku/bert-base-japanese-whole-word-masking-pytorch_model.bin",
53
+ "bert-base-japanese-char": "https://s3.amazonaws.com/models.huggingface.co/bert/cl-tohoku/bert-base-japanese-char-pytorch_model.bin",
54
+ "bert-base-japanese-char-whole-word-masking": "https://s3.amazonaws.com/models.huggingface.co/bert/cl-tohoku/bert-base-japanese-char-whole-word-masking-pytorch_model.bin",
55
+ "bert-base-finnish-cased-v1": "https://s3.amazonaws.com/models.huggingface.co/bert/TurkuNLP/bert-base-finnish-cased-v1/pytorch_model.bin",
56
+ "bert-base-finnish-uncased-v1": "https://s3.amazonaws.com/models.huggingface.co/bert/TurkuNLP/bert-base-finnish-uncased-v1/pytorch_model.bin",
57
+ "bert-base-dutch-cased": "https://s3.amazonaws.com/models.huggingface.co/bert/wietsedv/bert-base-dutch-cased/pytorch_model.bin",
58
+ }
59
+
60
+
61
+ def load_tf_weights_in_bert(model, config, tf_checkpoint_path):
62
+ """ Load tf checkpoints in a pytorch model.
63
+ """
64
+ try:
65
+ import re
66
+ import numpy as np
67
+ import tensorflow as tf
68
+ except ImportError:
69
+ logger.error(
70
+ "Loading a TensorFlow model in PyTorch, requires TensorFlow to be installed. Please see "
71
+ "https://www.tensorflow.org/install/ for installation instructions."
72
+ )
73
+ raise
74
+ tf_path = os.path.abspath(tf_checkpoint_path)
75
+ logger.info("Converting TensorFlow checkpoint from {}".format(tf_path))
76
+ # Load weights from TF model
77
+ init_vars = tf.train.list_variables(tf_path)
78
+ names = []
79
+ arrays = []
80
+ for name, shape in init_vars:
81
+ logger.info("Loading TF weight {} with shape {}".format(name, shape))
82
+ array = tf.train.load_variable(tf_path, name)
83
+ names.append(name)
84
+ arrays.append(array)
85
+
86
+ for name, array in zip(names, arrays):
87
+ name = name.split("/")
88
+ # adam_v and adam_m are variables used in AdamWeightDecayOptimizer to calculated m and v
89
+ # which are not required for using pretrained model
90
+ if any(
91
+ n in ["adam_v", "adam_m", "AdamWeightDecayOptimizer", "AdamWeightDecayOptimizer_1", "global_step"]
92
+ for n in name
93
+ ):
94
+ logger.info("Skipping {}".format("/".join(name)))
95
+ continue
96
+ pointer = model
97
+ for m_name in name:
98
+ if re.fullmatch(r"[A-Za-z]+_\d+", m_name):
99
+ scope_names = re.split(r"_(\d+)", m_name)
100
+ else:
101
+ scope_names = [m_name]
102
+ if scope_names[0] == "kernel" or scope_names[0] == "gamma":
103
+ pointer = getattr(pointer, "weight")
104
+ elif scope_names[0] == "output_bias" or scope_names[0] == "beta":
105
+ pointer = getattr(pointer, "bias")
106
+ elif scope_names[0] == "output_weights":
107
+ pointer = getattr(pointer, "weight")
108
+ elif scope_names[0] == "squad":
109
+ pointer = getattr(pointer, "classifier")
110
+ else:
111
+ try:
112
+ pointer = getattr(pointer, scope_names[0])
113
+ except AttributeError:
114
+ logger.info("Skipping {}".format("/".join(name)))
115
+ continue
116
+ if len(scope_names) >= 2:
117
+ num = int(scope_names[1])
118
+ pointer = pointer[num]
119
+ if m_name[-11:] == "_embeddings":
120
+ pointer = getattr(pointer, "weight")
121
+ elif m_name == "kernel":
122
+ array = np.transpose(array)
123
+ try:
124
+ assert pointer.shape == array.shape
125
+ except AssertionError as e:
126
+ e.args += (pointer.shape, array.shape)
127
+ raise
128
+ logger.info("Initialize PyTorch weight {}".format(name))
129
+ pointer.data = torch.from_numpy(array)
130
+ return model
131
+
132
+
133
+ def mish(x):
134
+ return x * torch.tanh(nn.functional.softplus(x))
135
+
136
+
137
+ ACT2FN = {"gelu": gelu, "relu": torch.nn.functional.relu, "swish": swish, "gelu_new": gelu_new, "mish": mish}
138
+
139
+
140
+ BertLayerNorm = torch.nn.LayerNorm
141
+
142
+
143
+ class BertEmbeddings(nn.Module):
144
+ """Construct the embeddings from word, position and token_type embeddings.
145
+ """
146
+
147
+ def __init__(self, config):
148
+ super().__init__()
149
+ self.word_embeddings = nn.Embedding(config.vocab_size, config.hidden_size, padding_idx=config.pad_token_id)
150
+ self.position_embeddings = nn.Embedding(config.max_position_embeddings, config.hidden_size)
151
+ self.token_type_embeddings = nn.Embedding(config.type_vocab_size, config.hidden_size)
152
+
153
+ # self.LayerNorm is not snake-cased to stick with TensorFlow model variable name and be able to load
154
+ # any TensorFlow checkpoint file
155
+ self.LayerNorm = BertLayerNorm(config.hidden_size, eps=config.layer_norm_eps)
156
+ self.dropout = nn.Dropout(config.hidden_dropout_prob)
157
+
158
+ def forward(self, input_ids=None, token_type_ids=None, position_ids=None, inputs_embeds=None):
159
+ if input_ids is not None:
160
+ input_shape = input_ids.size()
161
+ else:
162
+ input_shape = inputs_embeds.size()[:-1]
163
+
164
+ seq_length = input_shape[1]
165
+ device = input_ids.device if input_ids is not None else inputs_embeds.device
166
+ if position_ids is None:
167
+ position_ids = torch.arange(seq_length, dtype=torch.long, device=device)
168
+ position_ids = position_ids.unsqueeze(0).expand(input_shape)
169
+ if token_type_ids is None:
170
+ token_type_ids = torch.zeros(input_shape, dtype=torch.long, device=device)
171
+
172
+ if inputs_embeds is None:
173
+ inputs_embeds = self.word_embeddings(input_ids)
174
+ position_embeddings = self.position_embeddings(position_ids)
175
+ token_type_embeddings = self.token_type_embeddings(token_type_ids)
176
+
177
+ embeddings = inputs_embeds + position_embeddings + token_type_embeddings
178
+ embeddings = self.LayerNorm(embeddings)
179
+ embeddings = self.dropout(embeddings)
180
+ return embeddings
181
+
182
+
183
+ class BertSelfAttention(nn.Module):
184
+ def __init__(self, config):
185
+ super().__init__()
186
+ if config.hidden_size % config.num_attention_heads != 0 and not hasattr(config, "embedding_size"):
187
+ raise ValueError(
188
+ "The hidden size (%d) is not a multiple of the number of attention "
189
+ "heads (%d)" % (config.hidden_size, config.num_attention_heads)
190
+ )
191
+ self.output_attentions = config.output_attentions
192
+
193
+ self.num_attention_heads = config.num_attention_heads
194
+ self.attention_head_size = int(config.hidden_size / config.num_attention_heads)
195
+ self.all_head_size = self.num_attention_heads * self.attention_head_size
196
+
197
+ self.query = nn.Linear(config.hidden_size, self.all_head_size)
198
+ self.key = nn.Linear(config.hidden_size, self.all_head_size)
199
+ self.value = nn.Linear(config.hidden_size, self.all_head_size)
200
+
201
+ self.dropout = nn.Dropout(config.attention_probs_dropout_prob)
202
+
203
+ def transpose_for_scores(self, x):
204
+ new_x_shape = x.size()[:-1] + (self.num_attention_heads, self.attention_head_size)
205
+ x = x.view(*new_x_shape)
206
+ return x.permute(0, 2, 1, 3)
207
+
208
+ def forward(
209
+ self,
210
+ hidden_states,
211
+ attention_mask=None,
212
+ head_mask=None,
213
+ encoder_hidden_states=None,
214
+ encoder_attention_mask=None,
215
+ ):
216
+ mixed_query_layer = self.query(hidden_states)
217
+
218
+ # If this is instantiated as a cross-attention module, the keys
219
+ # and values come from an encoder; the attention mask needs to be
220
+ # such that the encoder's padding tokens are not attended to.
221
+ if encoder_hidden_states is not None:
222
+ mixed_key_layer = self.key(encoder_hidden_states)
223
+ mixed_value_layer = self.value(encoder_hidden_states)
224
+ attention_mask = encoder_attention_mask
225
+ else:
226
+ mixed_key_layer = self.key(hidden_states)
227
+ mixed_value_layer = self.value(hidden_states)
228
+
229
+ query_layer = self.transpose_for_scores(mixed_query_layer)
230
+ key_layer = self.transpose_for_scores(mixed_key_layer)
231
+ value_layer = self.transpose_for_scores(mixed_value_layer)
232
+
233
+ # Take the dot product between "query" and "key" to get the raw attention scores.
234
+ attention_scores = torch.matmul(query_layer, key_layer.transpose(-1, -2))
235
+ attention_scores = attention_scores / math.sqrt(self.attention_head_size)
236
+ if attention_mask is not None:
237
+ # Apply the attention mask is (precomputed for all layers in BertModel forward() function)
238
+ attention_scores = attention_scores + attention_mask
239
+
240
+ # Normalize the attention scores to probabilities.
241
+ attention_probs = nn.Softmax(dim=-1)(attention_scores)
242
+
243
+ # This is actually dropping out entire tokens to attend to, which might
244
+ # seem a bit unusual, but is taken from the original Transformer paper.
245
+ attention_probs = self.dropout(attention_probs)
246
+
247
+ # Mask heads if we want to
248
+ if head_mask is not None:
249
+ attention_probs = attention_probs * head_mask
250
+
251
+ context_layer = torch.matmul(attention_probs, value_layer)
252
+
253
+ context_layer = context_layer.permute(0, 2, 1, 3).contiguous()
254
+ new_context_layer_shape = context_layer.size()[:-2] + (self.all_head_size,)
255
+ context_layer = context_layer.view(*new_context_layer_shape)
256
+
257
+ outputs = (context_layer, attention_probs) if self.output_attentions else (context_layer,)
258
+ return outputs
259
+
260
+
261
+ class BertSelfOutput(nn.Module):
262
+ def __init__(self, config):
263
+ super().__init__()
264
+ self.dense = nn.Linear(config.hidden_size, config.hidden_size)
265
+ self.LayerNorm = BertLayerNorm(config.hidden_size, eps=config.layer_norm_eps)
266
+ self.dropout = nn.Dropout(config.hidden_dropout_prob)
267
+
268
+ def forward(self, hidden_states, input_tensor):
269
+ hidden_states = self.dense(hidden_states)
270
+ hidden_states = self.dropout(hidden_states)
271
+ hidden_states = self.LayerNorm(hidden_states + input_tensor)
272
+ return hidden_states
273
+
274
+
275
+ class BertAttention(nn.Module):
276
+ def __init__(self, config):
277
+ super().__init__()
278
+ self.self = BertSelfAttention(config)
279
+ self.output = BertSelfOutput(config)
280
+ self.pruned_heads = set()
281
+
282
+ def prune_heads(self, heads):
283
+ if len(heads) == 0:
284
+ return
285
+ mask = torch.ones(self.self.num_attention_heads, self.self.attention_head_size)
286
+ heads = set(heads) - self.pruned_heads # Convert to set and remove already pruned heads
287
+ for head in heads:
288
+ # Compute how many pruned heads are before the head and move the index accordingly
289
+ head = head - sum(1 if h < head else 0 for h in self.pruned_heads)
290
+ mask[head] = 0
291
+ mask = mask.view(-1).contiguous().eq(1)
292
+ index = torch.arange(len(mask))[mask].long()
293
+
294
+ # Prune linear layers
295
+ self.self.query = prune_linear_layer(self.self.query, index)
296
+ self.self.key = prune_linear_layer(self.self.key, index)
297
+ self.self.value = prune_linear_layer(self.self.value, index)
298
+ self.output.dense = prune_linear_layer(self.output.dense, index, dim=1)
299
+
300
+ # Update hyper params and store pruned heads
301
+ self.self.num_attention_heads = self.self.num_attention_heads - len(heads)
302
+ self.self.all_head_size = self.self.attention_head_size * self.self.num_attention_heads
303
+ self.pruned_heads = self.pruned_heads.union(heads)
304
+
305
+ def forward(
306
+ self,
307
+ hidden_states,
308
+ attention_mask=None,
309
+ head_mask=None,
310
+ encoder_hidden_states=None,
311
+ encoder_attention_mask=None,
312
+ ):
313
+ self_outputs = self.self(
314
+ hidden_states, attention_mask, head_mask, encoder_hidden_states, encoder_attention_mask
315
+ )
316
+ attention_output = self.output(self_outputs[0], hidden_states)
317
+ outputs = (attention_output,) + self_outputs[1:] # add attentions if we output them
318
+ return outputs
319
+
320
+
321
+ class BertIntermediate(nn.Module):
322
+ def __init__(self, config):
323
+ super().__init__()
324
+ self.dense = nn.Linear(config.hidden_size, config.intermediate_size)
325
+ if isinstance(config.hidden_act, str):
326
+ self.intermediate_act_fn = ACT2FN[config.hidden_act]
327
+ else:
328
+ self.intermediate_act_fn = config.hidden_act
329
+
330
+ def forward(self, hidden_states):
331
+ hidden_states = self.dense(hidden_states)
332
+ hidden_states = self.intermediate_act_fn(hidden_states)
333
+ return hidden_states
334
+
335
+
336
+ class BertOutput(nn.Module):
337
+ def __init__(self, config):
338
+ super().__init__()
339
+ self.dense = nn.Linear(config.intermediate_size, config.hidden_size)
340
+ self.LayerNorm = BertLayerNorm(config.hidden_size, eps=config.layer_norm_eps)
341
+ self.dropout = nn.Dropout(config.hidden_dropout_prob)
342
+
343
+ def forward(self, hidden_states, input_tensor):
344
+ hidden_states = self.dense(hidden_states)
345
+ hidden_states = self.dropout(hidden_states)
346
+ hidden_states = self.LayerNorm(hidden_states + input_tensor)
347
+ return hidden_states
348
+
349
+
350
+ class BertLayer(nn.Module):
351
+ def __init__(self, config):
352
+ super().__init__()
353
+ self.attention = BertAttention(config)
354
+ self.is_decoder = config.is_decoder
355
+ if self.is_decoder:
356
+ self.crossattention = BertAttention(config)
357
+ self.intermediate = BertIntermediate(config)
358
+ self.output = BertOutput(config)
359
+
360
+ def forward(
361
+ self,
362
+ hidden_states,
363
+ attention_mask=None,
364
+ head_mask=None,
365
+ encoder_hidden_states=None,
366
+ encoder_attention_mask=None,
367
+ ):
368
+ self_attention_outputs = self.attention(hidden_states, attention_mask, head_mask)
369
+ attention_output = self_attention_outputs[0]
370
+ outputs = self_attention_outputs[1:] # add self attentions if we output attention weights
371
+
372
+ if self.is_decoder and encoder_hidden_states is not None:
373
+ cross_attention_outputs = self.crossattention(
374
+ attention_output, attention_mask, head_mask, encoder_hidden_states, encoder_attention_mask
375
+ )
376
+ attention_output = cross_attention_outputs[0]
377
+ outputs = outputs + cross_attention_outputs[1:] # add cross attentions if we output attention weights
378
+
379
+ intermediate_output = self.intermediate(attention_output)
380
+ layer_output = self.output(intermediate_output, attention_output)
381
+ outputs = (layer_output,) + outputs
382
+ return outputs
383
+
384
+
385
+ class BertEncoder(nn.Module):
386
+ def __init__(self, config):
387
+ super().__init__()
388
+ self.output_attentions = config.output_attentions
389
+ self.output_hidden_states = config.output_hidden_states
390
+ self.layer = nn.ModuleList([BertLayer(config) for _ in range(config.num_hidden_layers)])
391
+
392
+ def forward(
393
+ self,
394
+ hidden_states,
395
+ attention_mask=None,
396
+ head_mask=None,
397
+ encoder_hidden_states=None,
398
+ encoder_attention_mask=None,
399
+ ):
400
+ all_hidden_states = ()
401
+ all_attentions = ()
402
+ for i, layer_module in enumerate(self.layer):
403
+ if self.output_hidden_states:
404
+ all_hidden_states = all_hidden_states + (hidden_states,)
405
+
406
+ layer_outputs = layer_module(
407
+ hidden_states, attention_mask, head_mask[i], encoder_hidden_states, encoder_attention_mask
408
+ )
409
+ hidden_states = layer_outputs[0]
410
+
411
+ if self.output_attentions:
412
+ all_attentions = all_attentions + (layer_outputs[1],)
413
+
414
+ # Add last layer
415
+ if self.output_hidden_states:
416
+ all_hidden_states = all_hidden_states + (hidden_states,)
417
+
418
+ outputs = (hidden_states,)
419
+ if self.output_hidden_states:
420
+ outputs = outputs + (all_hidden_states,)
421
+ if self.output_attentions:
422
+ outputs = outputs + (all_attentions,)
423
+ return outputs # last-layer hidden state, (all hidden states), (all attentions)
424
+
425
+
426
+ class BertPooler(nn.Module):
427
+ def __init__(self, config):
428
+ super().__init__()
429
+ self.dense = nn.Linear(config.hidden_size, config.hidden_size)
430
+ self.activation = nn.Tanh()
431
+
432
+ def forward(self, hidden_states):
433
+ # We "pool" the model by simply taking the hidden state corresponding
434
+ # to the first token.
435
+ first_token_tensor = hidden_states[:, 0]
436
+ pooled_output = self.dense(first_token_tensor)
437
+ pooled_output = self.activation(pooled_output)
438
+ return pooled_output
439
+
440
+
441
+ class BertPredictionHeadTransform(nn.Module):
442
+ def __init__(self, config):
443
+ super().__init__()
444
+ self.dense = nn.Linear(config.hidden_size, config.hidden_size)
445
+ if isinstance(config.hidden_act, str):
446
+ self.transform_act_fn = ACT2FN[config.hidden_act]
447
+ else:
448
+ self.transform_act_fn = config.hidden_act
449
+ self.LayerNorm = BertLayerNorm(config.hidden_size, eps=config.layer_norm_eps)
450
+
451
+ def forward(self, hidden_states):
452
+ hidden_states = self.dense(hidden_states)
453
+ hidden_states = self.transform_act_fn(hidden_states)
454
+ hidden_states = self.LayerNorm(hidden_states)
455
+ return hidden_states
456
+
457
+
458
+ class BertLMPredictionHead(nn.Module):
459
+ def __init__(self, config):
460
+ super().__init__()
461
+ self.transform = BertPredictionHeadTransform(config)
462
+
463
+ # The output weights are the same as the input embeddings, but there is
464
+ # an output-only bias for each token.
465
+ self.decoder = nn.Linear(config.hidden_size, config.vocab_size, bias=False)
466
+
467
+ self.bias = nn.Parameter(torch.zeros(config.vocab_size))
468
+
469
+ # Need a link between the two variables so that the bias is correctly resized with `resize_token_embeddings`
470
+ self.decoder.bias = self.bias
471
+
472
+ def forward(self, hidden_states):
473
+ hidden_states = self.transform(hidden_states)
474
+ hidden_states = self.decoder(hidden_states)
475
+ return hidden_states
476
+
477
+
478
+ class BertOnlyMLMHead(nn.Module):
479
+ def __init__(self, config):
480
+ super().__init__()
481
+ self.predictions = BertLMPredictionHead(config)
482
+
483
+ def forward(self, sequence_output):
484
+ prediction_scores = self.predictions(sequence_output)
485
+ return prediction_scores
486
+
487
+
488
+ class BertOnlyNSPHead(nn.Module):
489
+ def __init__(self, config):
490
+ super().__init__()
491
+ self.seq_relationship = nn.Linear(config.hidden_size, 2)
492
+
493
+ def forward(self, pooled_output):
494
+ seq_relationship_score = self.seq_relationship(pooled_output)
495
+ return seq_relationship_score
496
+
497
+
498
+ class BertPreTrainingHeads(nn.Module):
499
+ def __init__(self, config):
500
+ super().__init__()
501
+ self.predictions = BertLMPredictionHead(config)
502
+ self.seq_relationship = nn.Linear(config.hidden_size, 2)
503
+
504
+ def forward(self, sequence_output, pooled_output):
505
+ prediction_scores = self.predictions(sequence_output)
506
+ seq_relationship_score = self.seq_relationship(pooled_output)
507
+ return prediction_scores, seq_relationship_score
508
+
509
+
510
+ class BertPreTrainedModel(PreTrainedModel):
511
+ """ An abstract class to handle weights initialization and
512
+ a simple interface for downloading and loading pretrained models.
513
+ """
514
+
515
+ config_class = BertConfig
516
+ pretrained_model_archive_map = BERT_PRETRAINED_MODEL_ARCHIVE_MAP
517
+ load_tf_weights = load_tf_weights_in_bert
518
+ base_model_prefix = "bert"
519
+
520
+ def _init_weights(self, module):
521
+ """ Initialize the weights """
522
+ if isinstance(module, (nn.Linear, nn.Embedding)):
523
+ # Slightly different from the TF version which uses truncated_normal for initialization
524
+ # cf https://github.com/pytorch/pytorch/pull/5617
525
+ module.weight.data.normal_(mean=0.0, std=self.config.initializer_range)
526
+ elif isinstance(module, BertLayerNorm):
527
+ module.bias.data.zero_()
528
+ module.weight.data.fill_(1.0)
529
+ if isinstance(module, nn.Linear) and module.bias is not None:
530
+ module.bias.data.zero_()
531
+
532
+
533
+ BERT_START_DOCSTRING = r"""
534
+ This model is a PyTorch `torch.nn.Module <https://pytorch.org/docs/stable/nn.html#torch.nn.Module>`_ sub-class.
535
+ Use it as a regular PyTorch Module and refer to the PyTorch documentation for all matter related to general
536
+ usage and behavior.
537
+
538
+ Parameters:
539
+ config (:class:`~transformers.BertConfig`): Model configuration class with all the parameters of the model.
540
+ Initializing with a config file does not load the weights associated with the model, only the configuration.
541
+ Check out the :meth:`~transformers.PreTrainedModel.from_pretrained` method to load the model weights.
542
+ """
543
+
544
+ BERT_INPUTS_DOCSTRING = r"""
545
+ Args:
546
+ input_ids (:obj:`torch.LongTensor` of shape :obj:`(batch_size, sequence_length)`):
547
+ Indices of input sequence tokens in the vocabulary.
548
+
549
+ Indices can be obtained using :class:`transformers.BertTokenizer`.
550
+ See :func:`transformers.PreTrainedTokenizer.encode` and
551
+ :func:`transformers.PreTrainedTokenizer.encode_plus` for details.
552
+
553
+ `What are input IDs? <../glossary.html#input-ids>`__
554
+ attention_mask (:obj:`torch.FloatTensor` of shape :obj:`(batch_size, sequence_length)`, `optional`, defaults to :obj:`None`):
555
+ Mask to avoid performing attention on padding token indices.
556
+ Mask values selected in ``[0, 1]``:
557
+ ``1`` for tokens that are NOT MASKED, ``0`` for MASKED tokens.
558
+
559
+ `What are attention masks? <../glossary.html#attention-mask>`__
560
+ token_type_ids (:obj:`torch.LongTensor` of shape :obj:`(batch_size, sequence_length)`, `optional`, defaults to :obj:`None`):
561
+ Segment token indices to indicate first and second portions of the inputs.
562
+ Indices are selected in ``[0, 1]``: ``0`` corresponds to a `sentence A` token, ``1``
563
+ corresponds to a `sentence B` token
564
+
565
+ `What are token type IDs? <../glossary.html#token-type-ids>`_
566
+ position_ids (:obj:`torch.LongTensor` of shape :obj:`(batch_size, sequence_length)`, `optional`, defaults to :obj:`None`):
567
+ Indices of positions of each input sequence tokens in the position embeddings.
568
+ Selected in the range ``[0, config.max_position_embeddings - 1]``.
569
+
570
+ `What are position IDs? <../glossary.html#position-ids>`_
571
+ head_mask (:obj:`torch.FloatTensor` of shape :obj:`(num_heads,)` or :obj:`(num_layers, num_heads)`, `optional`, defaults to :obj:`None`):
572
+ Mask to nullify selected heads of the self-attention modules.
573
+ Mask values selected in ``[0, 1]``:
574
+ :obj:`1` indicates the head is **not masked**, :obj:`0` indicates the head is **masked**.
575
+ inputs_embeds (:obj:`torch.FloatTensor` of shape :obj:`(batch_size, sequence_length, hidden_size)`, `optional`, defaults to :obj:`None`):
576
+ Optionally, instead of passing :obj:`input_ids` you can choose to directly pass an embedded representation.
577
+ This is useful if you want more control over how to convert `input_ids` indices into associated vectors
578
+ than the model's internal embedding lookup matrix.
579
+ encoder_hidden_states (:obj:`torch.FloatTensor` of shape :obj:`(batch_size, sequence_length, hidden_size)`, `optional`, defaults to :obj:`None`):
580
+ Sequence of hidden-states at the output of the last layer of the encoder. Used in the cross-attention
581
+ if the model is configured as a decoder.
582
+ encoder_attention_mask (:obj:`torch.FloatTensor` of shape :obj:`(batch_size, sequence_length)`, `optional`, defaults to :obj:`None`):
583
+ Mask to avoid performing attention on the padding token indices of the encoder input. This mask
584
+ is used in the cross-attention if the model is configured as a decoder.
585
+ Mask values selected in ``[0, 1]``:
586
+ ``1`` for tokens that are NOT MASKED, ``0`` for MASKED tokens.
587
+ """
588
+
589
+
590
+ @add_start_docstrings(
591
+ "The bare Bert Model transformer outputting raw hidden-states without any specific head on top.",
592
+ BERT_START_DOCSTRING,
593
+ )
594
+ class BertModel(BertPreTrainedModel):
595
+ """
596
+
597
+ The model can behave as an encoder (with only self-attention) as well
598
+ as a decoder, in which case a layer of cross-attention is added between
599
+ the self-attention layers, following the architecture described in `Attention is all you need`_ by Ashish Vaswani,
600
+ Noam Shazeer, Niki Parmar, Jakob Uszkoreit, Llion Jones, Aidan N. Gomez, Lukasz Kaiser and Illia Polosukhin.
601
+
602
+ To behave as an decoder the model needs to be initialized with the
603
+ :obj:`is_decoder` argument of the configuration set to :obj:`True`; an
604
+ :obj:`encoder_hidden_states` is expected as an input to the forward pass.
605
+
606
+ .. _`Attention is all you need`:
607
+ https://arxiv.org/abs/1706.03762
608
+
609
+ """
610
+
611
+ def __init__(self, config):
612
+ super().__init__(config)
613
+ self.config = config
614
+
615
+ self.embeddings = BertEmbeddings(config)
616
+ self.encoder = BertEncoder(config)
617
+ self.pooler = BertPooler(config)
618
+
619
+ self.init_weights()
620
+
621
+ def get_input_embeddings(self):
622
+ return self.embeddings.word_embeddings
623
+
624
+ def set_input_embeddings(self, value):
625
+ self.embeddings.word_embeddings = value
626
+
627
+ def _prune_heads(self, heads_to_prune):
628
+ """ Prunes heads of the model.
629
+ heads_to_prune: dict of {layer_num: list of heads to prune in this layer}
630
+ See base class PreTrainedModel
631
+ """
632
+ for layer, heads in heads_to_prune.items():
633
+ self.encoder.layer[layer].attention.prune_heads(heads)
634
+
635
+ @add_start_docstrings_to_callable(BERT_INPUTS_DOCSTRING)
636
+ def forward(
637
+ self,
638
+ input_ids=None,
639
+ attention_mask=None,
640
+ token_type_ids=None,
641
+ position_ids=None,
642
+ head_mask=None,
643
+ inputs_embeds=None,
644
+ encoder_hidden_states=None,
645
+ encoder_attention_mask=None,
646
+ ):
647
+ r"""
648
+ Return:
649
+ :obj:`tuple(torch.FloatTensor)` comprising various elements depending on the configuration (:class:`~transformers.BertConfig`) and inputs:
650
+ last_hidden_state (:obj:`torch.FloatTensor` of shape :obj:`(batch_size, sequence_length, hidden_size)`):
651
+ Sequence of hidden-states at the output of the last layer of the model.
652
+ pooler_output (:obj:`torch.FloatTensor`: of shape :obj:`(batch_size, hidden_size)`):
653
+ Last layer hidden-state of the first token of the sequence (classification token)
654
+ further processed by a Linear layer and a Tanh activation function. The Linear
655
+ layer weights are trained from the next sentence prediction (classification)
656
+ objective during pre-training.
657
+
658
+ This output is usually *not* a good summary
659
+ of the semantic content of the input, you're often better with averaging or pooling
660
+ the sequence of hidden-states for the whole input sequence.
661
+ hidden_states (:obj:`tuple(torch.FloatTensor)`, `optional`, returned when ``config.output_hidden_states=True``):
662
+ Tuple of :obj:`torch.FloatTensor` (one for the output of the embeddings + one for the output of each layer)
663
+ of shape :obj:`(batch_size, sequence_length, hidden_size)`.
664
+
665
+ Hidden-states of the model at the output of each layer plus the initial embedding outputs.
666
+ attentions (:obj:`tuple(torch.FloatTensor)`, `optional`, returned when ``config.output_attentions=True``):
667
+ Tuple of :obj:`torch.FloatTensor` (one for each layer) of shape
668
+ :obj:`(batch_size, num_heads, sequence_length, sequence_length)`.
669
+
670
+ Attentions weights after the attention softmax, used to compute the weighted average in the self-attention
671
+ heads.
672
+
673
+ Examples::
674
+
675
+ from transformers import BertModel, BertTokenizer
676
+ import torch
677
+
678
+ tokenizer = BertTokenizer.from_pretrained('bert-base-uncased')
679
+ model = BertModel.from_pretrained('bert-base-uncased')
680
+
681
+ input_ids = torch.tensor(tokenizer.encode("Hello, my dog is cute", add_special_tokens=True)).unsqueeze(0) # Batch size 1
682
+ outputs = model(input_ids)
683
+
684
+ last_hidden_states = outputs[0] # The last hidden-state is the first element of the output tuple
685
+
686
+ """
687
+
688
+ if input_ids is not None and inputs_embeds is not None:
689
+ raise ValueError("You cannot specify both input_ids and inputs_embeds at the same time")
690
+ elif input_ids is not None:
691
+ input_shape = input_ids.size()
692
+ elif inputs_embeds is not None:
693
+ input_shape = inputs_embeds.size()[:-1]
694
+ else:
695
+ raise ValueError("You have to specify either input_ids or inputs_embeds")
696
+
697
+ device = input_ids.device if input_ids is not None else inputs_embeds.device
698
+
699
+ if attention_mask is None:
700
+ attention_mask = torch.ones(input_shape, device=device)
701
+ if token_type_ids is None:
702
+ token_type_ids = torch.zeros(input_shape, dtype=torch.long, device=device)
703
+
704
+ # We can provide a self-attention mask of dimensions [batch_size, from_seq_length, to_seq_length]
705
+ # ourselves in which case we just need to make it broadcastable to all heads.
706
+ extended_attention_mask: torch.Tensor = self.get_extended_attention_mask(
707
+ attention_mask, input_shape, self.device
708
+ )
709
+
710
+ # If a 2D ou 3D attention mask is provided for the cross-attention
711
+ # we need to make broadcastabe to [batch_size, num_heads, seq_length, seq_length]
712
+ if self.config.is_decoder and encoder_hidden_states is not None:
713
+ encoder_batch_size, encoder_sequence_length, _ = encoder_hidden_states.size()
714
+ encoder_hidden_shape = (encoder_batch_size, encoder_sequence_length)
715
+ if encoder_attention_mask is None:
716
+ encoder_attention_mask = torch.ones(encoder_hidden_shape, device=device)
717
+ encoder_extended_attention_mask = self.invert_attention_mask(encoder_attention_mask)
718
+ else:
719
+ encoder_extended_attention_mask = None
720
+
721
+ # Prepare head mask if needed
722
+ # 1.0 in head_mask indicate we keep the head
723
+ # attention_probs has shape bsz x n_heads x N x N
724
+ # input head_mask has shape [num_heads] or [num_hidden_layers x num_heads]
725
+ # and head_mask is converted to shape [num_hidden_layers x batch x num_heads x seq_length x seq_length]
726
+ head_mask = self.get_head_mask(head_mask, self.config.num_hidden_layers)
727
+
728
+ embedding_output = self.embeddings(
729
+ input_ids=input_ids, position_ids=position_ids, token_type_ids=token_type_ids, inputs_embeds=inputs_embeds
730
+ )
731
+ encoder_outputs = self.encoder(
732
+ embedding_output,
733
+ attention_mask=extended_attention_mask,
734
+ head_mask=head_mask,
735
+ encoder_hidden_states=encoder_hidden_states,
736
+ encoder_attention_mask=encoder_extended_attention_mask,
737
+ )
738
+ sequence_output = encoder_outputs[0]
739
+ pooled_output = self.pooler(sequence_output)
740
+
741
+ outputs = (sequence_output, pooled_output,) + encoder_outputs[
742
+ 1:
743
+ ] # add hidden_states and attentions if they are here
744
+ return outputs # sequence_output, pooled_output, (hidden_states), (attentions)
745
+
746
+
747
+ @add_start_docstrings(
748
+ """Bert Model with two heads on top as done during the pre-training: a `masked language modeling` head and
749
+ a `next sentence prediction (classification)` head. """,
750
+ BERT_START_DOCSTRING,
751
+ )
752
+ class BertForPreTraining(BertPreTrainedModel):
753
+ def __init__(self, config):
754
+ super().__init__(config)
755
+
756
+ self.bert = BertModel(config)
757
+ self.cls = BertPreTrainingHeads(config)
758
+
759
+ self.init_weights()
760
+
761
+ def get_output_embeddings(self):
762
+ return self.cls.predictions.decoder
763
+
764
+ @add_start_docstrings_to_callable(BERT_INPUTS_DOCSTRING)
765
+ def forward(
766
+ self,
767
+ input_ids=None,
768
+ attention_mask=None,
769
+ token_type_ids=None,
770
+ position_ids=None,
771
+ head_mask=None,
772
+ inputs_embeds=None,
773
+ masked_lm_labels=None,
774
+ next_sentence_label=None,
775
+ ):
776
+ r"""
777
+ masked_lm_labels (``torch.LongTensor`` of shape ``(batch_size, sequence_length)``, `optional`, defaults to :obj:`None`):
778
+ Labels for computing the masked language modeling loss.
779
+ Indices should be in ``[-100, 0, ..., config.vocab_size]`` (see ``input_ids`` docstring)
780
+ Tokens with indices set to ``-100`` are ignored (masked), the loss is only computed for the tokens with labels
781
+ in ``[0, ..., config.vocab_size]``
782
+ next_sentence_label (``torch.LongTensor`` of shape ``(batch_size,)``, `optional`, defaults to :obj:`None`):
783
+ Labels for computing the next sequence prediction (classification) loss. Input should be a sequence pair (see :obj:`input_ids` docstring)
784
+ Indices should be in ``[0, 1]``.
785
+ ``0`` indicates sequence B is a continuation of sequence A,
786
+ ``1`` indicates sequence B is a random sequence.
787
+
788
+ Returns:
789
+ :obj:`tuple(torch.FloatTensor)` comprising various elements depending on the configuration (:class:`~transformers.BertConfig`) and inputs:
790
+ loss (`optional`, returned when ``masked_lm_labels`` is provided) ``torch.FloatTensor`` of shape ``(1,)``:
791
+ Total loss as the sum of the masked language modeling loss and the next sequence prediction (classification) loss.
792
+ prediction_scores (:obj:`torch.FloatTensor` of shape :obj:`(batch_size, sequence_length, config.vocab_size)`)
793
+ Prediction scores of the language modeling head (scores for each vocabulary token before SoftMax).
794
+ seq_relationship_scores (:obj:`torch.FloatTensor` of shape :obj:`(batch_size, 2)`):
795
+ Prediction scores of the next sequence prediction (classification) head (scores of True/False
796
+ continuation before SoftMax).
797
+ hidden_states (:obj:`tuple(torch.FloatTensor)`, `optional`, returned when :obj:`config.output_hidden_states=True`):
798
+ Tuple of :obj:`torch.FloatTensor` (one for the output of the embeddings + one for the output of each layer)
799
+ of shape :obj:`(batch_size, sequence_length, hidden_size)`.
800
+
801
+ Hidden-states of the model at the output of each layer plus the initial embedding outputs.
802
+ attentions (:obj:`tuple(torch.FloatTensor)`, `optional`, returned when ``config.output_attentions=True``):
803
+ Tuple of :obj:`torch.FloatTensor` (one for each layer) of shape
804
+ :obj:`(batch_size, num_heads, sequence_length, sequence_length)`.
805
+
806
+ Attentions weights after the attention softmax, used to compute the weighted average in the self-attention
807
+ heads.
808
+
809
+
810
+ Examples::
811
+
812
+ from transformers import BertTokenizer, BertForPreTraining
813
+ import torch
814
+
815
+ tokenizer = BertTokenizer.from_pretrained('bert-base-uncased')
816
+ model = BertForPreTraining.from_pretrained('bert-base-uncased')
817
+
818
+ input_ids = torch.tensor(tokenizer.encode("Hello, my dog is cute", add_special_tokens=True)).unsqueeze(0) # Batch size 1
819
+ outputs = model(input_ids)
820
+
821
+ prediction_scores, seq_relationship_scores = outputs[:2]
822
+
823
+ """
824
+
825
+ outputs = self.bert(
826
+ input_ids,
827
+ attention_mask=attention_mask,
828
+ token_type_ids=token_type_ids,
829
+ position_ids=position_ids,
830
+ head_mask=head_mask,
831
+ inputs_embeds=inputs_embeds,
832
+ )
833
+
834
+ sequence_output, pooled_output = outputs[:2]
835
+ prediction_scores, seq_relationship_score = self.cls(sequence_output, pooled_output)
836
+
837
+ outputs = (prediction_scores, seq_relationship_score,) + outputs[
838
+ 2:
839
+ ] # add hidden states and attention if they are here
840
+
841
+ if masked_lm_labels is not None and next_sentence_label is not None:
842
+ loss_fct = CrossEntropyLoss()
843
+ masked_lm_loss = loss_fct(prediction_scores.view(-1, self.config.vocab_size), masked_lm_labels.view(-1))
844
+ next_sentence_loss = loss_fct(seq_relationship_score.view(-1, 2), next_sentence_label.view(-1))
845
+ total_loss = masked_lm_loss + next_sentence_loss
846
+ outputs = (total_loss,) + outputs
847
+
848
+ return outputs # (loss), prediction_scores, seq_relationship_score, (hidden_states), (attentions)
849
+
850
+
851
+ @add_start_docstrings("""Bert Model with a `language modeling` head on top. """, BERT_START_DOCSTRING)
852
+ class BertForMaskedLM(BertPreTrainedModel):
853
+ def __init__(self, config):
854
+ super().__init__(config)
855
+
856
+ self.bert = BertModel(config)
857
+ self.cls = BertOnlyMLMHead(config)
858
+
859
+ self.init_weights()
860
+
861
+ def get_output_embeddings(self):
862
+ return self.cls.predictions.decoder
863
+
864
+ @add_start_docstrings_to_callable(BERT_INPUTS_DOCSTRING)
865
+ def forward(
866
+ self,
867
+ input_ids=None,
868
+ attention_mask=None,
869
+ token_type_ids=None,
870
+ position_ids=None,
871
+ head_mask=None,
872
+ inputs_embeds=None,
873
+ masked_lm_labels=None,
874
+ encoder_hidden_states=None,
875
+ encoder_attention_mask=None,
876
+ lm_labels=None,
877
+ ):
878
+ r"""
879
+ masked_lm_labels (:obj:`torch.LongTensor` of shape :obj:`(batch_size, sequence_length)`, `optional`, defaults to :obj:`None`):
880
+ Labels for computing the masked language modeling loss.
881
+ Indices should be in ``[-100, 0, ..., config.vocab_size]`` (see ``input_ids`` docstring)
882
+ Tokens with indices set to ``-100`` are ignored (masked), the loss is only computed for the tokens with labels
883
+ in ``[0, ..., config.vocab_size]``
884
+ lm_labels (:obj:`torch.LongTensor` of shape :obj:`(batch_size, sequence_length)`, `optional`, defaults to :obj:`None`):
885
+ Labels for computing the left-to-right language modeling loss (next word prediction).
886
+ Indices should be in ``[-100, 0, ..., config.vocab_size]`` (see ``input_ids`` docstring)
887
+ Tokens with indices set to ``-100`` are ignored (masked), the loss is only computed for the tokens with labels
888
+ in ``[0, ..., config.vocab_size]``
889
+
890
+ Returns:
891
+ :obj:`tuple(torch.FloatTensor)` comprising various elements depending on the configuration (:class:`~transformers.BertConfig`) and inputs:
892
+ masked_lm_loss (`optional`, returned when ``masked_lm_labels`` is provided) ``torch.FloatTensor`` of shape ``(1,)``:
893
+ Masked language modeling loss.
894
+ ltr_lm_loss (:obj:`torch.FloatTensor` of shape :obj:`(1,)`, `optional`, returned when :obj:`lm_labels` is provided):
895
+ Next token prediction loss.
896
+ prediction_scores (:obj:`torch.FloatTensor` of shape :obj:`(batch_size, sequence_length, config.vocab_size)`)
897
+ Prediction scores of the language modeling head (scores for each vocabulary token before SoftMax).
898
+ hidden_states (:obj:`tuple(torch.FloatTensor)`, `optional`, returned when ``config.output_hidden_states=True``):
899
+ Tuple of :obj:`torch.FloatTensor` (one for the output of the embeddings + one for the output of each layer)
900
+ of shape :obj:`(batch_size, sequence_length, hidden_size)`.
901
+
902
+ Hidden-states of the model at the output of each layer plus the initial embedding outputs.
903
+ attentions (:obj:`tuple(torch.FloatTensor)`, `optional`, returned when ``config.output_attentions=True``):
904
+ Tuple of :obj:`torch.FloatTensor` (one for each layer) of shape
905
+ :obj:`(batch_size, num_heads, sequence_length, sequence_length)`.
906
+
907
+ Attentions weights after the attention softmax, used to compute the weighted average in the self-attention
908
+ heads.
909
+
910
+ Examples::
911
+
912
+ from transformers import BertTokenizer, BertForMaskedLM
913
+ import torch
914
+
915
+ tokenizer = BertTokenizer.from_pretrained('bert-base-uncased')
916
+ model = BertForMaskedLM.from_pretrained('bert-base-uncased')
917
+
918
+ input_ids = torch.tensor(tokenizer.encode("Hello, my dog is cute", add_special_tokens=True)).unsqueeze(0) # Batch size 1
919
+ outputs = model(input_ids, masked_lm_labels=input_ids)
920
+
921
+ loss, prediction_scores = outputs[:2]
922
+
923
+ """
924
+
925
+ outputs = self.bert(
926
+ input_ids,
927
+ attention_mask=attention_mask,
928
+ token_type_ids=token_type_ids,
929
+ position_ids=position_ids,
930
+ head_mask=head_mask,
931
+ inputs_embeds=inputs_embeds,
932
+ encoder_hidden_states=encoder_hidden_states,
933
+ encoder_attention_mask=encoder_attention_mask,
934
+ )
935
+
936
+ sequence_output = outputs[0]
937
+ prediction_scores = self.cls(sequence_output)
938
+
939
+ outputs = (prediction_scores,) + outputs[2:] # Add hidden states and attention if they are here
940
+
941
+ # Although this may seem awkward, BertForMaskedLM supports two scenarios:
942
+ # 1. If a tensor that contains the indices of masked labels is provided,
943
+ # the cross-entropy is the MLM cross-entropy that measures the likelihood
944
+ # of predictions for masked words.
945
+ # 2. If `lm_labels` is provided we are in a causal scenario where we
946
+ # try to predict the next token for each input in the decoder.
947
+ if masked_lm_labels is not None:
948
+ loss_fct = CrossEntropyLoss() # -100 index = padding token
949
+ masked_lm_loss = loss_fct(prediction_scores.view(-1, self.config.vocab_size), masked_lm_labels.view(-1))
950
+ outputs = (masked_lm_loss,) + outputs
951
+
952
+ if lm_labels is not None:
953
+ # we are doing next-token prediction; shift prediction scores and input ids by one
954
+ prediction_scores = prediction_scores[:, :-1, :].contiguous()
955
+ lm_labels = lm_labels[:, 1:].contiguous()
956
+ loss_fct = CrossEntropyLoss()
957
+ ltr_lm_loss = loss_fct(prediction_scores.view(-1, self.config.vocab_size), lm_labels.view(-1))
958
+ outputs = (ltr_lm_loss,) + outputs
959
+
960
+ return outputs # (ltr_lm_loss), (masked_lm_loss), prediction_scores, (hidden_states), (attentions)
961
+
962
+ def prepare_inputs_for_generation(self, input_ids, attention_mask=None, **model_kwargs):
963
+ input_shape = input_ids.shape
964
+ effective_batch_size = input_shape[0]
965
+
966
+ # if model is used as a decoder in encoder-decoder model, the decoder attention mask is created on the fly
967
+ if attention_mask is None:
968
+ attention_mask = input_ids.new_ones(input_shape)
969
+
970
+ # if model is does not use a causal mask then add a dummy token
971
+ if self.config.is_decoder is False:
972
+ assert self.config.pad_token_id is not None, "The PAD token should be defined for generation"
973
+ attention_mask = torch.cat(
974
+ [attention_mask, attention_mask.new_zeros((attention_mask.shape[0], 1))], dim=-1
975
+ )
976
+
977
+ dummy_token = torch.full(
978
+ (effective_batch_size, 1), self.config.pad_token_id, dtype=torch.long, device=input_ids.device
979
+ )
980
+ input_ids = torch.cat([input_ids, dummy_token], dim=1)
981
+
982
+ return {"input_ids": input_ids, "attention_mask": attention_mask}
983
+
984
+
985
+ @add_start_docstrings(
986
+ """Bert Model with a `next sentence prediction (classification)` head on top. """, BERT_START_DOCSTRING,
987
+ )
988
+ class BertForNextSentencePrediction(BertPreTrainedModel):
989
+ def __init__(self, config):
990
+ super().__init__(config)
991
+
992
+ self.bert = BertModel(config)
993
+ self.cls = BertOnlyNSPHead(config)
994
+
995
+ self.init_weights()
996
+
997
+ @add_start_docstrings_to_callable(BERT_INPUTS_DOCSTRING)
998
+ def forward(
999
+ self,
1000
+ input_ids=None,
1001
+ attention_mask=None,
1002
+ token_type_ids=None,
1003
+ position_ids=None,
1004
+ head_mask=None,
1005
+ inputs_embeds=None,
1006
+ next_sentence_label=None,
1007
+ ):
1008
+ r"""
1009
+ next_sentence_label (:obj:`torch.LongTensor` of shape :obj:`(batch_size,)`, `optional`, defaults to :obj:`None`):
1010
+ Labels for computing the next sequence prediction (classification) loss. Input should be a sequence pair (see ``input_ids`` docstring)
1011
+ Indices should be in ``[0, 1]``.
1012
+ ``0`` indicates sequence B is a continuation of sequence A,
1013
+ ``1`` indicates sequence B is a random sequence.
1014
+
1015
+ Returns:
1016
+ :obj:`tuple(torch.FloatTensor)` comprising various elements depending on the configuration (:class:`~transformers.BertConfig`) and inputs:
1017
+ loss (:obj:`torch.FloatTensor` of shape :obj:`(1,)`, `optional`, returned when :obj:`next_sentence_label` is provided):
1018
+ Next sequence prediction (classification) loss.
1019
+ seq_relationship_scores (:obj:`torch.FloatTensor` of shape :obj:`(batch_size, 2)`):
1020
+ Prediction scores of the next sequence prediction (classification) head (scores of True/False continuation before SoftMax).
1021
+ hidden_states (:obj:`tuple(torch.FloatTensor)`, `optional`, returned when ``config.output_hidden_states=True``):
1022
+ Tuple of :obj:`torch.FloatTensor` (one for the output of the embeddings + one for the output of each layer)
1023
+ of shape :obj:`(batch_size, sequence_length, hidden_size)`.
1024
+
1025
+ Hidden-states of the model at the output of each layer plus the initial embedding outputs.
1026
+ attentions (:obj:`tuple(torch.FloatTensor)`, `optional`, returned when ``config.output_attentions=True``):
1027
+ Tuple of :obj:`torch.FloatTensor` (one for each layer) of shape
1028
+ :obj:`(batch_size, num_heads, sequence_length, sequence_length)`.
1029
+
1030
+ Attentions weights after the attention softmax, used to compute the weighted average in the self-attention
1031
+ heads.
1032
+
1033
+ Examples::
1034
+
1035
+ from transformers import BertTokenizer, BertForNextSentencePrediction
1036
+ import torch
1037
+
1038
+ tokenizer = BertTokenizer.from_pretrained('bert-base-uncased')
1039
+ model = BertForNextSentencePrediction.from_pretrained('bert-base-uncased')
1040
+
1041
+ input_ids = torch.tensor(tokenizer.encode("Hello, my dog is cute", add_special_tokens=True)).unsqueeze(0) # Batch size 1
1042
+ outputs = model(input_ids)
1043
+
1044
+ seq_relationship_scores = outputs[0]
1045
+
1046
+ """
1047
+
1048
+ outputs = self.bert(
1049
+ input_ids,
1050
+ attention_mask=attention_mask,
1051
+ token_type_ids=token_type_ids,
1052
+ position_ids=position_ids,
1053
+ head_mask=head_mask,
1054
+ inputs_embeds=inputs_embeds,
1055
+ )
1056
+
1057
+ pooled_output = outputs[1]
1058
+
1059
+ seq_relationship_score = self.cls(pooled_output)
1060
+
1061
+ outputs = (seq_relationship_score,) + outputs[2:] # add hidden states and attention if they are here
1062
+ if next_sentence_label is not None:
1063
+ loss_fct = CrossEntropyLoss()
1064
+ next_sentence_loss = loss_fct(seq_relationship_score.view(-1, 2), next_sentence_label.view(-1))
1065
+ outputs = (next_sentence_loss,) + outputs
1066
+
1067
+ return outputs # (next_sentence_loss), seq_relationship_score, (hidden_states), (attentions)
1068
+
1069
+
1070
+ @add_start_docstrings(
1071
+ """Bert Model transformer with a sequence classification/regression head on top (a linear layer on top of
1072
+ the pooled output) e.g. for GLUE tasks. """,
1073
+ BERT_START_DOCSTRING,
1074
+ )
1075
+ class BertForSequenceClassification(BertPreTrainedModel):
1076
+ def __init__(self, config):
1077
+ super().__init__(config)
1078
+ self.num_labels = config.num_labels
1079
+
1080
+ self.bert = BertModel(config)
1081
+ self.dropout = nn.Dropout(config.hidden_dropout_prob)
1082
+ self.classifier = nn.Linear(config.hidden_size, self.config.num_labels)
1083
+
1084
+ self.init_weights()
1085
+
1086
+ @add_start_docstrings_to_callable(BERT_INPUTS_DOCSTRING)
1087
+ def forward(
1088
+ self,
1089
+ input_ids=None,
1090
+ attention_mask=None,
1091
+ token_type_ids=None,
1092
+ position_ids=None,
1093
+ head_mask=None,
1094
+ inputs_embeds=None,
1095
+ labels=None,
1096
+ ):
1097
+ r"""
1098
+ labels (:obj:`torch.LongTensor` of shape :obj:`(batch_size,)`, `optional`, defaults to :obj:`None`):
1099
+ Labels for computing the sequence classification/regression loss.
1100
+ Indices should be in :obj:`[0, ..., config.num_labels - 1]`.
1101
+ If :obj:`config.num_labels == 1` a regression loss is computed (Mean-Square loss),
1102
+ If :obj:`config.num_labels > 1` a classification loss is computed (Cross-Entropy).
1103
+
1104
+ Returns:
1105
+ :obj:`tuple(torch.FloatTensor)` comprising various elements depending on the configuration (:class:`~transformers.BertConfig`) and inputs:
1106
+ loss (:obj:`torch.FloatTensor` of shape :obj:`(1,)`, `optional`, returned when :obj:`label` is provided):
1107
+ Classification (or regression if config.num_labels==1) loss.
1108
+ logits (:obj:`torch.FloatTensor` of shape :obj:`(batch_size, config.num_labels)`):
1109
+ Classification (or regression if config.num_labels==1) scores (before SoftMax).
1110
+ hidden_states (:obj:`tuple(torch.FloatTensor)`, `optional`, returned when ``config.output_hidden_states=True``):
1111
+ Tuple of :obj:`torch.FloatTensor` (one for the output of the embeddings + one for the output of each layer)
1112
+ of shape :obj:`(batch_size, sequence_length, hidden_size)`.
1113
+
1114
+ Hidden-states of the model at the output of each layer plus the initial embedding outputs.
1115
+ attentions (:obj:`tuple(torch.FloatTensor)`, `optional`, returned when ``config.output_attentions=True``):
1116
+ Tuple of :obj:`torch.FloatTensor` (one for each layer) of shape
1117
+ :obj:`(batch_size, num_heads, sequence_length, sequence_length)`.
1118
+
1119
+ Attentions weights after the attention softmax, used to compute the weighted average in the self-attention
1120
+ heads.
1121
+
1122
+ Examples::
1123
+
1124
+ from transformers import BertTokenizer, BertForSequenceClassification
1125
+ import torch
1126
+
1127
+ tokenizer = BertTokenizer.from_pretrained('bert-base-uncased')
1128
+ model = BertForSequenceClassification.from_pretrained('bert-base-uncased')
1129
+
1130
+ input_ids = torch.tensor(tokenizer.encode("Hello, my dog is cute", add_special_tokens=True)).unsqueeze(0) # Batch size 1
1131
+ labels = torch.tensor([1]).unsqueeze(0) # Batch size 1
1132
+ outputs = model(input_ids, labels=labels)
1133
+
1134
+ loss, logits = outputs[:2]
1135
+
1136
+ """
1137
+
1138
+ outputs = self.bert(
1139
+ input_ids,
1140
+ attention_mask=attention_mask,
1141
+ token_type_ids=token_type_ids,
1142
+ position_ids=position_ids,
1143
+ head_mask=head_mask,
1144
+ inputs_embeds=inputs_embeds,
1145
+ )
1146
+
1147
+ pooled_output = outputs[1]
1148
+
1149
+ pooled_output = self.dropout(pooled_output)
1150
+ logits = self.classifier(pooled_output)
1151
+
1152
+ outputs = (logits,) + outputs[2:] # add hidden states and attention if they are here
1153
+
1154
+ if labels is not None:
1155
+ if self.num_labels == 1:
1156
+ # We are doing regression
1157
+ loss_fct = MSELoss()
1158
+ loss = loss_fct(logits.view(-1), labels.view(-1))
1159
+ else:
1160
+ loss_fct = CrossEntropyLoss()
1161
+ loss = loss_fct(logits.view(-1, self.num_labels), labels.view(-1))
1162
+ outputs = (loss,) + outputs
1163
+
1164
+ return outputs # (loss), logits, (hidden_states), (attentions)
1165
+
1166
+
1167
+ @add_start_docstrings(
1168
+ """Bert Model with a multiple choice classification head on top (a linear layer on top of
1169
+ the pooled output and a softmax) e.g. for RocStories/SWAG tasks. """,
1170
+ BERT_START_DOCSTRING,
1171
+ )
1172
+ class BertForMultipleChoice(BertPreTrainedModel):
1173
+ def __init__(self, config):
1174
+ super().__init__(config)
1175
+
1176
+ self.bert = BertModel(config)
1177
+ self.dropout = nn.Dropout(config.hidden_dropout_prob)
1178
+ self.classifier = nn.Linear(config.hidden_size, 1)
1179
+
1180
+ self.init_weights()
1181
+
1182
+ @add_start_docstrings_to_callable(BERT_INPUTS_DOCSTRING)
1183
+ def forward(
1184
+ self,
1185
+ input_ids=None,
1186
+ attention_mask=None,
1187
+ token_type_ids=None,
1188
+ position_ids=None,
1189
+ head_mask=None,
1190
+ inputs_embeds=None,
1191
+ labels=None,
1192
+ ):
1193
+ r"""
1194
+ labels (:obj:`torch.LongTensor` of shape :obj:`(batch_size,)`, `optional`, defaults to :obj:`None`):
1195
+ Labels for computing the multiple choice classification loss.
1196
+ Indices should be in ``[0, ..., num_choices]`` where `num_choices` is the size of the second dimension
1197
+ of the input tensors. (see `input_ids` above)
1198
+
1199
+ Returns:
1200
+ :obj:`tuple(torch.FloatTensor)` comprising various elements depending on the configuration (:class:`~transformers.BertConfig`) and inputs:
1201
+ loss (:obj:`torch.FloatTensor` of shape `(1,)`, `optional`, returned when :obj:`labels` is provided):
1202
+ Classification loss.
1203
+ classification_scores (:obj:`torch.FloatTensor` of shape :obj:`(batch_size, num_choices)`):
1204
+ `num_choices` is the second dimension of the input tensors. (see `input_ids` above).
1205
+
1206
+ Classification scores (before SoftMax).
1207
+ hidden_states (:obj:`tuple(torch.FloatTensor)`, `optional`, returned when ``config.output_hidden_states=True``):
1208
+ Tuple of :obj:`torch.FloatTensor` (one for the output of the embeddings + one for the output of each layer)
1209
+ of shape :obj:`(batch_size, sequence_length, hidden_size)`.
1210
+
1211
+ Hidden-states of the model at the output of each layer plus the initial embedding outputs.
1212
+ attentions (:obj:`tuple(torch.FloatTensor)`, `optional`, returned when ``config.output_attentions=True``):
1213
+ Tuple of :obj:`torch.FloatTensor` (one for each layer) of shape
1214
+ :obj:`(batch_size, num_heads, sequence_length, sequence_length)`.
1215
+
1216
+ Attentions weights after the attention softmax, used to compute the weighted average in the self-attention
1217
+ heads.
1218
+
1219
+ Examples::
1220
+
1221
+ from transformers import BertTokenizer, BertForMultipleChoice
1222
+ import torch
1223
+
1224
+ tokenizer = BertTokenizer.from_pretrained('bert-base-uncased')
1225
+ model = BertForMultipleChoice.from_pretrained('bert-base-uncased')
1226
+ choices = ["Hello, my dog is cute", "Hello, my cat is amazing"]
1227
+
1228
+ input_ids = torch.tensor([tokenizer.encode(s, add_special_tokens=True) for s in choices]).unsqueeze(0) # Batch size 1, 2 choices
1229
+ labels = torch.tensor(1).unsqueeze(0) # Batch size 1
1230
+ outputs = model(input_ids, labels=labels)
1231
+
1232
+ loss, classification_scores = outputs[:2]
1233
+
1234
+ """
1235
+ num_choices = input_ids.shape[1]
1236
+
1237
+ input_ids = input_ids.view(-1, input_ids.size(-1))
1238
+ attention_mask = attention_mask.view(-1, attention_mask.size(-1)) if attention_mask is not None else None
1239
+ token_type_ids = token_type_ids.view(-1, token_type_ids.size(-1)) if token_type_ids is not None else None
1240
+ position_ids = position_ids.view(-1, position_ids.size(-1)) if position_ids is not None else None
1241
+
1242
+ outputs = self.bert(
1243
+ input_ids,
1244
+ attention_mask=attention_mask,
1245
+ token_type_ids=token_type_ids,
1246
+ position_ids=position_ids,
1247
+ head_mask=head_mask,
1248
+ inputs_embeds=inputs_embeds,
1249
+ )
1250
+
1251
+ pooled_output = outputs[1]
1252
+
1253
+ pooled_output = self.dropout(pooled_output)
1254
+ logits = self.classifier(pooled_output)
1255
+ reshaped_logits = logits.view(-1, num_choices)
1256
+
1257
+ outputs = (reshaped_logits,) + outputs[2:] # add hidden states and attention if they are here
1258
+
1259
+ if labels is not None:
1260
+ loss_fct = CrossEntropyLoss()
1261
+ loss = loss_fct(reshaped_logits, labels)
1262
+ outputs = (loss,) + outputs
1263
+
1264
+ return outputs # (loss), reshaped_logits, (hidden_states), (attentions)
1265
+
1266
+
1267
+ @add_start_docstrings(
1268
+ """Bert Model with a token classification head on top (a linear layer on top of
1269
+ the hidden-states output) e.g. for Named-Entity-Recognition (NER) tasks. """,
1270
+ BERT_START_DOCSTRING,
1271
+ )
1272
+ class BertForTokenClassification(BertPreTrainedModel):
1273
+ def __init__(self, config):
1274
+ super().__init__(config)
1275
+ self.num_labels = config.num_labels
1276
+
1277
+ self.bert = BertModel(config)
1278
+ self.dropout = nn.Dropout(config.hidden_dropout_prob)
1279
+ self.classifier = nn.Linear(config.hidden_size, config.num_labels)
1280
+
1281
+ self.init_weights()
1282
+
1283
+ @add_start_docstrings_to_callable(BERT_INPUTS_DOCSTRING)
1284
+ def forward(
1285
+ self,
1286
+ input_ids=None,
1287
+ attention_mask=None,
1288
+ token_type_ids=None,
1289
+ position_ids=None,
1290
+ head_mask=None,
1291
+ inputs_embeds=None,
1292
+ labels=None,
1293
+ ):
1294
+ r"""
1295
+ labels (:obj:`torch.LongTensor` of shape :obj:`(batch_size, sequence_length)`, `optional`, defaults to :obj:`None`):
1296
+ Labels for computing the token classification loss.
1297
+ Indices should be in ``[0, ..., config.num_labels - 1]``.
1298
+
1299
+ Returns:
1300
+ :obj:`tuple(torch.FloatTensor)` comprising various elements depending on the configuration (:class:`~transformers.BertConfig`) and inputs:
1301
+ loss (:obj:`torch.FloatTensor` of shape :obj:`(1,)`, `optional`, returned when ``labels`` is provided) :
1302
+ Classification loss.
1303
+ scores (:obj:`torch.FloatTensor` of shape :obj:`(batch_size, sequence_length, config.num_labels)`)
1304
+ Classification scores (before SoftMax).
1305
+ hidden_states (:obj:`tuple(torch.FloatTensor)`, `optional`, returned when ``config.output_hidden_states=True``):
1306
+ Tuple of :obj:`torch.FloatTensor` (one for the output of the embeddings + one for the output of each layer)
1307
+ of shape :obj:`(batch_size, sequence_length, hidden_size)`.
1308
+
1309
+ Hidden-states of the model at the output of each layer plus the initial embedding outputs.
1310
+ attentions (:obj:`tuple(torch.FloatTensor)`, `optional`, returned when ``config.output_attentions=True``):
1311
+ Tuple of :obj:`torch.FloatTensor` (one for each layer) of shape
1312
+ :obj:`(batch_size, num_heads, sequence_length, sequence_length)`.
1313
+
1314
+ Attentions weights after the attention softmax, used to compute the weighted average in the self-attention
1315
+ heads.
1316
+
1317
+ Examples::
1318
+
1319
+ from transformers import BertTokenizer, BertForTokenClassification
1320
+ import torch
1321
+
1322
+ tokenizer = BertTokenizer.from_pretrained('bert-base-uncased')
1323
+ model = BertForTokenClassification.from_pretrained('bert-base-uncased')
1324
+
1325
+ input_ids = torch.tensor(tokenizer.encode("Hello, my dog is cute", add_special_tokens=True)).unsqueeze(0) # Batch size 1
1326
+ labels = torch.tensor([1] * input_ids.size(1)).unsqueeze(0) # Batch size 1
1327
+ outputs = model(input_ids, labels=labels)
1328
+
1329
+ loss, scores = outputs[:2]
1330
+
1331
+ """
1332
+
1333
+ outputs = self.bert(
1334
+ input_ids,
1335
+ attention_mask=attention_mask,
1336
+ token_type_ids=token_type_ids,
1337
+ position_ids=position_ids,
1338
+ head_mask=head_mask,
1339
+ inputs_embeds=inputs_embeds,
1340
+ )
1341
+
1342
+ sequence_output = outputs[0]
1343
+
1344
+ sequence_output = self.dropout(sequence_output)
1345
+ logits = self.classifier(sequence_output)
1346
+
1347
+ outputs = (logits,) + outputs[2:] # add hidden states and attention if they are here
1348
+ if labels is not None:
1349
+ loss_fct = CrossEntropyLoss()
1350
+ # Only keep active parts of the loss
1351
+ if attention_mask is not None:
1352
+ active_loss = attention_mask.view(-1) == 1
1353
+ active_logits = logits.view(-1, self.num_labels)
1354
+ active_labels = torch.where(
1355
+ active_loss, labels.view(-1), torch.tensor(loss_fct.ignore_index).type_as(labels)
1356
+ )
1357
+ loss = loss_fct(active_logits, active_labels)
1358
+ else:
1359
+ loss = loss_fct(logits.view(-1, self.num_labels), labels.view(-1))
1360
+ outputs = (loss,) + outputs
1361
+
1362
+ return outputs # (loss), scores, (hidden_states), (attentions)
1363
+
1364
+
1365
+ @add_start_docstrings(
1366
+ """Bert Model with a span classification head on top for extractive question-answering tasks like SQuAD (a linear
1367
+ layers on top of the hidden-states output to compute `span start logits` and `span end logits`). """,
1368
+ BERT_START_DOCSTRING,
1369
+ )
1370
+ class BertForQuestionAnswering(BertPreTrainedModel):
1371
+ def __init__(self, config):
1372
+ super().__init__(config)
1373
+ self.num_labels = config.num_labels
1374
+
1375
+ self.bert = BertModel(config)
1376
+ self.qa_outputs = nn.Linear(config.hidden_size, config.num_labels)
1377
+
1378
+ self.init_weights()
1379
+
1380
+ @add_start_docstrings_to_callable(BERT_INPUTS_DOCSTRING)
1381
+ def forward(
1382
+ self,
1383
+ input_ids=None,
1384
+ attention_mask=None,
1385
+ token_type_ids=None,
1386
+ position_ids=None,
1387
+ head_mask=None,
1388
+ inputs_embeds=None,
1389
+ start_positions=None,
1390
+ end_positions=None,
1391
+ ):
1392
+ r"""
1393
+ start_positions (:obj:`torch.LongTensor` of shape :obj:`(batch_size,)`, `optional`, defaults to :obj:`None`):
1394
+ Labels for position (index) of the start of the labelled span for computing the token classification loss.
1395
+ Positions are clamped to the length of the sequence (`sequence_length`).
1396
+ Position outside of the sequence are not taken into account for computing the loss.
1397
+ end_positions (:obj:`torch.LongTensor` of shape :obj:`(batch_size,)`, `optional`, defaults to :obj:`None`):
1398
+ Labels for position (index) of the end of the labelled span for computing the token classification loss.
1399
+ Positions are clamped to the length of the sequence (`sequence_length`).
1400
+ Position outside of the sequence are not taken into account for computing the loss.
1401
+
1402
+ Returns:
1403
+ :obj:`tuple(torch.FloatTensor)` comprising various elements depending on the configuration (:class:`~transformers.BertConfig`) and inputs:
1404
+ loss (:obj:`torch.FloatTensor` of shape :obj:`(1,)`, `optional`, returned when :obj:`labels` is provided):
1405
+ Total span extraction loss is the sum of a Cross-Entropy for the start and end positions.
1406
+ start_scores (:obj:`torch.FloatTensor` of shape :obj:`(batch_size, sequence_length,)`):
1407
+ Span-start scores (before SoftMax).
1408
+ end_scores (:obj:`torch.FloatTensor` of shape :obj:`(batch_size, sequence_length,)`):
1409
+ Span-end scores (before SoftMax).
1410
+ hidden_states (:obj:`tuple(torch.FloatTensor)`, `optional`, returned when ``config.output_hidden_states=True``):
1411
+ Tuple of :obj:`torch.FloatTensor` (one for the output of the embeddings + one for the output of each layer)
1412
+ of shape :obj:`(batch_size, sequence_length, hidden_size)`.
1413
+
1414
+ Hidden-states of the model at the output of each layer plus the initial embedding outputs.
1415
+ attentions (:obj:`tuple(torch.FloatTensor)`, `optional`, returned when ``config.output_attentions=True``):
1416
+ Tuple of :obj:`torch.FloatTensor` (one for each layer) of shape
1417
+ :obj:`(batch_size, num_heads, sequence_length, sequence_length)`.
1418
+
1419
+ Attentions weights after the attention softmax, used to compute the weighted average in the self-attention
1420
+ heads.
1421
+
1422
+ Examples::
1423
+
1424
+ from transformers import BertTokenizer, BertForQuestionAnswering
1425
+ import torch
1426
+
1427
+ tokenizer = BertTokenizer.from_pretrained('bert-base-uncased')
1428
+ model = BertForQuestionAnswering.from_pretrained('bert-large-uncased-whole-word-masking-finetuned-squad')
1429
+
1430
+ question, text = "Who was Jim Henson?", "Jim Henson was a nice puppet"
1431
+ encoding = tokenizer.encode_plus(question, text)
1432
+ input_ids, token_type_ids = encoding["input_ids"], encoding["token_type_ids"]
1433
+ start_scores, end_scores = model(torch.tensor([input_ids]), token_type_ids=torch.tensor([token_type_ids]))
1434
+
1435
+ all_tokens = tokenizer.convert_ids_to_tokens(input_ids)
1436
+ answer = ' '.join(all_tokens[torch.argmax(start_scores) : torch.argmax(end_scores)+1])
1437
+
1438
+ assert answer == "a nice puppet"
1439
+
1440
+ """
1441
+
1442
+ outputs = self.bert(
1443
+ input_ids,
1444
+ attention_mask=attention_mask,
1445
+ token_type_ids=token_type_ids,
1446
+ position_ids=position_ids,
1447
+ head_mask=head_mask,
1448
+ inputs_embeds=inputs_embeds,
1449
+ )
1450
+
1451
+ sequence_output = outputs[0]
1452
+
1453
+ logits = self.qa_outputs(sequence_output)
1454
+ start_logits, end_logits = logits.split(1, dim=-1)
1455
+ start_logits = start_logits.squeeze(-1)
1456
+ end_logits = end_logits.squeeze(-1)
1457
+
1458
+ outputs = (start_logits, end_logits,) + outputs[2:]
1459
+ if start_positions is not None and end_positions is not None:
1460
+ # If we are on multi-GPU, split add a dimension
1461
+ if len(start_positions.size()) > 1:
1462
+ start_positions = start_positions.squeeze(-1)
1463
+ if len(end_positions.size()) > 1:
1464
+ end_positions = end_positions.squeeze(-1)
1465
+ # sometimes the start/end positions are outside our model inputs, we ignore these terms
1466
+ ignored_index = start_logits.size(1)
1467
+ start_positions.clamp_(0, ignored_index)
1468
+ end_positions.clamp_(0, ignored_index)
1469
+
1470
+ loss_fct = CrossEntropyLoss(ignore_index=ignored_index)
1471
+ start_loss = loss_fct(start_logits, start_positions)
1472
+ end_loss = loss_fct(end_logits, end_positions)
1473
+ total_loss = (start_loss + end_loss) / 2
1474
+ outputs = (total_loss,) + outputs
1475
+
1476
+ return outputs # (loss), start_logits, end_logits, (hidden_states), (attentions)
models/modeling_utils.py ADDED
@@ -0,0 +1,2098 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # coding=utf-8
2
+ # Copyright 2018 The Google AI Language Team Authors, Facebook AI Research authors and The HuggingFace Inc. team.
3
+ # Copyright (c) 2018, NVIDIA CORPORATION. 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 BERT model."""
17
+
18
+ import logging
19
+ import os
20
+ from typing import Callable, Tuple
21
+
22
+ import torch
23
+ from torch import Tensor, device, dtype, nn
24
+ from torch.nn import CrossEntropyLoss
25
+ from torch.nn import functional as F
26
+
27
+ from .activations import get_activation
28
+ from .configuration_utils import PretrainedConfig
29
+ from .file_utils import (
30
+ DUMMY_INPUTS,
31
+ TF2_WEIGHTS_NAME,
32
+ TF_WEIGHTS_NAME,
33
+ WEIGHTS_NAME,
34
+ cached_path,
35
+ hf_bucket_url,
36
+ is_remote_url,
37
+ )
38
+
39
+
40
+ logger = logging.getLogger(__name__)
41
+
42
+
43
+ try:
44
+ from torch.nn import Identity
45
+ except ImportError:
46
+ # Older PyTorch compatibility
47
+ class Identity(nn.Module):
48
+ r"""A placeholder identity operator that is argument-insensitive.
49
+ """
50
+
51
+ def __init__(self, *args, **kwargs):
52
+ super().__init__()
53
+
54
+ def forward(self, input):
55
+ return input
56
+
57
+
58
+ class ModuleUtilsMixin:
59
+ """
60
+ A few utilities for torch.nn.Modules, to be used as a mixin.
61
+ """
62
+
63
+ def num_parameters(self, only_trainable: bool = False) -> int:
64
+ """
65
+ Get number of (optionally, trainable) parameters in the module.
66
+ """
67
+ params = filter(lambda x: x.requires_grad, self.parameters()) if only_trainable else self.parameters()
68
+ return sum(p.numel() for p in params)
69
+
70
+ @staticmethod
71
+ def _hook_rss_memory_pre_forward(module, *args, **kwargs):
72
+ try:
73
+ import psutil
74
+ except (ImportError):
75
+ raise ImportError("You need to install psutil (pip install psutil) to use memory tracing.")
76
+
77
+ process = psutil.Process(os.getpid())
78
+ mem = process.memory_info()
79
+ module.mem_rss_pre_forward = mem.rss
80
+ return None
81
+
82
+ @staticmethod
83
+ def _hook_rss_memory_post_forward(module, *args, **kwargs):
84
+ try:
85
+ import psutil
86
+ except (ImportError):
87
+ raise ImportError("You need to install psutil (pip install psutil) to use memory tracing.")
88
+
89
+ process = psutil.Process(os.getpid())
90
+ mem = process.memory_info()
91
+ module.mem_rss_post_forward = mem.rss
92
+ mem_rss_diff = module.mem_rss_post_forward - module.mem_rss_pre_forward
93
+ module.mem_rss_diff = mem_rss_diff + (module.mem_rss_diff if hasattr(module, "mem_rss_diff") else 0)
94
+ return None
95
+
96
+ def add_memory_hooks(self):
97
+ """ Add a memory hook before and after each sub-module forward pass to record increase in memory consumption.
98
+ Increase in memory consumption is stored in a `mem_rss_diff` attribute for each module and can be reset to zero with `model.reset_memory_hooks_state()`
99
+ """
100
+ for module in self.modules():
101
+ module.register_forward_pre_hook(self._hook_rss_memory_pre_forward)
102
+ module.register_forward_hook(self._hook_rss_memory_post_forward)
103
+ self.reset_memory_hooks_state()
104
+
105
+ def reset_memory_hooks_state(self):
106
+ for module in self.modules():
107
+ module.mem_rss_diff = 0
108
+ module.mem_rss_post_forward = 0
109
+ module.mem_rss_pre_forward = 0
110
+
111
+ @property
112
+ def device(self) -> device:
113
+ return next(self.parameters()).device
114
+
115
+ @property
116
+ def dtype(self) -> dtype:
117
+ return next(self.parameters()).dtype
118
+
119
+ def invert_attention_mask(self, encoder_attention_mask: Tensor) -> Tensor:
120
+ """type: torch.Tensor -> torch.Tensor"""
121
+ if encoder_attention_mask.dim() == 3:
122
+ encoder_extended_attention_mask = encoder_attention_mask[:, None, :, :]
123
+ if encoder_attention_mask.dim() == 2:
124
+ encoder_extended_attention_mask = encoder_attention_mask[:, None, None, :]
125
+ # T5 has a mask that can compare sequence ids, we can simulate this here with this transposition
126
+ # Cf. https://github.com/tensorflow/mesh/blob/8d2465e9bc93129b913b5ccc6a59aa97abd96ec6/mesh_tensorflow
127
+ # /transformer/transformer_layers.py#L270
128
+ # encoder_extended_attention_mask = (encoder_extended_attention_mask ==
129
+ # encoder_extended_attention_mask.transpose(-1, -2))
130
+ encoder_extended_attention_mask = encoder_extended_attention_mask.to(dtype=self.dtype) # fp16 compatibility
131
+ encoder_extended_attention_mask = (1.0 - encoder_extended_attention_mask) * -1e9
132
+ return encoder_extended_attention_mask
133
+
134
+ def get_extended_attention_mask(self, attention_mask: Tensor, input_shape: tuple, device: device):
135
+ """Makes broadcastable attention mask and causal mask so that future and maked tokens are ignored.
136
+
137
+ Arguments:
138
+ attention_mask: torch.Tensor with 1 indicating tokens to ATTEND to
139
+ input_shape: tuple, shape of input_ids
140
+ device: torch.Device, usually self.device
141
+
142
+ Returns:
143
+ torch.Tensor with dtype of attention_mask.dtype
144
+ """
145
+ # We can provide a self-attention mask of dimensions [batch_size, from_seq_length, to_seq_length]
146
+ # ourselves in which case we just need to make it broadcastable to all heads.
147
+ if attention_mask.dim() == 3:
148
+ extended_attention_mask = attention_mask[:, None, :, :]
149
+ elif attention_mask.dim() == 2:
150
+ # Provided a padding mask of dimensions [batch_size, seq_length]
151
+ # - if the model is a decoder, apply a causal mask in addition to the padding mask
152
+ # - if the model is an encoder, make the mask broadcastable to [batch_size, num_heads, seq_length, seq_length]
153
+ if self.config.is_decoder:
154
+ batch_size, seq_length = input_shape
155
+ seq_ids = torch.arange(seq_length, device=device)
156
+ causal_mask = seq_ids[None, None, :].repeat(batch_size, seq_length, 1) <= seq_ids[None, :, None]
157
+ # causal and attention masks must have same type with pytorch version < 1.3
158
+ causal_mask = causal_mask.to(attention_mask.dtype)
159
+ extended_attention_mask = causal_mask[:, None, :, :] * attention_mask[:, None, None, :]
160
+ else:
161
+ extended_attention_mask = attention_mask[:, None, None, :]
162
+ else:
163
+ raise ValueError(
164
+ "Wrong shape for input_ids (shape {}) or attention_mask (shape {})".format(
165
+ input_shape, attention_mask.shape
166
+ )
167
+ )
168
+
169
+ # Since attention_mask is 1.0 for positions we want to attend and 0.0 for
170
+ # masked positions, this operation will create a tensor which is 0.0 for
171
+ # positions we want to attend and -10000.0 for masked positions.
172
+ # Since we are adding it to the raw scores before the softmax, this is
173
+ # effectively the same as removing these entirely.
174
+ extended_attention_mask = extended_attention_mask.to(dtype=self.dtype) # fp16 compatibility
175
+ extended_attention_mask = (1.0 - extended_attention_mask) * -10000.0
176
+ return extended_attention_mask
177
+
178
+ def get_head_mask(self, head_mask, num_hidden_layers):
179
+ """
180
+ # Prepare head mask if needed
181
+ # 1.0 in head_mask indicate we keep the head
182
+ attention_probs has shape bsz x n_heads x N x N
183
+ Arguments:
184
+ head_mask: torch.Tensor or None: has shape [num_heads] or [num_hidden_layers x num_heads]
185
+ num_hidden_layers: int
186
+ Returns:
187
+ Tensor of shape shape [num_hidden_layers x batch x num_heads x seq_length x seq_length]
188
+ or list with [None] for each layer
189
+ """
190
+ if head_mask is not None:
191
+ head_mask = self._convert_head_mask_to_5d(head_mask, num_hidden_layers)
192
+ else:
193
+ head_mask = [None] * num_hidden_layers
194
+
195
+ return head_mask
196
+
197
+ def _convert_head_mask_to_5d(self, head_mask, num_hidden_layers):
198
+ """-> [num_hidden_layers x batch x num_heads x seq_length x seq_length]"""
199
+ if head_mask.dim() == 1:
200
+ head_mask = head_mask.unsqueeze(0).unsqueeze(0).unsqueeze(-1).unsqueeze(-1)
201
+ head_mask = head_mask.expand(num_hidden_layers, -1, -1, -1, -1)
202
+ elif head_mask.dim() == 2:
203
+ head_mask = head_mask.unsqueeze(1).unsqueeze(-1).unsqueeze(-1) # We can specify head_mask for each layer
204
+ assert head_mask.dim() == 5, f"head_mask.dim != 5, instead {head_mask.dim()}"
205
+ head_mask = head_mask.to(dtype=self.dtype) # switch to fload if need + fp16 compatibility
206
+ return head_mask
207
+
208
+
209
+ class PreTrainedModel(nn.Module, ModuleUtilsMixin):
210
+ r""" Base class for all models.
211
+
212
+ :class:`~transformers.PreTrainedModel` takes care of storing the configuration of the models and handles methods for loading/downloading/saving models
213
+ as well as a few methods common to all models to (i) resize the input embeddings and (ii) prune heads in the self-attention heads.
214
+
215
+ Class attributes (overridden by derived classes):
216
+ - ``config_class``: a class derived from :class:`~transformers.PretrainedConfig` to use as configuration class for this model architecture.
217
+ - ``pretrained_model_archive_map``: a python ``dict`` of with `short-cut-names` (string) as keys and `url` (string) of associated pretrained weights as values.
218
+ - ``load_tf_weights``: a python ``method`` for loading a TensorFlow checkpoint in a PyTorch model, taking as arguments:
219
+
220
+ - ``model``: an instance of the relevant subclass of :class:`~transformers.PreTrainedModel`,
221
+ - ``config``: an instance of the relevant subclass of :class:`~transformers.PretrainedConfig`,
222
+ - ``path``: a path (string) to the TensorFlow checkpoint.
223
+
224
+ - ``base_model_prefix``: a string indicating the attribute associated to the base model in derived classes of the same architecture adding modules on top of the base model.
225
+ """
226
+ config_class = None
227
+ pretrained_model_archive_map = {}
228
+ base_model_prefix = ""
229
+
230
+ @property
231
+ def dummy_inputs(self):
232
+ """ Dummy inputs to do a forward pass in the network.
233
+
234
+ Returns:
235
+ torch.Tensor with dummy inputs
236
+ """
237
+ return {"input_ids": torch.tensor(DUMMY_INPUTS)}
238
+
239
+ def __init__(self, config, *inputs, **kwargs):
240
+ super().__init__()
241
+ if not isinstance(config, PretrainedConfig):
242
+ raise ValueError(
243
+ "Parameter config in `{}(config)` should be an instance of class `PretrainedConfig`. "
244
+ "To create a model from a pretrained model use "
245
+ "`model = {}.from_pretrained(PRETRAINED_MODEL_NAME)`".format(
246
+ self.__class__.__name__, self.__class__.__name__
247
+ )
248
+ )
249
+ # Save config in model
250
+ self.config = config
251
+
252
+ @property
253
+ def base_model(self):
254
+ return getattr(self, self.base_model_prefix, self)
255
+
256
+ def get_input_embeddings(self):
257
+ """
258
+ Returns the model's input embeddings.
259
+
260
+ Returns:
261
+ :obj:`nn.Module`:
262
+ A torch module mapping vocabulary to hidden states.
263
+ """
264
+ base_model = getattr(self, self.base_model_prefix, self)
265
+ if base_model is not self:
266
+ return base_model.get_input_embeddings()
267
+ else:
268
+ raise NotImplementedError
269
+
270
+ def set_input_embeddings(self, value):
271
+ """
272
+ Set model's input embeddings
273
+
274
+ Args:
275
+ value (:obj:`nn.Module`):
276
+ A module mapping vocabulary to hidden states.
277
+ """
278
+ base_model = getattr(self, self.base_model_prefix, self)
279
+ if base_model is not self:
280
+ base_model.set_input_embeddings(value)
281
+ else:
282
+ raise NotImplementedError
283
+
284
+ def get_output_embeddings(self):
285
+ """
286
+ Returns the model's output embeddings.
287
+
288
+ Returns:
289
+ :obj:`nn.Module`:
290
+ A torch module mapping hidden states to vocabulary.
291
+ """
292
+ return None # Overwrite for models with output embeddings
293
+
294
+ def tie_weights(self):
295
+ """
296
+ Tie the weights between the input embeddings and the output embeddings.
297
+ If the `torchscript` flag is set in the configuration, can't handle parameter sharing so we are cloning
298
+ the weights instead.
299
+ """
300
+ output_embeddings = self.get_output_embeddings()
301
+ if output_embeddings is not None:
302
+ self._tie_or_clone_weights(output_embeddings, self.get_input_embeddings())
303
+
304
+ def _tie_or_clone_weights(self, output_embeddings, input_embeddings):
305
+ """ Tie or clone module weights depending of whether we are using TorchScript or not
306
+ """
307
+ if self.config.torchscript:
308
+ output_embeddings.weight = nn.Parameter(input_embeddings.weight.clone())
309
+ else:
310
+ output_embeddings.weight = input_embeddings.weight
311
+
312
+ if getattr(output_embeddings, "bias", None) is not None:
313
+ output_embeddings.bias.data = torch.nn.functional.pad(
314
+ output_embeddings.bias.data,
315
+ (0, output_embeddings.weight.shape[0] - output_embeddings.bias.shape[0],),
316
+ "constant",
317
+ 0,
318
+ )
319
+ if hasattr(output_embeddings, "out_features") and hasattr(input_embeddings, "num_embeddings"):
320
+ output_embeddings.out_features = input_embeddings.num_embeddings
321
+
322
+ def resize_token_embeddings(self, new_num_tokens=None):
323
+ """ Resize input token embeddings matrix of the model if new_num_tokens != config.vocab_size.
324
+ Take care of tying weights embeddings afterwards if the model class has a `tie_weights()` method.
325
+
326
+ Arguments:
327
+
328
+ new_num_tokens: (`optional`) int:
329
+ New number of tokens in the embedding matrix. Increasing the size will add newly initialized vectors at the end. Reducing the size will remove vectors from the end.
330
+ If not provided or None: does nothing and just returns a pointer to the input tokens ``torch.nn.Embeddings`` Module of the model.
331
+
332
+ Return: ``torch.nn.Embeddings``
333
+ Pointer to the input tokens Embeddings Module of the model
334
+ """
335
+ base_model = getattr(self, self.base_model_prefix, self) # get the base model if needed
336
+ model_embeds = base_model._resize_token_embeddings(new_num_tokens)
337
+ if new_num_tokens is None:
338
+ return model_embeds
339
+
340
+ # Update base model and current model config
341
+ self.config.vocab_size = new_num_tokens
342
+ base_model.vocab_size = new_num_tokens
343
+
344
+ # Tie weights again if needed
345
+ self.tie_weights()
346
+
347
+ return model_embeds
348
+
349
+ def _resize_token_embeddings(self, new_num_tokens):
350
+ old_embeddings = self.get_input_embeddings()
351
+ new_embeddings = self._get_resized_embeddings(old_embeddings, new_num_tokens)
352
+ self.set_input_embeddings(new_embeddings)
353
+ return self.get_input_embeddings()
354
+
355
+ def _get_resized_embeddings(self, old_embeddings, new_num_tokens=None):
356
+ """ Build a resized Embedding Module from a provided token Embedding Module.
357
+ Increasing the size will add newly initialized vectors at the end
358
+ Reducing the size will remove vectors from the end
359
+
360
+ Args:
361
+ new_num_tokens: (`optional`) int
362
+ New number of tokens in the embedding matrix.
363
+ Increasing the size will add newly initialized vectors at the end
364
+ Reducing the size will remove vectors from the end
365
+ If not provided or None: return the provided token Embedding Module.
366
+ Return: ``torch.nn.Embeddings``
367
+ Pointer to the resized Embedding Module or the old Embedding Module if new_num_tokens is None
368
+ """
369
+ if new_num_tokens is None:
370
+ return old_embeddings
371
+
372
+ old_num_tokens, old_embedding_dim = old_embeddings.weight.size()
373
+ if old_num_tokens == new_num_tokens:
374
+ return old_embeddings
375
+
376
+ # Build new embeddings
377
+ new_embeddings = nn.Embedding(new_num_tokens, old_embedding_dim)
378
+ new_embeddings.to(old_embeddings.weight.device)
379
+
380
+ # initialize all new embeddings (in particular added tokens)
381
+ self._init_weights(new_embeddings)
382
+
383
+ # Copy token embeddings from the previous weights
384
+ num_tokens_to_copy = min(old_num_tokens, new_num_tokens)
385
+ new_embeddings.weight.data[:num_tokens_to_copy, :] = old_embeddings.weight.data[:num_tokens_to_copy, :]
386
+
387
+ return new_embeddings
388
+
389
+ def init_weights(self):
390
+ """ Initialize and prunes weights if needed. """
391
+ # Initialize weights
392
+ self.apply(self._init_weights)
393
+
394
+ # Prune heads if needed
395
+ if self.config.pruned_heads:
396
+ self.prune_heads(self.config.pruned_heads)
397
+
398
+ # Tie weights if needed
399
+ self.tie_weights()
400
+
401
+ def prune_heads(self, heads_to_prune):
402
+ """ Prunes heads of the base model.
403
+
404
+ Arguments:
405
+
406
+ heads_to_prune: dict with keys being selected layer indices (`int`) and associated values being the list of heads to prune in said layer (list of `int`).
407
+ E.g. {1: [0, 2], 2: [2, 3]} will prune heads 0 and 2 on layer 1 and heads 2 and 3 on layer 2.
408
+ """
409
+ # save new sets of pruned heads as union of previously stored pruned heads and newly pruned heads
410
+ for layer, heads in heads_to_prune.items():
411
+ union_heads = set(self.config.pruned_heads.get(layer, [])) | set(heads)
412
+ self.config.pruned_heads[layer] = list(union_heads) # Unfortunately we have to store it as list for JSON
413
+
414
+ self.base_model._prune_heads(heads_to_prune)
415
+
416
+ def save_pretrained(self, save_directory):
417
+ """ Save a model and its configuration file to a directory, so that it
418
+ can be re-loaded using the `:func:`~transformers.PreTrainedModel.from_pretrained`` class method.
419
+
420
+ Arguments:
421
+ save_directory: directory to which to save.
422
+ """
423
+ assert os.path.isdir(
424
+ save_directory
425
+ ), "Saving path should be a directory where the model and configuration can be saved"
426
+
427
+ # Only save the model itself if we are using distributed training
428
+ model_to_save = self.module if hasattr(self, "module") else self
429
+
430
+ # Attach architecture to the config
431
+ model_to_save.config.architectures = [model_to_save.__class__.__name__]
432
+
433
+ # If we save using the predefined names, we can load using `from_pretrained`
434
+ output_model_file = os.path.join(save_directory, WEIGHTS_NAME)
435
+
436
+ if getattr(self.config, "xla_device", False):
437
+ import torch_xla.core.xla_model as xm
438
+
439
+ if xm.is_master_ordinal():
440
+ # Save configuration file
441
+ model_to_save.config.save_pretrained(save_directory)
442
+ # xm.save takes care of saving only from master
443
+ xm.save(model_to_save.state_dict(), output_model_file)
444
+ else:
445
+ model_to_save.config.save_pretrained(save_directory)
446
+ torch.save(model_to_save.state_dict(), output_model_file)
447
+
448
+ logger.info("Model weights saved in {}".format(output_model_file))
449
+
450
+ @classmethod
451
+ def from_pretrained(cls, pretrained_model_name_or_path, *model_args, **kwargs):
452
+ r"""Instantiate a pretrained pytorch model from a pre-trained model configuration.
453
+
454
+ The model is set in evaluation mode by default using ``model.eval()`` (Dropout modules are deactivated)
455
+ To train the model, you should first set it back in training mode with ``model.train()``
456
+
457
+ The warning ``Weights from XXX not initialized from pretrained model`` means that the weights of XXX do not come pre-trained with the rest of the model.
458
+ It is up to you to train those weights with a downstream fine-tuning task.
459
+
460
+ The warning ``Weights from XXX not used in YYY`` means that the layer XXX is not used by YYY, therefore those weights are discarded.
461
+
462
+ Parameters:
463
+ pretrained_model_name_or_path: either:
464
+ - a string with the `shortcut name` of a pre-trained model to load from cache or download, e.g.: ``bert-base-uncased``.
465
+ - a string with the `identifier name` of a pre-trained model that was user-uploaded to our S3, e.g.: ``dbmdz/bert-base-german-cased``.
466
+ - a path to a `directory` containing model weights saved using :func:`~transformers.PreTrainedModel.save_pretrained`, e.g.: ``./my_model_directory/``.
467
+ - a path or url to a `tensorflow index checkpoint file` (e.g. `./tf_model/model.ckpt.index`). In this case, ``from_tf`` should be set to True and a configuration object should be provided as ``config`` argument. This loading path is slower than converting the TensorFlow checkpoint in a PyTorch model using the provided conversion scripts and loading the PyTorch model afterwards.
468
+ - None if you are both providing the configuration and state dictionary (resp. with keyword arguments ``config`` and ``state_dict``)
469
+
470
+ model_args: (`optional`) Sequence of positional arguments:
471
+ All remaning positional arguments will be passed to the underlying model's ``__init__`` method
472
+
473
+ config: (`optional`) one of:
474
+ - an instance of a class derived from :class:`~transformers.PretrainedConfig`, or
475
+ - a string valid as input to :func:`~transformers.PretrainedConfig.from_pretrained()`
476
+ Configuration for the model to use instead of an automatically loaded configuation. Configuration can be automatically loaded when:
477
+ - the model is a model provided by the library (loaded with the ``shortcut-name`` string of a pretrained model), or
478
+ - the model was saved using :func:`~transformers.PreTrainedModel.save_pretrained` and is reloaded by suppling the save directory.
479
+ - the model is loaded by suppling a local directory as ``pretrained_model_name_or_path`` and a configuration JSON file named `config.json` is found in the directory.
480
+
481
+ state_dict: (`optional`) dict:
482
+ an optional state dictionnary for the model to use instead of a state dictionary loaded from saved weights file.
483
+ This option can be used if you want to create a model from a pretrained configuration but load your own weights.
484
+ In this case though, you should check if using :func:`~transformers.PreTrainedModel.save_pretrained` and :func:`~transformers.PreTrainedModel.from_pretrained` is not a simpler option.
485
+
486
+ cache_dir: (`optional`) string:
487
+ Path to a directory in which a downloaded pre-trained model
488
+ configuration should be cached if the standard cache should not be used.
489
+
490
+ force_download: (`optional`) boolean, default False:
491
+ Force to (re-)download the model weights and configuration files and override the cached versions if they exists.
492
+
493
+ resume_download: (`optional`) boolean, default False:
494
+ Do not delete incompletely recieved file. Attempt to resume the download if such a file exists.
495
+
496
+ proxies: (`optional`) dict, default None:
497
+ A dictionary of proxy servers to use by protocol or endpoint, e.g.: {'http': 'foo.bar:3128', 'http://hostname': 'foo.bar:4012'}.
498
+ The proxies are used on each request.
499
+
500
+ output_loading_info: (`optional`) boolean:
501
+ Set to ``True`` to also return a dictionnary containing missing keys, unexpected keys and error messages.
502
+
503
+ kwargs: (`optional`) Remaining dictionary of keyword arguments:
504
+ Can be used to update the configuration object (after it being loaded) and initiate the model. (e.g. ``output_attention=True``). Behave differently depending on whether a `config` is provided or automatically loaded:
505
+
506
+ - If a configuration is provided with ``config``, ``**kwargs`` will be directly passed to the underlying model's ``__init__`` method (we assume all relevant updates to the configuration have already been done)
507
+ - If a configuration is not provided, ``kwargs`` will be first passed to the configuration class initialization function (:func:`~transformers.PretrainedConfig.from_pretrained`). Each key of ``kwargs`` that corresponds to a configuration attribute will be used to override said attribute with the supplied ``kwargs`` value. Remaining keys that do not correspond to any configuration attribute will be passed to the underlying model's ``__init__`` function.
508
+
509
+ Examples::
510
+
511
+ # For example purposes. Not runnable.
512
+ model = BertModel.from_pretrained('bert-base-uncased') # Download model and configuration from S3 and cache.
513
+ model = BertModel.from_pretrained('./test/saved_model/') # E.g. model was saved using `save_pretrained('./test/saved_model/')`
514
+ model = BertModel.from_pretrained('bert-base-uncased', output_attention=True) # Update configuration during loading
515
+ assert model.config.output_attention == True
516
+ # Loading from a TF checkpoint file instead of a PyTorch model (slower)
517
+ config = BertConfig.from_json_file('./tf_model/my_tf_model_config.json')
518
+ model = BertModel.from_pretrained('./tf_model/my_tf_checkpoint.ckpt.index', from_tf=True, config=config)
519
+
520
+ """
521
+ config = kwargs.pop("config", None)
522
+ state_dict = kwargs.pop("state_dict", None)
523
+ cache_dir = kwargs.pop("cache_dir", None)
524
+ from_tf = kwargs.pop("from_tf", False)
525
+ force_download = kwargs.pop("force_download", False)
526
+ resume_download = kwargs.pop("resume_download", False)
527
+ proxies = kwargs.pop("proxies", None)
528
+ output_loading_info = kwargs.pop("output_loading_info", False)
529
+ local_files_only = kwargs.pop("local_files_only", False)
530
+
531
+ # Load config if we don't provide a configuration
532
+ if not isinstance(config, PretrainedConfig):
533
+ config_path = config if config is not None else pretrained_model_name_or_path
534
+ config, model_kwargs = cls.config_class.from_pretrained(
535
+ config_path,
536
+ *model_args,
537
+ cache_dir=cache_dir,
538
+ return_unused_kwargs=True,
539
+ force_download=force_download,
540
+ resume_download=resume_download,
541
+ proxies=proxies,
542
+ local_files_only=local_files_only,
543
+ **kwargs,
544
+ )
545
+ else:
546
+ model_kwargs = kwargs
547
+
548
+ # Load model
549
+ if pretrained_model_name_or_path is not None:
550
+ if pretrained_model_name_or_path in cls.pretrained_model_archive_map:
551
+ archive_file = cls.pretrained_model_archive_map[pretrained_model_name_or_path]
552
+ elif os.path.isdir(pretrained_model_name_or_path):
553
+ if from_tf and os.path.isfile(os.path.join(pretrained_model_name_or_path, TF_WEIGHTS_NAME + ".index")):
554
+ # Load from a TF 1.0 checkpoint
555
+ archive_file = os.path.join(pretrained_model_name_or_path, TF_WEIGHTS_NAME + ".index")
556
+ elif from_tf and os.path.isfile(os.path.join(pretrained_model_name_or_path, TF2_WEIGHTS_NAME)):
557
+ # Load from a TF 2.0 checkpoint
558
+ archive_file = os.path.join(pretrained_model_name_or_path, TF2_WEIGHTS_NAME)
559
+ elif os.path.isfile(os.path.join(pretrained_model_name_or_path, WEIGHTS_NAME)):
560
+ # Load from a PyTorch checkpoint
561
+ archive_file = os.path.join(pretrained_model_name_or_path, WEIGHTS_NAME)
562
+ else:
563
+ raise EnvironmentError(
564
+ "Error no file named {} found in directory {} or `from_tf` set to False".format(
565
+ [WEIGHTS_NAME, TF2_WEIGHTS_NAME, TF_WEIGHTS_NAME + ".index"],
566
+ pretrained_model_name_or_path,
567
+ )
568
+ )
569
+ elif os.path.isfile(pretrained_model_name_or_path) or is_remote_url(pretrained_model_name_or_path):
570
+ archive_file = pretrained_model_name_or_path
571
+ elif os.path.isfile(pretrained_model_name_or_path + ".index"):
572
+ assert (
573
+ from_tf
574
+ ), "We found a TensorFlow checkpoint at {}, please set from_tf to True to load from this checkpoint".format(
575
+ pretrained_model_name_or_path + ".index"
576
+ )
577
+ archive_file = pretrained_model_name_or_path + ".index"
578
+ else:
579
+ archive_file = hf_bucket_url(
580
+ pretrained_model_name_or_path, postfix=(TF2_WEIGHTS_NAME if from_tf else WEIGHTS_NAME),
581
+ )
582
+
583
+ # redirect to the cache, if necessary
584
+ try:
585
+ resolved_archive_file = cached_path(
586
+ archive_file,
587
+ cache_dir=cache_dir,
588
+ force_download=force_download,
589
+ proxies=proxies,
590
+ resume_download=resume_download,
591
+ local_files_only=local_files_only,
592
+ )
593
+ except EnvironmentError:
594
+ if pretrained_model_name_or_path in cls.pretrained_model_archive_map:
595
+ msg = "Couldn't reach server at '{}' to download pretrained weights.".format(archive_file)
596
+ else:
597
+ msg = (
598
+ "Model name '{}' was not found in model name list ({}). "
599
+ "We assumed '{}' was a path or url to model weight files named one of {} but "
600
+ "couldn't find any such file at this path or url.".format(
601
+ pretrained_model_name_or_path,
602
+ ", ".join(cls.pretrained_model_archive_map.keys()),
603
+ archive_file,
604
+ [WEIGHTS_NAME, TF2_WEIGHTS_NAME, TF_WEIGHTS_NAME],
605
+ )
606
+ )
607
+ raise EnvironmentError(msg)
608
+
609
+ if resolved_archive_file == archive_file:
610
+ logger.info("loading weights file {}".format(archive_file))
611
+ else:
612
+ logger.info("loading weights file {} from cache at {}".format(archive_file, resolved_archive_file))
613
+ else:
614
+ resolved_archive_file = None
615
+
616
+ # Instantiate model.
617
+ model = cls(config, *model_args, **model_kwargs)
618
+
619
+ if state_dict is None and not from_tf:
620
+ try:
621
+ state_dict = torch.load(resolved_archive_file, map_location="cpu")
622
+ except Exception:
623
+ raise OSError(
624
+ "Unable to load weights from pytorch checkpoint file. "
625
+ "If you tried to load a PyTorch model from a TF 2.0 checkpoint, please set from_tf=True. "
626
+ )
627
+
628
+ missing_keys = []
629
+ unexpected_keys = []
630
+ error_msgs = []
631
+
632
+ if from_tf:
633
+ if resolved_archive_file.endswith(".index"):
634
+ # Load from a TensorFlow 1.X checkpoint - provided by original authors
635
+ model = cls.load_tf_weights(model, config, resolved_archive_file[:-6]) # Remove the '.index'
636
+ else:
637
+ # Load from our TensorFlow 2.0 checkpoints
638
+ try:
639
+ from transformers import load_tf2_checkpoint_in_pytorch_model
640
+
641
+ model = load_tf2_checkpoint_in_pytorch_model(model, resolved_archive_file, allow_missing_keys=True)
642
+ except ImportError:
643
+ logger.error(
644
+ "Loading a TensorFlow model in PyTorch, requires both PyTorch and TensorFlow to be installed. Please see "
645
+ "https://pytorch.org/ and https://www.tensorflow.org/install/ for installation instructions."
646
+ )
647
+ raise
648
+ else:
649
+ # Convert old format to new format if needed from a PyTorch state_dict
650
+ old_keys = []
651
+ new_keys = []
652
+ for key in state_dict.keys():
653
+ new_key = None
654
+ if "gamma" in key:
655
+ new_key = key.replace("gamma", "weight")
656
+ if "beta" in key:
657
+ new_key = key.replace("beta", "bias")
658
+ if new_key:
659
+ old_keys.append(key)
660
+ new_keys.append(new_key)
661
+ for old_key, new_key in zip(old_keys, new_keys):
662
+ state_dict[new_key] = state_dict.pop(old_key)
663
+
664
+ # copy state_dict so _load_from_state_dict can modify it
665
+ metadata = getattr(state_dict, "_metadata", None)
666
+ state_dict = state_dict.copy()
667
+ if metadata is not None:
668
+ state_dict._metadata = metadata
669
+
670
+ # PyTorch's `_load_from_state_dict` does not copy parameters in a module's descendants
671
+ # so we need to apply the function recursively.
672
+ def load(module: nn.Module, prefix=""):
673
+ local_metadata = {} if metadata is None else metadata.get(prefix[:-1], {})
674
+ module._load_from_state_dict(
675
+ state_dict, prefix, local_metadata, True, missing_keys, unexpected_keys, error_msgs,
676
+ )
677
+ for name, child in module._modules.items():
678
+ if child is not None:
679
+ load(child, prefix + name + ".")
680
+
681
+ # Make sure we are able to load base models as well as derived models (with heads)
682
+ start_prefix = ""
683
+ model_to_load = model
684
+ has_prefix_module = any(s.startswith(cls.base_model_prefix) for s in state_dict.keys())
685
+ if not hasattr(model, cls.base_model_prefix) and has_prefix_module:
686
+ start_prefix = cls.base_model_prefix + "."
687
+ if hasattr(model, cls.base_model_prefix) and not has_prefix_module:
688
+ model_to_load = getattr(model, cls.base_model_prefix)
689
+
690
+ load(model_to_load, prefix=start_prefix)
691
+
692
+ if model.__class__.__name__ != model_to_load.__class__.__name__:
693
+ base_model_state_dict = model_to_load.state_dict().keys()
694
+ head_model_state_dict_without_base_prefix = [
695
+ key.split(cls.base_model_prefix + ".")[-1] for key in model.state_dict().keys()
696
+ ]
697
+
698
+ missing_keys.extend(head_model_state_dict_without_base_prefix - base_model_state_dict)
699
+
700
+ if len(missing_keys) > 0:
701
+ logger.info(
702
+ "Weights of {} not initialized from pretrained model: {}".format(
703
+ model.__class__.__name__, missing_keys
704
+ )
705
+ )
706
+ if len(unexpected_keys) > 0:
707
+ logger.info(
708
+ "Weights from pretrained model not used in {}: {}".format(
709
+ model.__class__.__name__, unexpected_keys
710
+ )
711
+ )
712
+ if len(error_msgs) > 0:
713
+ raise RuntimeError(
714
+ "Error(s) in loading state_dict for {}:\n\t{}".format(
715
+ model.__class__.__name__, "\n\t".join(error_msgs)
716
+ )
717
+ )
718
+ model.tie_weights() # make sure token embedding weights are still tied if needed
719
+
720
+ # Set model in evaluation mode to deactivate DropOut modules by default
721
+ model.eval()
722
+
723
+ if output_loading_info:
724
+ loading_info = {
725
+ "missing_keys": missing_keys,
726
+ "unexpected_keys": unexpected_keys,
727
+ "error_msgs": error_msgs,
728
+ }
729
+ return model, loading_info
730
+
731
+ if hasattr(config, "xla_device") and config.xla_device:
732
+ import torch_xla.core.xla_model as xm
733
+
734
+ model = xm.send_cpu_data_to_device(model, xm.xla_device())
735
+ model = model.to(xm.xla_device())
736
+
737
+ return model
738
+
739
+ def prepare_inputs_for_generation(self, input_ids, **kwargs):
740
+ return {"input_ids": input_ids}
741
+
742
+ def prepare_scores_for_generation(self, scores, **kwargs):
743
+ return scores
744
+
745
+ def _use_cache(self, outputs, use_cache):
746
+ """During generation, decide whether to pass the `past` variable to the next forward pass."""
747
+ if len(outputs) <= 1 or use_cache is False:
748
+ return False
749
+ if hasattr(self.config, "mem_len") and self.config.mem_len == 0:
750
+ return False
751
+ return True
752
+
753
+ def enforce_repetition_penalty_(self, lprobs, batch_size, num_beams, prev_output_tokens, repetition_penalty):
754
+ """repetition penalty (from CTRL paper https://arxiv.org/abs/1909.05858). """
755
+ for i in range(batch_size * num_beams):
756
+ for previous_token in set(prev_output_tokens[i].tolist()):
757
+ # if score < 0 then repetition penalty has to multiplied to reduce the previous token probability
758
+ if lprobs[i, previous_token] < 0:
759
+ lprobs[i, previous_token] *= repetition_penalty
760
+ else:
761
+ lprobs[i, previous_token] /= repetition_penalty
762
+
763
+ @torch.no_grad()
764
+ def generate(
765
+ self,
766
+ input_ids=None,
767
+ max_length=None,
768
+ min_length=None,
769
+ do_sample=None,
770
+ early_stopping=None,
771
+ num_beams=None,
772
+ temperature=None,
773
+ top_k=None,
774
+ top_p=None,
775
+ repetition_penalty=None,
776
+ bad_words_ids=None,
777
+ bos_token_id=None,
778
+ pad_token_id=None,
779
+ eos_token_id=None,
780
+ length_penalty=None,
781
+ no_repeat_ngram_size=None,
782
+ num_return_sequences=None,
783
+ attention_mask=None,
784
+ decoder_start_token_id=None,
785
+ use_cache=None,
786
+ ):
787
+ r""" Generates sequences for models with a LM head. The method currently supports greedy decoding, beam-search decoding, sampling with temperature, sampling with top-k or nucleus sampling.
788
+
789
+ Adapted in part from `Facebook's XLM beam search code`_.
790
+
791
+ .. _`Facebook's XLM beam search code`:
792
+ https://github.com/facebookresearch/XLM/blob/9e6f6814d17be4fe5b15f2e6c43eb2b2d76daeb4/src/model/transformer.py#L529
793
+
794
+
795
+ Parameters:
796
+
797
+ input_ids: (`optional`) `torch.LongTensor` of shape `(batch_size, sequence_length)`
798
+ The sequence used as a prompt for the generation. If `None` the method initializes
799
+ it as an empty `torch.LongTensor` of shape `(1,)`.
800
+
801
+ max_length: (`optional`) int
802
+ The max length of the sequence to be generated. Between `min_length` and infinity. Default to 20.
803
+
804
+ min_length: (`optional`) int
805
+ The min length of the sequence to be generated. Between 0 and infinity. Default to 0.
806
+
807
+ do_sample: (`optional`) bool
808
+ If set to `False` greedy decoding is used. Otherwise sampling is used. Defaults to `False` as defined in `configuration_utils.PretrainedConfig`.
809
+
810
+ early_stopping: (`optional`) bool
811
+ if set to `True` beam search is stopped when at least `num_beams` sentences finished per batch. Defaults to `False` as defined in `configuration_utils.PretrainedConfig`.
812
+
813
+ num_beams: (`optional`) int
814
+ Number of beams for beam search. Must be between 1 and infinity. 1 means no beam search. Default to 1.
815
+
816
+ temperature: (`optional`) float
817
+ The value used to module the next token probabilities. Must be strictly positive. Default to 1.0.
818
+
819
+ top_k: (`optional`) int
820
+ The number of highest probability vocabulary tokens to keep for top-k-filtering. Between 1 and infinity. Default to 50.
821
+
822
+ top_p: (`optional`) float
823
+ The cumulative probability of parameter highest probability vocabulary tokens to keep for nucleus sampling. Must be between 0 and 1. Default to 1.
824
+
825
+ repetition_penalty: (`optional`) float
826
+ The parameter for repetition penalty. Between 1.0 and infinity. 1.0 means no penalty. Default to 1.0.
827
+
828
+ pad_token_id: (`optional`) int
829
+ Padding token. Default to specicic model pad_token_id or None if it does not exist.
830
+
831
+ bos_token_id: (`optional`) int
832
+ BOS token. Defaults to `bos_token_id` as defined in the models config.
833
+
834
+ eos_token_id: (`optional`) int
835
+ EOS token. Defaults to `eos_token_id` as defined in the models config.
836
+
837
+ length_penalty: (`optional`) float
838
+ Exponential penalty to the length. Default to 1.
839
+
840
+ no_repeat_ngram_size: (`optional`) int
841
+ If set to int > 0, all ngrams of size `no_repeat_ngram_size` can only occur once.
842
+ bad_words_ids: (`optional`) list of lists of int
843
+ `bad_words_ids` contains tokens that are not allowed to be generated. In order to get the tokens of the words that should not appear in the generated text, use `tokenizer.encode(bad_word, add_prefix_space=True)`.
844
+
845
+ num_return_sequences: (`optional`) int
846
+ The number of independently computed returned sequences for each element in the batch. Default to 1.
847
+
848
+ attention_mask (`optional`) obj: `torch.LongTensor` of same shape as `input_ids`
849
+ Mask to avoid performing attention on padding token indices.
850
+ Mask values selected in ``[0, 1]``:
851
+ ``1`` for tokens that are NOT MASKED, ``0`` for MASKED tokens.
852
+ Defaults to `None`.
853
+
854
+ `What are attention masks? <../glossary.html#attention-mask>`__
855
+
856
+ decoder_start_token_id=None: (`optional`) int
857
+ If an encoder-decoder model starts decoding with a different token than BOS.
858
+ Defaults to `None` and is changed to `BOS` later.
859
+
860
+ use_cache: (`optional`) bool
861
+ If `use_cache` is True, past key values are used to speed up decoding if applicable to model. Defaults to `True`.
862
+
863
+ Return:
864
+
865
+ output: `torch.LongTensor` of shape `(batch_size * num_return_sequences, sequence_length)`
866
+ sequence_length is either equal to max_length or shorter if all batches finished early due to the `eos_token_id`
867
+
868
+ Examples::
869
+
870
+ tokenizer = AutoTokenizer.from_pretrained('distilgpt2') # Initialize tokenizer
871
+ model = AutoModelWithLMHead.from_pretrained('distilgpt2') # Download model and configuration from S3 and cache.
872
+ outputs = model.generate(max_length=40) # do greedy decoding
873
+ print('Generated: {}'.format(tokenizer.decode(outputs[0], skip_special_tokens=True)))
874
+
875
+ tokenizer = AutoTokenizer.from_pretrained('openai-gpt') # Initialize tokenizer
876
+ model = AutoModelWithLMHead.from_pretrained('openai-gpt') # Download model and configuration from S3 and cache.
877
+ input_context = 'The dog'
878
+ input_ids = tokenizer.encode(input_context, return_tensors='pt') # encode input context
879
+ outputs = model.generate(input_ids=input_ids, num_beams=5, num_return_sequences=3, temperature=1.5) # generate 3 independent sequences using beam search decoding (5 beams) with sampling from initial context 'The dog'
880
+ for i in range(3): # 3 output sequences were generated
881
+ print('Generated {}: {}'.format(i, tokenizer.decode(outputs[i], skip_special_tokens=True)))
882
+
883
+ tokenizer = AutoTokenizer.from_pretrained('distilgpt2') # Initialize tokenizer
884
+ model = AutoModelWithLMHead.from_pretrained('distilgpt2') # Download model and configuration from S3 and cache.
885
+ input_context = 'The dog'
886
+ input_ids = tokenizer.encode(input_context, return_tensors='pt') # encode input context
887
+ outputs = model.generate(input_ids=input_ids, max_length=40, temperature=0.7, num_return_sequences=3) # 3 generate sequences using by sampling
888
+ for i in range(3): # 3 output sequences were generated
889
+ print('Generated {}: {}'.format(i, tokenizer.decode(outputs[i], skip_special_tokens=True)))
890
+
891
+ tokenizer = AutoTokenizer.from_pretrained('ctrl') # Initialize tokenizer
892
+ model = AutoModelWithLMHead.from_pretrained('ctrl') # Download model and configuration from S3 and cache.
893
+ input_context = 'Legal My neighbor is' # "Legal" is one of the control codes for ctrl
894
+ input_ids = tokenizer.encode(input_context, return_tensors='pt') # encode input context
895
+ outputs = model.generate(input_ids=input_ids, max_length=50, temperature=0.7, repetition_penalty=1.2) # generate sequences
896
+ print('Generated: {}'.format(tokenizer.decode(outputs[0], skip_special_tokens=True)))
897
+
898
+ tokenizer = AutoTokenizer.from_pretrained('gpt2') # Initialize tokenizer
899
+ model = AutoModelWithLMHead.from_pretrained('gpt2') # Download model and configuration from S3 and cache.
900
+ input_context = 'My cute dog' # "Legal" is one of the control codes for ctrl
901
+ bad_words_ids = [tokenizer.encode(bad_word, add_prefix_space=True) for bad_word in ['idiot', 'stupid', 'shut up']]
902
+ input_ids = tokenizer.encode(input_context, return_tensors='pt') # encode input context
903
+ outputs = model.generate(input_ids=input_ids, max_length=100, do_sample=True, bad_words_ids=bad_words_ids) # generate sequences without allowing bad_words to be generated
904
+ """
905
+
906
+ # We cannot generate if the model does not have a LM head
907
+ if self.get_output_embeddings() is None:
908
+ raise AttributeError(
909
+ "You tried to generate sequences with a model that does not have a LM Head."
910
+ "Please use another model class (e.g. `OpenAIGPTLMHeadModel`, `XLNetLMHeadModel`, `GPT2LMHeadModel`, `CTRLLMHeadModel`, `T5WithLMHeadModel`, `TransfoXLLMHeadModel`, `XLMWithLMHeadModel`, `BartForConditionalGeneration` )"
911
+ )
912
+
913
+ max_length = max_length if max_length is not None else self.config.max_length
914
+ min_length = min_length if min_length is not None else self.config.min_length
915
+ do_sample = do_sample if do_sample is not None else self.config.do_sample
916
+ early_stopping = early_stopping if early_stopping is not None else self.config.early_stopping
917
+ use_cache = use_cache if use_cache is not None else self.config.use_cache
918
+ num_beams = num_beams if num_beams is not None else self.config.num_beams
919
+ temperature = temperature if temperature is not None else self.config.temperature
920
+ top_k = top_k if top_k is not None else self.config.top_k
921
+ top_p = top_p if top_p is not None else self.config.top_p
922
+ repetition_penalty = repetition_penalty if repetition_penalty is not None else self.config.repetition_penalty
923
+ bos_token_id = bos_token_id if bos_token_id is not None else self.config.bos_token_id
924
+ pad_token_id = pad_token_id if pad_token_id is not None else self.config.pad_token_id
925
+ eos_token_id = eos_token_id if eos_token_id is not None else self.config.eos_token_id
926
+ length_penalty = length_penalty if length_penalty is not None else self.config.length_penalty
927
+ no_repeat_ngram_size = (
928
+ no_repeat_ngram_size if no_repeat_ngram_size is not None else self.config.no_repeat_ngram_size
929
+ )
930
+ bad_words_ids = bad_words_ids if bad_words_ids is not None else self.config.bad_words_ids
931
+ num_return_sequences = (
932
+ num_return_sequences if num_return_sequences is not None else self.config.num_return_sequences
933
+ )
934
+ decoder_start_token_id = (
935
+ decoder_start_token_id if decoder_start_token_id is not None else self.config.decoder_start_token_id
936
+ )
937
+
938
+ if input_ids is not None:
939
+ batch_size = input_ids.shape[0] # overriden by the input batch_size
940
+ else:
941
+ batch_size = 1
942
+
943
+ assert isinstance(max_length, int) and max_length > 0, "`max_length` should be a strictly positive integer."
944
+ assert isinstance(min_length, int) and min_length >= 0, "`min_length` should be a positive integer."
945
+ assert isinstance(do_sample, bool), "`do_sample` should be a boolean."
946
+ assert isinstance(early_stopping, bool), "`early_stopping` should be a boolean."
947
+ assert isinstance(use_cache, bool), "`use_cache` should be a boolean."
948
+ assert isinstance(num_beams, int) and num_beams > 0, "`num_beams` should be a strictly positive integer."
949
+ assert temperature > 0, "`temperature` should be strictly positive."
950
+ assert isinstance(top_k, int) and top_k >= 0, "`top_k` should be a positive integer."
951
+ assert 0 <= top_p <= 1, "`top_p` should be between 0 and 1."
952
+ assert repetition_penalty >= 1.0, "`repetition_penalty` should be >= 1."
953
+ assert input_ids is not None or (
954
+ isinstance(bos_token_id, int) and bos_token_id >= 0
955
+ ), "If input_ids is not defined, `bos_token_id` should be a positive integer."
956
+ assert pad_token_id is None or (
957
+ isinstance(pad_token_id, int) and (pad_token_id >= 0)
958
+ ), "`pad_token_id` should be a positive integer."
959
+ assert (eos_token_id is None) or (
960
+ isinstance(eos_token_id, int) and (eos_token_id >= 0)
961
+ ), "`eos_token_id` should be a positive integer."
962
+ assert length_penalty > 0, "`length_penalty` should be strictly positive."
963
+ assert (
964
+ isinstance(no_repeat_ngram_size, int) and no_repeat_ngram_size >= 0
965
+ ), "`no_repeat_ngram_size` should be a positive integer."
966
+ assert (
967
+ isinstance(num_return_sequences, int) and num_return_sequences > 0
968
+ ), "`num_return_sequences` should be a strictly positive integer."
969
+ assert (
970
+ bad_words_ids is None or isinstance(bad_words_ids, list) and isinstance(bad_words_ids[0], list)
971
+ ), "`bad_words_ids` is either `None` or a list of lists of tokens that should not be generated"
972
+
973
+ if input_ids is None:
974
+ assert isinstance(bos_token_id, int) and bos_token_id >= 0, (
975
+ "you should either supply a context to complete as `input_ids` input "
976
+ "or a `bos_token_id` (integer >= 0) as a first token to start the generation."
977
+ )
978
+ input_ids = torch.full(
979
+ (batch_size, 1), bos_token_id, dtype=torch.long, device=next(self.parameters()).device,
980
+ )
981
+ else:
982
+ assert input_ids.dim() == 2, "Input prompt should be of shape (batch_size, sequence length)."
983
+
984
+ # not allow to duplicate outputs when greedy decoding
985
+ if do_sample is False:
986
+ if num_beams == 1:
987
+ # no_beam_search greedy generation conditions
988
+ assert (
989
+ num_return_sequences == 1
990
+ ), "Greedy decoding will always produce the same output for num_beams == 1 and num_return_sequences > 1. Please set num_return_sequences = 1"
991
+
992
+ else:
993
+ # beam_search greedy generation conditions
994
+ assert (
995
+ num_beams >= num_return_sequences
996
+ ), "Greedy beam search decoding cannot return more sequences than it has beams. Please set num_beams >= num_return_sequences"
997
+
998
+ # create attention mask if necessary
999
+ # TODO (PVP): this should later be handled by the forward fn() in each model in the future see PR 3140
1000
+ if (attention_mask is None) and (pad_token_id is not None) and (pad_token_id in input_ids):
1001
+ attention_mask = input_ids.ne(pad_token_id).long()
1002
+ elif attention_mask is None:
1003
+ attention_mask = input_ids.new_ones(input_ids.shape)
1004
+
1005
+ # set pad_token_id to eos_token_id if not set. Important that this is done after
1006
+ # attention_mask is created
1007
+ if pad_token_id is None and eos_token_id is not None:
1008
+ logger.warning(
1009
+ "Setting `pad_token_id` to {} (first `eos_token_id`) to generate sequence".format(eos_token_id)
1010
+ )
1011
+ pad_token_id = eos_token_id
1012
+
1013
+ # current position and vocab size
1014
+ if hasattr(self.config, "vocab_size"):
1015
+ vocab_size = self.config.vocab_size
1016
+ elif (
1017
+ self.config.is_encoder_decoder
1018
+ and hasattr(self.config, "decoder")
1019
+ and hasattr(self.config.decoder, "vocab_size")
1020
+ ):
1021
+ vocab_size = self.config.decoder.vocab_size
1022
+
1023
+ # set effective batch size and effective batch multiplier according to do_sample
1024
+ if do_sample:
1025
+ effective_batch_size = batch_size * num_return_sequences
1026
+ effective_batch_mult = num_return_sequences
1027
+ else:
1028
+ effective_batch_size = batch_size
1029
+ effective_batch_mult = 1
1030
+
1031
+ if self.config.is_encoder_decoder:
1032
+ if decoder_start_token_id is None:
1033
+ decoder_start_token_id = bos_token_id
1034
+
1035
+ assert (
1036
+ decoder_start_token_id is not None
1037
+ ), "decoder_start_token_id or bos_token_id has to be defined for encoder-decoder generation"
1038
+ assert hasattr(self, "get_encoder"), "{} should have a 'get_encoder' function defined".format(self)
1039
+ assert callable(self.get_encoder), "{} should be a method".format(self.get_encoder)
1040
+
1041
+ # get encoder and store encoder outputs
1042
+ encoder = self.get_encoder()
1043
+
1044
+ encoder_outputs: tuple = encoder(input_ids, attention_mask=attention_mask)
1045
+
1046
+ # Expand input ids if num_beams > 1 or num_return_sequences > 1
1047
+ if num_return_sequences > 1 or num_beams > 1:
1048
+ input_ids_len = input_ids.shape[-1]
1049
+ input_ids = input_ids.unsqueeze(1).expand(batch_size, effective_batch_mult * num_beams, input_ids_len)
1050
+ attention_mask = attention_mask.unsqueeze(1).expand(
1051
+ batch_size, effective_batch_mult * num_beams, input_ids_len
1052
+ )
1053
+
1054
+ input_ids = input_ids.contiguous().view(
1055
+ effective_batch_size * num_beams, input_ids_len
1056
+ ) # shape: (batch_size * num_return_sequences * num_beams, cur_len)
1057
+ attention_mask = attention_mask.contiguous().view(
1058
+ effective_batch_size * num_beams, input_ids_len
1059
+ ) # shape: (batch_size * num_return_sequences * num_beams, cur_len)
1060
+
1061
+ if self.config.is_encoder_decoder:
1062
+ # create empty decoder_input_ids
1063
+ input_ids = torch.full(
1064
+ (effective_batch_size * num_beams, 1),
1065
+ decoder_start_token_id,
1066
+ dtype=torch.long,
1067
+ device=next(self.parameters()).device,
1068
+ )
1069
+ cur_len = 1
1070
+
1071
+ assert (
1072
+ batch_size == encoder_outputs[0].shape[0]
1073
+ ), f"expected encoder_outputs[0] to have 1st dimension bs={batch_size}, got {encoder_outputs[0].shape[0]} "
1074
+
1075
+ # expand batch_idx to assign correct encoder output for expanded input_ids (due to num_beams > 1 and num_return_sequences > 1)
1076
+ expanded_batch_idxs = (
1077
+ torch.arange(batch_size)
1078
+ .view(-1, 1)
1079
+ .repeat(1, num_beams * effective_batch_mult)
1080
+ .view(-1)
1081
+ .to(input_ids.device)
1082
+ )
1083
+ # expand encoder_outputs
1084
+ encoder_outputs = (encoder_outputs[0].index_select(0, expanded_batch_idxs), *encoder_outputs[1:])
1085
+
1086
+ else:
1087
+ encoder_outputs = None
1088
+ cur_len = input_ids.shape[-1]
1089
+
1090
+ if num_beams > 1:
1091
+ output = self._generate_beam_search(
1092
+ input_ids,
1093
+ cur_len=cur_len,
1094
+ max_length=max_length,
1095
+ min_length=min_length,
1096
+ do_sample=do_sample,
1097
+ early_stopping=early_stopping,
1098
+ temperature=temperature,
1099
+ top_k=top_k,
1100
+ top_p=top_p,
1101
+ repetition_penalty=repetition_penalty,
1102
+ no_repeat_ngram_size=no_repeat_ngram_size,
1103
+ bad_words_ids=bad_words_ids,
1104
+ bos_token_id=bos_token_id,
1105
+ pad_token_id=pad_token_id,
1106
+ decoder_start_token_id=decoder_start_token_id,
1107
+ eos_token_id=eos_token_id,
1108
+ batch_size=effective_batch_size,
1109
+ num_return_sequences=num_return_sequences,
1110
+ length_penalty=length_penalty,
1111
+ num_beams=num_beams,
1112
+ vocab_size=vocab_size,
1113
+ encoder_outputs=encoder_outputs,
1114
+ attention_mask=attention_mask,
1115
+ use_cache=use_cache,
1116
+ )
1117
+ else:
1118
+ output = self._generate_no_beam_search(
1119
+ input_ids,
1120
+ cur_len=cur_len,
1121
+ max_length=max_length,
1122
+ min_length=min_length,
1123
+ do_sample=do_sample,
1124
+ temperature=temperature,
1125
+ top_k=top_k,
1126
+ top_p=top_p,
1127
+ repetition_penalty=repetition_penalty,
1128
+ no_repeat_ngram_size=no_repeat_ngram_size,
1129
+ bad_words_ids=bad_words_ids,
1130
+ bos_token_id=bos_token_id,
1131
+ pad_token_id=pad_token_id,
1132
+ decoder_start_token_id=decoder_start_token_id,
1133
+ eos_token_id=eos_token_id,
1134
+ batch_size=effective_batch_size,
1135
+ encoder_outputs=encoder_outputs,
1136
+ attention_mask=attention_mask,
1137
+ use_cache=use_cache,
1138
+ )
1139
+
1140
+ return output
1141
+
1142
+ def _generate_no_beam_search(
1143
+ self,
1144
+ input_ids,
1145
+ cur_len,
1146
+ max_length,
1147
+ min_length,
1148
+ do_sample,
1149
+ temperature,
1150
+ top_k,
1151
+ top_p,
1152
+ repetition_penalty,
1153
+ no_repeat_ngram_size,
1154
+ bad_words_ids,
1155
+ bos_token_id,
1156
+ pad_token_id,
1157
+ eos_token_id,
1158
+ decoder_start_token_id,
1159
+ batch_size,
1160
+ encoder_outputs,
1161
+ attention_mask,
1162
+ use_cache,
1163
+ ):
1164
+ """ Generate sequences for each example without beam search (num_beams == 1).
1165
+ All returned sequence are generated independantly.
1166
+ """
1167
+ # length of generated sentences / unfinished sentences
1168
+ unfinished_sents = input_ids.new(batch_size).fill_(1)
1169
+ sent_lengths = input_ids.new(batch_size).fill_(max_length)
1170
+
1171
+ past = encoder_outputs # defined for encoder-decoder models, None for decoder-only models
1172
+
1173
+ while cur_len < max_length:
1174
+ model_inputs = self.prepare_inputs_for_generation(
1175
+ input_ids, past=past, attention_mask=attention_mask, use_cache=use_cache
1176
+ )
1177
+
1178
+ outputs = self(**model_inputs)
1179
+ next_token_logits = outputs[0][:, -1, :]
1180
+
1181
+ # if model has past, then set the past variable to speed up decoding
1182
+ if self._use_cache(outputs, use_cache):
1183
+ past = outputs[1]
1184
+
1185
+ # repetition penalty from CTRL paper (https://arxiv.org/abs/1909.05858)
1186
+ if repetition_penalty != 1.0:
1187
+ self.enforce_repetition_penalty_(next_token_logits, batch_size, 1, input_ids, repetition_penalty)
1188
+
1189
+ if no_repeat_ngram_size > 0:
1190
+ # calculate a list of banned tokens to prevent repetitively generating the same ngrams
1191
+ # from fairseq: https://github.com/pytorch/fairseq/blob/a07cb6f40480928c9e0548b737aadd36ee66ac76/fairseq/sequence_generator.py#L345
1192
+ banned_tokens = calc_banned_ngram_tokens(input_ids, batch_size, no_repeat_ngram_size, cur_len)
1193
+ for batch_idx in range(batch_size):
1194
+ next_token_logits[batch_idx, banned_tokens[batch_idx]] = -float("inf")
1195
+
1196
+ if bad_words_ids is not None:
1197
+ # calculate a list of banned tokens according to bad words
1198
+ banned_tokens = calc_banned_bad_words_ids(input_ids, bad_words_ids)
1199
+
1200
+ for batch_idx in range(batch_size):
1201
+ next_token_logits[batch_idx, banned_tokens[batch_idx]] = -float("inf")
1202
+
1203
+ # set eos token prob to zero if min_length is not reached
1204
+ if eos_token_id is not None and cur_len < min_length:
1205
+ next_token_logits[:, eos_token_id] = -float("inf")
1206
+
1207
+ if do_sample:
1208
+ # Temperature (higher temperature => more likely to sample low probability tokens)
1209
+ if temperature != 1.0:
1210
+ next_token_logits = next_token_logits / temperature
1211
+ # Top-p/top-k filtering
1212
+ next_token_logits = top_k_top_p_filtering(next_token_logits, top_k=top_k, top_p=top_p)
1213
+ # Sample
1214
+ probs = F.softmax(next_token_logits, dim=-1)
1215
+ next_token = torch.multinomial(probs, num_samples=1).squeeze(1)
1216
+ else:
1217
+ # Greedy decoding
1218
+ next_token = torch.argmax(next_token_logits, dim=-1)
1219
+
1220
+ # update generations and finished sentences
1221
+ if eos_token_id is not None:
1222
+ # pad finished sentences if eos_token_id exist
1223
+ tokens_to_add = next_token * unfinished_sents + (pad_token_id) * (1 - unfinished_sents)
1224
+ else:
1225
+ tokens_to_add = next_token
1226
+
1227
+ input_ids = torch.cat([input_ids, tokens_to_add.unsqueeze(-1)], dim=-1)
1228
+
1229
+ if eos_token_id is not None:
1230
+ eos_in_sents = tokens_to_add == eos_token_id
1231
+ # if sentence is unfinished and the token to add is eos, sent_lengths is filled with current length
1232
+ is_sents_unfinished_and_token_to_add_is_eos = unfinished_sents.mul(eos_in_sents.long()).bool()
1233
+ sent_lengths.masked_fill_(is_sents_unfinished_and_token_to_add_is_eos, cur_len + 1)
1234
+ # unfinished_sents is set to zero if eos in sentence
1235
+ unfinished_sents.mul_((~eos_in_sents).long())
1236
+
1237
+ # stop when there is a </s> in each sentence, or if we exceed the maximul length
1238
+ if unfinished_sents.max() == 0:
1239
+ break
1240
+
1241
+ # extend attention_mask for new generated input if only decoder
1242
+ if self.config.is_encoder_decoder is False:
1243
+ attention_mask = torch.cat(
1244
+ [attention_mask, attention_mask.new_ones((attention_mask.shape[0], 1))], dim=-1
1245
+ )
1246
+
1247
+ cur_len = cur_len + 1
1248
+
1249
+ # if there are different sentences lengths in the batch, some batches have to be padded
1250
+ if sent_lengths.min().item() != sent_lengths.max().item():
1251
+ assert pad_token_id is not None, "`Pad_token_id` has to be defined if batches have different lengths"
1252
+ # finished sents are filled with pad_token
1253
+ decoded = input_ids.new(batch_size, sent_lengths.max().item()).fill_(pad_token_id)
1254
+ else:
1255
+ decoded = input_ids
1256
+
1257
+ for hypo_idx, hypo in enumerate(input_ids):
1258
+ decoded[hypo_idx, : sent_lengths[hypo_idx]] = hypo[: sent_lengths[hypo_idx]]
1259
+
1260
+ return decoded
1261
+
1262
+ def _generate_beam_search(
1263
+ self,
1264
+ input_ids,
1265
+ cur_len,
1266
+ max_length,
1267
+ min_length,
1268
+ do_sample,
1269
+ early_stopping,
1270
+ temperature,
1271
+ top_k,
1272
+ top_p,
1273
+ repetition_penalty,
1274
+ no_repeat_ngram_size,
1275
+ bad_words_ids,
1276
+ bos_token_id,
1277
+ pad_token_id,
1278
+ eos_token_id,
1279
+ decoder_start_token_id,
1280
+ batch_size,
1281
+ num_return_sequences,
1282
+ length_penalty,
1283
+ num_beams,
1284
+ vocab_size,
1285
+ encoder_outputs,
1286
+ attention_mask,
1287
+ use_cache,
1288
+ ):
1289
+ """ Generate sequences for each example with beam search.
1290
+ """
1291
+
1292
+ # generated hypotheses
1293
+ generated_hyps = [
1294
+ BeamHypotheses(num_beams, max_length, length_penalty, early_stopping=early_stopping)
1295
+ for _ in range(batch_size)
1296
+ ]
1297
+
1298
+ # scores for each sentence in the beam
1299
+ beam_scores = torch.zeros((batch_size, num_beams), dtype=torch.float, device=input_ids.device)
1300
+
1301
+ # for greedy decoding it is made sure that only tokens of the first beam are considered to avoid sampling the exact same tokens three times
1302
+ if do_sample is False:
1303
+ beam_scores[:, 1:] = -1e9
1304
+ beam_scores = beam_scores.view(-1) # shape (batch_size * num_beams,)
1305
+
1306
+ # cache compute states
1307
+ past = encoder_outputs # defined for encoder-decoder models, None for decoder-only models
1308
+
1309
+ # done sentences
1310
+ done = [False for _ in range(batch_size)]
1311
+
1312
+ while cur_len < max_length:
1313
+ model_inputs = self.prepare_inputs_for_generation(
1314
+ input_ids, past=past, attention_mask=attention_mask, use_cache=use_cache
1315
+ )
1316
+ outputs = self(**model_inputs) # (batch_size * num_beams, cur_len, vocab_size)
1317
+ next_token_logits = outputs[0][:, -1, :] # (batch_size * num_beams, vocab_size)
1318
+
1319
+ # if model has past, then set the past variable to speed up decoding
1320
+ if self._use_cache(outputs, use_cache):
1321
+ past = outputs[1]
1322
+
1323
+ # repetition penalty (from CTRL paper https://arxiv.org/abs/1909.05858)
1324
+ if repetition_penalty != 1.0:
1325
+ self.enforce_repetition_penalty_(
1326
+ next_token_logits, batch_size, num_beams, input_ids, repetition_penalty,
1327
+ )
1328
+
1329
+ if temperature != 1.0:
1330
+ next_token_logits = next_token_logits / temperature
1331
+
1332
+ scores = F.log_softmax(next_token_logits, dim=-1) # (batch_size * num_beams, vocab_size)
1333
+ if self.config.is_encoder_decoder and do_sample is False:
1334
+ # TODO (PVP) still a bit hacky here - there might be a better solutino
1335
+ scores = self.prepare_scores_for_generation(scores, cur_len=cur_len, max_length=max_length)
1336
+
1337
+ # set eos token prob to zero if min_length is not reached
1338
+ if eos_token_id is not None and cur_len < min_length:
1339
+ scores[:, eos_token_id] = -float("inf")
1340
+
1341
+ if no_repeat_ngram_size > 0:
1342
+ # calculate a list of banned tokens to prevent repetitively generating the same ngrams
1343
+ num_batch_hypotheses = batch_size * num_beams
1344
+ # from fairseq: https://github.com/pytorch/fairseq/blob/a07cb6f40480928c9e0548b737aadd36ee66ac76/fairseq/sequence_generator.py#L345
1345
+ banned_batch_tokens = calc_banned_ngram_tokens(
1346
+ input_ids, num_batch_hypotheses, no_repeat_ngram_size, cur_len
1347
+ )
1348
+ for i, banned_tokens in enumerate(banned_batch_tokens):
1349
+ scores[i, banned_tokens] = -float("inf")
1350
+
1351
+ if bad_words_ids is not None:
1352
+ # calculate a list of banned tokens according to bad words
1353
+ banned_tokens = calc_banned_bad_words_ids(input_ids, bad_words_ids)
1354
+
1355
+ for i, banned_tokens in enumerate(banned_tokens):
1356
+ scores[i, banned_tokens] = -float("inf")
1357
+
1358
+ assert scores.shape == (batch_size * num_beams, vocab_size), "Shapes of scores: {} != {}".format(
1359
+ scores.shape, (batch_size * num_beams, vocab_size)
1360
+ )
1361
+
1362
+ if do_sample:
1363
+ _scores = scores + beam_scores[:, None].expand_as(scores) # (batch_size * num_beams, vocab_size)
1364
+ # Top-p/top-k filtering
1365
+ _scores = top_k_top_p_filtering(
1366
+ _scores, top_k=top_k, top_p=top_p, min_tokens_to_keep=2
1367
+ ) # (batch_size * num_beams, vocab_size)
1368
+ # re-organize to group the beam together to sample from all beam_idxs
1369
+ _scores = _scores.contiguous().view(
1370
+ batch_size, num_beams * vocab_size
1371
+ ) # (batch_size, num_beams * vocab_size)
1372
+
1373
+ # Sample 2 next tokens for each beam (so we have some spare tokens and match output of greedy beam search)
1374
+ probs = F.softmax(_scores, dim=-1)
1375
+ next_tokens = torch.multinomial(probs, num_samples=2 * num_beams) # (batch_size, num_beams * 2)
1376
+ # Compute next scores
1377
+ next_scores = torch.gather(_scores, -1, next_tokens) # (batch_size, num_beams * 2)
1378
+ # sort the sampled vector to make sure that the first num_beams samples are the best
1379
+ next_scores, next_scores_indices = torch.sort(next_scores, descending=True, dim=1)
1380
+ next_tokens = torch.gather(next_tokens, -1, next_scores_indices) # (batch_size, num_beams * 2)
1381
+
1382
+ else:
1383
+ next_scores = scores + beam_scores[:, None].expand_as(scores) # (batch_size * num_beams, vocab_size)
1384
+
1385
+ # re-organize to group the beam together (we are keeping top hypothesis accross beams)
1386
+ next_scores = next_scores.view(
1387
+ batch_size, num_beams * vocab_size
1388
+ ) # (batch_size, num_beams * vocab_size)
1389
+
1390
+ next_scores, next_tokens = torch.topk(next_scores, 2 * num_beams, dim=1, largest=True, sorted=True)
1391
+
1392
+ assert next_scores.size() == next_tokens.size() == (batch_size, 2 * num_beams)
1393
+
1394
+ # next batch beam content
1395
+ next_batch_beam = []
1396
+
1397
+ # for each sentence
1398
+ for batch_idx in range(batch_size):
1399
+
1400
+ # if we are done with this sentence
1401
+ if done[batch_idx]:
1402
+ assert (
1403
+ len(generated_hyps[batch_idx]) >= num_beams
1404
+ ), "Batch can only be done if at least {} beams have been generated".format(num_beams)
1405
+ assert (
1406
+ eos_token_id is not None and pad_token_id is not None
1407
+ ), "generated beams >= num_beams -> eos_token_id and pad_token have to be defined"
1408
+ next_batch_beam.extend([(0, pad_token_id, 0)] * num_beams) # pad the batch
1409
+ continue
1410
+
1411
+ # next sentence beam content
1412
+ next_sent_beam = []
1413
+
1414
+ # next tokens for this sentence
1415
+ for beam_token_rank, (beam_token_id, beam_token_score) in enumerate(
1416
+ zip(next_tokens[batch_idx], next_scores[batch_idx])
1417
+ ):
1418
+ # get beam and token IDs
1419
+ beam_id = beam_token_id // vocab_size
1420
+ token_id = beam_token_id % vocab_size
1421
+
1422
+ effective_beam_id = batch_idx * num_beams + beam_id
1423
+ # add to generated hypotheses if end of sentence or last iteration
1424
+ if (eos_token_id is not None) and (token_id.item() == eos_token_id):
1425
+ # if beam_token does not belong to top num_beams tokens, it should not be added
1426
+ is_beam_token_worse_than_top_num_beams = beam_token_rank >= num_beams
1427
+ if is_beam_token_worse_than_top_num_beams:
1428
+ continue
1429
+ generated_hyps[batch_idx].add(
1430
+ input_ids[effective_beam_id].clone(), beam_token_score.item(),
1431
+ )
1432
+ else:
1433
+ # add next predicted token if it is not eos_token
1434
+ next_sent_beam.append((beam_token_score, token_id, effective_beam_id))
1435
+
1436
+ # the beam for next step is full
1437
+ if len(next_sent_beam) == num_beams:
1438
+ break
1439
+
1440
+ # Check if were done so that we can save a pad step if all(done)
1441
+ done[batch_idx] = done[batch_idx] or generated_hyps[batch_idx].is_done(
1442
+ next_scores[batch_idx].max().item(), cur_len=cur_len
1443
+ )
1444
+
1445
+ # update next beam content
1446
+ assert len(next_sent_beam) == num_beams, "Beam should always be full"
1447
+ next_batch_beam.extend(next_sent_beam)
1448
+ assert len(next_batch_beam) == num_beams * (batch_idx + 1)
1449
+
1450
+ # stop when we are done with each sentence
1451
+ if all(done):
1452
+ break
1453
+
1454
+ # sanity check / prepare next batch
1455
+ assert len(next_batch_beam) == batch_size * num_beams
1456
+ beam_scores = beam_scores.new([x[0] for x in next_batch_beam])
1457
+ beam_tokens = input_ids.new([x[1] for x in next_batch_beam])
1458
+ beam_idx = input_ids.new([x[2] for x in next_batch_beam])
1459
+
1460
+ # re-order batch
1461
+ input_ids = input_ids[beam_idx, :]
1462
+ input_ids = torch.cat([input_ids, beam_tokens.unsqueeze(1)], dim=-1)
1463
+ # re-order internal states
1464
+ if past is not None:
1465
+ past = self._reorder_cache(past, beam_idx)
1466
+
1467
+ # extend attention_mask for new generated input if only decoder
1468
+ if self.config.is_encoder_decoder is False:
1469
+ attention_mask = torch.cat(
1470
+ [attention_mask, attention_mask.new_ones((attention_mask.shape[0], 1))], dim=-1
1471
+ )
1472
+
1473
+ # update current length
1474
+ cur_len = cur_len + 1
1475
+
1476
+ # finalize all open beam hypotheses and end to generated hypotheses
1477
+ for batch_idx in range(batch_size):
1478
+ if done[batch_idx]:
1479
+ continue
1480
+
1481
+ # test that beam scores match previously calculated scores if not eos and batch_idx not done
1482
+ if eos_token_id is not None and all(
1483
+ (token_id % vocab_size).item() is not eos_token_id for token_id in next_tokens[batch_idx]
1484
+ ):
1485
+ assert torch.all(
1486
+ next_scores[batch_idx, :num_beams] == beam_scores.view(batch_size, num_beams)[batch_idx]
1487
+ ), "If batch_idx is not done, final next scores: {} have to equal to accumulated beam_scores: {}".format(
1488
+ next_scores[:, :num_beams][batch_idx], beam_scores.view(batch_size, num_beams)[batch_idx],
1489
+ )
1490
+
1491
+ # need to add best num_beams hypotheses to generated hyps
1492
+ for beam_id in range(num_beams):
1493
+ effective_beam_id = batch_idx * num_beams + beam_id
1494
+ final_score = beam_scores[effective_beam_id].item()
1495
+ final_tokens = input_ids[effective_beam_id]
1496
+ generated_hyps[batch_idx].add(final_tokens, final_score)
1497
+
1498
+ # depending on whether greedy generation is wanted or not define different output_batch_size and output_num_return_sequences_per_batch
1499
+ output_batch_size = batch_size if do_sample else batch_size * num_return_sequences
1500
+ output_num_return_sequences_per_batch = 1 if do_sample else num_return_sequences
1501
+
1502
+ # select the best hypotheses
1503
+ sent_lengths = input_ids.new(output_batch_size)
1504
+ best = []
1505
+
1506
+ # retrieve best hypotheses
1507
+ for i, hypotheses in enumerate(generated_hyps):
1508
+ sorted_hyps = sorted(hypotheses.beams, key=lambda x: x[0])
1509
+ for j in range(output_num_return_sequences_per_batch):
1510
+ effective_batch_idx = output_num_return_sequences_per_batch * i + j
1511
+ best_hyp = sorted_hyps.pop()[1]
1512
+ sent_lengths[effective_batch_idx] = len(best_hyp)
1513
+ best.append(best_hyp)
1514
+
1515
+ # shorter batches are filled with pad_token
1516
+ if sent_lengths.min().item() != sent_lengths.max().item():
1517
+ assert pad_token_id is not None, "`Pad_token_id` has to be defined"
1518
+ sent_max_len = min(sent_lengths.max().item() + 1, max_length)
1519
+ decoded = input_ids.new(output_batch_size, sent_max_len).fill_(pad_token_id)
1520
+
1521
+ # fill with hypothesis and eos_token_id if necessary
1522
+ for i, hypo in enumerate(best):
1523
+ decoded[i, : sent_lengths[i]] = hypo
1524
+ if sent_lengths[i] < max_length:
1525
+ decoded[i, sent_lengths[i]] = eos_token_id
1526
+ else:
1527
+ # none of the hypotheses have an eos_token
1528
+ assert (len(hypo) == max_length for hypo in best)
1529
+ decoded = torch.stack(best).type(torch.long).to(next(self.parameters()).device)
1530
+
1531
+ return decoded
1532
+
1533
+ # force one of token_ids to be generated by setting prob of all other tokens to 0.
1534
+ def _force_token_ids_generation(self, scores, token_ids) -> None:
1535
+ if isinstance(token_ids, int):
1536
+ token_ids = [token_ids]
1537
+ all_but_token_ids_mask = torch.tensor(
1538
+ [x for x in range(self.config.vocab_size) if x not in token_ids],
1539
+ dtype=torch.long,
1540
+ device=next(self.parameters()).device,
1541
+ )
1542
+ assert len(scores.shape) == 2, "scores should be of rank 2 with shape: [batch_size, vocab_size]"
1543
+ scores[:, all_but_token_ids_mask] = -float("inf")
1544
+
1545
+ @staticmethod
1546
+ def _reorder_cache(past: Tuple, beam_idx: Tensor) -> Tuple[Tensor]:
1547
+ return tuple(layer_past.index_select(1, beam_idx) for layer_past in past)
1548
+
1549
+
1550
+ def calc_banned_ngram_tokens(prev_input_ids: Tensor, num_hypos: int, no_repeat_ngram_size: int, cur_len: int) -> None:
1551
+ """Copied from fairseq for no_repeat_ngram in beam_search"""
1552
+ if cur_len + 1 < no_repeat_ngram_size:
1553
+ # return no banned tokens if we haven't generated no_repeat_ngram_size tokens yet
1554
+ return [[] for _ in range(num_hypos)]
1555
+ generated_ngrams = [{} for _ in range(num_hypos)]
1556
+ for idx in range(num_hypos):
1557
+ gen_tokens = prev_input_ids[idx].tolist()
1558
+ generated_ngram = generated_ngrams[idx]
1559
+ for ngram in zip(*[gen_tokens[i:] for i in range(no_repeat_ngram_size)]):
1560
+ prev_ngram_tuple = tuple(ngram[:-1])
1561
+ generated_ngram[prev_ngram_tuple] = generated_ngram.get(prev_ngram_tuple, []) + [ngram[-1]]
1562
+
1563
+ def _get_generated_ngrams(hypo_idx):
1564
+ # Before decoding the next token, prevent decoding of ngrams that have already appeared
1565
+ start_idx = cur_len + 1 - no_repeat_ngram_size
1566
+ ngram_idx = tuple(prev_input_ids[hypo_idx, start_idx:cur_len].tolist())
1567
+ return generated_ngrams[hypo_idx].get(ngram_idx, [])
1568
+
1569
+ banned_tokens = [_get_generated_ngrams(hypo_idx) for hypo_idx in range(num_hypos)]
1570
+ return banned_tokens
1571
+
1572
+
1573
+ def calc_banned_bad_words_ids(prev_input_ids, bad_words_ids):
1574
+ banned_tokens = []
1575
+
1576
+ def _tokens_match(prev_tokens, tokens):
1577
+ if len(tokens) == 0:
1578
+ # if bad word tokens is just one token always ban it
1579
+ return True
1580
+ if len(tokens) > len(prev_input_ids):
1581
+ # if bad word tokens are longer then prev input_ids they can't be equal
1582
+ return False
1583
+
1584
+ if prev_tokens[-len(tokens) :] == tokens:
1585
+ # if tokens match
1586
+ return True
1587
+ else:
1588
+ return False
1589
+
1590
+ for prev_input_ids_slice in prev_input_ids:
1591
+ banned_tokens_slice = []
1592
+
1593
+ for banned_token_seq in bad_words_ids:
1594
+ assert len(banned_token_seq) > 0, "Banned words token sequences {} cannot have an empty list".format(
1595
+ bad_words_ids
1596
+ )
1597
+
1598
+ if _tokens_match(prev_input_ids_slice.tolist(), banned_token_seq[:-1]) is False:
1599
+ # if tokens do not match continue
1600
+ continue
1601
+
1602
+ banned_tokens_slice.append(banned_token_seq[-1])
1603
+
1604
+ banned_tokens.append(banned_tokens_slice)
1605
+
1606
+ return banned_tokens
1607
+
1608
+
1609
+ def top_k_top_p_filtering(logits, top_k=0, top_p=1.0, filter_value=-float("Inf"), min_tokens_to_keep=1):
1610
+ """ Filter a distribution of logits using top-k and/or nucleus (top-p) filtering
1611
+ Args:
1612
+ logits: logits distribution shape (batch size, vocabulary size)
1613
+ if top_k > 0: keep only top k tokens with highest probability (top-k filtering).
1614
+ if top_p < 1.0: keep the top tokens with cumulative probability >= top_p (nucleus filtering).
1615
+ Nucleus filtering is described in Holtzman et al. (http://arxiv.org/abs/1904.09751)
1616
+ Make sure we keep at least min_tokens_to_keep per batch example in the output
1617
+ From: https://gist.github.com/thomwolf/1a5a29f6962089e871b94cbd09daf317
1618
+ """
1619
+ if top_k > 0:
1620
+ top_k = min(max(top_k, min_tokens_to_keep), logits.size(-1)) # Safety check
1621
+ # Remove all tokens with a probability less than the last token of the top-k
1622
+ indices_to_remove = logits < torch.topk(logits, top_k)[0][..., -1, None]
1623
+ logits[indices_to_remove] = filter_value
1624
+
1625
+ if top_p < 1.0:
1626
+ sorted_logits, sorted_indices = torch.sort(logits, descending=True)
1627
+ cumulative_probs = torch.cumsum(F.softmax(sorted_logits, dim=-1), dim=-1)
1628
+
1629
+ # Remove tokens with cumulative probability above the threshold (token with 0 are kept)
1630
+ sorted_indices_to_remove = cumulative_probs > top_p
1631
+ if min_tokens_to_keep > 1:
1632
+ # Keep at least min_tokens_to_keep (set to min_tokens_to_keep-1 because we add the first one below)
1633
+ sorted_indices_to_remove[..., :min_tokens_to_keep] = 0
1634
+ # Shift the indices to the right to keep also the first token above the threshold
1635
+ sorted_indices_to_remove[..., 1:] = sorted_indices_to_remove[..., :-1].clone()
1636
+ sorted_indices_to_remove[..., 0] = 0
1637
+
1638
+ # scatter sorted tensors to original indexing
1639
+ indices_to_remove = sorted_indices_to_remove.scatter(1, sorted_indices, sorted_indices_to_remove)
1640
+ logits[indices_to_remove] = filter_value
1641
+ return logits
1642
+
1643
+
1644
+ class BeamHypotheses(object):
1645
+ def __init__(self, num_beams, max_length, length_penalty, early_stopping):
1646
+ """
1647
+ Initialize n-best list of hypotheses.
1648
+ """
1649
+ self.max_length = max_length - 1 # ignoring bos_token
1650
+ self.length_penalty = length_penalty
1651
+ self.early_stopping = early_stopping
1652
+ self.num_beams = num_beams
1653
+ self.beams = []
1654
+ self.worst_score = 1e9
1655
+
1656
+ def __len__(self):
1657
+ """
1658
+ Number of hypotheses in the list.
1659
+ """
1660
+ return len(self.beams)
1661
+
1662
+ def add(self, hyp, sum_logprobs):
1663
+ """
1664
+ Add a new hypothesis to the list.
1665
+ """
1666
+ score = sum_logprobs / len(hyp) ** self.length_penalty
1667
+ if len(self) < self.num_beams or score > self.worst_score:
1668
+ self.beams.append((score, hyp))
1669
+ if len(self) > self.num_beams:
1670
+ sorted_scores = sorted([(s, idx) for idx, (s, _) in enumerate(self.beams)])
1671
+ del self.beams[sorted_scores[0][1]]
1672
+ self.worst_score = sorted_scores[1][0]
1673
+ else:
1674
+ self.worst_score = min(score, self.worst_score)
1675
+
1676
+ def is_done(self, best_sum_logprobs, cur_len=None):
1677
+ """
1678
+ If there are enough hypotheses and that none of the hypotheses being generated
1679
+ can become better than the worst one in the heap, then we are done with this sentence.
1680
+ """
1681
+
1682
+ if len(self) < self.num_beams:
1683
+ return False
1684
+ elif self.early_stopping:
1685
+ return True
1686
+ else:
1687
+ if cur_len is None:
1688
+ cur_len = self.max_length
1689
+ cur_score = best_sum_logprobs / cur_len ** self.length_penalty
1690
+ ret = self.worst_score >= cur_score
1691
+ return ret
1692
+
1693
+
1694
+ class Conv1D(nn.Module):
1695
+ def __init__(self, nf, nx):
1696
+ """ Conv1D layer as defined by Radford et al. for OpenAI GPT (and also used in GPT-2)
1697
+ Basically works like a Linear layer but the weights are transposed
1698
+ """
1699
+ super().__init__()
1700
+ self.nf = nf
1701
+ w = torch.empty(nx, nf)
1702
+ nn.init.normal_(w, std=0.02)
1703
+ self.weight = nn.Parameter(w)
1704
+ self.bias = nn.Parameter(torch.zeros(nf))
1705
+
1706
+ def forward(self, x):
1707
+ size_out = x.size()[:-1] + (self.nf,)
1708
+ x = torch.addmm(self.bias, x.view(-1, x.size(-1)), self.weight)
1709
+ x = x.view(*size_out)
1710
+ return x
1711
+
1712
+
1713
+ class PoolerStartLogits(nn.Module):
1714
+ """ Compute SQuAD start_logits from sequence hidden states. """
1715
+
1716
+ def __init__(self, config):
1717
+ super().__init__()
1718
+ self.dense = nn.Linear(config.hidden_size, 1)
1719
+
1720
+ def forward(self, hidden_states, p_mask=None):
1721
+ """ Args:
1722
+ **p_mask**: (`optional`) ``torch.FloatTensor`` of shape `(batch_size, seq_len)`
1723
+ invalid position mask such as query and special symbols (PAD, SEP, CLS)
1724
+ 1.0 means token should be masked.
1725
+ """
1726
+ x = self.dense(hidden_states).squeeze(-1)
1727
+
1728
+ if p_mask is not None:
1729
+ if next(self.parameters()).dtype == torch.float16:
1730
+ x = x * (1 - p_mask) - 65500 * p_mask
1731
+ else:
1732
+ x = x * (1 - p_mask) - 1e30 * p_mask
1733
+
1734
+ return x
1735
+
1736
+
1737
+ class PoolerEndLogits(nn.Module):
1738
+ """ Compute SQuAD end_logits from sequence hidden states and start token hidden state.
1739
+ """
1740
+
1741
+ def __init__(self, config):
1742
+ super().__init__()
1743
+ self.dense_0 = nn.Linear(config.hidden_size * 2, config.hidden_size)
1744
+ self.activation = nn.Tanh()
1745
+ self.LayerNorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps)
1746
+ self.dense_1 = nn.Linear(config.hidden_size, 1)
1747
+
1748
+ def forward(self, hidden_states, start_states=None, start_positions=None, p_mask=None):
1749
+ """ Args:
1750
+ One of ``start_states``, ``start_positions`` should be not None.
1751
+ If both are set, ``start_positions`` overrides ``start_states``.
1752
+
1753
+ **start_states**: ``torch.LongTensor`` of shape identical to hidden_states
1754
+ hidden states of the first tokens for the labeled span.
1755
+ **start_positions**: ``torch.LongTensor`` of shape ``(batch_size,)``
1756
+ position of the first token for the labeled span:
1757
+ **p_mask**: (`optional`) ``torch.FloatTensor`` of shape ``(batch_size, seq_len)``
1758
+ Mask of invalid position such as query and special symbols (PAD, SEP, CLS)
1759
+ 1.0 means token should be masked.
1760
+ """
1761
+ assert (
1762
+ start_states is not None or start_positions is not None
1763
+ ), "One of start_states, start_positions should be not None"
1764
+ if start_positions is not None:
1765
+ slen, hsz = hidden_states.shape[-2:]
1766
+ start_positions = start_positions[:, None, None].expand(-1, -1, hsz) # shape (bsz, 1, hsz)
1767
+ start_states = hidden_states.gather(-2, start_positions) # shape (bsz, 1, hsz)
1768
+ start_states = start_states.expand(-1, slen, -1) # shape (bsz, slen, hsz)
1769
+
1770
+ x = self.dense_0(torch.cat([hidden_states, start_states], dim=-1))
1771
+ x = self.activation(x)
1772
+ x = self.LayerNorm(x)
1773
+ x = self.dense_1(x).squeeze(-1)
1774
+
1775
+ if p_mask is not None:
1776
+ if next(self.parameters()).dtype == torch.float16:
1777
+ x = x * (1 - p_mask) - 65500 * p_mask
1778
+ else:
1779
+ x = x * (1 - p_mask) - 1e30 * p_mask
1780
+
1781
+ return x
1782
+
1783
+
1784
+ class PoolerAnswerClass(nn.Module):
1785
+ """ Compute SQuAD 2.0 answer class from classification and start tokens hidden states. """
1786
+
1787
+ def __init__(self, config):
1788
+ super().__init__()
1789
+ self.dense_0 = nn.Linear(config.hidden_size * 2, config.hidden_size)
1790
+ self.activation = nn.Tanh()
1791
+ self.dense_1 = nn.Linear(config.hidden_size, 1, bias=False)
1792
+
1793
+ def forward(self, hidden_states, start_states=None, start_positions=None, cls_index=None):
1794
+ """
1795
+ Args:
1796
+ One of ``start_states``, ``start_positions`` should be not None.
1797
+ If both are set, ``start_positions`` overrides ``start_states``.
1798
+
1799
+ **start_states**: ``torch.LongTensor`` of shape identical to ``hidden_states``.
1800
+ hidden states of the first tokens for the labeled span.
1801
+ **start_positions**: ``torch.LongTensor`` of shape ``(batch_size,)``
1802
+ position of the first token for the labeled span.
1803
+ **cls_index**: torch.LongTensor of shape ``(batch_size,)``
1804
+ position of the CLS token. If None, take the last token.
1805
+
1806
+ note(Original repo):
1807
+ no dependency on end_feature so that we can obtain one single `cls_logits`
1808
+ for each sample
1809
+ """
1810
+ hsz = hidden_states.shape[-1]
1811
+ assert (
1812
+ start_states is not None or start_positions is not None
1813
+ ), "One of start_states, start_positions should be not None"
1814
+ if start_positions is not None:
1815
+ start_positions = start_positions[:, None, None].expand(-1, -1, hsz) # shape (bsz, 1, hsz)
1816
+ start_states = hidden_states.gather(-2, start_positions).squeeze(-2) # shape (bsz, hsz)
1817
+
1818
+ if cls_index is not None:
1819
+ cls_index = cls_index[:, None, None].expand(-1, -1, hsz) # shape (bsz, 1, hsz)
1820
+ cls_token_state = hidden_states.gather(-2, cls_index).squeeze(-2) # shape (bsz, hsz)
1821
+ else:
1822
+ cls_token_state = hidden_states[:, -1, :] # shape (bsz, hsz)
1823
+
1824
+ x = self.dense_0(torch.cat([start_states, cls_token_state], dim=-1))
1825
+ x = self.activation(x)
1826
+ x = self.dense_1(x).squeeze(-1)
1827
+
1828
+ return x
1829
+
1830
+
1831
+ class SQuADHead(nn.Module):
1832
+ r""" A SQuAD head inspired by XLNet.
1833
+
1834
+ Parameters:
1835
+ config (:class:`~transformers.XLNetConfig`): Model configuration class with all the parameters of the model.
1836
+
1837
+ Inputs:
1838
+ **hidden_states**: ``torch.FloatTensor`` of shape ``(batch_size, seq_len, hidden_size)``
1839
+ hidden states of sequence tokens
1840
+ **start_positions**: ``torch.LongTensor`` of shape ``(batch_size,)``
1841
+ position of the first token for the labeled span.
1842
+ **end_positions**: ``torch.LongTensor`` of shape ``(batch_size,)``
1843
+ position of the last token for the labeled span.
1844
+ **cls_index**: torch.LongTensor of shape ``(batch_size,)``
1845
+ position of the CLS token. If None, take the last token.
1846
+ **is_impossible**: ``torch.LongTensor`` of shape ``(batch_size,)``
1847
+ Whether the question has a possible answer in the paragraph or not.
1848
+ **p_mask**: (`optional`) ``torch.FloatTensor`` of shape ``(batch_size, seq_len)``
1849
+ Mask of invalid position such as query and special symbols (PAD, SEP, CLS)
1850
+ 1.0 means token should be masked.
1851
+
1852
+ Outputs: `Tuple` comprising various elements depending on the configuration (config) and inputs:
1853
+ **loss**: (`optional`, returned if both ``start_positions`` and ``end_positions`` are provided) ``torch.FloatTensor`` of shape ``(1,)``:
1854
+ Classification loss as the sum of start token, end token (and is_impossible if provided) classification losses.
1855
+ **start_top_log_probs**: (`optional`, returned if ``start_positions`` or ``end_positions`` is not provided)
1856
+ ``torch.FloatTensor`` of shape ``(batch_size, config.start_n_top)``
1857
+ Log probabilities for the top config.start_n_top start token possibilities (beam-search).
1858
+ **start_top_index**: (`optional`, returned if ``start_positions`` or ``end_positions`` is not provided)
1859
+ ``torch.LongTensor`` of shape ``(batch_size, config.start_n_top)``
1860
+ Indices for the top config.start_n_top start token possibilities (beam-search).
1861
+ **end_top_log_probs**: (`optional`, returned if ``start_positions`` or ``end_positions`` is not provided)
1862
+ ``torch.FloatTensor`` of shape ``(batch_size, config.start_n_top * config.end_n_top)``
1863
+ Log probabilities for the top ``config.start_n_top * config.end_n_top`` end token possibilities (beam-search).
1864
+ **end_top_index**: (`optional`, returned if ``start_positions`` or ``end_positions`` is not provided)
1865
+ ``torch.LongTensor`` of shape ``(batch_size, config.start_n_top * config.end_n_top)``
1866
+ Indices for the top ``config.start_n_top * config.end_n_top`` end token possibilities (beam-search).
1867
+ **cls_logits**: (`optional`, returned if ``start_positions`` or ``end_positions`` is not provided)
1868
+ ``torch.FloatTensor`` of shape ``(batch_size,)``
1869
+ Log probabilities for the ``is_impossible`` label of the answers.
1870
+ """
1871
+
1872
+ def __init__(self, config):
1873
+ super().__init__()
1874
+ self.start_n_top = config.start_n_top
1875
+ self.end_n_top = config.end_n_top
1876
+
1877
+ self.start_logits = PoolerStartLogits(config)
1878
+ self.end_logits = PoolerEndLogits(config)
1879
+ self.answer_class = PoolerAnswerClass(config)
1880
+
1881
+ def forward(
1882
+ self, hidden_states, start_positions=None, end_positions=None, cls_index=None, is_impossible=None, p_mask=None,
1883
+ ):
1884
+ outputs = ()
1885
+
1886
+ start_logits = self.start_logits(hidden_states, p_mask=p_mask)
1887
+
1888
+ if start_positions is not None and end_positions is not None:
1889
+ # If we are on multi-GPU, let's remove the dimension added by batch splitting
1890
+ for x in (start_positions, end_positions, cls_index, is_impossible):
1891
+ if x is not None and x.dim() > 1:
1892
+ x.squeeze_(-1)
1893
+
1894
+ # during training, compute the end logits based on the ground truth of the start position
1895
+ end_logits = self.end_logits(hidden_states, start_positions=start_positions, p_mask=p_mask)
1896
+
1897
+ loss_fct = CrossEntropyLoss()
1898
+ start_loss = loss_fct(start_logits, start_positions)
1899
+ end_loss = loss_fct(end_logits, end_positions)
1900
+ total_loss = (start_loss + end_loss) / 2
1901
+
1902
+ if cls_index is not None and is_impossible is not None:
1903
+ # Predict answerability from the representation of CLS and START
1904
+ cls_logits = self.answer_class(hidden_states, start_positions=start_positions, cls_index=cls_index)
1905
+ loss_fct_cls = nn.BCEWithLogitsLoss()
1906
+ cls_loss = loss_fct_cls(cls_logits, is_impossible)
1907
+
1908
+ # note(zhiliny): by default multiply the loss by 0.5 so that the scale is comparable to start_loss and end_loss
1909
+ total_loss += cls_loss * 0.5
1910
+
1911
+ outputs = (total_loss,) + outputs
1912
+
1913
+ else:
1914
+ # during inference, compute the end logits based on beam search
1915
+ bsz, slen, hsz = hidden_states.size()
1916
+ start_log_probs = F.softmax(start_logits, dim=-1) # shape (bsz, slen)
1917
+
1918
+ start_top_log_probs, start_top_index = torch.topk(
1919
+ start_log_probs, self.start_n_top, dim=-1
1920
+ ) # shape (bsz, start_n_top)
1921
+ start_top_index_exp = start_top_index.unsqueeze(-1).expand(-1, -1, hsz) # shape (bsz, start_n_top, hsz)
1922
+ start_states = torch.gather(hidden_states, -2, start_top_index_exp) # shape (bsz, start_n_top, hsz)
1923
+ start_states = start_states.unsqueeze(1).expand(-1, slen, -1, -1) # shape (bsz, slen, start_n_top, hsz)
1924
+
1925
+ hidden_states_expanded = hidden_states.unsqueeze(2).expand_as(
1926
+ start_states
1927
+ ) # shape (bsz, slen, start_n_top, hsz)
1928
+ p_mask = p_mask.unsqueeze(-1) if p_mask is not None else None
1929
+ end_logits = self.end_logits(hidden_states_expanded, start_states=start_states, p_mask=p_mask)
1930
+ end_log_probs = F.softmax(end_logits, dim=1) # shape (bsz, slen, start_n_top)
1931
+
1932
+ end_top_log_probs, end_top_index = torch.topk(
1933
+ end_log_probs, self.end_n_top, dim=1
1934
+ ) # shape (bsz, end_n_top, start_n_top)
1935
+ end_top_log_probs = end_top_log_probs.view(-1, self.start_n_top * self.end_n_top)
1936
+ end_top_index = end_top_index.view(-1, self.start_n_top * self.end_n_top)
1937
+
1938
+ start_states = torch.einsum("blh,bl->bh", hidden_states, start_log_probs)
1939
+ cls_logits = self.answer_class(hidden_states, start_states=start_states, cls_index=cls_index)
1940
+
1941
+ outputs = (start_top_log_probs, start_top_index, end_top_log_probs, end_top_index, cls_logits,) + outputs
1942
+
1943
+ # return start_top_log_probs, start_top_index, end_top_log_probs, end_top_index, cls_logits
1944
+ # or (if labels are provided) (total_loss,)
1945
+ return outputs
1946
+
1947
+
1948
+ class SequenceSummary(nn.Module):
1949
+ r""" Compute a single vector summary of a sequence hidden states according to various possibilities:
1950
+ Args of the config class:
1951
+ summary_type:
1952
+ - 'last' => [default] take the last token hidden state (like XLNet)
1953
+ - 'first' => take the first token hidden state (like Bert)
1954
+ - 'mean' => take the mean of all tokens hidden states
1955
+ - 'cls_index' => supply a Tensor of classification token position (GPT/GPT-2)
1956
+ - 'attn' => Not implemented now, use multi-head attention
1957
+ summary_use_proj: Add a projection after the vector extraction
1958
+ summary_proj_to_labels: If True, the projection outputs to config.num_labels classes (otherwise to hidden_size). Default: False.
1959
+ summary_activation: 'tanh' or another string => add an activation to the output, Other => no activation. Default
1960
+ summary_first_dropout: Add a dropout before the projection and activation
1961
+ summary_last_dropout: Add a dropout after the projection and activation
1962
+ """
1963
+
1964
+ def __init__(self, config: PretrainedConfig):
1965
+ super().__init__()
1966
+
1967
+ self.summary_type = getattr(config, "summary_type", "last")
1968
+ if self.summary_type == "attn":
1969
+ # We should use a standard multi-head attention module with absolute positional embedding for that.
1970
+ # Cf. https://github.com/zihangdai/xlnet/blob/master/modeling.py#L253-L276
1971
+ # We can probably just use the multi-head attention module of PyTorch >=1.1.0
1972
+ raise NotImplementedError
1973
+
1974
+ self.summary = Identity()
1975
+ if hasattr(config, "summary_use_proj") and config.summary_use_proj:
1976
+ if hasattr(config, "summary_proj_to_labels") and config.summary_proj_to_labels and config.num_labels > 0:
1977
+ num_classes = config.num_labels
1978
+ else:
1979
+ num_classes = config.hidden_size
1980
+ self.summary = nn.Linear(config.hidden_size, num_classes)
1981
+
1982
+ activation_string = getattr(config, "summary_activation", None)
1983
+ self.activation: Callable = (get_activation(activation_string) if activation_string else Identity())
1984
+
1985
+ self.first_dropout = Identity()
1986
+ if hasattr(config, "summary_first_dropout") and config.summary_first_dropout > 0:
1987
+ self.first_dropout = nn.Dropout(config.summary_first_dropout)
1988
+
1989
+ self.last_dropout = Identity()
1990
+ if hasattr(config, "summary_last_dropout") and config.summary_last_dropout > 0:
1991
+ self.last_dropout = nn.Dropout(config.summary_last_dropout)
1992
+
1993
+ def forward(self, hidden_states, cls_index=None):
1994
+ """ hidden_states: float Tensor in shape [bsz, ..., seq_len, hidden_size], the hidden-states of the last layer.
1995
+ cls_index: [optional] position of the classification token if summary_type == 'cls_index',
1996
+ shape (bsz,) or more generally (bsz, ...) where ... are optional leading dimensions of hidden_states.
1997
+ if summary_type == 'cls_index' and cls_index is None:
1998
+ we take the last token of the sequence as classification token
1999
+ """
2000
+ if self.summary_type == "last":
2001
+ output = hidden_states[:, -1]
2002
+ elif self.summary_type == "first":
2003
+ output = hidden_states[:, 0]
2004
+ elif self.summary_type == "mean":
2005
+ output = hidden_states.mean(dim=1)
2006
+ elif self.summary_type == "cls_index":
2007
+ if cls_index is None:
2008
+ cls_index = torch.full_like(hidden_states[..., :1, :], hidden_states.shape[-2] - 1, dtype=torch.long,)
2009
+ else:
2010
+ cls_index = cls_index.unsqueeze(-1).unsqueeze(-1)
2011
+ cls_index = cls_index.expand((-1,) * (cls_index.dim() - 1) + (hidden_states.size(-1),))
2012
+ # shape of cls_index: (bsz, XX, 1, hidden_size) where XX are optional leading dim of hidden_states
2013
+ output = hidden_states.gather(-2, cls_index).squeeze(-2) # shape (bsz, XX, hidden_size)
2014
+ elif self.summary_type == "attn":
2015
+ raise NotImplementedError
2016
+
2017
+ output = self.first_dropout(output)
2018
+ output = self.summary(output)
2019
+ output = self.activation(output)
2020
+ output = self.last_dropout(output)
2021
+
2022
+ return output
2023
+
2024
+
2025
+ def create_position_ids_from_input_ids(input_ids, padding_idx):
2026
+ """ Replace non-padding symbols with their position numbers. Position numbers begin at
2027
+ padding_idx+1. Padding symbols are ignored. This is modified from fairseq's
2028
+ `utils.make_positions`.
2029
+
2030
+ :param torch.Tensor x:
2031
+ :return torch.Tensor:
2032
+ """
2033
+ # The series of casts and type-conversions here are carefully balanced to both work with ONNX export and XLA.
2034
+ mask = input_ids.ne(padding_idx).int()
2035
+ incremental_indices = torch.cumsum(mask, dim=1).type_as(mask) * mask
2036
+ return incremental_indices.long() + padding_idx
2037
+
2038
+
2039
+ def prune_linear_layer(layer, index, dim=0):
2040
+ """ Prune a linear layer (a model parameters) to keep only entries in index.
2041
+ Return the pruned layer as a new layer with requires_grad=True.
2042
+ Used to remove heads.
2043
+ """
2044
+ index = index.to(layer.weight.device)
2045
+ W = layer.weight.index_select(dim, index).clone().detach()
2046
+ if layer.bias is not None:
2047
+ if dim == 1:
2048
+ b = layer.bias.clone().detach()
2049
+ else:
2050
+ b = layer.bias[index].clone().detach()
2051
+ new_size = list(layer.weight.size())
2052
+ new_size[dim] = len(index)
2053
+ new_layer = nn.Linear(new_size[1], new_size[0], bias=layer.bias is not None).to(layer.weight.device)
2054
+ new_layer.weight.requires_grad = False
2055
+ new_layer.weight.copy_(W.contiguous())
2056
+ new_layer.weight.requires_grad = True
2057
+ if layer.bias is not None:
2058
+ new_layer.bias.requires_grad = False
2059
+ new_layer.bias.copy_(b.contiguous())
2060
+ new_layer.bias.requires_grad = True
2061
+ return new_layer
2062
+
2063
+
2064
+ def prune_conv1d_layer(layer, index, dim=1):
2065
+ """ Prune a Conv1D layer (a model parameters) to keep only entries in index.
2066
+ A Conv1D work as a Linear layer (see e.g. BERT) but the weights are transposed.
2067
+ Return the pruned layer as a new layer with requires_grad=True.
2068
+ Used to remove heads.
2069
+ """
2070
+ index = index.to(layer.weight.device)
2071
+ W = layer.weight.index_select(dim, index).clone().detach()
2072
+ if dim == 0:
2073
+ b = layer.bias.clone().detach()
2074
+ else:
2075
+ b = layer.bias[index].clone().detach()
2076
+ new_size = list(layer.weight.size())
2077
+ new_size[dim] = len(index)
2078
+ new_layer = Conv1D(new_size[1], new_size[0]).to(layer.weight.device)
2079
+ new_layer.weight.requires_grad = False
2080
+ new_layer.weight.copy_(W.contiguous())
2081
+ new_layer.weight.requires_grad = True
2082
+ new_layer.bias.requires_grad = False
2083
+ new_layer.bias.copy_(b.contiguous())
2084
+ new_layer.bias.requires_grad = True
2085
+ return new_layer
2086
+
2087
+
2088
+ def prune_layer(layer, index, dim=None):
2089
+ """ Prune a Conv1D or nn.Linear layer (a model parameters) to keep only entries in index.
2090
+ Return the pruned layer as a new layer with requires_grad=True.
2091
+ Used to remove heads.
2092
+ """
2093
+ if isinstance(layer, nn.Linear):
2094
+ return prune_linear_layer(layer, index, dim=0 if dim is None else dim)
2095
+ elif isinstance(layer, Conv1D):
2096
+ return prune_conv1d_layer(layer, index, dim=1 if dim is None else dim)
2097
+ else:
2098
+ raise ValueError("Can't prune layer of class {}".format(layer.__class__))
models/models.py ADDED
@@ -0,0 +1,263 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from .roberta import RobertaForTokenClassification, RobertaModel
2
+ import torch
3
+ import torch.nn as nn
4
+ from torch.nn import CrossEntropyLoss, MSELoss
5
+ import math
6
+ import torch.nn.functional as F
7
+
8
+ from .modeling_bert import BertEmbeddings, BertLayerNorm, BertModel, BertPreTrainedModel, gelu
9
+ from .configuration_roberta import RobertaConfig
10
+ from .file_utils import add_start_docstrings, add_start_docstrings_to_callable
11
+
12
+ from transformers import GPT2Model
13
+ from transformers import AutoModelWithLMHead, AutoTokenizer
14
+
15
+
16
+ ROBERTA_PRETRAINED_MODEL_ARCHIVE_MAP = {
17
+ "roberta-base": "https://s3.amazonaws.com/models.huggingface.co/bert/roberta-base-pytorch_model.bin",
18
+ "roberta-large": "https://s3.amazonaws.com/models.huggingface.co/bert/roberta-large-pytorch_model.bin",
19
+ "roberta-large-mnli": "https://s3.amazonaws.com/models.huggingface.co/bert/roberta-large-mnli-pytorch_model.bin",
20
+ "distilroberta-base": "https://s3.amazonaws.com/models.huggingface.co/bert/distilroberta-base-pytorch_model.bin",
21
+ "roberta-base-openai-detector": "https://s3.amazonaws.com/models.huggingface.co/bert/roberta-base-openai-detector-pytorch_model.bin",
22
+ "roberta-large-openai-detector": "https://s3.amazonaws.com/models.huggingface.co/bert/roberta-large-openai-detector-pytorch_model.bin",
23
+ }
24
+
25
+
26
+ class Norm(nn.Module):
27
+ def __init__(self, d_model, eps = 1e-6):
28
+ super().__init__()
29
+
30
+ self.size = d_model
31
+ # create two learnable parameters to calibrate normalisation
32
+ self.alpha = nn.Parameter(torch.ones(self.size))
33
+ self.bias = nn.Parameter(torch.zeros(self.size))
34
+ self.eps = eps
35
+ def forward(self, x):
36
+ norm = self.alpha * (x - x.mean(dim=-1, keepdim=True)) \
37
+ / (x.std(dim=-1, keepdim=True) + self.eps) + self.bias
38
+ return norm
39
+
40
+
41
+ class MultiHeadAttention(nn.Module):
42
+ def __init__(self, heads, d_model, dropout = 0.1):
43
+ super().__init__()
44
+
45
+ self.d_model = d_model
46
+ self.d_k = d_model // heads
47
+ self.h = heads
48
+
49
+ self.q_linear = nn.Linear(d_model, d_model)
50
+ self.v_linear = nn.Linear(d_model, d_model)
51
+ self.k_linear = nn.Linear(d_model, d_model)
52
+ self.dropout = nn.Dropout(dropout)
53
+ self.out = nn.Linear(d_model, d_model)
54
+
55
+ def forward(self, q, k, v, mask=None):
56
+
57
+ bs = q.size(0)
58
+
59
+ k = self.k_linear(k).view(bs, -1, self.h, self.d_k)
60
+ q = self.q_linear(q).view(bs, -1, self.h, self.d_k)
61
+ v = self.v_linear(v).view(bs, -1, self.h, self.d_k)
62
+
63
+ k = k.transpose(1,2)
64
+ q = q.transpose(1,2)
65
+ v = v.transpose(1,2)
66
+
67
+ scores = self.attention(q, k, v, self.d_k, mask, self.dropout)
68
+
69
+ concat = scores.transpose(1,2).contiguous()\
70
+ .view(bs, -1, self.d_model)
71
+
72
+ output = self.out(concat)
73
+
74
+ return output
75
+
76
+ def attention(self, q, k, v, d_k, mask=None, dropout=None):
77
+
78
+ scores = torch.matmul(q, k.transpose(-2, -1)) / math.sqrt(d_k)
79
+
80
+ if mask is not None:
81
+ mask = mask.unsqueeze(1)
82
+ scores = scores.masked_fill(mask == 0, -1e9)
83
+
84
+ scores = F.softmax(scores, dim=-1)
85
+
86
+ if dropout is not None:
87
+ scores = dropout(scores)
88
+
89
+ output = torch.matmul(scores, v)
90
+
91
+ return output
92
+
93
+
94
+ class SeekerEncoder(BertPreTrainedModel):
95
+ config_class = RobertaConfig
96
+ pretrained_model_archive_map = ROBERTA_PRETRAINED_MODEL_ARCHIVE_MAP
97
+ base_model_prefix = "roberta"
98
+
99
+ def __init__(self, config):
100
+ super().__init__(config)
101
+ self.num_labels = config.num_labels
102
+ self.roberta = RobertaModel(config)
103
+ self.init_weights()
104
+
105
+ def get_input_embeddings(self):
106
+ return self.roberta.embeddings.word_embeddings
107
+
108
+ def set_input_embeddings(self, value):
109
+ self.roberta.embeddings.word_embeddings = value
110
+
111
+
112
+ class ResponderEncoder(BertPreTrainedModel):
113
+ config_class = RobertaConfig
114
+ pretrained_model_archive_map = ROBERTA_PRETRAINED_MODEL_ARCHIVE_MAP
115
+ base_model_prefix = "roberta"
116
+
117
+ def __init__(self, config):
118
+ super().__init__(config)
119
+ self.roberta = RobertaModel(config)
120
+ self.init_weights()
121
+
122
+ def get_input_embeddings(self):
123
+ return self.roberta.embeddings.word_embeddings
124
+
125
+ def set_input_embeddings(self, value):
126
+ self.roberta.embeddings.word_embeddings = value
127
+
128
+ class BiEncoderAttentionWithRationaleClassification(nn.Module):
129
+
130
+ def __init__(self, hidden_dropout_prob=0.2, rationale_num_labels=2, empathy_num_labels=3, hidden_size=768, attn_heads = 1):
131
+ super().__init__()
132
+
133
+ self.dropout = nn.Dropout(hidden_dropout_prob)
134
+ self.rationale_classifier = nn.Linear(hidden_size, rationale_num_labels)
135
+ self.attn = MultiHeadAttention(attn_heads, hidden_size)
136
+ self.norm = Norm(hidden_size)
137
+ self.rationale_num_labels = rationale_num_labels
138
+ self.empathy_num_labels = empathy_num_labels
139
+ self.empathy_classifier = RobertaClassificationHead(hidden_size = 768)
140
+
141
+ self.apply(self._init_weights)
142
+
143
+ self.seeker_encoder = SeekerEncoder.from_pretrained(
144
+ "roberta-base", # Use the 12-layer BERT model, with an uncased vocab.
145
+ output_attentions = False, # Whether the model returns attentions weights.
146
+ output_hidden_states = False)
147
+
148
+ self.responder_encoder = ResponderEncoder.from_pretrained(
149
+ "roberta-base", # Use the 12-layer BERT model, with an uncased vocab.
150
+ output_attentions = False, # Whether the model returns attentions weights.
151
+ output_hidden_states = False)
152
+
153
+
154
+ def _init_weights(self, module):
155
+ """ Initialize the weights """
156
+ if isinstance(module, (nn.Linear, nn.Embedding)):
157
+ # Slightly different from the TF version which uses truncated_normal for initialization
158
+ # cf https://github.com/pytorch/pytorch/pull/5617
159
+ initializer_range=0.02
160
+ module.weight.data.normal_(mean=0.0, std=initializer_range)
161
+ elif isinstance(module, BertLayerNorm):
162
+ module.bias.data.zero_()
163
+ module.weight.data.fill_(1.0)
164
+ if isinstance(module, nn.Linear) and module.bias is not None:
165
+ module.bias.data.zero_()
166
+
167
+
168
+ # @add_start_docstrings_to_callable(ROBERTA_INPUTS_DOCSTRING)
169
+ def forward(
170
+ self,
171
+ input_ids_SP=None,
172
+ input_ids_RP=None,
173
+ attention_mask_SP=None,
174
+ attention_mask_RP=None,
175
+ token_type_ids_SP=None,
176
+ token_type_ids_RP=None,
177
+ position_ids_SP=None,
178
+ position_ids_RP=None,
179
+ head_mask_SP=None,
180
+ head_mask_RP=None,
181
+ inputs_embeds_SP=None,
182
+ inputs_embeds_RP=None,
183
+ empathy_labels=None,
184
+ rationale_labels=None,
185
+ lambda_EI=1,
186
+ lambda_RE=0.1
187
+ ):
188
+ outputs_SP = self.seeker_encoder.roberta(
189
+ input_ids_SP,
190
+ attention_mask=attention_mask_SP,
191
+ token_type_ids=token_type_ids_SP,
192
+ position_ids=position_ids_SP,
193
+ head_mask=head_mask_SP,
194
+ inputs_embeds=inputs_embeds_SP,
195
+ )
196
+
197
+
198
+ outputs_RP = self.responder_encoder.roberta(
199
+ input_ids_RP,
200
+ attention_mask=attention_mask_RP,
201
+ token_type_ids=token_type_ids_RP,
202
+ position_ids=position_ids_RP,
203
+ head_mask=head_mask_RP,
204
+ inputs_embeds=inputs_embeds_RP,
205
+ )
206
+
207
+ sequence_output_SP = outputs_SP[0]
208
+ sequence_output_RP = outputs_RP[0]
209
+
210
+ sequence_output_RP = sequence_output_RP + self.dropout(self.attn(sequence_output_RP, sequence_output_SP, sequence_output_SP))
211
+
212
+ logits_empathy = self.empathy_classifier(sequence_output_RP[:, 0, :]) # (sequence_output_RP[:, 0, :]) #(torch.tanh(concat_tensor))
213
+
214
+ sequence_output = self.dropout(sequence_output_RP)
215
+ logits_rationales = self.rationale_classifier(sequence_output)
216
+ outputs = (logits_empathy,logits_rationales) + outputs_RP[2:]
217
+
218
+ loss_rationales = 0.0
219
+ loss_empathy = 0.0
220
+
221
+ if rationale_labels is not None:
222
+ loss_fct = CrossEntropyLoss()
223
+ # Only keep active parts of the loss
224
+ if attention_mask_RP is not None:
225
+ active_loss = attention_mask_RP.view(-1) == 1
226
+ active_logits = logits_rationales.view(-1, self.rationale_num_labels)
227
+ active_labels = torch.where(
228
+ active_loss, rationale_labels.view(-1), torch.tensor(loss_fct.ignore_index).type_as(rationale_labels)
229
+ )
230
+ loss_rationales = loss_fct(active_logits, active_labels)
231
+ else:
232
+ loss_rationales = loss_fct(logits_rationales.view(-1, self.rationale_num_labels), rationale_labels.view(-1))
233
+
234
+ if empathy_labels is not None:
235
+ loss_fct = CrossEntropyLoss()
236
+ loss_empathy = loss_fct(logits_empathy.view(-1, self.empathy_num_labels), empathy_labels.view(-1))
237
+
238
+ loss = lambda_EI * loss_empathy + lambda_RE * loss_rationales
239
+
240
+ outputs = (loss, loss_empathy, loss_rationales) + outputs
241
+
242
+ return outputs # (loss), (scores_empathy, scores_rationales), (hidden_states), (attentions)
243
+
244
+
245
+
246
+ class RobertaClassificationHead(nn.Module):
247
+ """Head for sentence-level classification tasks."""
248
+
249
+ def __init__(self, hidden_dropout_prob=0.1, hidden_size=768, empathy_num_labels=3):
250
+ super().__init__()
251
+
252
+ self.dense = nn.Linear(hidden_size, hidden_size)
253
+ self.dropout = nn.Dropout(hidden_dropout_prob)
254
+ self.out_proj = nn.Linear(hidden_size, empathy_num_labels)
255
+
256
+ def forward(self, features, **kwargs):
257
+ x = features[:, :] # take <s> token (equiv. to [CLS])
258
+ x = self.dropout(x)
259
+ x = self.dense(x)
260
+ x = torch.relu(x)
261
+ x = self.dropout(x)
262
+ x = self.out_proj(x)
263
+ return x
models/roberta.py ADDED
@@ -0,0 +1,685 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # coding=utf-8
2
+ # Copyright 2018 The Google AI Language Team Authors and The HuggingFace Inc. team.
3
+ # Copyright (c) 2018, NVIDIA CORPORATION. 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 RoBERTa model. """
17
+
18
+
19
+ import logging
20
+
21
+ import torch
22
+ import torch.nn as nn
23
+ from torch.nn import CrossEntropyLoss, MSELoss
24
+
25
+ from .configuration_roberta import RobertaConfig
26
+ from .file_utils import add_start_docstrings, add_start_docstrings_to_callable
27
+ from .modeling_bert import BertEmbeddings, BertLayerNorm, BertModel, BertPreTrainedModel, gelu
28
+ from .modeling_utils import create_position_ids_from_input_ids
29
+
30
+
31
+ logger = logging.getLogger(__name__)
32
+
33
+ ROBERTA_PRETRAINED_MODEL_ARCHIVE_MAP = {
34
+ "roberta-base": "https://s3.amazonaws.com/models.huggingface.co/bert/roberta-base-pytorch_model.bin",
35
+ "roberta-large": "https://s3.amazonaws.com/models.huggingface.co/bert/roberta-large-pytorch_model.bin",
36
+ "roberta-large-mnli": "https://s3.amazonaws.com/models.huggingface.co/bert/roberta-large-mnli-pytorch_model.bin",
37
+ "distilroberta-base": "https://s3.amazonaws.com/models.huggingface.co/bert/distilroberta-base-pytorch_model.bin",
38
+ "roberta-base-openai-detector": "https://s3.amazonaws.com/models.huggingface.co/bert/roberta-base-openai-detector-pytorch_model.bin",
39
+ "roberta-large-openai-detector": "https://s3.amazonaws.com/models.huggingface.co/bert/roberta-large-openai-detector-pytorch_model.bin",
40
+ }
41
+
42
+
43
+ class RobertaEmbeddings(BertEmbeddings):
44
+ """
45
+ Same as BertEmbeddings with a tiny tweak for positional embeddings indexing.
46
+ """
47
+
48
+ def __init__(self, config):
49
+ super().__init__(config)
50
+ self.padding_idx = 1
51
+ self.word_embeddings = nn.Embedding(config.vocab_size, config.hidden_size, padding_idx=self.padding_idx)
52
+ self.position_embeddings = nn.Embedding(
53
+ config.max_position_embeddings, config.hidden_size, padding_idx=self.padding_idx
54
+ )
55
+
56
+ def forward(self, input_ids=None, token_type_ids=None, position_ids=None, inputs_embeds=None):
57
+ if position_ids is None:
58
+ if input_ids is not None:
59
+ # Create the position ids from the input token ids. Any padded tokens remain padded.
60
+ position_ids = create_position_ids_from_input_ids(input_ids, self.padding_idx).to(input_ids.device)
61
+ else:
62
+ position_ids = self.create_position_ids_from_inputs_embeds(inputs_embeds)
63
+
64
+ return super().forward(
65
+ input_ids, token_type_ids=token_type_ids, position_ids=position_ids, inputs_embeds=inputs_embeds
66
+ )
67
+
68
+ def create_position_ids_from_inputs_embeds(self, inputs_embeds):
69
+ """ We are provided embeddings directly. We cannot infer which are padded so just generate
70
+ sequential position ids.
71
+ :param torch.Tensor inputs_embeds:
72
+ :return torch.Tensor:
73
+ """
74
+ input_shape = inputs_embeds.size()[:-1]
75
+ sequence_length = input_shape[1]
76
+
77
+ position_ids = torch.arange(
78
+ self.padding_idx + 1, sequence_length + self.padding_idx + 1, dtype=torch.long, device=inputs_embeds.device
79
+ )
80
+ return position_ids.unsqueeze(0).expand(input_shape)
81
+
82
+
83
+ ROBERTA_START_DOCSTRING = r"""
84
+ This model is a PyTorch `torch.nn.Module <https://pytorch.org/docs/stable/nn.html#torch.nn.Module>`_ sub-class.
85
+ Use it as a regular PyTorch Module and refer to the PyTorch documentation for all matter related to general
86
+ usage and behavior.
87
+ Parameters:
88
+ config (:class:`~transformers.RobertaConfig`): Model configuration class with all the parameters of the
89
+ model. Initializing with a config file does not load the weights associated with the model, only the configuration.
90
+ Check out the :meth:`~transformers.PreTrainedModel.from_pretrained` method to load the model weights.
91
+ """
92
+
93
+ ROBERTA_INPUTS_DOCSTRING = r"""
94
+ Args:
95
+ input_ids (:obj:`torch.LongTensor` of shape :obj:`(batch_size, sequence_length)`):
96
+ Indices of input sequence tokens in the vocabulary.
97
+ Indices can be obtained using :class:`transformers.RobertaTokenizer`.
98
+ See :func:`transformers.PreTrainedTokenizer.encode` and
99
+ :func:`transformers.PreTrainedTokenizer.encode_plus` for details.
100
+ `What are input IDs? <../glossary.html#input-ids>`__
101
+ attention_mask (:obj:`torch.FloatTensor` of shape :obj:`(batch_size, sequence_length)`, `optional`, defaults to :obj:`None`):
102
+ Mask to avoid performing attention on padding token indices.
103
+ Mask values selected in ``[0, 1]``:
104
+ ``1`` for tokens that are NOT MASKED, ``0`` for MASKED tokens.
105
+ `What are attention masks? <../glossary.html#attention-mask>`__
106
+ token_type_ids (:obj:`torch.LongTensor` of shape :obj:`(batch_size, sequence_length)`, `optional`, defaults to :obj:`None`):
107
+ Segment token indices to indicate first and second portions of the inputs.
108
+ Indices are selected in ``[0, 1]``: ``0`` corresponds to a `sentence A` token, ``1``
109
+ corresponds to a `sentence B` token
110
+ `What are token type IDs? <../glossary.html#token-type-ids>`_
111
+ position_ids (:obj:`torch.LongTensor` of shape :obj:`(batch_size, sequence_length)`, `optional`, defaults to :obj:`None`):
112
+ Indices of positions of each input sequence tokens in the position embeddings.
113
+ Selected in the range ``[0, config.max_position_embeddings - 1]``.
114
+ `What are position IDs? <../glossary.html#position-ids>`_
115
+ head_mask (:obj:`torch.FloatTensor` of shape :obj:`(num_heads,)` or :obj:`(num_layers, num_heads)`, `optional`, defaults to :obj:`None`):
116
+ Mask to nullify selected heads of the self-attention modules.
117
+ Mask values selected in ``[0, 1]``:
118
+ :obj:`1` indicates the head is **not masked**, :obj:`0` indicates the head is **masked**.
119
+ inputs_embeds (:obj:`torch.FloatTensor` of shape :obj:`(batch_size, sequence_length, hidden_size)`, `optional`, defaults to :obj:`None`):
120
+ Optionally, instead of passing :obj:`input_ids` you can choose to directly pass an embedded representation.
121
+ This is useful if you want more control over how to convert `input_ids` indices into associated vectors
122
+ than the model's internal embedding lookup matrix.
123
+ """
124
+
125
+
126
+ @add_start_docstrings(
127
+ "The bare RoBERTa Model transformer outputting raw hidden-states without any specific head on top.",
128
+ ROBERTA_START_DOCSTRING,
129
+ )
130
+ class RobertaModel(BertModel):
131
+ """
132
+ This class overrides :class:`~transformers.BertModel`. Please check the
133
+ superclass for the appropriate documentation alongside usage examples.
134
+ """
135
+
136
+ config_class = RobertaConfig
137
+ pretrained_model_archive_map = ROBERTA_PRETRAINED_MODEL_ARCHIVE_MAP
138
+ base_model_prefix = "roberta"
139
+
140
+ def __init__(self, config):
141
+ super().__init__(config)
142
+
143
+ self.embeddings = RobertaEmbeddings(config)
144
+ self.init_weights()
145
+
146
+ def get_input_embeddings(self):
147
+ return self.embeddings.word_embeddings
148
+
149
+ def set_input_embeddings(self, value):
150
+ self.embeddings.word_embeddings = value
151
+
152
+
153
+ @add_start_docstrings("""RoBERTa Model with a `language modeling` head on top. """, ROBERTA_START_DOCSTRING)
154
+ class RobertaForMaskedLM(BertPreTrainedModel):
155
+ config_class = RobertaConfig
156
+ pretrained_model_archive_map = ROBERTA_PRETRAINED_MODEL_ARCHIVE_MAP
157
+ base_model_prefix = "roberta"
158
+
159
+ def __init__(self, config):
160
+ super().__init__(config)
161
+
162
+ self.roberta = RobertaModel(config)
163
+ self.lm_head = RobertaLMHead(config)
164
+
165
+ self.init_weights()
166
+
167
+ def get_output_embeddings(self):
168
+ return self.lm_head.decoder
169
+
170
+ @add_start_docstrings_to_callable(ROBERTA_INPUTS_DOCSTRING)
171
+ def forward(
172
+ self,
173
+ input_ids=None,
174
+ attention_mask=None,
175
+ token_type_ids=None,
176
+ position_ids=None,
177
+ head_mask=None,
178
+ inputs_embeds=None,
179
+ masked_lm_labels=None,
180
+ ):
181
+ r"""
182
+ masked_lm_labels (:obj:`torch.LongTensor` of shape :obj:`(batch_size, sequence_length)`, `optional`, defaults to :obj:`None`):
183
+ Labels for computing the masked language modeling loss.
184
+ Indices should be in ``[-100, 0, ..., config.vocab_size]`` (see ``input_ids`` docstring)
185
+ Tokens with indices set to ``-100`` are ignored (masked), the loss is only computed for the tokens with labels
186
+ in ``[0, ..., config.vocab_size]``
187
+ Returns:
188
+ :obj:`tuple(torch.FloatTensor)` comprising various elements depending on the configuration (:class:`~transformers.RobertaConfig`) and inputs:
189
+ masked_lm_loss (`optional`, returned when ``masked_lm_labels`` is provided) ``torch.FloatTensor`` of shape ``(1,)``:
190
+ Masked language modeling loss.
191
+ prediction_scores (:obj:`torch.FloatTensor` of shape :obj:`(batch_size, sequence_length, config.vocab_size)`)
192
+ Prediction scores of the language modeling head (scores for each vocabulary token before SoftMax).
193
+ hidden_states (:obj:`tuple(torch.FloatTensor)`, `optional`, returned when ``config.output_hidden_states=True``):
194
+ Tuple of :obj:`torch.FloatTensor` (one for the output of the embeddings + one for the output of each layer)
195
+ of shape :obj:`(batch_size, sequence_length, hidden_size)`.
196
+ Hidden-states of the model at the output of each layer plus the initial embedding outputs.
197
+ attentions (:obj:`tuple(torch.FloatTensor)`, `optional`, returned when ``config.output_attentions=True``):
198
+ Tuple of :obj:`torch.FloatTensor` (one for each layer) of shape
199
+ :obj:`(batch_size, num_heads, sequence_length, sequence_length)`.
200
+ Attentions weights after the attention softmax, used to compute the weighted average in the self-attention
201
+ heads.
202
+ Examples::
203
+ from transformers import RobertaTokenizer, RobertaForMaskedLM
204
+ import torch
205
+ tokenizer = RobertaTokenizer.from_pretrained('roberta-base')
206
+ model = RobertaForMaskedLM.from_pretrained('roberta-base')
207
+ input_ids = torch.tensor(tokenizer.encode("Hello, my dog is cute", add_special_tokens=True)).unsqueeze(0) # Batch size 1
208
+ outputs = model(input_ids, masked_lm_labels=input_ids)
209
+ loss, prediction_scores = outputs[:2]
210
+ """
211
+ outputs = self.roberta(
212
+ input_ids,
213
+ attention_mask=attention_mask,
214
+ token_type_ids=token_type_ids,
215
+ position_ids=position_ids,
216
+ head_mask=head_mask,
217
+ inputs_embeds=inputs_embeds,
218
+ )
219
+ sequence_output = outputs[0]
220
+ prediction_scores = self.lm_head(sequence_output)
221
+
222
+ outputs = (prediction_scores,) + outputs[2:] # Add hidden states and attention if they are here
223
+
224
+ if masked_lm_labels is not None:
225
+ loss_fct = CrossEntropyLoss()
226
+ masked_lm_loss = loss_fct(prediction_scores.view(-1, self.config.vocab_size), masked_lm_labels.view(-1))
227
+ outputs = (masked_lm_loss,) + outputs
228
+
229
+ return outputs # (masked_lm_loss), prediction_scores, (hidden_states), (attentions)
230
+
231
+
232
+ class RobertaLMHead(nn.Module):
233
+ """Roberta Head for masked language modeling."""
234
+
235
+ def __init__(self, config):
236
+ super().__init__()
237
+ self.dense = nn.Linear(config.hidden_size, config.hidden_size)
238
+ self.layer_norm = BertLayerNorm(config.hidden_size, eps=config.layer_norm_eps)
239
+
240
+ self.decoder = nn.Linear(config.hidden_size, config.vocab_size, bias=False)
241
+ self.bias = nn.Parameter(torch.zeros(config.vocab_size))
242
+
243
+ # Need a link between the two variables so that the bias is correctly resized with `resize_token_embeddings`
244
+ self.decoder.bias = self.bias
245
+
246
+ def forward(self, features, **kwargs):
247
+ x = self.dense(features)
248
+ x = gelu(x)
249
+ x = self.layer_norm(x)
250
+
251
+ # project back to size of vocabulary with bias
252
+ x = self.decoder(x)
253
+
254
+ return x
255
+
256
+
257
+ @add_start_docstrings(
258
+ """RoBERTa Model transformer with a sequence classification/regression head on top (a linear layer
259
+ on top of the pooled output) e.g. for GLUE tasks. """,
260
+ ROBERTA_START_DOCSTRING,
261
+ )
262
+ class RobertaForSequenceClassification(BertPreTrainedModel):
263
+ config_class = RobertaConfig
264
+ pretrained_model_archive_map = ROBERTA_PRETRAINED_MODEL_ARCHIVE_MAP
265
+ base_model_prefix = "roberta"
266
+
267
+ def __init__(self, config):
268
+
269
+ print(config)
270
+
271
+
272
+ super().__init__(config)
273
+ self.num_labels = config.num_labels
274
+
275
+ self.roberta = RobertaModel(config)
276
+ self.classifier_ER = RobertaClassificationHead(config)
277
+ self.classifier_IP = RobertaClassificationHead(config)
278
+ self.classifier_EX = RobertaClassificationHead(config)
279
+
280
+ @add_start_docstrings_to_callable(ROBERTA_INPUTS_DOCSTRING)
281
+ def forward(
282
+ self,
283
+ input_ids=None,
284
+ attention_mask=None,
285
+ token_type_ids=None,
286
+ position_ids=None,
287
+ head_mask=None,
288
+ inputs_embeds=None,
289
+ labels_ER=None,
290
+ labels_IP=None,
291
+ labels_EX=None,
292
+ lambda_ER=0.1,
293
+ lambda_IP=0.4,
294
+ lambda_EX=0.5
295
+ ):
296
+ r"""
297
+ labels (:obj:`torch.LongTensor` of shape :obj:`(batch_size,)`, `optional`, defaults to :obj:`None`):
298
+ Labels for computing the sequence classification/regression loss.
299
+ Indices should be in :obj:`[0, ..., config.num_labels - 1]`.
300
+ If :obj:`config.num_labels == 1` a regression loss is computed (Mean-Square loss),
301
+ If :obj:`config.num_labels > 1` a classification loss is computed (Cross-Entropy).
302
+ Returns:
303
+ :obj:`tuple(torch.FloatTensor)` comprising various elements depending on the configuration (:class:`~transformers.RobertaConfig`) and inputs:
304
+ loss (:obj:`torch.FloatTensor` of shape :obj:`(1,)`, `optional`, returned when :obj:`label` is provided):
305
+ Classification (or regression if config.num_labels==1) loss.
306
+ logits (:obj:`torch.FloatTensor` of shape :obj:`(batch_size, config.num_labels)`):
307
+ Classification (or regression if config.num_labels==1) scores (before SoftMax).
308
+ hidden_states (:obj:`tuple(torch.FloatTensor)`, `optional`, returned when ``config.output_hidden_states=True``):
309
+ Tuple of :obj:`torch.FloatTensor` (one for the output of the embeddings + one for the output of each layer)
310
+ of shape :obj:`(batch_size, sequence_length, hidden_size)`.
311
+ Hidden-states of the model at the output of each layer plus the initial embedding outputs.
312
+ attentions (:obj:`tuple(torch.FloatTensor)`, `optional`, returned when ``config.output_attentions=True``):
313
+ Tuple of :obj:`torch.FloatTensor` (one for each layer) of shape
314
+ :obj:`(batch_size, num_heads, sequence_length, sequence_length)`.
315
+ Attentions weights after the attention softmax, used to compute the weighted average in the self-attention
316
+ heads.
317
+ Examples::
318
+ from transformers import RobertaTokenizer, RobertaForSequenceClassification
319
+ import torch
320
+ tokenizer = RobertaTokenizer.from_pretrained('roberta-base')
321
+ model = RobertaForSequenceClassification.from_pretrained('roberta-base')
322
+ input_ids = torch.tensor(tokenizer.encode("Hello, my dog is cute", add_special_tokens=True)).unsqueeze(0) # Batch size 1
323
+ labels = torch.tensor([1]).unsqueeze(0) # Batch size 1
324
+ outputs = model(input_ids, labels=labels)
325
+ loss, logits = outputs[:2]
326
+ """
327
+
328
+ outputs = self.roberta(
329
+ input_ids,
330
+ attention_mask=attention_mask,
331
+ token_type_ids=token_type_ids,
332
+ position_ids=position_ids,
333
+ head_mask=head_mask,
334
+ inputs_embeds=inputs_embeds,
335
+ )
336
+
337
+ sequence_output = outputs[0]
338
+
339
+
340
+ logits_ER = self.classifier_ER(sequence_output)
341
+ logits_IP = self.classifier_IP(sequence_output)
342
+ logits_EX = self.classifier_EX(sequence_output)
343
+
344
+
345
+ outputs = (logits_ER, logits_IP, logits_EX) + outputs[2:]
346
+
347
+
348
+ if labels_ER is not None:
349
+ loss_fct = CrossEntropyLoss()
350
+ # loss_fct_IP = CrossEntropyLoss()
351
+ # loss_fct_EX = CrossEntropyLoss()
352
+
353
+
354
+ loss_ER = loss_fct(logits_ER.view(-1, self.num_labels), labels_ER.view(-1))
355
+ loss_IP = loss_fct(logits_IP.view(-1, self.num_labels), labels_IP.view(-1))
356
+ loss_EX = loss_fct(logits_EX.view(-1, self.num_labels), labels_EX.view(-1))
357
+
358
+
359
+ loss = (lambda_ER * loss_ER) + (lambda_IP * loss_IP) + (lambda_EX * loss_EX)
360
+
361
+ outputs = (loss,) + outputs
362
+
363
+
364
+ # if self.num_labels == 1:
365
+ # # We are doing regression
366
+ # loss_fct = MSELoss()
367
+ # loss = loss_fct(logits.view(-1), labels.view(-1))
368
+ # else:
369
+ # loss_fct = CrossEntropyLoss()
370
+ # loss = loss_fct(logits.view(-1, self.num_labels), labels.view(-1))
371
+ # outputs = (loss,) + outputs
372
+
373
+ return outputs # (loss), logits, (hidden_states), (attentions)
374
+
375
+
376
+ @add_start_docstrings(
377
+ """Roberta Model with a multiple choice classification head on top (a linear layer on top of
378
+ the pooled output and a softmax) e.g. for RocStories/SWAG tasks. """,
379
+ ROBERTA_START_DOCSTRING,
380
+ )
381
+ class RobertaForMultipleChoice(BertPreTrainedModel):
382
+ config_class = RobertaConfig
383
+ pretrained_model_archive_map = ROBERTA_PRETRAINED_MODEL_ARCHIVE_MAP
384
+ base_model_prefix = "roberta"
385
+
386
+ def __init__(self, config):
387
+ super().__init__(config)
388
+
389
+ self.roberta = RobertaModel(config)
390
+ self.dropout = nn.Dropout(config.hidden_dropout_prob)
391
+ self.classifier = nn.Linear(config.hidden_size, 1)
392
+
393
+ self.init_weights()
394
+
395
+ @add_start_docstrings_to_callable(ROBERTA_INPUTS_DOCSTRING)
396
+ def forward(
397
+ self,
398
+ input_ids=None,
399
+ token_type_ids=None,
400
+ attention_mask=None,
401
+ labels=None,
402
+ position_ids=None,
403
+ head_mask=None,
404
+ inputs_embeds=None,
405
+ ):
406
+ r"""
407
+ labels (:obj:`torch.LongTensor` of shape :obj:`(batch_size,)`, `optional`, defaults to :obj:`None`):
408
+ Labels for computing the multiple choice classification loss.
409
+ Indices should be in ``[0, ..., num_choices]`` where `num_choices` is the size of the second dimension
410
+ of the input tensors. (see `input_ids` above)
411
+ Returns:
412
+ :obj:`tuple(torch.FloatTensor)` comprising various elements depending on the configuration (:class:`~transformers.RobertaConfig`) and inputs:
413
+ loss (:obj:`torch.FloatTensor`` of shape ``(1,)`, `optional`, returned when :obj:`labels` is provided):
414
+ Classification loss.
415
+ classification_scores (:obj:`torch.FloatTensor` of shape :obj:`(batch_size, num_choices)`):
416
+ `num_choices` is the second dimension of the input tensors. (see `input_ids` above).
417
+ Classification scores (before SoftMax).
418
+ hidden_states (:obj:`tuple(torch.FloatTensor)`, `optional`, returned when ``config.output_hidden_states=True``):
419
+ Tuple of :obj:`torch.FloatTensor` (one for the output of the embeddings + one for the output of each layer)
420
+ of shape :obj:`(batch_size, sequence_length, hidden_size)`.
421
+ Hidden-states of the model at the output of each layer plus the initial embedding outputs.
422
+ attentions (:obj:`tuple(torch.FloatTensor)`, `optional`, returned when ``config.output_attentions=True``):
423
+ Tuple of :obj:`torch.FloatTensor` (one for each layer) of shape
424
+ :obj:`(batch_size, num_heads, sequence_length, sequence_length)`.
425
+ Attentions weights after the attention softmax, used to compute the weighted average in the self-attention
426
+ heads.
427
+ Examples::
428
+ from transformers import RobertaTokenizer, RobertaForMultipleChoice
429
+ import torch
430
+ tokenizer = RobertaTokenizer.from_pretrained('roberta-base')
431
+ model = RobertaForMultipleChoice.from_pretrained('roberta-base')
432
+ choices = ["Hello, my dog is cute", "Hello, my cat is amazing"]
433
+ input_ids = torch.tensor([tokenizer.encode(s, add_special_tokens=True) for s in choices]).unsqueeze(0) # Batch size 1, 2 choices
434
+ labels = torch.tensor(1).unsqueeze(0) # Batch size 1
435
+ outputs = model(input_ids, labels=labels)
436
+ loss, classification_scores = outputs[:2]
437
+ """
438
+ num_choices = input_ids.shape[1]
439
+
440
+ flat_input_ids = input_ids.view(-1, input_ids.size(-1))
441
+ flat_position_ids = position_ids.view(-1, position_ids.size(-1)) if position_ids is not None else None
442
+ flat_token_type_ids = token_type_ids.view(-1, token_type_ids.size(-1)) if token_type_ids is not None else None
443
+ flat_attention_mask = attention_mask.view(-1, attention_mask.size(-1)) if attention_mask is not None else None
444
+ outputs = self.roberta(
445
+ flat_input_ids,
446
+ position_ids=flat_position_ids,
447
+ token_type_ids=flat_token_type_ids,
448
+ attention_mask=flat_attention_mask,
449
+ head_mask=head_mask,
450
+ )
451
+ pooled_output = outputs[1]
452
+
453
+ pooled_output = self.dropout(pooled_output)
454
+ logits = self.classifier(pooled_output)
455
+ reshaped_logits = logits.view(-1, num_choices)
456
+
457
+ outputs = (reshaped_logits,) + outputs[2:] # add hidden states and attention if they are here
458
+
459
+ if labels is not None:
460
+ loss_fct = CrossEntropyLoss()
461
+ loss = loss_fct(reshaped_logits, labels)
462
+ outputs = (loss,) + outputs
463
+
464
+ return outputs # (loss), reshaped_logits, (hidden_states), (attentions)
465
+
466
+
467
+ @add_start_docstrings(
468
+ """Roberta Model with a token classification head on top (a linear layer on top of
469
+ the hidden-states output) e.g. for Named-Entity-Recognition (NER) tasks. """,
470
+ ROBERTA_START_DOCSTRING,
471
+ )
472
+ class RobertaForTokenClassification(BertPreTrainedModel):
473
+ config_class = RobertaConfig
474
+ pretrained_model_archive_map = ROBERTA_PRETRAINED_MODEL_ARCHIVE_MAP
475
+ base_model_prefix = "roberta"
476
+
477
+ def __init__(self, config):
478
+ super().__init__(config)
479
+ self.num_labels = config.num_labels
480
+
481
+ self.roberta = RobertaModel(config)
482
+ self.dropout = nn.Dropout(config.hidden_dropout_prob)
483
+ self.classifier = nn.Linear(config.hidden_size, config.num_labels)
484
+
485
+ self.init_weights()
486
+
487
+ @add_start_docstrings_to_callable(ROBERTA_INPUTS_DOCSTRING)
488
+ def forward(
489
+ self,
490
+ input_ids=None,
491
+ attention_mask=None,
492
+ token_type_ids=None,
493
+ position_ids=None,
494
+ head_mask=None,
495
+ inputs_embeds=None,
496
+ labels=None,
497
+ ):
498
+ r"""
499
+ labels (:obj:`torch.LongTensor` of shape :obj:`(batch_size, sequence_length)`, `optional`, defaults to :obj:`None`):
500
+ Labels for computing the token classification loss.
501
+ Indices should be in ``[0, ..., config.num_labels - 1]``.
502
+ Returns:
503
+ :obj:`tuple(torch.FloatTensor)` comprising various elements depending on the configuration (:class:`~transformers.RobertaConfig`) and inputs:
504
+ loss (:obj:`torch.FloatTensor` of shape :obj:`(1,)`, `optional`, returned when ``labels`` is provided) :
505
+ Classification loss.
506
+ scores (:obj:`torch.FloatTensor` of shape :obj:`(batch_size, sequence_length, config.num_labels)`)
507
+ Classification scores (before SoftMax).
508
+ hidden_states (:obj:`tuple(torch.FloatTensor)`, `optional`, returned when ``config.output_hidden_states=True``):
509
+ Tuple of :obj:`torch.FloatTensor` (one for the output of the embeddings + one for the output of each layer)
510
+ of shape :obj:`(batch_size, sequence_length, hidden_size)`.
511
+ Hidden-states of the model at the output of each layer plus the initial embedding outputs.
512
+ attentions (:obj:`tuple(torch.FloatTensor)`, `optional`, returned when ``config.output_attentions=True``):
513
+ Tuple of :obj:`torch.FloatTensor` (one for each layer) of shape
514
+ :obj:`(batch_size, num_heads, sequence_length, sequence_length)`.
515
+ Attentions weights after the attention softmax, used to compute the weighted average in the self-attention
516
+ heads.
517
+ Examples::
518
+ from transformers import RobertaTokenizer, RobertaForTokenClassification
519
+ import torch
520
+ tokenizer = RobertaTokenizer.from_pretrained('roberta-base')
521
+ model = RobertaForTokenClassification.from_pretrained('roberta-base')
522
+ input_ids = torch.tensor(tokenizer.encode("Hello, my dog is cute", add_special_tokens=True)).unsqueeze(0) # Batch size 1
523
+ labels = torch.tensor([1] * input_ids.size(1)).unsqueeze(0) # Batch size 1
524
+ outputs = model(input_ids, labels=labels)
525
+ loss, scores = outputs[:2]
526
+ """
527
+
528
+ outputs = self.roberta(
529
+ input_ids,
530
+ attention_mask=attention_mask,
531
+ token_type_ids=token_type_ids,
532
+ position_ids=position_ids,
533
+ head_mask=head_mask,
534
+ inputs_embeds=inputs_embeds,
535
+ )
536
+
537
+ sequence_output = outputs[0]
538
+
539
+ sequence_output = self.dropout(sequence_output)
540
+ logits = self.classifier(sequence_output)
541
+
542
+ outputs = (logits,) + outputs[2:] # add hidden states and attention if they are here
543
+
544
+ if labels is not None:
545
+ loss_fct = CrossEntropyLoss()
546
+ # Only keep active parts of the loss
547
+ if attention_mask is not None:
548
+ active_loss = attention_mask.view(-1) == 1
549
+ active_logits = logits.view(-1, self.num_labels)
550
+ active_labels = torch.where(
551
+ active_loss, labels.view(-1), torch.tensor(loss_fct.ignore_index).type_as(labels)
552
+ )
553
+ loss = loss_fct(active_logits, active_labels)
554
+ else:
555
+ loss = loss_fct(logits.view(-1, self.num_labels), labels.view(-1))
556
+ outputs = (loss,) + outputs
557
+
558
+ return outputs # (loss), scores, (hidden_states), (attentions)
559
+
560
+
561
+ class RobertaClassificationHead(nn.Module):
562
+ """Head for sentence-level classification tasks."""
563
+
564
+ def __init__(self, config):
565
+ super().__init__()
566
+ self.dense = nn.Linear(config.hidden_size, 128)
567
+ self.dropout = nn.Dropout(config.hidden_dropout_prob)
568
+ self.out_proj = nn.Linear(128, config.num_labels)
569
+
570
+ def forward(self, features, **kwargs):
571
+ x = features[:, 0, :] # take <s> token (equiv. to [CLS])
572
+ x = self.dropout(x)
573
+ x = self.dense(x)
574
+ x = torch.tanh(x)
575
+ x = self.dropout(x)
576
+ x = self.out_proj(x)
577
+ return x
578
+
579
+
580
+ @add_start_docstrings(
581
+ """Roberta Model with a span classification head on top for extractive question-answering tasks like SQuAD (a linear layers on top of
582
+ the hidden-states output to compute `span start logits` and `span end logits`). """,
583
+ ROBERTA_START_DOCSTRING,
584
+ )
585
+ class RobertaForQuestionAnswering(BertPreTrainedModel):
586
+ config_class = RobertaConfig
587
+ pretrained_model_archive_map = ROBERTA_PRETRAINED_MODEL_ARCHIVE_MAP
588
+ base_model_prefix = "roberta"
589
+
590
+ def __init__(self, config):
591
+ super().__init__(config)
592
+ self.num_labels = config.num_labels
593
+
594
+ self.roberta = RobertaModel(config)
595
+ self.qa_outputs = nn.Linear(config.hidden_size, config.num_labels)
596
+
597
+ self.init_weights()
598
+
599
+ @add_start_docstrings_to_callable(ROBERTA_INPUTS_DOCSTRING)
600
+ def forward(
601
+ self,
602
+ input_ids,
603
+ attention_mask=None,
604
+ token_type_ids=None,
605
+ position_ids=None,
606
+ head_mask=None,
607
+ inputs_embeds=None,
608
+ start_positions=None,
609
+ end_positions=None,
610
+ ):
611
+ r"""
612
+ start_positions (:obj:`torch.LongTensor` of shape :obj:`(batch_size,)`, `optional`, defaults to :obj:`None`):
613
+ Labels for position (index) of the start of the labelled span for computing the token classification loss.
614
+ Positions are clamped to the length of the sequence (`sequence_length`).
615
+ Position outside of the sequence are not taken into account for computing the loss.
616
+ end_positions (:obj:`torch.LongTensor` of shape :obj:`(batch_size,)`, `optional`, defaults to :obj:`None`):
617
+ Labels for position (index) of the end of the labelled span for computing the token classification loss.
618
+ Positions are clamped to the length of the sequence (`sequence_length`).
619
+ Position outside of the sequence are not taken into account for computing the loss.
620
+ Returns:
621
+ :obj:`tuple(torch.FloatTensor)` comprising various elements depending on the configuration (:class:`~transformers.RobertaConfig`) and inputs:
622
+ loss (:obj:`torch.FloatTensor` of shape :obj:`(1,)`, `optional`, returned when :obj:`labels` is provided):
623
+ Total span extraction loss is the sum of a Cross-Entropy for the start and end positions.
624
+ start_scores (:obj:`torch.FloatTensor` of shape :obj:`(batch_size, sequence_length,)`):
625
+ Span-start scores (before SoftMax).
626
+ end_scores (:obj:`torch.FloatTensor` of shape :obj:`(batch_size, sequence_length,)`):
627
+ Span-end scores (before SoftMax).
628
+ hidden_states (:obj:`tuple(torch.FloatTensor)`, `optional`, returned when ``config.output_hidden_states=True``):
629
+ Tuple of :obj:`torch.FloatTensor` (one for the output of the embeddings + one for the output of each layer)
630
+ of shape :obj:`(batch_size, sequence_length, hidden_size)`.
631
+ Hidden-states of the model at the output of each layer plus the initial embedding outputs.
632
+ attentions (:obj:`tuple(torch.FloatTensor)`, `optional`, returned when ``config.output_attentions=True``):
633
+ Tuple of :obj:`torch.FloatTensor` (one for each layer) of shape
634
+ :obj:`(batch_size, num_heads, sequence_length, sequence_length)`.
635
+ Attentions weights after the attention softmax, used to compute the weighted average in the self-attention
636
+ heads.
637
+ Examples::
638
+ # The checkpoint roberta-large is not fine-tuned for question answering. Please see the
639
+ # examples/run_squad.py example to see how to fine-tune a model to a question answering task.
640
+ from transformers import RobertaTokenizer, RobertaForQuestionAnswering
641
+ import torch
642
+ tokenizer = RobertaTokenizer.from_pretrained('roberta-base')
643
+ model = RobertaForQuestionAnswering.from_pretrained('roberta-base')
644
+ question, text = "Who was Jim Henson?", "Jim Henson was a nice puppet"
645
+ input_ids = tokenizer.encode(question, text)
646
+ start_scores, end_scores = model(torch.tensor([input_ids]))
647
+ all_tokens = tokenizer.convert_ids_to_tokens(input_ids)
648
+ answer = ' '.join(all_tokens[torch.argmax(start_scores) : torch.argmax(end_scores)+1])
649
+ """
650
+
651
+ outputs = self.roberta(
652
+ input_ids,
653
+ attention_mask=attention_mask,
654
+ token_type_ids=token_type_ids,
655
+ position_ids=position_ids,
656
+ head_mask=head_mask,
657
+ inputs_embeds=inputs_embeds,
658
+ )
659
+
660
+ sequence_output = outputs[0]
661
+
662
+ logits = self.qa_outputs(sequence_output)
663
+ start_logits, end_logits = logits.split(1, dim=-1)
664
+ start_logits = start_logits.squeeze(-1)
665
+ end_logits = end_logits.squeeze(-1)
666
+
667
+ outputs = (start_logits, end_logits,) + outputs[2:]
668
+ if start_positions is not None and end_positions is not None:
669
+ # If we are on multi-GPU, split add a dimension
670
+ if len(start_positions.size()) > 1:
671
+ start_positions = start_positions.squeeze(-1)
672
+ if len(end_positions.size()) > 1:
673
+ end_positions = end_positions.squeeze(-1)
674
+ # sometimes the start/end positions are outside our model inputs, we ignore these terms
675
+ ignored_index = start_logits.size(1)
676
+ start_positions.clamp_(0, ignored_index)
677
+ end_positions.clamp_(0, ignored_index)
678
+
679
+ loss_fct = CrossEntropyLoss(ignore_index=ignored_index)
680
+ start_loss = loss_fct(start_logits, start_positions)
681
+ end_loss = loss_fct(end_logits, end_positions)
682
+ total_loss = (start_loss + end_loss) / 2
683
+ outputs = (total_loss,) + outputs
684
+
685
+ return outputs # (loss), start_logits, end_logits, (hidden_states), (attentions)
requirements.txt CHANGED
@@ -1,3 +1,4 @@
1
  transformers>=4.30.0
2
  torch>=1.9.0
3
  numpy>=1.19.0
 
 
1
  transformers>=4.30.0
2
  torch>=1.9.0
3
  numpy>=1.19.0
4
+ sentencepiece