riccorl commited on
Commit
d45eb59
1 Parent(s): d5dfdb6

Automatic push from sapienzanlp

Browse files
added_tokens.json ADDED
@@ -0,0 +1,104 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "--NME--": 128001,
3
+ "[E-0]": 128002,
4
+ "[E-10]": 128012,
5
+ "[E-11]": 128013,
6
+ "[E-12]": 128014,
7
+ "[E-13]": 128015,
8
+ "[E-14]": 128016,
9
+ "[E-15]": 128017,
10
+ "[E-16]": 128018,
11
+ "[E-17]": 128019,
12
+ "[E-18]": 128020,
13
+ "[E-19]": 128021,
14
+ "[E-1]": 128003,
15
+ "[E-20]": 128022,
16
+ "[E-21]": 128023,
17
+ "[E-22]": 128024,
18
+ "[E-23]": 128025,
19
+ "[E-24]": 128026,
20
+ "[E-25]": 128027,
21
+ "[E-26]": 128028,
22
+ "[E-27]": 128029,
23
+ "[E-28]": 128030,
24
+ "[E-29]": 128031,
25
+ "[E-2]": 128004,
26
+ "[E-30]": 128032,
27
+ "[E-31]": 128033,
28
+ "[E-32]": 128034,
29
+ "[E-33]": 128035,
30
+ "[E-34]": 128036,
31
+ "[E-35]": 128037,
32
+ "[E-36]": 128038,
33
+ "[E-37]": 128039,
34
+ "[E-38]": 128040,
35
+ "[E-39]": 128041,
36
+ "[E-3]": 128005,
37
+ "[E-40]": 128042,
38
+ "[E-41]": 128043,
39
+ "[E-42]": 128044,
40
+ "[E-43]": 128045,
41
+ "[E-44]": 128046,
42
+ "[E-45]": 128047,
43
+ "[E-46]": 128048,
44
+ "[E-47]": 128049,
45
+ "[E-48]": 128050,
46
+ "[E-49]": 128051,
47
+ "[E-4]": 128006,
48
+ "[E-50]": 128052,
49
+ "[E-51]": 128053,
50
+ "[E-52]": 128054,
51
+ "[E-53]": 128055,
52
+ "[E-54]": 128056,
53
+ "[E-55]": 128057,
54
+ "[E-56]": 128058,
55
+ "[E-57]": 128059,
56
+ "[E-58]": 128060,
57
+ "[E-59]": 128061,
58
+ "[E-5]": 128007,
59
+ "[E-60]": 128062,
60
+ "[E-61]": 128063,
61
+ "[E-62]": 128064,
62
+ "[E-63]": 128065,
63
+ "[E-64]": 128066,
64
+ "[E-65]": 128067,
65
+ "[E-66]": 128068,
66
+ "[E-67]": 128069,
67
+ "[E-68]": 128070,
68
+ "[E-69]": 128071,
69
+ "[E-6]": 128008,
70
+ "[E-70]": 128072,
71
+ "[E-71]": 128073,
72
+ "[E-72]": 128074,
73
+ "[E-73]": 128075,
74
+ "[E-74]": 128076,
75
+ "[E-75]": 128077,
76
+ "[E-76]": 128078,
77
+ "[E-77]": 128079,
78
+ "[E-78]": 128080,
79
+ "[E-79]": 128081,
80
+ "[E-7]": 128009,
81
+ "[E-80]": 128082,
82
+ "[E-81]": 128083,
83
+ "[E-82]": 128084,
84
+ "[E-83]": 128085,
85
+ "[E-84]": 128086,
86
+ "[E-85]": 128087,
87
+ "[E-86]": 128088,
88
+ "[E-87]": 128089,
89
+ "[E-88]": 128090,
90
+ "[E-89]": 128091,
91
+ "[E-8]": 128010,
92
+ "[E-90]": 128092,
93
+ "[E-91]": 128093,
94
+ "[E-92]": 128094,
95
+ "[E-93]": 128095,
96
+ "[E-94]": 128096,
97
+ "[E-95]": 128097,
98
+ "[E-96]": 128098,
99
+ "[E-97]": 128099,
100
+ "[E-98]": 128100,
101
+ "[E-99]": 128101,
102
+ "[E-9]": 128011,
103
+ "[MASK]": 128000
104
+ }
config.json ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "activation": "gelu",
3
+ "add_entity_embedding": null,
4
+ "additional_special_symbols": 101,
5
+ "additional_special_symbols_types": 0,
6
+ "architectures": [
7
+ "RelikReaderSpanModel"
8
+ ],
9
+ "auto_map": {
10
+ "AutoModel": "modeling_relik.RelikReaderSpanModel"
11
+ },
12
+ "default_reader_class": null,
13
+ "entity_type_loss": false,
14
+ "linears_hidden_size": 512,
15
+ "model_type": "relik-reader",
16
+ "num_layers": null,
17
+ "torch_dtype": "float32",
18
+ "training": true,
19
+ "transformer_model": "microsoft/deberta-v3-large",
20
+ "transformers_version": "4.33.3",
21
+ "use_last_k_layers": 1
22
+ }
configuration_relik.py ADDED
@@ -0,0 +1,44 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from typing import Optional
2
+
3
+ from transformers import AutoConfig
4
+ from transformers.configuration_utils import PretrainedConfig
5
+
6
+
7
+ class RelikReaderConfig(PretrainedConfig):
8
+ model_type = "relik-reader"
9
+
10
+ def __init__(
11
+ self,
12
+ transformer_model: str = "microsoft/deberta-v3-base",
13
+ additional_special_symbols: int = 101,
14
+ additional_special_symbols_types: Optional[int] = 0,
15
+ num_layers: Optional[int] = None,
16
+ activation: str = "gelu",
17
+ linears_hidden_size: Optional[int] = 512,
18
+ use_last_k_layers: int = 1,
19
+ entity_type_loss: bool = False,
20
+ add_entity_embedding: bool = None,
21
+ training: bool = False,
22
+ default_reader_class: Optional[str] = None,
23
+ **kwargs
24
+ ) -> None:
25
+ # TODO: add name_or_path to kwargs
26
+ self.transformer_model = transformer_model
27
+ self.additional_special_symbols = additional_special_symbols
28
+ self.additional_special_symbols_types = additional_special_symbols_types
29
+ self.num_layers = num_layers
30
+ self.activation = activation
31
+ self.linears_hidden_size = linears_hidden_size
32
+ self.use_last_k_layers = use_last_k_layers
33
+ self.entity_type_loss = entity_type_loss
34
+ self.add_entity_embedding = (
35
+ True
36
+ if add_entity_embedding is None and entity_type_loss
37
+ else add_entity_embedding
38
+ )
39
+ self.training = training
40
+ self.default_reader_class = default_reader_class
41
+ super().__init__(**kwargs)
42
+
43
+
44
+ AutoConfig.register("relik-reader", RelikReaderConfig)
modeling_relik.py ADDED
@@ -0,0 +1,982 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from typing import Any, Dict, Optional
2
+
3
+ import torch
4
+ from transformers import AutoModel, PreTrainedModel
5
+ from transformers.activations import ClippedGELUActivation, GELUActivation
6
+ from transformers.configuration_utils import PretrainedConfig
7
+ from transformers.modeling_utils import PoolerEndLogits
8
+
9
+ from .configuration_relik import RelikReaderConfig
10
+
11
+
12
+ class RelikReaderSample:
13
+ def __init__(self, **kwargs):
14
+ super().__setattr__("_d", {})
15
+ self._d = kwargs
16
+
17
+ def __getattribute__(self, item):
18
+ return super(RelikReaderSample, self).__getattribute__(item)
19
+
20
+ def __getattr__(self, item):
21
+ if item.startswith("__") and item.endswith("__"):
22
+ # this is likely some python library-specific variable (such as __deepcopy__ for copy)
23
+ # better follow standard behavior here
24
+ raise AttributeError(item)
25
+ elif item in self._d:
26
+ return self._d[item]
27
+ else:
28
+ return None
29
+
30
+ def __setattr__(self, key, value):
31
+ if key in self._d:
32
+ self._d[key] = value
33
+ else:
34
+ super().__setattr__(key, value)
35
+
36
+
37
+ activation2functions = {
38
+ "relu": torch.nn.ReLU(),
39
+ "gelu": GELUActivation(),
40
+ "gelu_10": ClippedGELUActivation(-10, 10),
41
+ }
42
+
43
+
44
+ class PoolerEndLogitsBi(PoolerEndLogits):
45
+ def __init__(self, config: PretrainedConfig):
46
+ super().__init__(config)
47
+ self.dense_1 = torch.nn.Linear(config.hidden_size, 2)
48
+
49
+ def forward(
50
+ self,
51
+ hidden_states: torch.FloatTensor,
52
+ start_states: Optional[torch.FloatTensor] = None,
53
+ start_positions: Optional[torch.LongTensor] = None,
54
+ p_mask: Optional[torch.FloatTensor] = None,
55
+ ) -> torch.FloatTensor:
56
+ if p_mask is not None:
57
+ p_mask = p_mask.unsqueeze(-1)
58
+ logits = super().forward(
59
+ hidden_states,
60
+ start_states,
61
+ start_positions,
62
+ p_mask,
63
+ )
64
+ return logits
65
+
66
+
67
+ class RelikReaderSpanModel(PreTrainedModel):
68
+ config_class = RelikReaderConfig
69
+
70
+ def __init__(self, config: RelikReaderConfig, *args, **kwargs):
71
+ super().__init__(config)
72
+ # Transformer model declaration
73
+ self.config = config
74
+ self.transformer_model = (
75
+ AutoModel.from_pretrained(self.config.transformer_model)
76
+ if self.config.num_layers is None
77
+ else AutoModel.from_pretrained(
78
+ self.config.transformer_model, num_hidden_layers=self.config.num_layers
79
+ )
80
+ )
81
+ self.transformer_model.resize_token_embeddings(
82
+ self.transformer_model.config.vocab_size
83
+ + self.config.additional_special_symbols
84
+ )
85
+
86
+ self.activation = self.config.activation
87
+ self.linears_hidden_size = self.config.linears_hidden_size
88
+ self.use_last_k_layers = self.config.use_last_k_layers
89
+
90
+ # named entity detection layers
91
+ self.ned_start_classifier = self._get_projection_layer(
92
+ self.activation, last_hidden=2, layer_norm=False
93
+ )
94
+ self.ned_end_classifier = PoolerEndLogits(self.transformer_model.config)
95
+
96
+ # END entity disambiguation layer
97
+ self.ed_start_projector = self._get_projection_layer(self.activation)
98
+ self.ed_end_projector = self._get_projection_layer(self.activation)
99
+
100
+ self.training = self.config.training
101
+
102
+ # criterion
103
+ self.criterion = torch.nn.CrossEntropyLoss()
104
+
105
+ def _get_projection_layer(
106
+ self,
107
+ activation: str,
108
+ last_hidden: Optional[int] = None,
109
+ input_hidden=None,
110
+ layer_norm: bool = True,
111
+ ) -> torch.nn.Sequential:
112
+ head_components = [
113
+ torch.nn.Dropout(0.1),
114
+ torch.nn.Linear(
115
+ self.transformer_model.config.hidden_size * self.use_last_k_layers
116
+ if input_hidden is None
117
+ else input_hidden,
118
+ self.linears_hidden_size,
119
+ ),
120
+ activation2functions[activation],
121
+ torch.nn.Dropout(0.1),
122
+ torch.nn.Linear(
123
+ self.linears_hidden_size,
124
+ self.linears_hidden_size if last_hidden is None else last_hidden,
125
+ ),
126
+ ]
127
+
128
+ if layer_norm:
129
+ head_components.append(
130
+ torch.nn.LayerNorm(
131
+ self.linears_hidden_size if last_hidden is None else last_hidden,
132
+ self.transformer_model.config.layer_norm_eps,
133
+ )
134
+ )
135
+
136
+ return torch.nn.Sequential(*head_components)
137
+
138
+ def _mask_logits(self, logits: torch.Tensor, mask: torch.Tensor) -> torch.Tensor:
139
+ mask = mask.unsqueeze(-1)
140
+ if next(self.parameters()).dtype == torch.float16:
141
+ logits = logits * (1 - mask) - 65500 * mask
142
+ else:
143
+ logits = logits * (1 - mask) - 1e30 * mask
144
+ return logits
145
+
146
+ def _get_model_features(
147
+ self,
148
+ input_ids: torch.Tensor,
149
+ attention_mask: torch.Tensor,
150
+ token_type_ids: Optional[torch.Tensor],
151
+ ):
152
+ model_input = {
153
+ "input_ids": input_ids,
154
+ "attention_mask": attention_mask,
155
+ "output_hidden_states": self.use_last_k_layers > 1,
156
+ }
157
+
158
+ if token_type_ids is not None:
159
+ model_input["token_type_ids"] = token_type_ids
160
+
161
+ model_output = self.transformer_model(**model_input)
162
+
163
+ if self.use_last_k_layers > 1:
164
+ model_features = torch.cat(
165
+ model_output[1][-self.use_last_k_layers :], dim=-1
166
+ )
167
+ else:
168
+ model_features = model_output[0]
169
+
170
+ return model_features
171
+
172
+ def compute_ned_end_logits(
173
+ self,
174
+ start_predictions,
175
+ start_labels,
176
+ model_features,
177
+ prediction_mask,
178
+ batch_size,
179
+ ) -> Optional[torch.Tensor]:
180
+ # todo: maybe when constraining on the spans,
181
+ # we should not use a prediction_mask for the end tokens.
182
+ # at least we should not during training imo
183
+ start_positions = start_labels if self.training else start_predictions
184
+ start_positions_indices = (
185
+ torch.arange(start_positions.size(1), device=start_positions.device)
186
+ .unsqueeze(0)
187
+ .expand(batch_size, -1)[start_positions > 0]
188
+ ).to(start_positions.device)
189
+
190
+ if len(start_positions_indices) > 0:
191
+ expanded_features = model_features.repeat_interleave(
192
+ torch.sum(start_positions > 0, dim=-1), dim=0
193
+ )
194
+ expanded_prediction_mask = prediction_mask.repeat_interleave(
195
+ torch.sum(start_positions > 0, dim=-1), dim=0
196
+ )
197
+ end_logits = self.ned_end_classifier(
198
+ hidden_states=expanded_features,
199
+ start_positions=start_positions_indices,
200
+ p_mask=expanded_prediction_mask,
201
+ )
202
+
203
+ return end_logits
204
+
205
+ return None
206
+
207
+ def compute_classification_logits(
208
+ self,
209
+ model_features,
210
+ special_symbols_mask,
211
+ prediction_mask,
212
+ batch_size,
213
+ start_positions=None,
214
+ end_positions=None,
215
+ ) -> torch.Tensor:
216
+ if start_positions is None or end_positions is None:
217
+ start_positions = torch.zeros_like(prediction_mask)
218
+ end_positions = torch.zeros_like(prediction_mask)
219
+
220
+ model_start_features = self.ed_start_projector(model_features)
221
+ model_end_features = self.ed_end_projector(model_features)
222
+ model_end_features[start_positions > 0] = model_end_features[end_positions > 0]
223
+
224
+ model_ed_features = torch.cat(
225
+ [model_start_features, model_end_features], dim=-1
226
+ )
227
+
228
+ # computing ed features
229
+ classes_representations = torch.sum(special_symbols_mask, dim=1)[0].item()
230
+ special_symbols_representation = model_ed_features[special_symbols_mask].view(
231
+ batch_size, classes_representations, -1
232
+ )
233
+
234
+ logits = torch.bmm(
235
+ model_ed_features,
236
+ torch.permute(special_symbols_representation, (0, 2, 1)),
237
+ )
238
+
239
+ logits = self._mask_logits(logits, prediction_mask)
240
+
241
+ return logits
242
+
243
+ def forward(
244
+ self,
245
+ input_ids: torch.Tensor,
246
+ attention_mask: torch.Tensor,
247
+ token_type_ids: Optional[torch.Tensor] = None,
248
+ prediction_mask: Optional[torch.Tensor] = None,
249
+ special_symbols_mask: Optional[torch.Tensor] = None,
250
+ start_labels: Optional[torch.Tensor] = None,
251
+ end_labels: Optional[torch.Tensor] = None,
252
+ use_predefined_spans: bool = False,
253
+ *args,
254
+ **kwargs,
255
+ ) -> Dict[str, Any]:
256
+ batch_size, seq_len = input_ids.shape
257
+
258
+ model_features = self._get_model_features(
259
+ input_ids, attention_mask, token_type_ids
260
+ )
261
+
262
+ ned_start_labels = None
263
+
264
+ # named entity detection if required
265
+ if use_predefined_spans: # no need to compute spans
266
+ ned_start_logits, ned_start_probabilities, ned_start_predictions = (
267
+ None,
268
+ None,
269
+ torch.clone(start_labels)
270
+ if start_labels is not None
271
+ else torch.zeros_like(input_ids),
272
+ )
273
+ ned_end_logits, ned_end_probabilities, ned_end_predictions = (
274
+ None,
275
+ None,
276
+ torch.clone(end_labels)
277
+ if end_labels is not None
278
+ else torch.zeros_like(input_ids),
279
+ )
280
+
281
+ ned_start_predictions[ned_start_predictions > 0] = 1
282
+ ned_end_predictions[ned_end_predictions > 0] = 1
283
+
284
+ else: # compute spans
285
+ # start boundary prediction
286
+ ned_start_logits = self.ned_start_classifier(model_features)
287
+ ned_start_logits = self._mask_logits(ned_start_logits, prediction_mask)
288
+ ned_start_probabilities = torch.softmax(ned_start_logits, dim=-1)
289
+ ned_start_predictions = ned_start_probabilities.argmax(dim=-1)
290
+
291
+ # end boundary prediction
292
+ ned_start_labels = (
293
+ torch.zeros_like(start_labels) if start_labels is not None else None
294
+ )
295
+
296
+ if ned_start_labels is not None:
297
+ ned_start_labels[start_labels == -100] = -100
298
+ ned_start_labels[start_labels > 0] = 1
299
+
300
+ ned_end_logits = self.compute_ned_end_logits(
301
+ ned_start_predictions,
302
+ ned_start_labels,
303
+ model_features,
304
+ prediction_mask,
305
+ batch_size,
306
+ )
307
+
308
+ if ned_end_logits is not None:
309
+ ned_end_probabilities = torch.softmax(ned_end_logits, dim=-1)
310
+ ned_end_predictions = torch.argmax(ned_end_probabilities, dim=-1)
311
+ else:
312
+ ned_end_logits, ned_end_probabilities = None, None
313
+ ned_end_predictions = ned_start_predictions.new_zeros(batch_size)
314
+
315
+ # flattening end predictions
316
+ # (flattening can happen only if the
317
+ # end boundaries were not predicted using the gold labels)
318
+ if not self.training:
319
+ flattened_end_predictions = torch.clone(ned_start_predictions)
320
+ flattened_end_predictions[flattened_end_predictions > 0] = 0
321
+
322
+ batch_start_predictions = list()
323
+ for elem_idx in range(batch_size):
324
+ batch_start_predictions.append(
325
+ torch.where(ned_start_predictions[elem_idx] > 0)[0].tolist()
326
+ )
327
+
328
+ # check that the total number of start predictions
329
+ # is equal to the end predictions
330
+ total_start_predictions = sum(map(len, batch_start_predictions))
331
+ total_end_predictions = len(ned_end_predictions)
332
+ assert (
333
+ total_start_predictions == 0
334
+ or total_start_predictions == total_end_predictions
335
+ ), (
336
+ f"Total number of start predictions = {total_start_predictions}. "
337
+ f"Total number of end predictions = {total_end_predictions}"
338
+ )
339
+
340
+ curr_end_pred_num = 0
341
+ for elem_idx, bsp in enumerate(batch_start_predictions):
342
+ for sp in bsp:
343
+ ep = ned_end_predictions[curr_end_pred_num].item()
344
+ if ep < sp:
345
+ ep = sp
346
+
347
+ # if we already set this span throw it (no overlap)
348
+ if flattened_end_predictions[elem_idx, ep] == 1:
349
+ ned_start_predictions[elem_idx, sp] = 0
350
+ else:
351
+ flattened_end_predictions[elem_idx, ep] = 1
352
+
353
+ curr_end_pred_num += 1
354
+
355
+ ned_end_predictions = flattened_end_predictions
356
+
357
+ start_position, end_position = (
358
+ (start_labels, end_labels)
359
+ if self.training
360
+ else (ned_start_predictions, ned_end_predictions)
361
+ )
362
+
363
+ # Entity disambiguation
364
+ ed_logits = self.compute_classification_logits(
365
+ model_features,
366
+ special_symbols_mask,
367
+ prediction_mask,
368
+ batch_size,
369
+ start_position,
370
+ end_position,
371
+ )
372
+ ed_probabilities = torch.softmax(ed_logits, dim=-1)
373
+ ed_predictions = torch.argmax(ed_probabilities, dim=-1)
374
+
375
+ # output build
376
+ output_dict = dict(
377
+ batch_size=batch_size,
378
+ ned_start_logits=ned_start_logits,
379
+ ned_start_probabilities=ned_start_probabilities,
380
+ ned_start_predictions=ned_start_predictions,
381
+ ned_end_logits=ned_end_logits,
382
+ ned_end_probabilities=ned_end_probabilities,
383
+ ned_end_predictions=ned_end_predictions,
384
+ ed_logits=ed_logits,
385
+ ed_probabilities=ed_probabilities,
386
+ ed_predictions=ed_predictions,
387
+ )
388
+
389
+ # compute loss if labels
390
+ if start_labels is not None and end_labels is not None and self.training:
391
+ # named entity detection loss
392
+
393
+ # start
394
+ if ned_start_logits is not None:
395
+ ned_start_loss = self.criterion(
396
+ ned_start_logits.view(-1, ned_start_logits.shape[-1]),
397
+ ned_start_labels.view(-1),
398
+ )
399
+ else:
400
+ ned_start_loss = 0
401
+
402
+ # end
403
+ if ned_end_logits is not None:
404
+ ned_end_labels = torch.zeros_like(end_labels)
405
+ ned_end_labels[end_labels == -100] = -100
406
+ ned_end_labels[end_labels > 0] = 1
407
+
408
+ ned_end_loss = self.criterion(
409
+ ned_end_logits,
410
+ (
411
+ torch.arange(
412
+ ned_end_labels.size(1), device=ned_end_labels.device
413
+ )
414
+ .unsqueeze(0)
415
+ .expand(batch_size, -1)[ned_end_labels > 0]
416
+ ).to(ned_end_labels.device),
417
+ )
418
+
419
+ else:
420
+ ned_end_loss = 0
421
+
422
+ # entity disambiguation loss
423
+ start_labels[ned_start_labels != 1] = -100
424
+ ed_labels = torch.clone(start_labels)
425
+ ed_labels[end_labels > 0] = end_labels[end_labels > 0]
426
+ ed_loss = self.criterion(
427
+ ed_logits.view(-1, ed_logits.shape[-1]),
428
+ ed_labels.view(-1),
429
+ )
430
+
431
+ output_dict["ned_start_loss"] = ned_start_loss
432
+ output_dict["ned_end_loss"] = ned_end_loss
433
+ output_dict["ed_loss"] = ed_loss
434
+
435
+ output_dict["loss"] = ned_start_loss + ned_end_loss + ed_loss
436
+
437
+ return output_dict
438
+
439
+
440
+ class RelikReaderREModel(PreTrainedModel):
441
+ config_class = RelikReaderConfig
442
+
443
+ def __init__(self, config, *args, **kwargs):
444
+ super().__init__(config)
445
+ # Transformer model declaration
446
+ # self.transformer_model_name = transformer_model
447
+ self.config = config
448
+ self.transformer_model = (
449
+ AutoModel.from_pretrained(config.transformer_model)
450
+ if config.num_layers is None
451
+ else AutoModel.from_pretrained(
452
+ config.transformer_model, num_hidden_layers=config.num_layers
453
+ )
454
+ )
455
+ self.transformer_model.resize_token_embeddings(
456
+ self.transformer_model.config.vocab_size
457
+ + config.additional_special_symbols
458
+ + config.additional_special_symbols_types
459
+ )
460
+
461
+ # named entity detection layers
462
+ self.ned_start_classifier = self._get_projection_layer(
463
+ config.activation, last_hidden=2, layer_norm=False
464
+ )
465
+
466
+ self.ned_end_classifier = PoolerEndLogitsBi(self.transformer_model.config)
467
+
468
+ self.relation_disambiguation_loss = (
469
+ config.relation_disambiguation_loss
470
+ if hasattr(config, "relation_disambiguation_loss")
471
+ else False
472
+ )
473
+
474
+ if self.config.entity_type_loss and self.config.add_entity_embedding:
475
+ input_hidden_ents = 3 * self.transformer_model.config.hidden_size
476
+ else:
477
+ input_hidden_ents = 2 * self.transformer_model.config.hidden_size
478
+
479
+ self.re_subject_projector = self._get_projection_layer(
480
+ config.activation, input_hidden=input_hidden_ents
481
+ )
482
+ self.re_object_projector = self._get_projection_layer(
483
+ config.activation, input_hidden=input_hidden_ents
484
+ )
485
+ self.re_relation_projector = self._get_projection_layer(config.activation)
486
+
487
+ if self.config.entity_type_loss or self.relation_disambiguation_loss:
488
+ self.re_entities_projector = self._get_projection_layer(
489
+ config.activation,
490
+ input_hidden=2 * self.transformer_model.config.hidden_size,
491
+ )
492
+ self.re_definition_projector = self._get_projection_layer(
493
+ config.activation,
494
+ )
495
+
496
+ self.re_classifier = self._get_projection_layer(
497
+ config.activation,
498
+ input_hidden=config.linears_hidden_size,
499
+ last_hidden=2,
500
+ layer_norm=False,
501
+ )
502
+
503
+ self.training = config.training
504
+
505
+ # criterion
506
+ self.criterion = torch.nn.CrossEntropyLoss()
507
+ self.criterion_type = torch.nn.BCEWithLogitsLoss()
508
+
509
+ def _get_projection_layer(
510
+ self,
511
+ activation: str,
512
+ last_hidden: Optional[int] = None,
513
+ input_hidden=None,
514
+ layer_norm: bool = True,
515
+ ) -> torch.nn.Sequential:
516
+ head_components = [
517
+ torch.nn.Dropout(0.1),
518
+ torch.nn.Linear(
519
+ self.transformer_model.config.hidden_size
520
+ * self.config.use_last_k_layers
521
+ if input_hidden is None
522
+ else input_hidden,
523
+ self.config.linears_hidden_size,
524
+ ),
525
+ activation2functions[activation],
526
+ torch.nn.Dropout(0.1),
527
+ torch.nn.Linear(
528
+ self.config.linears_hidden_size,
529
+ self.config.linears_hidden_size if last_hidden is None else last_hidden,
530
+ ),
531
+ ]
532
+
533
+ if layer_norm:
534
+ head_components.append(
535
+ torch.nn.LayerNorm(
536
+ self.config.linears_hidden_size
537
+ if last_hidden is None
538
+ else last_hidden,
539
+ self.transformer_model.config.layer_norm_eps,
540
+ )
541
+ )
542
+
543
+ return torch.nn.Sequential(*head_components)
544
+
545
+ def _mask_logits(self, logits: torch.Tensor, mask: torch.Tensor) -> torch.Tensor:
546
+ mask = mask.unsqueeze(-1)
547
+ if next(self.parameters()).dtype == torch.float16:
548
+ logits = logits * (1 - mask) - 65500 * mask
549
+ else:
550
+ logits = logits * (1 - mask) - 1e30 * mask
551
+ return logits
552
+
553
+ def _get_model_features(
554
+ self,
555
+ input_ids: torch.Tensor,
556
+ attention_mask: torch.Tensor,
557
+ token_type_ids: Optional[torch.Tensor],
558
+ ):
559
+ model_input = {
560
+ "input_ids": input_ids,
561
+ "attention_mask": attention_mask,
562
+ "output_hidden_states": self.config.use_last_k_layers > 1,
563
+ }
564
+
565
+ if token_type_ids is not None:
566
+ model_input["token_type_ids"] = token_type_ids
567
+
568
+ model_output = self.transformer_model(**model_input)
569
+
570
+ if self.config.use_last_k_layers > 1:
571
+ model_features = torch.cat(
572
+ model_output[1][-self.config.use_last_k_layers :], dim=-1
573
+ )
574
+ else:
575
+ model_features = model_output[0]
576
+
577
+ return model_features
578
+
579
+ def compute_ned_end_logits(
580
+ self,
581
+ start_predictions,
582
+ start_labels,
583
+ model_features,
584
+ prediction_mask,
585
+ batch_size,
586
+ mask_preceding: bool = False,
587
+ ) -> Optional[torch.Tensor]:
588
+ # todo: maybe when constraining on the spans,
589
+ # we should not use a prediction_mask for the end tokens.
590
+ # at least we should not during training imo
591
+ start_positions = start_labels if self.training else start_predictions
592
+ start_positions_indices = (
593
+ torch.arange(start_positions.size(1), device=start_positions.device)
594
+ .unsqueeze(0)
595
+ .expand(batch_size, -1)[start_positions > 0]
596
+ ).to(start_positions.device)
597
+
598
+ if len(start_positions_indices) > 0:
599
+ expanded_features = model_features.repeat_interleave(
600
+ torch.sum(start_positions > 0, dim=-1), dim=0
601
+ )
602
+ expanded_prediction_mask = prediction_mask.repeat_interleave(
603
+ torch.sum(start_positions > 0, dim=-1), dim=0
604
+ )
605
+ if mask_preceding:
606
+ expanded_prediction_mask[
607
+ torch.arange(
608
+ expanded_prediction_mask.shape[1],
609
+ device=expanded_prediction_mask.device,
610
+ )
611
+ < start_positions_indices.unsqueeze(1)
612
+ ] = 1
613
+ end_logits = self.ned_end_classifier(
614
+ hidden_states=expanded_features,
615
+ start_positions=start_positions_indices,
616
+ p_mask=expanded_prediction_mask,
617
+ )
618
+
619
+ return end_logits
620
+
621
+ return None
622
+
623
+ def compute_relation_logits(
624
+ self,
625
+ model_entity_features,
626
+ special_symbols_features,
627
+ ) -> torch.Tensor:
628
+ model_subject_features = self.re_subject_projector(model_entity_features)
629
+ model_object_features = self.re_object_projector(model_entity_features)
630
+ special_symbols_start_representation = self.re_relation_projector(
631
+ special_symbols_features
632
+ )
633
+ re_logits = torch.einsum(
634
+ "bse,bde,bfe->bsdfe",
635
+ model_subject_features,
636
+ model_object_features,
637
+ special_symbols_start_representation,
638
+ )
639
+ re_logits = self.re_classifier(re_logits)
640
+
641
+ return re_logits
642
+
643
+ def compute_entity_logits(
644
+ self,
645
+ model_entity_features,
646
+ special_symbols_features,
647
+ ) -> torch.Tensor:
648
+ model_ed_features = self.re_entities_projector(model_entity_features)
649
+ special_symbols_ed_representation = self.re_definition_projector(
650
+ special_symbols_features
651
+ )
652
+
653
+ logits = torch.bmm(
654
+ model_ed_features,
655
+ torch.permute(special_symbols_ed_representation, (0, 2, 1)),
656
+ )
657
+ logits = self._mask_logits(
658
+ logits, (model_entity_features == -100).all(2).long()
659
+ )
660
+ return logits
661
+
662
+ def compute_loss(self, logits, labels, mask=None):
663
+ logits = logits.reshape(-1, logits.shape[-1])
664
+ labels = labels.reshape(-1).long()
665
+ if mask is not None:
666
+ return self.criterion(logits[mask], labels[mask])
667
+ return self.criterion(logits, labels)
668
+
669
+ def compute_ned_type_loss(
670
+ self,
671
+ disambiguation_labels,
672
+ re_ned_entities_logits,
673
+ ned_type_logits,
674
+ re_entities_logits,
675
+ entity_types,
676
+ mask,
677
+ ):
678
+ if self.config.entity_type_loss and self.relation_disambiguation_loss:
679
+ return self.criterion_type(
680
+ re_ned_entities_logits[disambiguation_labels != -100],
681
+ disambiguation_labels[disambiguation_labels != -100],
682
+ )
683
+ if self.config.entity_type_loss:
684
+ return self.criterion_type(
685
+ ned_type_logits[mask],
686
+ disambiguation_labels[:, :, :entity_types][mask],
687
+ )
688
+
689
+ if self.relation_disambiguation_loss:
690
+ return self.criterion_type(
691
+ re_entities_logits[disambiguation_labels != -100],
692
+ disambiguation_labels[disambiguation_labels != -100],
693
+ )
694
+ return 0
695
+
696
+ def compute_relation_loss(self, relation_labels, re_logits):
697
+ return self.compute_loss(
698
+ re_logits, relation_labels, relation_labels.view(-1) != -100
699
+ )
700
+
701
+ def forward(
702
+ self,
703
+ input_ids: torch.Tensor,
704
+ attention_mask: torch.Tensor,
705
+ token_type_ids: torch.Tensor,
706
+ prediction_mask: Optional[torch.Tensor] = None,
707
+ special_symbols_mask: Optional[torch.Tensor] = None,
708
+ special_symbols_mask_entities: Optional[torch.Tensor] = None,
709
+ start_labels: Optional[torch.Tensor] = None,
710
+ end_labels: Optional[torch.Tensor] = None,
711
+ disambiguation_labels: Optional[torch.Tensor] = None,
712
+ relation_labels: Optional[torch.Tensor] = None,
713
+ relation_threshold: float = 0.5,
714
+ is_validation: bool = False,
715
+ is_prediction: bool = False,
716
+ use_predefined_spans: bool = False,
717
+ *args,
718
+ **kwargs,
719
+ ) -> Dict[str, Any]:
720
+ batch_size = input_ids.shape[0]
721
+
722
+ model_features = self._get_model_features(
723
+ input_ids, attention_mask, token_type_ids
724
+ )
725
+
726
+ # named entity detection
727
+ if use_predefined_spans:
728
+ ned_start_logits, ned_start_probabilities, ned_start_predictions = (
729
+ None,
730
+ None,
731
+ torch.zeros_like(start_labels),
732
+ )
733
+ ned_end_logits, ned_end_probabilities, ned_end_predictions = (
734
+ None,
735
+ None,
736
+ torch.zeros_like(end_labels),
737
+ )
738
+
739
+ ned_start_predictions[start_labels > 0] = 1
740
+ ned_end_predictions[end_labels > 0] = 1
741
+ ned_end_predictions = ned_end_predictions[~(end_labels == -100).all(2)]
742
+ ned_start_labels = start_labels
743
+ ned_start_labels[start_labels > 0] = 1
744
+ else:
745
+ # start boundary prediction
746
+ ned_start_logits = self.ned_start_classifier(model_features)
747
+ if is_validation or is_prediction:
748
+ ned_start_logits = self._mask_logits(
749
+ ned_start_logits, prediction_mask
750
+ ) # why?
751
+ ned_start_probabilities = torch.softmax(ned_start_logits, dim=-1)
752
+ ned_start_predictions = ned_start_probabilities.argmax(dim=-1)
753
+
754
+ # end boundary prediction
755
+ ned_start_labels = (
756
+ torch.zeros_like(start_labels) if start_labels is not None else None
757
+ )
758
+
759
+ # start_labels contain entity id at their position, we just need 1 for start of entity
760
+ if ned_start_labels is not None:
761
+ ned_start_labels[start_labels == -100] = -100
762
+ ned_start_labels[start_labels > 0] = 1
763
+
764
+ # compute end logits only if there are any start predictions.
765
+ # For each start prediction, n end predictions are made
766
+ ned_end_logits = self.compute_ned_end_logits(
767
+ ned_start_predictions,
768
+ ned_start_labels,
769
+ model_features,
770
+ prediction_mask,
771
+ batch_size,
772
+ True,
773
+ )
774
+
775
+ if ned_end_logits is not None:
776
+ # For each start prediction, n end predictions are made based on
777
+ # binary classification ie. argmax at each position.
778
+ ned_end_probabilities = torch.softmax(ned_end_logits, dim=-1)
779
+ ned_end_predictions = ned_end_probabilities.argmax(dim=-1)
780
+ else:
781
+ ned_end_logits, ned_end_probabilities = None, None
782
+ ned_end_predictions = torch.zeros_like(ned_start_predictions)
783
+
784
+ if is_prediction or is_validation:
785
+ end_preds_count = ned_end_predictions.sum(1)
786
+ # If there are no end predictions for a start prediction, remove the start prediction
787
+ if (end_preds_count == 0).any() and (ned_start_predictions > 0).any():
788
+ ned_start_predictions[ned_start_predictions == 1] = (
789
+ end_preds_count != 0
790
+ ).long()
791
+ ned_end_predictions = ned_end_predictions[end_preds_count != 0]
792
+
793
+ if end_labels is not None:
794
+ end_labels = end_labels[~(end_labels == -100).all(2)]
795
+
796
+ start_position, end_position = (
797
+ (start_labels, end_labels)
798
+ if (not is_prediction and not is_validation)
799
+ else (ned_start_predictions, ned_end_predictions)
800
+ )
801
+
802
+ start_counts = (start_position > 0).sum(1)
803
+ if (start_counts > 0).any():
804
+ ned_end_predictions = ned_end_predictions.split(start_counts.tolist())
805
+ # limit to 30 predictions per document using start_counts, by setting all po after sum is 30 to 0
806
+ # if is_validation or is_prediction:
807
+ # ned_start_predictions[ned_start_predictions == 1] = start_counts
808
+ # We can only predict relations if we have start and end predictions
809
+ if (end_position > 0).sum() > 0:
810
+ ends_count = (end_position > 0).sum(1)
811
+ model_subject_features = torch.cat(
812
+ [
813
+ torch.repeat_interleave(
814
+ model_features[start_position > 0], ends_count, dim=0
815
+ ), # start position features
816
+ torch.repeat_interleave(model_features, start_counts, dim=0)[
817
+ end_position > 0
818
+ ], # end position features
819
+ ],
820
+ dim=-1,
821
+ )
822
+ ents_count = torch.nn.utils.rnn.pad_sequence(
823
+ torch.split(ends_count, start_counts.tolist()),
824
+ batch_first=True,
825
+ padding_value=0,
826
+ ).sum(1)
827
+ model_subject_features = torch.nn.utils.rnn.pad_sequence(
828
+ torch.split(model_subject_features, ents_count.tolist()),
829
+ batch_first=True,
830
+ padding_value=-100,
831
+ )
832
+
833
+ # if is_validation or is_prediction:
834
+ # model_subject_features = model_subject_features[:, :30, :]
835
+
836
+ # entity disambiguation. Here relation_disambiguation_loss would only be useful to
837
+ # reduce the number of candidate relations for the next step, but currently unused.
838
+ if self.config.entity_type_loss or self.relation_disambiguation_loss:
839
+ (re_ned_entities_logits) = self.compute_entity_logits(
840
+ model_subject_features,
841
+ model_features[
842
+ special_symbols_mask | special_symbols_mask_entities
843
+ ].view(batch_size, -1, model_features.shape[-1]),
844
+ )
845
+ entity_types = torch.sum(special_symbols_mask_entities, dim=1)[0].item()
846
+ ned_type_logits = re_ned_entities_logits[:, :, :entity_types]
847
+ re_entities_logits = re_ned_entities_logits[:, :, entity_types:]
848
+
849
+ if self.config.entity_type_loss:
850
+ ned_type_probabilities = torch.sigmoid(ned_type_logits)
851
+ ned_type_predictions = ned_type_probabilities.argmax(dim=-1)
852
+
853
+ if self.config.add_entity_embedding:
854
+ special_symbols_representation = model_features[
855
+ special_symbols_mask_entities
856
+ ].view(batch_size, entity_types, -1)
857
+
858
+ entities_representation = torch.einsum(
859
+ "bsp,bpe->bse",
860
+ ned_type_probabilities,
861
+ special_symbols_representation,
862
+ )
863
+ model_subject_features = torch.cat(
864
+ [model_subject_features, entities_representation], dim=-1
865
+ )
866
+ re_entities_probabilities = torch.sigmoid(re_entities_logits)
867
+ re_entities_predictions = re_entities_probabilities.round()
868
+ else:
869
+ (
870
+ ned_type_logits,
871
+ ned_type_probabilities,
872
+ re_entities_logits,
873
+ re_entities_probabilities,
874
+ ) = (None, None, None, None)
875
+ ned_type_predictions, re_entities_predictions = (
876
+ torch.zeros([batch_size, 1], dtype=torch.long).to(input_ids.device),
877
+ torch.zeros([batch_size, 1], dtype=torch.long).to(input_ids.device),
878
+ )
879
+
880
+ # Compute relation logits
881
+ re_logits = self.compute_relation_logits(
882
+ model_subject_features,
883
+ model_features[special_symbols_mask].view(
884
+ batch_size, -1, model_features.shape[-1]
885
+ ),
886
+ )
887
+
888
+ re_probabilities = torch.softmax(re_logits, dim=-1)
889
+ # we set a thresshold instead of argmax in cause it needs to be tweaked
890
+ re_predictions = re_probabilities[:, :, :, :, 1] > relation_threshold
891
+ # re_predictions = re_probabilities.argmax(dim=-1)
892
+ re_probabilities = re_probabilities[:, :, :, :, 1]
893
+ # re_logits, re_probabilities, re_predictions = (
894
+ # torch.zeros(
895
+ # [batch_size, 1, 1, special_symbols_mask.sum(1)[0]], dtype=torch.long
896
+ # ).to(input_ids.device),
897
+ # torch.zeros(
898
+ # [batch_size, 1, 1, special_symbols_mask.sum(1)[0]], dtype=torch.long
899
+ # ).to(input_ids.device),
900
+ # torch.zeros(
901
+ # [batch_size, 1, 1, special_symbols_mask.sum(1)[0]], dtype=torch.long
902
+ # ).to(input_ids.device),
903
+ # )
904
+
905
+ else:
906
+ (
907
+ ned_type_logits,
908
+ ned_type_probabilities,
909
+ re_entities_logits,
910
+ re_entities_probabilities,
911
+ ) = (None, None, None, None)
912
+ ned_type_predictions, re_entities_predictions = (
913
+ torch.zeros([batch_size, 1], dtype=torch.long).to(input_ids.device),
914
+ torch.zeros([batch_size, 1], dtype=torch.long).to(input_ids.device),
915
+ )
916
+ re_logits, re_probabilities, re_predictions = (
917
+ torch.zeros(
918
+ [batch_size, 1, 1, special_symbols_mask.sum(1)[0]], dtype=torch.long
919
+ ).to(input_ids.device),
920
+ torch.zeros(
921
+ [batch_size, 1, 1, special_symbols_mask.sum(1)[0]], dtype=torch.long
922
+ ).to(input_ids.device),
923
+ torch.zeros(
924
+ [batch_size, 1, 1, special_symbols_mask.sum(1)[0]], dtype=torch.long
925
+ ).to(input_ids.device),
926
+ )
927
+
928
+ # output build
929
+ output_dict = dict(
930
+ batch_size=batch_size,
931
+ ned_start_logits=ned_start_logits,
932
+ ned_start_probabilities=ned_start_probabilities,
933
+ ned_start_predictions=ned_start_predictions,
934
+ ned_end_logits=ned_end_logits,
935
+ ned_end_probabilities=ned_end_probabilities,
936
+ ned_end_predictions=ned_end_predictions,
937
+ ned_type_logits=ned_type_logits,
938
+ ned_type_probabilities=ned_type_probabilities,
939
+ ned_type_predictions=ned_type_predictions,
940
+ re_entities_logits=re_entities_logits,
941
+ re_entities_probabilities=re_entities_probabilities,
942
+ re_entities_predictions=re_entities_predictions,
943
+ re_logits=re_logits,
944
+ re_probabilities=re_probabilities,
945
+ re_predictions=re_predictions,
946
+ )
947
+
948
+ if (
949
+ start_labels is not None
950
+ and end_labels is not None
951
+ and relation_labels is not None
952
+ and is_prediction is False
953
+ ):
954
+ ned_start_loss = self.compute_loss(ned_start_logits, ned_start_labels)
955
+ end_labels[end_labels > 0] = 1
956
+ ned_end_loss = self.compute_loss(ned_end_logits, end_labels)
957
+ if self.config.entity_type_loss or self.relation_disambiguation_loss:
958
+ ned_type_loss = self.compute_ned_type_loss(
959
+ disambiguation_labels,
960
+ re_ned_entities_logits,
961
+ ned_type_logits,
962
+ re_entities_logits,
963
+ entity_types,
964
+ (model_subject_features != -100).all(2),
965
+ )
966
+ relation_loss = self.compute_relation_loss(relation_labels, re_logits)
967
+ # compute loss. We can skip the relation loss if we are in the first epochs (optional)
968
+ if self.config.entity_type_loss or self.relation_disambiguation_loss:
969
+ output_dict["loss"] = (
970
+ ned_start_loss + ned_end_loss + relation_loss + ned_type_loss
971
+ ) / 4
972
+ output_dict["ned_type_loss"] = ned_type_loss
973
+ else:
974
+ output_dict["loss"] = ((1 / 4) * (ned_start_loss + ned_end_loss)) + (
975
+ (1 / 2) * relation_loss
976
+ )
977
+
978
+ output_dict["ned_start_loss"] = ned_start_loss
979
+ output_dict["ned_end_loss"] = ned_end_loss
980
+ output_dict["re_loss"] = relation_loss
981
+
982
+ return output_dict
pytorch_model.bin ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:f77acaaeedefcbb1f4b532ec6b368b1b9c3abf3c64db4de0d0bfbacdbf30a714
3
+ size 1753425274
special_tokens_map.json ADDED
@@ -0,0 +1,112 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "additional_special_tokens": [
3
+ "--NME--",
4
+ "[E-0]",
5
+ "[E-1]",
6
+ "[E-2]",
7
+ "[E-3]",
8
+ "[E-4]",
9
+ "[E-5]",
10
+ "[E-6]",
11
+ "[E-7]",
12
+ "[E-8]",
13
+ "[E-9]",
14
+ "[E-10]",
15
+ "[E-11]",
16
+ "[E-12]",
17
+ "[E-13]",
18
+ "[E-14]",
19
+ "[E-15]",
20
+ "[E-16]",
21
+ "[E-17]",
22
+ "[E-18]",
23
+ "[E-19]",
24
+ "[E-20]",
25
+ "[E-21]",
26
+ "[E-22]",
27
+ "[E-23]",
28
+ "[E-24]",
29
+ "[E-25]",
30
+ "[E-26]",
31
+ "[E-27]",
32
+ "[E-28]",
33
+ "[E-29]",
34
+ "[E-30]",
35
+ "[E-31]",
36
+ "[E-32]",
37
+ "[E-33]",
38
+ "[E-34]",
39
+ "[E-35]",
40
+ "[E-36]",
41
+ "[E-37]",
42
+ "[E-38]",
43
+ "[E-39]",
44
+ "[E-40]",
45
+ "[E-41]",
46
+ "[E-42]",
47
+ "[E-43]",
48
+ "[E-44]",
49
+ "[E-45]",
50
+ "[E-46]",
51
+ "[E-47]",
52
+ "[E-48]",
53
+ "[E-49]",
54
+ "[E-50]",
55
+ "[E-51]",
56
+ "[E-52]",
57
+ "[E-53]",
58
+ "[E-54]",
59
+ "[E-55]",
60
+ "[E-56]",
61
+ "[E-57]",
62
+ "[E-58]",
63
+ "[E-59]",
64
+ "[E-60]",
65
+ "[E-61]",
66
+ "[E-62]",
67
+ "[E-63]",
68
+ "[E-64]",
69
+ "[E-65]",
70
+ "[E-66]",
71
+ "[E-67]",
72
+ "[E-68]",
73
+ "[E-69]",
74
+ "[E-70]",
75
+ "[E-71]",
76
+ "[E-72]",
77
+ "[E-73]",
78
+ "[E-74]",
79
+ "[E-75]",
80
+ "[E-76]",
81
+ "[E-77]",
82
+ "[E-78]",
83
+ "[E-79]",
84
+ "[E-80]",
85
+ "[E-81]",
86
+ "[E-82]",
87
+ "[E-83]",
88
+ "[E-84]",
89
+ "[E-85]",
90
+ "[E-86]",
91
+ "[E-87]",
92
+ "[E-88]",
93
+ "[E-89]",
94
+ "[E-90]",
95
+ "[E-91]",
96
+ "[E-92]",
97
+ "[E-93]",
98
+ "[E-94]",
99
+ "[E-95]",
100
+ "[E-96]",
101
+ "[E-97]",
102
+ "[E-98]",
103
+ "[E-99]"
104
+ ],
105
+ "bos_token": "[CLS]",
106
+ "cls_token": "[CLS]",
107
+ "eos_token": "[SEP]",
108
+ "mask_token": "[MASK]",
109
+ "pad_token": "[PAD]",
110
+ "sep_token": "[SEP]",
111
+ "unk_token": "[UNK]"
112
+ }
spm.model ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:c679fbf93643d19aab7ee10c0b99e460bdbc02fedf34b92b05af343b4af586fd
3
+ size 2464616
tokenizer.json ADDED
The diff for this file is too large to render. See raw diff
 
tokenizer_config.json ADDED
@@ -0,0 +1,120 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "add_prefix_space": true,
3
+ "additional_special_tokens": [
4
+ "--NME--",
5
+ "[E-0]",
6
+ "[E-1]",
7
+ "[E-2]",
8
+ "[E-3]",
9
+ "[E-4]",
10
+ "[E-5]",
11
+ "[E-6]",
12
+ "[E-7]",
13
+ "[E-8]",
14
+ "[E-9]",
15
+ "[E-10]",
16
+ "[E-11]",
17
+ "[E-12]",
18
+ "[E-13]",
19
+ "[E-14]",
20
+ "[E-15]",
21
+ "[E-16]",
22
+ "[E-17]",
23
+ "[E-18]",
24
+ "[E-19]",
25
+ "[E-20]",
26
+ "[E-21]",
27
+ "[E-22]",
28
+ "[E-23]",
29
+ "[E-24]",
30
+ "[E-25]",
31
+ "[E-26]",
32
+ "[E-27]",
33
+ "[E-28]",
34
+ "[E-29]",
35
+ "[E-30]",
36
+ "[E-31]",
37
+ "[E-32]",
38
+ "[E-33]",
39
+ "[E-34]",
40
+ "[E-35]",
41
+ "[E-36]",
42
+ "[E-37]",
43
+ "[E-38]",
44
+ "[E-39]",
45
+ "[E-40]",
46
+ "[E-41]",
47
+ "[E-42]",
48
+ "[E-43]",
49
+ "[E-44]",
50
+ "[E-45]",
51
+ "[E-46]",
52
+ "[E-47]",
53
+ "[E-48]",
54
+ "[E-49]",
55
+ "[E-50]",
56
+ "[E-51]",
57
+ "[E-52]",
58
+ "[E-53]",
59
+ "[E-54]",
60
+ "[E-55]",
61
+ "[E-56]",
62
+ "[E-57]",
63
+ "[E-58]",
64
+ "[E-59]",
65
+ "[E-60]",
66
+ "[E-61]",
67
+ "[E-62]",
68
+ "[E-63]",
69
+ "[E-64]",
70
+ "[E-65]",
71
+ "[E-66]",
72
+ "[E-67]",
73
+ "[E-68]",
74
+ "[E-69]",
75
+ "[E-70]",
76
+ "[E-71]",
77
+ "[E-72]",
78
+ "[E-73]",
79
+ "[E-74]",
80
+ "[E-75]",
81
+ "[E-76]",
82
+ "[E-77]",
83
+ "[E-78]",
84
+ "[E-79]",
85
+ "[E-80]",
86
+ "[E-81]",
87
+ "[E-82]",
88
+ "[E-83]",
89
+ "[E-84]",
90
+ "[E-85]",
91
+ "[E-86]",
92
+ "[E-87]",
93
+ "[E-88]",
94
+ "[E-89]",
95
+ "[E-90]",
96
+ "[E-91]",
97
+ "[E-92]",
98
+ "[E-93]",
99
+ "[E-94]",
100
+ "[E-95]",
101
+ "[E-96]",
102
+ "[E-97]",
103
+ "[E-98]",
104
+ "[E-99]"
105
+ ],
106
+ "bos_token": "[CLS]",
107
+ "clean_up_tokenization_spaces": true,
108
+ "cls_token": "[CLS]",
109
+ "do_lower_case": false,
110
+ "eos_token": "[SEP]",
111
+ "mask_token": "[MASK]",
112
+ "model_max_length": 1000000000000000019884624838656,
113
+ "pad_token": "[PAD]",
114
+ "sep_token": "[SEP]",
115
+ "sp_model_kwargs": {},
116
+ "split_by_punct": false,
117
+ "tokenizer_class": "DebertaV2Tokenizer",
118
+ "unk_token": "[UNK]",
119
+ "vocab_type": "spm"
120
+ }