MLIR Inference Code


서론

이 장은 ONNX-MLIR을 통해 생성된 공유 라이브러리(.so)를 가지고 추론하는 코드를 공유한다.

목차

  1. ONNX Inference Code
  2. MLIR Inferece Code
  3. Pytorch Inference Code

ONNX Inference Code

Code
import cv2
import onnx
import numpy as np
import os
import onnxruntime
import time


def get_image(image_dirs) :
    image_list = []
    for roots, dirs, files in os.walk(image_dirs) :
        for file in files :
            image_dir = os.path.join(roots, file)
            if image_dir.endswith("png") or image_dir.endswith("jpg") or image_dir.endswith("JPEG") :
                image_list.append(image_dir)

    return image_list



def preprocess_image(image_path) :
    image_path = image_path
    image = cv2.imread(image_path, 1) #image read
    image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
    image_data = cv2.resize(image, (256, 256), interpolation=cv2.INTER_LINEAR).astype(np.float32) # cv2.INTER_LINEAR
    image_data = image_data[16:240, 16:240, :].copy()
    
    image_data = image_data.transpose([2, 0, 1]) # C, H, W
    mean = np.array([0.079, 0.05, 0]) + 0.406 # 0.485, 0.456, 0.406
    std = np.array([0.005, 0, 0.001]) + 0.224 #0.229, 0.224, 0.225

    for channel in range(image_data.shape[0]): 
        image_data[channel, :, :] = (image_data[channel, :, :] / 255 - mean[channel]) / std[channel] #RGB

    image_data = np.expand_dims(image_data, axis=0)
    
    return image_data


def softmax(x):
    e_x = np.exp(x - np.max(x))
    return e_x / e_x.sum()


with open("imagenet_classes.txt", "r") as f:
    categories = [s.strip() for s in f.readlines()]


model_path = "./mobilenetv2-7.onnx"


data = "./parrot.jpg"
#image = get_image(data)
input_data = preprocess_image(data)


session = onnxruntime.InferenceSession(model_path)
input_name = session.get_inputs()[0].name
output_name = session.get_outputs()[0].name


output = session.run([output_name], {input_name:input_data})[0]
output = output.flatten()
output = softmax(output) # this is optional

top1 = np.argmax(output)

print(f"{categories[top1]},{output[top1]}")

MLIR Inferece Code

You need (.so) file

Code
import numpy as np
from PyRuntime import OMExecutionSession
import cv2

with open("imagenet_classes.txt", "r") as f :
    categories = [s.strip() for s in f.readlines()]


def softmax(x):
    e_x = np.exp(x - np.max(x))
    return e_x / e_x.sum()

def get_image(image_dirs) :
    image_list = []
    for roots, dirs, files in os.walk(image_dirs) :
        for file in files :
            image_dir = os.path.join(roots, file)
            if image_dir.endswith("png") or image_dir.endswith("jpg") or image_dir.endswith("JPEG") :
                image_list.append(image_dir)

    return image_list

def preprocess_image(image_path) :
    image_path = image_path
    image = cv2.imread(image_path, 1) #image read
    image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
    image_data = cv2.resize(image, (256, 256), interpolation=cv2.INTER_LINEAR).astype(np.float32) # cv2.INTER_LINEAR
    image_data = image_data[16:240, 16:240, :].copy()
    
    image_data = image_data.transpose([2, 0, 1]) # C, H, W
    mean = np.array([0.079, 0.05, 0]) + 0.406 # 0.485, 0.456, 0.406
    std = np.array([0.005, 0, 0.001]) + 0.224 #0.229, 0.224, 0.225

    for channel in range(image_data.shape[0]): 
        image_data[channel, :, :] = (image_data[channel, :, :] / 255 - mean[channel]) / std[channel] #RGB
        
    image_data = np.expand_dims(image_data, axis=0)
    image_data = np.ascontiguousarray(image_data.data)

    return image_data


model = './mobilenetv2-7.so' # LeNet from ONNX Zoo compiled with onnx-mlir

data = "./parrot.jpg"
#image = get_image(data)
input_data = preprocess_image(data)


session = OMExecutionSession(shared_lib_path=model)

print("input signature in json", session.input_signature())
print("output signature in json",session.output_signature())
print(input_data.shape)
outputs = session.run(input=[input_data])


outputs = softmax(outputs[0][0])
idx = np.argmax(outputs)
print(f"Label: {categories[idx]}, score: {outputs[idx]}")

Pytorch Inference Code

Code
import torch
from PIL import Image
from torchvision import transforms
import argparse

def main():
    parser = argparse.ArgumentParser(formatter_class=argparse.ArgumentDefaultsHelpFormatter)

    parser.add_argument(
      '-m', '--image', required=True, help='File path of image file.')
    parser.add_argument(
      '-l', '--label', help='File path of label file.')

    args = parser.parse_args()

    filename = args.image
    label = args.label

    # 카테고리 읽어들이기
    # with open("imagenet_classes.txt", "r") as f:
    #     categories = [s.strip() for s in f.readlines()]
    #filename = "./parrot.jpg"

    #카테고리 읽어들이기
    with open(label, "r") as f:
        categories = [s.strip() for s in f.readlines()]


    preprocess = transforms.Compose([
        transforms.Resize(256),
        transforms.CenterCrop(224),
        transforms.ToTensor(),
        transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]),
    ])

    input_image = Image.open(filename)

    input_tensor = preprocess(input_image)
    input_batch = input_tensor.unsqueeze(0) # 모델에서 요구하는 형태의 미니배치 생성

    model = torch.hub.load('pytorch/vision:v0.10.0', 'mobilenet_v2', pretrained=True)
    model.eval()

    if torch.cuda.is_available():
        input_batch = input_batch.to('cuda')
        model.to('cuda')

    with torch.no_grad():
        output = model(input_batch)

    print(output[0])
    probabilities = torch.nn.functional.softmax(output[0], dim=0)
    #print(probabilities)

    top5_prob, top5_catid = torch.topk(probabilities, 5)
    for i in range(top5_prob.size(0)):
        print(f"{categories[top5_catid[i]]} {top5_prob[i].item()}")


if name == 'main':
    main()