Guía de ONNX Runtime: acelerando la IA local en ordenadores Windows 11

  • ONNX Runtime permite ejecutar modelos ONNX en local sobre Windows 11 aprovechando CPU, GPU y otros aceleradores mediante distintos execution providers.
  • WinML integra ONNX Runtime en el propio sistema operativo y simplifica la selección del hardware óptimo, la carga de modelos y el despliegue en aplicaciones Windows.
  • Con .NET y WinUI 3 es posible crear aplicaciones de escritorio que cargan imágenes, las procesan y obtienen predicciones de modelos ONNX como ResNet de forma eficiente.
  • El ecosistema de ONNX Runtime ofrece builds para múltiples lenguajes y plataformas, así como opciones avanzadas para usar varias versiones, procesos separados y entrenamiento optimizado.

Guía de ONNX Runtime acelerando la IA local en ordenadores Windows 11

Si te apetece llevar la inteligencia artificial directamente a tu PC con Windows 11 sin depender de la nube, ONNX Runtime es ahora mismo una de las piezas clave del puzle. Esta guía está pensada para que entiendas qué es, cómo se integra con WinML, qué necesitas instalar y cómo puedes aprovecharlo tanto con .NET (C#, VB.NET) como con otros lenguajes y aceleradores de hardware.

A lo largo del texto vas a ver explicaciones técnicas, ejemplos de uso real y detalles de instalación, pero todo con un tono cercano. La idea es que, cuando acabes de leer, tengas claro cómo montar en Windows 11 una aplicación que cargue modelos ONNX, los ejecute de forma eficiente (CPU, GPU o NPU) y se integre bien con el ecosistema moderno de Windows.

Qué es ONNX Runtime y por qué encaja tan bien con Windows 11

ONNX Runtime es un motor de ejecución multiplataforma pensado para cargar y puntuar modelos de machine learning y deep learning en formato ONNX (Open Neural Network Exchange). Este formato es un estándar abierto que permite entrenar modelos en frameworks como PyTorch, TensorFlow, Keras, TFLite o scikit-learn y, después, exportarlos a ONNX para poder ejecutarlos en casi cualquier entorno.

Dentro de este ecosistema, Windows 10 (a partir de la versión 1809) y todo Windows 11 ya incluyen una copia integrada de ONNX Runtime a través de Windows Machine Learning (WinML), en la biblioteca Microsoft.Windows.AI.MachineLearning.dll. Esa copia ofrece ejecución sobre CPU y sobre GPU mediante DirectML, de forma que puedes sacar partido de la GPU sin tener que pelearte tú directamente con controladores y capas de bajo nivel.

El diseño de ONNX Runtime destaca porque permite conectar diferentes “execution providers” (EP), que son los responsables de mapear los cálculos del modelo sobre el hardware disponible: CPU, GPU DirectML, CUDA, TensorRT, NPU, FPGA, etc. Esto convierte a ONNX Runtime en una especie de capa de abstracción que simplifica mucho la vida al desarrollador.

Además, en Windows 11 reciente (especialmente desde la versión 24H2) WinML se apoya en ONNX Runtime y automatiza la elección del EP más adecuado para el dispositivo del usuario, pudiendo cambiar entre CPU, GPU y otros aceleradores según el hardware disponible, sin que tú tengas que reescribir toda tu aplicación cada vez.

Modelos ONNX: cómo son y qué ventajas tienen en local

Un modelo en formato ONNX es, en esencia, una representación portable de una red neuronal o algoritmo de ML ya entrenado. El archivo incluye la arquitectura de la red (capas, conexiones, tipos de operaciones), los pesos aprendidos durante el entrenamiento y la descripción formal de las entradas y salidas esperadas.

Por ejemplo, un modelo de clasificación de imágenes suele recibir una imagen preprocesada (por ejemplo 224×224 píxeles en RGB) y devolver un vector de probabilidades donde cada posición está asociada a una etiqueta (perro, gato, barco, etc.). El índice que ocupa cada etiqueta en ese vector viene definido por una lista de clases que normalmente encontrarás acompañando al modelo en el repositorio o en el zoo de modelos de ONNX.

La gran gracia de trabajar con ONNX en Windows 11 es que puedes ejecutar esos modelos de forma completamente local, sin enviar datos a servidores externos. Esto tiene implicaciones claras en términos de privacidad, coste y latencia:

  • Privacidad: las imágenes, textos o datos sensibles nunca salen de tu máquina.
  • Coste: no dependes de servicios de pago en la nube para inferencia.
  • Velocidad: eliminas la latencia de red y aprovechas mejor CPU, GPU o NPU.
  • Control: puedes decidir qué modelos usar, cuándo actualizarlos y cómo desplegarlos.

En el caso concreto de Windows, WinML y ONNX Runtime facilitan muchísimo la integración con el sistema: puedes pasar directamente objetos como Windows.Media.VideoFrame (capturados de la cámara) al modelo para hacer inferencia en tiempo real, algo perfecto para escenarios de visión por computador en escritorio.

WinML y ONNX Runtime en Windows 11: cómo encajan

Arquitectura WinML y ONNX Runtime

Dentro de Windows, WinML (Windows Machine Learning) es la API WinRT de alto nivel que expone capacidades de inferencia sobre modelos ONNX. Se distribuye como parte del propio sistema operativo (desde Windows 10 1809) y también puede instalarse como paquete redistribuible para aplicaciones que necesiten versiones concretas.

WinML utiliza internamente ONNX Runtime, pero su objetivo es simplificar la vida al desarrollador de aplicaciones Windows: ofrece integración nativa con tipos del sistema (como VideoFrame), automatiza la selección del proveedor de ejecución y despliega de forma unificada las dependencias necesarias para correr modelos de IA en el cliente.

A grandes rasgos, en Windows 11 tienes dos formas de interactuar con ONNX Runtime:

  • Usar la API WinRT (WinML): especialmente recomendable en Windows 11 24H2 o superior, donde WinML pule la selección de EP y ofrece soporte amplio para distintos fabricantes de silicio.
  • Usar directamente la API C de ONNX Runtime o sus bindings (C#, C++, Python, Java, etc.), lo cual te da más control sobre qué versión de la DLL usas y qué EP activas en cada caso.
  Apple CarPlay se prepara para la reproducción de vídeo en el coche

Si ya tienes código escrito contra el espacio de nombres Windows.AI.MachineLearning, actualizarlo para usar el paquete NuGet de Microsoft.ML.OnnxRuntime y las APIs asociadas es relativamente directo: básicamente cambias referencias de espacio de nombres Windows por Microsoft y ajustas tipos equivalentes, manteniendo en esencia la misma lógica.

En versiones anteriores de Windows 11 y en Windows 10 (1809+), ONNX Runtime funciona igualmente, pero tendrás que gestionar tú mismo la elección de modelos y execution providers, mientras que en Windows 11 24H2+ WinML te ahorra gran parte de esa complejidad.

Requisitos previos en Windows 11 y variantes de instalación

Para trabajar cómodamente con ONNX Runtime en ordenadores con Windows 11, conviene revisar algunos requisitos básicos a nivel de sistema, herramientas de desarrollo y bibliotecas adicionales:

  • Windows 11 o Windows 10 (1809+): las APIs de WinML y la copia integrada de ONNX Runtime se encuentran disponibles a partir de esas versiones.
  • Visual C++ 2019 Runtime: las builds oficiales de ONNX Runtime para Windows necesitan este runtime instalado; es recomendable tener la versión más reciente.
  • Modo desarrollador habilitado: si vas a desplegar y depurar aplicaciones UWP o WinUI3 en local, activa el modo desarrollador en la configuración de Windows.
  • Visual Studio 2022 o posterior: si tu idea es crear aplicaciones de escritorio con .NET (C#, VB.NET), instala la carga de trabajo de “desarrollo de aplicaciones de escritorio .NET”.

Cuando hablamos de aceleración por GPU en Windows, hay varios frentes a tener en cuenta y las combinaciones varían según el lenguaje y la distribución que elijas:

  • Paquetes Python: puedes instalar onnxruntime (CPU) o paquetes específicos para GPU (CUDA, TensorRT, DirectML) teniendo en cuenta los requisitos de CUDA y cuDNN. Para los paquetes GPU es obligatorio alinear la versión de CUDA y cuDNN con la tabla de compatibilidad oficial.
  • Paquetes C#/C/C++: ONNX Runtime ofrece builds para CPU, GPU con CUDA (11.8 o 12.x) y paquetes orientados a DirectML (aunque DirectML está en modo “sustained engineering”; para proyectos nuevos de Windows se aconseja WinML).
  • JavaScript y móvil: existen builds para navegadores (ONNX Runtime Web), Node.js, React Native, iOS y Android, con opciones de compilación personalizada para recortar operadores y reducir tamaño.

En entornos con GPU NVIDIA, los paquetes GPU de ONNX Runtime requieren CUDA y cuDNN configurados correctamente. En Windows, las carpetas bin de CUDA y cuDNN deben estar añadidas a la variable de entorno PATH. En Linux, se añade lib64 y las bibliotecas de cuDNN a LD_LIBRARY_PATH; además, algunas versiones de cuDNN requieren zlib instalado.

Instalación de ONNX Runtime y WinML en proyectos .NET

Si trabajas con .NET en Windows 11, tienes varios caminos para integrar ONNX Runtime, pero los dos más habituales son usar directamente los paquetes NuGet de ONNX Runtime o apoyarte en WinML con la copia integrada en Windows ML.

En un proyecto típico de escritorio con C# y WinUI3, el flujo sería algo así:

  1. Crear en Visual Studio un proyecto “Aplicación vacía, empaquetada (WinUI 3 en escritorio)” y nombrarlo, por ejemplo, ONNXWinUIExample.
  2. Abrir el Administrador de paquetes NuGet para ese proyecto y añadir los paquetes necesarios.

Para un escenario de clasificación de imágenes acelerado por GPU con DirectML desde C#, suele añadirse al menos:

  • Microsoft.ML.OnnxRuntime.DirectML: expone las APIs de ONNX Runtime con soporte para ejecución acelerada sobre GPU usando DirectML.
  • SixLabors.ImageSharp: proporciona herramientas potentes para cargar y procesar imágenes, reescalarlas y normalizarlas antes de pasarlas al modelo.
  • SharpDX.DXGI (u otro acceso a DirectX): permite seleccionar adaptadores gráficos y coordinar la integración con DirectML.

Una vez instalados los paquetes, en el archivo de código principal (por ejemplo MainWindow.xaml.cs) se añaden las directivas using necesarias para trabajar con InferenceSession, tensores y procesamiento de imágenes. Con eso ya puedes crear tu sesión de inferencia y preparar datos de entrada.

Ejemplo práctico: app WinUI 3 en Windows 11 que clasifica imágenes

Guía de ONNX Runtime para ordenadores Windows 11

Uno de los ejemplos más ilustrativos consiste en crear una aplicación WinUI 3 que permita elegir una foto, ejecutarla contra un modelo ONNX (por ejemplo ResNet50 v2) y mostrar en pantalla las etiquetas más probables con sus porcentajes de confianza.

En la parte de interfaz XAML, basta una vista muy sencilla con:

  • Un botón para seleccionar la imagen mediante un cuadro de diálogo de archivos.
  • Un control Image para mostrar la foto elegida por el usuario.
  • Un TextBlock para listar las predicciones devueltas por el modelo.

En el manejador del botón se suele usar un FileOpenPicker configurado para permitir extensiones comunes de imagen (.jpg, .jpeg, .png, .gif), inicializado con el identificador de ventana correcto (vía InitializeWithWindow.Initialize) para que funcione bien en aplicaciones WinUI de escritorio. Una vez el usuario selecciona el fichero, se carga como BitmapImage y se asigna al control Image.

  Herramientas de gestión de ventanas en Windows para exprimir tu productividad

Después llega la parte interesante: preprocesar la imagen para adaptarla al formato que el modelo espera. Con ImageSharp puedes abrir la imagen en formato RGB de 24 bits, redimensionarla a 224×224 píxeles (si el modelo lo requiere) y normalizar los valores de píxel usando medias y desviaciones típicas concretas, del estilo 255× para la media y 255× para la desviación estándar en clasificación tipo ImageNet.

Inicialización del modelo y ejecución con DirectML

Para ejecutar el modelo ONNX desde C# en Windows 11 con aceleración de GPU, lo habitual es crear una InferenceSession configurada con el execution provider de DirectML. Previamente, puedes usar SharpDX.DXGI para enumerar adaptadores gráficos y elegir el que quieras, aunque lo más común es empezar con el primer adaptador disponible.

Esta configuración se suele encapsular en un método de ayuda (por ejemplo, InitModel) que:

  • Comprueba si ya existe una sesión de inferencia inicializada.
  • Utiliza una Factory1 de DXGI para seleccionar un adapter (Adapter1).
  • Crea un objeto SessionOptions en ONNX Runtime, establece el nivel de logging deseado y llama a AppendExecutionProvider_DML con el identificador del dispositivo.
  • Inicializa la InferenceSession apuntando al archivo .onnx dentro de una carpeta de modelo incluida en el proyecto (por ejemplo, “model\resnet50-v2-7.onnx”).

El modelo ResNet50 v2 se puede descargar en formato ONNX desde el repositorio oficial de modelos de ONNX. Una vez descargado, se incluye en el proyecto dentro de una carpeta “model” y se configura el archivo con la opción “Copiar al directorio de salida – Copiar si es más reciente” en Visual Studio, para que esté siempre disponible junto al ejecutable.

En el manejador del botón se suele invocar InitModel solo si la sesión no está inicializada aún, con lo que la primera inferencia tarda un poco más y las siguientes son bastante más rápidas, porque la sesión y los recursos ya están listos.

Preparación de tensores, inferencia y postprocesado de resultados

Una vez que tienes la imagen normalizada en memoria, el siguiente paso es organizar los datos en un tensor con la forma que el modelo espera. En el caso típico de clasificación con ResNet, la forma suele ser (batch size 1, tres canales RGB, 224×224 píxeles).

Con DenseTensor<float> puedes crear un buffer multi-dimensional que facilita el acceso con índices . Al recorrer las filas de píxeles (por ejemplo con el patrón ProcessPixelRows de ImageSharp), se van asignando los valores normalizados al tensor, canal por canal (R, G, B).

Para reducir copias y sacar más rendimiento, ONNX Runtime permite crear un OrtValue que use directamente el buffer gestionado del DenseTensor, anclándolo en memoria (pin) para que el recolector de basura no lo mueva mientras el runtime lo está usando. Con eso se evita replicar los datos dentro del motor.

El diccionario de entradas se construye asignando el nombre que el modelo espera (por ejemplo, “data”) al OrtValue creado. A continuación se llama a _inferenceSession.Run con las opciones deseadas y la lista de nombres de salida, obteniendo una colección de OrtValue como resultado.

En muchos modelos de clasificación, la salida es simplemente un vector de logits que necesitan un softmax para transformarse en probabilidades entre 0 y 1. Para ello se suelen copiar los datos a un array, aplicar exp(x) a cada valor, sumarlos y dividir cada exponencial por esa suma, obteniendo así la probabilidad normalizada por clase.

Mapeo de etiquetas, top-k y presentación al usuario

El último paso de la tubería es transformar ese vector de probabilidades en algo que el usuario pueda entender fácilmente. Cada índice de la salida corresponde a una clase de la lista de etiquetas con la que se entrenó el modelo, por lo que necesitas disponer de un mapeo de índices a cadenas de texto.

Una práctica común es definir una clase estática, por ejemplo LabelMap, que incluya un array de strings con todas las etiquetas del modelo en el orden exacto en que fueron usadas durante el entrenamiento. Este listado suele ser largo (en el caso de ImageNet, miles de clases), así que normalmente se copia desde archivos de ejemplo oficiales o repos de referencia.

En el código de C#, se puede crear una pequeña clase auxiliar Prediction con dos propiedades: Label (la etiqueta textual) y Confidence (el valor de probabilidad). A partir del vector de probabilidades, con una proyección Select que incluya el índice, se genera una secuencia de Prediction, se ordena en orden descendente por Confidence y se toma, por ejemplo, el top 10.

  Gestores de ventanas alternativos para optimizar tu flujo de trabajo

Esos resultados se envían al TextBlock de la interfaz con un formato legible, indicando algo tipo “Etiqueta: X, Confianza: Y”. El usuario ve un listado de las 10 clases más probables para la imagen seleccionada, con porcentajes que suman aproximadamente 1 (gracias al softmax), lo que facilita entender qué ha detectado el modelo y con qué seguridad.

Una vez desplegado el proyecto y ejecutada la app, basta con pulsar el botón de elegir foto, localizar una imagen en el disco y dejar que la aplicación inicialice el modelo si es la primera vez. Tras la inferencia, aparece la lista de predicciones ordenada, permitiendo probar rápidamente diferentes imágenes para comprobar cómo responde el modelo.

Uso de ONNX Runtime desde otros lenguajes en Windows 11

Además de C# y WinUI, ONNX Runtime se puede consumir casi igual que en otros sistemas operativos cuando trabajas en Windows 11 con Python, C++ o incluso JavaScript.

En Python, si instalas la versión integrada a través de Windows ML, el módulo se importa como de costumbre con import onnxruntime as ort, igual que cuando trabajas con la versión genérica de ONNX Runtime fuera del ecosistema WinML. La creación de sesiones de inferencia, la gestión de feeds y fetches y la consulta de metadatos de los modelos siguen la misma API presente en la documentación estándar.

En C++ y C, se usan los headers y bibliotecas distribuidos con las builds oficiales o integrados en Windows ML, según el escenario. En ambos casos, las funciones para crear sesiones, cargar modelos, establecer proveedores de ejecución y ejecutar inferencias son las mismas que ya están documentadas en la web oficial de ONNX Runtime, de modo que lo aprendido para Linux o macOS se transfiere bastante bien.

También hay soporte para JavaScript (web y Node.js), React Native y plataformas móviles. En estos entornos, las builds de ONNX Runtime Web o los paquetes de Android/iOS permiten realizar inferencia en el dispositivo, con la opción de crear builds personalizadas que solo incluyan los operadores necesarios para tus modelos y así reducir el tamaño de descarga y el consumo de recursos.

Escenarios avanzados: múltiples versiones, procesos separados y entrenamiento

En determinados escenarios de producción puede que necesites usar varias versiones de ONNX Runtime al mismo tiempo. Esto puede ocurrir si tu aplicación carga complementos de terceros que traen su propia versión del runtime o cuando ciertos modelos dependen de una build concreta (por compatibilidad con un execution provider, por ejemplo).

En Windows, una solución práctica es ejecutar Windows ML en un proceso independiente y comunicarte con esa aplicación auxiliar. Un patrón común consiste en compilar un pequeño ejecutable de consola que carga un modelo (por ejemplo SqueezeNet), acepta como parámetro la ruta de una imagen y devuelve por la salida estándar su interpretación del contenido (etiquetas y probabilidades).

Tu aplicación principal puede entonces lanzar ese proceso con System.Diagnostics.Process, redactar los argumentos apropiados, redirigir la salida estándar y parsear las líneas que vaya emitiendo el proceso hijo, sin necesidad de compartir directamente la DLL de ONNX Runtime entre ambos contextos.

Este enfoque funciona especialmente bien en casos en los que solo necesitas hacer inferencias puntuales con entrada y salida de tipo texto. Para casos más complejos —procesos de IA persistentes o intercambio de tipos de datos binarios o estructurados— Windows ofrece una batería de mecanismos de comunicación entre procesos (pipes, sockets, AppService, etc.) que puedes combinar con ONNX Runtime según la arquitectura que diseñes.

Por otro lado, ONNX Runtime también incluye capacidades de entrenamiento optimizado y entrenamiento en dispositivo (on-device training). Para estos escenarios existen tablas específicas de instalación, versiones acopladas a determinadas versiones de CUDA y paquetes como torch-ort y onnxruntime-training, pensados para grandes modelos y workflows de entrenamiento avanzados, aunque en la mayoría de aplicaciones de escritorio en Windows 11 te bastará con la parte de inferencia.

Con todo este ecosistema, Windows 11 se convierte en una plataforma muy sólida para correr IA en local: tienes ONNX Runtime embebido en el sistema a través de WinML, paquetes NuGet y distribuciones para prácticamente todos los lenguajes habituales, integración con GPU mediante DirectML o CUDA, soporte para CPU en cualquier equipo moderno y la posibilidad de personalizar builds para reducir tamaño o adaptarte a hardware específico. Entender bien estas piezas y cómo encajan te permite montar aplicaciones que aprovechan al máximo la aceleración disponible en el PC del usuario, manteniendo control total sobre los datos y sin depender de servicios externos.

detección de objetos en imágenes con IA
Artículo relacionado:
IA para detectar objetos: cómo funciona esta tecnología en imágenes