Ultralytics YOLO27 : Inscris-toi sur la liste d’attente.
Get Started
Ultralytics YOLO en production·Optimiser·Leçon 4/9
Leçonintermédiaire

OpenVINO sur CPU

Exporte des modèles OpenVINO en FP32, FP16 et INT8, valide chacun d’eux et ne conserve INT8 que s’il apporte un gain sur ton propre CPU.

Un CPU Intel que tu possèdes déjà peut souvent remplacer une instance GPU : dans les benchmarks Ultralytics, YOLO26m passe de 192 ms dans PyTorch à 36 ms avec OpenVINO INT8 sur le CPU Core Ultra d’un ordinateur portable. Les gains dépendent toutefois de la puce ; sur l’ordinateur portable ARM utilisé pour les essais de ce cours, un export INT8 étalonné sur quatre images a perdu 3 points de mAP. Tu apprendras à déterminer lequel de ces cas s’applique avant le déploiement.

Résultat

Exporte des modèles OpenVINO en FP32, FP16 et INT8, compare leur précision et leur vitesse sur ton CPU et choisis-en un en justifiant ton choix par écrit.

Parcours accéléré
Si tu connais déjà les bases, voici la version courte.
  1. yolo export model=yolo26n.pt format=openvino génère yolo26n_openvino_model/.

  2. FP16 (quantize=16) divise la taille du fichier par deux, mais s’exécute à la vitesse de FP32 sur la plupart des CPU. INT8 (quantize=8 data=your.yaml) accélère l’exécution sur les CPU Intel.

  3. Choisis le périphérique Intel à l’inférence : device="intel:cpu", "intel:gpu" ou "intel:npu".

  4. Valide chaque précision avant que l’export suivant n’écrase son dossier ; compare les performances à ONNX Runtime sur la cible.

Pratique

Ce qu’apporte OpenVINO#

Écosystème OpenVINO : les modèles provenant de PyTorch, TensorFlow, Keras, TensorFlow Lite, ONNX, JAX et PaddlePaddle s’exécutent via OpenVINO sur les CPU (et ARM), GPU et NPU Intel, ainsi que sur des FPGA, sous Windows, Linux et macOS

OpenVINO prend en charge les modèles PyTorch et ONNX et les exécute sur les CPU Intel, les GPU intégrés et discrets, ainsi que les NPU, via une seule API. Ses noyaux CPU ciblent les jeux d’instructions Intel (AVX2, AVX-512, AMX), et sa prise en charge d’INT8 est mature. Remarque la case ARM dans la colonne CPU : OpenVINO fonctionne aussi sur ARM, mais ses noyaux sont optimisés pour Intel ; mesure donc les performances avant de t’y fier.

Le benchmark publié sur un CPU Intel Core Ultra 7 155H (COCO128) :

ModèlePyTorch FP32OpenVINO FP32OpenVINO INT8mAP50-95 FP32 → INT8
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

Trois règles se dégagent de ce tableau :

  • OpenVINO FP32 réduit à lui seul de moitié environ la latence de PyTorch sur un CPU Intel. Commence par là.
  • INT8 est d’autant plus avantageux que le modèle est grand : 1,2× pour n, 2,9× pour m, au prix de 1,2 à 1,7 point de mAP. Sur n, INT8 vaut rarement le coût en précision.
  • Essaie le GPU intégré avant d’acheter du matériel : l’iGPU Arc (device="intel:gpu") de la même puce a exécuté YOLO26n FP32 en 9,13 ms et YOLO26m en 34,47 ms.

Compare les précisions sur ton propre CPU#

Exporte chaque précision, valide-la immédiatement, puis seulement après exporte la suivante :

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/

Ce que chaque ligne t’indique :

  • FP32 et FP16 obtiennent le même score, et FP16 occupe deux fois moins d’espace (5,1 contre 9,6 Mo), mais les deux ont été enregistrés dans le même dossier. Si tu avais d’abord exporté les deux modèles avant de les valider, tu aurais mesuré deux fois FP16.
  • INT8 fait 3,2 Mo et a perdu 3,2 points, car son étalonnage reposait sur les quatre images de COCO8. L’avertissement le signale : un véritable étalonnage nécessite des centaines d’images représentatives de la production issues de ton propre fichier YAML (fraction limite leur nombre).
  • Rien de tout cela ne mesure la vitesse. Pour cela, utilise le benchmark ci-dessous.

Pour exécuter un modèle exporté sur un périphérique Intel précis :

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

Déploie le dossier complet : yolo26n.xml (le graphe), yolo26n.bin (les poids) et metadata.yaml. intel:gpu et intel:npu nécessitent du matériel Intel.

Mesure les performances par rapport à ONNX Runtime#

La précision est établie ; la vitesse se mesure sur la cible, dans les conditions de charge réelles. Exécute pick_runtime.py de la première leçon avec CANDIDATES = ("onnx", "openvino"). Sur l’ordinateur portable de test avec puce Apple, tandis que d’autres tâches partageaient le 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 avait une meilleure médiane, mais une queue de distribution nettement plus mauvaise. Le wrapper Ultralytics compile OpenVINO avec l’indication LATENCY (le journal affiche Using OpenVINO LATENCY mode for batch=1 inference on CPU), ce qui répartit chaque requête sur les cœurs du CPU ; lorsque d’autres tâches se disputent ces cœurs, les requêtes les plus lentes en pâtissent le plus. Sur une machine Intel dédiée, les résultats sont généralement ceux publiés ci-dessus, mais seul ton propre p95 peut te renseigner.

Règles de décision :

Pièges#

S'attendre à ce que FP16 accélère un CPU

Symptôme : l'export FP16 est deux fois plus petit, mais tout aussi lent. Solution : sur la plupart des CPU, le module d'extension choisit sa propre précision d'exécution ; utilise FP16 pour réduire la taille des téléchargements, et INT8 ou le GPU intégré pour accélérer.

Valider après tous les exports

Symptôme : FP32 et FP16 affichent des valeurs identiques, car il s'agissait du même fichier. Solution : les exports FP32 et FP16 partagent le dossier *_openvino_model/ ; valide-les (ou renomme le dossier) juste après chaque export.

Effectuer un benchmark sur une machine inactive

Symptôme : la moyenne semble correcte, mais des images sont tout de même perdues aux périodes de forte activité. Solution : mesure le temps d'inférence avec la charge de production en cours et base-toi sur le p95, pas sur la moyenne. Pour de nombreux flux sur un même serveur, compile avec l'indication THROUGHPUT en chargeant directement .xml avec l'environnement d'exécution OpenVINO, comme l'explique le guide sur les modes latence et débit.

Protéger les scripts de validation

Sur macOS et Windows, la validation démarre des processus de travail qui réimportent ton script. Sans if __name__ == "__main__":, l'exécution de test de cette leçon a répété les exports dans ces processus, perdant ainsi plusieurs minutes et mobilisant le CPU qu'elle tentait de mesurer.

Essayer

Sur le CPU cible, exécute ov_compare.py avec ton propre modèle et le fichier YAML de ton jeu de données, puis exécute pick_runtime.py avec ONNX et OpenVINO pendant que la charge de production (ou une simulation) est active. Fournis un tableau concis (précision ou environnement d’exécution, mAP50-95, taille, p95 en ms) et une phrase indiquant ce que tu déploierais.

Terminé lorsque
Tu as terminé la leçon lorsque tous les éléments suivants sont réunis.
  • Tu as validé les exports OpenVINO FP32, FP16 et INT8 du même modèle sur les mêmes données.

  • Tu disposes des latences p95 d’OpenVINO et d’ONNX Runtime mesurées sur la même machine sous une charge réaliste.

  • Ton choix de précision et de moteur indique le coût en mAP et le gain de vitesse que tu as mesurés.

Afficher la solution
python ov_compare.py    # accuracy and size of FP32, FP16, INT8
python pick_runtime.py  # p50 and p95 for ONNX Runtime and OpenVINO

Voici une décision concrète à partir des chiffres ci-dessus pour le Core Ultra 7 155H :

OptionmAP50-95Volumems par image
OpenVINO FP320.47349.6 MB13.43
OpenVINO INT80.46113.2 MB11.40
iGPU FP32 (intel:gpu)0.47589.6 MB9.13

Déploie OpenVINO FP32 sur le GPU intégré : c’est l’option la plus rapide et elle ne fait rien perdre, tandis que l’INT8 sur le CPU coûterait 1,2 point pour gagner 2 ms. Pour un déploiement de YOLO26m, la décision s’inverse en faveur du CPU INT8 (2,9× plus rapide pour 1,7 point), si cette perte reste dans ton budget.

Et ensuite ?

Les détections sur des images isolées sont la brique de base. Ensuite : le suivi, qui les transforme en objets persistants avec des ID stables.