저번 글에 이어 이번에는 OpenVINO모델을 Inference하는 방법에 대해 설명드리도록 하겠습니다.
1. OpenVINO Runtime
OpenVINO (IR)모델을 inference할 수 있도록 하는 것이 OpenVINO runtime입니다.
OpenVINO runtime은 C, python의 binding과 함께 C++ library로 구현되어 있습니다. 그리고 위 그림에서 알 수 있듯이 OpenVINO runtime을 통해 IR모델 뿐만아니라 ONNX, PaddlePaddle(바이두)모델도 Inference가능하도록 API를 제공합니다. 또한 plugin architecture를 사용하기 때문에 해당 plugin들은 각 hardware device에 맞춰진 complete한 구현이 되어있습니다.
OpenVINO runtime을 사용하기 위해서 openvino PyPI을 설치하였습니다.
2. OpenVINO Inference
2.1 환경 설정
이전 글에서 생성한 yolov7 OpenVINO모델을 사용하여 infernece를 진행할 것이며 inference환경은 다음과 같습니다.
- openvino: 2022.1.0 (from PypI)
- CPU: Intel(R) Xeon(R) Gold 5120 CPU @ 2.20GHz (가상 core수: 56)
- Model: yolov7 OpenVINO model
- yolov7.xml
- yolov7.bin
2.2 Load OpenVINO model
먼저 OpenVINO model을 load해봅니다.
from openvino.runtime import Core
model_path = "./yolov7_openvino/yolov7.xml"
ie = Core() # initialize inference engine
network = ie.read_model(model=model_path, weights=Path(model_path).with_suffix('.bin'))
executable_network = ie.compile_model(model=network, device_name="CPU")
ie=Core()
- inference engine을 초기화 함
ie.read_model()
- Core클래스 함수의 read_model함수로 OpenVINO model을 read함
- Model인자의 값으로 model topology가 담긴 xml파일을, weights에는 weight(bias) binary 파일을 넣어줌
ie.compile_model()
- 지정한 device(CPU)에서 model을 compile시켜 inference가능한 형태로 만들어 줌
2.3 Inference OpenVINO model
im = np.random.randn(1,3,640,640) #random input
output_layer = next(iter(executable_network.outputs)) # OpenVINO model의 output layer를 가져옴
y = executable_network([im])[output_layer] # Inference 실행하여 output_layer에 해당하는 output을 y에 할당
next(iter(executable_network.outputs))
- yolov7 OpenVINO모델의 outputs중 가장 첫 번째 output을 가져와 output_layer에 할당 (아래 사진 참조)
executable_network([im])[output_layer]
- Inference 실행하여 output_layer에 해당하는 output을 y에 할당
2.4 Torch와 OpenVINO 모델 inference time 비교
OpenVINO모델로 inference해보았으니 Torch모델과 비교했을 때 Intel cpu에서 얼마나 빨라는 지 확인해보았습니다. 사용한 cpu는 Intel(R) Xeon(R) Gold 5120 CPU @ 2.20GHz (가상 core수: 56)이며 총 50번의 inference에 대해 평균을 내어 결과를 도출하였습니다. Torch, OpenVINO 모델 모두 weight의 data type은 FP32입니다. OpenVINO 모델은 여기서 다운 가능하며 Torch모델은 yolov7 공식 repo에서 받으시면 됩니다.
start = time.time()
y = executable_network([im])[output_layer
prinf(f'time lapse: {time.time()-start}')
Model | File size(MB) | Inference time (s) |
Yolov7 Torch | 147.7 | 1.093 |
Yolov7 OpenVINO | 148.1 | 0.118 |
두 모델의 file size는 비슷한데 Inference time의 경우에는 OpenVINO모델이 10배정도 빠른 것을 알 수 있다!!
2.5 Batch 수에 따른 Inference time비교
from openvino.runtime import Core, PartialShape
ie = Core()
network = ie.read_model(model=model_path, weights=Path(model_path).with_suffix('.bin'))
batch = 2
inputs = next(iter(network.inputs))
new_shape = PartialShape([batch, 3, 640, 640]) # batch 2
network.reshape({inputs.any_name: new_shape}) # reshape batch size of input
executable_network = ie.compile_model(model=network, device_name="CPU")
im = np.random.randn(batch, 3, 640, 640)
output_layer = next(iter(executable_network.outputs))
y = executable_network([im])[output_layer]
PartialShape
과 network.reshape
을 통해 network의 input batch size를 변경 가능합니다.
위의 코드는 batch가 2일 경우입니다. 위의 코드를 기반으로 Batch가 1, 2, 4, 8인 경우를 모두 측정하여 아래와 같은 결과를 보여드립니다. (50번의 inference에 대해 average하였습니다.)
Batch size | Inference time (s) |
1 | 0.118 |
2 | 0.229 |
4 | 0.480 |
8 | 0.935 |
결과표를 보시면 아시겠지만 batch 수에 비례하여 inference time이 늘어나는 것을 확인 가능합니다. (완전한 정비례는 아니네요..)
'AI Engineering > OpenVINO' 카테고리의 다른 글
OpenVINO 뽀개기 (3) OpenVINO Quantization (0) | 2022.08.22 |
---|---|
OpenVINO 뽀개기 (1) OpenVINO 이해 및 변환 (0) | 2022.08.14 |