3 points par GN⁺ 2024-04-13 | 1 commentaires | Partager sur WhatsApp
  • 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

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

 
GN⁺ 2024-04-13
Commentaires sur Hacker News
  • Cette bibliothèque est vraiment géniale. Je l’ai utilisée plusieurs fois dans des notebooks Observable, tant il est facile de monter une démo rapide
    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....
    • Les embeddings binaires nécessiteront sans doute un réordonnancement supplémentaire, mais ce sera intéressant à tester
      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]
  • J’utilise cette bibliothèque pour créer des embeddings gte-small (~0,07 Go) et les stocker dans Upstash Vector
    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
  • Le podcast Syntax a récemment publié un épisode sur Transformers.js et son développeur
    https://syntax.fm/show/740/local-ai-models-in-javascript-mac...
  • transformers.js est vraiment une bibliothèque géniale
    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
    • Je l’utilise pour un projet simple : https://github.com/sroussey/ellmers
      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
  • C’est vraiment cool, mais malheureusement, la praticité semble assez limitée. Les modèles sont généralement assez volumineux, donc même si le navigateur peut les exécuter, les amener jusqu’au navigateur implique l’une de ces deux options
    1. un gros téléchargement à chaque visite d’un site
    2. un gros téléchargement et une forte consommation de stockage pour chaque site utilisant un gros modèle. Par exemple, 150 sites × un modèle de 800 Mo, cela représente 120 Go de stockage
      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

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

  • C’est à peu près le même problème qui pénalise les jeux web depuis les premières démos Unreal/Unity en asm.js il y a 10 ans, et il n’y a pas vraiment eu de progrès vers une solution depuis
    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 modèles font moins de 80 Mo, le reste concerne les LLM et sort donc du périmètre. Whisper fait 40 Mo, les embeddings 23 Mo
    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
  • Certains modèles sont assez petits pour qu’il vaille la peine de les exécuter on-device plutôt que d’envoyer toutes les données à un serveur pour traitement
    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
  • Ce n’est pas seulement un problème propre au navigateur, mais un problème fondamental du traitement IA on-device
    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
  • Est-ce que cela veut dire qu’on peut maintenant créer un plugin de navigateur capable de sélectionner tous les vélos ou les ponts dans les captchas Google ?
  • L’entraînement est-il impossible ? Il y a quelques années, j’avais travaillé sur la création et l’entraînement de petits réseaux de neurones dans le navigateur, et je me demande si aujourd’hui cette approche fonctionnerait mieux avec un petit transformer personnalisé
    • En théorie, c’est clairement possible, mais les performances sont probablement la raison pour laquelle ce n’est pas encore implémenté
      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
  • Cela n’ouvre-t-il pas aussi la possibilité d’exécuter ce type de modèle dans des fonctions serverless Node.js ?
    Il y aurait clairement du potentiel pour de l’inférence à la demande
  • Est-ce que l’accélération Apple Silicon est prise en charge ?