I am trying to get distractors for a list of words and return them in arrays, but i keep getting this error.
Traceback (most recent call last):
File "/home/maro/Documents/codefiles/nlp/venv/lib/python3.8/site-packages/uvicorn/protocols/http/httptools_impl.py", line 401, in run_asgi
result = await app(self.scope, self.receive, self.send)
File "/home/maro/Documents/codefiles/nlp/venv/lib/python3.8/site-packages/uvicorn/middleware/proxy_headers.py", line 78, in __call__
return await self.app(scope, receive, send)
File "/home/maro/Documents/codefiles/nlp/venv/lib/python3.8/site-packages/fastapi/applications.py", line 199, in __call__
await super().__call__(scope, receive, send)
File "/home/maro/Documents/codefiles/nlp/venv/lib/python3.8/site-packages/starlette/applications.py", line 111, in __call__
await self.middleware_stack(scope, receive, send)
File "/home/maro/Documents/codefiles/nlp/venv/lib/python3.8/site-packages/starlette/middleware/errors.py", line 181, in __call__
raise exc from None
File "/home/maro/Documents/codefiles/nlp/venv/lib/python3.8/site-packages/starlette/middleware/errors.py", line 159, in __call__
await self.app(scope, receive, _send)
File "/home/maro/Documents/codefiles/nlp/venv/lib/python3.8/site-packages/starlette/exceptions.py", line 82, in __call__
raise exc from None
File "/home/maro/Documents/codefiles/nlp/venv/lib/python3.8/site-packages/starlette/exceptions.py", line 71, in __call__
await self.app(scope, receive, sender)
File "/home/maro/Documents/codefiles/nlp/venv/lib/python3.8/site-packages/starlette/routing.py", line 566, in __call__
await route.handle(scope, receive, send)
File "/home/maro/Documents/codefiles/nlp/venv/lib/python3.8/site-packages/starlette/routing.py", line 227, in handle
await self.app(scope, receive, send)
File "/home/maro/Documents/codefiles/nlp/venv/lib/python3.8/site-packages/starlette/routing.py", line 41, in app
response = await func(request)
File "/home/maro/Documents/codefiles/nlp/venv/lib/python3.8/site-packages/fastapi/routing.py", line 201, in app
raw_response = await run_endpoint_function(
File "/home/maro/Documents/codefiles/nlp/venv/lib/python3.8/site-packages/fastapi/routing.py", line 150, in run_endpoint_function
return await run_in_threadpool(dependant.call, **values)
File "/home/maro/Documents/codefiles/nlp/venv/lib/python3.8/site-packages/starlette/concurrency.py", line 34, in run_in_threadpool
return await loop.run_in_executor(None, func, *args)
File "/usr/lib/python3.8/concurrent/futures/thread.py", line 57, in run
result = self.fn(*self.args, **self.kwargs)
File "/home/maro/Documents/codefiles/nlx/./main.py", line 104, in getquestion
distractors.append(get_distractors_wordnet(wn.synsets(word),word))
File "/home/maro/Documents/codefiles/nlx/./main.py", line 76, in get_distractors_wordnet
hypernym = syn.hypernyms()
AttributeError: 'list' object has no attribute 'hypernyms'
This is my entire code
from typing import List
from fastT5 import get_onnx_model,get_onnx_runtime_sessions,OnnxT5
from transformers import AutoTokenizer
from pathlib import Path
import os
from fastapi import FastAPI
from pydantic import BaseModel
from textblob import TextBlob
import nltk
from nltk.corpus import wordnet as wn
app = FastAPI()
class QuestionRequest(BaseModel):
context: str
class QuestionResponse(BaseModel):
question: List[str] = []
answer: List[str] = []
distractors_sublist: List[List[str]] = [ [] ]
trained_model_path = './t5_squad_v1/'
pretrained_model_name = Path(trained_model_path).stem
encoder_path = os.path.join(trained_model_path,f"{pretrained_model_name}-encoder-quantized.onnx")
decoder_path = os.path.join(trained_model_path,f"{pretrained_model_name}-decoder-quantized.onnx")
init_decoder_path = os.path.join(trained_model_path,f"{pretrained_model_name}-init-decoder-quantized.onnx")
model_paths = encoder_path, decoder_path, init_decoder_path
model_sessions = get_onnx_runtime_sessions(model_paths)
model = OnnxT5(trained_model_path, model_sessions)
tokenizer = AutoTokenizer.from_pretrained(trained_model_path)
def get_question(sentence,mdl,tknizer):
gfg = TextBlob(sentence)
gfg = gfg.noun_phrases
array=[]
for i in gfg:
text = "context: {} answer: {}".format(sentence,i)
array.append(text)
max_len = 256
question_array =[]
for text in array:
encoding = tknizer.encode_plus(text,max_length=max_len, pad_to_max_length=False,truncation=True, return_tensors="pt")
input_ids, attention_mask = encoding["input_ids"], encoding["attention_mask"]
outs = mdl.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=128)
dec = [tknizer.decode(ids,skip_special_tokens=True) for ids in outs]
Question = dec[0].replace("question:","")
Question= Question.strip()
question_array.append(Question)
print (question_array)
return question_array, gfg
# 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
@app.get('/')
def index():
return {'message':'hello world'}
@app.post("/getquestion", response_model= QuestionResponse)
def getquestion(question: QuestionRequest):
context = question.context
question_array, gfg = get_question(context,model,tokenizer)
answer = gfg[0]
distractors = []
for word in gfg:
distractors.append(get_distractors_wordnet(wn.synsets(word),word))
distractors_sublist = []
for i in range(len(distractors)):
distractors_sublist.append(distractors[i])
return QuestionResponse(question=question_array, answer=answer, distractors_sublist=distractors_sublist)
distractors = get_distractors_wordnet(wn.synsets(answer),answer)
distractors_sublist = [distractors[i:i+3] for i in range(0, len(distractors), 3)]
return QuestionResponse(question=question_array, answer=answer, distractors_sublist=distractors_sublist)
I have tried so many iterations, none seem to work. I am using Fastapi and some personal models. The response should return an array of distractors that contain several sub arrays each representing the distractor for each answer
or gfg
I took a look at the documentation for NLTK at https://www.nltk.org/howto/wordnet.html. It looks like the culprit is wn.synsets(word)
, in your invocation of get_distractors_wordnet
. An easy typo - wn.synset returns a single synonym set, whereas wn.synsets returns a list of synonym sets. You're getting that error because you're trying to use a member function of a synset on a list of synsets (hence, "'list' object has no attribute 'hypernyms'").
All you have to do is either iterate over the list, or refactor to use wn.synset
instead. Hope this helps!