StreamDiffusion : une solution au niveau du pipeline pour la génération interactive en temps réel
(github.com/cumulo-autumn)- StreamDiffusion est un pipeline qui améliore la génération d’images basée sur la diffusion pour l’adapter à la génération interactive en temps réel, avec pour objectif d’augmenter les performances des techniques existantes de génération d’images par diffusion
- Les fonctions clés se composent de Stream Batch, Residual Classifier-Free Guidance, Stochastic Similarity Filter, IO Queues, pré-calcul du KV-cache et outils d’accélération de modèle
- Dans un environnement RTX 4090, Core i9-13900K et Ubuntu 22.04.3 LTS, SD-turbo a enregistré 106,16 fps en Txt2Img et 93,897 fps en Img2Img avec 1 étape de débruitage
- Des démos en temps réel sont disponibles dans
demo/realtime-txt2imgetdemo/realtime-img2img, et la démo Img2Img utilise un flux webcam en direct ou une capture d’écran dans le navigateur web - L’utilisation consiste à envelopper le
StableDiffusionPipelinede Diffusers, et il est possible d’obtenir une exécution plus rapide via la fusion LCM-LoRA, Tiny VAE, xformers et l’accélération TensorRT
Objectif et performances de StreamDiffusion
- StreamDiffusion est un pipeline de diffusion pour la génération interactive en temps réel
- Il vise à améliorer les performances des techniques actuelles de génération d’images basées sur la diffusion
- L’article est lié à arXiv 2312.12491 et à Hugging Face Papers
- L’environnement de mesure des performances pour la génération d’images avec le pipeline proposé est le suivant
- GPU : RTX 4090
- CPU : Core i9-13900K
- OS : Ubuntu 22.04.3 LTS
- Tableau des performances
- SD-turbo : 1 étape de débruitage, Txt2Img 106,16 fps, Img2Img 93,897 fps
- LCM-LoRA + KohakuV2 : 4 étapes de débruitage, Txt2Img 38,023 fps, Img2Img 37,133 fps
Fonctions clés
-
Stream Batch
- Simplifie le traitement des données grâce à des opérations de batch efficaces
-
Residual Classifier-Free Guidance
- Mécanisme de guidance amélioré qui réduit les calculs redondants
-
Stochastic Similarity Filter
- Technique de filtrage avancée qui améliore l’efficacité d’utilisation du GPU
-
IO Queues
- Fonction qui gère efficacement les entrées et sorties pour permettre une exécution plus fluide
-
Pre-Computation for KV-Caches
- Optimise la stratégie de cache afin d’accélérer le traitement
-
Model Acceleration Tools
- Utilise plusieurs outils pour l’optimisation du modèle et l’amélioration des performances
Installation et mode d’exécution
- StreamDiffusion peut être installé via pip, conda ou Docker
- Les environnements Python recommandés sont par exemple un environnement conda basé sur
python=3.10ouvenv - Les exemples d’installation de PyTorch distinguent CUDA 11.8 et CUDA 12.1
- CUDA 11.8 :
torch==2.1.0,torchvision==0.16.0,xformers - CUDA 12.1 :
torch==2.1.0,torchvision==0.16.0,xformers
- CUDA 11.8 :
- Méthodes d’installation pour l’utilisateur
- Version la plus récente recommandée :
pip install git+https://github.com/cumulo-autumn/StreamDiffusion.git@main/…] - Version stable :
pip install streamdiffusion[tensorrt] - L’extension TensorRT s’installe avec
python -m streamdiffusion.tools.install-tensorrt
- Version la plus récente recommandée :
- Sous Windows, si la version stable est installée, il peut être nécessaire d’ajouter
pywin32 - L’installation Docker vise un environnement préparé pour TensorRT, avec exécution après
docker builden utilisant l’option--gpus all
Démos et exemples d’utilisation
- Les exemples peuvent être exécutés depuis le répertoire
examples - La démo Txt2Img en temps réel se trouve dans le répertoire
demo/realtime-txt2img - La démo Img2Img en temps réel se trouve dans le répertoire
demo/realtime-img2img- Il est possible d’utiliser un flux webcam en direct ou une capture d’écran dans le navigateur web
- Le flux d’utilisation de base consiste à charger le
StableDiffusionPipelinede Diffusers puis à l’envelopper avecStreamDiffusion - L’exemple Img2Img charge le modèle
KBlueLeaf/kohaku-v2.1et configure le flux avect_index_list=[32, 45]- Si le modèle n’est pas un LCM, il faut utiliser
load_lcm_lora()etfuse_lora() - Pour une accélération supplémentaire, il utilise Tiny VAE de
madebyollin/taesd - Il active l’attention mémoire efficace de xformers via
enable_xformers_memory_efficient_attention()
- Si le modèle n’est pas un LCM, il faut utiliser
- L’exemple Txt2Img utilise
t_index_list=[0, 16, 32, 45]et recommandecfg_type="none"pour le texte-vers-image - Le nombre de warmups doit être supérieur ou égal à
len(t_index_list) x frame_buffer_size
Accélération TensorRT
- Pour une génération plus rapide, le code d’activation de xformers peut être remplacé par du code d’accélération TensorRT
- Il utilise
accelerate_with_tensorrtdestreamdiffusion.acceleration.tensorrt - La configuration d’exemple transmet
stream,"engines"etmax_batch_size=2 - L’extension TensorRT est nécessaire, et la construction des moteurs prend du temps
- Une fois les moteurs construits, l’exécution devient plus rapide que dans les exemples précédents
Stochastic Similarity Filter
- Le Stochastic Similarity Filter réduit les opérations de transformation sur une entrée vidéo lorsqu’il y a peu de changements par rapport à l’image précédente
- En réduisant les opérations de transformation, il allège la charge de traitement du GPU
- Son utilisation consiste à appeler
stream.enable_similar_image_filter() - Paramètres configurables
similar_image_filter_threshold: seuil de similarité entre l’image précédente et l’image actuelle avant la suspension du traitementsimilar_image_filter_max_skip_frame: intervalle maximal autorisé pendant la suspension avant la reprise de la transformation
Residual CFG
- RCFG est une méthode qui implémente une approximation du CFG avec une complexité de calcul comparable aux cas sans utilisation de CFG
- Il peut être défini via l’argument
cfg_typedeStreamDiffusion - Il existe deux types de RCFG
- RCFG Self-Negative : méthode sans élément de prompt négatif spécifié
- RCFG Onetime-Negative : méthode permettant de spécifier un prompt négatif
- Comparaison de la complexité de calcul
- Sans CFG : N
- CFG classique : 2N
- RCFG Self-Negative : N
- RCFG Onetime-Negative : N+1
- Les valeurs de
cfg_typesont les suivantes- Sans CFG :
"none" - CFG classique :
"full" - RCFG Self-Negative :
"self" - RCFG Onetime-Negative :
"initialize"
- Sans CFG :
deltajoue un rôle d’atténuation pour ajuster l’effet du RCFG
Modèles et ressources utilisés
- Les démos vidéo et image du dépôt ont été générées avec LCM-LoRA + KohakuV2, et SD-Turbo
- Le modèle KohakuV2 peut être téléchargé depuis Civitai et Hugging Face
- SD-Turbo est également disponible sur Hugging Face Space
1 commentaires
Avis sur Hacker News
L’article arXiv est ici : https://arxiv.org/abs/2312.12491
Je pense qu’on pourrait faire plus rapide que les mesures de base sur une 4090. Avec SDXL Turbo, sans optimisation et en une seule itération, on arrivait déjà à 10 fps.
Cela dit, des améliorations comme le filtre de similarité stochastique, qui évite les générations inutiles, semblent utiles pour obtenir des résultats rapides sans garder le GPU bloqué à 100 % en permanence.
C’est presque irréel. On a l’impression que 10 ans se sont écoulés en un an.
apt-get install.Je viens d’essayer la démo
realtime-text2img, et utiliser npm pour le frontend me semble excessif pour cet usage. Je l’ai modifiée pour ne générer qu’une seule image au lieu de 16, et ça fonctionne bien même sur un portable avec RTX 3080. Ça doit sortir environ 2 images par seconde.Édition : la démo
examples\screendonne presque une impression de temps réel. La fenêtre indique 4 fps, mais je ne sais pas exactement ce que cela signifie.Édition : en revanche, l’intensité de débruitage de l’img2img est très faible, donc l’image renvoyée ne diffère que très légèrement de l’image d’origine.
Les articles sur les modèles génératifs sont toujours difficiles à juger avant de les exécuter soi-même. Comme il faut montrer des résultats aux relecteurs, ils sont inévitablement sélectionnés. Je ne dis pas que c’est une bonne chose, mais c’est la réalité actuelle.
Est-ce qu’ils utilisent ici un petit autoencodeur ? Artspew faisait aussi ça et obtenait un FPS plus élevé, mais il n’utilisait pas TensorRT, utilisait Triton, et la qualité était catastrophique. Cela restait tout de même impressionnant.
Quoi qu’il en soit, même si la qualité est bien inférieure à ce qui est montré, cela reste impressionnant, mais en pratique c’est difficile à savoir.
Je me demande si 100 fps signifie qu’on peut fournir une nouvelle entrée toutes les 10 ms et recevoir une nouvelle sortie toutes les 10 ms. Ou bien faut-il regrouper les entrées en lots pour obtenir ce débit moyen ?
La partie lente d’un modèle est son chargement. Une fois le modèle en mémoire, on peut lui envoyer les entrées qu’on veut.
J’ai l’intuition que le parsing et l’envoi des données d’image ne sont pas le goulot d’étranglement ici.
Ça a fonctionné presque immédiatement, à peu près comme indiqué dans la documentation. La plupart de ces démos plantent et sortent des erreurs profondes et bizarres, mais celle-ci s’en est bien sortie.
C’est bien fait. Ça vaut le coup d’essayer. Si vous voulez générer autre chose qu’un style anime, il suffit de changer le modèle dans
server.pyderealtime-txt2img. Par exemple, en le pointant vers https://huggingface.co/runwayml/stable-diffusion-v1-5, ça fonctionne aussi très bien.Les résultats sont vraiment rapides. Pas excellents, mais rapides. Passer à SDXL via LCM-LoRA (https://huggingface.co/latent-consistency) pourrait donner de meilleurs résultats, mais à partir de là ça devient plus difficile et on commence à rencontrer les crashs mystérieux évoqués plus haut. C’est le moment où il faut vraiment mettre les mains dans le cambouis.
Mon environnement est 4090/3990x/CUDA 12.2/debian sid, donc cela peut varier selon la configuration.
Comment fonctionne la démo où un personnage féminin entre et sort du cadre ? C’est ControlNet ?
Quel fps obtient-on sur Apple Silicon ?
Cela dit, à prix comparable aujourd’hui, sur le marché du reconditionné autour de 1 800 dollars, un Studio M1 Max 64 Go est environ 13 fois plus lent qu’une RTX 4090 24 Go pour l’IA générative avec SD1.5 et SDXL.
Une image en 512x512, 5 étapes, est générée en 5 secondes. Je n’utilise pas de refiner, d’upscaler ni de restauration de visage.
À ma connaissance, DrawThings n’est pas encore optimisé pour SDXL Turbo ni pour la génération en pipeline.
À titre de comparaison, générer une image 2k x 2k en 50 étapes avec SDXL Base+Refiner et la restauration de visage activée prend environ 120 secondes.
Surtout pour un style anime, où l’on dessine en gros une image toutes les deux frames, donc 12 fps pourraient suffire.
Y a-t-il une vidéo visible quelque part ?