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

如何解决合并不同spacy.Language结果时的Vocab不匹配错误?

解决spaCy中合并不同Language实例Doc的Vocab不匹配问题

问题场景与报错

在处理邮件等场景时,不同字段需要用不同的实体识别规则(比如地址栏数字识别为邮编,页脚数字识别为电话),因此会创建多个spacy.Language实例分别处理,之后合并处理后的Doc对象时,触发如下错误:

ValueError('[E999] Unable to merge the Doc objects because they do not all share the same Vocab.')

示例代码:

import spacy
from spacy.tokens import Doc

nlp_1 = spacy.blank("en")
ruler = nlp_1.add_pipe("entity_ruler")
ruler.add_patterns([{"label": "ORG", "pattern": "Apple"}, ])
doc_1 = nlp_1('Apple')

nlp_2 = spacy.blank("en")
ruler = nlp_2.add_pipe("entity_ruler")
ruler.add_patterns([{"label": "PER", "pattern": "Peter"}, ])
doc_2 = nlp_2('Peter')

print(Doc.from_docs([doc_1, doc_2]))
# ValueError: [E999] Unable to merge the Doc objects because they do not all share the same `Vocab`.

解决方法

核心是让多个spacy.Language实例共享同一个Vocab对象,以下是两种常用实现方式:

1. 复用第一个nlp实例的Vocab创建第二个实例

直接将第一个nlp对象的vocab作为第二个nlp实例的初始化参数:

import spacy
from spacy.tokens import Doc

# 创建第一个nlp实例,自带默认Vocab
nlp_1 = spacy.blank("en")
ruler = nlp_1.add_pipe("entity_ruler")
ruler.add_patterns([{"label": "ORG", "pattern": "Apple"}, ])
doc_1 = nlp_1('Apple')

# 复用nlp_1的Vocab创建nlp_2
nlp_2 = spacy.blank("en", vocab=nlp_1.vocab)
ruler = nlp_2.add_pipe("entity_ruler")
ruler.add_patterns([{"label": "PER", "pattern": "Peter"}, ])
doc_2 = nlp_2('Peter')

# 正常合并Doc
merged_doc = Doc.from_docs([doc_1, doc_2])
print(merged_doc.text)  # 输出: ApplePeter
print([(ent.text, ent.label_) for ent in merged_doc.ents])  # 输出: [('Apple', 'ORG'), ('Peter', 'PER')]

2. 先创建独立Vocab,再传递给所有nlp实例

如果需要提前配置Vocab(比如自定义词向量映射),可以先单独创建Vocab对象,再传给每个nlp实例:

import spacy
from spacy.tokens import Doc, Vocab

# 创建共享的Vocab对象
shared_vocab = Vocab()

# 两个nlp实例均使用该共享Vocab
nlp_1 = spacy.blank("en", vocab=shared_vocab)
ruler = nlp_1.add_pipe("entity_ruler")
ruler.add_patterns([{"label": "ORG", "pattern": "Apple"}, ])
doc_1 = nlp_1('Apple')

nlp_2 = spacy.blank("en", vocab=shared_vocab)
ruler = nlp_2.add_pipe("entity_ruler")
ruler.add_patterns([{"label": "PER", "pattern": "Peter"}, ])
doc_2 = nlp_2('Peter')

# 合并成功
merged_doc = Doc.from_docs([doc_1, doc_2])
print(merged_doc.text)
print([(ent.text, ent.label_) for ent in merged_doc.ents])

原理说明

spaCy的Vocab是核心词汇管理对象,负责维护字符串与哈希值的映射、词向量等数据。只有当Doc对象共享同一个Vocab时,内部的哈希映射规则才一致,才能被安全合并。不同nlp实例默认会创建独立的Vocab,这就是触发报错的根本原因。

内容的提问来源于stack exchange,提问作者Andreas

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 20:39:27