You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

FastAPI调用WordNet生成干扰项时遇AttributeError问题求助

问题原因分析

报错AttributeError: 'list' object has no attribute 'hypernyms'的核心原因是:wn.synsets(word)返回的是同义词集列表(包含多个Synset对象的list),但你在get_distractors_wordnet函数里直接把这个列表当成单个Synset对象调用hypernyms()方法,自然会触发属性不存在的错误。

解决方案

需要修改两个核心部分:

  1. 调用get_distractors_wordnet时,从wn.synsets(word)的结果中取出有效的Synset对象(比如第一个匹配项),同时处理找不到同义词集的空列表情况。
  2. 完善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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 17:48:11