Ultralytics YOLO27: Únete a la lista de espera.
Get Started
Ultralytics YOLO en producción·Optimizar·Lección 4/9
Lecciónintermedio

OpenVINO en CPU

Exporta modelos OpenVINO en FP32, FP16 e INT8, valida cada uno y conserva INT8 solo cuando te aporte ventajas en tu propia CPU.

Una CPU Intel que ya tengas puede sustituir a menudo una instancia con GPU: en las pruebas de rendimiento de Ultralytics, YOLO26m pasa de 192 ms en PyTorch a 36 ms con OpenVINO INT8 en una CPU Core Ultra de portátil. Sin embargo, las mejoras dependen del chip y, en el portátil de prueba ARM de este curso, una exportación INT8 calibrada con cuatro imágenes perdió 3 puntos de mAP. Aprenderás a medir en qué caso estás antes de publicar.

Resultado

Exporta modelos OpenVINO en FP32, FP16 e INT8, compara su precisión y velocidad en tu CPU y elige uno justificando la decisión por escrito.

Vía rápida
Si ya tienes experiencia, aquí tienes un resumen.
  1. yolo export model=yolo26n.pt format=openvino genera yolo26n_openvino_model/.

  2. FP16 (quantize=16) reduce el tamaño del archivo a la mitad, pero en la mayoría de las CPU se ejecuta a la velocidad de FP32. INT8 (quantize=8 data=your.yaml) es lo que acelera la ejecución en CPU Intel.

  3. En la inferencia, selecciona el dispositivo Intel: device="intel:cpu", "intel:gpu" o "intel:npu".

  4. Valida cada nivel de precisión antes de que la siguiente exportación sobrescriba su carpeta; compara el rendimiento con ONNX Runtime en el dispositivo de destino.

Práctico

Qué ofrece OpenVINO#

Ecosistema OpenVINO: los modelos de PyTorch, TensorFlow, Keras, TensorFlow Lite, ONNX, JAX y PaddlePaddle se ejecutan mediante OpenVINO en CPU Intel (y ARM), GPU Intel, NPU Intel y FPGA con Windows, Linux y macOS

OpenVINO acepta modelos de PyTorch y ONNX y los ejecuta en CPU Intel, GPU integradas y discretas y NPU mediante una única API. Sus kernels de CPU están optimizados para los conjuntos de instrucciones de Intel (AVX2, AVX-512, AMX), y su ruta INT8 está muy desarrollada. Fíjate en el recuadro ARM de la columna de CPU: OpenVINO también funciona en ARM, pero sus kernels están optimizados para Intel, así que mide el rendimiento antes de confiar en él.

La prueba de rendimiento publicada en una CPU Intel Core Ultra 7 155H (COCO128):

ModeloPyTorch FP32OpenVINO FP32OpenVINO INT8mAP50-95 de FP32 a 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

De esa tabla se desprenden tres reglas:

  • OpenVINO FP32 por sí solo reduce aproximadamente a la mitad la latencia de PyTorch en una CPU Intel. Empieza por aquí.
  • INT8 aporta más ventajas a medida que crece el modelo: 1,2× para n, 2,9× para m, a cambio de entre 1,2 y 1,7 puntos de mAP. En n, INT8 rara vez compensa la pérdida de precisión.
  • Prueba la GPU integrada antes de comprar hardware: la iGPU Arc del mismo chip (device="intel:gpu") ejecutó YOLO26n FP32 en 9,13 ms y YOLO26m en 34,47 ms.

Compara los niveles de precisión en tu propia CPU#

Exporta cada nivel de precisión, valídalo inmediatamente y solo entonces exporta el siguiente:

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/

Qué indica cada línea:

  • FP32 y FP16 obtienen la misma puntuación y FP16 ocupa la mitad (5,1 frente a 9,6 MB), pero ambos se escribieron en la misma carpeta. Si hubieras exportado ambos primero y los hubieras validado después, habrías medido FP16 dos veces.
  • INT8 ocupa 3,2 MB y perdió 3,2 puntos, porque se calibró con las cuatro imágenes de COCO8. La advertencia lo indica: una calibración real necesita cientos de imágenes representativas de producción de tu propio YAML (fraction limita cuántas se usan).
  • Nada de esto mide la velocidad. Para eso, usa la prueba de rendimiento de abajo.

Para ejecutar un modelo exportado en un dispositivo Intel concreto:

from ultralytics import YOLO

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

Publica la carpeta completa: yolo26n.xml (el grafo), yolo26n.bin (los pesos) y metadata.yaml. intel:gpu y intel:npu necesitan hardware Intel.

Mídelo frente a ONNX Runtime#

La precisión ya está resuelta; la velocidad se determina en el dispositivo de destino, bajo la carga de trabajo real que deberá soportar. Ejecuta pick_runtime.py de la primera lección con CANDIDATES = ("onnx", "openvino"). En el portátil de prueba con Apple silicon, mientras otros trabajos compartían la 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 tuvo una mediana mejor y una cola mucho peor. El wrapper de Ultralytics compila OpenVINO con la sugerencia LATENCY (el registro indica Using OpenVINO LATENCY mode for batch=1 inference on CPU), que distribuye cada solicitud entre los núcleos de la CPU; cuando otras tareas compiten por esos núcleos, las solicitudes más lentas son las que más sufren. En un equipo Intel dedicado, los resultados suelen parecerse a los publicados arriba, pero solo tu propio p95 puede confirmártelo.

Reglas para decidir:

Errores habituales#

Esperar que FP16 acelere una CPU

Síntoma: la exportación FP16 ocupa la mitad y es igual de lenta. Solución: en la mayoría de las CPU, el complemento elige su propia precisión de ejecución; usa FP16 para reducir el tamaño de las descargas e INT8 o la iGPU para ganar velocidad.

Validar después de todas las exportaciones

Síntoma: FP32 y FP16 muestran cifras idénticas porque eran el mismo archivo. Solución: las exportaciones FP32 y FP16 comparten la carpeta *_openvino_model/; valida (o cambia el nombre de la carpeta) justo después de cada exportación.

Evaluar el rendimiento en una máquina inactiva

Síntoma: la media parece correcta, pero se siguen perdiendo fotogramas en los momentos de mayor actividad. Solución: mide el tiempo de inferencia con la carga de producción en marcha y fíjate en el p95, no en la media. Para ejecutar muchas secuencias en un servidor, compila con la sugerencia THROUGHPUT cargando .xml directamente con el entorno de ejecución de OpenVINO, como se explica en la guía sobre modos de latencia y rendimiento.

Proteger los scripts que validan

En macOS y Windows, la validación inicia procesos de trabajo que vuelven a importar tu script. Sin if __name__ == "__main__":, la prueba de esta lección repitió las exportaciones dentro de esos procesos, desperdició minutos y compitió por la CPU que intentaba medir.

Pruébalo

En la CPU de destino, ejecuta ov_compare.py con tu propio modelo y el YAML del conjunto de datos; después, ejecuta pick_runtime.py con ONNX y OpenVINO mientras está activa la carga de producción (o una carga simulada). Entrega una tabla breve (precisión o entorno de ejecución, mAP50-95, tamaño, p95 en ms) y una frase que indique qué publicarías.

Cuándo se considera terminado
Has terminado la lección cuando se cumplen todas estas condiciones.
  • Has validado exportaciones OpenVINO en FP32, FP16 e INT8 del mismo modelo con los mismos datos.

  • Tienes las latencias p95 de OpenVINO y ONNX Runtime obtenidas en la misma máquina con una carga realista.

  • Al elegir la precisión y el runtime, indicas el coste en mAP y la mejora de velocidad que has medido.

Mostrar solución
python ov_compare.py    # accuracy and size of FP32, FP16, INT8
python pick_runtime.py  # p50 and p95 for ONNX Runtime and OpenVINO

Una decisión práctica con los valores anteriores del Core Ultra 7 155H:

OpciónmAP50-95Cantidadms por imagen
OpenVINO FP320.47349.6 MB13.43
OpenVINO INT80.46113.2 MB11.40
iGPU FP32 (intel:gpu)0.47589.6 MB9.13

Despliega OpenVINO FP32 en la GPU integrada: es la opción más rápida y no pierde precisión, mientras que INT8 en la CPU costaría 1,2 puntos para ahorrar 2 ms. En un despliegue de YOLO26m, la respuesta cambia a CPU INT8 (2,9 veces más rápido por 1,7 puntos), si esa pérdida entra en tu presupuesto.

Qué viene después

Las detecciones en fotogramas individuales son el componente básico. Siguiente paso: seguimiento, que las convierte en objetos persistentes con ID estables.