模型推理加速系列 | 02:如何用ONNX加速BERT特征抽取-part2(附代码)

本文涉及的产品
实时数仓Hologres,5000CU*H 100GB 3个月
实时计算 Flink 版,5000CU*H 3个月
检索分析服务 Elasticsearch 版,2核4GB开发者规格 1个月
简介: 本文紧接之前的一篇文章如何用ONNX加速BERT特征抽取,继续介绍如何用ONNX+ONNXRuntime来加速BERT模型推理。

背景

本文紧接之前的一篇文章如何用ONNX加速BERT特征抽取,继续介绍如何用ONNX+ONNXRuntime来加速BERT模型推理。

更多、更新文章欢迎关注微信公众号:小窗幽记机器学习。后续会持续整理模型加速、模型部署、模型压缩、LLM、AI艺术等系列专题,敬请关注。

如果看过之前的那篇文章的童鞋估计还记得文中留了一个疑问:为何优化过的ONNX模型与未优化的ONNX性能相近?说好的优化,说好地提速呢?与预期不符~

经热心网友冠达提醒优化的ONNX模型运行时要开启OpenMP(如果没有安装,用apt-get install libgomp1安装OpenMP运行时库即可)。回来一试,果然如此,在此感谢热心网友!本文一方面将以正确姿势重新对比ONNX和优化过的ONNX,另一方面引入量化进一步提升模型的推理性能。

PS:本文的实验模型是BERT-base中文版;实验环境的CPU型号信息如下:32 Intel(R) Xeon(R) Gold 6134 CPU @ 3.20GHz

优化ONNX v.s 未优化ONNX

相比于之前代码的唯一区别是在开头加入以下内容,开启OpenMP加速运行。

from os import environ
from psutil import cpu_count
# Constants from the performance optimization available in onnxruntime
# It needs to be done before importing onnxruntime
environ["OMP_NUM_THREADS"] = str(cpu_count(logical=True))
environ["OMP_WAIT_POLICY"] = 'ACTIVE'

所以,此次所有模型都是在此基础上对比,对比结果如下图所示:

image.png

各个模型运行的平均时长如下所示,可以看出,PyTorch模型在开启了OpenMP之后,也从130ms骤降到35ms。其他模型也受益于OpenMP,优化过的ONNX推理耗时只要7ms

{'PyTorch CPU': 35.71977376937866,
 'ONNX CPU': 8.49233627319336,
 'ONNX opt CPU': 7.421176433563232}

模型量化

量化(使用整数而不是浮点)能够让神经网络模型运行得更快。量化是将浮点32范围的值映射为int8,同时尽量地维持模型原来的精度。Hugging Face的transformers也提供了量化功能,可以很方便地导出量化模型。

Pytorch模型量化

import torch 
from transformers import BertTokenizerFast

# Load Pytorch model
torch_model = "/home/data/pretrain_models/bert-base-chinese-pytorch"
model_pt = BertModel.from_pretrained("/home/data/pretrain_models/bert-base-chinese-pytorch").to(device)

tokenizer = BertTokenizerFast.from_pretrained(torch_model)

# Quantize
model_pt_quantized = torch.quantization.quantize_dynamic(
    model_pt.to("cpu"), {torch.nn.Linear}, dtype=torch.qint8
)

model_inputs = tokenizer("大家好, 我是卖切糕的小男孩, 毕业于华中科技大学", return_tensors="pt")

# Warm up 
model_pt_quantized(**model_inputs)

# Benchmark PyTorch quantized model
time_buffer = []
for _ in trange(100):
    with track_infer_time(time_buffer):
        model_pt_quantized(**model_inputs)

results["PyTorch CPU Quantized"] = OnnxInferenceResult(
    time_buffer,
    None
)

ONNX模型量化

## ONNX Quantize
from transformers.convert_graph_to_onnx import quantize
onnx_quantized_model_path = quantize(Path(model_onnx_path))
quantized_model = create_model_for_provider(onnx_quantized_model_path.as_posix(), "CPUExecutionProvider")

# Warm up the overall model to have a fair comparaison
outputs = quantized_model.run(None, inputs_onnx)

# Evaluate performances
time_buffer = []
for _ in trange(100, desc=f"Tracking inference time on CPUExecutionProvider with quantized model"):
    with track_infer_time(time_buffer):
        outputs = quantized_model.run(None, inputs_onnx)

# Store the result
results["ONNX CPU Quantized"] = OnnxInferenceResult(
    time_buffer,
    onnx_quantized_model_path
)

量化前后结果对比

Pytorch模型及其量化模型、ONNX模型、优化过的ONNX模型及其量化模型在CPU上运行的对比结果如下图所示:

image.png

具体数值如下图所示,可以看出,优化过的ONNX模型,再加持量化操作,可以取得5ms的推理耗时。

{'PyTorch CPU': 32.65737533569336,
 'ONNX CPU': 11.347918510437012,
 'ONNX opt CPU': 8.921334743499756,
 'PyTorch CPU Quantized': 29.652047157287598,
 'ONNX CPU Quantized': 6.680562496185303,
 'ONNX opt CPU Quantized': 5.557553768157959}

总结

综上,得出以下结论:

  • 将Pytorch模型转为ONNX格式,再用ONNX Runtime 进行推理,可以显著提速。本文这里的实验结果,单条数据在CPU上的推理提速约3倍。
  • 优化ONNX模型在OpenMP上运行加速显著。
  • 量化效果提速显著。在ONNX上进行量化,大约可以继续提速2倍,最终取得5.5ms的模型推理性能。
相关文章
|
24天前
|
算法 异构计算
自研分布式训练框架EPL问题之帮助加速Bert Large模型的训练如何解决
自研分布式训练框架EPL问题之帮助加速Bert Large模型的训练如何解决
|
1月前
|
机器学习/深度学习 存储 自然语言处理
【NLP-新闻文本分类】3 Bert模型的对抗训练
详细介绍了使用BERT模型进行新闻文本分类的过程,包括数据集预处理、使用预处理数据训练BERT语料库、加载语料库和词典后用原始数据训练BERT模型,以及模型测试。
37 1
|
2月前
|
机器学习/深度学习 人工智能 自然语言处理
算法金 | 秒懂 AI - 深度学习五大模型:RNN、CNN、Transformer、BERT、GPT 简介
**RNN**,1986年提出,用于序列数据,如语言模型和语音识别,但原始模型有梯度消失问题。**LSTM**和**GRU**通过门控解决了此问题。 **CNN**,1989年引入,擅长图像处理,卷积层和池化层提取特征,经典应用包括图像分类和物体检测,如LeNet-5。 **Transformer**,2017年由Google推出,自注意力机制实现并行计算,优化了NLP效率,如机器翻译。 **BERT**,2018年Google的双向预训练模型,通过掩码语言模型改进上下文理解,适用于问答和文本分类。
118 9
|
1月前
|
数据采集 人工智能 数据挖掘
2021 第五届“达观杯” 基于大规模预训练模型的风险事件标签识别】3 Bert和Nezha方案
2021第五届“达观杯”基于大规模预训练模型的风险事件标签识别比赛中使用的NEZHA和Bert方案,包括预训练、微调、模型融合、TTA测试集数据增强以及总结和反思。
25 0
|
2月前
|
数据采集 自然语言处理 PyTorch
AIGC之BERT模型
7月更文挑战第5天
|
3月前
|
机器学习/深度学习 自然语言处理 TensorFlow
使用Python实现深度学习模型:BERT模型教程
使用Python实现深度学习模型:BERT模型教程
119 0
|
3月前
|
机器学习/深度学习 自然语言处理 PyTorch
【自然语言处理NLP】Bert预训练模型、Bert上搭建CNN、LSTM模型的输入、输出详解
【自然语言处理NLP】Bert预训练模型、Bert上搭建CNN、LSTM模型的输入、输出详解
80 0
|
4月前
|
机器学习/深度学习 人工智能 开发工具
如何快速部署本地训练的 Bert-VITS2 语音模型到 Hugging Face
Hugging Face是一个机器学习(ML)和数据科学平台和社区,帮助用户构建、部署和训练机器学习模型。它提供基础设施,用于在实时应用中演示、运行和部署人工智能(AI)。用户还可以浏览其他用户上传的模型和数据集。Hugging Face通常被称为机器学习界的GitHub,因为它让开发人员公开分享和测试他们所训练的模型。 本次分享如何快速部署本地训练的 Bert-VITS2 语音模型到 Hugging Face。
如何快速部署本地训练的 Bert-VITS2 语音模型到 Hugging Face
|
4月前
|
PyTorch 算法框架/工具
Bert Pytorch 源码分析:五、模型架构简图 REV1
Bert Pytorch 源码分析:五、模型架构简图 REV1
68 0
|
4月前
|
JavaScript
Bert-vits2-v2.2新版本本地训练推理整合包(原神八重神子英文模型miko)
近日,Bert-vits2-v2.2如约更新,该新版本v2.2主要把Emotion 模型换用CLAP多模态模型,推理支持输入text prompt提示词和audio prompt提示语音来进行引导风格化合成,让推理音色更具情感特色,并且推出了新的预处理webuI,操作上更加亲民和接地气。
Bert-vits2-v2.2新版本本地训练推理整合包(原神八重神子英文模型miko)