1. 序列标注的应用场景
如果说分类是"这段新闻讲的是什么",序列标注就是"这段话里哪些是人名、哪些是地名、哪些是机构名"。
典型应用场景:
- 命名实体识别:从文本中抽取出人名、地名、机构名、时间、金额等实体,是构建知识图谱、信息检索的基础
- 信息抽取:从简历、合同、发票等半结构化文档中自动提取关键字段
- 搜索与推荐:理解用户 query 中的实体("北京到上海的机票"→ 出发地、目的地、产品类型),提升搜索精度
- 数据脱敏:自动识别并打码手机号、身份证号、银行卡号等敏感信息
2. 数据准备与探索分析
2.1 数据集获取与构建
本文使用的数据集是cluener2020
下载地址:https://storage.googleapis.com/cluebenchmark/tasks/cluener_public.zip
train.json(训练集)、validation.json(验证集)、test.json(测试集)
里面的数据格式是这样的,text是话,label里是实体的类型+下标:
{
"text": "彭小军认为,国内银行现在走的是台湾的发卡模式,先通过跑马圈地再在圈的地里面选择客户,",
"label": {
"address": {
"台湾": [
[
15,
16
]
]
},
"name": {
"彭小军": [
[
0,
2
]
]
}
}
}
2.2 数据探索揭示的规律



从数据集统计结果可以看出,CLUENER2020 整体以短文本为主,句子长度集中在40字左右、单句实体密度适中,整体任务难度可控,非常适合作为中文序列标注的基准实验数据集。
数据集实体分布存在明显长尾特征,人名、机构、公司、职位类样本数量充足,模型容易学习;而书籍、影视作品两类实体样本最少。
同时数据集中实体平均长度仅4.5字,极少存在超长实体与单字歧义实体,大幅降低了实体边界分割的难度。
3. 方案一:调 LLM API 做 NER
3.1 提示词设计与调用流程
把 text 传给 api,然后把 api 的输出,对比 json 里面的 label(下标不用对比)。要求 api 的输出和 label 里面的完全一样才算这个 case 通过。
SYSTEM_PROMPT = """你是一个命名实体识别(NER)专家,专门处理中文文本。
请从用户输入的文本中识别以下10类实体,并以 JSON 格式输出结果:
- address:地址(如街道、城市)
- book:书名
- company:公司名称
- game:游戏名称
- government:政府机构名称
- movie:影视作品名称
- name:人名
- organization:组织机构名称
- position:职位名称
- scene:景点或场所名称
输出格式(严格遵守,不要包含其他文字):
{"entities": [{"text": "实体文本", "type": "实体类型英文名"}, ...]}
如果没有实体,输出:{"entities": []}"""
3.2 测试效果
使用的deepseek-v4-flash模型,效果如下:
总评测样本数:1343
实体完全匹配样本数:358
严格匹配准确率:0.2666
接口总耗时:995.97 秒
单条文本平均调用耗时:0.74 秒
基于验证集 1343 条样本对 DeepSeek-V4-Flash 做 NER 严格匹配评测,整体严格匹配准确率仅 26.66%,单条文本平均调用耗时 0.74s,性能表现存在明显短板。
这里采用全集实体完全对齐的严苛判断标准:只有预测实体的文本、类别与标注全部一致才算命中,任意实体漏检、多识别、类别判错都会直接判定整条样本不通过,大幅拉低了整体分数。
结合数据分布来看,低分一部分源于模型识别能力不足,另一部分来自数据集本身的歧义样本:部分句子中部分实体边界、类别归属本身模棱两可,人工标注也存在模糊性,大模型容易给出和标注不完全一致但逻辑合理的抽取结果,在当前 "完全匹配" 规则下统一算作错误。
3.3 接口方案做 NER 的额外困境
调用 DeepSeek API 能快速搭建 NER 能力,但实测验证集严格匹配准确率仅 26.66%,单条平均耗时 0.74s,结合错误样本,相比文本分类存在更多落地硬伤:
- 效果存在明显天花板
仅靠提示词无法根治各类识别问题:地址 / 景点、机构 / 企业、影视 / 游戏容易类别混淆;实体边界经常错位、丢符号;频繁出现实体幻觉或漏检;加上部分标注本身存在歧义,进一步拉低匹配率。且云端接口不支持微调,无法用标注数据针对性优化长尾实体。 - 推理速度慢,批量处理低效
NER 需要生成完整实体 JSON,输出 token 更多,单条平均 0.74 秒,海量文本抽取耗时极长,不适合离线批量清洗与高并发线上场景。 - 结构化输出不稳定,工程成本高
模型可能附带多余文字、格式错乱,需要在工程方面做容错。 - 长期使用成本高
API 按 token 计费,数据量越大开销越高;本地 BERT / 私有化 LLM 仅一次性训练,推理几乎无增量成本。 - 隐私与业务稳定性无保障
业务文本需外传第三方,存在数据合规风险;接口受厂商限流、版本调整影响,无法自主扩容优化。
4. 方案二:Bert 微调------序列标注的经典基线
4.1 序列标注基础原理
比较常见的是BIO标注
| 标签 | 具体含义 |
|---|---|
| B-TYPE | 实体首个token,TYPE替换为对应实体类别(name、address、company等) |
| I-TYPE | 实体中间、末尾的token,必须紧跟同类B标签/I标签之后 |
| O | 不属于任何实体的普通字符token |
例子:
| 字符 | 马 | 云 | 创 | 立 | 阿 | 里 | 巴 | 巴 |
|---|---|---|---|---|---|---|---|---|
| 标签 | B-PER | I-PER | O | O | B-ORG | I-ORG | I-ORG | I-ORG |
在BIO的基础上有BIOES标注,E是结束、S是单字,E的好处是有的词有明显的结尾。
BIO标注也有缺陷,比如无法表示嵌套,例子:
| 文本 | 北 | 京 | 大 | 学 |
|---|---|---|---|---|
| 外层标签(机构) | B-ORG | I-ORG | I-ORG | I-ORG |
| 内层标签(地点) | B-LOC | I-LOC | O | O |
也有方案解决嵌套:
- 扩大空间。多层标注,每层独立 BIO 序列
- 扩大时间。Span-based 方法,暴力枚举句子的所有子句,依次让模型判断是不是实体、是哪类实体
- 如果比例低,忽略处理
4.2 CRF介绍
原始的方案有个缺点,每个汉字的标签都是单独计算的,没有考虑到约束关系。比如 O 后面是不能直接接 I 的;I-name 后面不能接 I-loc。
CRF 在输出层加入全局转移约束,对整条标签序列联合建模,找全局最优输出。
公式是: score(Y, X) = Σₜ emission(yₜ, xₜ) + Σₜ transition(yₜ₋₁, yₜ)
emission:发射分数。来自bert+Linear层的输出
transition:转移分数。一个可学习的矩阵 T,大小为 (num_tags, num_tags)。
Tij 表示从标签 i 转移到标签 j 的得分。
转移分数长这样,高分 = 允许、推荐跳转;极低负数 = 禁止、惩罚跳转。
T12 = 4.5:上一个标签是 B-name,当前标签是 I-name。模型训练后此处分数很高,解码时这条路径总得分更高,会优先选择该组合。
T14 = -9.0:上一个标签是 B-name,当前标签是 I-loc。B-name 代表人实体起始,后面不可能直接跟地点内部标签 I-loc,属于典型非法序列。
| 上标签 \ 当前标签 | Tag_0(O) | Tag_1(B-name) | Tag_2(I-name) | Tag_3(B-loc) | Tag_4(I-loc) |
|---|---|---|---|---|---|
| Tag_0(O) | 4.2 | 3.8 | -8.5 | 3.7 | -8.3 |
| Tag_1(B-name) | 2.1 | -9.1 | 4.5 | -8.8 | -9.0 |
| Tag_2(I-name) | 2.3 | -8.7 | 4.1 | -8.9 | -9.2 |
| Tag_3(B-loc) | 2.0 | -8.6 | -9.3 | 4.3 | 4.4 |
| Tag_4(I-loc) | 2.2 | -8.8 | -9.0 | -8.5 | 4.0 |
不过CRF并不是必选项。因为BERT 的双向注意力已能捕捉全局标签依赖,加上CRF也会拖慢训练时间。
4.3 训练代码核心模块拆解

假设现在有个原始数据是:"我现在在南京",标注的是南京,是地名。max_len 是 10。将被处理成这样:
{
"input_ids": tensor([101, 2769, 6432, 1762, 1762, 1299, 776, 102, 0, 0]),
"attention_mask": tensor([1, 1, 1, 1, 1, 1, 1, 1, 0, 0]),
"token_type_ids": tensor([0, 0, 0, 0, 0, 0, 0, 0, 0, 0]),
"labels": tensor([-100, 0, 0, 0, 0, 1, 2, -100, -100, -100])
}
| token 内容 | CLS | 我 | 现 | 在 | 在 | 南 | 京 | SEP | PAD | PAD |
|---|---|---|---|---|---|---|---|---|---|---|
| word_ids | None | 0 | 1 | 2 | 3 | 4 | 5 | None | None | None |
| 最终labels数值 | -100 | 0 | 0 | 0 | 0 | 1 | 2 | -100 | -100 | -100 |
| attention_mask | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 |
| token_type_ids | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
4.4 Linear vs CRF 实测效果
两个模型统一训练 5 轮收敛,二者 F1 差距很小。核心原因是 BERT 自带双向上下文建模能力,CRF 很难带来大幅精度提升,更多是修正标签格式。
BERT+Linear:实体 F1=0.7603;1343 条样本中 231 条存在非法 BIO 序列,非法占比 17.2%
BERT+CRF:实体 F1=0.7687,仅上涨 0.84 个百分点;非法序列数量下降至 185 条,占比降至 13.8%
5. 方案三:LLM 私有化微调
5.1 微调方法
本实验依旧采用 LoRA 轻量化微调,训练逻辑和我上一篇文本分类文章完全一致:样本拼接成提示词 + 标准答案的对话格式交给模型做续写训练,训练时只对答案部分计算 loss 更新权重,prompt 部分屏蔽梯度。
5.2 效果
=================================================================
LLM SFT NER 评估结果
=================================================================
样本数 : 1343
Precision : 0.7434
Recall : 0.7025
F1 : 0.7223
JSON 解析失败: 0 条 (0.0%)
总耗时 : 528.6s,均值 0.39s/条
6. 综合对比与总结
6.1 方案横向评测表
本次实验一共对比四类实体识别实现方案:BERT+Linear、BERT+CRF、DeepSeek-v4-Flash 大模型原生接口调用、Qwen2-0.5B-Instruct LoRA 微调 SFT,基于 CLUENER 验证集(1343 条样本)的核心指标汇总如下:
| 方案 | 实体F1值 | 非法BIO占比 | 单条推理耗时 | 训练/调用特征 |
|---|---|---|---|---|
| BERT+Linear | 0.7603 | 17.20% | 本地毫秒级 | 全量参数训练,单轮训练24s,速度最快;易产生标签跳转错误 |
| BERT+CRF | 0.7687 | 13.80% | 本地毫秒级 | 在Linear基础上F1小幅提升0.84个百分点,依靠转移矩阵约束标签合法性,非法序列占比下降3.4%;训练计算量上涨,单轮耗时翻倍至50s |
| DeepSeek-v4-Flash 在线接口 | 严格匹配率0.2666 | - | 0.74s/条 | 闭源大模型零训练成本,但远程调用延迟最高,实体精准匹配效果最差 |
| Qwen2-0.5B LoRA-SFT | 0.7223 | 无BIO非法问题(结构化输出) | 0.39s/条 | 轻量化LoRA微调,沿用文本分类一致的SFT范式,仅对答案区间计算损失;输出JSON格式天然规避标签语法错误,推理速度优于商用接口,整体F1略低于BERT系列模型 |
BERT 类模型训练 5 轮后均进入性能平台期,继续训练会出现验证损失抬升、过拟合问题,最优权重均可锁定在训练中期节点;CRF 层在 BERT 双向上下文的加持下,不再具备大幅涨分能力,核心价值收敛为规整标签序列格式。LLM 两种方案里,在线 API 调用受模型输出自由性、远程网络影响,实体精准匹配效果垫底;本地小模型 LoRA 微调无需标注 BIO 序列,依靠结构化输出简化工程处理流程,推理时延最优。
6.2 场景化选型建议
- 高性能、低时延的标准实体抽取场景(业务核心链路):优先选择BERT+CRF。模型推理为本地前向计算,响应速度极快,F1 指标最优,同时降低非法标签比例;若业务可增加少量规则清洗非法序列,BERT+Linear可进一步节省训练与算力开销,性价比更高。
- 快速落地、无标注训练算力、小体量业务需求:可直接调用 DeepSeek 等商用大模型接口,免去数据集标注、模型训练、部署全流程工作,但需要承受较高调用耗时与实体匹配精度不足的缺陷。
- 需要统一业务输出格式、多任务复用微调框架:选用开源小模型(Qwen2-0.5B)+LoRA 监督微调方案。复用文本分类的 SFT 训练逻辑,统一使用提示词拼接 + 答案段损失计算的训练方式,输出 JSON 结构化数据无需处理 BIO 非法格式,本地部署可控性强、推理延迟适中,适合多 NLP 任务统一维护。