ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

GLiNER2.5零样本NER新架构:边界预测替代跨度枚举

GLiNER2.5零样本NER新架构:边界预测替代跨度枚举 最近在做知识库实体抽取时一直在对比不同 NER命名实体识别方案的落地效果。GLiNER 这类零样本模型确实省去了标注数据的成本但早期版本基于“跨度枚举”的做法在高密度文本上推理速度偏慢边界不准的问题也时有发生。刚好看到 Fastino 发布 GLiNER2.5 的消息核心变化是用“边界预测”取代了原来的“跨度枚举”架构。这篇文章就围绕这一架构变更展开详细拆解 GLiNER2.5 的原理、安装配置、代码实战和工程落地注意事项想直接上手的读者也可以照着操作。1. 背景与核心概念1.1 信息抽取与命名实体识别信息抽取Information Extraction, IE是 NLP 领域中非常基础也非常重要的一环。它的目标是从非结构化文本中抽取出结构化信息包括实体、关系、事件等。命名实体识别是其中最基础的任务负责识别文本中的人名、地名、机构名、时间、金额等实体片段并给它们打上类型标签。命名实体识别几乎是所有上层 NLP 应用的地基。知识图谱构建需要实体抽取搜索引擎需要识别查询中的实体对话系统需要理解用户提到的实体舆情系统需要识别公司名、人名、产品名。如果实体识别不准确后续的关系抽取、事件抽取都会受到影响。传统的命名实体识别方法经历了几个发展阶段早期基于规则和词典中期基于统计机器学习如 HMM、CRF再后来基于 BiLSTM-CRF 等深度学习方法。这些方法有一个共同点都需要针对特定领域准备大量标注数据并且在领域迁移时效果会明显下降。1.2 传统 NER 方法的核心痛点在实际项目中传统 NER 方案会面临几个非常现实的困难标注成本高。要训练一个可用的领域 NER 模型通常需要几千到几万条标注数据。标注实体边界和类型本身就是专业性较强的工作成本不低而且不同标注人员之间可能存在不一致。领域迁移难。在金融领域训练好的模型换到医疗、法律、电商等领域效果通常会有明显下降需要重新标注和训练。类别扩展麻烦。业务方随时可能提出新增实体类型比如从人名、地名、机构名扩展到产品名、品牌名、型号名每次扩展类别都需要重新处理数据并训练模型。这些痛点推动了零样本 NER 的发展。所谓零样本就是模型在训练时见过的实体类型与推理时遇到的实体类型可以不同模型具备理解新的实体类型描述的能力。GLiNER 正是这一方向的代表性模型。1.3 GLiNER 是什么GLiNER 的全称是 Generalist Model for Named Entity Recognition using Bidirectional Transformer也就是基于双向 Transformer 的通用命名实体识别模型。它最早由 Urchade Zaratiana 等人提出核心思路是利用预训练语言模型的双向编码能力并行识别文本中的实体与类型。与基于生成式大模型做 NER 的方式不同GLiNER 使用的是编码器架构。生成式方法通常将实体识别建模为序列生成例如让模型输出 JSON 格式的实体列表而 GLiNER 将实体识别建模为 span-level 的匹配与分类问题推理速度更快对实体边界的控制也更精确。GLiNER 的创新点在于它不再要求模型只能在预定义的实体类型集合上工作而是允许在推理时传入任意文本形式的实体类型描述。例如模型训练时只见过人名、地名、机构名但推理时你可以传入药品名称汽车品牌菜品名称等新类别模型仍然可以识别。最新的 GLiNER2.5 在此基础上进一步调整了模型架构用边界预测替代跨度枚举从根本上改变了模型搜索实体的方式。下面展开说明。2. 从跨度枚举到边界预测GLiNER2.5 的架构变化2.1 什么是跨度枚举在早期的 GLiNER 版本中模型识别实体的方式是枚举输入文本中所有可能成为实体的连续片段。假设输入文本长度为 N 个 token那么候选跨度span的数量大约是 N×(N1)/2。举个例子一句话包含 50 个 token候选跨度数量就有 1275 个。这些候选跨度会被逐一送入模型与实体类型进行匹配打分最终筛选出可能性最高的片段作为预测结果。这种设计思路直接、实现也比较直观。在短文本上效果不错模型也确实借助这种方式取得了很好的零样本效果。但随着文本长度增加候选跨度数量呈二次方增长计算开销会明显变大。2.2 跨度枚举的三个瓶颈推理速度慢。这是最直观的问题。候选跨度数量与文本长度的平方成正比文本越长需要打分的跨度就越多推理耗时自然水涨船高。在长文档或高吞吐场景下这种开销往往不可接受。边界精度受限。跨度枚举虽然覆盖了所有可能的边界组合但模型在打分时容易出现边界偏移。例如本应识别为北京科技创新中心这一完整实体模型可能只命中北京科技创新或者把范围扩大成北京科技创新中心有限公司。跨度枚举本质上是在大量候选中做排序对边界的细粒度判断依赖训练数据的覆盖程度。内存开销大。每个候选跨度都需要生成对应的向量表示并与所有实体类型计算匹配度。当序列长度较长且实体类型数量较多时中间表示会占用大量显存。2.3 边界预测的基本思路GLiNER2.5 的思路与跨度枚举完全不同。它不再枚举所有候选片段而是直接预测每个 token 在实体中的角色是实体的开始、中间、结束还是非实体。这种思路本质上更接近经典的序列标注但 GLiNER2.5 是在编码器架构上实现同时保留了零样本类型匹配能力。通俗地理解跨度枚举相当于把每一段都拿出来看看像不像实体边界预测则是一边扫描文本一边判断哪里开始、哪里结束。前者是枚举筛选后者是直接定位。边界预测的核心优势有两个推理复杂度降低。模型只需要对每个 token 做一次分类或边界判断不再需要枚举大量候选跨度推理耗时的增长从平方级降为线性级。长文本场景下的性能提升非常明显。边界表达能力更强。模型可以在训练时学习实体边界的上下文模式比如实体前的介词、实体后的助词、实体内部的结构特征等从而更准确地确定边界位置。当然边界预测也对模型的训练数据和解码策略提出了更高要求这一点在后面的实战部分会详细说明。3. 环境准备与版本说明3.1 运行环境GLiNER2.5 以 Python 生态为主官方推荐使用 PyTorch 作为深度学习框架。本文示例以常见环境为例具体版本需根据项目实际情况调整重点是演示配置思路和代码结构。建议环境如下依赖项建议操作系统Linux 或 macOSPython3.9 及以上PyTorch2.0 及以上CUDA11.7 及以上使用 GPU 推理时transformers4.30 及以上如果只是做 CPU 推理验证不一定需要 CUDA但推理速度会慢不少。生产环境建议使用 GPU 或对长文本做适当截断。3.2 安装依赖如果使用的是 GLiNER 官方库直接通过 pip 安装即可pip install gliner如果需要安装支持 GLiNER2.5 架构的最新版本建议从源码安装这样可以确保拿到最新的代码与权重加载逻辑git clone https://github.com/urchade/GLiNER.git cd GLiNER pip install -e .这里说明一下源码安装的好处是可以直接修改模型代码做调试对研究架构细节很有帮助。如果你的项目只需要调用接口pip 安装就足够了。3.3 验证安装安装完成后可以通过以下命令验证基础依赖是否可用python -c import gliner; import torch; print(GLiNER version:, gliner.__version__ if hasattr(gliner, __version__) else unknown); print(PyTorch version:, torch.__version__)如果能看到 PyTorch 版本号正常输出说明基础环境没有问题。4. 快速上手加载 GLiNER2.5 模型4.1 加载预训练模型GLiNER 系列模型在 HuggingFace Hub 上提供了多个预训练权重。GLiNER2.5 对应的权重需要根据实际发布的模型名称加载示例如下from gliner import GLiNER # 示例加载预训练模型实际模型名称以官方发布为准 model GLiNER.from_pretrained(fastino/gliner2.5-base) print(模型加载成功)这里需要注意不同厂商发布的权重命名可能不同。如果你的网络环境无法直接访问 HuggingFace也可以从镜像站下载后从本地路径加载model GLiNER.from_pretrained(/path/to/local/gliner2.5)4.2 最小 NER 示例模型加载之后就可以直接进行命名实体识别。下面是一个最小示例text 苹果公司今天发布了新款 iPhone由库克在加利福尼亚州的发布会上介绍。 labels [公司名, 产品名, 人名, 地名] entities model.predict_entities(text, labels) for entity in entities: print(f实体: {entity[text]}类型: {entity[label]}置信度: {entity[score]:.4f})预期输出格式如下具体字段名可能因模型版本而异实体: 苹果公司类型: 公司名置信度: 0.9732 实体: iPhone类型: 产品名置信度: 0.9611 实体: 库克类型: 人名置信度: 0.9456 实体: 加利福尼亚州类型: 地名置信度: 0.9820通过示例可以看到GLiNER 的使用方式是传入原文与类型描述列表模型返回识别出的实体文本、类型标签与置信度。这种动态传入类型的能力正是零样本 NER 的核心体验。5. 实战案例基于边界预测的信息抽取这一节我们做一个更完整的实战案例对比 GLiNER2.5 在边界预测架构下的实际使用效果。5.1 数据准备假设我们需要从一段法律合同的摘录中抽取实体涉及类型包括甲方乙方合同金额履约期限管辖法院。text 甲方北京中科智远科技有限公司与乙方上海华清数据服务有限公司于2024年3月15日签订技术服务合同 合同总金额为人民币壹佰贰拾万元整。双方约定履约期限为2024年4月1日至2025年3月31日。 如发生争议双方应提交北京市朝阳区人民法院管辖。 这段文本中包含了公司名、日期、金额、法院名称等多个实体。其中的甲方乙方并不是传统的命名实体而是文本中的角色标签在合同审查和信息抽取任务中非常常见。5.2 编写抽取代码构建一个完整的抽取脚本文件路径可以是scripts/extract_contract.py# scripts/extract_contract.py from gliner import GLiNER def load_model(model_name: str fastino/gliner2.5-base): return GLiNER.from_pretrained(model_name) def extract_entities(model, text: str, labels: list, threshold: float 0.5): entities model.predict_entities(text, labels, thresholdthreshold) return entities def main(): model load_model() text 甲方北京中科智远科技有限公司与乙方上海华清数据服务有限公司于2024年3月15日签订技术服务合同 合同总金额为人民币壹佰贰拾万元整。双方约定履约期限为2024年4月1日至2025年3月31日。 如发生争议双方应提交北京市朝阳区人民法院管辖。 labels [甲方, 乙方, 合同金额, 履约期限, 管辖法院] entities extract_entities(model, text, labels) print( * 50) print(抽取结果) print( * 50) for entity in entities: print(f[{entity[label]}] {entity[text]} (score: {entity[score]:.4f})) if __name__ __main__: main()5.3 运行与验证在终端中执行以下命令python scripts/extract_contract.py预期输出如下具体结果取决于实际权重和版本 抽取结果 [甲方] 北京中科智远科技有限公司 (score: 0.9812) [乙方] 上海华清数据服务有限公司 (score: 0.9778) [合同金额] 壹佰贰拾万元 (score: 0.9023) [履约期限] 2024年4月1日至2025年3月31日 (score: 0.9367) [管辖法院] 北京市朝阳区人民法院 (score: 0.9644)与早期基于跨度枚举的模型相比GLiNER2.5 在这种多类型混合抽取的任务中边界定位会更干脆。尤其是在履约期限这类包含起止日期的长跨度实体上边界预测架构能更完整地捕获整段信息减少头尾丢失的情况。5.4 结果说明从输出可以观察到第一模型可以识别非传统命名实体的角色类型如甲方乙方。这是 GLiNER 零样本能力的重要体现类型描述由调用方在推理时传入模型动态匹配。第二合同金额实体识别为壹佰贰拾万元而非人民币壹佰贰拾万元说明模型对金额实体的边界判断有自己的标准。如果业务上需要包含货币单位可以通过调整类型描述来引导例如将类型描述改为带有货币单位的合同金额。第三置信度分数可以作为下游判断的依据。在自动抽取流程中可以设置阈值过滤低置信度结果降低误报。6. 边界预测架构的关键细节看完实战后我们来深入理解边界预测架构中几个关键的实现细节。6.1 标签体系设计在边界预测架构中文本中的每个 token 都会被赋予一个标签。常见的设计是 BIESO 标签体系BBegin实体开始IInside实体中间EEnd实体结束SSingle单 token 实体OOutside非实体对于不同类型的实体可以进一步组合例如 B-公司名、I-公司名、E-公司名等。这种标签体系可以在一个前向过程中同时确定实体边界和实体类型。GLiNER2.5 的标签体系会在类型描述的基础上动态构造。也就是说模型会根据调用方传入的实体类型列表动态生成对应的标签集合而不是使用固定的标签表。这一点是零样本能力的关键类型可以随时变化标签也随之变化。6.2 损失函数与训练目标边界预测模型在训练阶段的目标是在给定 token 序列的条件下最大化每个 token 标签的正确概率。常见做法是在编码器输出层接一个线性分类头使用交叉熵损失进行训练。与跨度枚举方法不同边界预测模型不需要对所有候选跨度计算交互特征因此训练和推理的计算成本更低。但也存在标签不平衡问题大部分 token 属于 O 标签实体 token 相对稀少。训练时需要使用类别权重或 Focal Loss 等策略缓解标签不平衡带来的偏向性问题。6.3 推理阶段如何解码边界推理阶段模型对每个 token 预测一个标签然后通过解码算法将 token 级别的标签序列转换为实体片段。解码规则如下遇到 B 标签时开始一个新实体片段记录开始位置。遇到 I 标签时将当前 token 追加到上一个实体片段内。遇到 E 标签时结束当前实体片段并标记该实体的类型。遇到 S 标签时生成一个单独的实体。遇到 O 标签时不产生实体。解码后还需要将 token 位置映射回原始文本中的字符位置。由于 GLiNER 使用 tokenizer 将文本切分为 token一个中文词可能会被切分成多个 token所以需要建立 token 到字符的映射关系确保输出的实体文本是完整的原始字符序列。6.4 与跨度枚举的复杂度对比从计算复杂度的角度可以做如下对比方法时间复杂度空间复杂度跨度枚举O(N²)O(N²)边界预测O(N)O(N)其中 N 表示序列长度。在长度为 128 的短文本上两者的差距可能不明显但当 N 达到 512 甚至更长时跨度枚举的候选数量会达到数万级别边界预测的优势就非常显著了。这也解释了为什么 GLiNER2.5 会采用边界预测架构。它在保持零样本泛化能力的前提下显著降低了推理开销使得模型在生产环境的可用性大幅提升。7. 常见问题与排查思路7.1 模型加载失败或权重路径错误问题现象调用from_pretrained时提示模型不存在或网络下载失败。可能原因模型名称拼写错误、网络无法访问 HuggingFace、本地路径不存在。解决思路先确认模型名称是否与官方发布一致再到 HuggingFace 页面确认。如果网络受限可以手动下载权重到本地后使用本地路径加载。7.2 中文抽取效果不理想问题现象对中文文本的实体识别结果明显不准。可能原因模型预训练数据中中文占比不足或 tokenizer 对中文分词不友好。解决思路替换中文能力更强的基础编码器或使用专门针对中文优化的 GLiNER 变体。此外可以从类型描述入手把描述写得更贴近目标文本。比如将公司改为中国本土企业名称。7.3 实体边界偏大或偏小问题现象预测出的实体比预期多出或少几个字。可能原因边界预测模型对特定边界模式学习不够或者类型描述产生误导。解决思路可以适当调整阈值。阈值提高后低置信度的边界会被过滤掉。更有效的方案是在提示词类型描述中补充边界约束例如只包含公司名称本身不包含公司类型后缀。7.4 推理速度仍然较慢问题现象批量处理大量文本时吞吐量不理想。可能原因使用 CPU 推理或文本长度过长导致注意力计算开销大。解决思路使用 GPU 推理对超过模型最大长度的文本进行切分处理。同时可以对批处理大小进行调整找到吞吐量和显存占用之间的平衡点。7.5 置信度分数集中在 0.5 附近问题现象所有实体的置信度分数都不高难以通过阈值筛选。可能原因模型对当前类型集合不熟悉或输入文本的表述方式与训练数据差异较大。解决思路置信度分数不等于真实概率不同模型之间的分数分布可能有差异。建议先在小样本上观察分数分布再设定合理的业务阈值不要直接套用别的项目的经验值。下面用表格汇总常见问题问题现象常见原因解决思路模型加载失败网络受限或路径错误检查模型名使用本地路径中文效果差基础模型中文能力不足换中文优化模型或调整类型描述实体边界不准边界模式学习不足调整阈值优化类型描述推理速度慢CPU 推理或文本过长使用 GPU切分长文本置信度分布异常类型不熟悉或描述不当小样验证后设定合理阈值8. 最佳实践与工程建议8.1 类型描述要具体且自包含GLiNER 是零样本模型类型描述的质量直接影响抽取效果。类型描述建议具体、自包含包含该类型文本的典型特征。参考如下示例不够好的描述公司更好的描述注册成立的企业名称不包含冒号和标点不够好的描述地址更好的描述包含省市区街道门牌号的完整邮寄地址描述越具体模型越容易将文本片段与类型对应起来。8.2 充分利用阈值参数进行质量控制生产环境中不要直接使用默认阈值。建议在业务数据集上先运行一次观察置信度分布再根据精确率和召回率的平衡需求确定阈值。如果业务更看重精确率可以适当调高阈值如果更看重召回率可以调低阈值。8.3 长文本处理策略GLiNER 模型通常有最大输入长度限制。对于长文档建议先按段落切分再对每个段落进行实体抽取。切分时要注意不要将同一实体切断。可以基于标点符号进行切分也可以使用滑动窗口并保留重叠区域。8.4 与规则和词典结合使用GLiNER 的零样本能力适合作为基础抽取层但并不排除引入规则和词典。对于确定性的实体如身份证号、手机号可以用正则表达式直接抽取对于需要语义理解的实体可以使用 GLiNER2.5。两者结合往往能在生产环境达到更好的效果。8.5 生产环境部署注意事项部署 GLiNER2.5 时建议使用模型服务框架封装推理接口例如使用 FastAPI 或 Triton Inference Server。模型加载后常驻内存避免每次请求都重新加载权重。如果需要更高吞吐可以使用批处理队列将短文本合并为 batch 输入模型。还要注意资源限制。边界预测架构虽然已经比跨度枚举更节省资源但 GLiNER 系列模型本身仍然是百亿参数规模以下的 Transformer 模型显存占用在几百 MB 到几 GB 之间部署前需要做好资源评估。9. 总结GLiNER2.5 的核心变化可以概括为一句话用边界预测替代跨度枚举在保留零样本实体识别能力的同时显著提升推理效率和边界精度。本文从命名实体识别的背景出发对比了跨度枚举和边界预测两种架构的差异分析了边界预测的标签体系、训练目标和解码策略并通过一个合同文本抽取的实战案例演示了完整的使用流程。在工程实践中类型描述的设计、阈值策略的调整、长文本切分方案以及规则兜底机制都是让 GLiNER2.5 在真实业务中稳定发挥作用的关键。如果你之前使用过早期的 GLiNER 版本建议在同样的数据集上对比一下新旧版本的推理速度和边界质量如果你还没有用过 GLiNER 系列模型GLiNER2.5 是一个不错的切入点代码量少、上手快十分适合做零样本实体抽取能力验证。希望这篇文章能帮你少走一些弯路。
返回列表