- Transformers.js es una biblioteca para ejecutar modelos de 🤗 Transformers en el navegador sin servidor, y busca ser funcionalmente equivalente a
transformers de Python de Hugging Face con una API similar
- Usa ONNX Runtime para ejecutar los modelos, y los modelos preentrenados de PyTorch, TensorFlow y JAX pueden convertirse a ONNX con 🤗 Optimum para usarse aquí
- Con la API
pipeline, se pueden invocar tareas como análisis de sentimiento de forma similar a Python, y se puede elegir otro modelo indicando el ID o la ruta del modelo como segundo argumento
- La ejecución predeterminada en el navegador usa CPU basada en WASM; también se puede elegir WebGPU con
device: 'webgpu', aunque la API de WebGPU sigue siendo experimental en varios navegadores
- En entornos con recursos limitados, como los navegadores web, se pueden elegir tipos de datos como
"fp32", "fp16", "q8" y "q4" con dtype para ajustar el ancho de banda y el rendimiento
Transformers ejecutándose en el navegador
- Transformers.js es una biblioteca diseñada para ejecutar 🤗 Transformers directamente en el navegador sin necesidad de servidor
- Busca ofrecer una experiencia de uso funcionalmente equivalente a la biblioteca de Python transformers de Hugging Face, permitiendo ejecutar los mismos modelos preentrenados con una API muy similar
- Las tareas compatibles abarcan varias modalidades
- Procesamiento de lenguaje natural: clasificación de texto, reconocimiento de entidades nombradas, preguntas y respuestas, modelado de lenguaje, resumen, traducción, opción múltiple, generación de texto
- Visión por computadora: clasificación de imágenes, detección de objetos, segmentación, estimación de profundidad
- Audio: reconocimiento automático de voz, clasificación de audio, conversión de texto a voz
- Multimodal: embeddings, clasificación de audio zero-shot, clasificación de imágenes zero-shot, detección de objetos zero-shot
Método de ejecución y conversión de modelos
Instalación y uso en el navegador
- El paquete de NPM se instala con el siguiente comando
npm i @huggingface/transformers
- También puede usarse en JavaScript vanilla sin bundler, importándolo como ES Modules mediante un CDN o hosting estático
<script type="module">
import { pipeline } from 'https://cdn.jsdelivr.net/npm/@huggingface/transformers@4.2.0';
</script>
API pipeline similar a Python
- La API
pipeline agrupa un modelo preentrenado, el preprocesamiento de entrada y el posprocesamiento de salida, y es la forma más sencilla de ejecutar modelos con la biblioteca
- Igual que en el ejemplo de análisis de sentimiento de
transformers para Python, en JavaScript también se puede crear pipeline('sentiment-analysis'), ingresar texto y obtener el resultado
import { pipeline } from '@huggingface/transformers';
const pipe = await pipeline('sentiment-analysis');
const out = await pipe('I love transformers!');
// [{'label': 'POSITIVE', 'score': 0.999817686}]
- Para usar otro modelo, se indica el ID o la ruta del modelo como segundo argumento de la función
pipeline
const pipe = await pipeline(
'sentiment-analysis',
'Xenova/bert-base-multilingual-uncased-sentiment'
);
CPU, WebGPU y opciones de cuantización
- El valor predeterminado en el navegador es la ejecución en CPU basada en WASM
- Para ejecutar en GPU, se configura
device: 'webgpu'
const pipe = await pipeline(
'sentiment-analysis',
'Xenova/distilbert-base-uncased-finetuned-sst-2-english',
{
device: 'webgpu',
}
);
- Más detalles sobre WebGPU están en la WebGPU guide
- Como la API de WebGPU sigue siendo experimental en varios navegadores, se indica que si surgen problemas se envíe un reporte de error de WebGPU
- En entornos de navegador con recursos limitados, se recomienda usar modelos cuantizados
- La opción
dtype permite elegir el tipo de dato del modelo
- Las opciones habituales son
"fp32", valor predeterminado de WebGPU, "fp16", "q8", valor predeterminado de WASM, y "q4"
- Más detalles están en la quantization guide
const pipe = await pipeline(
'sentiment-analysis',
'Xenova/distilbert-base-uncased-finetuned-sst-2-english',
{
dtype: 'q4',
}
);
Configuración personalizada
import { env } from '@huggingface/transformers';
env.localModelPath = '/path/to/models/';
env.allowRemoteModels = false;
env.backends.onnx.wasm.wasmPaths = '/path/to/files/';
- Toda la configuración disponible está en la API Reference
- Al convertir modelos de PyTorch a ONNX, se recomienda el método de un solo comando con Optimum
Tareas compatibles y alcance de modelos
- Para encontrar modelos compatibles en Hugging Face Hub, se puede filtrar por la etiqueta de biblioteca transformers.js
- Las tareas compatibles abarcan procesamiento de lenguaje natural, visión, audio, multimodal y aprendizaje por refuerzo, aunque algunas tareas todavía no están disponibles
- En procesamiento de lenguaje natural se admiten fill-mask, question-answering, summarization, text-classification, text-generation, token-classification, translation, zero-shot-classification, feature-extraction, entre otras
- En visión se admiten background-removal, depth-estimation, image-classification, image-segmentation, image-to-image, object-detection, image-feature-extraction, entre otras
- En audio se admiten audio-classification, automatic-speech-recognition y text-to-speech
- En multimodal se admiten document-question-answering, image-to-text, zero-shot audio/image classification, zero-shot object detection, entre otras
- También se indican las tareas que aún no están soportadas
- table-question-answering, mask-generation, video-classification, unconditional-image-generation
- audio-to-audio, tabular-classification, tabular-regression
- text-to-image, visual-question-answering
- La lista de arquitecturas de modelos compatibles incluye muchas familias como BERT, BART, CLIP, DistilBERT, Whisper, Llama, Qwen, Gemma, Phi, Segment Anything y ViT
- Si la tarea o el modelo que buscas no está en la lista o todavía no es compatible, puedes abrir una solicitud de funcionalidad
1 comentarios
Opiniones de Hacker News
CLIP en el navegador: https://observablehq.com/@simonw/openai-clip-in-a-browser
Detección de objetos en imágenes con detra-resnet-50: https://observablehq.com/@simonw/detect-objects-in-images
Al principio, el tamaño del modelo se siente como una limitación, pero hay bastantes apps en las que no es descabellado pedirle a un usuario con una buena laptop y conexión que espere unos 30 segundos a que cargue
La versión más reciente agregó soporte para cuantización de embeddings binarios, y tengo muchas ganas de probarlo: https://github.com/xenova/transformers.js/releases/tag/2.17....
Ya tengo armado un paquete npm de transformers.js v3 y creo que tengo que actualizarlo. No estoy seguro de si ya incluye esta función
Mantenía un fork principalmente para hacerlo funcionar en bun, y cuando salga v3 planea dar soporte adecuado a bun. Aunque WebGPU no funcionará, es una función opcional
[Edición: si quieres usarlo, mándame un DM. No quiero promocionar el fork]
Solo tiene 384 dimensiones, pero funciona sorprendentemente bien con texto a nivel de párrafo. Incluso aparece por encima de text-embedding-ada-002 en el ranking
https://huggingface.co/spaces/mteb/leaderboard
https://syntax.fm/show/740/local-ai-models-in-javascript-mac...
Hice una pequeña webapp para eliminar fondos de imágenes con el modelo RMBG1.4 de BRIA AI: https://aether.nco.dev
Me encanta que no haya que enviar datos a una API y que también funcione en smartphones. Creo que en el futuro habrá muchos proyectos que usen esto para modelos pequeños de visión, lenguaje y otras utilidades (estimación de profundidad, eliminación de fondos, etc.), y el futuro de la web se ve prometedor
Ya estoy trabajando en mi siguiente proyecto y seguramente volveré a usar transformers.js ahí también
El plan es probar embeddings y estrategias de búsqueda para varias estrategias RAG que se puedan usar en servidores o apps Electron
Ambas opciones son malas
A largo plazo, quizá lo correcto sea que los navegadores incorporen algunos modelos y los expongan mediante APIs web estandarizadas, pero todavía no he oído que haya algún esfuerzo en marcha en ese sentido
(44 MB) Eliminación de fondos en el navegador: https://huggingface.co/spaces/Xenova/remove-background-web. También hay una versión WebGPU: https://huggingface.co/spaces/Xenova/remove-background-webgp...
(51 MB) Whisper Web para reconocimiento automático de voz: https://huggingface.co/spaces/Xenova/whisper-web basta con seleccionar la versión cuantizada en la configuración
(28 MB) Depth Anything Web para estimación de profundidad monocular: https://huggingface.co/spaces/Xenova/depth-anything-web
(14 MB) Segment Anything Web para segmentación de imágenes: https://huggingface.co/spaces/Xenova/segment-anything-web
(20 MB) Doodle Dash, un juego de reconocimiento de bocetos basado en machine learning: https://huggingface.co/spaces/Xenova/doodle-dash
Y hay muchas más. Puedes ver otros ejemplos en la colección de demos de Transformers.js: https://huggingface.co/collections/Xenova/transformersjs-dem...
Los modelos se almacenan en caché por dominio (usando la Web Cache API), así que no hace falta volver a descargarlos cada vez que se carga la página. Si quieres conservar modelos entre dominios, puedes crear una extensión de navegador con esta biblioteca
Sobre esto último, hay esfuerzos en curso, pero todavía no estamos en una etapa en la que se pueda hablar de ello
Es difícil crear de forma práctica webapps que requieran gigabytes de datos en el cliente. No hay una forma confiable de garantizar que permanezcan en caché tanto tiempo como el usuario quiera y, aun si se pudieran cachear de manera confiable, por las políticas de particionamiento de caché del navegador, cada sitio que use el mismo modelo termina duplicando descargas y espacio de almacenamiento
Las partes del comentario original como “se ve muy poco práctico”, “los modelos en general son bastante grandes” y “150 sitios × modelo de 800 MB” parecen llevar implícita la propia salvedad de que falta comprensión del tema
Otra gran ventaja es que transformers también corre en Node.js. Es mucho más fácil armar el entorno de ejecución que acertarle a la extraña combinación de Python y sus dependencias
Creo que mejorará cuando los sistemas operativos empiecen a preinstalar modelos y a ofrecer APIs que también puedan usar los proveedores de navegadores
Aun así, para la mayoría de las tareas, es probable que los modelos alojados en la nube sigan siendo siempre mucho mejores
Hay un benchmark de embeddings con WebGPU en Hugging Face Space que permite estimar cómo funciona la propagación hacia adelante: https://huggingface.co/spaces/Xenova/webgpu-embedding-benchm...
De por sí es impresionante, pero entrenar con esa latencia parece doloroso. Con fp16, batch 32 y longitud de secuencia 512, la propagación hacia adelante de un modelo de 22 millones de parámetros tarda unos 500 ms
Parece que definitivamente abre posibilidades para predicciones bajo demanda