spaCy自定义NER模型如何排除分词器进行保存与加载?
解决spaCy保存/加载不含Tokenizer的自定义NER模型问题
我明白你遇到的问题了——想保存训练好的NER模型但不带自定义Tokenizer,结果加载后不仅Pipeline为空,还自动用上了spaCy的默认Tokenizer。咱们来一步步解决这个问题:
正确的保存方式
不要直接把nlp.tokenizer设为None,这会破坏spaCy模型的内部结构。正确的做法是创建一个仅包含NER组件的新Language对象,再保存它:
import spacy from spacy.language import Language # 假设trained_nlp是你训练好的、带自定义Tokenizer的完整模型对象 trained_nlp = ... # 你的训练后的nlp实例 # 创建一个空的英文Language对象,默认不带任何组件(包括Tokenizer) ner_only_nlp = Language("en") # 从训练好的模型中复制NER组件到新对象里 ner_only_nlp.add_pipe("ner", source=trained_nlp) # 保存这个仅含NER的模型 ner_only_nlp.to_disk("/tmp/my_ner_only_model")
正确的加载方式
加载的时候,你需要明确处理Tokenizer的问题——要么给加载后的模型指定你的自定义Tokenizer,要么把NER组件整合到已有自定义Tokenizer的nlp对象中:
方式1:加载模型后设置自定义Tokenizer
import spacy from spacy.language import Language # 加载仅含NER的模型 nlp_ner = Language("en").from_disk("/tmp/my_ner_only_model") # 设置你的自定义Tokenizer nlp_ner.tokenizer = your_custom_tokenizer # 替换成你的自定义tokenizer实例 # 现在可以正常使用NER了 doc = nlp_ner("需要处理的文本") print([(ent.text, ent.label_) for ent in doc.ents])
方式2:将NER组件添加到已有自定义Tokenizer的nlp中
如果你已经有一个配置好自定义Tokenizer的nlp对象,直接把NER组件加进去更高效:
import spacy # 创建空nlp并设置自定义Tokenizer nlp = spacy.blank("en") nlp.tokenizer = your_custom_tokenizer # 加载仅含NER的模型,并把组件添加到当前nlp nlp.add_pipe("ner", source=spacy.load("/tmp/my_ner_only_model"))
为什么你的原方法不行?
你之前把nlp.tokenizer = None再保存的操作,会导致spaCy模型的元数据丢失关键信息——spaCy的Language对象依赖Tokenizer作为基础组件,直接设为None会让保存的模型无法正确记录Pipeline结构。而用spacy.blank('en').from_disk加载时,blank对象默认会创建一个默认Tokenizer,同时因为保存的模型元数据异常,导致NER组件没有被正确加载,最终出现Pipeline为空的情况。
内容的提问来源于stack exchange,提问作者Gino
相关产品推荐
相关产品推荐

