- Transformers.js est une bibliothèque permettant d’exécuter des modèles 🤗 Transformers dans le navigateur sans serveur. Elle vise une équivalence fonctionnelle avec le
transformers Python de Hugging Face et une API similaire
- L’exécution des modèles utilise ONNX Runtime ; les modèles pré-entraînés PyTorch, TensorFlow et JAX peuvent être convertis en ONNX avec 🤗 Optimum
- L’API
pipeline permet d’appeler des tâches comme l’analyse de sentiment d’une manière proche de Python, et l’on peut choisir un autre modèle en indiquant un ID de modèle ou un chemin en second argument
- L’exécution par défaut dans le navigateur se fait sur CPU via WASM ;
device: 'webgpu' permet de choisir une exécution WebGPU, mais l’API WebGPU reste expérimentale dans plusieurs navigateurs
- Dans les environnements aux ressources limitées comme les navigateurs web, on peut choisir des types de données comme
"fp32", "fp16", "q8" ou "q4" via dtype afin d’ajuster la bande passante et les performances
Des Transformers exécutés dans le navigateur
- Transformers.js est une bibliothèque conçue pour exécuter directement 🤗 Transformers dans le navigateur, sans serveur
- Elle vise une expérience fonctionnellement équivalente à celle de la bibliothèque Python transformers de Hugging Face, avec la possibilité d’exécuter les mêmes modèles pré-entraînés via une API très similaire
- Les tâches prises en charge couvrent plusieurs modalités
- Traitement automatique du langage naturel : classification de texte, reconnaissance d’entités nommées, question-réponse, modélisation du langage, résumé, traduction, QCM, génération de texte
- Vision par ordinateur : classification d’images, détection d’objets, segmentation, estimation de profondeur
- Audio : reconnaissance automatique de la parole, classification audio, synthèse vocale
- Multimodal : embeddings, classification audio zero-shot, classification d’images zero-shot, détection d’objets zero-shot
Mode d’exécution et conversion des modèles
Installation et utilisation dans le navigateur
- Le package NPM s’installe avec la commande suivante
npm i @huggingface/transformers
- Il peut aussi être utilisé en vanilla JS sans bundler, en l’important comme ES Module via un CDN ou un hébergement statique
<script type="module">
import { pipeline } from 'https://cdn.jsdelivr.net/npm/@huggingface/transformers@4.2.0';
</script>
Une API pipeline proche de Python
- L’API
pipeline est le moyen le plus simple d’exécuter un modèle dans la bibliothèque, en regroupant modèle pré-entraîné, prétraitement des entrées et post-traitement des sorties
- Comme dans l’exemple d’analyse de sentiment de
transformers en Python, JavaScript permet aussi de créer pipeline('sentiment-analysis'), puis de fournir un texte pour obtenir un résultat
import { pipeline } from '@huggingface/transformers';
const pipe = await pipeline('sentiment-analysis');
const out = await pipe('I love transformers!');
// [{'label': 'POSITIVE', 'score': 0.999817686}]
- Pour utiliser un autre modèle, il faut indiquer un ID de modèle ou un chemin comme second argument de la fonction
pipeline
const pipe = await pipeline(
'sentiment-analysis',
'Xenova/bert-base-multilingual-uncased-sentiment'
);
CPU, WebGPU et options de quantification
- Par défaut, l’exécution dans le navigateur se fait sur CPU via WASM
- Pour exécuter sur GPU, il faut définir
device: 'webgpu'
const pipe = await pipeline(
'sentiment-analysis',
'Xenova/distilbert-base-uncased-finetuned-sst-2-english',
{
device: 'webgpu',
}
);
- Plus de détails sur WebGPU sont disponibles dans le guide WebGPU
- Comme l’API WebGPU reste expérimentale dans plusieurs navigateurs, il est recommandé de soumettre un rapport de bug WebGPU en cas de problème
- Dans les environnements de navigateur web aux ressources limitées, l’utilisation de modèles quantifiés est recommandée
- L’option
dtype permet de choisir le type de données du modèle
- Les choix courants sont
"fp32", valeur par défaut de WebGPU, "fp16", "q8", valeur par défaut de WASM, et "q4"
- Plus de détails se trouvent dans le guide de quantification
const pipe = await pipeline(
'sentiment-analysis',
'Xenova/distilbert-base-uncased-finetuned-sst-2-english',
{
dtype: 'q4',
}
);
Configuration personnalisée
- Par défaut, Transformers.js est configuré pour fonctionner immédiatement avec des modèles pré-entraînés hébergés et des binaires WASM précompilés
- La configuration
env permet de modifier l’emplacement des modèles, le chargement des modèles distants et le chemin des fichiers WASM
import { env } from '@huggingface/transformers';
env.localModelPath = '/path/to/models/';
env.allowRemoteModels = false;
env.backends.onnx.wasm.wasmPaths = '/path/to/files/';
- La liste complète des paramètres disponibles se trouve dans la référence API
- Pour convertir un modèle PyTorch en ONNX, l’approche recommandée consiste à utiliser la commande unique fournie par Optimum
Tâches prises en charge et périmètre des modèles
- Pour trouver des modèles compatibles sur le Hugging Face Hub, il est possible de filtrer avec le tag de bibliothèque transformers.js
- Les tâches prises en charge couvrent le traitement du langage naturel, la vision, l’audio, le multimodal et l’apprentissage par renforcement, certaines tâches n’étant pas encore prises en charge
- En traitement du langage naturel, fill-mask, question-answering, summarization, text-classification, text-generation, token-classification, translation, zero-shot-classification, feature-extraction, entre autres, sont pris en charge
- En vision, background-removal, depth-estimation, image-classification, image-segmentation, image-to-image, object-detection, image-feature-extraction, entre autres, sont pris en charge
- En audio, audio-classification, automatic-speech-recognition et text-to-speech sont pris en charge
- En multimodal, document-question-answering, image-to-text, zero-shot audio/image classification, zero-shot object detection, entre autres, sont pris en charge
- Les tâches qui ne sont pas encore prises en charge sont également indiquées
- table-question-answering, mask-generation, video-classification, unconditional-image-generation
- audio-to-audio, tabular-classification, tabular-regression
- text-to-image, visual-question-answering
- La liste des architectures de modèles prises en charge comprend de nombreuses familles de modèles, dont BERT, BART, CLIP, DistilBERT, Whisper, Llama, Qwen, Gemma, Phi, Segment Anything et ViT
- Si la tâche ou le modèle souhaité ne figure pas dans la liste, ou n’est pas encore pris en charge, il est possible d’ouvrir une demande de fonctionnalité
1 commentaires
Commentaires sur Hacker News
CLIP dans le navigateur : https://observablehq.com/@simonw/openai-clip-in-a-browser
Détection d’objets dans des images avec detra-resnet-50 : https://observablehq.com/@simonw/detect-objects-in-images
La taille des modèles ressemble au départ à une contrainte, mais pour pas mal d’apps, demander à des utilisateurs disposant d’un bon ordinateur portable et d’une bonne connexion d’attendre environ 30 secondes au chargement n’est pas absurde
La dernière version ajoute la prise en charge de la quantification des embeddings binaires, et j’ai vraiment envie de l’essayer : https://github.com/xenova/transformers.js/releases/tag/2.17....
J’ai préparé un paquet npm pour transformers.js v3, et il faudrait que je le mette à jour. Je ne suis pas sûr qu’il inclue déjà cette fonctionnalité
Je maintenais surtout un fork pour que ça tourne avec bun, et la v3 devrait prendre correctement en charge bun une fois publiée. En revanche, WebGPU ne fonctionnera pas, mais c’est une fonctionnalité optionnelle
[Édition : laissez un DM si vous voulez l’utiliser. Je n’ai pas envie de faire la promotion de mon fork]
Ils n’ont que 384 dimensions, mais fonctionnent étonnamment bien sur du texte découpé par paragraphes. Dans le classement, ils se placent même au-dessus de text-embedding-ada-002
https://huggingface.co/spaces/mteb/leaderboard
https://syntax.fm/show/740/local-ai-models-in-javascript-mac...
J’ai créé une petite webapp qui fait de la suppression d’arrière-plan d’image avec le modèle RMBG1.4 de BRIA AI : https://aether.nco.dev
Le fait de ne pas avoir à envoyer les données à une API, et que ça fonctionne même sur smartphone, est vraiment appréciable. Je pense qu’on verra de plus en plus de projets l’utiliser pour de petits modèles de vision, de langage et d’autres utilitaires (estimation de profondeur, suppression d’arrière-plan, etc.), et l’avenir du web paraît prometteur
Je travaille déjà sur le prochain projet, et j’y réutiliserai très certainement transformers.js
L’idée est de tester des embeddings et des stratégies de recherche pour différentes stratégies RAG à utiliser sur serveur ou dans une app Electron
Aucune des deux options n’est très séduisante
À long terme, la bonne approche serait peut-être que les navigateurs intègrent certains modèles et les exposent via une API web standardisée, mais je n’ai pas encore entendu parler d’efforts en cours dans ce sens
(44 Mo) Suppression d’arrière-plan dans le navigateur : https://huggingface.co/spaces/Xenova/remove-background-web. Il existe aussi une version WebGPU : https://huggingface.co/spaces/Xenova/remove-background-webgp...
(51 Mo) Whisper Web pour la reconnaissance automatique de la parole : https://huggingface.co/spaces/Xenova/whisper-web il suffit de choisir la version quantifiée dans les réglages
(28 Mo) Depth Anything Web pour l’estimation de profondeur monoculaire : https://huggingface.co/spaces/Xenova/depth-anything-web
(14 Mo) Segment Anything Web pour la segmentation d’images : https://huggingface.co/spaces/Xenova/segment-anything-web
(20 Mo) Doodle Dash, un jeu de reconnaissance de croquis basé sur le machine learning : https://huggingface.co/spaces/Xenova/doodle-dash
Et il y en a beaucoup d’autres. Vous pouvez voir d’autres exemples dans la collection de démos Transformers.js : https://huggingface.co/collections/Xenova/transformersjs-dem...
Les modèles sont mis en cache par domaine (via la Web Cache API), il n’est donc pas nécessaire de les retélécharger à chaque chargement de page. Si l’on veut conserver les modèles au-delà d’un domaine, on peut créer une extension de navigateur avec cette bibliothèque
Sur le dernier point évoqué, des travaux sont en cours, mais ce n’est pas encore à un stade où l’on peut en parler
Les webapps qui nécessitent des gigaoctets de données côté client sont difficiles à rendre pratiques. Il n’existe pas de moyen fiable de garantir qu’elles resteront en cache aussi longtemps que l’utilisateur le souhaite, et même si l’on pouvait les mettre en cache de façon fiable, les politiques de partitionnement du cache des navigateurs entraînent des téléchargements et un stockage dupliqués pour chaque site utilisant le même modèle
Les formulations du commentaire d’origine comme « cela paraît très peu pratique », « les modèles sont généralement assez gros » ou « 150 sites × un modèle de 800 Mo » semblent surtout signaler, de l’aveu même de leur auteur, un manque de compréhension
Un autre gros avantage est que transformers fonctionne aussi avec Node.js. Il est bien plus simple de créer un environnement d’exécution que de réussir à faire cohabiter Python et son étrange assortiment de dépendances
Les choses ne devraient s’améliorer que lorsque les systèmes d’exploitation commenceront à préinstaller des modèles et à fournir des API utilisables aussi par les éditeurs de navigateurs
Malgré tout, pour la plupart des tâches, les modèles hébergés dans le cloud resteront probablement largement meilleurs
Il existe un benchmark d’embeddings WebGPU sur Hugging Face Space qui permet de se faire une idée des performances en propagation avant : https://huggingface.co/spaces/Xenova/webgpu-embedding-benchm...
C’est impressionnant en soi, mais entraîner avec une telle latence serait sans doute pénible. En fp16, avec un batch de 32 et une longueur de séquence de 512, la propagation avant d’un modèle à 22 millions de paramètres prend environ 500 ms
Il y aurait clairement du potentiel pour de l’inférence à la demande