FastAPI调用WordNet生成干扰项时遇AttributeError问题求助
问题原因分析
报错AttributeError: 'list' object has no attribute 'hypernyms'的核心原因是:wn.synsets(word)返回的是同义词集列表(包含多个Synset对象的list),但你在get_distractors_wordnet函数里直接把这个列表当成单个Synset对象调用hypernyms()方法,自然会触发属性不存在的错误。
解决方案
需要修改两个核心部分:
- 调用
get_distractors_wordnet时,从wn.synsets(word)的结果中取出有效的Synset对象(比如第一个匹配项),同时处理找不到同义词集的空列表情况。 - 完善
get_distractors_wordnet函数的参数校验,避免传入非Synset类型的参数。
修改后的完整代码
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 = [] if not syn: return distractors word = word.lower() orig_word = word if len(word.split()) > 0: word = word.replace(" ", "_") # 处理传入的单个Synset对象 hypernym = syn.hypernyms() if len(hypernym) == 0: return distractors for item in hypernym[0].hyponyms(): name = item.lemmas()[0].name() 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: # 获取同义词集列表,取第一个有效Synset,空列表则传None syn_list = wn.synsets(word) target_syn = syn_list[0] if syn_list else None distractors.append(get_distractors_wordnet(target_syn, word)) # 直接用distractors作为distractors_sublist,简化逻辑 return QuestionResponse(question=question_array, answer=answer, distractors_sublist=distractors)
关键修改点
- 调用
get_distractors_wordnet时,先判断wn.synsets(word)是否为空,不为空则取第一个Synset对象传入,为空则传None - 在
get_distractors_wordnet函数开头增加空值判断,避免无效调用 - 简化了
distractors_sublist的生成逻辑,直接使用distractors即可,无需额外循环
内容的提问来源于stack exchange,提问作者blockhead
相关产品推荐
相关产品推荐

