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

是否可导出无vocab的spaCy NER模型并实时注入tokens/vectors使用?

问题背景

我的问题起源和标题关联度不高,但标题本质上很好地概括了我当前遇到的卡点。
我需要将spaCy的NER模型集成到复杂的分布式NLP pipeline中,目前的实现思路如下:

  1. 基于en_core_web_lg模型训练新的NER模型,使其在NER任务中可识别自定义实体
  2. 保存模型时跳过vocab(词汇表),以节省磁盘空间和内存占用
  3. 最终加载模型执行推理时,使用pipeline中提前预计算好的tokens和vectors,而非通过模型vocab(标准方式)重新计算。

我选择不保存vocab的原因是,在我的分布式pipeline中,第一步就会完成文本的分词/向量化处理,后续所有任务都可以直接使用这一输出。

澄清:使用保存vocab的标准方式时,我可以正常训练自定义NER模型,保存/加载及推理均无明显问题,且准确率很高。

后续查阅spaCy官方文档发现,确实可以不携带vocab保存模型,还可以基于token列表和自定义vocab(我这里用的是空vocab)构建Doc对象。同时我也可以通过pipeline提前计算好的向量来设置文档向量。
但我发现保存的模型中ner/cfg文件内存在对NER模型训练所用向量的引用(en_core_web_lg.vectors):

{
   "disable":[
     "tagger",
     "parser"
   ],
   "beam_width":1,
   "beam_density":0.0,
   "beam_update_prob":1.0,
   "cnn_maxout_pieces":3,
   "nr_feature_tokens":6,
   "deprecation_fixes":{
      "vectors_name":"en_core_web_lg.vectors"
   },
   "nr_class":86,
   "hidden_depth":1,
   "token_vector_width":96,
   "hidden_width":64,
   "maxout_pieces":2,
   "pretrained_vectors":"en_core_web_lg.vectors",
   "bilstm_depth":0,
   "self_attn_depth":0,
   "conv_depth":4,
   "conv_window":1,
   "embed_size":2000
 }

当我尝试在内存中未加载对应向量(即未加载对应vocab)的情况下加载模型时,上述引用就会导致报错。
如果我删除cfg文件中的这些引用,模型可以正常加载,也能使用我的向量执行推理,但得到的预测结果和携带原始vocab的模型输出差异很大,且存在较多错误。

核心问题

是否可以保存携带空vocab的NER模型,之后基于pipeline预计算的tokens和vectors构建SpaCy Doc对象完成推理?

当前使用版本为spaCy 2.3.7,相关代码片段如下:

1. 训练代码

nlp = spacy.load("en_core_web_lg", disable=['tagger', 'parser'])

ner = nlp.get_pipe('ner')
ner.add_label("FOO_ENTITY")
ner.add_label("BAR_ENTITY")
ner.add_label("COOL_ENTITY")

# Start the training
optimizer = nlp.begin_training()

# Loop for EPOCHS iterations
losses_hist = []
for itn in range(30):
    # Shuffle the training data
    random.shuffle(Xy_train)
    losses = {}

    # Batch the examples and iterate over them
    for batch in spacy.util.minibatch(Xy_train, size=32):
        texts = [text for text, entities, _ in batch]
        golds = [{'entities': entities} for text, entities, _ in batch]

        # Update the model
        nlp.update(docs=texts, golds=golds, losses=losses)

    print(losses)
    losses_hist.append(losses)

2.a 标准推理代码

# I already have the text split in tokens
doc = Doc(nlp.vocab, words=tokens)  # Create doc from tokens
ner = nlp.get_pipe("ner")
doc = ner(doc)  # Call NER step for doc

for ent in doc.ents:
    print(f"value: {ent.text}, start: {ent.start_char}, end: {ent.end_char}, entity: {ent.label_}")

2.b 外部向量推理代码

# I already have the text split in tokens and their vectors
vectors = Vectors(data=embeddings, keys=tokens)
nlp.vocab.vectors = vectors
doc = Doc(nlp.vocab, words=tokens)

ner = nlp.get_pipe("ner")
doc = ner(doc)  # Call NER step for doc

for ent in doc.ents:
    print(f"value: {ent.text}, start: {ent.start_char}, end: {ent.end_char}, entity: {ent.label_}")

3. 模型保存/加载代码

# Save model
nlp.to_disk(str(dir_))

# Load model
nlp = spacy.load(str(dir_), exclude=['vocab']) 
解决方案

可以实现该需求,你当前效果异常的核心原因是操作逻辑不符合spaCy 2.x的底层特征依赖规则,按以下步骤调整即可:

  1. 不要删除ner/cfg里的pretrained_vectors和vectors_name配置。spaCy 2.x的NER模型训练时绑定了en_core_web_lg的向量分布,删除配置后模型会跳过预训练向量的特征注入逻辑,缺失核心输入特征自然效果大幅下降。
  2. 加载模型时手动补全向量名配置,避免报错。你使用空vocab加载模型时,手动给vocab的向量设置和cfg匹配的名称即可绕过向量校验,不需要加载完整的原始vocab:
# 加载排除vocab的模型
nlp = spacy.load(str(dir_), exclude=['vocab'])
# 手动设置向量名匹配cfg配置,消除加载报错
nlp.vocab.vectors.name = 'en_core_web_lg.vectors'
  1. 确保预计算的向量和训练用的en_core_web_lg向量维度、分布完全一致,如果你分布式pipeline用的就是en_core_web_lg的向量输出,直接注入即可。
  2. 构建Doc对象时补充必要属性:除了words参数外,还要传入spaces参数(每个token后是否带空格),否则实体偏移量计算会出错;如果能提前拿到词的大小写、数字标识等lexeme属性也一并传入,补全NER所需的特征输入。

调整后的推理代码示例:

nlp = spacy.load(str(dir_), exclude=['vocab'])
nlp.vocab.vectors.name = 'en_core_web_lg.vectors'
# 注入预计算向量,确保embeddings是en_core_web_lg输出的300维向量
vectors = Vectors(data=embeddings, keys=tokens)
nlp.vocab.vectors = vectors
# 传入spaces参数,和你分词时的空格情况保持一致
doc = Doc(nlp.vocab, words=tokens, spaces=spaces_list)

ner = nlp.get_pipe("ner")
doc = ner(doc)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 05:45:05