NNCF のトレーニング後の量子化を使用して NLP モデルを量子化#

この Jupyter ノートブックはオンラインで起動でき、ブラウザーのウィンドウで対話型環境を開きます。ローカルにインストールすることもできます。次のオプションのいずれかを選択します:

Google ColabGitHub

このチュートリアルでは、トレーニング後の量子化 API (NNCF ライブラリー) を使用して、BERT として知られる自然言語処理モデルに INT8 量子化を適用する方法を説明します。Microsoft Research Paraphrase Corpus (MRPC) でトレーニングされ、微調整された HuggingFace BERT PyTorch モデルが使用されます。チュートリアルは、カスタムモデルとデータセットに拡張できるように設計されています。これは次の手順で構成されます:

  • BERT モデルと MRPC データセットをダウンロードして準備します。

  • データの読み込みと精度検証の機能を定義します。

  • 量子化用のモデルを準備します。

  • 最適化パイプラインを実行します。

  • 量子化モデルをロードしてテストします。

  • オリジナル、変換、量子化されたモデルのパフォーマンスを比較します。

目次:

%pip install -q "nncf>=2.5.0" 
%pip install -q torch transformers "torch>=2.1" datasets evaluate tqdm --extra-index-url https://download.pytorch.org/whl/cpu 
%pip install -q "openvino>=2023.1.0"
Note: you may need to restart the kernel to use updated packages.
Note: you may need to restart the kernel to use updated packages.
Note: you may need to restart the kernel to use updated packages.

インポート#

import os 
import time 
from pathlib import Path 
from zipfile import ZipFile 
from typing import Iterable 
from typing import Any 

import datasets 
import evaluate 
import numpy as np 
import nncf 
from nncf.parameters import ModelType 
import openvino as ov 
import torch 
from transformers import BertForSequenceClassification, BertTokenizer 

# `notebook_utils` モジュールを取得 
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
2024-07-13 00:54:14.849761: I tensorflow/core/util/port.cc:110] oneDNN custom operations are on.You may see slightly different numerical results due to floating-point round-off errors from different computation orders.To turn them off, set the environment variable TF_ENABLE_ONEDNN_OPTS=0.
2024-07-13 00:54:14.884698: I tensorflow/core/platform/cpu_feature_guard.cc:182] This TensorFlow binary is optimized to use available CPU instructions in performance-critical operations.
To enable the following instructions: AVX2 AVX512F AVX512_VNNI FMA, in other operations, rebuild TensorFlow with the appropriate compiler flags.
2024-07-13 00:54:15.454440: W tensorflow/compiler/tf2tensorrt/utils/py_utils.cc:38] 
TF-TRT Warning: Could not find TensorRT
INFO:nncf:NNCF が正常に初期化されました: torch、tensorflow、onnx、openvinoサポートされているフレームワークが検出されました: torch tensorflow onnx openvino

設定#

# データとモデルのディレクトリー、ソース URL、およびモデルのファイル名を設定
DATA_DIR = "data" 
MODEL_DIR = "model" 
MODEL_LINK = "https://download.pytorch.org/tutorial/MRPC.zip" 
FILE_NAME = MODEL_LINK.split("/")[-1] 
PRETRAINED_MODEL_DIR = os.path.join(MODEL_DIR, "MRPC") 

os.makedirs(DATA_DIR, exist_ok=True) 
os.makedirs(MODEL_DIR, exist_ok=True)

モデルの準備#

以下を実行します:

  • PyTorch による MRPC 用の事前トレーニング済み BERT モデルをダウンロードして解凍します。

  • モデルを OpenVINO 中間表現 (OpenVINO IR) に変換します。

download_file(MODEL_LINK, directory=MODEL_DIR, show_progress=True) 
with ZipFile(f"{MODEL_DIR}/{FILE_NAME}", "r") as zip_ref: 
    zip_ref.extractall(MODEL_DIR)
model/MRPC.zip: 0%|          | 0.00/387M [00:00<?, ?B/s]

元の PyTorch モデルを OpenVINO 中間表現に変換します。

OpenVINO 2023.0 からは、モデル・トランスフォーメーション API を使用してモデルを PyTorch 形式から OpenVINO IR 形式に直接変換できるようになりました。次の PyTorch モデル形式がサポートされています:

  • torch.nn.Module

  • torch.jit.ScriptModule

  • torch.jit.ScriptFunction

MAX_SEQ_LENGTH = 128 
input_shape = ov.PartialShape([1, -1]) 
ir_model_xml = Path(MODEL_DIR) / "bert_mrpc.xml" 
core = ov.Core() 

torch_model = BertForSequenceClassification.from_pretrained(PRETRAINED_MODEL_DIR) torch_model.eval 

input_info = [ 
    ("input_ids", input_shape, np.int64), 
    ("attention_mask", input_shape, np.int64), 
    ("token_type_ids", input_shape, np.int64), 
] 
default_input = torch.ones(1, MAX_SEQ_LENGTH, dtype=torch.int64) 
inputs = { 
    "input_ids": default_input, 
    "attention_mask": default_input, 
    "token_type_ids": default_input, 
} 

# PyTorch モデルを OpenVINO IR FP32 に変換 
if not ir_model_xml.exists(): 
    model = ov.convert_model(torch_model, example_input=inputs, input=input_info) 
    ov.save_model(model, str(ir_model_xml)) 
else: 
    model = core.read_model(ir_model_xml)
警告:tensorflow:インポートを修正してください。モジュール tensorflow.python.training.tracking.base  tensorflow.python.trackable.base に移動されました。古いモジュールはバージョン 2.11 で削除されます。 
[ WARNING ] Please fix your imports.Module %s has been moved to %s.The old module will be deleted in version %s./opt/home/k8sworker/ci-ai/cibuilds/ov-notebook/OVNotebookOps-727/.workspace/scm/ov-notebook/.venv/lib/python3.8/site-packages/transformers/modeling_utils.py:4565: FutureWarning: _is_quantized_training_enabled is going to be deprecated in transformers 4.39.0.Please use model.hf_quantizer.is_trainable instead warnings.warn(

データセットの準備#

MRPC タスク用の一般言語理解評価 (GLUE) データセットを HuggingFace データセットからダウンロードします。次に、HuggingFace の事前トレーニング済み BERT トークナイザーを使用してデータをトークン化します。

def create_data_source(): 
    raw_dataset = datasets.load_dataset("glue", "mrpc", split="validation") 
    tokenizer = BertTokenizer.from_pretrained(PRETRAINED_MODEL_DIR) 

    def _preprocess_fn(examples): 
        texts = (examples["sentence1"], examples["sentence2"]) 
        result = tokenizer(*texts, padding="max_length", max_length=MAX_SEQ_LENGTH, truncation=True) 
        result["labels"] = examples["label"] 
        return result 

    processed_dataset = raw_dataset.map(_preprocess_fn, batched=True, batch_size=1) 

    return processed_dataset 

data_source = create_data_source()

NNCF トレーニング後の量子化 API を使用してモデルを最適化#

NNCF は、精度の低下を最小限に抑えながら、OpenVINO でニューラル・ネットワーク推論を最適化する一連の高度なアルゴリズムを提供します。BERT を最適化するため、ポストトレーニング・モード (微調整パイプラインなし) で 8 ビット量子化を使用します。

最適化プロセスには次の手順が含まれます:

  1. 量子化用のデータセットを作成します。

  2. nncf.quantize を実行して、最適化されたモデルを取得します。

  3. openvino.save_model 関数を使用して OpenVINO IR モデルをシリアル化します。

INPUT_NAMES = [key for key in inputs.keys()] 

def transform_fn(data_item): 
    """ 
    Extract the model's input from the data item. 
    The data item here is the data item that is returned from the data source per iteration. 
    This function should be passed when the data item cannot be used as model's input.
    """ 
    inputs = {name: np.asarray([data_item[name]], dtype=np.int64) for name in INPUT_NAMES} 
    return inputs 

calibration_dataset = nncf.Dataset(data_source, transform_fn) 
# モデルを量子化します。model_type を指定することにより、モデル内の追加のトランスフォーマー・パターンを指定 
quantized_model = nncf.quantize(model, calibration_dataset, 
model_type=ModelType.TRANSFORMER)
Output()
Output()
INFO:nncf:50 ignored nodes were found by name in the NNCFGraph
Output()
Output()
compressed_model_xml = Path(MODEL_DIR) / "quantized_bert_mrpc.xml" 
ov.save_model(quantized_model, compressed_model_xml)

OpenVINO モデルのロードとテスト#

変換されたモデルをロードしてテストするには、次の手順を実行します:

  • モデルをロードし、選択したデバイス用にコンパイルします。

  • 入力を準備します。

  • 推論を実行します。

  • モデルの出力から答えを取得します。

推論デバイスの選択#

OpenVINO を使用して推論を実行するためにドロップダウン・リストからデバイスを選択します

import ipywidgets as widgets 

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

device
Dropdown(description='Device:', index=1, options=('CPU', 'AUTO'), value='AUTO')
# 特定のデバイス用にモデルをコンパイル 
compiled_quantized_model = core.compile_model(model=quantized_model, device_name=device.value) 
output_layer = compiled_quantized_model.outputs[0]

データソースは 2 つの文 (sample_idx で示される) を返し、推論ではこれらの文を比較し、それらの意味が同じかどうかを出力します。他の文をテストするには、sample_idx を別の値 (0 ~ 407) に変更します。

sample_idx = 5 
sample = data_source[sample_idx] 
inputs = {k: torch.unsqueeze(torch.tensor(sample[k]), 0) for k in ["input_ids", "token_type_ids", "attention_mask"]} 

result = compiled_quantized_model(inputs)[output_layer] 
result = np.argmax(result) 

print(f"Text 1: {sample['sentence1']}") 
print(f"Text 2: {sample['sentence2']}") 
print(f"The same meaning: {'yes' if result == 1 else 'no'}")
Text 1: Wal-Mart said it would check all of its million-plus domestic workers to ensure they were legally employed . Text 2: It has also said it would review all of its domestic employees more than 1 million to ensure they have legal status . The same meaning: yes

FP32 モデルと INT8 モデルの F1 スコアを比較#

def validate(model: ov.Model, dataset: Iterable[Any]) -> float: 
    """ 
    Evaluate the model on GLUE dataset.     Returns F1 score metric.
    """ 
    compiled_model = core.compile_model(model, device_name=device.value) 
    output_layer = compiled_model.output(0) 

    metric = evaluate.load("glue", "mrpc") 
    for batch in dataset: 
        inputs = [np.expand_dims(np.asarray(batch[key], dtype=np.int64), 0) for key in INPUT_NAMES] 
        outputs = compiled_model(inputs)[output_layer] 
        predictions = outputs[0].argmax(axis=-1) 
        metric.add_batch(predictions=[predictions], references=[batch["labels"]]) 
    metrics = metric.compute() 
    f1_score = metrics["f1"] 

    return f1_score 

print("Checking the accuracy of the original model:") 
metric = validate(model, data_source) 
print(f"F1 score: {metric:.4f}") 

print("Checking the accuracy of the quantized model:") 
metric = validate(quantized_model, data_source) 
print(f"F1 score: {metric:.4f}")
Checking the accuracy of the original model: 
F1 score: 0.9019 
Checking the accuracy of the quantized model: 
F1 score: 0.8969

オリジナル、変換済み、量子化されたモデルのパフォーマンスを比較#

オリジナルの PyTorch モデルと OpenVINO に変換され量子化されたモデル (FP32INT8) を比較して、パフォーマンスの違いを確認します。これは、画像の 1 秒あたりのフレーム数 (FPS) と同様に、1 秒あたりの文数 (SPS) の単位で表されます。

# 特定のデバイス用にモデルをコンパイル 
compiled_model = core.compile_model(model=model, device_name=device.value)
num_samples = 50 
sample = data_source[0] 
inputs = {k: torch.unsqueeze(torch.tensor(sample[k]), 0) for k in ["input_ids", "token_type_ids", "attention_mask"]} 

with torch.no_grad(): 
    start = time.perf_counter() 
    for _ in range(num_samples): 
        torch_model(torch.vstack(list(inputs.values()))) 
    end = time.perf_counter() 
    time_torch = end - start 
print(f"PyTorch model on CPU: {time_torch / num_samples:.3f} seconds per sentence, " f"SPS: {num_samples / time_torch:.2f}") 

start = time.perf_counter() 
for _ in range(num_samples): 
    compiled_model(inputs) 
end = time.perf_counter() 
time_ir = end - start 
print(f"IR FP32 model in OpenVINO Runtime/{device.value}: {time_ir / num_samples:.3f} " f"seconds per sentence, SPS: {num_samples / time_ir:.2f}") 

start = time.perf_counter() 
for _ in range(num_samples): 
    compiled_quantized_model(inputs) 
end = time.perf_counter() 
time_ir = end - start 
print(f"OpenVINO IR INT8 model in OpenVINO Runtime/{device.value}: {time_ir / num_samples:.3f} " f"seconds per sentence, SPS: {num_samples / time_ir:.2f}")
input_ids が埋め込まれる可能性があるため、attention_mask を渡すことを強く推奨します。Https://huggingface.co/docs/transformers/troubleshooting#incorrect-output-when-padding-tokens-arent-masked (英語) を参照してください。
PyTorch model on CPU: 0.071 seconds per sentence, SPS: 14.14 
IR FP32 model in OpenVINO Runtime/AUTO: 0.021 seconds per sentence, SPS: 47.94 
OpenVINO IR INT8 model in OpenVINO Runtime/AUTO: 0.009 seconds per sentence, SPS: 105.56

最後に、OpenVINO FP32 モデルと INT8 モデルの推論パフォーマンスを測定します。これには、OpenVINO のベンチマーク・ツールを使用します。

: benchmark_app ツールは、OpenVINO 中間表現 (OpenVINO IR) モデルのパフォーマンスのみを測定できます。より正確なパフォーマンスを得るには、他のアプリケーションを閉じて、ターミナル/コマンドプロンプトで benchmark_app を実行します。benchmark_app -m model.xml -d CPU を実行して、CPU で非同期推論のベンチマークを 1 分間実行します。GPU でベンチマークを行うには、CPUGPU に変更します。benchmark_app --help を実行すると、すべてのコマンドライン・オプションの概要が表示されます。

# FP32 モデルの推論 (OpenVINO IR) 
!benchmark_app -m $ir_model_xml -shape [1,128],[1,128],[1,128] -d {device.value} -api sync
[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.2.0-15519-5c0f38f83f6-releases/2024/2 
[ INFO ] 
[ INFO ] Device info: 
[ INFO ] AUTO 
[ INFO ] Build .................................2024.2.0-15519-5c0f38f83f6-releases/2024/2 
[ 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 17.97 ms 
[ INFO ] Original model I/O parameters: 
[ INFO ] Model inputs: 
[ INFO ]     images (node: images) : i64 / [...] / [1,?] 
[ INFO ]     attention_mask , 63 (node: attention_mask) : i64 / [...]/ [1,?]
[ INFO ]     images (node: images) : i64 / [...]/ [1,?]
[ INFO ] Model outputs: 
[ INFO ]     logits (node: __module.classifier/aten::linear/Add) : f32 / [...] / [1,2] 
[Step 5/11] Resizing model to match image sizes and given batch 
[ INFO ] Model batch size: 1 
[ INFO ] Reshaping model: 'input_ids': [1,128], '63': [1,128], 'token_type_ids': [1,128] 
[ INFO ] Reshape model took 5.17 ms [Step 6/11] Configuring input of the model 
[ INFO ] Model inputs: 
[ INFO ]     images (node: images) : i64 / [...]/ [1,128] 
[ INFO ]     attention_mask , 63 (node: attention_mask) : i64 / [...]/[1,128]
[ INFO ]     images (node: images) : i64 / [...]/ [1,128] 
[ INFO ] Model outputs: 
[ INFO ]     logits (node: __module.classifier/aten::linear/Add) : f32 / [...]/ [1,2] 
[Step 7/11] Loading the model to the device 
[ INFO ] Compile model took 412.90 ms 
[Step 8/11] Querying optimal runtime parameters 
[ INFO ] Model: 
[ INFO ]     NETWORK_NAME: Model0 
[ INFO ]     EXECUTION_DEVICES: ['CPU'] 
[ INFO ]     PERFORMANCE_HINT: PerformanceMode.LATENCY 
[ INFO ]     OPTIMAL_NUMBER_OF_INFER_REQUESTS: 1 
[ 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: False 
[ INFO ]       EXECUTION_DEVICES: ['CPU'] 
[ INFO ]       EXECUTION_MODE_HINT: ExecutionMode.PERFORMANCE 
[ INFO ]       INFERENCE_NUM_THREADS: 12 
[ INFO ]       INFERENCE_PRECISION_HINT: <Type: 'float32'> 
[ INFO ]       KV_CACHE_PRECISION: <Type: 'float16'> 
[ INFO ]       LOG_LEVEL: Level.NO 
[ INFO ]       MODEL_DISTRIBUTION_POLICY: set() 
[ INFO ]       NETWORK_NAME: Model0 
[ INFO ]       NUM_STREAMS: 1 
[ INFO ]       OPTIMAL_NUMBER_OF_INFER_REQUESTS: 1 
[ INFO ]       PERFORMANCE_HINT: LATENCY 
[ 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 
[ INFO ] PERF_COUNT: False 
[Step 9/11] Creating infer requests and preparing input tensors 
[ WARNING ] No input files were given for input 'input_ids'!.This input will be filled with random values! 
[ WARNING ] No input files were given for input '63'!. This input will be filled with random values! 
[ WARNING ] No input files were given for input 'token_type_ids'!.This input will be filled with random values! 
[ INFO ] Fill input 'input_ids' with random values 
[ INFO ] Fill input '63' with random values 
[ INFO ] Fill input 'token_type_ids' with random values 
[Step 10/11] Measuring performance (Start inference synchronously, limits: 120000 ms duration) 
[ INFO ] Benchmarking in inference only mode (inputs filling are not included in measurement loop).
[ INFO ] First inference took 31.38 ms 
[Step 11/11] Dumping statistics report 
[ INFO ] Execution Devices:['CPU'] 
[ INFO ] Count: 6026 iterations 
[ INFO ] Duration: 120012.51 ms 
[ INFO ] Latency: 
[ INFO ]     Median: 19.74 ms 
[ INFO ]     Average: 19.82 ms 
[ INFO ]     Min: 18.76 ms 
[ INFO ]     Max: 22.82 ms 
[ INFO ] Throughput: 50.21 FPS
# INT8 モデルの推論 (OpenVINO IR) 
! benchmark_app -m $compressed_model_xml -shape [1,128],[1,128],[1,128] -d {device.value} -api sync
[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.2.0-15519-5c0f38f83f6-releases/2024/2 
[ INFO ] 
[ INFO ] Device info: 
[ INFO ] AUTO 
[ INFO ] Build .................................2024.2.0-15519-5c0f38f83f6-releases/2024/2 
[ 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 23.50 ms 
[ INFO ] Original model I/O parameters: 
[ INFO ] Model inputs: 
[ INFO ]     images (node: images) : i64 / [...]/ [1,?] 
[ INFO ] 63 , attention_mask (node: attention_mask) : i64 / [...] / [1,?]
[ INFO ]     images (node: images) : i64 / [...]/ [1,?]
[ INFO ] Model outputs: 
[ INFO ]     logits (node: __module.classifier/aten::linear/Add) : f32 / [...]/ [1,2] 
[Step 5/11] Resizing model to match image sizes and given batch 
[ INFO ] Model batch size: 1 
[ INFO ] Reshaping model: 'input_ids': [1,128], '63': [1,128], 'token_type_ids': [1,128] 
[ INFO ] Reshape model took 6.93 ms 
[Step 6/11] Configuring input of the model 
[ INFO ] Model inputs: 
[ INFO ]     images (node: images) : i64 / [...]/ [1,128] 
[ INFO ] 63 , attention_mask (node: attention_mask) : i64 / [...]/[1,128]
[ INFO ]     images (node: images) : i64 / [...]/ [1,128] 
[ INFO ] Model outputs: 
[ INFO ]     logits (node: __module.classifier/aten::linear/Add) : f32 / [...]/ [1,2] 
[Step 7/11] Loading the model to the device 
[ INFO ] Compile model took 1164.57 ms 
[Step 8/11] Querying optimal runtime parameters 
[ INFO ] Model: 
[ INFO ]     NETWORK_NAME: Model0 
[ INFO ]     EXECUTION_DEVICES: ['CPU'] 
[ INFO ]     PERFORMANCE_HINT: PerformanceMode.LATENCY 
[ INFO ]     OPTIMAL_NUMBER_OF_INFER_REQUESTS: 1 
[ 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: False 
[ INFO ]       EXECUTION_DEVICES: ['CPU'] 
[ INFO ]       EXECUTION_MODE_HINT: ExecutionMode.PERFORMANCE 
[ INFO ]       INFERENCE_NUM_THREADS: 12 
[ INFO ]       INFERENCE_PRECISION_HINT: <Type: 'float32'> 
[ INFO ]       KV_CACHE_PRECISION: <Type: 'float16'> 
[ INFO ]       LOG_LEVEL: Level.NO 
[ INFO ]       MODEL_DISTRIBUTION_POLICY: set() 
[ INFO ]       NETWORK_NAME: Model0 
[ INFO ]       NUM_STREAMS: 1 
[ INFO ]       OPTIMAL_NUMBER_OF_INFER_REQUESTS: 1 
[ INFO ]       PERFORMANCE_HINT: LATENCY 
[ 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 
[ INFO ] PERF_COUNT: False 
[Step 9/11] Creating infer requests and preparing input tensors 
[ WARNING ] No input files were given for input 'input_ids'!.This input will be filled with random values! 
[ WARNING ] No input files were given for input '63'!.This input will be filled with random values! 
[ WARNING ] No input files were given for input 'token_type_ids'!.This input will be filled with random values! 
[ INFO ] Fill input 'input_ids' with random values 
[ INFO ] Fill input '63' with random values 
[ INFO ] Fill input 'token_type_ids' with random values 
[Step 10/11] Measuring performance (Start inference synchronously, limits: 120000 ms duration) 
[ INFO ] Benchmarking in inference only mode (inputs filling are not included in measurement loop).
[ INFO ] First inference took 16.55 ms 
[Step 11/11] Dumping statistics report 
[ INFO ] Execution Devices:['CPU'] 
[ INFO ] Count: 12217 iterations 
[ INFO ] Duration: 120007.78 ms 
[ INFO ] Latency: 
[ INFO ]     Median: 9.78 ms 
[ INFO ]     Average: 9.73 ms 
[ INFO ]     Min: 8.31 ms 
[ INFO ]     Max: 10.71 ms 
[ INFO ] Throughput: 101.80 FPS