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

BERT NER如何获取原词级实体而非wordpiece子词标注结果

低复杂度实现方案

方案1:直接用pipeline内置能力(零额外代码,推荐)

不用自己写子词对齐、实体合并逻辑,transformers的NER pipeline原生支持偏移量计算和子词聚合,初始化时加2个参数即可:

nlp_ner = pipeline(
    "ner",
    model=mode,
    tokenizer=tokenize,
    offset_mapping=True, # 开启原文本字符偏移计算
    aggregation_strategy="simple" # 自动合并wordpiece拆分的同实体子词
)

配置后调用接口返回的结果直接携带原文本字符级的起止索引,拆分的子词会被自动拼接成完整实体,你示例里的conf+##using会直接合并为confusing,返回结构示例:

{
    "entity_group": "LABEL_9",
    "score": 0.82,
    "word": "confusing",
    "start": 121, # 原文本中实体首字符的索引
    "end": 130 # 原文本中实体尾字符后一位的索引,text[start:end]可直接切出完整实体
}

拿到结果后直接过滤你需要的标签(比如LABEL_9),用对应的start/end字段就能完成定位,不管是生成Doccanno标注格式,还是插入HTML高亮标签都可以直接用。

插HTML高亮的注意点:拿到所有待高亮实体后,按start从大到小排序,从原文本末尾往前插入标签,避免插入标签后前面的字符索引错位,示例代码:

target_ents = [e for e in nlp_ner(text) if e["entity_group"] == "LABEL_9"]
target_ents.sort(key=lambda x:x["start"], reverse=True)
render_text = text
for ent in target_ents:
    s, e = ent["start"], ent["end"]
    render_text = render_text[:s] + f'<span class="ner-highlight">{render_text[s:e]}</span>' + render_text[e:]

方案2:手动对齐(需要自定义聚合规则时用)

如果内置聚合策略不符合你的标签规则,自己实现对齐逻辑也只有3步,复杂度极低:

  • 调用tokenizer分词时传入return_offsets_mapping=True,分词器会直接返回每个token(包括子词)对应原文本的起止位置,不需要自己做字符串模糊匹配,不会错位
  • 遍历预测结果,按你的规则合并连续子词:遇到以##开头的子词,就和前一个token拼接,实体start继承前一个token的start,end取当前子词的end,直到遇到不带##的新token为止
  • 合并完成后过滤目标标签,拿到的start/end和方案1的结果完全一致,可以直接使用

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 14:09:26