Created
January 28, 2021 18:03
-
-
Save ramsrigouthamg/170eb7175173097798819c35ac9f2020 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import csv | |
| import os | |
| from collections import namedtuple | |
| import re | |
| import torch | |
| from tabulate import tabulate | |
| from torch.nn.functional import softmax | |
| from tqdm import tqdm | |
| from transformers import BertTokenizer | |
| import time | |
| from transformers import T5ForConditionalGeneration,T5Tokenizer | |
| import nltk | |
| nltk.download('wordnet') | |
| from nltk.corpus import wordnet as wn | |
| import torch | |
| from tqdm import tqdm | |
| GlossSelectionRecord = namedtuple("GlossSelectionRecord", ["guid", "sentence", "sense_keys", "glosses", "targets"]) | |
| BertInput = namedtuple("BertInput", ["input_ids", "input_mask", "segment_ids", "label_id"]) | |
| def _create_features_from_records(records, max_seq_length, tokenizer, cls_token_at_end=False, pad_on_left=False, | |
| cls_token='[CLS]', sep_token='[SEP]', pad_token=0, | |
| sequence_a_segment_id=0, sequence_b_segment_id=1, | |
| cls_token_segment_id=1, pad_token_segment_id=0, | |
| mask_padding_with_zero=True, disable_progress_bar=False): | |
| """ Convert records to list of features. Each feature is a list of sub-features where the first element is | |
| always the feature created from context-gloss pair while the rest of the elements are features created from | |
| context-example pairs (if available) | |
| `cls_token_at_end` define the location of the CLS token: | |
| - False (Default, BERT/XLM pattern): [CLS] + A + [SEP] + B + [SEP] | |
| - True (XLNet/GPT pattern): A + [SEP] + B + [SEP] + [CLS] | |
| `cls_token_segment_id` define the segment id associated to the CLS token (0 for BERT, 2 for XLNet) | |
| """ | |
| features = [] | |
| for record in tqdm(records, disable=disable_progress_bar): | |
| tokens_a = tokenizer.tokenize(record.sentence) | |
| sequences = [(gloss, 1 if i in record.targets else 0) for i, gloss in enumerate(record.glosses)] | |
| pairs = [] | |
| for seq, label in sequences: | |
| tokens_b = tokenizer.tokenize(seq) | |
| # Modifies `tokens_a` and `tokens_b` in place so that the total | |
| # length is less than the specified length. | |
| # Account for [CLS], [SEP], [SEP] with "- 3" | |
| _truncate_seq_pair(tokens_a, tokens_b, max_seq_length - 3) | |
| # The convention in BERT is: | |
| # (a) For sequence pairs: | |
| # tokens: [CLS] is this jack ##son ##ville ? [SEP] no it is not . [SEP] | |
| # type_ids: 0 0 0 0 0 0 0 0 1 1 1 1 1 1 | |
| # | |
| # Where "type_ids" are used to indicate whether this is the first | |
| # sequence or the second sequence. The embedding vectors for `type=0` and | |
| # `type=1` were learned during pre-training and are added to the wordpiece | |
| # embedding vector (and position vector). This is not *strictly* necessary | |
| # since the [SEP] token unambiguously separates the sequences, but it makes | |
| # it easier for the model to learn the concept of sequences. | |
| # | |
| # For classification tasks, the first vector (corresponding to [CLS]) is | |
| # used as as the "sentence vector". Note that this only makes sense because | |
| # the entire model is fine-tuned. | |
| tokens = tokens_a + [sep_token] | |
| segment_ids = [sequence_a_segment_id] * len(tokens) | |
| tokens += tokens_b + [sep_token] | |
| segment_ids += [sequence_b_segment_id] * (len(tokens_b) + 1) | |
| if cls_token_at_end: | |
| tokens = tokens + [cls_token] | |
| segment_ids = segment_ids + [cls_token_segment_id] | |
| else: | |
| tokens = [cls_token] + tokens | |
| segment_ids = [cls_token_segment_id] + segment_ids | |
| input_ids = tokenizer.convert_tokens_to_ids(tokens) | |
| # The mask has 1 for real tokens and 0 for padding tokens. Only real | |
| # tokens are attended to. | |
| input_mask = [1 if mask_padding_with_zero else 0] * len(input_ids) | |
| # Zero-pad up to the sequence length. | |
| padding_length = max_seq_length - len(input_ids) | |
| if pad_on_left: | |
| input_ids = ([pad_token] * padding_length) + input_ids | |
| input_mask = ([0 if mask_padding_with_zero else 1] * padding_length) + input_mask | |
| segment_ids = ([pad_token_segment_id] * padding_length) + segment_ids | |
| else: | |
| input_ids = input_ids + ([pad_token] * padding_length) | |
| input_mask = input_mask + ([0 if mask_padding_with_zero else 1] * padding_length) | |
| segment_ids = segment_ids + ([pad_token_segment_id] * padding_length) | |
| assert len(input_ids) == max_seq_length | |
| assert len(input_mask) == max_seq_length | |
| assert len(segment_ids) == max_seq_length | |
| pairs.append( | |
| BertInput(input_ids=input_ids, input_mask=input_mask, segment_ids=segment_ids, label_id=label) | |
| ) | |
| features.append(pairs) | |
| return features | |
| def _truncate_seq_pair(tokens_a, tokens_b, max_length): | |
| """Truncates a sequence pair in place to the maximum length.""" | |
| # This is a simple heuristic which will always truncate the longer sequence | |
| # one token at a time. This makes more sense than truncating an equal percent | |
| # of tokens from each, since if one sequence is very short then each token | |
| # that's truncated likely contains more information than a longer sequence. | |
| while True: | |
| total_length = len(tokens_a) + len(tokens_b) | |
| if total_length <= max_length: | |
| break | |
| if len(tokens_a) > len(tokens_b): | |
| tokens_a.pop() | |
| else: | |
| tokens_b.pop() | |
| question_model = T5ForConditionalGeneration.from_pretrained('ramsrigouthamg/t5_squad_v1') | |
| question_tokenizer = T5Tokenizer.from_pretrained('t5-base') | |
| MAX_SEQ_LENGTH = 128 | |
| def get_sense(sent): | |
| re_result = re.search(r"\[TGT\](.*)\[TGT\]", sent) | |
| if re_result is None: | |
| print("\nIncorrect input format. Please try again.") | |
| ambiguous_word = re_result.group(1).strip() | |
| results = dict() | |
| wn_pos = wn.NOUN | |
| for i, synset in enumerate(set(wn.synsets(ambiguous_word, pos=wn_pos))): | |
| results[synset] = synset.definition() | |
| if len(results) ==0: | |
| return (None,None,ambiguous_word) | |
| # print (results) | |
| sense_keys=[] | |
| definitions=[] | |
| for sense_key, definition in results.items(): | |
| sense_keys.append(sense_key) | |
| definitions.append(definition) | |
| record = GlossSelectionRecord("test", sent, sense_keys, definitions, [-1]) | |
| features = _create_features_from_records([record], MAX_SEQ_LENGTH, tokenizer, | |
| cls_token=tokenizer.cls_token, | |
| sep_token=tokenizer.sep_token, | |
| cls_token_segment_id=1, | |
| pad_token_segment_id=0, | |
| disable_progress_bar=True)[0] | |
| with torch.no_grad(): | |
| logits = torch.zeros(len(definitions), dtype=torch.double).to(DEVICE) | |
| for i, bert_input in tqdm(list(enumerate(features)), desc="Progress"): | |
| logits[i] = model.ranking_linear( | |
| model.bert( | |
| input_ids=torch.tensor(bert_input.input_ids, dtype=torch.long).unsqueeze(0).to(DEVICE), | |
| attention_mask=torch.tensor(bert_input.input_mask, dtype=torch.long).unsqueeze(0).to(DEVICE), | |
| token_type_ids=torch.tensor(bert_input.segment_ids, dtype=torch.long).unsqueeze(0).to(DEVICE) | |
| )[1] | |
| ) | |
| scores = softmax(logits, dim=0) | |
| preds = (sorted(zip(sense_keys, definitions, scores), key=lambda x: x[-1], reverse=True)) | |
| # print (preds) | |
| sense = preds[0][0] | |
| meaning = preds[0][1] | |
| return (sense,meaning,ambiguous_word) | |
| # Distractors from Wordnet | |
| def get_distractors_wordnet(syn,word): | |
| distractors=[] | |
| word= word.lower() | |
| orig_word = word | |
| if len(word.split())>0: | |
| word = word.replace(" ","_") | |
| hypernym = syn.hypernyms() | |
| if len(hypernym) == 0: | |
| return distractors | |
| for item in hypernym[0].hyponyms(): | |
| name = item.lemmas()[0].name() | |
| #print ("name ",name, " word",orig_word) | |
| if name == orig_word: | |
| continue | |
| name = name.replace("_"," ") | |
| name = " ".join(w.capitalize() for w in name.split()) | |
| if name is not None and name not in distractors: | |
| distractors.append(name) | |
| return distractors | |
| def get_question(sentence,answer): | |
| text = "context: {} answer: {} </s>".format(sentence,answer) | |
| max_len = 256 | |
| encoding = question_tokenizer.encode_plus(text,max_length=max_len, pad_to_max_length=True, return_tensors="pt") | |
| input_ids, attention_mask = encoding["input_ids"], encoding["attention_mask"] | |
| outs = question_model.generate(input_ids=input_ids, | |
| attention_mask=attention_mask, | |
| early_stopping=True, | |
| num_beams=5, | |
| num_return_sequences=1, | |
| no_repeat_ngram_size=2, | |
| max_length=200) | |
| dec = [question_tokenizer.decode(ids) for ids in outs] | |
| Question = dec[0].replace("question:","") | |
| Question= Question.strip() | |
| return Question |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Heyy, what is the method at line 179? which is model.bert , it seems that when we load your model from your onedrive link,
it throws,
`Input In [3], in get_sense(sent)
55 print("input_mask\n\n\n", bert_input.input_mask,"\n\n\n")
56 print("segment_ids\n\n\n", bert_input.segment_ids,"\n\n\n")
---> 58 abba = model.bert(
59 input_ids=torch.tensor(bert_input.input_ids, dtype=torch.long).unsqueeze(0).to(DEVICE),
60 attention_mask=torch.tensor(bert_input.input_mask, dtype=torch.long).unsqueeze(0).to(DEVICE),
61 token_type_ids=torch.tensor(bert_input.segment_ids, dtype=torch.long).unsqueeze(0).to(DEVICE)
62 )
63 print("abba \n\n\n\n\n", abba)
64 logits[i] = model.ranking_linear(
65 abba[1]
66 )
File ~/scraps/gemsqa-testbench/venv-bert-distractor/lib/python3.8/site-packages/torch/nn/modules/module.py:1102, in Module._call_impl(self, *input, **kwargs)
1098 # If we don't have any hooks, we want to skip the rest of the logic in
1099 # this function, and just call forward.
1100 if not (self._backward_hooks or self._forward_hooks or self._forward_pre_hooks or _global_backward_hooks
1101 or _global_forward_hooks or _global_forward_pre_hooks):
-> 1102 return forward_call(*input, **kwargs)
1103 # Do not call functions when jit is used
1104 full_backward_hooks, non_full_backward_hooks = [], []
File ~/scraps/gemsqa-testbench/venv-bert-distractor/lib/python3.8/site-packages/transformers/models/bert/modeling_bert.py:989, in BertModel.forward(self, input_ids, attention_mask, token_type_ids, position_ids, head_mask, inputs_embeds, encoder_hidden_states, encoder_attention_mask, past_key_values, use_cache, output_attentions, output_hidden_states, return_dict)
982 # Prepare head mask if needed
983 # 1.0 in head_mask indicate we keep the head
984 # attention_probs has shape bsz x n_heads x N x N
985 # input head_mask has shape [num_heads] or [num_hidden_layers x num_heads]
986 # and head_mask is converted to shape [num_hidden_layers x batch x num_heads x seq_length x seq_length]
987 head_mask = self.get_head_mask(head_mask, self.config.num_hidden_layers)
--> 989 embedding_output = self.embeddings(
990 input_ids=input_ids,
991 position_ids=position_ids,
992 token_type_ids=token_type_ids,
993 inputs_embeds=inputs_embeds,
994 past_key_values_length=past_key_values_length,
995 )
996 encoder_outputs = self.encoder(
997 embedding_output,
998 attention_mask=extended_attention_mask,
(...)
1006 return_dict=return_dict,
1007 )
1008 sequence_output = encoder_outputs[0]
File ~/scraps/gemsqa-testbench/venv-bert-distractor/lib/python3.8/site-packages/torch/nn/modules/module.py:1102, in Module._call_impl(self, *input, **kwargs)
1098 # If we don't have any hooks, we want to skip the rest of the logic in
1099 # this function, and just call forward.
1100 if not (self._backward_hooks or self._forward_hooks or self._forward_pre_hooks or _global_backward_hooks
1101 or _global_forward_hooks or _global_forward_pre_hooks):
-> 1102 return forward_call(*input, **kwargs)
1103 # Do not call functions when jit is used
1104 full_backward_hooks, non_full_backward_hooks = [], []
File ~/scraps/gemsqa-testbench/venv-bert-distractor/lib/python3.8/site-packages/transformers/models/bert/modeling_bert.py:214, in BertEmbeddings.forward(self, input_ids, token_type_ids, position_ids, inputs_embeds, past_key_values_length)
211 token_type_ids = torch.zeros(input_shape, dtype=torch.long, device=self.position_ids.device)
213 if inputs_embeds is None:
--> 214 inputs_embeds = self.word_embeddings(input_ids)
215 token_type_embeddings = self.token_type_embeddings(token_type_ids)
217 embeddings = inputs_embeds + token_type_embeddings
File ~/scraps/gemsqa-testbench/venv-bert-distractor/lib/python3.8/site-packages/torch/nn/modules/module.py:1102, in Module._call_impl(self, *input, **kwargs)
1098 # If we don't have any hooks, we want to skip the rest of the logic in
1099 # this function, and just call forward.
1100 if not (self._backward_hooks or self._forward_hooks or self._forward_pre_hooks or _global_backward_hooks
1101 or _global_forward_hooks or _global_forward_pre_hooks):
-> 1102 return forward_call(*input, **kwargs)
1103 # Do not call functions when jit is used
1104 full_backward_hooks, non_full_backward_hooks = [], []
File ~/scraps/gemsqa-testbench/venv-bert-distractor/lib/python3.8/site-packages/torch/nn/modules/sparse.py:158, in Embedding.forward(self, input)
157 def forward(self, input: Tensor) -> Tensor:
--> 158 return F.embedding(
159 input, self.weight, self.padding_idx, self.max_norm,
160 self.norm_type, self.scale_grad_by_freq, self.sparse)
File ~/scraps/gemsqa-testbench/venv-bert-distractor/lib/python3.8/site-packages/torch/nn/functional.py:2044, in embedding(input, weight, padding_idx, max_norm, norm_type, scale_grad_by_freq, sparse)
2038 # Note [embedding_renorm set_grad_enabled]
2039 # XXX: equivalent to
2040 # with torch.no_grad():
2041 # torch.embedding_renorm_
2042 # remove once script supports set_grad_enabled
2043 no_grad_embedding_renorm(weight, input, max_norm, norm_type)
-> 2044 return torch.embedding(weight, input, padding_idx, scale_grad_by_freq, sparse)
IndexError: index out of range in self
`
We have checked the
bert_input.input_ids,
bert_input.input_mask,
bert_input.segment_ids,
and value seem to exist there.
Thankss