En 2022, le domaine de la génération d'images a été révolutionné par les modèles de diffusion — une classe de modèles génératifs qui apprennent à créer des images en débruitant progressivement du bruit aléatoire. L'idée clé provient de l'article « Denoising Diffusion Probabilistic Models » (DDPM) de Ho et al. (2020), qui a montré que le débruitage itératif d'une image sur de nombreuses étapes pouvait produire des résultats photoréalistes. Cependant, les premiers modèles de diffusion étaient coûteux en calcul, nécessitant des centaines d'étapes de débruitage. Les modèles de diffusion latente (Latent Diffusion Models, LDM), introduits par Rombach et al. en 2022, ont considérablement amélioré l'efficacité en effectuant le processus de diffusion dans un espace latent compressé plutôt que dans l'espace pixel.
Pour rendre la génération praticable sur processeur (CPU), nous utiliserons un modèle compressé (compact model) appelé bk-sdm qui maintient une qualité de génération acceptable tout en étant beaucoup plus léger que le modèle original. Dans ce travail, vous explorerez ces modèles de manière pratique.
In 2022, the field of image generation was revolutionized by diffusion models—a class of generative models that learn to create images by gradually denoising random noise. The key insight came from the 2020 paper "Denoising Diffusion Probabilistic Models" (DDPM) by Ho et al., which showed that iteratively denoising an image over many steps could produce photorealistic results. However, early diffusion models were computationally expensive, requiring hundreds of denoising steps. Latent Diffusion Models (LDMs), introduced by Rombach et al. in 2022, dramatically improved efficiency by performing the diffusion process in a compressed latent space rather than pixel space.
To make generation practical on CPUs, we will use a compressed model named bk-sdm which maintains acceptable generation quality while being much lighter than the original model. In this assignment, you will explore these models hands-on.
Le but de ce travail est d'explorer la génération d'images texte-vers-image à l'aide de modèles de diffusion et d'étendre un code existant pour supporter l'inpainting — la tâche de remplir des régions masquées d'une image. Vous devrez :
The goal of this homework is to explore text-to-image generation using diffusion models and extend an existing codebase to support inpainting—the task of filling in masked regions of an image. You will:
imgs.zip (images et masques de test) nécessaires pour les
sections sur l'inpainting.
pip install -r requirements.txt.
python tp5.py. Lors de la première exécution, le téléchargement du modèle
prendra quelques minutes.
prompt dans tp5.py avec une courte description
de votre cru (par exemple "un paysage magnifique avec un soleil couchant") et exécutez à
nouveau le script. Vous devriez voir l'image générée s'enregistrer sous
example.png. Répétez cette opération avec au moins 3 prompts différents de votre cru et rapportez les images générées dans votre rapport.
Le guidage sans classifieur (Classifier-Free Guidance, CFG) est une technique qui améliore l'alignement entre les images générées et les prompts textuels. Le paramètre d'échelle de guidage (guidance scale) contrôle le compromis entre la qualité/diversité des images et l'adhérence au prompt.
L'équation clef est :
$\varepsilon_{\text{guidé}} = \varepsilon_{\text{incond}} + s \cdot (\varepsilon_{\text{cond}} - \varepsilon_{\text{incond}})$
où $\varepsilon_{\text{cond}}$ est la prédiction du modèle conditionnée par le prompt textuel, $\varepsilon_{\text{incond}}$ est la prédiction inconditionnelle (sans prompt) et $s$ est le facteur de guidage. Un facteur de guidage plus élevé aligne la génération plus fortement vers le prompt, mais peut causer des artéfacts.
En utilisant la même graine (seed, déjà spécifié fixe dans le code de départ) et le même prompt, générez des images avec les
facteurs de guidage suivants : 0.0, 0.5, 1.0, 2.0, 3.0, 5.0, 7.5, 10.0, 15.0, 20.0, 40.0 et 60.0. Vous devrez modifier la variable guidance_scale dans
le script tp5.py.
Pour chaque échelle de guidage, documentez :
guidance_scale = 1.0 ? Pourquoi ?L'inpainting consiste à reconstruire une région masquée d'une image en générant un contenu cohérent avec le contexte visuel autour du masque.
Étendez le code fourni pour supporter l'inpainting d'images.
Voici les étapes à réaliser pour effectuer l'inpainting:
generate_image.width et height pixels, puis convertissez-la en tenseur [-1, 1] et encodez l'image par le VAE pour obtenir les vecteurs latents qui la représentent. Finalement, générez le masque latent en réduisant la résolution du masque d'entrée pour correspondre aux dimensions latentes. Voici un code d'exemple pour réaliser ceci:image = image.resize((width, height), Image.Resampling.LANCZOS)
mask = mask.resize((width, height), Image.Resampling.LANCZOS)
# Convertir l'image en tenseur [-1, 1]
img_array = np.array(image.convert("RGB")).astype(np.float32) / 127.5 - 1.0
img_tensor = torch.from_numpy(img_array).permute(2, 0, 1).unsqueeze(0).to(device, dtype=text_embeddings.dtype)
# Encoder l'image dans l'espace latent
init_latents_orig = pipe.vae.encode(img_tensor).latent_dist.sample(generator=generator)
init_latents_orig = init_latents_orig * pipe.vae.config.scaling_factor
# Convertir le masque en tenseur [0, 1] et redimensionner pour correspondre aux dimensions latentes
mask_array = np.array(mask.convert("L")).astype(np.float32) / 255.0
# Le masque est 1 où nous voulons régénérer (blanc), 0 où nous voulons conserver (noir)
mask_tensor = torch.from_numpy(mask_array).unsqueeze(0).unsqueeze(0).to(device, dtype=text_embeddings.dtype)
mask_latent = torch.nn.functional.interpolate(mask_tensor, size=(height // 8, width // 8), mode='nearest')t_prev = timesteps[i + 1]) dans les régions non masquées, par exemple: noise = torch.randn_like(init_latents_orig) t_prev_tensor = torch.tensor([t_prev.item()], device=device) noisy_orig_latents = pipe.scheduler.add_noise(init_latents_orig, noise, t_prev_tensor)Puis, fusionnez ces latents avec les latents générés à l'étape courante, une étape similaire à celle de composition:
latents = (1 - mask_latent) * noisy_orig_latents + mask_latent * latentsTestez votre implémentation sur les images et masques de test fournis. Votre inpainting devrait :
Discussion requise : Veuillez discuter brièvement des résultats obtenus dans cette section, avec quelques images de tests et leurs résultats en inpainting.
Exemple de suppression d'objet (avant / masque / résultat). Le modèle employé n'est pas parfait, mais permet d'obtenir des résultats éducatifs.
En utilisant votre implémentation d'inpainting, effectuez la suppression d'objets sur des images. L'objectif est de retirer des objets indésirables et de remplir la région avec un contenu d'arrière-plan plausible.
Utilisez les images de imgs.zip suivantes (avec le masque
*_mask.png correspondant) :
graffiti.png : supprimez le graffitipisa.png : supprimez la tour de Pisechateau_frontenac.png : supprimez la personne devant le ChâteauPour chaque suppression :
Exigence obligatoire (évaluée) : Ajoutez au moins un cas supplémentaire avec votre propre image et votre propre masque.
Discussion requise : Veuillez discuter brièvement des résultats obtenus dans cette section.
Remplacement d'objet (avant / masque / résultat).
Le remplacement d'objets combine le masquage avec la génération ciblée : au lieu de remplir avec de l'arrière-plan, vous générez un nouvel objet à la place de l'ancien.
Utilisez les images de imgs.zip suivantes (avec le masque
*_mask.png correspondant) :
pyramides.webp : ajoutez de la neige sur la pyramidebaie_beauport.avif : ajoutez un pingouin sur la plagemoulin.png : remplacez le moulin par un géantPour chaque remplacement :
Exigence obligatoire (évaluée) : Ajoutez au moins un cas supplémentaire avec votre propre image et votre propre masque.
Discussion requise : Veuillez discuter brièvement des résultats obtenus dans cette section.
Cette section est OBLIGATOIRE pour les étudiants aux cycles supérieurs (maîtrise/doctorat) :
Dans votre rapport, montrez clairement l'évolution du débruitage au fil des étapes de diffusion pour au moins un exemple d'inpainting.
Discussion requise : Veuillez discuter brièvement des résultats obtenus dans cette section.
imgs.zip (test images and masks) needed for the inpainting sections.
pip install -r requirements.txt.python tp5.py. On the first run, model download will take a few minutes.prompt in tp5.py with a short prompt of your choice (for example "a beautiful landscape with a sunset") and run the script again. You should see the generated image saved as example.png. Repeat this with at least 3 different prompts and include the generated images in your report.Classifier-Free Guidance (CFG) is a technique that improves the alignment between generated images and text prompts without requiring a separate classifier network. The guidance scale parameter controls the trade-off between image quality/diversity and prompt adherence.
The key equation is:
$\varepsilon_{\text{guided}} = \varepsilon_{\text{uncond}} + s \times (\varepsilon_{\text{cond}} - \varepsilon_{\text{uncond}})$
where $\varepsilon_{\text{cond}}$ is the model's prediction conditioned on the text prompt, $\varepsilon_{\text{uncond}}$ is the unconditional prediction (no prompt), and $s$ is the guidance scale. Higher guidance scales push the generation more strongly toward the prompt, but may produce artifacts.
Using the same seed (already fixed in the starter code) and the same prompt, generate images with guidance scales: 0.0, 0.5, 1.0, 2.0, 3.0, 5.0, 7.5, 10.0, 15.0, 20.0, 40.0, and 60.0. You will need to modify the variable guidance_scale in tp5.py.
For each guidance scale, document:
guidance_scale = 1.0? Why?Inpainting is the task of reconstructing a masked region in an image by generating content that is consistent with the surrounding visual context.
Extend the provided code to support image inpainting.
Here are the steps to implement inpainting:
generate_image.width and height, convert it to a tensor in [-1, 1], and encode it with the VAE to obtain latent vectors. Then build a latent mask by downsampling the input mask to match latent dimensions. Example code:
image = image.resize((width, height), Image.Resampling.LANCZOS)
mask = mask.resize((width, height), Image.Resampling.LANCZOS)
# Convert image to tensor [-1, 1]
img_array = np.array(image.convert("RGB")).astype(np.float32) / 127.5 - 1.0
img_tensor = torch.from_numpy(img_array).permute(2, 0, 1).unsqueeze(0).to(device, dtype=text_embeddings.dtype)
# Encode image in latent space
init_latents_orig = pipe.vae.encode(img_tensor).latent_dist.sample(generator=generator)
init_latents_orig = init_latents_orig * pipe.vae.config.scaling_factor
# Convert mask to tensor [0, 1] and resize to latent dimensions
mask_array = np.array(mask.convert("L")).astype(np.float32) / 255.0
# The mask is 1 where we regenerate (white), 0 where we keep (black)
mask_tensor = torch.from_numpy(mask_array).unsqueeze(0).unsqueeze(0).to(device, dtype=text_embeddings.dtype)
mask_latent = torch.nn.functional.interpolate(mask_tensor, size=(height // 8, width // 8), mode='nearest')t_prev = timesteps[i + 1]) in the unmasked region, for example:
noise = torch.randn_like(init_latents_orig) t_prev_tensor = torch.tensor([t_prev.item()], device=device) noisy_orig_latents = pipe.scheduler.add_noise(init_latents_orig, noise, t_prev_tensor)Then combine these latents with current generated latents, similarly to compositing:
latents = (1 - mask_latent) * noisy_orig_latents + mask_latent * latents.Test your implementation on the provided test images and masks. Your inpainting should:
Required Discussion: Please discuss briefly the results obtained in this section.
Teaser: object removal (before / mask / result).
Using your inpainting implementation, perform object removal on images. The goal is to remove unwanted objects and fill the region with plausible background content.
Use the following images from imgs.zip (with the corresponding
*_mask.png mask):
graffiti.png: remove the graffitipisa.png: remove the Pisa towerchateau_frontenac.png: remove the person in front of the ChâteauFor each removal:
Mandatory graded requirement: Include at least one additional test case using your own image and your own mask.
Required Discussion: Please discuss briefly the results obtained in this section.
Teaser: object replacement (before / mask / result).
Object replacement combines masking with targeted generation: instead of filling with background, you generate a new object in place of the old one.
Use the following images from imgs.zip (with the corresponding
*_mask.png mask):
pyramides.webp: add snow on the pyramidbaie_beauport.avif: add a penguin to the beachmoulin.png: replace the windmill by a giantFor each replacement:
Mandatory graded requirement: Include at least one additional test case using your own image and your own mask.
Required Discussion: Please discuss briefly the results obtained in this section.
This section is MANDATORY for graduate students (Masters/PhD):
In your report, clearly present the denoising progression across diffusion steps for at least one inpainting example.
Required Discussion: Please discuss briefly the results obtained in this section.
Essayez une (ou plusieurs !) de ces idées pour approfondir vos connaissances (et bonifier votre note). Pour chaque idée, vous devez présenter les résultats obtenus et une brève discussion sur ceux-ci.
Try one (or many!) of these ideas to increase your understanding on this subject (and your grade). For each idea, you must present the results obtained and a brief discussion on them.
tp5.py et diffusion.py pour
comprendre la boucle de base avant de la modifier.tp5.py and diffusion.py to
understand the basic loop before modifying it.Chaque section doit inclure des figures démontrant vos résultats :
| Section | Contenu requis | Points (GIF-4105) | Points (GIF-7105) |
|---|---|---|---|
| 1. Configuration et génération | Info système, exemples de génération, expériences de prompts | 15% | 10% |
| 2. Guidage sans classifieur | Comparaisons d'échelle de guidage, analyse et discussion | 15% | 10% |
| 3. Implémentation de l'inpainting | Explication du code, résultats de validation | 30% | 25% |
| 4. Suppression d'objets | Exemples avant/après, analyse des échecs | 15% | 10% |
| 5. Remplacement d'objets | Exemples de remplacement | 15% | 10% |
| 6. Visualisation des étapes de diffusion (cycles supérieurs) | Séquence des étapes intermédiaires et analyse | — | 15% |
| Qualité du rapport | Clarté, qualité des figures, complétude | 10% | 10% |
| Crédits supplémentaires | Description, résultats, brève discussion pour chaque | Jusqu'à 20% bonus | |
Each section must include figures demonstrating your results:
| Section | Required Content | Points (GIF-4105) | Points (GIF-7105) |
|---|---|---|---|
| 1. Setup and Generation | System info, generation examples, prompt experiments | 15% | 10% |
| 2. Classifier-Free Guidance | Guidance scale comparisons, analysis and discussion | 15% | 10% |
| 3. Inpainting Implementation | Code explanation, validation results | 30% | 25% |
| 4. Object Removal | Before/after examples, failure analysis | 15% | 10% |
| 5. Object Replacement | Replacement examples | 15% | 10% |
| 6. Diffusion Step Visualization (graduate only) | Intermediate step sequence and analysis of its effect | — | 15% |
| Report Quality | Clarity, figure quality, completeness | 10% | 10% |
| Extra Credit | Description, results, brief discussion for each | Up to 20% bonus | |
Pour la remise de votre travail, créez un fichier tp5.zip qui contient :
code contenant tous vos fichiers sources modifiés et scripts
supplémentairesrapport contenant votre rapport HTML (rapport/index.html)
et toutes les images/ressources auxquelles il fait référence. Assurez-vous de mettre les images en chemin relatif, afin que les images puissent être chargées depuis l'ordinateur du correcteur!Finalement, veuillez téléverser votre fichier tp5.zip sur le
portail des cours avant la date limite. La politique des retards mentionnée dans le plan de
cours sera appliquée. Pour toutes questions concernant la procédure de remise ou le travail
lui-même, posez vos
questions sur PAX !
For this homework, you must create a tp5.zip file containing:
code folder containing all modified source files and additional scriptsrapport folder containing your HTML report (rapport/index.html) and
all images/assets it references. Make sure all image paths are relative, so images load correctly on the grader's machine.Finally, you should upload this file (tp5.zip) on the "portail
des cours" before the deadline. The late submission policy described in the course plan will
be applied. For any question regarding the submission process or the project as such, ask your questions on
PAX!
Si vous souhaitez approfondir vos connaissances sur les modèles de diffusion et l'inpainting, nous recommandons les ressources suivantes :
If you want to deepen your understanding of diffusion models and inpainting, we recommend the following resources: