一、 MindStudio介绍
MindStudio提供了在AI开发所需的一站式开发环境,支持模型开发、算子开发以及应用开发三个主流程中的开发任务。依靠模型可视化、算力测试、IDE本地仿真调试等功能,MindStudio能够实现在一个工具上高效便捷地完成AI应用开发。
对推理任务而言,MindStudio提供了模型压缩工具、模型转换工具和模型可视化工具。模型转换工具将开源框架的网络模型 (如Caffe、TensorFlow等)转换成昇腾AI处理器支持的离线模型,模型转换过程中可以实现算子调度的优化、权值数据重排、内存使用优化等。,并为NER任务实现一流的性能。它可以识别四种类型的实体:位置(LOC),组织(ORG),人员(PER)和其他(MISC)。具体而言,此模型是一个bert-large-cased模型,在标准CoNLL-2003命名实体识别(https://www.aclweb.org/anthology/W03-0419.pdf)数据集的英文版上进行了微调。
如果要在同一数据集上使用较小的 BERT 模型进行微调,也可以使用基于 NER 的 BERT(https://huggingface.co/dslim/bert-base-NER/) 版本。
本文介绍了如何使用MindStudio将hugging face上开源的bert_large_NER模型部署到Ascend平台上,并进行数据预处理、推理脚本的开发,在CoNLL-2003命名实体识别数据集上完成推理任务。
三、 推理环境准备
3.1 Linux端环境准备
1. 配置conda环境、安装依赖包
依赖名称 | 版本 |
---|---|
ONNX | 1.9.0 |
onnxruntime | 1.12.1 |
Pytorch | 1.8.0 |
TorchVision | 0.9.0 |
numpy | 1.20.3 |
transformers | 4.21.1 |
tensorflow | 2.9.1 |
创建conda环境,并安装对应版本安装项目依赖的包。
2. 配置环境变量
source /usr/local/Ascend/ascend-toolkit/set_env.sh #root用户下
export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:/usr/local/Ascend/driver/lib64/driver/source /usr/local/Ascend/ascend-toolkit/set_env.sh
npu-smi info #查看npu信息
3.2 windows端环境准备
按照MindStudio用户手册中的安装指南—>本地安装依赖:Python(版本要求:3.7~3.9)、MinGW、CMake,安装MindStudio。
三、 创建工程
4.1 创建工程
添加远程服务器,选择远程服务器中正确的CANN版本:
等待本地同步远端服务器CANN文件,同步完成后,选择ACL Projection(python)项目,点击完成,完成新建项目。
配置项目结构:
选择add python SDK:
选择ssh interpreter,并配置正确的python解释器:
配置本地文件夹和远程服务器映射:
4.2配置本地、远端环境同步
工程目录为:
├──bert_large_NER
└── bert-large-NER //hugging face提供的词典等
└── bert-large-OUT //推理结果输出路径
└── bert_bin //生成的推理用数据保存路径
└── conll2003 //CoNll-2003数据集
└── bert_metric.py //精度测试脚本
└── bert_onnx_inference.py //使用onnx模型推理脚本
└── bin_create.py //生成om模型推理用数据脚本
└── npy_dataset_generate.py //生成onnx模型推理用数据脚本
五、 执行推理
5.1 数据预处理
获取原始数据集CoNLL-2003:数据集下载链接:https://data.deepai.org/conll2003.zip
数据集目录为:
├──conll2003
└── valid.txt //验证集
└── train.txt //验证集
└── test.txt //测试集
该数据集为从路透社的新闻文章中摘取的句子,并为这些单词标记人名、地名和组织名称。以测试集为例,数据集的主要形式如下:
词 词性 词块 实体
U.N. NNP I-NP I-ORG
official NN I-NP O
Ekeus NNP I-NP I-PER
heads VBZ I-VP O
for IN I-PP O
Baghdad NNP I-NP I-LOC
. . O O
在NER任务中,只关心1、4列,其中,第一列代表单词,最后一列代表实体对应的类别。实体类别NAME_ENTITY记录为以下九类:
B-PER/I-PER表示单词对应于个人实体的开头。
B-ORG/I-ORG表示单词对应于组织实体的开头/内部。
B-LOC/I-LOC表示对应于位置实体开头的单词。
B-MISC/I-MISC表示单词对应于其他实体的开头。
0表示单词非四大类实体。
数据预处理:将原始数据集转换为模型输入的二进制数据。
数据预处理脚本开发:
模型有三个输入,input_ids,attention_mask,token_type_ids;input_ids表示将输入的单词经过bert_large_NER模型生成embedding,在这个过程中,设置sequence长度为512,padding为Ture,实现将input_ids补全为长度为512的向量。同时,在每一条句子对应的512个单词中,哪些是句子的实际长度就将其对应的attention_mask设置为1,padding的部分就将对应的attention_mask设置为0。在一些任务中,存在模型的一条输入超过一句话的情况,此时借助token_type_ids来区分不同的句子,但在NER任务中,CoNLL-2003这个语料库里每个语料只有一句话,因此token_type_ids全都是0。
数据预处理的代码实现如下:(bin_create.py、npy_dataset_generate.py)
首先,定义INPUT_KEYS和NAME_ENTITY两个列表,分别记录输入和实体名称:
设置生成数据的文件结构,并创建三个输入token对应的文件夹:
加载bert_large_NER模型中定义的tokenizer:
使用tokenizer中的convert_tokens_to_ids方法,将英语单词根据对应的词汇表转换成embedding。手动将每个句子的长度填充到512,并根据句子长度填写attention_mask的值。此外,处理每个单词时,记录其对应的实体类别,并将其记录在annofile中,便于后续精度的计算。
对于om模型而言,要求的输入是.bin格式的,并将每条数据对应的三条输入分别存入三个文件夹。对于onnx模型而言,要求的输入是.npy格式的,并将每条数据对应的三条输入存入三个.npy文件。因此,在脚本开发中文件保存时要注意格式要求。
执行bin_create.py脚本生成om模型需要的推理数据:
- 运行成功后生成:input_ids.npy、attention_mask.npy、token_type_ids.npy三个npy文件,保存在./bert_bin/bert_npy_2022xxxx-xxxxxx/文件夹下,.anno文件记录token对应的label,保存在./bert_bin文件夹下。
执行npy_dataset_generate.py脚本生成onnx模型需要的推理数据:
- 运行成功后生成:input_ids、attention_mask、token_type_ids三个文件夹,保存在./bert_bin/bert_bin_2022xxxx-xxxxxx/文件夹下,文件夹中存的数据格式为.bin,作为om模型的输入。.anno文件记录token对应的label,保存在./bert_bin/文件夹下。
5.2 模型转换
5.2.1 借助transformers[onnx]工具由path转换成onnx
pip install transformers[onnx]
使用transformers.onnx进行模型转换:
python -m transformers.onnx --model=bert-large-NER --feature=token-classification onnx/
■参数说明:
– model:hugging face上下载的开源模型
– feature:用于导出模型的特征类型
– onnx/:保存导出的onnx模型的路径
运行结束后生成model.onnx保存在./onnx文件夹下。
5.2.2 onnx转换成om
使用ATC命令将onnx模型转换为om模型:
atc --framework=5 --model=model.onnx --output=bert_large_bs16_seq512 --input_shape="input_ids:16,512;attention_mask:16,512;token_type_ids:16,512" --soc_version=Ascend310P3
■参数说明:
--model:为ONNX模型文件。
--framework:5代表ONNX模型。
--output:输出的OM模型。
--input_shape:输入数据的shape。输入数据有三条,均为batch*512,其中512为sequence序列长度。
--soc_version:处理器型号。
运行成功后生成bert_large_bs16_seq512.om模型文件。
对om模型进行可视化,观察模型的输入输出。
5.3 执行离线推理
转换om模型成功后,使用MindStudio remote终端执行ais_infer推理。
启动ssh session,切换conda环境,切换工作目录:
使用ais_infer工具进行推理:
a. 下载推理工具ais_infer。
git clone https://gitee.com/ascend/tools.git
b. 编译、安装推理工具
cd /home/lcy/RotaE/tools/ais-bench_workload/tool/ais_infer/backend/
pip3.7 wheel ./ #编译 要根据自己的python版本
ls
pip install aclruntime-0.0.1-cp37-cp37m-linux_x86_64.whl
精度测试(以batchsize=16为例):
python ./tools/ais-bench_workload/tool/ais_infer/ais_infer.py --model ./bert_large_bs16_seq512_1.om --input "./bert_bin/bert_bin_20220928-061343/input_ids,.bert_bin/bert_bin_20220928-061343/attention_mask,./bert_bin/bert_bin_20220928-061343/token_type_ids" --output ./bert-large-OUT/bs16 --outfmt NPY
■参数说明:
--model:为ONNX模型文件。
--batchsize:模型的batchsize大小。
--input:模型的输入,input_ids、attention_mask、token_type_ids三个文件夹。
--output:输出指定在./bert-large-OUT/bs16下。
--outfmt:推理结果保存格式。
执行结束输出保存在./bert-large-OUT/bs16下。
5.4 精度验证
推理成功,需要对推理结果进行后处理,通过bert_metric.py进行后处理,验证推理结果,进行精度评估。
精度推理脚本开发:
首先获取到./bert-large-OUT/bs16目录下的推理结果文件:
根据预测正确的条数/总数量得到预测正确的准确率acc:
在MindStudio运行bert_metric.py脚本进行精度验证:
运行成功后输出模型预测结果的精度为90.73%,接近于hugging face中在测试集上的精度结果91.2%:
六、 性能调优
使用aoe工具进行自动性能调优。
No performance improvement”表明:自动性能调优未带来模型推理性能的提升。
Q&A
-
由于bert_large_NER模型转换得到的onnx模型较大,且三个输入的形状均为动态的[batch, sequence],因此在使用MindStudio进行onnx模型的可视化以及onnx模型向om模型转换时出现报错:
故在模型转换时直接使用ATC工具完成。
-
在数据预处理过程中,transformer库提供的AutoTokenizer.tokenizer方法,生成的embedding存在两个问题:①对未见过的单词自动进行拆分,导致生成的input_keys与原句子相比常常会变长,此时annofile中记录的每个单词对应的实体类别就会失效;②在句子的起始处和结尾处自动增加[CLS]、[SEP]作为起始符和终止符,在更加强调整句话语义的NLP任务中是至关重要的,但在关注每个单词对应的实体类别的NER任务中是不重要的。在测试过程中,也推测出作者在进行模型训练时,也是未增加起始、终止符的。
因此,选择借助AutoTokenizer.convert_tokens_to_ids方法,先手动的对应词汇表将英语单词编码为embedding,对于词汇表中没有的单词会将其编码成100。之后再对根据句子长度和sequence长度(512)对编码后的input_ids进行padding,完成input_ids,attention_mask,token_type_ids的生成和annofile记录单词label的对应 。
bert_large_NER的vocab.txt如下所示:
由tokenizer方法生成的数据如下所示,101表示[CLS],102表示[SEP]。
由convert_tokens_to_ids生成的数据如下所示,对词汇表中未出现过的单词会将其编码为100。
ttention_mask,token_type_ids的生成和annofile记录单词label的对应 。
bert_large_NER的vocab.txt如下所示:
由tokenizer方法生成的数据如下所示,101表示[CLS],102表示[SEP]。
由convert_tokens_to_ids生成的数据如下所示,对词汇表中未出现过的单词会将其编码为100。
若读者在使用MindStudio过程中或推理过程中遇到问题,可在MindStudio昇腾论坛进行提问、讨论。