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

创建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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.28 20:42:40