Démo Stable Diffusion WebGPU
(islamov.ai)- Démo de génération d’images Stable Diffusion exécutée directement dans le navigateur, sans serveur séparé, basée sur WebGPU et WebAssembly
- Utilisable dans la dernière version de Chrome après activation des flags « Experimental WebAssembly » et « Experimental WebAssembly JavaScript Promise Integration (JSPI) »
- Génère des images à partir d’un Prompt, d’un Negative Prompt et d’un nombre d’étapes d’inférence ; les fichiers du modèle sont mis en cache, il n’est donc pas nécessaire de les télécharger à nouveau à chaque fois
- Résultat d’un portage en JS du StableDiffusionPipeline de Python, avec des patchs de onnxruntime, emscripten et binaryen pour allouer plus de 4 Go de mémoire
- Actuellement lent en raison de l’absence de multithreading et de certaines opérations WebGPU non implémentées, mais des améliorations sont envisagées via l’implémentation de kernels JS et la prise en charge de memory64
Prérequis d’exécution
- Nécessite d’activer les flags Experimental WebAssembly et Experimental WebAssembly JavaScript Promise Integration (JSPI) dans la dernière version du navigateur Chrome
- Les Model files sont mis en cache, il n’est donc pas nécessaire de les retélécharger lors des visites suivantes
Entrées et fonctionnement
- Les champs d’entrée proposés sont Prompt, Negative Prompt et le nombre d’étapes d’inférence
- Avec le PNDM Scheduler, le nombre réel de steps est traité comme i+1 à partir de la valeur saisie i
- Chaque step prend environ 1 minute, et l’exécution du VAE decoder pour générer l’image prend environ 10 secondes supplémentaires
- Lorsque DevTools est ouvert, la vitesse globale est environ 2 fois plus lente
- UNET s’exécute uniquement sur CPU ; il est 10 % plus rapide que sur GPU, tandis que sur GPU il ne produit pas de résultat correct et fige l’onglet du navigateur
- Le nombre minimal de steps pour obtenir un résultat acceptable est de 20, mais 3 steps suffisent pour une démonstration
FAQ
-
Erreur protobuf parsing failed
- Dans DevTools, aller dans Application → Storage puis exécuter « Clear site data »
-
Erreur sbox_fatal_memory_exceeded
- Indique un manque de RAM nécessaire à l’exécution de SD ; essayer de résoudre le problème en rechargeant l’onglet ou le navigateur
-
Méthode d’implémentation
- Portage en JS du StableDiffusionPipeline de Python
- Patch de onnxruntime et d’emscripten+binaryen (toolchain de compilation WebAssembly) pour prendre en charge l’allocation et l’utilisation de plus de 4 Go de mémoire
- Une fois les pull requests associées intégrées dans les releases, tout le monde pourra compiler et exécuter dans le navigateur du code utilisant plus de 4 Go de mémoire
-
Causes de la lenteur
- Le multithreading n’est pas encore pris en charge, un seul cœur CPU est donc utilisé
- Il est impossible de créer une mémoire 64 bits via un SharedArrayBuffer au moyen du constructeur WebAssembly.Memory
- Une modification de la spécification du flag « memory64 » a été proposée ; après son adoption, le moteur V8 sera patché pour la prendre en charge
-
Exécution sur GPU
- L’exécution sur GPU est possible, mais WebGPU dans onnxruntime en est à un stade initial et de nombreuses opérations ne sont pas implémentées
- Les données sont continuellement transférées entre CPU et GPU via JS
- Une forte amélioration des performances sera possible lorsque des kernels JS seront implémentés pour la plupart des opérations
-
Exécution locale possible
- Oui, le code de cette page est fourni dans le dépôt stable-diffusion-webgpu-minimal
-
Possibilité d’exécuter de grands LLM avec transformers.js
- Le package onnxruntime patché (@aislamov/onnxruntime-web64) peut être utilisé, mais son fonctionnement n’est pas garanti dans tous les cas
- Ce build est limité à 8 Go de mémoire et peut donc charger jusqu’à environ 4 Go de poids
-
Plan de pull request vers le dépôt onnxruntime
- C’est prévu ; il s’agira d’un second travail après l’ajout précédent de l’accélération GPU aux bindings node.js
1 commentaires
Avis de Hacker News
L’équipe MLC avait déjà fait fonctionner ça en mars : https://github.com/mlc-ai/web-stable-diffusion
Le plus impressionnant, c’est qu’ils ont ensuite ajouté la prise en charge de plusieurs grands modèles de langage : https://webllm.mlc.ai/
« Charge 3,5 Go et utilise 8 Go de RAM »
C’est intéressant de voir le navigateur en arriver là. Le Web a dévoré le système d’exploitation
Même en le téléchargeant directement et en l’exécutant sans navigateur, la taille du téléchargement et l’utilisation de la RAM seraient à peu près les mêmes
Fournir ce type d’expérience via le navigateur simplifie certaines choses, et il ne semble pas y avoir de moyen plus simple pour exécuter Stable Diffusion ; j’espère donc que ce genre de projet continuera à être soutenu
Il faut une version récente de Chrome avec les flags
Experimental WebAssemblyetExperimental WebAssembly JavaScript Promise Integration (JSPI)activés ; je vais donc attendre que ça arrive dans Firefoxchrome:flagsdemandés dans Brave, mais ça ne fonctionnait toujours pas. Je n’ai jamais téléchargé Chrome sur mes Mac M1, et je ne compte pas commencer maintenantC’est déjà implémenté ici aussi : https://websd.mlc.ai/#text-to-image-generation-demo
MLC utilise Apache TVM pour la génération de code WebGPU et l’auto-tuning, et les performances sont plutôt correctes
J’ai intégré Stable Diffusion de MLC-AI à mon site Web comme générateur d’arrière-plan personnalisé. Les données du modèle viennent de Hugging Face
https://dustinbrett.com/
Pour les tâches liées au CPU, ça peut valoir le coup d’envisager des service workers afin d’éviter de bloquer le thread principal
La prochaine étape, c’est un chatbot WebGPU ? Une conversation façon ChatGPT dans le navigateur, avec mon GPU ?
Plus un grand modèle de langage est bon, plus il consomme de RAM/VRAM, ce qui le rend particulièrement délicat avec WebGPU
C’est déjà implémenté
Par curiosité, à quoi ça sert ?
Ce que je comprends, c’est qu’on génère des images dans le navigateur plutôt que sur un serveur. La seule chose qui me vient à l’esprit, c’est qu’il n’est pas nécessaire de recharger la page pour modifier ou générer une nouvelle image.
Cela pourrait donc permettre des sites Web dont le design visuel change en temps réel, et ce serait assez cool si ça pouvait aussi changer de manière fonctionnellement significative. Cela dit, je ne sais pas très bien à quel point Stable Diffusion est utile pour générer des composants d’interface ou des éléments visuels d’un site
Les prompts sensibles ne fuitent pas vers quelqu’un à distance
Existe-t-il des métriques comparant les performances dans WebGPU et les performances en exécution native ?
J’imagine que c’est parce que la plupart des opérations GPU pour VAE sont déjà implémentées, mais pas celles pour UNET. Dans ce dernier cas, le navigateur continue de transférer des données entre le GPU et le CPU à chaque étape
Si c’est suffisamment rapide, on peut l’utiliser pour rendre localement des images à usage personnel. Le site Web pourrait ne transmettre que le prompt et rendre une image différente pour chaque utilisateur.
À ce stade, qu’en est-il du droit d’auteur ? Le modèle lui-même est-il soumis au droit d’auteur, ou bien tout le système s’effondre-t-il ?
Et je doute que beaucoup de designers Web acceptent le risque que le modèle interprète mal un prompt, produise un résultat déformé avec un mauvais nombre de doigts, ou génère par accident du contenu sexuel ou violent dans un contexte non prévu.
Aujourd’hui, avec beaucoup de modèles génératifs d’images, on choisit généralement la meilleure parmi dix images ou plus, et celles qu’on jette peuvent être vraiment mauvaises.
Pour illustrer dynamiquement des sites Web au quotidien, il faudrait que la qualité et la prévisibilité des modèles soient bien supérieures à ce qu’elles sont aujourd’hui.
Je ne veux pas pour autant dire qu’on n’y arrivera jamais. Les modèles récents font déjà des choses qu’on jugeait inimaginables il y a seulement quelques années. En comparaison avec https://xkcd.com/1425/, il pourrait même être difficile d’expliquer aux jeunes lecteurs le problème qui servait de contexte à cette blague !