import and contansts¶

In [1]:
import common
import ktc
import cv2
import numpy as np
from IPython.display import Image as IpyImage, display
import cv2_imgproc as cv2imgproc
import yunet_utils as yunet
IMAGE_DIR=f"/workspace/host/notebook/quantizationImages"
MODEL_DIR=f"/workspace/host/notebook/models/yunet"
/workspace/miniconda/lib/python3.7/site-packages/numpy/__init__.py:156: UserWarning: mkl-service package failed to import, therefore Intel(R) MKL initialization ensuring its correct out-of-the box operation under condition when Gnu OpenMP had already been loaded by Python process is not assured. Please install mkl-service package, see http://github.com/IntelPython/mkl-service
  from . import _distributor_init
Using TensorFlow backend.

function show opencv image for notebook¶

In [2]:
def imshow(img, width=None):
    _, encoded = cv2.imencode(".jpg", img)
    display(IpyImage(data=encoded, width=width))

model argments¶

In [3]:
modelSize=(360,360)
platform=720
prior = yunet.getPriors(modelSize)
os1, os2, os3, os4 = yunet.getOutputSize(modelSize[::-1])
modelSizeStr=f"{modelSize[0]}x{modelSize[1]}"
modelOnnxPath = f"{MODEL_DIR}/yunet-{modelSizeStr}-sim-cutPost-opt.onnx"
modelBiePath = f"{MODEL_DIR}/yunet-{modelSizeStr}-sim-cutPost-opt.quan.wqbi.bie"
modelNefPath = f"{MODEL_DIR}/yunet-{modelSizeStr}-sim-cutPost-opt-kl{platform}.nef"
print(f"model Size = {repr(modelSize)}")
print(f"platform = {repr(platform)}")
print(f"prior = {repr(prior.shape)}")

print(f"output size = {repr((os1, os2, os3, os4))}")
print(f"model Onnx Path = {repr(modelOnnxPath)}")
print(f"model Bie Path = {repr(modelBiePath)}")
print(f"model Nef Path = {repr(modelBiePath)}")
model Size = (360, 360)
platform = 720
prior = (7360, 4)
output size = ((45, 45), (22, 22), (11, 11), (5, 5))
model Onnx Path = '/workspace/host/notebook/models/yunet/yunet-360x360-sim-cutPost-opt.onnx'
model Bie Path = '/workspace/host/notebook/models/yunet/yunet-360x360-sim-cutPost-opt.quan.wqbi.bie'
model Nef Path = '/workspace/host/notebook/models/yunet/yunet-360x360-sim-cutPost-opt.quan.wqbi.bie'

load image¶

In [4]:
imagePath = f"{IMAGE_DIR}/image_10.jpg"
imageData = cv2.imread(imagePath)
imageSize = cv2imgproc.size(imageData)
imageARSize = cv2imgproc.getKARSizeByFitMaxSize(imageSize, modelSize)
print(f"image Path = {imagePath}")
print(f"image Shape = {imageData.shape}")
print(f"image Size = {imageSize}")
print(f"image Aspect Ratio Size = {imageARSize}")
imshow(width=200, img=imageData)
image Path = /workspace/host/notebook/quantizationImages/image_10.jpg
image Shape = (1537, 1024, 3)
image Size = (1024, 1537)
image Aspect Ratio Size = (239, 360)

perprocess image¶

In [5]:
# preprocess
inputImageData = cv2.resize(imageData, imageARSize)
inputImageData = cv2.copyMakeBorder(
    inputImageData,
    0, modelSize[1]-imageARSize[1],
    0, modelSize[0]-imageARSize[0],
    cv2.BORDER_CONSTANT, value=(0)
)
imshow(width=200, img=inputImageData)
inputData = cv2.cvtColor(inputImageData, cv2.COLOR_BGR2RGB)
inputData = inputImageData.astype(np.float32)
inputData = np.expand_dims(inputData, axis=0)
print(inputData.shape)
(1, 360, 360, 3)

kneron inference on Onnx¶

In [6]:
# onnx file
onnxOutputData = ktc.kneron_inference([inputData], onnx_file=modelOnnxPath, input_names=["input"], platform=platform, radix=-1)

kneron inference on Bie file¶

In [7]:
bieOutputData = ktc.kneron_inference([inputData], bie_file=modelBiePath, input_names=["input"], platform=platform, radix=-1)
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
/tmp/ipykernel_19034/987768876.py in <module>
----> 1 bieOutputData = ktc.kneron_inference([inputData], bie_file=modelBiePath, input_names=["input"], platform=platform, radix=-1)

/workspace/E2E_Simulator/python_flow/kneron_inference.py in kneron_inference(pre_results, nef_file, onnx_file, bie_file, model_id, input_names, radix, data_type, reordering, ioinfo_file, dump, platform)
     59 
     60             input_files = dynasty.prep_dynasty(
---> 61                 pre_results, input_folder, output_folder, input_names, platform, True, str(bie))
     62             output = dynasty.dynasty_inference(
     63                 str(bie), "bie", str(platform), data_type, input_files, input_names,

/workspace/E2E_Simulator/python_flow/dynasty/dynasty.py in prep_dynasty(pre_results, input_folder, output_folder, input_names, platform, is_bie, model_file)
     89             np_radix = np.array([*radix[1:], radix[0]])  # set to channel last to match input
     90             np_radix = np.broadcast_to(np_radix, (1, height, width, channel))
---> 91             np_radix = np.power(2, np_radix)
     92 
     93             new_result = result * np_radix

ValueError: Integers to negative integer powers are not allowed.

kneron inference on Nef file¶

In [8]:
nefOutputData = ktc.kneron_inference([inputData], nef_file=modelNefPath, input_names=["input"], platform=platform, radix=-1)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
/tmp/ipykernel_19034/3508556893.py in <module>
----> 1 nefOutputData = ktc.kneron_inference([inputData], nef_file=modelNefPath, input_names=["input"], platform=platform, radix=-1)

/workspace/E2E_Simulator/python_flow/kneron_inference.py in kneron_inference(pre_results, nef_file, onnx_file, bie_file, model_id, input_names, radix, data_type, reordering, ioinfo_file, dump, platform)
     39             platform, model_name, input_folder, output_folder = nef.setup_nef(nef_path, model_id)
     40             input_files = nef.prep_csim_inputs(
---> 41                 pre_results, input_folder, str(platform), nef_path.parent, model_name)
     42             output = nef.nef_inference(
     43                 model_name, str(platform), data_type, nef_path.parent, input_files, input_folder,

/workspace/E2E_Simulator/python_flow/nef/nef.py in prep_csim_inputs(pre_results, input_folder, platform, nef_folder, model_name)
    156 
    157         radix = utils.get_radix(setup, index, str(platform))
--> 158         utils.convert_pre_numpy_to_rgba(result, input_file, radix, platform, setup, index)
    159 
    160     return input_files

/workspace/E2E_Simulator/python_flow/utils/utils.py in convert_pre_numpy_to_rgba(data, output, radix, platform, setup_file, input_num)
    263     # conversion for CSIM/Dynasty bit-match purposes and rounding issues
    264     if new_data.dtype == np.float64 or new_data.dtype == np.float32:
--> 265         new_data *= (1 << radix)
    266     new_data = np.round(new_data)
    267     new_data = np.clip(new_data, -128, 127).astype(np.int8)

TypeError: ufunc 'multiply' output (typecode 'O') could not be coerced to provided output parameter (typecode 'f') according to the casting rule ''same_kind''

onnxRT inference on same onnx model for comparison¶

In [9]:
import onnxruntime
onnxSession = onnxruntime.InferenceSession(modelOnnxPath, providers=['CPUExecutionProvider'])
onnxRTOutput = onnxSession.run(
    ["output_1", "output_2", "output_3", "output_4"],
    {"input": np.transpose(inputData, [0, 3, 1, 2])}
)
In [10]:
def postProcess(outputData, targetImag):
    outputDataReshaped = np.concatenate([
        outputData[0].reshape((1,51,*os1)).transpose((0,2,3,1)).flatten(),
        outputData[1].reshape((1,34,*os2)).transpose((0,2,3,1)).flatten(),
        outputData[2].reshape((1,34,*os3)).transpose((0,2,3,1)).flatten(),
        outputData[3].reshape((1,51,*os4)).transpose((0,2,3,1)).flatten()
    ]).reshape((len(prior), 17))
    locData = outputDataReshaped[:,0:14].copy()
    confData = outputDataReshaped[:,14:16].copy()
    confData[:] = yunet.softmax(confData, axis=1)
    iouData = outputDataReshaped[:,16].copy()
    decodedData = yunet.decodeRawFaceDataList(modelSize, confData, iouData, locData, prior)
    dets = yunet.nms(decodedData)
    bboxes = dets[:,:4].astype(int)
    landmarks = dets[:,4:14].reshape(( -1, 5, 2)).astype(int)
    scores = dets[:,14]
    return common.bboxVisualize(inputImageData, bboxes, landmarks, landmark_colors=yunet.FACE_LANDMARK_COLORS)

Visualize result for kneron inference on onnx¶

In [11]:
onnxVisualImageData = postProcess(onnxOutputData, inputImageData)
imshow(width=500, img=onnxVisualImageData)

Visualize result for kneron inference on onnx¶

In [12]:
onnxRTVisualImageData = postProcess(onnxRTOutput, inputImageData)
imshow(width=500, img=onnxRTVisualImageData)

cat kneron-tool-chain version and runnung kneron_inference signature¶

In [13]:
!cat /workspace/version.txt
kneron/toolchain:v0.17.2
In [14]:
!cat -n {ktc.kneron_inference.__code__.co_filename} | head -n 3
     1	"""
     2	Generic inference function for ONNX, BIE, or NEF model.
     3	"""
In [15]:
!cat -n {ktc.kneron_inference.__code__.co_filename} | head -n 34 | tail -n 21
    14	def kneron_inference(pre_results, nef_file="", onnx_file="", bie_file="", model_id=None,
    15	                     input_names=[], radix=8, data_type="float", reordering=[],
    16	                     ioinfo_file="", dump=False, platform=520):
    17	    """Performs inference on the input model given the specified parameters.
    18	
    19	    Input pre_results should be in format (1, h, w, c).
    20	
    21	    Arguments:
    22	        pre_results: List of NumPy arrays in channel last format from preprocessing
    23	        nef_file: Path to NEF model for inference
    24	        onnx_file: Path to ONNX model for inference, unused if nef_file is specified
    25	        bie_file: Path to BIE model for inference, unused if nef_file/onnx_file is specified
    26	        model_id: Integer of model to run inference, only necessary for NEF with multiple models
    27	        input_names: List of input node names of BIE/ONNX model, unused if nef_file is specified
    28	        radix: Integer radix to convert from float to fixed input, DEPRECATED
    29	        data_type: String format of the resulting output, "fixed" or "float"
    30	        dump: Boolean flag to dump intermediate nodes
    31	        reordering: List of node names/integers specifying the output order
    32	        ioinfo_file: String path to file mapping output node number to name, only used with NEF
    33	        platform: Integer indicating platform of Dynasty fixed model
    34	    """
In [16]:
!cat -n {ktc.kneron_inference.__code__.co_filename}
     1	"""
     2	Generic inference function for ONNX, BIE, or NEF model.
     3	"""
     4	import pathlib
     5	import sys
     6	
     7	ROOT_FOLDER = pathlib.Path(__file__).resolve().parent.parent
     8	sys.path.append(str(ROOT_FOLDER))
     9	
    10	import python_flow.common.exceptions as exceptions
    11	import python_flow.nef.nef as nef
    12	import python_flow.dynasty.dynasty as dynasty
    13	
    14	def kneron_inference(pre_results, nef_file="", onnx_file="", bie_file="", model_id=None,
    15	                     input_names=[], radix=8, data_type="float", reordering=[],
    16	                     ioinfo_file="", dump=False, platform=520):
    17	    """Performs inference on the input model given the specified parameters.
    18	
    19	    Input pre_results should be in format (1, h, w, c).
    20	
    21	    Arguments:
    22	        pre_results: List of NumPy arrays in channel last format from preprocessing
    23	        nef_file: Path to NEF model for inference
    24	        onnx_file: Path to ONNX model for inference, unused if nef_file is specified
    25	        bie_file: Path to BIE model for inference, unused if nef_file/onnx_file is specified
    26	        model_id: Integer of model to run inference, only necessary for NEF with multiple models
    27	        input_names: List of input node names of BIE/ONNX model, unused if nef_file is specified
    28	        radix: Integer radix to convert from float to fixed input, DEPRECATED
    29	        data_type: String format of the resulting output, "fixed" or "float"
    30	        dump: Boolean flag to dump intermediate nodes
    31	        reordering: List of node names/integers specifying the output order
    32	        ioinfo_file: String path to file mapping output node number to name, only used with NEF
    33	        platform: Integer indicating platform of Dynasty fixed model
    34	    """
    35	    dump = 2 if dump else 0
    36	    try:
    37	        if nef_file:
    38	            nef_path = pathlib.Path(nef_file).resolve()
    39	            platform, model_name, input_folder, output_folder = nef.setup_nef(nef_path, model_id)
    40	            input_files = nef.prep_csim_inputs(
    41	                pre_results, input_folder, str(platform), nef_path.parent, model_name)
    42	            output = nef.nef_inference(
    43	                model_name, str(platform), data_type, nef_path.parent, input_files, input_folder,
    44	                output_folder, reordering, ioinfo_file, str(dump))
    45	        elif onnx_file:
    46	            onnx = pathlib.Path(onnx_file).resolve()
    47	            input_folder = onnx.parent / "out/onnx/inputs" / onnx.name
    48	            output_folder = onnx.parent / "out/onnx/outputs" / onnx.name
    49	
    50	            input_files = dynasty.prep_dynasty(
    51	                pre_results, input_folder, output_folder, input_names, platform, False, str(onnx))
    52	            output = dynasty.dynasty_inference(
    53	                str(onnx), "Float", str(platform), data_type, input_files, input_names,
    54	                str(output_folder), reordering, dump)
    55	        elif bie_file:
    56	            bie = pathlib.Path(bie_file).resolve()
    57	            input_folder = bie.parent / "out/bie/inputs" / bie.name
    58	            output_folder = bie.parent / "out/bie/outputs" / bie.name
    59	
    60	            input_files = dynasty.prep_dynasty(
    61	                pre_results, input_folder, output_folder, input_names, platform, True, str(bie))
    62	            output = dynasty.dynasty_inference(
    63	                str(bie), "bie", str(platform), data_type, input_files, input_names,
    64	                str(output_folder), reordering, dump)
    65	        else:
    66	            raise exceptions.RequiredConfigError("No input model selected for inference.")
    67	    except exceptions.ConfigError as error:
    68	        sys.exit(error)
    69	
    70	    return output