RichardWang commited on
Commit
2f88e34
1 Parent(s): 5965276
Files changed (4) hide show
  1. config.json +22 -0
  2. configuration_tsp.py +32 -0
  3. modeling_tsp.py +506 -0
  4. pytorch_model.bin +3 -0
config.json ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "architectures": [
3
+ "TSPModelForPretraining"
4
+ ],
5
+ "auto_map": {
6
+ "AutoConfig": "configuration_tsp.TSPConfig",
7
+ "AutoModelForPreTraining": "modeling_tsp.TSPModelForPretraining"
8
+ },
9
+ "dropout_prob": 0.1,
10
+ "embedding_size": 128,
11
+ "hidden_size": 256,
12
+ "intermediate_size": 1024,
13
+ "max_sequence_length": 128,
14
+ "model_type": "tsp",
15
+ "num_attention_heads": 4,
16
+ "num_hidden_layers": 12,
17
+ "pad_token_id": 0,
18
+ "position_embedding_type": "absolute",
19
+ "torch_dtype": "float32",
20
+ "transformers_version": "4.17.0",
21
+ "vocab_size": 30522
22
+ }
configuration_tsp.py ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from transformers import PretrainedConfig
2
+
3
+
4
+ class TSPConfig(PretrainedConfig):
5
+ model_type = "tsp"
6
+
7
+ def __init__(
8
+ self,
9
+ embedding_size=128,
10
+ hidden_size=256,
11
+ num_hidden_layers=12,
12
+ num_attention_heads=4,
13
+ intermediate_size=1024,
14
+ dropout_prob=0.1,
15
+ max_sequence_length=128,
16
+ position_embedding_type="absolute",
17
+ pad_token_id=0,
18
+ vocab_size=30522,
19
+ **kwargs
20
+ ):
21
+ assert hidden_size % num_attention_heads == 0
22
+ assert position_embedding_type in ["absolute", "rotary"]
23
+ self.vocab_size = vocab_size
24
+ self.embedding_size = embedding_size
25
+ self.hidden_size = hidden_size
26
+ self.num_hidden_layers = num_hidden_layers
27
+ self.num_attention_heads = num_attention_heads
28
+ self.intermediate_size = intermediate_size
29
+ self.dropout_prob = dropout_prob
30
+ self.max_sequence_length = max_sequence_length
31
+ self.position_embedding_type = position_embedding_type
32
+ super().__init__(pad_token_id=pad_token_id, **kwargs)
modeling_tsp.py ADDED
@@ -0,0 +1,506 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # A BERT model that
2
+ # - has embedding projector when embedding_size != hiddne_size, like ELECTRA
3
+ # - the attention use one linear projection to generate query, key, value at once to get faster
4
+ # - is able to choose rotary position embedding
5
+
6
+ from copy import deepcopy
7
+ import math
8
+ import torch
9
+ from torch import nn
10
+ import torch.nn.functional as F
11
+ from transformers import PreTrainedModel
12
+ from .configuration_tsp import TSPConfig
13
+
14
+
15
+ class TSPPreTrainedModel(PreTrainedModel):
16
+ config_class = TSPConfig
17
+ base_model_prefix = "tsp"
18
+
19
+ def _init_weights(self, module):
20
+ """Initialize the weights"""
21
+ if isinstance(module, nn.Linear):
22
+ # Slightly different from the TF version which uses truncated_normal for initialization
23
+ # cf https://github.com/pytorch/pytorch/pull/5617
24
+ module.weight.data.normal_(mean=0.0, std=0.02)
25
+ if module.bias is not None:
26
+ module.bias.data.zero_()
27
+ elif isinstance(module, nn.Embedding):
28
+ module.weight.data.normal_(mean=0.0, std=0.02)
29
+ if module.padding_idx is not None:
30
+ module.weight.data[module.padding_idx].zero_()
31
+ elif isinstance(module, nn.LayerNorm):
32
+ module.bias.data.zero_()
33
+ module.weight.data.fill_(1.0)
34
+
35
+ # ====================================
36
+ # Pretraining Model
37
+ # ====================================
38
+
39
+
40
+ class TSPModelForPretraining(TSPPreTrainedModel):
41
+ def __init__(self, config, use_electra=False):
42
+ super().__init__(config)
43
+ self.backbone = TSPModel(config)
44
+ if use_electra:
45
+ mlm_config = deepcopy(config)
46
+ mlm_config.hidden_size /= config.generator_size_divisor
47
+ mlm_config.intermediate_size /= config.generator_size_divisor
48
+ mlm_config.num_attention_heads /= config.generator_size_divisor
49
+ self.mlm_backbone = TSPModel(mlm_config)
50
+ self.mlm_head = MaskedLMHead(
51
+ mlm_config, word_embeddings=self.mlm_backbone.embeddings.word_embeddings
52
+ )
53
+ self.rtd_backbone = self.backbone
54
+ self.rtd_backbone.embeddings = self.mlm_backbone.embeddings
55
+ self.rtd_head = ReplacedTokenDiscriminationHead(config)
56
+ else:
57
+ self.mlm_backbone = self.backbone
58
+ self.mlm_head = MaskedLMHead(config)
59
+ self.apply(self._init_weights)
60
+
61
+ def forward(self, *args, **kwargs):
62
+ raise NotImplementedError(
63
+ "Refer to the implementation of text structrue prediction task for how to use the model."
64
+ )
65
+
66
+ def mlm_forward(
67
+ self,
68
+ corrupted_ids, # <int>(B,L), partially masked/replaced input token ids
69
+ attention_mask, # <int>(B,L), 1 / 0 for tokens that are not attended/ attended
70
+ token_type_ids, # <int>(B,L), 0 / 1 corresponds to a segment A / B token
71
+ mlm_selected=None, # <bool>(B,L), True at mlm selected positiosns. Calculate logits at mlm selected positions if not None.
72
+ ):
73
+ hidden_states = self.mlm_backbone(
74
+ input_ids=corrupted_ids,
75
+ attention_mask=attention_mask,
76
+ token_type_ids=token_type_ids,
77
+ ) # (B,L,D)
78
+ return self.mlm_head(
79
+ hidden_states, is_selected=mlm_selected
80
+ ) # (#mlm selected, vocab size)/ (B,L,vocab size)
81
+
82
+ def rtd_forward(
83
+ self,
84
+ corrupted_ids, # <int>(B,L), partially replaced input token ids
85
+ attention_mask, # <int>(B,L), 1 / 0 for tokens that are not attended/ attended
86
+ token_type_ids, # <int>(B,L), 0 / 1 corresponds to a segment A / B token
87
+ ):
88
+ hidden_states = self.rtd_backbone(
89
+ input_ids=corrupted_ids,
90
+ attention_mask=attention_mask,
91
+ token_type_ids=token_type_ids,
92
+ ) # (B,L,D)
93
+ return self.rtd_backbone(hidden_states) # (B,L)
94
+
95
+ def tsp_forward(
96
+ self, hidden_states, # (B,L,D)
97
+ ):
98
+ raise NotImplementedError
99
+
100
+
101
+ class MaskedLMHead(nn.Module):
102
+ def __init__(self, config, word_embeddings=None):
103
+ super().__init__()
104
+ self.linear = nn.Linear(config.hidden_size, config.embedding_size)
105
+ self.norm = nn.LayerNorm(config.embedding_size)
106
+ self.predictor = nn.Linear(config.embedding_size, config.vocab_size)
107
+ if word_embeddings is not None:
108
+ self.predictor.weight = word_embeddings.weight
109
+
110
+ def forward(
111
+ self,
112
+ x, # (B,L,D)
113
+ is_selected=None, # <bool>(B,L), True at positions choosed by mlm probability
114
+ ):
115
+ if is_selected is not None:
116
+ # Only mlm positions are counted in loss, so we can apply output layer computation only to
117
+ # those positions to significantly reduce compuatational cost
118
+ x = x[is_selected] # ( #selected, D)
119
+ x = self.linear(x) # (B,L,E)/(#selected,E)
120
+ x = F.gelu(x) # (B,L,E)/(#selected,E)
121
+ x = self.norm(x) # (B,L,E)/(#selected,E)
122
+ return self.predictor(x) # (B,L,V)/(#selected,V)
123
+
124
+
125
+ class ReplacedTokenDiscriminationHead(nn.Module):
126
+ def __init__(self, config):
127
+ super().__init__()
128
+ self.linear = nn.Linear(config.hidden_size, config.hidden_size)
129
+ self.predictor = nn.Linear(config.hidden_size, 1)
130
+
131
+ def forward(self, x): # (B,L,D)
132
+ x = self.linear(x) # (B,L,D)
133
+ x = F.gelu(x)
134
+ x = self.predictor(x) # (B,L,1)
135
+ return x.squeeze(-1) # (B,L)
136
+
137
+
138
+ # ====================================
139
+ # Finetuning Model
140
+ # ====================================
141
+
142
+
143
+ class TSPModelForTokenClassification(TSPPreTrainedModel):
144
+ def __init__(self, config, num_classes):
145
+ super().__init__(config)
146
+ self.backbone = TSPModel(config)
147
+ self.head = TokenClassificationHead(config, num_classes)
148
+ self.apply(self._init_weights)
149
+
150
+ def forward(
151
+ self,
152
+ input_ids, # <int>(B,L)
153
+ attention_mask, # <int>(B,L), 1 / 0 for tokens that are not attended/ attended
154
+ token_type_ids, # <int>(B,L), 0 / 1 corresponds to a segment A / B token
155
+ ):
156
+ hidden_states = self.backbone(
157
+ input_ids=input_ids,
158
+ attention_mask=attention_mask,
159
+ token_type_ids=token_type_ids,
160
+ ) # (B,L,D)
161
+ return self.head(hidden_states) # (B,L,C)
162
+
163
+
164
+ class TokenClassificationHead(nn.Module):
165
+ def __init__(self, config, num_classes):
166
+ super().__init__()
167
+ self.dropout = nn.Dropout(c.dropout_prob)
168
+ self.classifier = nn.Linear(c.hidden_size, num_classes)
169
+
170
+ def forward(self, x): # (B,L,D)
171
+ x = self.dropout(x) # (B,L,D)
172
+ x = self.classifier(x) # (B,L,C)
173
+ return x # (B,L,C)
174
+
175
+
176
+ class TSPModelForSequenceClassification(TSPPreTrainedModel):
177
+ def __init__(self, config, num_classes):
178
+ super().__init__(config)
179
+ self.backbone = TSPModel(config)
180
+ self.head = SequenceClassififcationHead(config, num_classes)
181
+ self.apply(self._init_weights)
182
+
183
+ def forward(
184
+ self,
185
+ input_ids, # <int>(B,L)
186
+ attention_mask, # <int>(B,L), 1 / 0 for tokens that are not attended/ attended
187
+ token_type_ids, # <int>(B,L), 0 / 1 corresponds to a segment A / B token
188
+ ):
189
+ hidden_states = self.backbone(
190
+ input_ids=input_ids,
191
+ attention_mask=attention_mask,
192
+ token_type_ids=token_type_ids,
193
+ ) # (B,L,D)
194
+ return self.head(hidden_states) # (B,L,C)
195
+
196
+
197
+ class SequenceClassififcationHead(nn.Module):
198
+ def __init__(self, config, num_classes):
199
+ super().__init__()
200
+ self.dropout = nn.Dropout(config.dropout_prob)
201
+ self.classifier = nn.Linear(config.hidden_size, num_classes)
202
+
203
+ def forward(
204
+ self, x, # (B,L,D)
205
+ ):
206
+ x = x[:, 0, :] # (B,D), CLS token is taken
207
+ x = self.dropout(x) # (B,D)
208
+ return self.classifier(x) # (B,C)
209
+
210
+
211
+ class TSPModelForQuestionAnswering(TSPPreTrainedModel):
212
+ def __init__(self, config, num_classes):
213
+ super().__init__()
214
+ self.backbone = TSPModel(config)
215
+ self.head = SequenceClassififcationHead(config, num_classes)
216
+
217
+ def forward(
218
+ self,
219
+ input_ids, # <int>(B,L)
220
+ attention_mask, # <int>(B,L), 1 / 0 for tokens that are not attended/ attended
221
+ token_type_ids, # <int>(B,L), 0 / 1 corresponds to a segment A / B token
222
+ ):
223
+ hidden_states = self.backbone(
224
+ input_ids=input_ids,
225
+ attention_mask=attention_mask,
226
+ token_type_ids=token_type_ids,
227
+ ) # (B,L,D)
228
+ return self.head(hidden_states) # (B,L), (B,L), (B)/None
229
+
230
+
231
+ class SquadHead(nn.Module):
232
+ def __init__(
233
+ self, config, beam_size, predict_answerability,
234
+ ):
235
+ super().__init__()
236
+ self.beam_size = beam_size
237
+ self.predict_answerability = predict_answerability
238
+
239
+ # answer start position predictor
240
+ self.start_predictor = nn.Linear(config.hidden_size, 1)
241
+
242
+ # answer end position predictor
243
+ self.end_predictor = nn.Sequential(
244
+ nn.Linear(config.hidden_size * 2, 512), nn.GELU(), nn.Linear(512, 1),
245
+ )
246
+
247
+ # answerability_predictor
248
+ if predict_answerability:
249
+ self.answerability_predictor = nn.Sequential(
250
+ nn.Linear(config.hidden_size * 2, 512), nn.GELU(), nn.Linear(512, 1),
251
+ )
252
+ else:
253
+ self.answerability_predictor = None
254
+
255
+ def forward(
256
+ self,
257
+ hidden_states, # (B,L,D)
258
+ token_type_ids, # <int>(B,L), 0/1 for first sentence (question) or pad, 1 for second sentence (context)
259
+ answer_start_position=None, # train/eval: <int>(B)/None
260
+ ):
261
+
262
+ # Possible range for answer. Note CLS token is also possible to say it is unanswerable
263
+ answer_mask = token_type_ids # (B,L)
264
+ last_sep = answer_mask.cumsum(dim=1) == answer_mask.sum(
265
+ dim=1, keepdim=True
266
+ ) # (B,L), True if it is the last SEP or token after it
267
+ answer_mask = answer_mask * ~last_sep
268
+ answer_mask[:, 0] = 1
269
+ answer_mask = answer_mask.bool()
270
+
271
+ # preidct start positions
272
+ start_logits, start_top_hidden_states = self._calculate_start(
273
+ hidden_states, answer_mask, answer_start_position
274
+ ) # (B,L) , None/ (B,1,D)/ (B,k,D)
275
+
276
+ # predict end positions
277
+ end_logits = self._calculate_end_logits(
278
+ hidden_states, start_top_hidden_states, answer_mask,
279
+ ) # (B,L) / (B,k,L)
280
+
281
+ # (optional) preidct answerability
282
+ answerability_logits = None
283
+ if self.answerability_predictor is not None:
284
+ answerability_logits = self._calculate_answerability_logits(
285
+ hidden_states, start_logits
286
+ ) # (B)
287
+
288
+ return start_logits, end_logits, answerability_logits
289
+
290
+ def _calculate_start(self, hidden_states, answer_mask, start_positions):
291
+ start_logits = self.start_predictor(hidden_states).squeeze(-1) # (B, L)
292
+ start_logits = start_logits.masked_fill(~answer_mask, -float("inf")) # (B,L)
293
+ start_top_indices, start_top_hidden_states = None, None
294
+ if self.training:
295
+ start_top_indices = start_positions # (B,)
296
+ else:
297
+ k = self.beam_size
298
+ _, start_top_indices = start_logits.topk(k=k, dim=-1) # (B,k)
299
+ start_top_hidden_states = torch.stack(
300
+ [
301
+ hiddens.index_select(dim=0, index=index)
302
+ for hiddens, index in zip(hidden_states, start_top_indices)
303
+ ]
304
+ ) # train: (B,1,D)/ eval: (B,k,D)
305
+ return start_logits, start_top_hidden_states
306
+
307
+ def _calculate_end_logits(
308
+ self, hidden_states, start_top_hidden_states, answer_mask
309
+ ):
310
+ B, L, D = hidden_states.shape
311
+ start_tophiddens = start_top_hidden_states.view(B, -1, 1, D).expand(
312
+ -1, -1, L, -1
313
+ ) # train: (B,1,L,D) / eval: (B,k,L,D)
314
+ end_hidden_states = torch.cat(
315
+ [
316
+ start_tophiddens,
317
+ hidden_states.view(B, 1, L, D).expand_as(start_tophiddens),
318
+ ],
319
+ dim=-1,
320
+ ) # train: (B,1,L,2D) / eval: (B,k,L,2D)
321
+ end_logits = self.end_predictor(end_hidden_states).squeeze(-1) # (B,1/k,L)
322
+ end_logits = end_logits.masked_fill(
323
+ ~answer_mask.view(B, 1, L), -float("inf")
324
+ ) # train: (B,1,L) / eval: (B,k,L)
325
+ end_logits = end_logits.squeeze(1) # train: (B,L) / eval: (B,k,L)
326
+
327
+ return end_logits
328
+
329
+ def _calculate_answerability_logits(self, hidden_states, start_logits):
330
+ answerability_hidden_states = hidden_states[:, 0, :] # (B,D)
331
+ start_probs = start_logits.softmax(dim=-1).unsqueeze(-1) # (B,L,1)
332
+ start_featrues = (start_probs * hidden_states).sum(dim=1) # (B,D)
333
+ answerability_hidden_states = torch.cat(
334
+ [answerability_hidden_states, start_featrues], dim=-1
335
+ ) # (B,2D)
336
+ answerability_logits = self.answerability_predictor(
337
+ answerability_hidden_states
338
+ ) # (B,1)
339
+ return answerability_logits.squeeze(-1) # (B,)
340
+
341
+
342
+ # ====================================
343
+ # Backbone (Transformer Encoder)
344
+ # ====================================
345
+
346
+
347
+ class TSPModel(TSPPreTrainedModel):
348
+ config_class = TSPConfig
349
+ base_model_prefix = "tsp"
350
+
351
+ def __init__(self, config):
352
+ super().__init__(config)
353
+ self.embeddings = Embeddings(config)
354
+ if config.embedding_size != config.hidden_size:
355
+ self.embeddings_project = nn.Linear(
356
+ config.embedding_size, config.hidden_size
357
+ )
358
+ self.layers = nn.ModuleList(
359
+ EncoderLayer(config) for _ in range(config.num_hidden_layers)
360
+ )
361
+ self.apply(self._init_weights)
362
+
363
+ def forward(
364
+ self,
365
+ input_ids, # <int>(B,L)
366
+ attention_mask, # <int>(B,L), 1 / 0 for tokens that are not attended/ attended
367
+ token_type_ids, # <int>(B,L), 0 / 1 corresponds to a segment A / B token
368
+ ):
369
+ x = self.embeddings(
370
+ input_ids=input_ids, token_type_ids=token_type_ids
371
+ ) # (B,L,E)
372
+ if hasattr(self, "embeddings_project"):
373
+ x = self.embeddings_project(x) # (B,L,D)
374
+
375
+ extended_attention_mask = self.get_extended_attention_mask(
376
+ attention_mask=attention_mask,
377
+ input_shape=input_ids.shape,
378
+ device=input_ids.device,
379
+ ) # (B,1,1,L)
380
+
381
+ for layer_idx, layer in enumerate(self.layers):
382
+ x = layer(x, attention_mask=extended_attention_mask) # (B,L,D)
383
+
384
+ return x # (B,L,D)
385
+
386
+
387
+ class Embeddings(nn.Module):
388
+ def __init__(self, config):
389
+ super().__init__()
390
+ self.word_embeddings = nn.Embedding(
391
+ config.vocab_size, config.embedding_size, padding_idx=config.pad_token_id
392
+ )
393
+ if config.position_embedding_type == "absolute":
394
+ self.position_embeddings = nn.Embedding(
395
+ config.max_sequence_length, config.embedding_size
396
+ )
397
+ self.token_type_embeddings = nn.Embedding(2, config.embedding_size)
398
+ self.norm = nn.LayerNorm(config.embedding_size)
399
+ self.dropout = nn.Dropout(config.dropout_prob)
400
+
401
+ def forward(
402
+ self,
403
+ input_ids, # <int>(B,L)
404
+ token_type_ids, # <int>(B,L), 0 / 1 corresponds to a segment A / B token
405
+ ):
406
+ B, L = input_ids.shape
407
+ embeddings = self.word_embeddings(input_ids) # (B,L,E)
408
+ if hasattr(self, "position_embeddings"):
409
+ embeddings += self.position_embeddings.weight[None, :L, :]
410
+ embeddings += self.token_type_embeddings(token_type_ids)
411
+ embeddings = self.norm(embeddings) # (B,L,E)
412
+ embeddings = self.dropout(embeddings) # (B,L,E)
413
+ return embeddings # (B,L,E)
414
+
415
+
416
+ class EncoderLayer(nn.Module):
417
+ def __init__(self, config):
418
+ super().__init__()
419
+ self.self_attn_block = BlockWrapper(config, MultiHeadSelfAttention)
420
+ self.transition_block = BlockWrapper(config, FeedForwardNetwork)
421
+
422
+ def forward(
423
+ self,
424
+ x, # (B,L,D)
425
+ attention_mask, # <int>(B,H,L,L), 0 / -1e4 for tokens that are not attended/ attended
426
+ ):
427
+ x = self.self_attn_block(x, attention_mask=attention_mask)
428
+ x = self.transition_block(x)
429
+ return x # (B,L,D)
430
+
431
+
432
+ class BlockWrapper(nn.Module):
433
+ def __init__(self, config, sublayer_cls):
434
+ super().__init__()
435
+ self.sublayer = sublayer_cls(config)
436
+ self.dropout = nn.Dropout(config.dropout_prob)
437
+ self.norm = nn.LayerNorm(config.hidden_size)
438
+
439
+ def forward(self, x, **kwargs):
440
+ original_x = x
441
+ x = self.sublayer(x, **kwargs)
442
+ x = self.dropout(x)
443
+ x = original_x + x
444
+ x = self.norm(x)
445
+ return x
446
+
447
+
448
+ class MultiHeadSelfAttention(nn.Module):
449
+ def __init__(self, config):
450
+ super().__init__()
451
+ self.mix_proj = nn.Linear(config.hidden_size, 3 * config.hidden_size)
452
+ self.attention = Attention(config)
453
+ self.o_proj = nn.Linear(config.hidden_size, config.hidden_size)
454
+ self.H = config.num_attention_heads
455
+ self.d = config.hidden_size // self.H
456
+
457
+ def forward(
458
+ self,
459
+ x, # (B,L,D)
460
+ attention_mask, # <int>(B,H,L,L), 0 / -1e4 for tokens that are not attended/ attended
461
+ ):
462
+ B, L, D, H, d = *x.shape, self.H, self.d
463
+ query, key, value = (
464
+ self.mix_proj(x).view(B, L, H, 3 * d).transpose(1, 2).split(d, dim=-1)
465
+ ) # (B,H,L,d),(B,H,L,d),(B,H,L,d)
466
+ output = self.attention(query, key, value, attention_mask) # (B,H,L,d)
467
+ output = self.o_proj(output.transpose(1, 2).reshape(B, L, D)) # (B,L,D)
468
+ return output # (B,L,D)
469
+
470
+
471
+ class Attention(nn.Module):
472
+ def __init__(self, config):
473
+ super().__init__()
474
+ self.dropout = nn.Dropout(config.dropout_prob)
475
+
476
+ def forward(
477
+ self,
478
+ query, # (B,H,L,d)
479
+ key, # (B,H,L,d)
480
+ value, # (B,H,L,d)
481
+ attention_mask, # <int>(B,H,L,L), 0 / -1e4 for tokens that are not attended/ attended
482
+ ):
483
+ B, H, L, d = key.shape
484
+ attention_score = query.matmul(key.transpose(-2, -1)) # (B,H,L,L)
485
+ attention_score = attention_score / math.sqrt(d) # (B,H,L,L)
486
+ attention_score += attention_mask # (B,H,L,L)
487
+ attention_probs = attention_score.softmax(dim=-1) # (B,H,L,L)
488
+ attention_probs = self.dropout(attention_probs) # (B,H,L,L)
489
+ output = attention_probs.matmul(value) # (B,H,L,d)
490
+ return output # (B,H,L,d)
491
+
492
+
493
+ class FeedForwardNetwork(nn.Module):
494
+ def __init__(self, config):
495
+ super().__init__()
496
+ self.linear1 = nn.Linear(config.hidden_size, config.intermediate_size)
497
+ self.linear2 = nn.Linear(config.intermediate_size, config.hidden_size)
498
+
499
+ def forward(self, x): # (B,L,D)
500
+ x = self.linear1(x) # (B L,intermediate_size)
501
+ x = F.gelu(x) # (B,L,intermediate_size)
502
+ x = self.linear2(x) # (B,L,D)
503
+ return x # (B,L,D)
504
+
505
+
506
+
pytorch_model.bin ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:1868401491982e5ef2feb75d89045551b59931f5bfb89fca510bb50e50fd72ff
3
+ size 69713927