BERT命名实体识别模型转ONNX后的输入长度处理及推理管线构建问题
BERT命名实体识别模型转ONNX后的输入长度处理及推理管线构建问题
嘿,针对你这两个关于BERT转ONNX后的问题,我给你详细梳理下:
一、关于动态输入长度的处理
不用非得把所有输入都截断到512长度!ONNX本身是支持动态维度的,关键是你在导出模型时要正确配置动态轴(dynamic axes)。
默认情况下,如果导出时没指定动态轴,模型会被固定成你导出测试用的输入长度,但只要在导出阶段明确设置好动态维度,就能处理任意长度的输入(当然不能超过BERT本身的最大序列长度512,超过的话还是得做截断或者滑动窗口拆分处理)。
给你个实际导出的代码示例,用Hugging Face的transformers工具导出时,这样配置动态轴:
from transformers import AutoTokenizer, AutoModelForTokenClassification, export_onnx model_name = "你的BERT-NER模型名称/路径" tokenizer = AutoTokenizer.from_pretrained(model_name) model = AutoModelForTokenClassification.from_pretrained(model_name) # 指定动态轴:将batch_size和sequence_length设为可变化的维度 dynamic_axes = { "input_ids": {0: "batch_size", 1: "sequence_length"}, "attention_mask": {0: "batch_size", 1: "sequence_length"}, "token_type_ids": {0: "batch_size", 1: "sequence_length"}, "outputs": {0: "batch_size", 1: "sequence_length"} } # 导出带动态维度的ONNX模型 export_onnx( model=model, tokenizer=tokenizer, output="model.onnx", dynamic_axes=dynamic_axes )
导出后的模型就可以接受不同长度的输入序列了,推理时直接传入对应长度的tokenized数据就行,不用强行截断到512。
二、构建ONNX模型的NER推理管线
你提到的Hugging Face原生库不支持ONNX模型做NER是旧情况啦,现在可以用Optimum库(Hugging Face官方推出的模型优化工具库)来轻松构建推理管线,它完美支持ONNX格式的TokenClassification任务(也就是NER)。
操作步骤很简单:
- 先安装依赖:
pip install optimum onnxruntime
- 加载ONNX模型和对应tokenizer,创建推理管线:
from optimum.onnxruntime import ORTModelForTokenClassification from transformers import AutoTokenizer, pipeline # 加载ONNX模型和配套tokenizer model = ORTModelForTokenClassification.from_pretrained("./你的ONNX模型所在文件夹路径") tokenizer = AutoTokenizer.from_pretrained("你的BERT-NER模型名称/路径") # 创建NER推理管线,aggregation_strategy参数可以把子词合并成完整实体 ner_pipeline = pipeline( "token-classification", model=model, tokenizer=tokenizer, aggregation_strategy="simple" ) # 测试推理 result = ner_pipeline("这里是你的测试句子,比如'小明在2023年加入了阿里巴巴集团'。") print(result)
如果你不想用Optimum,也可以手动搭建管线:自己写函数把文本做tokenize处理,然后用ONNX Runtime直接运行模型,再把模型输出的logits转换成实体标签。不过用Optimum的pipeline会省事很多,用法和原生Hugging Face pipeline几乎一致。
备注:内容来源于stack exchange,提问作者singa1994
相关产品推荐
相关产品推荐

