WebNN y la inferencia sobre WebGPU en 2026
El estado real de la especificación de redes neuronales del W3C, qué librerías corren hoy sobre WebGPU, y los límites de la API que muerden en un modelo grande.
Hay dos caminos para ejecutar un modelo de aprendizaje automático en un navegador. Uno es escribir los kernels tú, en WGSL, con todo lo que has visto en este bloque: tiling, cuantización, reducciones. El otro es delegar en una API que hable con el acelerador dedicado del dispositivo. El primero funciona hoy en los tres motores; el segundo lleva años acercándose y en agosto de 2026 sigue sin estar disponible en producción. Conviene saber exactamente dónde está cada uno para no construir sobre una promesa.
- Situar el estado de la especificación WebNN y su disponibilidad real en navegadores.
- Distinguir qué aporta WebNN sobre un kernel propio en WebGPU.
- Enumerar las librerías que ejecutan modelos sobre WebGPU y su ámbito.
- Reconocer los límites de WebGPU que condicionan un modelo grande.
Dónde está WebNN
La Web Neural Network API es una especificación del W3C que expone un grafo de operaciones de red neuronal para que el navegador lo ejecute en el mejor acelerador disponible: la NPU si la hay, la GPU si no, la CPU como último recurso.
El W3C publicó una Candidate Recommendation actualizada el 22 de enero de 2026, con un periodo de comentarios que se cerró el 22 de marzo. Respecto a la instantánea anterior, de abril de 2024, la especificación acumula más de cien cambios significativos: una tercera tanda de operadores orientada a modelos de tipo transformer, la API MLTensor para compartir búferes sin copias, y un mecanismo abstracto de selección de dispositivo que sustituye a la enumeración explícita de aceleradores.
La disponibilidad es otra historia. Las implementaciones más maduras son las de Chrome y Edge, y siguen detrás de banderas experimentales; no hay despliegue estable en ningún navegador y no existe soporte multiplataforma. La propia fase del proceso lo dice: la ronda de comentarios servía para decidir si la API está lista para avanzar hacia estándar, no para desplegarla.
Traducido a decisiones: WebNN no es una opción para producción en 2026. Merece la pena seguirla, merece la pena probarla detrás de la bandera, y no merece la pena diseñar el producto contando con ella.
Qué aportaría, y qué no
Cuando llegue, lo que WebNN aporta sobre escribir tus propios kernels en WebGPU es concreto y vale bastante:
Acceso a la NPU, que es la unidad de inferencia dedicada de los procesadores modernos. WebGPU no la ve; solo ve la GPU. En un portátil reciente, la NPU ejecuta un modelo de visión con una fracción del consumo, lo que en un dispositivo con batería cambia la viabilidad del caso de uso.
Kernels del fabricante, ajustados a cada arquitectura, en vez de tu WGSL genérico. La diferencia entre una GEMM bien escrita y una de librería del fabricante es del orden de dos veces, y crece con las unidades matriciales dedicadas, que WGSL no expone.
Lo que no aporta es flexibilidad. WebNN ejecuta un grafo de operadores predefinidos; si tu modelo tiene una capa que no está en el catálogo, no hay forma de escribirla. Con WebGPU escribes lo que quieras. Por eso el escenario probable no es que uno sustituya al otro sino que convivan, con el grafo estándar en WebNN y las piezas raras en WebGPU compartiendo búferes, que es exactamente lo que MLTensor está diseñado para permitir.
Lo que sí funciona hoy
La ruta viable en 2026 es WebGPU, y hay un ecosistema real encima.
ONNX Runtime Web con su proveedor de ejecución WebGPU ejecuta modelos en formato ONNX y es la opción más general: si puedes exportar tu modelo a ONNX, probablemente funciona. Es también la más pesada.
Transformers.js envuelve ONNX Runtime Web con la ergonomía de la librería de Hugging Face y soporta WebGPU desde su versión 3. Para clasificación, extracción de embeddings, transcripción de voz o modelos de visión, es el camino con menos fricción: unas pocas líneas y el modelo se descarga y ejecuta.
WebLLM, del proyecto MLC, se centra en modelos de lenguaje generativos con kernels compilados específicamente para WebGPU y cuantización agresiva. Es donde está el trabajo más afinado en el problema concreto de generar texto token a token, que como vimos está limitado por leer los pesos.
TensorFlow.js mantiene un backend WebGPU, útil si ya tienes un modelo en ese ecosistema.
Todas comparten dos requisitos prácticos: la característica 'shader-f16' mejora mucho el rendimiento y conviene pedirla, y el tamaño del modelo descargado es el verdadero cuello de botella de la experiencia. Un modelo de lenguaje pequeño cuantizado a 4 bits son entre uno y dos gigabytes que hay que descargar y cachear; ninguna optimización de kernel arregla eso.
Los límites que muerden
Un modelo grande choca contra límites de WebGPU que en gráficos casi nunca se tocan.
maxStorageBufferBindingSize vale 128 MiB por defecto. Un modelo de siete mil millones de parámetros cuantizado a 4 bits ocupa unos 3,5 GB: no cabe en un binding, ni de lejos. Hay que trocearlo en decenas de buffers y despachar por trozos, con la contabilidad que eso implica. Muchos dispositivos ofrecen mucho más y se puede pedir, pero el troceado sigue haciendo falta como camino general.
maxBufferSize vale 256 MiB por defecto y limita el buffer completo, no solo lo que se enlaza de una vez. Es el otro techo del mismo problema.
maxStorageBuffersPerShaderStage garantiza al menos 8 por etapa. Un kernel de atención que quiera consultas, claves, valores, máscara, salida y varios tensores intermedios se acerca al límite deprisa. Las implementaciones recientes de Chrome ofrecen bastante más si se pide, pero el mínimo garantizado es lo que hay que respetar para ser portable.
maxComputeWorkgroupStorageSize vale 16 KiB, que como vimos fija el tamaño máximo de tile de una GEMM. Es la razón por la que las implementaciones de WebGPU no alcanzan las cifras de una biblioteca nativa, que puede usar bloques mayores.
Y hay un límite que no está en la especificación: el tiempo de un dispatch. Los navegadores vigilan que la GPU responda, y un kernel que tarde demasiado provoca una pérdida de dispositivo. No hay un número publicado y varía por plataforma, pero un dispatch que se acerque al segundo es territorio peligroso. La consecuencia es que un modelo grande hay que trocearlo también en el tiempo, no solo en memoria, y eso condiciona el diseño de los kernels de atención con secuencias largas.
Es fácil evaluar la inferencia en el navegador con la métrica equivocada y descartarla. Una GPU de portátil da unos pocos TFLOP/s a través de WebGPU, con las restricciones de tamaño de tile y de buffer que acabamos de ver; un acelerador de servidor da dos órdenes de magnitud más y no tiene ninguna de esas restricciones. Si la comparación es “tokens por segundo”, el navegador pierde siempre y por mucho. Pero esa no es la comparación que decide, y hay tres razones. La primera es la privacidad: los datos no salen del dispositivo, lo cual no es un detalle de cumplimiento normativo sino la diferencia entre poder y no poder aplicar un modelo a documentos médicos, a fotos personales o a lo que el usuario escribe mientras escribe. La segunda es el coste marginal: una vez descargado el modelo, cada inferencia cuesta cero al operador del servicio, lo que hace viables productos con muchísimos usuarios y sin monetización por uso. La tercera es la latencia de ida y vuelta: para autocompletar mientras se teclea o para segmentar la imagen de una cámara en directo, los 50 milisegundos de red son inaceptables aunque el servidor calcule mil veces más rápido. La consecuencia de diseño es que los modelos que tienen sentido en el navegador no son versiones recortadas de los grandes, son modelos concebidos para tareas acotadas: reconocimiento de voz corto, extracción de embeddings para una búsqueda local, clasificación de imagen, corrección de texto, segmentación. Y en esas tareas un modelo de cien megabytes bien cuantizado corriendo sobre los kernels que has aprendido a escribir en este bloque hace el trabajo perfectamente, sin servidor, sin cuenta y sin conexión.