LLM 时代下的轻量级NER 解法

张开发
2026/6/7 18:11:21 15 分钟阅读

分享文章

LLM 时代下的轻量级NER 解法
任务定义金融query 中的实体抽取ori_querycompaniesinstitutionsindustriesproducts众安在线最近海外营收占比多少众安在线哪些会议纪要提到欧洲央行利率决策欧洲央行越洋钻探最近营收增长多少越洋钻探过去六个月被下调评级的港股地产板块公司研报地产板块中国建筑国际2023年火锅底料销量是多少中国建筑国际火锅底料而金融 query 实际上有几个非常特殊的优势句子短通常 40 chars实体密度低实体类型固定Query 语法高度模板化中文金融实体具有强 lexical pattern然后现在基本的NER 方案主要分成三类维度Sequence Labeling (BERTBIO)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 等适用任务主要NERFlat主要NER可扩展多任务通用IENERREEE...训练/部署难度低中低中高当前地位经典基线2024-2026 实用零样本NER主流复杂多任务场景主流Sequence Labeling / Token ClassificationEncoder Token Classifier工作方式对每一个 token独立预测标签B-PER、I-ORG、O 等。属于token-level classification。特点需要固定实体类型closed-set训练时标签是固定的ID。速度快、结构简单、工业界早期主流。零样本/开放实体能力很弱新实体类型基本无法处理。标签本身没有语义只是ID。标签建设BIO 标注BIO 的本质是序列标注sequence labeling), 模型在做每个token 的分类Begin实体开始 Inside实体内部 Outside非实体e.gquery 众安在线最近海外营收占比多少entity: 众安在线company字标签众B-COMPANY安I-COMPANY在I-COMPANY线I-COMPANY最O近O海O外O抽取BERT→Linear→Softmaxprosconspro速度非常快复杂度 O(seq_len)con1. 它是逐字决策不理解“整体实体”容易出现边界错误2. bio 脆弱 中间断一次整个span 就断裂了B-COMPANYI-COMPANYOI-COMPANY3. nested entity 很难例如港股地产板块公司里面港股地产板块行业地产更细粒度行业BIO 很难同时表示。4. 长实体容易拖尾例如中国建筑国际2023年火锅底料销量模型可能中国建筑国际2023年全打成 company。BIOES在实体抽取过程中会存在“尾部多带一个字”的问题这就是边界没训练好在这种情况下BIOES 通常比 BIO 更友好。B entity beginI entity insideE entity endS single-token entityO 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 模型: RoberTARoBERTa理解为是对 BERT 的一个“强化升级版”, 是训练更狠、更久、更规范的 BERTEncoder-only 模型只有编码器没有生成能力用来做理解文本而不是生成文本具体改进包括❌ 去掉了 BERT 的 NSPNext Sentence Prediction任务 用了更大的数据集⏱️ 训练时间更长 更大的 batch size 动态 masking每次 mask 不一样这些改动让它在很多任务上都比 BERT 强。 能干啥典型 NLP 任务文本分类情感分析、spam detectionNLI自然语言推理问答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_cacheTrue同一次 evaluate 里若已算过 label_representation 会复用避免每个 batch 重算reset_label_cache 在 evaluate 开头清空。训练主损失对 logits 与 labels 做 CrossEntropyLoss(ignore_index-100)只在首子词等有效位置算。对比损失仅当 contrastive_weight 0且前向 return_representationsTrue在有效监督位上labels ! IGNORE_INDEX 且 english_mask 为真即单字母英文 token 位置——设计上是让对比学习作用在你关心的英文场景子集。其中 实体类型为 contrastive_label默认 C 的 token 作为 anchor。候选集 上述有效 token 的 embedding 所有 label 的 representationL2 归一化后算相似度 / temperature 得到 logits去掉自身正样本是「候选里类型为 C 的」。形式是 log-sum-exp 的对比目标与 supervised contrastive / InfoNCE 同类拉近 anchor 与同类型含对应标签向量推远其他。总损失loss ce_loss contrastive_weight * contrastiveGeneralist NERhttps://github.com/fastino-ai/GLiNER2核心定位轻量级通用NER模型Generalist Lightweight。Bidirectional Encoder Span Matching工作方式使用双向Transformer EncoderBERT-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 1Document / Text Encoder一个标准的BERT或类似负责编码输入文本。它输出每个token的表示hidden states。Encoder 2Label Encoder另一个独立的BERT专门负责编码标签的自然语言描述。例如把 “PER” 转成 “person”、“begin person”、“inside person” 等自然语言句子。取每个标签描述的[CLS]token 作为该标签的最终表示。特点两个编码器完全独立互不共享参数。在推理时标签表示可以预先计算并缓存lookup table。后续通过token表示 vs 标签表示的相似度dot product softmax来做匹配。优势标签语义利用得比较充分适合 few-shot 场景。劣势两个独立BERT参数量接近翻倍计算效率相对较低。GLiNER encoderuniencoder架构类型单共享编码器Shared Bidirectional Encoder也叫Uni-encoder或Joint 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标签是固定 IDclosed-set模型学的是“这个 token 属于第几个类别”。遇到训练时没见过的实体类型几乎完全无法处理需要重新训练分类头。GLiNER把 NER 变成span文本跨度与实体类型描述自然语言之间的相似度匹配。 实体类型不再是 ID而是“person”、“上市子公司”、“发货地址”等文本描述模型在共享的语义空间中计算匹配分数。 → 这让它天然支持open-set / zero-shot只要给新标签的文字描述就能尝试识别即使训练时完全没见过。标签语义被充分利用GLiNER尤其是 bi-encoder 版本用专门的 Label EncoderSentence 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 conspro在多个 zero-shot 跨领域基准如 CrossNER上GLiNER bi-encoder 大版本达到了61.5% Micro-F1是当时 SOTA 水平。即使小模型也经常在零样本设置下打败参数量大几十倍的 LLM。在生物医学、法律、多语言等垂直/低资源场景泛化优势特别明显因为它不需要为每个新领域重新收集大量标注数据。con在特定领域有大量高质量标注数据时传统 fine-tuned BERT-CRF 可能在精度上还略胜因为它“死记硬背”得更准。长尾复杂实体、上下文极强的消歧上仍然可能需要 LLM 辅助。UIE Universal Information ExtractionSeq2Seq / 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-companyUIE 更像是问模型请从这句话中抽取“公司” 文本众安在线最近海外营收占比多少然后模型预测 span众安在线InstructUIE基于LLM的指令微调版本。后续很多LLM-based工作都沿这个路线schema prompt 生成结构化输出。

更多文章