OpenVINO™ を使用した YOLOv8 インスタンスのセグメント化モデルの変換と最適化#

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

Google ColabGitHub

インスタンスのセグメント化は、オブジェクト検出よりも一歩進んで、画像内の個々のオブジェクトを識別し、それらを画像の残りの部分からセグメント化します。オブジェクト検出としてのインスタンスのセグメント化は、コンピューター・ビジョン・システムの主要コンポーネントとしてよく使用されます。リアルタイム・インスタンスのセグメント化モデルを使用するアプリケーションには、ビデオ分析、ロボット工学、自律走行車、複数オブジェクトの追跡とオブジェクトのカウント、医療画像分析などがあります。

このチュートリアルでは、OpenVINO を使用して PyTorch YOLOv8 を実行および最適化する手順を段階的に説明します。インスタンスのセグメント化シナリオに必要な手順を検討します。

このチュートリアルは次のステップで構成されます: - PyTorch モデルの準備。- データセットをダウンロードして準備します。- 元のモデルを検証します。- PyTorch モデルを OpenVINO IR に変換します。- 変換されたモデルを検証します。- 最適化パイプラインの準備と実行- FP32 モデルと量子化モデルのパフォーマンスを比較します。- FP32 モデルと量子化モデルの精度を比較します。- ライブデモ

目次:

PyTorch モデルを取得#

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

  1. クラスのインスタンスを作成します。
  2. 事前トレーニングされたモデルの重みを含むチェックポイント状態辞書をロードします。
  3. 一部の操作を推論モードに切り替えるためモデルを評価に切り替えます。

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

必要条件#

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

%pip install -q "openvino>=2024.0.0" "nncf>=2.9.0" 
%pip install -q "torch>=2.1" "torchvision>=0.16" "ultralytics==8.2.24" onnx opencv-python tqdm --extra-index-url https://download.pytorch.org/whl/cpu

必要なユーティリティー関数をインポートします。下のセルは、GitHub から notebook_utils Python モジュールをダウンロードします。

from pathlib import Path 

# `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
#  テストサンプルをダウンロード 
IMAGE_PATH = Path("./data/coco_bike.jpg") 
download_file( 

url="https://storage.openvinotoolkit.org/repositories/openvino_notebooks/data/data/image/coco_bike.jpg", 
    filename=IMAGE_PATH.name, 
    directory=IMAGE_PATH.parent, 
)
data/coco_bike.jpg: 0%| | 0.00/182k [00:00<?, ?B/s]
PosixPath('/home/maleksandr/test_notebooks/update_ultralytics/openvino_notebooks/notebooks/yolov8-optimization/data/coco_bike.jpg')

モデルのインスタンス化#

モデルをロードするには、モデル・チェックポイントへのパスを指定する必要があります。モデルハブで使用可能なローカルパスまたは名前にすることができます (この場合、モデル・チェックポイントは自動的にダウンロードされます)。

予測を行う際、モデルは入力画像へのパスを受け入れ、Results クラス・オブジェクトを含むリストを返します。結果には、オブジェクト検出モデルのボックスと、セグメント化モデルのボックスとマスクが含まれます。また、描画用の plot() メソッドなど、結果を処理するユーティリティーも含まれています。

例を考えてみましょう:

models_dir = Path("./models") 
models_dir.mkdir(exist_ok=True)
from PIL import Image 
from ultralytics import YOLO 

SEG_MODEL_NAME = "yolov8n-seg" 

seg_model = YOLO(models_dir / f"{}.pt") 
label_map = seg_model.model.names 

res = seg_model(IMAGE_PATH) 
Image.fromarray(res[0].plot()[:, :, ::-1])
Downloading ultralytics/assets to 'models/yolov8n-seg.pt'...
100%|██████████████████████████████████████████████████████████████████████████████| 6.73M/6.73M [00:01<00:00, 3.89MB/s]
image 1/1 /home/maleksandr/test_notebooks/update_ultralytics/openvino_notebooks/notebooks/yolov8-optimization/data/coco_bike.jpg: 480x640 1 bicycle, 2 cars, 1 dog, 55.6ms 
Speed: 1.8ms preprocess, 55.6ms inference, 2.0ms postprocess per image at shape (1, 3, 480, 640)
../_images/yolov8-instance-segmentation-with-output_9_3.png

YOLOv8 は、OpenVINO IR を含むさまざまな形式にモデルをエクスポートする便利な API を提供します。model.export はモデルの変換を担当します。形式を指定する必要があり、さらにモデル内の動的な形状を保持することもできます。

# インスタンスのセグメント化モデル 
seg_model_path = models_dir / f"{SEG_MODEL_NAME}_openvino_model/{SEG_MODEL_NAME}.xml" 
if not seg_model_path.exists(): 
    seg_model.export(format="openvino", dynamic=True, half=True)
Ultralytics YOLOv8.1.42 🚀 Python-3.10.12 torch-2.2.2+cpu CPU (Intel Core(TM) i9-10980XE 3.00GHz) 

PyTorch: starting from 'models/yolov8n-seg.pt' with input shape (1, 3, 640, 640) BCHW and output shape(s) ((1, 116, 8400), (1, 32, 160, 160)) (6.7 MB) 

OpenVINO: starting export with openvino 2024.0.0-14509-34caeefd078-releases/2024/0...
OpenVINO: export success ✅ 1.8s, saved as 'models/yolov8n-seg_openvino_model/' (6.9 MB) 

Export complete (3.0s) 
Results saved to 
/home/maleksandr/test_notebooks/update_ultralytics/openvino_notebooks/notebooks/yolov8-optimization/models 
Predict: yolo predict task=segment model=models/yolov8n-seg_openvino_model imgsz=640 half 
Validate: yolo val task=segment model=models/yolov8n-seg_openvino_model imgsz=640 data=coco.yaml half 
Visualize: https://netron.app

推論に IR モデルを使用する方法を置き換えるだけで、前処理と後処理にベース・モデル・パイプラインを再利用できます。

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

import ipywidgets as widgets 
import openvino as ov 

core = ov.Core() 

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')
core = ov.Core() 
seg_ov_model = core.read_model(seg_model_path) 

ov_config = {} 
if device.value != "CPU": 
    seg_ov_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"} 
seg_compiled_model = core.compile_model(seg_ov_model, device.value, ov_config)
import torch 

def infer(*args): 
    result = seg_compiled_model(args) 
    return torch.from_numpy(result[0]), torch.from_numpy(result[1]) 

seg_model.predictor.inference = infer 
seg_model.predictor.model.pt = False
res = seg_model(IMAGE_PATH) 
Image.fromarray(res[0].plot()[:, :, ::-1])
image 1/1 /home/maleksandr/test_notebooks/update_ultralytics/openvino_notebooks/notebooks/yolov8-optimization/data/coco_bike.jpg: 640x640 1 bicycle, 2 cars, 1 dog, 27.6ms 
Speed: 3.5ms preprocess, 27.6ms inference, 4.5ms postprocess per image at shape (1, 3, 640, 640)
../_images/yolov8-instance-segmentation-with-output_18_1.png

これで完了です! 結果は、元のモデルで生成されたものと同じです。

データセット上のモデルの精度をチェック#

最適化されたモデルの結果を元のモデルと比較するには、検証データセットでのモデルの精度に関する測定可能な結果を​​いくつか知っておくとよいでしょう。

YOLOv8 は COCO データセットで事前トレーニングされているため、モデルの精度を評価するにはそれをダウンロードする必要があります。YOLOv8 リポジトリーで提供されている指示に従って、元のモデル評価関数で使用するため、モデルの作成者が使用した形式でアノテーションをダウンロードする必要もあります。

: 最初のデータセットのダウンロードが完了するまでに数分かかる場合があります。ダウンロード速度はインターネット接続の品質によって異なります。

from zipfile import ZipFile 

from ultralytics.data.utils import DATASETS_DIR 

DATA_URL = "http://images.cocodataset.org/zips/val2017.zip" 
LABELS_URL = "https://github.com/ultralytics/yolov5/releases/download/v1.0/coco2017labels-segments.zip" 
CFG_URL = 
"https://raw.githubusercontent.com/ultralytics/ultralytics/v8.1.0/ultralytics/cfg/datasets/coco.yaml" 

OUT_DIR = DATASETS_DIR 

DATA_PATH = OUT_DIR / "val2017.zip" 
LABELS_PATH = OUT_DIR / "coco2017labels-segments.zip" 
CFG_PATH = OUT_DIR / "coco.yaml" 

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

if not (OUT_DIR / "coco/labels").exists(): 
    with ZipFile(LABELS_PATH, "r") as zip_ref: 
        zip_ref.extractall(OUT_DIR) 
    with ZipFile(DATA_PATH, "r") as zip_ref: 
        zip_ref.extractall(OUT_DIR / "coco/images")
import numpy as np
 
from tqdm.notebook import tqdm 
from ultralytics.utils.metrics import ConfusionMatrix 

def test( 
    model: ov.Model, 
    core: ov.Core, 
    data_loader: torch.utils.data.DataLoader, 
    validator, 
    num_samples: int = None, 
): 
    """ 
    OpenVINO YOLOv8 model accuracy validation function.Runs model validation on dataset and returns metrics 
    Parameters: 
        model (Model): OpenVINO model 
        data_loader (torch.utils.data.DataLoader): dataset loader 
        validator: instance of validator class 
        num_samples (int, *optional*, None): validate model only on specified number samples, if provided 
    Returns: 
        stats: (Dict[str, float]) - dictionary with aggregated accuracy metrics statistics, key is metric name, value is metric value 
    """ 
    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) 
    model.reshape({0: [1, 3, -1, -1]}) 
    num_outputs = len(model.outputs) 
    compiled_model = core.compile_model(model) 
    for batch_i, batch in enumerate(tqdm(data_loader, total=num_samples)): 
        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) 
    stats = validator.get_stats() 
    return stats 

def print_stats(stats: np.ndarray, total_images: int, total_objects: int): 
    """ 
    Helper function for printing accuracy statistic 
    Parameters: 
        stats: (Dict[str, float]) - dictionary with aggregated accuracy metrics statistics, key is metric name, value is metric value 
        total_images (int) - number of evaluated images 
        total objects (int) 
    Returns:
        None 
    """ 
    print("Boxes:") 
    mp, mr, map50, mean_ap = ( 
        stats["metrics/precision(B)"], 
        stats["metrics/recall(B)"], 
        stats["metrics/mAP50(B)"], 
        stats["metrics/mAP50-95(B)"], 
    ) 
    # 結果をプリント 
    print(" Best mean average:") 
    s = ("%20s" + "%12s" * 6) % ( 
        "Class", 
        "Images", 
        "Labels", 
        "Precision", 
        "Recall", 
        "mAP@.5", 
        "mAP@.5:.95", 
    ) 
    print(s) 
    pf = "%20s" + "%12i" * 2 + "%12.3g" * 4 # プリント形式 
    print(pf % ("all", total_images, total_objects, mp, mr, map50, mean_ap)) 
    if "metrics/precision(M)" in stats: 
        s_mp, s_mr, s_map50, s_mean_ap = ( 
            stats["metrics/precision(M)"], 
            stats["metrics/recall(M)"], 
            stats["metrics/mAP50(M)"], 
            stats["metrics/mAP50-95(M)"], 
        ) 
        # 結果をプリント 
        print(" Macro average mean:") 
        s = ("%20s" + "%12s" * 6) % ( 
            "Class", 
            "Images", 
            "Labels", 
            "Precision", 
            "Recall", 
            "mAP@.5", 
            "mAP@.5:.95", 
        ) 
    print(s) 
    pf = "%20s" + "%12i" * 2 + "%12.3g" * 4 # プリント形式 
    print(pf % ("all", total_images, total_objects, s_mp, s_mr, s_map50, s_mean_ap))

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

from ultralytics.utils import DEFAULT_CFG 
from ultralytics.cfg import get_cfg 
from ultralytics.data.converter import coco80_to_coco91_class 
from ultralytics.data.utils import check_det_dataset 
from ultralytics.utils import ops 

args = get_cfg(cfg=DEFAULT_CFG) 
args.data = str(CFG_PATH)
seg_validator = seg_model.task_map[seg_model.task]["validator"](args=args) 
seg_validator.data = check_det_dataset(args.data) 
seg_validator.stride = 32 
seg_data_loader = seg_validator.get_dataloader(OUT_DIR / "coco/", 1) 

seg_validator.is_coco = True 
seg_validator.class_map = coco80_to_coco91_class() 
seg_validator.names = seg_model.model.names 
seg_validator.metrics.names = seg_validator.names 
seg_validator.nc = seg_model.model.model[-1].nc 
seg_validator.nm = 32 
seg_validator.process = ops.process_mask 
seg_validator.plot_masks = []
val: Scanning /home/maleksandr/test_notebooks/ultrali/datasets/coco/labels/val2017.cache...4952 images, 48 backgrounds,

テスト関数の定義と評価器の作成が完了したら、精度メトリックを取得する準備が整います > : モデル評価は時間のかかるプロセスであり、ハードウェアによっては数分かかる場合があります。計算時間を短縮するために、評価サブセットのサイズで num_samples パラメーターを定義しますが、この場合、検証サブセットの違いにより、モデルの作成者が最初に報告した精度と比較できない可能性があります。完全なデータセットでモデルを検証するには、``NUM_TEST_SAMPLES = None`` を設定します。

NUM_TEST_SAMPLES = 300
fp_seg_stats = test(seg_ov_model, core, seg_data_loader, seg_validator, num_samples=NUM_TEST_SAMPLES)
0%|          | 0/300 [00:00<?, ?it/s]
print_stats(fp_seg_stats, seg_validator.seen, seg_validator.nt_per_class.sum())
Boxes: 
Best mean average: 
Class Images Labels Precision Recall mAP@.5 mAP@.5:.95 
  all    300   2145     0.609  0.521   0.58      0.416 
Macro average mean: 
Class Images Labels Precision Recall mAP@.5 mAP@.5:.95 
  all    300   2145     0.605  0.501  0.558      0.353

print_stats は、次の精度メトリックのリストを報告します:

  • Precision は、関連するオブジェクトのみを識別するモデルの正確さの度合いです。

  • Recall は、モデルがすべてのグラウンド・トゥルース・オブジェクトを検出する能力を測定します。

  • mAP@t - 平均精度は、データセット内のすべてのクラスにわたって集計された適合率と再現率曲線下の領域として表されます。ここで、t は交差ユニオン (IOU) しきい値、つまり、グラウンドの真実と予測されたオブジェクト間の重複の度合いです。したがって、mAP@.5 は、平均精度が 0.5 IOU しきい値で計算されたことを示します。mAP@.5:.95 は、ステップ 0.05 で 0.5 から 0.95 までの範囲の IOU しきい値で計算されます。

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

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

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

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

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

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

モデルの推論速度を向上させるため量子化を実行するかどうかを以下で選択してください。

import ipywidgets as widgets 

int8_model_seg_path = models_dir / f"{SEG_MODEL_NAME}_openvino_int8_model/{SEG_MODEL_NAME}.xml" 

to_quantize = widgets.Checkbox( 
    value=True, 
    description="Quantization", 
    disabled=False, 
) 

to_quantize
Checkbox(value=True, description='Quantization')

to_quantize が選択されていない場合に量子化をスキップする skip magic 拡張機能をロードします

# `skip_kernel_extension` モジュールを取得 
import requests 

r = requests.get( 

url="https://raw.githubusercontent.com/openvinotoolkit/openvino_notebooks/latest/utils/skip_kernel_extension.py", 
) 
open("skip_kernel_extension.py", "w").write(r.text) 

%load_ext skip_kernel_extension

量子化の精度テストで検証データローダーを再利用します。そのため、nncf.Dataset オブジェクトにラップし、入力テンソルのみを取得する変換関数を定義する必要があります。

%%skip not $to_quantize.value 

import nncf 
from typing import Dict 

def transform_fn(data_item:Dict):
    """ 
    Quantization transform function.Extracts and preprocess input data from dataloader item for quantization.Parameters: 
        data_item: Dict with data item produced by DataLoader during iteration 
    Returns: 
        input_tensor: Input data for quantization 
    """ 
    input_tensor = seg_validator.preprocess(data_item)['img'].numpy() 
    return input_tensor 

quantization_dataset = nncf.Dataset(seg_data_loader, transform_fn)
INFO:nncf:NNCF initialized successfully.Supported frameworks detected: torch, onnx, openvino

nncf.quantize 関数は、モデル量子化のインターフェイスを提供します。OpenVINO モデルのインスタンスと量子化データセットが必要です。オプションで、量子化プロセスの追加パラメーター (量子化のサンプル数、プリセット、無視される範囲など) を提供できます。YOLOv8 モデルには、活性化の非対称量子化を必要とする非 ReLU 活性化関数が含まれています。さらに良い結果を得るため、mixed 量子化プリセットを使用します。これは、重みの対称量子化と活性化の非対称量子化を提供します。より正確な結果を得るには、ignored_scope パラメーターを使用して、後処理サブグラフの操作を浮動小数点精度に保つ必要があります。

: モデルのトレーニング後の量子化は時間のかかるプロセスです。ハードウェアによっては数分かかる場合があります。

%%skip not $to_quantize.value 

ignored_scope = nncf.IgnoredScope( 
    names=[ 
        "__module.model.22.cv3.0.0.conv/aten::_convolution/Convolution", # 後処理サブグラフ内 
        "__module.model.22.proto.cv1.conv/aten::_convolution/Convolution", 
        "__module.model.22.cv4.0.0.conv/aten::_convolution/Convolution", 
        "__module.model.16.conv/aten::_convolution/Convolution", 
        "__module.model.22.cv2.0.0.conv/aten::_convolution/Convolution", 
        "__module.model.6.cv1.conv/aten::_convolution/Convolution", 
        "__module.model.22.cv3.1.1.conv/aten::_convolution/Convolution", 
        "__module.model.21.cv2.conv/aten::_convolution/Convolution", 
        "__module.model.21.m.0.cv1.conv/aten::_convolution/Convolution", 
        "__module.model.22/aten::add/Add_6", 
        "__module.model.22/aten::sub/Subtract", 
        "__module.model.7.conv/aten::_convolution/Convolution", 
        "__module.model.12.cv1.conv/aten::_convolution/Convolution", 
        "__module.model.4.cv1.conv/aten::_convolution/Convolution", 
        "__module.model.22.cv2.2.1.conv/aten::_convolution/Convolution", 
        "__module.model.22.cv2.0.1.conv/aten::_convolution/Convolution", 
        "__module.model.22.cv4.2.1.conv/aten::_convolution/Convolution", 
        "__module.model.22.dfl.conv/aten::_convolution/Convolution", 
        "__module.model.22.cv3.2.2/aten::_convolution/Convolution", 
        "__module.model.22.cv3.0.2/aten::_convolution/Convolution", 
        "__module.model.15.cv1.conv/aten::_convolution/Convolution", 
        "__module.model.5.conv/aten::_convolution/Convolution", 
        "__module.model.0.conv/aten::_convolution/Convolution" 
    ] 
) 

# セグメント化モデル 
quantized_seg_model = nncf.quantize( 
    seg_ov_model, 
    quantization_dataset, 
    preset=nncf.QuantizationPreset.MIXED, 
    ignored_scope=ignored_scope 
)
INFO:nncf:23 ignored nodes were found by name in the NNCFGraph 
INFO:nncf:Not adding activation input quantizer for operation: 1 __module.model.0.conv/aten::_convolution/Convolution 
2 __module.model.0.conv/aten::_convolution/Add 
3 __module.model.22.cv4.2.1.act/aten::silu_/Swish 

INFO:nncf:Not adding activation input quantizer for operation: 25 __module.model.4.cv1.conv/aten::_convolution/Convolution 
26 __module.model.4.cv1.conv/aten::_convolution/Add 
27 __module.model.22.cv4.2.1.act/aten::silu_/Swish_7 

INFO:nncf:Not adding activation input quantizer for operation: 43 __module.model.5.conv/aten::_convolution/Convolution 
47 __module.model.5.conv/aten::_convolution/Add 
51 __module.model.22.cv4.2.1.act/aten::silu_/Swish_13 

INFO:nncf:Not adding activation input quantizer for operation: 54 __module.model.6.cv1.conv/aten::_convolution/Convolution 
56 __module.model.6.cv1.conv/aten::_convolution/Add 
59 __module.model.22.cv4.2.1.act/aten::silu_/Swish_14 

INFO:nncf:Not adding activation input quantizer for operation: 98 __module.model.7.conv/aten::_convolution/Convolution 
107 __module.model.7.conv/aten::_convolution/Add 
116 __module.model.22.cv4.2.1.act/aten::silu_/Swish_20 

INFO:nncf:Not adding activation input quantizer for operation: 106 __module.model.12.cv1.conv/aten::_convolution/Convolution 
115 __module.model.12.cv1.conv/aten::_convolution/Add 
123 __module.model.22.cv4.2.1.act/aten::silu_/Swish_27 

INFO:nncf:Not adding activation input quantizer for operation: 46 __module.model.15.cv1.conv/aten::_convolution/Convolution 
50 __module.model.15.cv1.conv/aten::_convolution/Add 
53 __module.model.22.cv4.2.1.act/aten::silu_/Swish_31 

INFO:nncf:Not adding activation input quantizer for operation: 74 __module.model.16.conv/aten::_convolution/Convolution 
83 __module.model.16.conv/aten::_convolution/Add 
92 __module.model.22.cv4.2.1.act/aten::silu_/Swish_42 

INFO:nncf:Not adding activation input quantizer for operation: 75 __module.model.22.cv2.0.0.conv/aten::_convolution/Convolution 
84 __module.model.22.cv2.0.0.conv/aten::_convolution/Add 
93 __module.model.22.cv4.2.1.act/aten::silu_/Swish_38 

INFO:nncf:Not adding activation input quantizer for operation: 102 __module.model.22.cv2.0.1.conv/aten::_convolution/Convolution 
111 __module.model.22.cv2.0.1.conv/aten::_convolution/Add 
119 __module.model.22.cv4.2.1.act/aten::silu_/Swish_39 

INFO:nncf:Not adding activation input quantizer for operation: 76 __module.model.22.cv3.0.0.conv/aten::_convolution/Convolution 
85 __module.model.22.cv3.0.0.conv/aten::_convolution/Add 
94 __module.model.22.cv4.2.1.act/aten::silu_/Swish_40 

INFO:nncf:Not adding activation input quantizer for operation: 127 __module.model.22.cv3.0.2/aten::_convolution/Convolution 
134 __module.model.22.cv3.0.2/aten::_convolution/Add 

INFO:nncf:Not adding activation input quantizer for operation: 77 __module.model.22.cv4.0.0.conv/aten::_convolution/Convolution 
86 __module.model.22.cv4.0.0.conv/aten::_convolution/Add 
95 __module.model.22.cv4.2.1.act/aten::silu_/Swish_60 

INFO:nncf:Not adding activation input quantizer for operation: 78 __module.model.22.proto.cv1.conv/aten::_convolution/Convolution 
87 __module.model.22.proto.cv1.conv/aten::_convolution/Add 
96 __module.model.22.cv4.2.1.act/aten::silu_/Swish_35 
INFO:nncf:Not adding activation input quantizer for operation: 234 __module.model.22.cv3.1.1.conv/aten::_convolution/Convolution 
247 __module.model.22.cv3.1.1.conv/aten::_convolution/Add 
258 __module.model.22.cv4.2.1.act/aten::silu_/Swish_50 

INFO:nncf:Not adding activation input quantizer for operation: 289 __module.model.21.m.0.cv1.conv/aten::_convolution/Convolution 
296 __module.model.21.m.0.cv1.conv/aten::_convolution/Add 
301 __module.model.22.cv4.2.1.act/aten::silu_/Swish_53 

INFO:nncf:Not adding activation input quantizer for operation: 295 __module.model.21.cv2.conv/aten::_convolution/Convolution 
300 __module.model.21.cv2.conv/aten::_convolution/Add 
304 __module.model.22.cv4.2.1.act/aten::silu_/Swish_55 

INFO:nncf:Not adding activation input quantizer for operation: 331 __module.model.22.cv2.2.1.conv/aten::_convolution/Convolution 
339 __module.model.22.cv2.2.1.conv/aten::_convolution/Add 
344 __module.model.22.cv4.2.1.act/aten::silu_/Swish_57 

INFO:nncf:Not adding activation input quantizer for operation: 333 __module.model.22.cv4.2.1.conv/aten::_convolution/Convolution 
341 __module.model.22.cv4.2.1.conv/aten::_convolution/Add 
346 __module.model.22.cv4.2.1.act/aten::silu_/Swish_65 

INFO:nncf:Not adding activation input quantizer for operation: 349 __module.model.22.cv3.2.2/aten::_convolution/Convolution 
353 __module.model.22.cv3.2.2/aten::_convolution/Add 

INFO:nncf:Not adding activation input quantizer for operation: 243 
__module.model.22.dfl.conv/aten::_convolution/Convolution 
INFO:nncf:Not adding activation input quantizer for operation: 263 
__module.model.22/aten::sub/Subtract 
INFO:nncf:Not adding activation input quantizer for operation: 264 
__module.model.22/aten::add/Add_6
Output()
/home/maleksandr/test_notebooks/update_ultralytics/openvino_notebooks/notebooks/yolov8-optimization/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()
%%skip not $to_quantize.value 

print(f"Quantized segmentation model will be saved to {int8_model_seg_path}") 
ov.save_model(quantized_seg_model, str(int8_model_seg_path))
Quantized segmentation model will be saved to models/yolov8n-seg_openvino_int8_model/yolov8n-seg.xml

予測を行うためデバイスにロードするのに適した OpenVINO モデル・クラス・インスタンスを返します。INT8 モデルの入力データと出力結果の形式は、浮動小数点モデルの表現と違いはありません。したがって、画像上の INT8 モデル結果を取得するために、上で定義した同じ検出関数を再利用できます。

%%skip not $to_quantize.value 

device
%%skip not $to_quantize.value 

ov_config = {} 
if device.value != "CPU": 
    quantized_seg_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_seg_compiled_model = core.compile_model(quantized_seg_model, device.value, ov_config)
%%skip not $to_quantize.value 

def infer(*args): 
    result = quantized_seg_compiled_model(args) 
    return torch.from_numpy(result[0]), torch.from_numpy(result[1]) 

seg_model.predictor.inference = infer
%%skip not $to_quantize.value 

res = seg_model(IMAGE_PATH) 
display(Image.fromarray(res[0].plot()[:, :, ::-1]))
image 1/1 /home/maleksandr/test_notebooks/update_ultralytics/openvino_notebooks/notebooks/yolov8-optimization/data/coco_bike.jpg: 640x640 1 bicycle, 2 cars, 2 dogs, 26.8ms 
Speed: 2.8ms preprocess, 26.8ms inference, 3.4ms postprocess per image at shape (1, 3, 640, 640)
../_images/yolov8-instance-segmentation-with-output_46_1.png

元のモデルと量子化モデルを比較#

最後に、OpenVINO Benchmark ツールを使用して、FP32INT8 モデルの推論パフォーマンスを測定します。

: より正確なパフォーマンスを得るには、他のアプリケーションを閉じて、ターミナル/コマンドプロンプトで benchmark_app を実行することを推奨します。benchmark_app -m <model_path> -d CPU -shape "<input_shape>" を実行して、CPU で非同期推論のベンチマークを 1 分間実行します。GPU でベンチマークを行うには、CPUGPU に変更します。benchmark_app --help を実行すると、すべてのコマンドライン・オプションの概要が表示されます。

%%skip not $to_quantize.value 

device
if int8_model_seg_path.exists(): !benchmark_app -m $seg_model_path -d $device.value -api async -shape "[1,3,640,640]" -t 15
[Step 1/11] Parsing and validating input arguments 
[ INFO ] Parsing input parameters 
[Step 2/11] Loading OpenVINO Runtime 
[ 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 15.84 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 9.23 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 304.42 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: 15000 ms duration) 
[ INFO ] Benchmarking in inference only mode (inputs filling are not included in measurement loop).
[ INFO ] First inference took 50.67 ms 
[Step 11/11] Dumping statistics report 
[ INFO ] Execution Devices:['CPU'] 
[ INFO ] Count: 2124 iterations 
[ INFO ] Duration: 15076.69 ms 
[ INFO ] Latency: 
[ INFO ]     Median: 84.69 ms 
[ INFO ]     Average: 84.95 ms 
[ INFO ]     Min: 43.23 ms 
[ INFO ]     Max: 184.81 ms 
[ INFO ] Throughput: 140.88 FPS
if int8_model_seg_path.exists(): 
    !benchmark_app -m $int8_model_seg_path -d $device.value -api async -shape "[1,3,640,640]" -t 15
[Step 1/11] Parsing and validating input arguments 
[ INFO ] Parsing input parameters 
[Step 2/11] Loading OpenVINO Runtime 
[ 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 24.33 ms 
[ INFO ] Original model I/O parameters: 
[ INFO ] Model inputs: 
[ INFO ] x (node: x) : f32 / [...]/ [1,3,?,?]
[ INFO ] Model outputs: 
[ INFO ]     *NO_NAME* (node: __module.model.22/aten::cat/Concat_8) : f32 / [...]/ [1,116,21..]
[ INFO ] input.199 (node: __module.model.22.cv4.2.1.act/aten::silu_/Swish_37) : f32 / [...] / [1,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 13.01 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 574.36 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: 15000 ms duration) 
[ INFO ] Benchmarking in inference only mode (inputs filling are not included in measurement loop).
[ INFO ] First inference took 41.26 ms 
[Step 11/11] Dumping statistics report 
[ INFO ] Execution Devices:['CPU'] 
[ INFO ] Count: 3048 iterations 
[ INFO ] Duration: 15096.50 ms 
[ INFO ] Latency: 
[ INFO ]     Median: 58.82 ms 
[ INFO ]     Average: 59.20 ms 
[ INFO ]     Min: 33.17 ms 
[ INFO ]     Max: 120.39 ms 
[ INFO ] Throughput: 201.90 FPS

ご覧のとおり、単一画像テストでは、INT8 モデルと float モデルの結果に大きな違いはありません。量子化がモデル予測の精度にどのように影響するか理解するため、データセット上のモデル精度を比較することができます。

%%skip not $to_quantize.value 

int8_seg_stats = test(quantized_seg_model, core, seg_data_loader, seg_validator, num_samples=NUM_TEST_SAMPLES)
0%|          | 0/300 [00:00<?, ?it/s]
%%skip not $to_quantize.value 

print("FP32 model accuracy") 
print_stats(fp_seg_stats, seg_validator.seen, seg_validator.nt_per_class.sum()) 

print("INT8 model accuracy") 
print_stats(int8_seg_stats, seg_validator.seen, seg_validator.nt_per_class.sum())

FP32 model accuracy 
Boxes: 
Best mean average: 
Class Images Labels Precision Recall mAP@.5 mAP@.5:.95 
  all    300   2153     0.609  0.521   0.58      0.416 
Macro average mean: 
Class Images Labels Precision Recall mAP@.5 mAP@.5:.95 
  all    300   2153     0.605  0.501  0.558      0.353 

INT8 model accuracy 
Boxes: 
Best mean average: 
Class Images Labels Precision Recall mAP@.5 mAP@.5:.95 
  all    300   2153     0.522  0.538  0.555      0.376 
Macro average mean: 
Class Images Labels Precision Recall mAP@.5 mAP@.5:.95 
  all    300   2153     0.631  0.463  0.529      0.344

これで完了です! 精度は変更されたようですが、大きな変化はなく、合格基準を満たしています。

モデルを最適化する他の方法#

非同期推論パイプラインや前処理 API などの別の OpenVINO メソッドによってパフォーマンスを向上させることもできます。

非同期推論パイプラインは、デバイスをより最適に活用するのに役立ちます。非同期 API の主な利点は、デバイスが推論でビジー状態のときに、アプリケーションが現在の推論が完了するのを待つのではなく、他のタスク (例えば、入力の入力や他の要求のスケジュール設定) を並行して実行できることです。openvino を使用して非同期推論を実行する方法を理解するには、非同期 API のチュートリアルを参照してください。

前処理 API を使用すると、前処理をモデルの一部にすることができ、アプリケーション・コードと追加の画像処理ライブラリーへの依存関係が削減されます。前処理 API の主な利点は、前処理手順が実行グラフに統合され、アプリケーションの一部として常に CPU 上で実行されるのではなく、選択したデバイス (CPU/GPU など) 上で実行されることです。これにより、選択したデバイスの使用率も向上します。詳細については、前処理 API チュートリアルの概要を参照してください。YOLOV8 オブジェクト検出モデルでどのように使用できるかを確認するには、OpenVINO チュートリアルを使用して YOLOv8 リアルタイム・オブジェクト検出を変換および最適化するを参照してください。

ライブデモ#

次のコードは、ビデオに対してモデル推論を実行します:

import collections 
import time 
import cv2 
from IPython import display 

def run_instance_segmentation( 
    source=0, 
    flip=False, 
    use_popup=False, 
    skip_first_frames=0, 
    model=seg_model, 
    device=device.value, 
): 
    player = None 

    ov_config = {} 
    if device != "CPU": 
        model.reshape({0: [1, 3, 640, 640]}) 
    if "GPU" in device or ("AUTO" in device and "GPU" in core.available_devices): 
        ov_config = {"GPU_DISABLE_WINOGRAD_CONVOLUTION": "YES"} 
    compiled_model = core.compile_model(model, device, ov_config) 

    def infer(*args): 
        result = compiled_model(args) 
        return torch.from_numpy(result[0]), torch.from_numpy(result[1]) 

    seg_model.predictor.inference = infer 

    try:
        # ターゲット fps で再生するビデオプレーヤーを作成 
        player = VideoPlayer(source=source, flip=flip, fps=30, skip_first_frames=skip_first_frames) 
        # キャプチャー開始 
        player.start() 
        if use_popup: 
            title = "Press ESC to Exit" 
            cv2.namedWindow(winname=title, flags=cv2.WINDOW_GUI_NORMAL | cv2.WINDOW_AUTOSIZE) 

        processing_times = collections.deque() 
        while True:
            # フレームをグラブ 
            frame = player.next() 
            if frame is None: 
                print("Source ended") 
                break 
            # フレームがフル HD より大きい場合は、サイズを縮小してパフォーマンスを向上させます 
            scale = 1280 / max(frame.shape) 
            if scale < 1: 
                frame = cv2.resize( 
                    src=frame, 
                    dsize=None, 
                    fx=scale, 
                    fy=scale, 
                    interpolation=cv2.INTER_AREA, 
                ) 
            # 結果を取得 
            input_image = np.array(frame) 

            start_time = time.time() 
            detections = seg_model(input_image) 
            stop_time = time.time() 
            frame = detections[0].plot() 

            processing_times.append(stop_time - start_time) 
            # 最後の 200 フレームの処理時間を使用 
            if len(processing_times) > 200: 
                processing_times.popleft() 

            _, f_width = frame.shape[:2] 
            # 平均処理時間 [ms] 
            processing_time = np.mean(processing_times) * 1000 
            fps = 1000 / processing_time 
            cv2.putText( 
                img=frame, 
                text=f"Inference time: {processing_time:.1f}ms ({fps:.1f} FPS)", 
                org=(20, 40), 
                fontFace=cv2.FONT_HERSHEY_COMPLEX, 
                fontScale=f_width / 1000, 
                color=(0, 0, 255), 
                thickness=1, 
                lineType=cv2.LINE_AA, 
            )
 
            # ちらつきがある場合はこの回避策を使用 
            if use_popup: 
                cv2.imshow(winname=title, mat=frame) 
                key = cv2.waitKey(1) 
                # escape = 27 
                if key == 27: 
                    break 
                else: 
                    # numpy 配列を jpg にエンコード
                    _, encoded_img = cv2.imencode(ext=".jpg", img=frame, params=[cv2.IMWRITE_JPEG_QUALITY, 100]) 
                    # IPython イメージを作成 
                    i = display.Image(data=encoded_img) 
                    # このノートブックに画像を表示 
                    display.clear_output(wait=True) 
                    display.display(i) 

# ctrl-c 
except KeyboardInterrupt: 
    print("Interrupted") 
# 異なるエラー 
except RuntimeError as e: 
    print(e) 
finally: 
    if player is not None: 
        # キャプチャーを停止 
        Player.stop().stop() 
    if use_popup: 
        cv2.destroyAllWindows()

Web カメラをビデオ入力として使用します。デフォルトでは、プライマリー・ウェブ・カメラは source=0 に設定されます。複数のウェブカメラがある場合、0 から始まる連続した番号が割り当てられます。前面カメラを使用する場合は、flip=True を設定します。一部のウェブブラウザー、特に Mozilla Firefox ではちらつきが発生する場合があります。ちらつきが発生する場合、use_popup=True を設定してください。

: このノートブックをウェブカメラで使用するには、ウェブカメラを備えたコンピューター上でノートブックを実行する必要があります。ノートブックをリモートサーバー (例えば、Binder または Google Colab サービス) で実行する場合、ウェブカメラは動作しません。デフォルトでは、下のセルはビデオファイルに対してモデル推論を実行します。ウェブカメラ・セットでライブ推論を試す場合、WEBCAM_INFERENCE = True を設定します

WEBCAM_INFERENCE = False 

if WEBCAM_INFERENCE: VIDEO_SOURCE = 0 # ウェブカメラ 
else: VIDEO_SOURCE = "https://storage.openvinotoolkit.org/repositories/openvino_notebooks/data/data/video/people.mp4"
device
Dropdown(description='Device:', index=1, options=('CPU', 'AUTO'), value='AUTO')
run_instance_segmentation( 
    source=VIDEO_SOURCE, 
    flip=True, 
    use_popup=False, 
    model=seg_ov_model, 
    device=device.value, 
)
../_images/yolov8-instance-segmentation-with-output_62_0.png
ソースの終わり