Saltar al contenido principal

ONNX Runtime

Definición

ONNX Runtime (ORT) es una biblioteca de inferencia y aceleración de entrenamiento de código abierto y multiplataforma desarrollada por Microsoft. Su propósito principal es ejecutar modelos en el formato Open Neural Network Exchange (ONNX) — una representación intermedia independiente del framework para modelos de aprendizaje automático — con alto rendimiento en una amplia gama de objetivos de hardware y sistemas operativos. ORT no está vinculado a ningún framework de entrenamiento único: los modelos de PyTorch, TensorFlow, scikit-learn, LightGBM, XGBoost y otros pueden exportarse a ONNX y ejecutarse a través de la misma API de runtime, lo que lo convierte en una de las soluciones de inferencia más interoperables disponibles.

En su núcleo, ORT carga un grafo ONNX, aplica una extensa serie de optimizaciones a nivel de grafo (plegado de constantes, fusión de nodos, transformación de diseño) y despacha operaciones al mejor proveedor de ejecución disponible para el hardware actual. La abstracción del Proveedor de Ejecución (EP) permite a ORT enrutar subgrafos a CPU, GPU NVIDIA a través de CUDA o TensorRT, GPU AMD a través de ROCm, hardware Intel a través de OpenVINO, Apple Silicon a través de CoreML, Android a través de NNAPI y Windows a través de DirectML — todo a través de una superficie de API unificada. Esto hace que ORT sea adecuado para un espectro de despliegue que va desde servidores en la nube hasta laptops con Windows, pasando por dispositivos móviles.

ONNX Runtime es particularmente valioso en entornos empresariales y de producción donde una única canalización de despliegue debe servir modelos entrenados en diferentes frameworks. Es el backend de inferencia que impulsa los endpoints de Azure ML, la biblioteca Optimum de Hugging Face, Windows ML y muchos sistemas de recomendación y clasificación en producción.

Cómo funciona

Formato ONNX e interoperabilidad de modelos

ONNX representa un modelo como un grafo de cómputo acíclico dirigido donde los nodos son operadores estandarizados (p. ej. Conv, MatMul, LayerNormalization) definidos en la especificación de operadores ONNX, y las aristas llevan tensores tipados. El formato está versionado: cada versión de opset de ONNX (actualmente 21) define el conjunto completo de operadores soportados y sus semánticas. El archivo .onnx serializado en protobuf incluye la topología del grafo, nombres de operadores, formas de tensores y valores de pesos constantes, haciendo que el formato sea autónomo y portátil.

Optimizaciones de grafo

Cuando se crea una InferenceSession, ORT aplica tres niveles de optimización de grafo controlados por la configuración GraphOptimizationLevel. El nivel 1 (básico) realiza reescrituras seguras: plegado de constantes, eliminación de nodos redundantes, inferencia de formas y eliminación de identidades. El nivel 2 (extendido) agrega fusión de operaciones: Conv + BatchNorm, Conv + Relu, Transpose + MatMul y patrones similares se fusionan en kernels únicos. El nivel 3 (optimización de diseño) reestructura los diseños de memoria de tensores para coincidir con lo que prefieren los proveedores de ejecución.

Proveedores de ejecución

El mecanismo de Proveedor de Ejecución es el principal palanca de extensibilidad y rendimiento de ORT. El EP de CPU usa MLAS (Microsoft Linear Algebra Subprograms), una implementación BLAS vectorizada a mano con soporte AVX-512 y NEON. El EP de CUDA descarga convoluciones y GEMMs a cuDNN y cuBLAS. El EP de TensorRT aplica la fusión de capas y calibración de precisión de TensorRT para FP16 e INT8. El EP de CoreML delega al Neural Engine de Apple en macOS e iOS. El EP de DirectML soporta inferencia acelerada por hardware en cualquier GPU compatible con DirectX 12 en Windows.

Cuantización en ONNX Runtime

ORT soporta inferencia INT8 a través del patrón de nodo QDQ (Quantize-Dequantize): el grafo ONNX contiene nodos explícitos QuantizeLinear y DequantizeLinear que representan los límites de precisión. La cuantización estática requiere un conjunto de datos de calibración para calcular escalas de entrada/salida; el paquete Python onnxruntime.quantization proporciona funciones quantize_static y quantize_dynamic.

Despliegue móvil y en el borde

ORT Mobile es una compilación reducida de ONNX Runtime para Android e iOS que elimina operadores no utilizados y bibliotecas EP, reduciendo el tamaño binario a ~1-3 MB comprimido. En Android, el EP de NNAPI delega al acelerador de hardware. En iOS y macOS, el EP de CoreML usa el Apple Neural Engine.

Cuándo usar / Cuándo NO usar

Usar cuandoEvitar cuando
Necesitas inferencia independiente del framework — servir modelos de PyTorch, TF y scikit-learn a través de un solo runtimeTu objetivo de despliegue es un microcontrolador con <256 KB de RAM (TFLM lo cubre mejor)
Estás construyendo pipelines de ML empresariales en Windows/Azure donde las herramientas de Microsoft ya están en usoNecesitas delegación de hardware Android profunda con herramientas maduras hoy (TFLite es más probado para Android)
Necesitas aceleración NVIDIA TensorRT sin gestionar directamente la API de TensorRTTu modelo usa operaciones personalizadas que no tienen equivalente ONNX y son impracticables de registrar
Quieres inferencia en el navegador/WASM para el mismo modelo que se ejecuta en el lado del servidorTu equipo es nativo de PyTorch y quiere el bucle más ajustado posible desde el entrenamiento hasta el móvil
La portabilidad multiplataforma es una preocupación de primera clase (mismo modelo en Windows, Linux, macOS, Android, iOS)Necesitas entrenamiento en tiempo real o aprendizaje en línea en el borde

Comparaciones

Comparación de ONNX Runtime con TFLite y PyTorch Mobile para despliegue en el borde y multiplataforma.

CriterioONNX RuntimeTensorFlow LitePyTorch Mobile
Soporte de plataformaWindows, Linux, macOS, Android, iOS, WASM, nube — cobertura más ampliaAndroid, iOS, Linux embebido, microcontroladores (TFLM)Android, iOS; ExecuTorch agrega embebido y bare-metal
Conversión de modelosCualquier framework → exportación ONNX (ruta más interoperable, múltiples convertidores)TF/Keras → TFLite Converter (maduro, solo ecosistema TF)PyTorch → TorchScript o ExecuTorch (nativo de PyTorch, menor fricción para usuarios de PT)
Rendimiento en dispositivoEP de CPU con MLAS es competitivo; EPs TensorRT/CUDA lideran para GPU; EPs CoreML/NNAPI para móvilExcelente en Android via NNAPI/delegado GPU; mejor en su clase para microcontroladoresXNNPACK en CPU ARM; Vulkan GPU; delegación de NPU ExecuTorch
EcosistemaIndependiente del framework; Hugging Face Optimum; Windows ML; Azure ML; fuerte adopción empresarialMaduro: MediaPipe, TF Hub, Model Garden; la comunidad móvil de ML más grandeFuerte en investigación; Hugging Face; comunidad ExecuTorch en crecimiento
Soporte de cuantizaciónINT8 via nodos QDQ; PTQ dinámico y estático; QAT; INT8 de hardware via EPCompleto: rango dinámico, INT8, FP16, QAT con rutas INT8 completasPTQ (INT8 dinámico + estático) y QAT via torch.ao.quantization

Pros y contras

ProsContras
Independiente del framework: cualquier modelo exportable a ONNX funciona con el mismo runtimeLa exportación ONNX puede fallar para modelos con ops no soportadas o personalizadas
Mayor cobertura de proveedor de ejecución: CPU, CUDA, TensorRT, DirectML, CoreML, NNAPI, OpenVINODepurar grafos ONNX es más difícil que depurar en el framework nativo
Fuerte integración con Windows y Azure; ciudadano de primera clase en el stack ML de MicrosoftMás complejidad operativa que TFLite para escenarios puros de Android/iOS
Hugging Face Optimum proporciona cuantización y optimización de alto nivel para transformersEl versionado del opset ONNX puede crear fricción de compatibilidad entre exportadores y versiones de ORT
Rendimiento CPU competitivo via MLAS con vectorización AVX-512 y NEONEl tamaño binario móvil es mayor que TFLite cuando se incluyen todos los EPs

Ejemplos de código

import numpy as np
import torch
import torch.nn as nn
import onnxruntime as ort

# ── 1. Define a simple model in PyTorch ───────────────────────────────────────
class SimpleClassifier(nn.Module):
"""Minimal classifier for demonstration."""

def __init__(self, input_dim: int = 784, num_classes: int = 10):
super().__init__()
self.net = nn.Sequential(
nn.Linear(input_dim, 128),
nn.ReLU(),
nn.Linear(128, 64),
nn.ReLU(),
nn.Linear(64, num_classes),
)

def forward(self, x: torch.Tensor) -> torch.Tensor:
return self.net(x)


model = SimpleClassifier()
# Switch to inference mode: disables dropout, BatchNorm uses running statistics
model.train(False)

# ── 2. Export PyTorch model to ONNX ──────────────────────────────────────────
dummy_input = torch.randn(1, 784) # batch=1, flattened 28x28 image

torch.onnx.export(
model,
dummy_input,
"model.onnx",
opset_version=17, # target ONNX opset
input_names=["input"],
output_names=["logits"],
dynamic_axes={
"input": {0: "batch_size"}, # allow variable batch size
"logits": {0: "batch_size"},
},
do_constant_folding=True, # fold constant sub-expressions during export
)
print("Exported model.onnx")

# ── 3. Apply INT8 post-training dynamic quantization ─────────────────────────
from onnxruntime.quantization import quantize_dynamic, QuantType

quantize_dynamic(
"model.onnx",
"model_int8.onnx",
weight_type=QuantType.QInt8, # quantize weights to INT8
)
print("Quantized model saved as model_int8.onnx")

# ── 4. Run inference with ONNX Runtime ───────────────────────────────────────
# SessionOptions allow controlling graph optimization level and thread counts
sess_options = ort.SessionOptions()
sess_options.graph_optimization_level = ort.GraphOptimizationLevel.ORT_ENABLE_ALL

# Providers list is checked in order; falls back to CPU if GPU is unavailable
providers = ["CUDAExecutionProvider", "CPUExecutionProvider"]
session = ort.InferenceSession("model_int8.onnx", sess_options, providers=providers)

print(f"Active execution provider: {session.get_providers()[0]}")

# Prepare a batch of random inputs as float32 numpy arrays
batch = np.random.randn(4, 784).astype(np.float32)
input_name = session.get_inputs()[0].name
output_name = session.get_outputs()[0].name

outputs = session.run([output_name], {input_name: batch})
logits = outputs[0] # shape (4, 10)
predicted_classes = np.argmax(logits, axis=1)
print(f"Batch predictions: {predicted_classes}")

Recursos prácticos

  • Documentación de ONNX Runtime — referencia oficial que cubre instalación, proveedores de ejecución, optimización de grafos, cuantización y despliegue móvil para todas las plataformas soportadas.
  • Referencia de API Python de ONNX Runtime — documentación detallada de la API para InferenceSession, SessionOptions, proveedores de ejecución y el subpaquete de cuantización.
  • Hugging Face Optimum — biblioteca de alto nivel que envuelve ORT para la optimización de modelos transformer, proporcionando clases ORTModelForXxx y ORTQuantizer para exportación e INT8 en un solo paso.
  • ONNX Model Zoo — repositorio curado de modelos ONNX preentrenados que abarca visión por computadora, PLN, voz y ML clásico.
  • Guía de despliegue móvil de ONNX Runtime — tutorial paso a paso para construir una aplicación ORT mínima para Android o iOS.

Ver también