OpenVINO™ を使用した YOLOv8 の変換と最適化#

この Jupyter ノートブックは、ローカルへのインストール後にのみ起動できます。

GitHub

Ultralytics が開発した YOLOv8 アルゴリズムは、高速、正確、そして使いやすく設計された最先端の (SOTA) モデルであり、幅広いオブジェクト検出、画像セグメント化、および画像分類タスクに最適です。実現に関する詳細については、元のモデル・リポジトリーを参照してください。

このチュートリアルでは、精度制御を伴う量子化を PyTorch YOLOv8 に適用する方法を段階的に説明します。高度な量子化フローにより、精度メトリックを制御しながら 8 ビット量子化をモデルに適用できます。モデル内で最も影響力のある操作を元の精度に維持することで実現されます。このフローは基本的な 8 ビット量子化に基づいており、次のような違いがあります:

  • 精度メトリックを計算するには、キャリブレーション・データセットと評価データセットが必要です。最も単純なケースでは、両方のデータセットが同じデータを参照できます。

  • 評価関数は、精度メトリックの計算に必要です。ソース・フレームワーク使用可能な関数またはカスタム関数を使用できます。

  • 精度の検証は量子化プロセス中に数回実行されるため、精度制御による量子化は基本 8 ビット量子化フローよりも時間がかかる場合があります。

  • 一部の操作が元の精度で維持されるため、結果のモデルでは、基本 8 ビット量子化フローよりもわずかですがパフォーマンス向上が得られます。

: 現在、精度制御を備えた 8 ビット量子化は、OpenVINO 表現のモデルでのみ使用できます。

精度制御を備えた量子化の手順を以下に説明します。

目次:

必要条件#

必要なパッケージをインストールします。

%pip install -q "openvino>=2024.0.0" 
%pip install -q "nncf>=2.9.0" 
%pip install -q "ultralytics==8.1.42" tqdm --extra-index-url https://download.pytorch.org/whl/cpu

Pytorch モデルと OpenVINO IR モデルを取得#

一般に、PyTorch モデルは、モデルの重みを含む状態辞書によって初期化された torch.nn.Module クラスのインスタンスを表します。このリポジトリーで入手可能な、COCO データセットで事前トレーニングされた YOLOv8 nano モデル (yolov8n とも呼ばれる) を使用します。この手順は他の YOLOv8 モデルにも適用できます。事前トレーニングされたモデルを取得する一般的な手順は次のとおりです:

  1. クラスのインスタンスを作成します。

  2. 事前トレーニングされたモデルの重みを含むチェックポイント状態辞書をロードします。

この場合、モデルの作成者は、YOLOv8 モデルを ONNX に変換してから OpenVINO IR に変換できる API を提供します。したがって、これらの手順を手動で実行する必要はありません。

import os 
from pathlib import Path 

from ultralytics import YOLO 
from ultralytics.cfg import get_cfg 
from ultralytics.data.utils import check_det_dataset 
from ultralytics.engine.validator import BaseValidator as Validator 
from ultralytics.utils import DEFAULT_CFG 
from ultralytics.utils import ops 
from ultralytics.utils.metrics import ConfusionMatrix 

ROOT = os.path.abspath("") 

MODEL_NAME = "yolov8n-seg" model = YOLO(f"{ROOT}/{MODEL_NAME}.pt") 
args = get_cfg(cfg=DEFAULT_CFG) 
args.data = "coco128-seg.yaml"
# openvino_notebooks リポジトリーからノートブック・ユーティリティー・スクリプトを取得 
import requests 

r = requests.get( 

url="https://raw.githubusercontent.com/openvinotoolkit/openvino_notebooks/latest/utils/notebook_utils.py", 
) 

open("notebook_utils.py", "w").write(r.text) 

from notebook_utils import download_file
from zipfile import ZipFile 

from ultralytics.data.utils import 

DATASETS_DIR DATA_URL = "https://www.ultralytics.com/assets/coco128-seg.zip" 
CFG_URL = 
"https://raw.githubusercontent.com/ultralytics/ultralytics/8ebe94d1e928687feaa1fee6d5668987df5e43be/ultralytics/datasets/coco128-seg.yaml" # Ultralytics 8.0.43 と互換性のある最後の形式 

OUT_DIR = DATASETS_DIR 

DATA_PATH = OUT_DIR / "coco128-seg.zip" 
CFG_PATH = OUT_DIR / "coco128-seg.yaml" 

download_file(DATA_URL, DATA_PATH.name, DATA_PATH.parent) 
download_file(CFG_URL, CFG_PATH.name, CFG_PATH.parent) 

if not (OUT_DIR / "coco128/labels").exists(): 
    with ZipFile(DATA_PATH, "r") as zip_ref: 
        zip_ref.extractall(OUT_DIR)
'/home/maleksandr/test_notebooks/ultrali/datasets/coco128-seg.zip' already exists.
/home/maleksandr/test_notebooks/ultrali/datasets/coco128-seg.yaml: 0%|          | 0.00/0.98k [00:00<?, ?B/s]

モデルをロードします。

import openvino as ov 

model_path = Path(f"{ROOT}/{MODEL_NAME}_openvino_model/{MODEL_NAME}.xml") 
if not model_path.exists(): 
    model.export(format="openvino", dynamic=True, half=False) 

ov_model = ov.Core().read_model(model_path)

バリデーターとデータローダーを定義#

元のモデル・リポジトリーは、精度検証パイプラインを表す Validator ラッパーを使用します。データローダーと評価メトリックを作成し、データローダーによって生成される各データバッチのメトリックを更新します。加えて、データの前処理と結果の後処理も担当します。クラスの初期化では、構成を提供する必要があります。デフォルトの設定を使用しますが、カスタムデータでテストするにはオーバーライドするいくつかのパラメーターに置き換えることができます。モデルは ValidatorClass メソッドに接続しており、これによりバリデーター・クラスのインスタンスが作成されます。

from ultralytics.data.converter import coco80_to_coco91_class 

validator = model.task_map[model.task]["validator"](args=args) 
validator.data = check_det_dataset(args.data) 
validator.stride = 3 
data_loader = validator.get_dataloader(OUT_DIR / "coco128-seg", 1) 

validator.is_coco = True 
validator.class_map = coco80_to_coco91_class() validator.names = model.model.names 
validator.metrics.names = validator.names 
validator.nc = model.model.model[-1].nc 
validator.nm = 32 
validator.process = ops.process_mask 
validator.plot_masks = []

キャリブレーションと評価データセットの準備#

1 つのデータセットをキャリブレーションと検証データセットとして使用できます。quantization_dataset という名付けます。

from typing import Dict 

import nncf 

def transform_fn(data_item: Dict): 
    input_tensor = validator.preprocess(data_item)["img"].numpy() 
    return input_tensor 

quantization_dataset = nncf.Dataset(data_loader, transform_fn)
INFO:nncf:NNCF が正常に初期化されました。サポートされているフレームワークが検出されました : torch, openvino

評価関数の準備#

from functools import partial 

import torch 
from nncf.quantization.advanced_parameters import AdvancedAccuracyRestorerParameters 

def validation_ac( 
    compiled_model: ov.CompiledModel, 
    validation_loader: torch.utils.data.DataLoader, 
    validator: Validator, 
    num_samples: int = None, 
    log=True, 
) -> float: 
    validator.seen = 0 
    validator.jdict = [] 
    validator.stats = dict(tp_m=[], tp=[], conf=[], pred_cls=[], target_cls=[]) 
    validator.batch_i = 1 
    validator.confusion_matrix = ConfusionMatrix(nc=validator.nc) 
    num_outputs = len(compiled_model.outputs) 

    counter = 0 
    for batch_i, batch in enumerate(validation_loader): 
        if num_samples is not None and batch_i == num_samples: 
            break 
        batch = validator.preprocess(batch) 
        results = compiled_model(batch["img"]) 
        if num_outputs == 1: 
            preds = torch.from_numpy(results[compiled_model.output(0)]) 
        else: 
            preds = [ 
                torch.from_numpy(results[compiled_model.output(0)]), 
                torch.from_numpy(results[compiled_model.output(1)]), 
            ]
        preds = validator.postprocess(preds) 
        validator.update_metrics(preds, batch) 
        counter += 1 
stats = validator.get_stats() 
if num_outputs == 1: 
    stats_metrics = stats["metrics/mAP50-95(B)"] 
else: 
    stats_metrics = stats["metrics/mAP50-95(M)"] 
if log: 
    print(f"Validate: dataset length = {counter}, metric value = {stats_metrics:.3f}") 

    return stats_metrics 

validation_fn = partial(validation_ac, validator=validator, log=False)

精度を制御して量子化を実行#

キャリブレーション・データセットと評価データセットを提供する必要があります。同じデータセットでもかまいません。- パラメーター max_drop は精度低下のしきい値を定義します。量子化プロセスは、評価データセットの精度メトリックの低下が max_drop 未満になると停止します。デフォルト値は 0.01 です。max_drop 値に到達しない場合、NNCF は量子化を停止し、エラーを報告します。

  • drop_type は、精度の低下の計算方法を定義します: ABSOLUTE (デフォルト) または RELATIVE。

  • - ranking_subset_size - 精度低下への影響度に基づいてレイヤーをランク付けするために使用されるサブセットのサイズ。デフォルト値は 300 で、サンプル数が多いほどランクが向上する可能性があります。ここでは、実行を高速化するため値 25 を使用します。

    : 実行には数十分かかる場合があり、最大 15 GB の空きメモリーが必要です

quantized_model = nncf.quantize_with_accuracy_control( 
    ov_model, 
    quantization_dataset, 
    quantization_dataset, 
    validation_fn=validation_fn, 
    max_drop=0.01, 
    preset=nncf.QuantizationPreset.MIXED, 
    subset_size=128, 
    advanced_accuracy_restorer_parameters=AdvancedAccuracyRestorerParameters(ranking_subset_size=25), 
)
Output()
/home/maleksandr/test_notebooks/ultrali/openvino_notebooks/notebooks/quantizing-model-with-accuracy-control/venv/lib/python3.10/site-packages/nncf/experimental/tensor/tensor.py:84: RuntimeWarning: invalid value encountered in multiply 
  return Tensor(self.data * unwrap_tensor_data(other))
Output()
INFO:nncf:Validation of initial model was started 
INFO:nncf:Elapsed Time: 00:00:00 
INFO:nncf:Elapsed Time: 00:00:03 
INFO:nncf:Metric of initial model: 0.3651327608484117 
INFO:nncf:Collecting values for each data item using the initial model 
INFO:nncf:Elapsed Time: 00:00:04 
INFO:nncf:Validation of quantized model was started 
INFO:nncf:Elapsed Time: 00:00:00 
INFO:nncf:Elapsed Time: 00:00:03 
INFO:nncf:Metric of quantized model: 0.34040251506886543 
INFO:nncf:Collecting values for each data item using the quantized model 
INFO:nncf:Elapsed Time: 00:00:04 
INFO:nncf:Accuracy drop: 0.024730245779546245 (absolute) 
INFO:nncf:Accuracy drop: 0.024730245779546245 (absolute) 
INFO:nncf:Total number of quantized operations in the model: 92 
INFO:nncf:Number of parallel workers to rank quantized operations: 1 
INFO:nncf:ORIGINAL metric is used to rank quantizers
Output()
INFO:nncf:Elapsed Time: 00:01:38 
INFO:nncf:Changing the scope of quantizer nodes was started 
INFO:nncf:Reverted 1 operations to the floating-point precision:     __module.model.4.m.0.cv2.conv/aten::_convolution/Convolution 
INFO:nncf:Accuracy drop with the new quantization scope is 0.023408466397916217 (absolute) 
INFO:nncf:Reverted 1 operations to the floating-point precision:     __module.model.18.m.0.cv2.conv/aten::_convolution/Convolution 
INFO:nncf:Accuracy drop with the new quantization scope is 0.024749654890442174 (absolute) 
INFO:nncf:Re-calculating ranking scores for remaining groups
Output()
INFO:nncf:Elapsed Time: 00:01:36 
INFO:nncf:Reverted 1 operations to the floating-point precision:     __module.model.22.proto.cv3.conv/aten::_convolution/Convolution 
INFO:nncf:Accuracy drop with the new quantization scope is 0.023229513575966754 (absolute) 
INFO:nncf:Reverted 2 operations to the floating-point precision:     __module.model.22/aten::add/Add_6 __module.model.22/aten::sub/Subtract 
INFO:nncf:Accuracy drop with the new quantization scope is 0.02425608378963906 (absolute) 
INFO:nncf:Re-calculating ranking scores for remaining groups
Output()
INFO:nncf:Elapsed Time: 00:01:35 
INFO:nncf:Reverted 1 operations to the floating-point precision:     __module.model.6.m.0.cv2.conv/aten::_convolution/Convolution 
INFO:nncf:Accuracy drop with the new quantization scope is 0.023297881500256024 (absolute) 
INFO:nncf:Reverted 2 operations to the floating-point precision:     __module.model.12.cv2.conv/aten::_convolution/Convolution __module.model.12.m.0.cv1.conv/aten::_convolution/Convolution 
INFO:nncf:Accuracy drop with the new quantization scope is 0.021779128052922092 (absolute) 
INFO:nncf:Reverted 2 operations to the floating-point precision:     __module.model.7.conv/aten::_convolution/Convolution 
    __module.model.12.cv1.conv/aten::_convolution/Convolution 
INFO:nncf:Accuracy drop with the new quantization scope is 0.01696486517685941 (absolute) 
INFO:nncf:Reverted 2 operations to the floating-point precision:     __module.model.22/aten::add/Add_7 
    __module.model.22/aten::sub/Subtract_1 
INFO:nncf:Algorithm completed: achieved required accuracy drop 0.005923437521415831 (absolute) 
INFO:nncf:9 out of 92 were reverted back to the floating-point precision:     __module.model.4.m.0.cv2.conv/aten::_convolution/Convolution 
    __module.model.22.proto.cv3.conv/aten::_convolution/Convolution 
    __module.model.6.m.0.cv2.conv/aten::_convolution/Convolution 
    __module.model.12.cv2.conv/aten::_convolution/Convolution 
    __module.model.12.m.0.cv1.conv/aten::_convolution/Convolution 
    __module.model.7.conv/aten::_convolution/Convolution 
    __module.model.12.cv1.conv/aten::_convolution/Convolution 
    __module.model.22/aten::add/Add_7 
    __module.model.22/aten::sub/Subtract_1

元のモデルと量子化されたモデルの精度とパフォーマンスを比較#

これで、元の非量子化 OpenVINO IR モデルと量子化された OpenVINO IR モデルのメトリックを比較して、max_drop を超えていないことを確認できます。

import ipywidgets as widgets 

core = ov.Core() 
device = widgets.Dropdown( 
    options=core.available_devices + ["AUTO"], 
    value="AUTO", 
    description="Device:", 
    disabled=False, 
) 

device
Dropdown(description='Device:', index=4, options=('CPU', 'GPU.0', 'GPU.1', 'GPU.2', 'AUTO'), value='AUTO')
core = ov.Core() 
ov_config = {} 
if device.value != "CPU": 
    quantized_model.reshape({0: [1, 3, 640, 640]}) 
if "GPU" in device.value or ("AUTO" in device.value and "GPU" in core.available_devices): 
    ov_config = {"GPU_DISABLE_WINOGRAD_CONVOLUTION": "YES"} 
quantized_compiled_model = core.compile_model(quantized_model, device.value, ov_config) 
compiled_ov_model = core.compile_model(ov_model, device.value, ov_config) 

pt_result = validation_ac(compiled_ov_model, data_loader, validator) 
quantized_result = validation_ac(quantized_compiled_model, data_loader, validator) 

print(f"[Original OpenVINO]: {pt_result:.4f}") 
print(f"[Quantized OpenVINO]: {quantized_result:.4f}")
Validate: dataset length = 128, metric value = 0.368 
Validate: dataset length = 128, metric value = 0.357 
[Original OpenVINO]: 0.3677 
[Quantized OpenVINO]: 0.3570

そして性能を比較します。

from pathlib import Path 

# モデル・ディレクトリーを設定 
MODEL_DIR = Path("model") 
MODEL_DIR.mkdir(exist_ok=True) 

ir_model_path = MODEL_DIR / "ir_model.xml" 
quantized_model_path = MODEL_DIR / "quantized_model.xml" 

# モデルを保存して、コマンドライン・ベンチマーク・アプリで使用 
ov.save_model(ov_model, ir_model_path, compress_to_fp16=False) 
ov.save_model(quantized_model, quantized_model_path, compress_to_fp16=False)
# 推論オリジナルモデル (OpenVINO IR) 
! benchmark_app -m $ir_model_path -shape "[1,3,640,640]" -d $device.value -api async
[Step 1/11] Parsing and validating input arguments 
[ INFO ] Parsing input parameters 
[Step 2/11] Loading OpenVINO Runtime 
[ WARNING ] Default duration 120 seconds is used for unknown device AUTO 
[ INFO ] OpenVINO: 
[ INFO ] Build .................................2024.0.0-14509-34caeefd078-releases/2024/0 
[ INFO ] 
[ INFO ] Device info: 
[ INFO ] AUTO 
[ INFO ] Build .................................2024.0.0-14509-34caeefd078-releases/2024/0 
[ INFO ] 
[ INFO ] 
[Step 3/11] Setting device configuration 
[ WARNING ] Performance hint was not explicitly specified in command line.Device(AUTO) performance hint will be set to PerformanceMode.THROUGHPUT.
[Step 4/11] Reading model files 
[ INFO ] Loading model files 
[ INFO ] Read model took 13.54 ms 
[ INFO ] Original model I/O parameters: 
[ INFO ] Model inputs: 
[ INFO ] x (node: x) : f32 / [...]/ [?,3,?,?]
[ INFO ] Model outputs: 
[ INFO ]     *NO_NAME* (node: __module.model.22/aten::cat/Concat_8) : f32 / [...]/ [?,116,16..] 
[ INFO ] input.199 (node: __module.model.22.cv4.2.1.act/aten::silu_/Swish_37) : f32 / [...] / [?,32,8..,8..] 
[Step 5/11] Resizing model to match image sizes and given batch 
[ INFO ] Model batch size: 1 
[ INFO ] Reshaping model: 'x': [1,3,640,640] 
[ INFO ] Reshape model took 8.56 ms 
[Step 6/11] Configuring input of the model 
[ INFO ] Model inputs: 
[ INFO ] x (node: x) : u8 / [N,C,H,W] / [1,3,640,640] 
[ INFO ] Model outputs: 
[ INFO ]     *NO_NAME* (node: __module.model.22/aten::cat/Concat_8) : f32 / [...]/ [1,116,8400] 
[ INFO ] input.199 (node: __module.model.22.cv4.2.1.act/aten::silu_/Swish_37) : f32 / [...] / [1,32,160,160] 
[Step 7/11] Loading the model to the device 
[ INFO ] Compile model took 437.16 ms 
[Step 8/11] Querying optimal runtime parameters 
[ INFO ] Model: 
[ INFO ]     NETWORK_NAME: Model0 
[ INFO ]     EXECUTION_DEVICES: ['CPU'] 
[ INFO ]     PERFORMANCE_HINT: PerformanceMode.THROUGHPUT 
[ INFO ]     OPTIMAL_NUMBER_OF_INFER_REQUESTS: 12 
[ INFO ]     MULTI_DEVICE_PRIORITIES: CPU 
[ INFO ]     CPU: 
[ INFO ]       AFFINITY: Affinity.CORE 
[ INFO ]       CPU_DENORMALS_OPTIMIZATION: False 
[ INFO ]       CPU_SPARSE_WEIGHTS_DECOMPRESSION_RATE: 1.0 
[ INFO ]       DYNAMIC_QUANTIZATION_GROUP_SIZE: 0 
[ INFO ]       ENABLE_CPU_PINNING: True 
[ INFO ]       ENABLE_HYPER_THREADING: True 
[ INFO ]       EXECUTION_DEVICES: ['CPU'] 
[ INFO ]       EXECUTION_MODE_HINT: ExecutionMode.PERFORMANCE 
[ INFO ]       INFERENCE_NUM_THREADS: 36 
[ INFO ]       INFERENCE_PRECISION_HINT: <Type: 'float32'> 
[ INFO ]       KV_CACHE_PRECISION: <Type: 'float16'> 
[ INFO ]       LOG_LEVEL: Level.NO 
[ INFO ] NETWORK_NAME: Model0 
[ INFO ] NUM_STREAMS: 12 
[ INFO ]       OPTIMAL_NUMBER_OF_INFER_REQUESTS: 12 
[ INFO ]       PERFORMANCE_HINT: THROUGHPUT 
[ INFO ]       PERFORMANCE_HINT_NUM_REQUESTS: 0 
[ INFO ]       PERF_COUNT: NO 
[ INFO ]       SCHEDULING_CORE_TYPE: SchedulingCoreType.ANY_CORE 
[ INFO ] MODEL_PRIORITY: Priority.MEDIUM 
[ INFO ] LOADED_FROM_CACHE: False 
[Step 9/11] Creating infer requests and preparing input tensors 
[ WARNING ] No input files were given for input 'x'!.This input will be filled with random values! 
[ INFO ] Fill input 'x' with random values 
[Step 10/11] Measuring performance (Start inference asynchronously, 12 inference requests, limits: 120000 ms duration) 
[ INFO ] Benchmarking in inference only mode (inputs filling are not included in measurement loop).
[ INFO ] First inference took 46.51 ms 
[Step 11/11] Dumping statistics report 
[ INFO ] Execution Devices:['CPU'] 
[ INFO ] Count: 16872 iterations 
[ INFO ] Duration: 120117.37 ms 
[ INFO ] Latency: [ INFO ] Median: 85.10 ms 
[ INFO ]     Average: 85.27 ms 
[ INFO ]     Min: 53.55 ms 
[ INFO ]     Max: 108.50 ms 
[ INFO ] Throughput: 140.46 FPS
# 推論量子化モデル (OpenVINO IR) 
! benchmark_app -m $quantized_model_path -shape "[1,3,640,640]" -d $device.value -api async
[Step 1/11] Parsing and validating input arguments 
[ INFO ] Parsing input parameters 
[Step 2/11] Loading OpenVINO Runtime 
[ WARNING ] Default duration 120 seconds is used for unknown device AUTO 
[ INFO ] OpenVINO: 
[ INFO ] Build .................................2024.0.0-14509-34caeefd078-releases/2024/0 
[ INFO ] 
[ INFO ] Device info: 
[ INFO ] AUTO 
[ INFO ] Build .................................2024.0.0-14509-34caeefd078-releases/2024/0 
[ INFO ] 
[ INFO ] 
[Step 3/11] Setting device configuration 
[ WARNING ] Performance hint was not explicitly specified in command line.Device(AUTO) performance hint will be set to PerformanceMode.THROUGHPUT.
[Step 4/11] Reading model files 
[ INFO ] Loading model files 
[ INFO ] Read model took 20.52 ms 
[ INFO ] Original model I/O parameters: 
[ INFO ] Model inputs: 
[ INFO ] x (node: x) : f32 / [...]/ [?,3,?,?]
[ INFO ] Model outputs: 
[ INFO ]     *NO_NAME* (node: __module.model.22/aten::cat/Concat_8) : f32 / [...]/ [?,116,16..]
[ INFO ] input.199 (node: __module.model.22.cv4.2.1.act/aten::silu_/Swish_37) : f32 / [...]/ [?,32,8..,8..]
[Step 5/11] Resizing model to match image sizes and given batch 
[ INFO ] Model batch size: 1 
[ INFO ] Reshaping model: 'x': [1,3,640,640] 
[ INFO ] Reshape model took 11.74 ms 
[Step 6/11] Configuring input of the model 
[ INFO ] Model inputs: 
[ INFO ] x (node: x) : u8 / [N,C,H,W] / [1,3,640,640] 
[ INFO ] Model outputs: 
[ INFO ]     *NO_NAME* (node: __module.model.22/aten::cat/Concat_8) : f32 / [...]/ [1,116,8400] 
[ INFO ] input.199 (node: __module.model.22.cv4.2.1.act/aten::silu_/Swish_37) : f32 / [...]/ [1,32,160,160] 
[Step 7/11] Loading the model to the device 
[ INFO ] Compile model took 711.53 ms 
[Step 8/11] Querying optimal runtime parameters 
[ INFO ] Model: 
[ INFO ]     NETWORK_NAME: Model0 
[ INFO ]     EXECUTION_DEVICES: ['CPU'] 
[ INFO ]     PERFORMANCE_HINT: PerformanceMode.THROUGHPUT 
[ INFO ]     OPTIMAL_NUMBER_OF_INFER_REQUESTS: 12 
[ INFO ]     MULTI_DEVICE_PRIORITIES: CPU 
[ INFO ]     CPU: 
[ INFO ]       AFFINITY: Affinity.CORE 
[ INFO ]       CPU_DENORMALS_OPTIMIZATION: False 
[ INFO ]       CPU_SPARSE_WEIGHTS_DECOMPRESSION_RATE: 1.0 
[ INFO ]       DYNAMIC_QUANTIZATION_GROUP_SIZE: 0 
[ INFO ]       ENABLE_CPU_PINNING: True 
[ INFO ]       ENABLE_HYPER_THREADING: True 
[ INFO ]       EXECUTION_DEVICES: ['CPU'] 
[ INFO ]       EXECUTION_MODE_HINT: ExecutionMode.PERFORMANCE 
[ INFO ]       INFERENCE_NUM_THREADS: 36 
[ INFO ]       INFERENCE_PRECISION_HINT: <Type: 'float32'> 
[ INFO ]       KV_CACHE_PRECISION: <Type: 'float16'> 
[ INFO ]       LOG_LEVEL: Level.NO 
[ INFO ] NETWORK_NAME: Model0 
[ INFO ] NUM_STREAMS: 12 
[ INFO ]       OPTIMAL_NUMBER_OF_INFER_REQUESTS: 12 
[ INFO ]       PERFORMANCE_HINT: THROUGHPUT 
[ INFO ]       PERFORMANCE_HINT_NUM_REQUESTS: 0 
[ INFO ]       PERF_COUNT: NO 
[ INFO ]       SCHEDULING_CORE_TYPE: SchedulingCoreType.ANY_CORE 
[ INFO ] MODEL_PRIORITY: Priority.MEDIUM 
[ INFO ] LOADED_FROM_CACHE: False 
[Step 9/11] Creating infer requests and preparing input tensors 
[ WARNING ] No input files were given for input 'x'!.This input will be filled with random values! 
[ INFO ] Fill input 'x' with random values 
[Step 10/11] Measuring performance (Start inference asynchronously, 12 inference requests, limits: 120000 ms duration) 
[ INFO ] Benchmarking in inference only mode (inputs filling are not included in measurement loop).
[ INFO ] First inference took 35.64 ms 
[Step 11/11] Dumping statistics report 
[ INFO ] Execution Devices:['CPU'] 
[ INFO ] Count: 33564 iterations 
[ INFO ] Duration: 120059.16 ms 
[ INFO ] Latency: 
[ INFO ]     Median: 42.72 ms 
[ INFO ]     Average: 42.76 ms 
[ INFO ]     Min: 23.29 ms 
[ INFO ]     Max: 67.71 ms 
[ INFO ] Throughput: 279.56 FPS