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

spaCy 3训练自定义NER模型多轮迭代损失值始终为空问题求助

spaCy 3自定义NER训练损失为空的问题原因及修复方案

核心错误原因

  • 你创建了ner管道后,没有将其添加到nlp的处理流水线中,nlp.update执行时没有可训练的组件,因此损失字典始终为空。
  • 你提供的训练数据中实体偏移量存在越界问题:第一条样本的总字符长度远小于你标注的89、98等起始位置,无效标注会被spaCy自动过滤,即便管道添加正确也会影响训练效果。
  • 代码中缺少import random语句,执行random.shuffle时会直接报错,不属于损失为空的直接原因,但需要补充。

修复后的完整代码

import spacy
import random
from spacy.training.example import Example
from spacy.util import minibatch, compounding

# 注意:请先修正你的TRAIN_DATA中实体偏移量越界的问题
TRAIN_DATA = [
    ('text data text data text data text data text data text data text data text data.',
     {'entities': [(7, 19, 'PERSON')]}), # 这里删除了越界的标注示例,你需要自行校准所有偏移量
    ('"text data text data text data text data text data text data text data text data text data text data text data text data.',
     {'entities': [(119, 137, 'PERSON')]}),
]

n_iter = 8
nlp = spacy.blank('en')
# 修正点1:创建ner管道后直接添加到流水线
ner = nlp.add_pipe('ner')

for _, annotations in TRAIN_DATA:
    for _s, _e, label in annotations.get('entities', []) :
        print('Adding label - "', label, '"')
        ner.add_label(label)

other_pipes = [pipe for pipe in nlp.pipe_names if pipe != 'ner']
with nlp.disable_pipes(*other_pipes): 
    optimizer = nlp.begin_training()
    for itn in range(n_iter):
        random.shuffle(TRAIN_DATA)
        losses = {}
        for batch in spacy.util.minibatch(TRAIN_DATA, size=compounding(4.0, 32.0, 1.001)):
            for text, annotations in batch:
                doc = nlp.make_doc(text)
                example = Example.from_dict(doc, annotations)
                nlp.update([example], drop=0.35,losses=losses, sgd=optimizer)
            print('losses -', losses)

额外校准建议

你可以用如下方法验证标注偏移量是否正确:

text = "你的训练样本文本"
for s,e,label in entities:
    print(text[s:e]) # 打印结果必须是你想要标注的实体内容,为空或者内容不对就是偏移量错误

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 19:06:03