3 puntos por GN⁺ 2024-04-13 | 1 comentarios | Compartir por WhatsApp
  • 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

  • De forma predeterminada, Transformers.js está configurado para funcionar de inmediato usando modelos preentrenados alojados y binarios WASM precompilados
  • Con la configuración env, se puede cambiar la ubicación de los modelos, la carga remota de modelos y la ruta de los archivos WASM
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

 
GN⁺ 2024-04-13
Opiniones de Hacker News
  • Esta biblioteca es realmente genial. Es muy fácil montar demos rápidas, así que la he usado varias veces en notebooks de Observable
    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....
    • Los embeddings binarios probablemente necesiten un reordenamiento adicional, pero sería divertido probarlo
      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]
  • Estoy usando esta biblioteca para generar embeddings con gte-small (~0.07 GB) y guardarlos en Upstash Vector
    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
  • El podcast Syntax publicó hace poco un episodio sobre Transformers.js y su desarrollador
    https://syntax.fm/show/740/local-ai-models-in-javascript-mac...
  • transformers.js es una biblioteca realmente genial
    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
    • Lo estoy usando en un proyecto sencillo: https://github.com/sroussey/ellmers
      El plan es probar embeddings y estrategias de búsqueda para varias estrategias RAG que se puedan usar en servidores o apps Electron
  • Es realmente genial, pero lamentablemente parece tener una utilidad práctica bastante baja. Como los modelos suelen ser bastante grandes, aunque el navegador pueda ejecutarlos, llevarlos hasta el navegador requiere una de estas dos cosas
    1. Una descarga grande cada vez que visitas un sitio web
    2. Una descarga grande y mucho uso de almacenamiento por cada sitio que use un modelo grande. Por ejemplo, 150 sitios × un modelo de 800 MB consumirían 120 GB de almacenamiento
      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

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 casi el mismo problema que viene afectando a los juegos web desde las primeras demos de Unreal/Unity en asm.js hace 10 años, y en todo este tiempo no ha habido muchos avances hacia una solución
    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
  • Los modelos pesan menos de 80 MB, y lo demás son LLM, así que queda fuera del alcance. Whisper pesa 40 MB y los embeddings 23 MB
    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
  • Algunos modelos son bastante pequeños, por lo que vale la pena ejecutarlos en el dispositivo en vez de enviar todos los datos al servidor para procesarlos
    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
  • Esto no es un problema exclusivo del navegador, sino un problema fundamental del procesamiento de IA en el dispositivo
    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
  • ¿Entonces ahora se puede crear un plugin de navegador que seleccione todas las bicicletas o puentes en los captchas de Google?
  • ¿No se puede entrenar? Hace unos años trabajé en crear y entrenar una red neuronal pequeña en el navegador, y me pregunto si hoy ese enfoque funcionaría mejor con un transformer personalizado pequeño
    • En teoría, sin duda es posible, pero probablemente los problemas de rendimiento sean la razón por la que aún no se ha implementado
      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
  • ¿Esto no abre también la posibilidad de correr estos modelos en funciones serverless de Node.js?
    Parece que definitivamente abre posibilidades para predicciones bajo demanda
  • ¿Soporta aceleración en Apple Silicon?