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

本文涉及的产品
实时计算 Flink 版,5000CU*H 3个月
检索分析服务 Elasticsearch 版,2核4GB开发者规格 1个月
实时数仓Hologres,5000CU*H 100GB 3个月
简介: 本文紧接之前的一篇文章如何用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的模型推理性能。
相关文章
|
2月前
|
自然语言处理 PyTorch 算法框架/工具
掌握从零到一的进阶攻略:让你轻松成为BERT微调高手——详解模型微调全流程,含实战代码与最佳实践秘籍,助你应对各类NLP挑战!
【10月更文挑战第1天】随着深度学习技术的进步,预训练模型已成为自然语言处理(NLP)领域的常见实践。这些模型通过大规模数据集训练获得通用语言表示,但需进一步微调以适应特定任务。本文通过简化流程和示例代码,介绍了如何选择预训练模型(如BERT),并利用Python库(如Transformers和PyTorch)进行微调。文章详细说明了数据准备、模型初始化、损失函数定义及训练循环等关键步骤,并提供了评估模型性能的方法。希望本文能帮助读者更好地理解和实现模型微调。
86 2
掌握从零到一的进阶攻略:让你轻松成为BERT微调高手——详解模型微调全流程,含实战代码与最佳实践秘籍,助你应对各类NLP挑战!
|
2月前
|
机器学习/深度学习 自然语言处理 知识图谱
|
2月前
|
机器学习/深度学习 自然语言处理 算法
[大语言模型-工程实践] 手把手教你-基于BERT模型提取商品标题关键词及优化改进
[大语言模型-工程实践] 手把手教你-基于BERT模型提取商品标题关键词及优化改进
189 0
|
3月前
|
搜索推荐 算法
模型小,还高效!港大最新推荐系统EasyRec:零样本文本推荐能力超越OpenAI、Bert
【9月更文挑战第21天】香港大学研究者开发了一种名为EasyRec的新推荐系统,利用语言模型的强大文本理解和生成能力,解决了传统推荐算法在零样本学习场景中的局限。EasyRec通过文本-行为对齐框架,结合对比学习和协同语言模型调优,提升了推荐准确性。实验表明,EasyRec在多个真实世界数据集上的表现优于现有模型,但其性能依赖高质量文本数据且计算复杂度较高。论文详见:http://arxiv.org/abs/2408.08821
77 7
|
2月前
|
机器学习/深度学习 人工智能 自然语言处理
【AI大模型】BERT模型:揭秘LLM主要类别架构(上)
【AI大模型】BERT模型:揭秘LLM主要类别架构(上)
|
4月前
|
算法 异构计算
自研分布式训练框架EPL问题之帮助加速Bert Large模型的训练如何解决
自研分布式训练框架EPL问题之帮助加速Bert Large模型的训练如何解决
|
4月前
|
数据采集 人工智能 数据挖掘
2021 第五届“达观杯” 基于大规模预训练模型的风险事件标签识别】3 Bert和Nezha方案
2021第五届“达观杯”基于大规模预训练模型的风险事件标签识别比赛中使用的NEZHA和Bert方案,包括预训练、微调、模型融合、TTA测试集数据增强以及总结和反思。
46 0
|
7月前
|
机器学习/深度学习 人工智能 开发工具
如何快速部署本地训练的 Bert-VITS2 语音模型到 Hugging Face
Hugging Face是一个机器学习(ML)和数据科学平台和社区,帮助用户构建、部署和训练机器学习模型。它提供基础设施,用于在实时应用中演示、运行和部署人工智能(AI)。用户还可以浏览其他用户上传的模型和数据集。Hugging Face通常被称为机器学习界的GitHub,因为它让开发人员公开分享和测试他们所训练的模型。 本次分享如何快速部署本地训练的 Bert-VITS2 语音模型到 Hugging Face。
如何快速部署本地训练的 Bert-VITS2 语音模型到 Hugging Face
|
7月前
|
PyTorch 算法框架/工具
Bert Pytorch 源码分析:五、模型架构简图 REV1
Bert Pytorch 源码分析:五、模型架构简图 REV1
100 0
|
7月前
|
PyTorch 算法框架/工具
Bert Pytorch 源码分析:五、模型架构简图
Bert Pytorch 源码分析:五、模型架构简图
76 0