Hugging Face Transformers NER 实战总结
本文主要构建一个基于 Hugging Face Transformers 的命名实体识别(NER)项目,结合个人实战涵盖从原理讲解、代码结构、训练、预测到踩坑排查等全流程。
一、NER 是什么?
NER 是自然语言处理中的基础任务,目标是从文本中识别并分类具有特定意义的“实体”,如:
- 人名 (PER)
- 组织 (ORG)
- 地点 (LOC)
- 其他 (MISC)
示例:
文本:Barack Obama was born in Hawaii.
输出:
- Barack Obama → PER
- Hawaii → LOC
NER 是其实上的“序列标注”问题,就是给每个 token 打一个标签。
二、使用 BERT 进行序列标注
基础模型:AutoModelForTokenClassification
Hugging Face 提供了 BERT 基础上进行 token-level 分类的简单方式:
model = AutoModelForTokenClassification.from_pretrained("bert-base-cased", num_labels=9)
它本质是:
- 使用 BERT encoder 将文本转换为 token embeddings
- 每个 token 经过 Linear 分类层 输出 label logits
三、数据预处理:Token 对齐
BERT 分词器是 subword 级别,例如:
HuggingFace → ['Hugging', '##Face']
需要把数据中的 word-level label 对齐到 subword,通常做此处理时:
- 首字段保留原标签
- 后续 subword 指定 -100 被 loss 算法忽略
即:tokenize_and_align_labels() 是很核心的预处理部分
四、训练流程:Trainer 自动化
Hugging Face 提供了 Trainer 类,它包装了很多系统性工作:
trainer = Trainer(
model=model,
args=training_args,
train_dataset=train_data,
eval_dataset=val_data,
tokenizer=tokenizer,
compute_metrics=metrics_fn
)
包括:
- 自动 batch 化处理
- 进行损失计算和回传
- 分期保存 checkpoint
- 算法器(AdamW、Scheduler)
同时,Trainer 支持 GPU/多 GPU 自动切换
五、推理流程:Pipeline 快速使用
很多时候,我们已经训好了模型,只想用一行代码进行使用,那么就是:
nlp_ner = pipeline("ner", model=OUTPUT_DIR, tokenizer=OUTPUT_DIR, aggregation_strategy="simple")
aggregation_strategy="simple"会自动合并 B-/I- 标签- 自动切词 -> 编码 -> 预测 -> 转换
六、实际问题:为什么我什么都没看到?
我在运行成功后,却发现:
text = "I love playing basketball."
results = nlp_ner(text)
print(results)
输出:
[]
原因:
1. 模型预测全是 'O' 标签,被 aggregation 过滤了
aggregation_strategy="simple"会被自动过滤- 可用 aggregation=None 查看所有 token 的分类
2. 输入文本不包含模型识别的实体
- 比如 CoNLL2003 不包含 sports/感情/物品 等
3. 未定义 id2label
如果你看到这样输出:
Apple -> LABEL_3
California -> LABEL_5
说明没有传入 id2label,需要:
id2label = {i: label for i, label in enumerate(LABEL_LIST)}
model = AutoModelForTokenClassification.from_pretrained(OUTPUT_DIR, id2label=id2label)
七、总结流程
文本
↓
Tokenizer
↓
tokenize_and_align_labels
↓
BERT Encoder
↓
Token logits (Linear)
↓
Softmax + loss
↓
Trainer 训练
↓
保存模型
↓
Pipeline 进行推理