Ultralytics YOLO27: ウェイトリストに登録する。
Get Started
本番環境でのUltralytics YOLO·最適化·レッスン 4/9
レッスン中級

CPUでOpenVINOを使用する

FP32、FP16、INT8のOpenVINOモデルをエクスポートしてそれぞれ検証し、使用するCPUで効果がある場合に限ってINT8を採用します。

すでにお持ちのIntel CPUでGPUインスタンスを置き換えられる場合があります。Ultralyticsのベンチマークでは、YOLO26mの処理時間がPyTorchの192 msから、ノートPCのCore Ultra CPUでOpenVINO INT8を使用した場合は36 msに短縮しました。ただし、性能向上の度合いはチップによって異なります。このコースで使用するARMテスト用ノートPCでは、4枚の画像でキャリブレーションしたINT8エクスポートによりmAPが3ポイント低下しました。リリース前に、どちらの状況に当てはまるかを計測する方法を学びます。

成果

FP32、FP16、INT8のOpenVINOモデルをエクスポートし、使用するCPUで精度と速度を比較して、理由を書面に記録したうえで1つを選択します。

短期集中コース
すでに使い方をご存じの方は、こちらをご覧ください。
  1. yolo export model=yolo26n.pt format=openvinoはyolo26n_openvino_model/を書き出します。

  2. FP16(quantize=16)はファイルサイズを半分にしますが、ほとんどのCPUではFP32と同じ速度で動作します。Intel CPUで高速化するにはINT8(quantize=8 data=your.yaml)を使用します。

  3. 推論時にIntelデバイスを選択してください:device="intel:cpu"、"intel:gpu"、または"intel:npu"。

  4. 次のエクスポートでフォルダーが上書きされる前に、各精度のモデルを検証してください。ターゲット上でONNX Runtimeと比較してベンチマークします。

実践的

OpenVINOが提供するもの#

OpenVINOエコシステム:PyTorch、TensorFlow、Keras、TensorFlow Lite、ONNX、JAX、PaddlePaddleのモデルを、Windows、Linux、macOS上でOpenVINO経由でIntel CPU(およびARM)、Intel GPU、Intel NPU、FPGA上で実行できます

OpenVINOはPyTorchやONNXのモデルを、単一のAPIを通じてIntel CPU、内蔵およびディスクリートGPU、NPU上で実行します。CPUカーネルはIntelの命令セット(AVX2、AVX-512、AMX)を対象としており、INT8の実装も成熟しています。CPU列のARMタイルに注目してください。OpenVINOはARMでも動作しますが、カーネルはIntel向けに最適化されています。ARMで利用する場合は、事前に計測してください。

Intel Core Ultra 7 155H CPU上で公開されているベンチマーク(COCO128):

モデルPyTorch FP32OpenVINO FP32OpenVINO INT8FP32からINT8へのmAP50-95
YOLO26n33.19 ms13.43 ms11.40 ms0.4734 → 0.4611
YOLO26s70.92 ms36.16 ms15.54 ms0.5632 → 0.5471
YOLO26m192.45 ms102.52 ms35.72 ms0.6191 → 0.6025

この表から、次の3つのルールが導けます。

  • Intel CPUでは、OpenVINO FP32だけでもPyTorchのレイテンシがおよそ半分になります。まずはこれを試してください。
  • モデルが大きいほどINT8の効果が高まります。nでは1.2倍、mでは2.9倍高速化し、mAPの低下は1.2~1.7ポイントです。nでは、精度低下を考えるとINT8が見合うことはほとんどありません。
  • ハードウェアを購入する前に内蔵GPUを試してください。同じチップのArc iGPU(device="intel:gpu")では、YOLO26n FP32を9.13 ms、YOLO26mを34.47 msで実行しました。

使用するCPUで精度モードを比較する#

各精度のモデルをエクスポートしたら、次のモデルをエクスポートする前にすぐ検証してください。

from ultralytics import YOLO

if __name__ == "__main__":  # validation starts worker processes on macOS and Windows
    model = YOLO("yolo26n.pt")  # or runs/detect/pills_v1/weights/best.pt
    for name, quantize in (("FP32", None), ("FP16", 16), ("INT8", 8)):
        path = model.export(format="openvino", quantize=quantize, data="coco8.yaml")  # or my_dataset/data.yaml
        m = YOLO(path).val(data="coco8.yaml", batch=1, plots=False, verbose=False)  # before the next export overwrites it
        print(f"{name}: mAP50-95 {m.box.map:.4f}  -> {path}")
OpenVINO: export success ✅ 2.3s, saved as 'yolo26n_openvino_model/' (9.6 MB)
FP32: mAP50-95 0.6783  -> yolo26n_openvino_model/
OpenVINO: export success ✅ 1.6s, saved as 'yolo26n_openvino_model/' (5.1 MB)
FP16: mAP50-95 0.6783  -> yolo26n_openvino_model/
WARNING ⚠️ OpenVINO: >300 images recommended for INT8 calibration, found 4 images.
OpenVINO: export success ✅ 11.3s, saved as 'yolo26n_int8_openvino_model/' (3.2 MB)
INT8: mAP50-95 0.6460  -> yolo26n_int8_openvino_model/

各行でわかること:

  • FP32とFP16のスコアは同じで、FP16のサイズは半分です(5.1 MB対9.6 MB)。ただし、両方が同じフォルダーに書き込まれていました。両方を先にエクスポートし、後で検証していたら、FP16を2回計測していたことになります。
  • INT8は3.2 MBですが、3.2ポイント低下しました。COCO8の4枚の画像でキャリブレーションしたためです。警告にもその旨が記載されています。実際のキャリブレーションには、独自のYAML(fractionで使用枚数を制限できます)から取得した、本番環境に近い画像が数百枚必要です。
  • これらの結果から速度は分かりません。速度の計測には、以下のベンチマークを使用してください。

エクスポートしたモデルを特定のIntelデバイスで実行するには、次のようにします。

from ultralytics import YOLO

ov_model = YOLO("yolo26n_openvino_model/")
results = ov_model("https://ultralytics.com/images/bus.jpg", device="intel:cpu")  # or intel:gpu, intel:npu

フォルダー全体を配布してください:yolo26n.xml(グラフ)、yolo26n.bin(重み)、metadata.yaml。intel:gpuとintel:npuにはIntelハードウェアが必要です。

ONNX Runtimeと比較して計測する#

精度の評価が済んだら、実際に処理する負荷をかけた状態で、ターゲット上で速度を評価します。最初のレッスンのpick_runtime.pyをCANDIDATES = ("onnx", "openvino")とともに実行してください。Appleシリコン搭載のテスト用ノートPCで、ほかのジョブがCPUを共有している状態で計測した結果は次のとおりです。

onnx      p50  30.0 ms  p95  46.4 ms  misses the 30 ms budget
openvino  p50  22.8 ms  p95 113.5 ms  misses the 30 ms budget

OpenVINOは中央値が優れていましたが、テールレイテンシは大幅に悪化しました。UltralyticsのラッパーはLATENCYヒントを使ってOpenVINOをコンパイルします(ログにはUsing OpenVINO LATENCY mode for batch=1 inference on CPUと表示されます)。この設定では各リクエストがCPUコア全体に分散されるため、ほかの処理が同じコアを使用すると、最も遅いリクエストへの影響が最大になります。専用のIntelマシンでは通常、上記の公開結果に近い傾向になりますが、実際のp95は自分で計測しなければ分かりません。

判断の目安:

よくある落とし穴#

FP16でCPUが高速化すると期待する

症状: FP16エクスポートのサイズは半分ですが、速度はまったく変わりません。 対処: ほとんどのCPUでは、プラグインが実行精度を独自に選択します。ダウンロードサイズを小さくするにはFP16を、速度を上げるにはINT8またはiGPUを使用します。

すべてのエクスポートが終わってから検証する

症状: FP32とFP16の数値が同じファイルを使っていたため、同一の数値として報告されます。 対処: FP32とFP16のエクスポートは*_openvino_model/フォルダーを共有します。エクスポートごとに、直後に検証するかフォルダー名を変更してください。

アイドル状態のマシンでベンチマークする

症状: 平均値は問題ないのに、負荷が高い時間帯にはフレームがドロップします。 対処: 本番環境の負荷をかけた状態で推論時間を測定し、平均値ではなくp95を基準に判断します。1台のサーバーで多数のストリームを処理する場合は、レイテンシモードとスループットモードのガイドに従い、OpenVINOランタイムで.xmlを直接読み込み、THROUGHPUTヒントを指定してコンパイルします。

検証を実行するスクリプトをガードする

macOSとWindowsでは、検証時にワーカープロセスが起動し、スクリプトが再インポートされます。if __name__ == "__main__":がないと、このレッスンのテスト実行ではワーカー内でエクスポートが繰り返され、数分を無駄にするうえ、測定対象のCPUを取り合っていました。

試してみる

ターゲットCPUで、独自のモデルとデータセットYAMLを指定してov_compare.pyを実行し、本番負荷(または代替の負荷)をかけた状態で、ONNXとOpenVINOを使用してpick_runtime.pyを実行してください。精度またはランタイム、mAP50-95、サイズ、p95 msをまとめた簡潔な表と、どのモデルをリリースするかを示す一文を提出してください。

完了条件
以下のすべてを満たすと、レッスンは完了です。
  • 同じモデルのFP32、FP16、INT8のOpenVINOエクスポートを、同じデータで検証しました。

  • 現実的な負荷のもと、同じマシンで測定したOpenVINOとONNX Runtimeのp95レイテンシがあります。

  • 選択した精度とランタイムについて、mAPへの影響と実測した速度向上を根拠として示しています。

解答を表示
python ov_compare.py    # accuracy and size of FP32, FP16, INT8
python pick_runtime.py  # p50 and p95 for ONNX Runtime and OpenVINO

上記のCore Ultra 7 155Hの数値を使った判断例:

オプションmAP50-95規模画像あたりのミリ秒数
OpenVINO FP320.47349.6 MB13.43
OpenVINO INT80.46113.2 MB11.40
iGPU FP32 (intel:gpu)0.47589.6 MB9.13

統合GPUでOpenVINO FP32をデプロイします。最速の選択肢で精度も低下しない一方、CPUでINT8を使っても2 msの短縮と引き換えに1.2ポイントを失います。YOLO26mのデプロイでは、許容できる精度低下の範囲内であれば、CPU INT8(1.7ポイントの低下で2.9倍高速)を選ぶ判断に変わります。

次のステップ

単一フレームの検出は、より大きな仕組みを構成する基本要素です。次はトラッキングです。検出結果を、安定したIDを持つ持続的なオブジェクトに変換します。