rueki

Pytorch 모델 OpenVINO 변환 및 Optimization 본문

pytorch

Pytorch 모델 OpenVINO 변환 및 Optimization

륵기 2023. 8. 16. 09:01
728x90
반응형

1. OpenVINO 설치

(PIP 기준)

- Windows

python -m venv openvino_env
openvino_env\Scripts\activate
python -m pip install --upgrade pip
pip install openvino-dev==2023.0.1

- Linux

python3 -m venv openvino_env
source openvino_env/bin/activate
python -m pip install --upgrade pip
pip install openvino-dev==2023.0.1

 

 

2. pytorch -> ONNX 변환

pytorch 모델을 onnx float32 type의 모델로 변환 먼저 적용

torch.onnx.export(net, x, onnx_save_path, export_params=True,
                        opset_version=11, do_constant_folding=True,
                        input_names=['input'], output_names=['loc','conf', 'landms'],
                   )

여기서 output_names는 모델의 마지막 layer 단에서 출력을 나타낸다.

만약 single layer만 존재하는 분류 모델이면 클래스 번호만 출력을 뱉어내니 output으로 설정해도 무관.

멀티모달의 경우 혹은 병렬 output은 각 layer마다 output 설정 변경을 하면 된다.

안 해도 큰 문제는 없었음

 

* 그러나 onnx 변환 후 성능은 큰 문제 없으나 나중에 OpenVINO 에서 int8 변환 할 때 성능 저하 크게 올 수 있어서 

   추가 작업 필요

 

-> Torch 모델 weigth를 onnx에 복사해서 초기화 하는 역할 (경험 상 이것이 OpenVino 했을 때 더 좋아짐)

onnx_model = onnx.load(onnx_save_path)
    
for param_name, torch_param in net.state_dict().items():
	for tensor in onnx_model.graph.initializer:
		if tensor.name == param_name:
			tensor.CopyFrom(onnx.helper.make_tensor(tensor.name, tensor.data_type, tensor.dims, torch_param.numpy().flatten()))
onnx.save(onnx_model, onnx_update_path)

 

 

3. ONNX -> OpenVINO

 

토치에서 사용하던 데이터를 nncf 사용해서 calibration data를 만들어야 한다.

import nncf
import openvino.runtime as ov
from openvino.tools.mo import convert_model
from openvino.runtime import Core, Tensor


def transform_fn(data_item):
    # Skip label and add a batch dimension to an image tensor
    images, _ = data_item
    return images

torch_dataset = "torch train 시에 선언한 dataset 사용"
torch_loader = "torch loader 사용"
calibration_dataset = nncf.Dataset(dataloader, transform_fn)

 

만약 float32 형태의 openvino 파일을 만들고 싶다면 하나만 해주면 된다.

ov_model = convert_model(onnx_model_path)

변환한 onnx를 convert 해주면 끝. 그러나 이러면 cpu 사양의 device에 사용하는 의미가 크게 없다.

물론 추론 속도만 줄이길 원한다면 상관 없음.

 

quantized_model = nncf.quantize(ov_model, calibration_dataset , fast_bias_correction=True, subset_size=1200, preset=nncf.QuantizationPreset.MIXED)
ov.serialize(quantized_model, "./quantized_model.xml")

float32 -> int8 type 모델로 양자화 진행, subset_size는 calibration에 사용할 데이터 셋 사이즈를 나타내는데, 많게 설정할수록 시간은 오래걸린다. 성능 비교는 task마다 해보면서 확인하는 것이 좋음

fast bias correction을 False로 두면 성능은 더 좋아지지만 cpu 부하가 걸릴 수 있어서 양자화 진행 중에 먹통 될 수도 있음.

preset에 MixedPreset 사용하면 성능 더 괜찮아진다.

 

 

 

728x90
반응형
Comments