1 points par GN⁺ 2023-12-25 | 1 commentaires | Partager sur WhatsApp
  • 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-txt2img et demo/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 StableDiffusionPipeline de 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.10 ou venv
  • 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
  • Méthodes d’installation pour l’utilisateur
  • 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 build en 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 StableDiffusionPipeline de Diffusers puis à l’envelopper avec StreamDiffusion
  • L’exemple Img2Img charge le modèle KBlueLeaf/kohaku-v2.1 et configure le flux avec t_index_list=[32, 45]
    • Si le modèle n’est pas un LCM, il faut utiliser load_lcm_lora() et fuse_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()
  • L’exemple Txt2Img utilise t_index_list=[0, 16, 32, 45] et recommande cfg_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_tensorrt de streamdiffusion.acceleration.tensorrt
  • La configuration d’exemple transmet stream, "engines" et max_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 traitement
    • similar_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_type de StreamDiffusion
  • 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_type sont les suivantes
    • Sans CFG : "none"
    • CFG classique : "full"
    • RCFG Self-Negative : "self"
    • RCFG Onetime-Negative : "initialize"
  • delta joue un rôle d’atténuation pour ajuster l’effet du RCFG

Modèles et ressources utilisés

1 commentaires

 
GN⁺ 2023-12-25
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.

    • J’attends le moment où cela pourra faire mon travail à ma place, tourner sur mon PC et être connecté à Slack. Mon employeur recevra alors un résultat similaire à ce que j’aurais produit à la main, je pourrai être payé sans passer réellement du temps à travailler, et je pourrai enfin me consacrer à mes loisirs. C’est bien vers ça que tout se dirige, non ?
    • Tout l’écosystème IA open source donne cette impression en ce moment. Presque chaque jour, une nouvelle avancée rend possible quelque chose qu’on pensait impossible, et il est vraiment difficile de suivre tous ces changements.
    • En tant que développeur frontend, je comprends maintenant les gens qui se plaignaient que le monde du frontend changeait trop vite pour qu’on puisse suivre.
    • Ces logiciels évoluent plus vite que je ne peux faire apt-get install.
    • Ça me fait penser aux jeux incrémentaux (https://www.reddit.com/r/incremental_games/). Mais il vaut mieux ne pas commencer ce genre de jeu. Vos vacances pourraient y passer.
  • 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\screen donne 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.

    • Je me demande ce qu’il en est de la qualité réelle, de la diversité et de l’adéquation au prompt. Je n’ai pas accès à mon GPU pendant quelques jours, donc je ne peux pas vérifier moi-même.
      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 ?

    • Je n’ai pas essayé moi-même, mais j’imagine qu’un traitement par lots n’est probablement pas nécessaire.
      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.py de realtime-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 ?

    • C’est une entrée vidéo. D’après l’article, le filtre de similarité stochastique réduit la charge GPU en diminuant le travail de transformation lorsque l’entrée vidéo change peu par rapport à la frame précédente. Les frames rouges du GIF ci-dessus en sont un exemple.
    • Comme une issue GitHub est actuellement ouverte pour ajouter la prise en charge de ControlNet, je ne pense pas que ce soit ControlNet. Ça ressemble plutôt à de l’img2img utilisant simplement un prompt et une échelle rcfg.
    • Donc cela veut dire que l’image de gauche est l’image d’origine et celle de droite le résultat ?
  • Quel fps obtient-on sur Apple Silicon ?

    • MPS n’est pas pris en charge, donc 0.
      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.
    • Je fais tourner SDXL Turbo avec DrawThings sur un M1 Pro et 32 Go de RAM.
      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.
    • Je pense qu’on pourrait au moins atteindre environ 1/8, mais si ça tournait à au moins 24 fps sur Apple, ce serait énorme. Avec un peu d’interpolation, ce serait peut-être possible.
      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 ?