创建Spacy Pipeline自定义组件时遭遇RecursionError问题求助
解决spaCy管道自定义组件的RecursionError问题
嘿,我一眼就瞅出问题根源了——你的自定义lemmatizer组件里居然又调用了nlp(doc.text),这直接搞出了无限递归循环!
为啥会触发递归错误?
当你执行nlp("Hi, I'm new here.")时,spaCy会按顺序跑管道里的所有组件。而你的lemmatizer函数里又调用了nlp(doc.text),这等于又一次触发了整个管道的处理流程——包括再次调用你的lemmatizer组件。就这么循环来循环去,直到超出Python的递归深度上限,自然就抛出RecursionError了。
另外还有个隐藏问题:spaCy的管道组件必须返回Doc对象,而你的函数返回的是字符串,就算没递归,后面也会触发ValueError: [E005]错误。
修正后的正确写法
首先要明确:spaCy的管道组件接收的doc参数已经是经过前面步骤处理后的Doc对象,你直接对这个Doc里的token操作就行,完全没必要再调用nlp重新解析一遍。另外,如果你需要lemmatization功能,空白模型spacy.blank("fr")是没有内置lemmatizer的,得加载带lemmatizer的预训练模型,比如fr_core_news_sm。
import spacy # 加载带lemmatizer的法语预训练模型 nlp = spacy.load("fr_core_news_sm") def custom_lemmatizer(doc): # 这里可以添加你的自定义lemmat逻辑,比如修改某些token的lemma_ for token in doc: # 举个例子:把特定词的lemma改成自定义值 if token.text.lower() == "nouveau": token.lemma_ = "nouveau" # 这里只是演示,实际spaCy已经会处理 # 管道组件必须返回Doc对象 return doc # 把自定义组件添加到管道,指定在内置lemmatizer之后执行 nlp.add_pipe(custom_lemmatizer, after="lemmatizer") # 测试处理 doc = nlp("Bonjour, je suis nouveau ici.") # 输出lemmatized文本 print(" ".join([token.lemma_ for token in doc]))
额外提醒
- 如果你的需求只是把文本转换成lemmatized字符串,其实没必要做成管道组件,直接写个普通函数就行:
def get_lemmatized_text(text): doc = nlp(text) return " ".join([token.lemma_ for token in doc]) print(get_lemmatized_text("Bonjour, je suis nouveau ici.")) - 管道组件更适合需要在spaCy的处理流程中插入逻辑(比如修改Doc属性、添加自定义扩展、过滤token等)的场景,必须遵守「接收Doc,返回Doc」的规则。
内容的提问来源于stack exchange,提问作者Saad Cherkaoui Ikbal
相关产品推荐
相关产品推荐

