news 2026/6/1 23:45:03

LLM 时代下的轻量级NER 解法

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
LLM 时代下的轻量级NER 解法

任务定义

金融query 中的实体抽取

ori_querycompaniesinstitutionsindustriesproducts
众安在线最近海外营收占比多少众安在线
哪些会议纪要提到欧洲央行利率决策欧洲央行
越洋钻探最近营收增长多少越洋钻探
过去六个月被下调评级的港股地产板块公司研报地产板块
中国建筑国际2023年火锅底料销量是多少中国建筑国际火锅底料

而金融 query 实际上有几个非常特殊的优势:

  • 句子短(通常 < 40 chars)
  • 实体密度低
  • 实体类型固定
  • Query 语法高度模板化
  • 中文金融实体具有强 lexical pattern

然后现在基本的NER 方案主要分成三类

维度Sequence Labeling (BERT+BIO)GLiNERUIE (生成式)
架构Encoder + Token ClassifierBidirectional Encoder + Span MatchingSeq2Seq / Generative LLM
输出方式每个token打标签Span + Type 相似度匹配生成结构化文本(JSON等)
实体类型灵活性固定(Closed-set)开放(Zero-shot 强)开放(Zero-shot / Few-shot 最强)
速度最快很快(推荐用于100ms场景)较慢
模型大小中等轻量(small/base 很小)较大(T5-11B 等)
适用任务主要NER(Flat)主要NER(可扩展多任务)通用IE(NER+RE+EE+...)
训练/部署难度中低中高
当前地位经典基线2024-2026 实用零样本NER主流复杂多任务场景主流

Sequence Labeling / Token Classification

Encoder + Token Classifier

工作方式

  • 每一个 token独立预测标签(B-PER、I-ORG、O 等)。
  • 属于token-level classification

特点

  • 需要固定实体类型(closed-set),训练时标签是固定的ID。
  • 速度快、结构简单、工业界早期主流。
  • 零样本/开放实体能力很弱(新实体类型基本无法处理)。
  • 标签本身没有语义(只是ID)。

标签建设

BIO 标注

BIO 的本质是序列标注(sequence labeling), 模型在做每个token 的分类

Begin(实体开始) Inside(实体内部) Outside(非实体)

e.g

query: 众安在线最近海外营收占比多少

entity: 众安在线(company)

标签
B-COMPANY
I-COMPANY
I-COMPANY
线I-COMPANY
O
O
O
O

抽取

BERT→Linear→Softmax

pros&cons

pro

速度非常快

复杂度 O(seq_len)

con

1. 它是逐字决策,不理解“整体实体”

容易出现边界错误

2. bio 脆弱, 中间断一次,整个span 就断裂了

B-COMPANY
I-COMPANY
O
I-COMPANY

3. nested entity 很难

例如:

港股地产板块公司

里面:

港股地产板块(行业)
地产(更细粒度行业)

BIO 很难同时表示。

4. 长实体容易拖尾

例如:

中国建筑国际2023年火锅底料销量

模型可能:

中国建筑国际2023年

全打成 company。

BIOES

在实体抽取过程中,会存在“尾部多带一个字”的问题,这就是边界没训练好,在这种情况下,BIOES 通常比 BIO 更友好。

B = entity begin
I = entity inside
E = entity end
S = single-token entity
O = outside

如果是中文字符级标注,也可以用:

B / M / E / S / O

效果类似。

e.g LabelSemantics(2022)

RoberTA + 对比学习

  • 用一个BERT编码标签描述(如 “person”、“begin person” 等自然语言)。
  • 用另一个BERT编码文本中的span / token
  • 通过相似度匹配(dot product + softmax)决定 token 属于哪个标签。
  • 核心:对比学习标签表示和实体表示。

参考论文: https://aclanthology.org/2022.findings-acl.155/

base 模型: RoberTA

RoBERTa理解为是对 BERT 的一个“强化升级版”, 是训练更狠、更久、更规范的 BERT

  • Encoder-only 模型(只有编码器,没有生成能力)
  • 用来做:理解文本,而不是生成文本

具体改进包括:

  • ❌ 去掉了 BERT 的 NSP(Next Sentence Prediction)任务
  • 📈 用了更大的数据集
  • ⏱️ 训练时间更长
  • 📦 更大的 batch size
  • 🎲 动态 masking(每次 mask 不一样)

这些改动让它在很多任务上都比 BERT 强。

🧩 能干啥?

典型 NLP 任务:

  • 文本分类(情感分析、spam detection)
  • NLI(自然语言推理)
  • 问答(QA)
  • 命名实体识别(NER)

👉 核心能力:理解一句话/一段话的语义

不擅长生成

  • 写文章 ❌
  • 对话 ❌

因为它不像 GPT 那样是 decoder-based。

可以这么想:

  • GPT:会“说话”的人(生成)
  • RoBERTa:擅长“读理解题”的人(理解)

标签空间 & 标签语义

双编码器 (LabelSemanticsNER):

token_encoder:编码输入句子,得到每个子词位置的 token_embeddings。

label_encoder:把每个 BIO 标签编成一段固定中文模板 + 描述的短文本,再编码;取 last_hidden_state[:, 0, :](序列第一个 token,一般是 [CLS])作为该标签的向量 label_representation。

分类方式

不是经典 Linear(hidden → num_labels),而是相似度:

对每个位置:logits = token_emb @ label_rep^T(实现里是 batch 维上的矩阵乘),argmax 得到预测标签 id。

标签向量缓存

评估时 use_label_cache=True,同一次 evaluate 里若已算过 label_representation 会复用,避免每个 batch 重算(reset_label_cache 在 evaluate 开头清空)。

训练

主损失:对 logits 与 labels 做 CrossEntropyLoss(ignore_index=-100),只在首子词等有效位置算。

对比损失(仅当 contrastive_weight > 0,且前向 return_representations=True):

在有效监督位上:labels != IGNORE_INDEX 且 english_mask 为真(即单字母英文 token 位置——设计上是让对比学习作用在你关心的英文场景子集)。

其中 实体类型为 contrastive_label(默认 C) 的 token 作为 anchor。

候选集 = 上述有效 token 的 embedding + 所有 label 的 representation;L2 归一化后算相似度 / temperature 得到 logits;去掉自身;正样本是「候选里类型为 C 的」。

形式是 log-sum-exp 的对比目标(与 supervised contrastive / InfoNCE 同类):拉近 anchor 与同类型(含对应标签向量),推远其他。

总损失:loss = ce_loss + contrastive_weight * contrastive

Generalist NER

https://github.com/fastino-ai/GLiNER2

核心定位轻量级通用NER模型(Generalist & Lightweight)。

Bidirectional Encoder + Span Matching

工作方式

  • 使用双向Transformer Encoder(BERT-like)。
  • 实体类型名称(如 "person"、"organization")和文本一起输入模型。
  • 通过span representation(跨度表示)+entity type embedding计算相似度(dot product + sigmoid),直接匹配哪些span属于哪个类型。
  • 并行提取所有实体(非自回归)。

特点

  • Zero-shot / Open-set能力强:不需要为新实体类型重新训练,直接给实体类型列表就能抽。
  • 仍然是encoder-only非生成式,所以速度快(非常适合你之前说的100ms需求)。
  • 比经典Sequence Labeling更灵活,但比LLM轻量得多。
  • 主要专注NER(虽然后续有GLiNER2支持多任务IE)。

e.g GLiNER(2024)

  • 实体类型名称(如 “person”、“organization”)编码成 embedding。
  • 把文本中的候选 span(连续的 token 组合)编码成 span representation。
  • 通过dot product + sigmoid计算每个 span 和每个实体类型的匹配分数。
  • 核心:span-entity type matching,本质也是对比/相似度匹配。

感觉这个工作和 LabelSematics 有点异曲同工之妙,都是基于语义匹配的 NER。GLiNER 可以看作是 Label Semantics 思路的进化版 + 工程优化版,在 zero-shot 能力和实用性上走得更远。

对比学习这块大差不差,我们看看encoder 这边的设计

Encoder 设计

Label Semantics encoder
  • 架构类型双编码器(Two separate BERT encoders),也叫Bi-encoder(但和后来GLiNER的bi-encoder不太一样)。
  • 具体结构
    • Encoder 1(Document / Text Encoder):一个标准的BERT(或类似),负责编码输入文本。它输出每个token的表示(hidden states)。
    • Encoder 2(Label Encoder)另一个独立的BERT,专门负责编码标签的自然语言描述
      • 例如:把 “PER” 转成 “person”、“begin person”、“inside person” 等自然语言句子。
      • 取每个标签描述的[CLS]token 作为该标签的最终表示。
  • 特点
    • 两个编码器完全独立,互不共享参数。
    • 在推理时,标签表示可以预先计算并缓存(lookup table)。
    • 后续通过token表示 vs 标签表示的相似度(dot product + softmax)来做匹配。

优势:标签语义利用得比较充分,适合 few-shot 场景。

劣势:两个独立BERT,参数量接近翻倍,计算效率相对较低。

GLiNER encoder
uniencoder
  • 架构类型单共享编码器(Shared Bidirectional Encoder),也叫Uni-encoderJoint Encoder
  • 具体结构
    • 只有一个 bidirectional Transformer Encoder(通常是 DeBERTa-v3 或 BERT-like)。
    • 输入构造:把文本所有实体类型名称一起拼接成一个序列输入模型(例如:文本 + [SEP] + entity types list)。
    • 这个同一个编码器同时负责:
      • 生成文本中每个 token / span 的表示。
      • 生成实体类型(label)的表示。
    • 后续通过span representation(对连续 token 做 pooling 或特殊处理得到候选实体跨度表示)和entity type embedding计算相似度(dot product + sigmoid)。

特点

  • 参数高效:只有一个编码器,模型整体更轻量。
  • 交互更充分:文本和标签在同一个编码器中一起处理,能捕捉更直接的上下文交互。
  • 推理时所有东西一起算,没有完全独立的 label encoder。
  • 每条query进来,模型都要重新编码一次所有实体类型
  • 当实体类型数量增多(比如50+,甚至几百个)时,输入序列变长,计算量显著增加(尤其是attention计算是平方级的)。
  • 结果:实体类型越多,速度下降越明显(论文中提到100+个标签时性能严重退化)。
bi-encoder(解耦版)

新工作又给它把文本和标签解耦, 效率反而更高了

为什么解耦后效率更高?

把重复计算的部分彻底隔离并缓存

  • 两个独立编码器
    • Text Encoder:只编码输入文本(query)。用 ModernBERT / Ettin系列(专门优化过的长上下文encoder),负责处理query和生成span表示。
    • Label Encoder:只编码实体类型名称(label descriptions)。用预训练的Sentence Transformer(如 BGE、MiniLM、all-MiniLM等),这些模型天生就擅长编码短文本的语义,已经在海量数据上做过句子级对比学习。
    • 两者通过训练时的对比损失(contrastive loss)强制对齐到同一个语义空间,而不是靠同一个模型来“天然相似”。

  • 关键优化实体类型(Label)表示可以提前预计算并缓存
    • 如果你的实体类型列表是固定的(或很少变化),Label embeddings 可以只算一次,存成向量库。
    • 每次推理时,只需要跑Text Encoder,然后直接做向量点积匹配(非常快)。

Q: 为啥非要双编码器,不能同一个编码器编码label 之后存起来,另外一个编码query, 这样在语义空间上还更相似呢

  • 文本和标签的特性差异很大

    • Label(实体类型):通常是非常短的文本(1-5个词,比如“person”、“上市子公司”、“发货地址”)。
    • Query/Text:是完整句子,有丰富上下文,需要捕捉span(跨度)的语义。

    如果强行用同一个模型同时处理这两种完全不同长度的输入,模型容易顾此失彼(trade-off),导致整体表示质量下降。

  • 干扰问题

    • 同一个编码器在训练时,注意力机制会同时看到长文本和短标签,容易让模型对短标签的编码不够“专业”。
    • 实际实验显示,共享权重在大规模实体类型(几百上千个)时表现变差。

即使你用同一个模型编码label存起来,语义空间的“相似性”也不是天然最好的。通过专门模型 + 针对性对比训练,反而能把两种不同性质的文本更好地对齐到同一个向量空间里。

凭什么Gliner 泛化性更好?

  • 从“固定分类”变成“开放匹配”(Matching vs Classification)
    • 传统 BERT + BIO:标签是固定 ID(closed-set),模型学的是“这个 token 属于第几个类别”。遇到训练时没见过的实体类型,几乎完全无法处理(需要重新训练分类头)。
    • GLiNER:把 NER 变成span(文本跨度)与实体类型描述(自然语言)之间的相似度匹配。 实体类型不再是 ID,而是“person”、“上市子公司”、“发货地址”等文本描述,模型在共享的语义空间中计算匹配分数。 → 这让它天然支持open-set / zero-shot:只要给新标签的文字描述,就能尝试识别,即使训练时完全没见过。
  • 标签语义被充分利用GLiNER(尤其是 bi-encoder 版本)用专门的 Label Encoder(Sentence Transformer 类)编码标签描述,Text Encoder 编码文本 span。两者通过对比学习(contrastive loss)对齐到同一个向量空间。 这让模型对未见实体类型的理解能力远强于传统模型(传统模型标签语义几乎为0)。
  • 训练数据和目标的差异
    • GLiNER 在训练时用了Pile-NER等大规模、多样化的数据集,覆盖了海量不同实体类型。
    • 目标是“通用匹配”,而不是“在固定几个类别上分类”,所以模型被迫学到更 robust 的表示。
    • 实验结果显示:即使是 small 版本(几十M参数),在out-of-domain(跨领域)zero-shot 测试上,也能超过 ChatGPT、InstructUIE 等大模型。
  • Span-level 而非纯 Token-level它直接对可能的实体跨度(span)做表示 + 匹配,而不是逐 token 打 BIO 标签,更容易捕捉完整实体,尤其在边界模糊或复杂场景下泛化更好。

pros & cons

pro:

  • 在多个 zero-shot 跨领域基准(如 CrossNER)上,GLiNER bi-encoder 大版本达到了61.5% Micro-F1,是当时 SOTA 水平。
  • 即使小模型,也经常在零样本设置下打败参数量大几十倍的 LLM。
  • 在生物医学、法律、多语言等垂直/低资源场景,泛化优势特别明显,因为它不需要为每个新领域重新收集大量标注数据。

con:

在特定领域有大量高质量标注数据时,传统 fine-tuned BERT-CRF 可能在精度上还略胜(因为它“死记硬背”得更准)。

长尾复杂实体、上下文极强的消歧上,仍然可能需要 LLM 辅助。

UIE (Universal Information Extraction

Seq2Seq / Generative LLM

论文 Unified Structure Generation for Universal Information Extraction

它不是传统 BIO NER,而是一种更像“给模型一个抽取指令/schema,让它按这个 schema 从文本里找 span”的方案。

工作方式

  • 生成式(Generative):基于T5、Flan-T5等seq2seq模型。
  • 自然语言prompt + schema(模式),让模型生成结构化输出(JSON、线性化结构、SEL等)。
  • 一个模型统一处理 NER、关系抽取(RE)、事件抽取(EE)、情感分析等。

特点

  • 最灵活:支持复杂结构化输出、层次化信息、多任务。
  • Zero-shot / Few-shot能力很强。
  • 缺点:自回归生成,速度慢(尤其是长输出时),模型通常较大。
  • 更适合复杂IE场景,而不只是简单实体提取。
输入文本: 众安在线最近海外营收占比多少 抽取 schema: 公司、机构、行业、产品 模型输出: 公司:众安在线

普通 NER 是固定标签训练:

众 B-company 安 I-company 在 I-company 线 I-company

UIE 更像是问模型:

请从这句话中抽取“公司” 文本:众安在线最近海外营收占比多少

然后模型预测 span:

众安在线

InstructUIE

基于LLM的指令微调版本。

后续很多LLM-based工作都沿这个路线(schema prompt + 生成结构化输出)。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/1 23:42:40

【全面解析】框架总览

Ch01:从 YAML 到 DetectionModel.forward 目标:看完这一章,你能从一份 yolo26.yaml 文件出发,完整追踪到 DetectionModel 的 forward 出口,并明确“哪些东西 YOLOv8/v9/v10/v11/v12/v26 共享,哪些不同”。 1.1 仓库的三层结构 Ultralytics 仓库可以先看成三层:配置层、…

作者头像 李华
网站建设 2026/6/1 23:45:26

Jasminum插件深度解析:Zotero中文文献管理的创新实践

Jasminum插件深度解析&#xff1a;Zotero中文文献管理的创新实践 【免费下载链接】jasminum A Zotero add-on to retrive CNKI meta data. 一个简单的Zotero 插件&#xff0c;用于识别中文元数据 项目地址: https://gitcode.com/gh_mirrors/ja/jasminum 在学术研究领域&…

作者头像 李华
网站建设 2026/6/1 23:47:29

免费去水印的软件免费下载|AI去水印工具实测推荐

做自媒体、日常保存短视频和高清图片&#xff0c;最头疼的问题就是素材自带水印&#xff0c;遮挡画面、影响观感&#xff0c;想要干净无水印的素材&#xff0c;大多付费工具价格昂贵&#xff0c;小众软件套路繁多。2026年我实测全网数十款工具&#xff0c;专门整理了免费去水印…

作者头像 李华
网站建设 2026/6/1 23:47:34

终极指南:Wand-Enhancer如何免费解锁WeMod专业版全部功能

终极指南&#xff1a;Wand-Enhancer如何免费解锁WeMod专业版全部功能 【免费下载链接】Wand-Enhancer Advanced UX and interoperability extension for Wand (WeMod) app 项目地址: https://gitcode.com/gh_mirrors/we/Wand-Enhancer 还在为WeMod专业版的订阅费用烦恼吗…

作者头像 李华
网站建设 2026/6/2 0:52:57

从Arduino IDE到VSCode:为你的ESP32项目升级更高效的现代开发工作流

从Arduino IDE到VSCode&#xff1a;为你的ESP32项目升级更高效的现代开发工作流 如果你已经用Arduino IDE完成了几个ESP32项目&#xff0c;可能会开始感受到它的局限性——简陋的代码补全、笨重的项目管理方式、缺乏版本控制支持。是时候拥抱现代开发工具链了。本文将带你从传…

作者头像 李华