一.简单说明
openvino是Intel公司为了加速模型推理而推出的一款工具,对于一些Intel公司的CPU和GPU上运行模型有不错的加速效果。
二.调用库推理
如果要对pycharm导出的pt模型部署到Intel公司的芯片上运行可以使用openvino将模型转化为xml+bin格式的文件再用openvino第三方库来调用推理。
三.主要讲解openvino量化pytoch模型,然后使用openvino调用推理:
1.pycharm中安装openvino
可以直接切换到python环境,运行pip install openvino,推荐最新版,老版本经常改动,很多方法经常变动。
本篇文章以2025.1.0为例来说明。
2.pt文件转onnx
此篇文章不做说明,一般是调用torch.onnx.export此方法转,会生成onnx文件。
3.onnx文件转xml+bin
下面会附上源码,只需要简单调用openvino.runtime里面的Core和serialize即可,注意不要使用from openvino.inference_engine import IECore这种,否则很可能报错。具体原因不想深究,总之我的量化和推理过程不需要用到openvino.inference_engine模块。
代码如下:
from openvino.runtime import Core
from openvino.runtime import serialize
ie = Core()
onnx_model_path = r"../_fp32.onnx"
model_onnx = ie.read_model(model=onnx_model_path)
# compiled_model_onnx = ie.compile_model(model=model_onnx, device_name="CPU")
serialize(model=model_onnx, xml_path="model.xml", bin_path="model.bin",
version="UNSPECIFIED")
4.如果需要量化,对xml+bin量化
下面的input_data 的取值范围和模型形状需要改为你自己的数据的对应范围和形状,前处理和推理时一致即可。完成量化后直接就是int8的模型,具体能不能在CPU上运行需要对应机器的CPU支持VNNI指令集。需要用到nncf,直接pip install nncf即可。
import numpy as np
import torch
import openvino as ov
import nncf
from openvino.runtime import serialize
if __name__ == '__main__':
input_data = np.random.randint(0, 101, size=(32, 3, 256, 256))
input_data_tensor = torch.tensor(input_data / 255.0, dtype=torch.float32) # 前处理
nncf_calibration_dataset = nncf.Dataset(input_data_tensor.unsqueeze_(0), None)
core = ov.Core()
ov_model = core.read_model("./model.xml")
quantized_model = nncf.quantize(
ov_model, nncf_calibration_dataset, preset=nncf.QuantizationPreset.MIXED, subset_size=300
)
nncf_int8_path = r"./model_int8.xml"
serialize(quantized_model, nncf_int8_path)
4.openvino推理调用xml+bin文件
注意xml和bin路径一致即可,推理代码如下(此代码只做示例,具体逻辑请自行修改),openvino推理加速主要针对的intel的芯片:
import time
import cv2
import numpy as np
import os
import torch
import openvino as ov
class InferPipeline(object):
def __init__(self, input_size=256):
self.input_size = input_size
core = ov.Core()
self.device=torch.device("cpu")#torch.device("cuda")if(torch.cuda.is_available())else torch.device("cpu")
self.core_device="CPU"#GPU
# 初始化 Inference Engine
ov_config={}
det_ov_model = core.read_model("./pretrain/openvino/model.xml")
self.model = core.compile_model(det_ov_model, self.core_device, ov_config)
@torch.no_grad()
def process(self, img):
self.height, self.width = img.shape[:2]
img = (img / 255.0).astype(np.float32)
img = cv2.resize(img, (self.input_size, self.input_size)).transpose((2, 0, 1))[None,...]
start_time=time.time()
# 执行推理
output_data = self.model(np.ascontiguousarray(img))
print(time.time()-start_time)
return output_data
model_class=InferPipeline()
path=r"./assets/1facefusion_new.jpg"
basename=os.path.basename(path)
img = cv2.imread(path)
image_out = model_class.process(img)
##todo