Le monde du commerce électronique se développant rapidement depuis la pandémie, il est plus important que jamais de pouvoir présenter son produit de manière attrayante et originale. Comme les clients ne peuvent ni toucher ni essayer votre produit, la première étape pour les inciter à acheter consiste à le faire ressortir dans des images étonnantes, professionnelles et détaillées. Des études montrent que 76,5 % des clients reconnaissent l'impact significatif d'une photographie de produit de haute qualité et le rôle qu'elle joue dans leur décision d'achat. Toutefois, l'obtention de photos de produits professionnelles et de haute qualité n'est pas gratuite. Sans compter le coût et les frais généraux liés à l'installation d'un studio et à l'acheminement de votre produit sur le lieu de travail, les professionnels peuvent facturer en moyenne entre 35 et 50 dollars par image, voire plus de 400 dollars dans le haut de gamme. Beaucoup de petits entrepreneurs n'ont tout simplement pas les moyens de faire cela pour chaque produit, mais même les grands acteurs, qui ont des fonds, peuvent ne pas avoir le temps de mettre tout cela en place, car leur catalogue de produits change rapidement.
Et si ce processus long et coûteux n'était pas nécessaire ? Et si nous pouvions simplement prendre une photo amateur de notre produit, laisser la magie de l'IA agir et obtenir des images professionnelles en ligne en un rien de temps ? Cet article de blog montre le développement d'un outil, exploitant plusieurs modèles génératifs d'IA et obtenant des résultats remarquables, comme le montre le schéma ci-dessous ! Si vous voulez l'essayer par vous-même, la démo et le code sont disponibles gratuitement sur HuggingFace !
Ceux qui sont impatients d'essayer la démo peuvent y accéder immédiatement ici.
Exemples :
A first step in building this demo was getting up to speed with current best practices in the field of Gen AI, especially for image generation. The Hugging Face Hub is a great platform offering a wide range of open source models, datasets and demo’s to test and learn about new, powerful models. This project combines 3 important models: SAM, Stable Diffusion (+Inpainting) and ControlNet. Figure {1} presents the general workflow for the generation process. In what follows we will dive deeper into every aspect of this process.
Le modèle Segment Anything de Meta AI Research a proposé un nouveau modèle pour la segmentation des images. Le modèle, illustré à la figure {2}, propose une solution à la tâche de segmentation à déclenchement, qui vise à fournir un masque de segmentation valide à partir d'une certaine invite. L'invite spécifie ce qu'il faut segmenter dans l'image. Dans le cas présent, il s'agit d'informations spatiales sous forme de points ou de boîtes indiquant l'objet que nous voulons masquer. Le modèle permet également de saisir du texte et des masques, mais cela n'a pas été utilisé dans ce contexte.
L'architecture générale du modèle se compose de trois parties principales. Un encodeur d'images lourd, un encodeur d'invites léger et un décodeur de masques rapide. Cette architecture permet une utilisation flexible et en temps réel, ce qui est parfaitement adapté à notre contexte. Le codeur d'images consiste en un transformateur de vision (ViT) pré-entraîné par MAE. Différentes tailles : Huge, Large et Base ViT SAM. Dans ce contexte, nous avons utilisé le modèle de base car il est plus léger, plus rapide et ses performances ne sont pas très éloignées de celles des modèles plus grands. Ce codeur d'image est exécuté une fois par image et peut ensuite être combiné avec différentes invites en tant qu'entrée pour le décodeur de masque. Le décodeur de masque associe efficacement l'image et l'incitation à des probabilités de masque pour chaque emplacement de l'image. Les invites étant ambiguës (par exemple, vous voulez un masque pour un t-shirt ou pour la personne entière portant le t-shirt), l'encodeur de masques compare plusieurs masques valides et produit celui dont le score de confiance associé est le plus élevé.
This part is where the true magic happens. Stable diffusion is a latent text-to-image diffusion model created by CompVis, Stability AI and LAION. The model is based on the ideas proposed in the paper by Robin Rombach et al. Stable Diffusion is capable of generating photo-realistic images given any text input. It consists of three main building blocks: a text encoder, a U-net and an autoencoder (VAE). Visualisation of these components can be found in figure {3}.
Stable Diffusion utilise un codeur de texte pré-entraîné appelé CLIPTextModel. Il convertit l'invite d'entrée, par exemple "dog on the moon", en une représentation numérique, également connue sous le nom d'intégration d'image, qui peut être utilisée comme entrée pour le réseau U. Le réseau U est l'endroit où la diffusion elle-même a lieu. C'est dans le réseau en U que s'effectue la diffusion proprement dite. Il s'agit d'une architecture de réseau neuronal avec une partie encodeur et une partie décodeur composées de blocs ResNet. Les parties encodeur et décodeur sont reliées par des connexions sautées afin de ne pas perdre la sémantique apprise au cours des premières étapes du réseau.
Lors de la génération d'images, le réseau en U prend en compte les incrustations rapides ainsi qu'une image contenant un bruit gaussien aléatoire pur. Il prédit itérativement des images moins bruitées en un nombre prédéfini d'étapes (par exemple 25) à partir de son itération précédente jusqu'à ce qu'il obtienne une image finale claire.
Enfin, l'Autoencoder vous permet d'aller et venir entre l'espace latent et l'espace pixel. Il peut convertir une image normale en un espace de dimension inférieure dans lequel le processus de diffusion peut avoir lieu. Cela permet au processus de diffusion d'être beaucoup moins gourmand en mémoire et en temps. Le fait de travailler dans l'espace latent permet également à l'U-net de se concentrer davantage sur les concepts généraux de l'image, tels que les formes, les positions et les couleurs, et de ne pas avoir à prédire chaque pixel. Après le processus de diffusion, l'autoencodeur projette l'image prédite de l'espace latent à l'espace pixel par l'intermédiaire du décodeur VAE. L'autoencodeur de la diffusion stable a un facteur de réduction de 8, ce qui signifie qu'une image de forme (3,512,512) devient (3,64,64) dans l'espace latent, soit 8x8 = 64 fois moins de mémoire !
Dans notre cas, nous avons utilisé stable-diffusion-2-inpainting. Ce modèle part essentiellement du point de contrôle normal stable-diffusion-2-base et est ensuite entraîné pendant 200 000 étapes supplémentaires à l'aide de la stratégie de génération de masques présentée dans le LAMA. Cela nous permet de conditionner davantage notre processus de diffusion et de conserver certaines parties, comme un objet personnel, à l'identique. Comme notre démo permet également l'inpainting dans le sens de la régénération d'une petite partie (corrompue) d'une image, nous l'utilisons principalement pour l'outpainting. L'outpainting est en fait le contraire et signifie que nous étendons une image ou, dans notre cas, une image de produit au-delà de ses limites normales. Le modèle que nous avons utilisé ici permet à la fois l'in- et l'outpainting. Des exemples sont présentés dans la figure {4}.
Controlnet présente une solution permettant de mieux contrôler le processus de génération de grands modèles texte-image tels que Stable Diffusion. Il est basé sur l'idée d'hyperréseaux où nous formons un petit réseau pour influencer les poids d'un plus grand. Controlnet clone les poids d'un grand modèle dans une copie "verrouillée" et "entraînable". Comme nous ne touchons pas au modèle de diffusion original, il ne perd aucune des connaissances acquises au cours de l'entraînement sur des milliards d'images. Dans le cas de la diffusion stable, Controlnet ne fait que copier les poids de l'encodeur U-net dans une copie entraînable. Les deux modèles sont ensuite connectés par des couches spéciales de zéro-convolution . Enfin, la copie entraînable peut être entraînée sur un certain ensemble de données spécifiques à une tâche afin d'apprendre un contrôle supplémentaire. La figure {5} illustre l'architecture de Controlnet avec diffusion stable.
Un grand nombre de modèles Controlnet différents sont disponibles sur HuggingFace, chacun ajoutant un conditionnement supplémentaire, tel que la perception de la profondeur, la pose d'une personne, la segmentation, et plus encore, afin d'améliorer le processus de génération. Dans notre démo, nous n'utilisons que le modèle "Canny edges" comme conditionnement. Ce modèle autorise une image de conditionnement supplémentaire en entrée. L'image de conditionnement est une image monochrome avec des bords blancs sur un fond noir. Ces bords seront alors préservés au cours du processus de génération. Dans notre cas, il s'agit d'un atout précieux, car nous souhaitons conserver les bords du produit original sans introduire de caractéristiques ou d'éléments visuels supplémentaires irréalistes.
La figure {6} présente un exemple de diffusion stable avec détection des bords par Controlnet Canny.
Pour rendre cette démo accessible au grand public, tous les modèles précédents ont été regroupés dans une démo conviviale utilisant Streamlit, afin que chacun puisse la tester par lui-même ! Streamlit permet un développement frontal rapide et flexible en intégrant certaines lignes de code dans vos scripts Python, ne nécessitant ainsi aucune connaissance en HTML, CSS ou JavaScript. La puissance de Streamlit vient de sa capacité à réexécuter automatiquement le script et à mettre à jour les sorties chaque fois qu'une entrée est modifiée. Toutefois, cela signifie également que Streamlit présente certains inconvénients et doit être utilisé avec précaution. Comme l'ensemble du script est réexécuté à chaque fois de haut en bas, les variables sont également créées à partir de zéro à chaque itération. Streamlit met en œuvre un concept d'état de session pour maintenir les variables entre les itérations. Vous devez réfléchir soigneusement à l'utilisation d'une variable normale ou à l'enregistrement de la variable dans l'état_de_session afin de vous assurer que le script complet peut être exécuté chaque fois qu'une certaine variable change.
Après avoir construit l'application, il est possible de l'exécuter et de la maintenir sur le site web de Hugging Face. Ils ont construit une plateforme appelée Hugging Face Spaces, qui vous permet d'exécuter des conteneurs Streamlit, Gradio et Docker sur une VM gérée par Hugging Face, permettant à d'autres personnes d'y accéder. Cependant, l'exécution de votre application dans un lieu public soulève également quelques problèmes. Puisque plusieurs utilisateurs peuvent accéder à la VM en même temps, vous devez gérer avec soin les différents threads, afin de ne pas épuiser les ressources disponibles et de ne pas faire chuter les performances de façon spectaculaire. Dans notre cas, le modèle de diffusion stable est très gourmand en mémoire, puisqu'il utilise la mémoire du GPU pour la génération d'images. Permettre à plusieurs utilisateurs de générer des images en même temps pourrait faire planter la démo (en donnant à tout le monde les fameuses erreurs CUDA out of memory). Pour résoudre ce problème, nous avons mis en place un système de file d'attente qui exploite les techniques de mise en cache intégrées à streamlit, ainsi qu'un mécanisme de mise en mémoire tampon des demandes d'inférence parallèles.
Streamlit offre un moyen pratique d'optimiser l'utilisation des ressources en appliquant la méthode st.cache_resource à vos fonctions. Ce décorateur enregistre les résultats des fonctions en mémoire et fonctionne de la même manière que lru_cache, un décorateur plus connu dans le domaine de la programmation. Lorsque la fonction est appelée à nouveau avec les mêmes entrées, elle récupère la sortie stockée au lieu de réexécuter la fonction. Ce mécanisme améliore considérablement les performances de l'application, en particulier pour les fonctions qui prennent du temps, comme la récupération des poids d'un modèle de diffusion stable. Le système de file d'attente, quant à lui, utilise ce concept pour partager la même instance d'une classe personnalisée WaitingQueue entre tous les utilisateurs. La figure {7} illustre ce système.
La classe stocke une file d'attente et un dictionnaire. La file d'attente détermine la position de l'utilisateur. Le dictionnaire est utilisé pour stocker des informations supplémentaires sur l'utilisateur. Ces informations sont utilisées pour vérifier si le prédécesseur dans la file d'attente est toujours actif. Deux mécanismes sont en place pour garantir l'absence de blocages et le bon déroulement du processus. Tout d'abord, si un utilisateur de la file d'attente ne met pas à jour son horodatage toutes les 10 secondes alors qu'il ne génère pas d'images, l'utilisateur qui le suit l'éliminera de la file d'attente. Deuxièmement, si un utilisateur génère des images pendant plus de 30 secondes, son successeur supposera également que quelque chose n'a pas fonctionné et retirera son prédécesseur de la file d'attente.
Maintenant que nous avons expliqué chaque élément du flux de travail général dans la figure {1}, nous allons donner un exemple simple de la façon dont tout cela se déroule dans la démo. Comme ce projet faisait partie d'un stage chez ML6, nous essaierons de faire des images professionnelles incluant certains de leurs produits. L'interface utilisateur de la démo est divisée en 3 onglets différents, chacun présentant une partie du flux de travail. Nous avons "Mask creation", "Place mask(s)" et "Generate Images" (voir figure 8 pour des captures d'écran du flux de travail).
Tout d'abord, nous devons prendre des photos amateurs de nos produits et les charger dans la démo. Ici, nous allons essayer quelques exemples avec une tasse à café, une bouteille d'eau et un t-shirt. Une fois les photos chargées dans la démo, nous commencerons par l'onglet 1 pour créer les masques des différents objets. Cela correspond à l'ajout d'un ou plusieurs points et/ou boîtes aux images qui peuvent servir d'entrée à notre modèle SAM. La figure {8} illustre ce processus.
Après avoir extrait tous les produits nécessaires de nos images, nous passons au deuxième onglet. Ici, nous pouvons redimensionner, faire pivoter et placer nos objets sur une toile vierge. Nous pouvons également définir la taille de la toile vierge. Celle-ci correspondra à la taille des images générées. La figure {9} illustre ce processus.
Enfin, nous passerons à l'onglet 3. Ici, nous pouvons spécifier le nombre d'images que nous voulons, ajouter une invite positive et négative et sélectionner une échelle d'orientation du réseau de contrôle. L'incitation positive doit être quelque chose à quoi vous voulez que vos images ressemblent "par exemple, une tasse à café sur la table". L'invite négative, quant à elle, doit contenir des mots désignant des choses ou des concepts que vous souhaitez que le modèle évite lors de la génération, par exemple "laid, de mauvaise qualité, mains déformées,...". L'échelle d'orientation de Controlnet indique dans quelle mesure le modèle Controlnet doit influencer Stable Diffusion. Lorsqu'elle est réglée sur 0, Controlnet ne fait rien. Si elle est réglée sur 1, Stable Diffusion ne génère des contours qu'aux endroits où ils étaient présents sur l'image de conditionnement. La figure {10} illustre le déroulement des opérations du dernier onglet. L'ensemble du processus n'a pris que 5 minutes !
Voici quelques-uns des résultats obtenus après quelques essais ! Remarquez les ombres et les reflets que la diffusion stable est capable de générer autour des objets.
Bien qu'il y ait encore un écart notable entre ces résultats et les images professionnelles réelles, ils montrent clairement le potentiel de ces modèles texte-image. Cet outil pourrait déjà s'avérer très utile, par exemple pour les petites entreprises, pour certains produits de base à faible coût, ou comme solution temporaire jusqu'à ce que les images professionnelles soient disponibles.
Comme les modèles utilisés dans cet exemple sont tous disponibles sur étagère, un réglage fin pour certains produits ou environnements peut encore améliorer considérablement les performances (pour un exemple, voir cette démonstration de décoration d'intérieur qui utilise un réseau de contrôle finement réglé pour une génération de haute qualité). Par ailleurs, la communauté de l'IA évolue à un rythme effréné, avec de nouveaux modèles/outils/applications qui sortent tous les jours. Parmi les nouveaux projets open source en cours de développement, citons BLIP-Diffusion et Unicontrolnet. BLIP-Diffusion, comme Dreambooth et Textual Inversion, permet au modèle d'apprendre des objets personnalisés basés sur des images. Le modèle devrait ensuite être capable de régénérer lui-même ces objets. L'un des grands défis consiste à pouvoir former les objets rapidement et à les générer avec précision. Unicontrolnet est une nouvelle approche qui permet d'appliquer plusieurs conditions de controlnet en même temps, ce qui permet de contrôler encore davantage le processus de génération.
Compte tenu du compromis entre la qualité et le coût/temps, l'IA générative est et sera certainement un grand concurrent et changera le monde de la photographie professionnelle de produits !
Ce billet a été rédigé par Clement Viaene, stagiaire à la ML6. Vous pouvez également le lire sur la plateforme Medium ici.