From fda63082d5ae2e3906ca0fd2f57c4c55441b0086 Mon Sep 17 00:00:00 2001 From: hysts Date: Wed, 24 Aug 2022 20:33:30 +0900 Subject: [PATCH 1/8] Refactor progress bar of pipeline __call__ --- src/diffusers/pipeline_utils.py | 17 +++++++++++++++++ src/diffusers/pipelines/ddim/pipeline_ddim.py | 4 +--- src/diffusers/pipelines/ddpm/pipeline_ddpm.py | 4 +--- .../pipeline_latent_diffusion.py | 3 +-- .../pipeline_latent_diffusion_uncond.py | 4 +--- src/diffusers/pipelines/pndm/pipeline_pndm.py | 4 +--- .../pipeline_stable_diffusion.py | 3 +-- .../pipeline_stochastic_karras_ve.py | 2 +- 8 files changed, 24 insertions(+), 17 deletions(-) diff --git a/src/diffusers/pipeline_utils.py b/src/diffusers/pipeline_utils.py index f27789f0bfa8..1b65490776b7 100644 --- a/src/diffusers/pipeline_utils.py +++ b/src/diffusers/pipeline_utils.py @@ -23,6 +23,7 @@ from huggingface_hub import snapshot_download from PIL import Image +from tqdm.auto import tqdm from .configuration_utils import ConfigMixin from .utils import DIFFUSERS_CACHE, logging @@ -57,6 +58,10 @@ class DiffusionPipeline(ConfigMixin): config_name = "model_index.json" + def __init__(self): + super().__init__() + self._is_progress_bar_enabled = True + def register_modules(self, **kwargs): # import it here to avoid circular import from diffusers import pipelines @@ -266,3 +271,15 @@ def numpy_to_pil(images): pil_images = [Image.fromarray(image) for image in images] return pil_images + + def progress_bar(self, iterable): + if self._is_progress_bar_enabled: + return tqdm(iterable) + else: + return iterable + + def enable_progress_bar(self): + self._is_progress_bar_enabled = True + + def disable_progress_bar(self): + self._is_progress_bar_enabled = False diff --git a/src/diffusers/pipelines/ddim/pipeline_ddim.py b/src/diffusers/pipelines/ddim/pipeline_ddim.py index 700e2b9ca392..03a9c52b16f9 100644 --- a/src/diffusers/pipelines/ddim/pipeline_ddim.py +++ b/src/diffusers/pipelines/ddim/pipeline_ddim.py @@ -18,8 +18,6 @@ import torch -from tqdm.auto import tqdm - from ...pipeline_utils import DiffusionPipeline @@ -56,7 +54,7 @@ def __call__(self, batch_size=1, generator=None, eta=0.0, num_inference_steps=50 # set step values self.scheduler.set_timesteps(num_inference_steps) - for t in tqdm(self.scheduler.timesteps): + for t in self.progress_bar(self.scheduler.timesteps): # 1. predict noise model_output model_output = self.unet(image, t)["sample"] diff --git a/src/diffusers/pipelines/ddpm/pipeline_ddpm.py b/src/diffusers/pipelines/ddpm/pipeline_ddpm.py index 099add5daa74..27c156def843 100644 --- a/src/diffusers/pipelines/ddpm/pipeline_ddpm.py +++ b/src/diffusers/pipelines/ddpm/pipeline_ddpm.py @@ -18,8 +18,6 @@ import torch -from tqdm.auto import tqdm - from ...pipeline_utils import DiffusionPipeline @@ -53,7 +51,7 @@ def __call__(self, batch_size=1, generator=None, output_type="pil", **kwargs): # set step values self.scheduler.set_timesteps(1000) - for t in tqdm(self.scheduler.timesteps): + for t in self.progress_bar(self.scheduler.timesteps): # 1. predict noise model_output model_output = self.unet(image, t)["sample"] diff --git a/src/diffusers/pipelines/latent_diffusion/pipeline_latent_diffusion.py b/src/diffusers/pipelines/latent_diffusion/pipeline_latent_diffusion.py index 17a15aca18dd..a348d9c08888 100644 --- a/src/diffusers/pipelines/latent_diffusion/pipeline_latent_diffusion.py +++ b/src/diffusers/pipelines/latent_diffusion/pipeline_latent_diffusion.py @@ -6,7 +6,6 @@ import torch.nn as nn import torch.utils.checkpoint -from tqdm.auto import tqdm from transformers.activations import ACT2FN from transformers.configuration_utils import PretrainedConfig from transformers.modeling_outputs import BaseModelOutput @@ -83,7 +82,7 @@ def __call__( if accepts_eta: extra_kwargs["eta"] = eta - for t in tqdm(self.scheduler.timesteps): + for t in self.progress_bar(self.scheduler.timesteps): if guidance_scale == 1.0: # guidance_scale of 1 means no guidance latents_input = latents diff --git a/src/diffusers/pipelines/latent_diffusion_uncond/pipeline_latent_diffusion_uncond.py b/src/diffusers/pipelines/latent_diffusion_uncond/pipeline_latent_diffusion_uncond.py index bdff4fc9486c..ed9bd09c2c13 100644 --- a/src/diffusers/pipelines/latent_diffusion_uncond/pipeline_latent_diffusion_uncond.py +++ b/src/diffusers/pipelines/latent_diffusion_uncond/pipeline_latent_diffusion_uncond.py @@ -3,8 +3,6 @@ import torch -from tqdm.auto import tqdm - from ...pipeline_utils import DiffusionPipeline @@ -45,7 +43,7 @@ def __call__(self, batch_size=1, generator=None, eta=0.0, num_inference_steps=50 if accepts_eta: extra_kwargs["eta"] = eta - for t in tqdm(self.scheduler.timesteps): + for t in self.progress_bar(self.scheduler.timesteps): # predict the noise residual noise_prediction = self.unet(latents, t)["sample"] # compute the previous noisy sample x_t -> x_t-1 diff --git a/src/diffusers/pipelines/pndm/pipeline_pndm.py b/src/diffusers/pipelines/pndm/pipeline_pndm.py index bc0f75648a10..32ddbd8c1711 100644 --- a/src/diffusers/pipelines/pndm/pipeline_pndm.py +++ b/src/diffusers/pipelines/pndm/pipeline_pndm.py @@ -18,8 +18,6 @@ import torch -from tqdm.auto import tqdm - from ...pipeline_utils import DiffusionPipeline @@ -54,7 +52,7 @@ def __call__(self, batch_size=1, generator=None, num_inference_steps=50, output_ image = image.to(self.device) self.scheduler.set_timesteps(num_inference_steps) - for t in tqdm(self.scheduler.timesteps): + for t in self.progress_bar(self.scheduler.timesteps): model_output = self.unet(image, t)["sample"] image = self.scheduler.step(model_output, t, image)["prev_sample"] diff --git a/src/diffusers/pipelines/stable_diffusion/pipeline_stable_diffusion.py b/src/diffusers/pipelines/stable_diffusion/pipeline_stable_diffusion.py index 550513b5c943..556bd8d0face 100644 --- a/src/diffusers/pipelines/stable_diffusion/pipeline_stable_diffusion.py +++ b/src/diffusers/pipelines/stable_diffusion/pipeline_stable_diffusion.py @@ -4,7 +4,6 @@ import torch -from tqdm.auto import tqdm from transformers import CLIPFeatureExtractor, CLIPTextModel, CLIPTokenizer from ...models import AutoencoderKL, UNet2DConditionModel @@ -126,7 +125,7 @@ def __call__( if accepts_eta: extra_step_kwargs["eta"] = eta - for i, t in tqdm(enumerate(self.scheduler.timesteps)): + for i, t in enumerate(self.progress_bar(self.scheduler.timesteps)): # expand the latents if we are doing classifier free guidance latent_model_input = torch.cat([latents] * 2) if do_classifier_free_guidance else latents if isinstance(self.scheduler, LMSDiscreteScheduler): diff --git a/src/diffusers/pipelines/stochatic_karras_ve/pipeline_stochastic_karras_ve.py b/src/diffusers/pipelines/stochatic_karras_ve/pipeline_stochastic_karras_ve.py index ebf95e666390..b1898488c8f1 100644 --- a/src/diffusers/pipelines/stochatic_karras_ve/pipeline_stochastic_karras_ve.py +++ b/src/diffusers/pipelines/stochatic_karras_ve/pipeline_stochastic_karras_ve.py @@ -53,7 +53,7 @@ def __call__(self, batch_size=1, num_inference_steps=50, generator=None, output_ self.scheduler.set_timesteps(num_inference_steps) - for t in tqdm(self.scheduler.timesteps): + for t in self.progress_bar(self.scheduler.timesteps): # here sigma_t == t_i from the paper sigma = self.scheduler.schedule[t] sigma_prev = self.scheduler.schedule[t - 1] if t > 0 else 0 From 3aa44e8e86d9d27cc4ff70ff4294a21e5b1f326c Mon Sep 17 00:00:00 2001 From: hysts Date: Wed, 24 Aug 2022 20:45:29 +0900 Subject: [PATCH 2/8] Make any tqdm configs available --- src/diffusers/pipeline_utils.py | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/src/diffusers/pipeline_utils.py b/src/diffusers/pipeline_utils.py index 1b65490776b7..e3b28a7706b6 100644 --- a/src/diffusers/pipeline_utils.py +++ b/src/diffusers/pipeline_utils.py @@ -60,7 +60,7 @@ class DiffusionPipeline(ConfigMixin): def __init__(self): super().__init__() - self._is_progress_bar_enabled = True + self._progress_bar_config = dict() def register_modules(self, **kwargs): # import it here to avoid circular import @@ -273,13 +273,7 @@ def numpy_to_pil(images): return pil_images def progress_bar(self, iterable): - if self._is_progress_bar_enabled: - return tqdm(iterable) - else: - return iterable - - def enable_progress_bar(self): - self._is_progress_bar_enabled = True + return tqdm(iterable, **self._progress_bar_config) - def disable_progress_bar(self): - self._is_progress_bar_enabled = False + def set_progress_bar_config(self, **kwargs): + self._progress_bar_config = kwargs From 72f180d3044bfd262bc2da5940192a15fa0cbdba Mon Sep 17 00:00:00 2001 From: Patrick von Platen Date: Tue, 30 Aug 2022 11:15:52 +0200 Subject: [PATCH 3/8] remove init --- src/diffusers/pipeline_utils.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/diffusers/pipeline_utils.py b/src/diffusers/pipeline_utils.py index e3b28a7706b6..14df7d3e703f 100644 --- a/src/diffusers/pipeline_utils.py +++ b/src/diffusers/pipeline_utils.py @@ -58,10 +58,6 @@ class DiffusionPipeline(ConfigMixin): config_name = "model_index.json" - def __init__(self): - super().__init__() - self._progress_bar_config = dict() - def register_modules(self, **kwargs): # import it here to avoid circular import from diffusers import pipelines @@ -273,6 +269,9 @@ def numpy_to_pil(images): return pil_images def progress_bar(self, iterable): + if not hasattr(self, "_progress_bar_config"): + self._progress_bar_config = {} + return tqdm(iterable, **self._progress_bar_config) def set_progress_bar_config(self, **kwargs): From 71881d4231fe4a20d6989953bfd69dfa847521e0 Mon Sep 17 00:00:00 2001 From: Patrick von Platen Date: Tue, 30 Aug 2022 11:49:21 +0200 Subject: [PATCH 4/8] add some tests --- 1 | 437 ++++++++++++++++++++++++++++++++ src/diffusers/pipeline_utils.py | 4 + tests/test_pipelines.py | 63 +++++ 3 files changed, 504 insertions(+) create mode 100644 1 diff --git a/1 b/1 new file mode 100644 index 000000000000..c842a330b354 --- /dev/null +++ b/1 @@ -0,0 +1,437 @@ +# coding=utf-8 +# Copyright 2022 HuggingFace Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import tempfile +import unittest + +import numpy as np +import torch + +import PIL +from diffusers import ( + DDIMPipeline, + DDIMScheduler, + DDPMPipeline, + DDPMScheduler, + KarrasVePipeline, + KarrasVeScheduler, + LDMPipeline, + LDMTextToImagePipeline, + LMSDiscreteScheduler, + PNDMPipeline, + PNDMScheduler, + ScoreSdeVePipeline, + ScoreSdeVeScheduler, + StableDiffusionPipeline, + UNet2DModel, +) +from diffusers.pipeline_utils import DiffusionPipeline +from diffusers.testing_utils import slow, torch_device + + +torch.backends.cuda.matmul.allow_tf32 = False + + +class PipelineTesterMixin(unittest.TestCase): + def test_from_pretrained_save_pretrained(self): + # 1. Load models + model = UNet2DModel( + block_out_channels=(32, 64), + layers_per_block=2, + sample_size=32, + in_channels=3, + out_channels=3, + down_block_types=("DownBlock2D", "AttnDownBlock2D"), + up_block_types=("AttnUpBlock2D", "UpBlock2D"), + ) + schedular = DDPMScheduler(num_train_timesteps=10) + + ddpm = DDPMPipeline(model, schedular) + ddpm.to(torch_device) + + with tempfile.TemporaryDirectory() as tmpdirname: + ddpm.save_pretrained(tmpdirname) + new_ddpm = DDPMPipeline.from_pretrained(tmpdirname) + new_ddpm.to(torch_device) + + generator = torch.manual_seed(0) + + image = ddpm(generator=generator, output_type="numpy")["sample"] + generator = generator.manual_seed(0) + new_image = new_ddpm(generator=generator, output_type="numpy")["sample"] + + assert np.abs(image - new_image).sum() < 1e-5, "Models don't give the same forward pass" + + def test_progress_bar(self): + model = UNet2DModel( + block_out_channels=(32, 64), + layers_per_block=2, + sample_size=32, + in_channels=3, + out_channels=3, + down_block_types=("DownBlock2D", "AttnDownBlock2D"), + up_block_types=("AttnUpBlock2D", "UpBlock2D"), + ) + scheduler = DDPMScheduler(num_train_timesteps=10) + + ddpm = DDPMPipeline(model, scheduler).to(torch_device) + other_ddpm = DDPMPipeline(model, scheduler).to(torch_device) + + generator = torch.manual_seed(0) + _ = ddpm(generator=generator, output_type="numpy")["sample"] + generator = torch.manual_seed(0) + image = ddpm(generator=generator, output_type="numpy")["sample"] + + generator = torch.manual_seed(0) + other_ddpm.set_progress_bar_config(leave=False) + new_image = other_ddpm(generator=generator, output_type="numpy")["sample"] + + assert np.abs(image - new_image).sum() < 1e-5, "Models don't give the same forward pass" + + @slow + def test_from_pretrained_hub(self): + model_path = "google/ddpm-cifar10-32" + + scheduler = DDPMScheduler(num_train_timesteps=10) + + ddpm = DDPMPipeline.from_pretrained(model_path, scheduler=scheduler) + ddpm.to(torch_device) + ddpm_from_hub = DiffusionPipeline.from_pretrained(model_path, scheduler=scheduler) + ddpm_from_hub.to(torch_device) + + generator = torch.manual_seed(0) + + image = ddpm(generator=generator, output_type="numpy")["sample"] + generator = generator.manual_seed(0) + new_image = ddpm_from_hub(generator=generator, output_type="numpy")["sample"] + + assert np.abs(image - new_image).sum() < 1e-5, "Models don't give the same forward pass" + + @slow + def test_from_pretrained_hub_pass_model(self): + model_path = "google/ddpm-cifar10-32" + + scheduler = DDPMScheduler(num_train_timesteps=10) + + # pass unet into DiffusionPipeline + unet = UNet2DModel.from_pretrained(model_path) + ddpm_from_hub_custom_model = DiffusionPipeline.from_pretrained(model_path, unet=unet, scheduler=scheduler) + ddpm_from_hub_custom_model.to(torch_device) + + ddpm_from_hub = DiffusionPipeline.from_pretrained(model_path, scheduler=scheduler) + ddpm_from_hub.to(torch_device) + + generator = torch.manual_seed(0) + + image = ddpm_from_hub_custom_model(generator=generator, output_type="numpy")["sample"] + generator = generator.manual_seed(0) + new_image = ddpm_from_hub(generator=generator, output_type="numpy")["sample"] + + assert np.abs(image - new_image).sum() < 1e-5, "Models don't give the same forward pass" + + @slow + def test_output_format(self): + model_path = "google/ddpm-cifar10-32" + + pipe = DDIMPipeline.from_pretrained(model_path) + pipe.to(torch_device) + + generator = torch.manual_seed(0) + images = pipe(generator=generator, output_type="numpy")["sample"] + assert images.shape == (1, 32, 32, 3) + assert isinstance(images, np.ndarray) + + images = pipe(generator=generator, output_type="pil")["sample"] + assert isinstance(images, list) + assert len(images) == 1 + assert isinstance(images[0], PIL.Image.Image) + + # use PIL by default + images = pipe(generator=generator)["sample"] + assert isinstance(images, list) + assert isinstance(images[0], PIL.Image.Image) + + @slow + def test_ddpm_cifar10(self): + model_id = "google/ddpm-cifar10-32" + + unet = UNet2DModel.from_pretrained(model_id) + scheduler = DDPMScheduler.from_config(model_id) + scheduler = scheduler.set_format("pt") + + ddpm = DDPMPipeline(unet=unet, scheduler=scheduler) + ddpm.to(torch_device) + + generator = torch.manual_seed(0) + image = ddpm(generator=generator, output_type="numpy")["sample"] + + image_slice = image[0, -3:, -3:, -1] + + assert image.shape == (1, 32, 32, 3) + expected_slice = np.array([0.41995, 0.35885, 0.19385, 0.38475, 0.3382, 0.2647, 0.41545, 0.3582, 0.33845]) + assert np.abs(image_slice.flatten() - expected_slice).max() < 1e-2 + + @slow + def test_ddim_lsun(self): + model_id = "google/ddpm-ema-bedroom-256" + + unet = UNet2DModel.from_pretrained(model_id) + scheduler = DDIMScheduler.from_config(model_id) + + ddpm = DDIMPipeline(unet=unet, scheduler=scheduler) + ddpm.to(torch_device) + + generator = torch.manual_seed(0) + image = ddpm(generator=generator, output_type="numpy")["sample"] + + image_slice = image[0, -3:, -3:, -1] + + assert image.shape == (1, 256, 256, 3) + expected_slice = np.array([0.00605, 0.0201, 0.0344, 0.00235, 0.00185, 0.00025, 0.00215, 0.0, 0.00685]) + assert np.abs(image_slice.flatten() - expected_slice).max() < 1e-2 + + @slow + def test_ddim_cifar10(self): + model_id = "google/ddpm-cifar10-32" + + unet = UNet2DModel.from_pretrained(model_id) + scheduler = DDIMScheduler(tensor_format="pt") + + ddim = DDIMPipeline(unet=unet, scheduler=scheduler) + ddim.to(torch_device) + + generator = torch.manual_seed(0) + image = ddim(generator=generator, eta=0.0, output_type="numpy")["sample"] + + image_slice = image[0, -3:, -3:, -1] + + assert image.shape == (1, 32, 32, 3) + expected_slice = np.array([0.17235, 0.16175, 0.16005, 0.16255, 0.1497, 0.1513, 0.15045, 0.1442, 0.1453]) + assert np.abs(image_slice.flatten() - expected_slice).max() < 1e-2 + + @slow + def test_pndm_cifar10(self): + model_id = "google/ddpm-cifar10-32" + + unet = UNet2DModel.from_pretrained(model_id) + scheduler = PNDMScheduler(tensor_format="pt") + + pndm = PNDMPipeline(unet=unet, scheduler=scheduler) + pndm.to(torch_device) + generator = torch.manual_seed(0) + image = pndm(generator=generator, output_type="numpy")["sample"] + + image_slice = image[0, -3:, -3:, -1] + + assert image.shape == (1, 32, 32, 3) + expected_slice = np.array([0.1564, 0.14645, 0.1406, 0.14715, 0.12425, 0.14045, 0.13115, 0.12175, 0.125]) + assert np.abs(image_slice.flatten() - expected_slice).max() < 1e-2 + + @slow + def test_ldm_text2img(self): + ldm = LDMTextToImagePipeline.from_pretrained("CompVis/ldm-text2im-large-256") + ldm.to(torch_device) + + prompt = "A painting of a squirrel eating a burger" + generator = torch.manual_seed(0) + image = ldm([prompt], generator=generator, guidance_scale=6.0, num_inference_steps=20, output_type="numpy")[ + "sample" + ] + + image_slice = image[0, -3:, -3:, -1] + + assert image.shape == (1, 256, 256, 3) + expected_slice = np.array([0.9256, 0.9340, 0.8933, 0.9361, 0.9113, 0.8727, 0.9122, 0.8745, 0.8099]) + assert np.abs(image_slice.flatten() - expected_slice).max() < 1e-2 + + @slow + def test_ldm_text2img_fast(self): + ldm = LDMTextToImagePipeline.from_pretrained("CompVis/ldm-text2im-large-256") + ldm.to(torch_device) + + prompt = "A painting of a squirrel eating a burger" + generator = torch.manual_seed(0) + image = ldm(prompt, generator=generator, num_inference_steps=1, output_type="numpy")["sample"] + + image_slice = image[0, -3:, -3:, -1] + + assert image.shape == (1, 256, 256, 3) + expected_slice = np.array([0.3163, 0.8670, 0.6465, 0.1865, 0.6291, 0.5139, 0.2824, 0.3723, 0.4344]) + assert np.abs(image_slice.flatten() - expected_slice).max() < 1e-2 + + @slow + @unittest.skipIf(torch_device == "cpu", "Stable diffusion is supposed to run on GPU") + def test_stable_diffusion(self): + # make sure here that pndm scheduler skips prk + sd_pipe = StableDiffusionPipeline.from_pretrained("CompVis/stable-diffusion-v1-1").to(torch_device) + + prompt = "A painting of a squirrel eating a burger" + generator = torch.Generator(device=torch_device).manual_seed(0) + with torch.autocast("cuda"): + output = sd_pipe( + [prompt], generator=generator, guidance_scale=6.0, num_inference_steps=20, output_type="np" + ) + + image = output["sample"] + + image_slice = image[0, -3:, -3:, -1] + + assert image.shape == (1, 512, 512, 3) + expected_slice = np.array([0.8887, 0.915, 0.91, 0.894, 0.909, 0.912, 0.919, 0.925, 0.883]) + assert np.abs(image_slice.flatten() - expected_slice).max() < 1e-2 + + @slow + @unittest.skipIf(torch_device == "cpu", "Stable diffusion is supposed to run on GPU") + def test_stable_diffusion_fast_ddim(self): + sd_pipe = StableDiffusionPipeline.from_pretrained("CompVis/stable-diffusion-v1-1").to(torch_device) + + scheduler = DDIMScheduler( + beta_start=0.00085, + beta_end=0.012, + beta_schedule="scaled_linear", + clip_sample=False, + set_alpha_to_one=False, + ) + sd_pipe.scheduler = scheduler + + prompt = "A painting of a squirrel eating a burger" + generator = torch.Generator(device=torch_device).manual_seed(0) + + with torch.autocast("cuda"): + output = sd_pipe([prompt], generator=generator, num_inference_steps=2, output_type="numpy") + image = output["sample"] + + image_slice = image[0, -3:, -3:, -1] + + assert image.shape == (1, 512, 512, 3) + expected_slice = np.array([0.8354, 0.83, 0.866, 0.838, 0.8315, 0.867, 0.836, 0.8584, 0.869]) + assert np.abs(image_slice.flatten() - expected_slice).max() < 1e-3 + + @slow + def test_score_sde_ve_pipeline(self): + model_id = "google/ncsnpp-church-256" + model = UNet2DModel.from_pretrained(model_id) + + scheduler = ScoreSdeVeScheduler.from_config(model_id) + + sde_ve = ScoreSdeVePipeline(unet=model, scheduler=scheduler) + sde_ve.to(torch_device) + + torch.manual_seed(0) + image = sde_ve(num_inference_steps=300, output_type="numpy")["sample"] + + image_slice = image[0, -3:, -3:, -1] + + assert image.shape == (1, 256, 256, 3) + + expected_slice = np.array([0.64363, 0.5868, 0.3031, 0.2284, 0.7409, 0.3216, 0.25643, 0.6557, 0.2633]) + assert np.abs(image_slice.flatten() - expected_slice).max() < 1e-2 + + @slow + def test_ldm_uncond(self): + ldm = LDMPipeline.from_pretrained("CompVis/ldm-celebahq-256") + ldm.to(torch_device) + + generator = torch.manual_seed(0) + image = ldm(generator=generator, num_inference_steps=5, output_type="numpy")["sample"] + + image_slice = image[0, -3:, -3:, -1] + + assert image.shape == (1, 256, 256, 3) + expected_slice = np.array([0.4399, 0.44975, 0.46825, 0.474, 0.4359, 0.4581, 0.45095, 0.4341, 0.4447]) + assert np.abs(image_slice.flatten() - expected_slice).max() < 1e-2 + + @slow + def test_ddpm_ddim_equality(self): + model_id = "google/ddpm-cifar10-32" + + unet = UNet2DModel.from_pretrained(model_id) + ddpm_scheduler = DDPMScheduler(tensor_format="pt") + ddim_scheduler = DDIMScheduler(tensor_format="pt") + + ddpm = DDPMPipeline(unet=unet, scheduler=ddpm_scheduler) + ddpm.to(torch_device) + ddim = DDIMPipeline(unet=unet, scheduler=ddim_scheduler) + ddim.to(torch_device) + + generator = torch.manual_seed(0) + ddpm_image = ddpm(generator=generator, output_type="numpy")["sample"] + + generator = torch.manual_seed(0) + ddim_image = ddim(generator=generator, num_inference_steps=1000, eta=1.0, output_type="numpy")["sample"] + + # the values aren't exactly equal, but the images look the same visually + assert np.abs(ddpm_image - ddim_image).max() < 1e-1 + + @unittest.skip("(Anton) The test is failing for large batch sizes, needs investigation") + def test_ddpm_ddim_equality_batched(self): + model_id = "google/ddpm-cifar10-32" + + unet = UNet2DModel.from_pretrained(model_id) + ddpm_scheduler = DDPMScheduler(tensor_format="pt") + ddim_scheduler = DDIMScheduler(tensor_format="pt") + + ddpm = DDPMPipeline(unet=unet, scheduler=ddpm_scheduler) + ddpm.to(torch_device) + + ddim = DDIMPipeline(unet=unet, scheduler=ddim_scheduler) + ddim.to(torch_device) + + generator = torch.manual_seed(0) + ddpm_images = ddpm(batch_size=4, generator=generator, output_type="numpy")["sample"] + + generator = torch.manual_seed(0) + ddim_images = ddim(batch_size=4, generator=generator, num_inference_steps=1000, eta=1.0, output_type="numpy")[ + "sample" + ] + + # the values aren't exactly equal, but the images look the same visually + assert np.abs(ddpm_images - ddim_images).max() < 1e-1 + + @slow + def test_karras_ve_pipeline(self): + model_id = "google/ncsnpp-celebahq-256" + model = UNet2DModel.from_pretrained(model_id) + scheduler = KarrasVeScheduler(tensor_format="pt") + + pipe = KarrasVePipeline(unet=model, scheduler=scheduler) + pipe.to(torch_device) + + generator = torch.manual_seed(0) + image = pipe(num_inference_steps=20, generator=generator, output_type="numpy")["sample"] + + image_slice = image[0, -3:, -3:, -1] + assert image.shape == (1, 256, 256, 3) + expected_slice = np.array([0.26815, 0.1581, 0.2658, 0.23248, 0.1550, 0.2539, 0.1131, 0.1024, 0.0837]) + assert np.abs(image_slice.flatten() - expected_slice).max() < 1e-2 + + @slow + @unittest.skipIf(torch_device == "cpu", "Stable diffusion is supposed to run on GPU") + def test_lms_stable_diffusion_pipeline(self): + model_id = "CompVis/stable-diffusion-v1-1" + pipe = StableDiffusionPipeline.from_pretrained(model_id, use_auth_token=True).to(torch_device) + scheduler = LMSDiscreteScheduler.from_config(model_id, subfolder="scheduler", use_auth_token=True) + pipe.scheduler = scheduler + + prompt = "a photograph of an astronaut riding a horse" + generator = torch.Generator(device=torch_device).manual_seed(0) + image = pipe([prompt], generator=generator, guidance_scale=7.5, num_inference_steps=10, output_type="numpy")[ + "sample" + ] + + image_slice = image[0, -3:, -3:, -1] + assert image.shape == (1, 512, 512, 3) + expected_slice = np.array([0.9077, 0.9254, 0.9181, 0.9227, 0.9213, 0.9367, 0.9399, 0.9406, 0.9024]) + assert np.abs(image_slice.flatten() - expected_slice).max() < 1e-2 diff --git a/src/diffusers/pipeline_utils.py b/src/diffusers/pipeline_utils.py index 14df7d3e703f..214133bc5f17 100644 --- a/src/diffusers/pipeline_utils.py +++ b/src/diffusers/pipeline_utils.py @@ -271,6 +271,10 @@ def numpy_to_pil(images): def progress_bar(self, iterable): if not hasattr(self, "_progress_bar_config"): self._progress_bar_config = {} + elif not isinstance(self._progress_bar_config, dict): + raise ValueError( + f"`self._progress_bar_config` should be of type `dict`, but is {type(self._progress_bar_config)}." + ) return tqdm(iterable, **self._progress_bar_config) diff --git a/tests/test_pipelines.py b/tests/test_pipelines.py index 9b6e08966e03..25898e75188d 100644 --- a/tests/test_pipelines.py +++ b/tests/test_pipelines.py @@ -44,6 +44,44 @@ torch.backends.cuda.matmul.allow_tf32 = False +def test_progress_bar_leave(capsys): + model = UNet2DModel( + block_out_channels=(32, 64), + layers_per_block=2, + sample_size=32, + in_channels=3, + out_channels=3, + down_block_types=("DownBlock2D", "AttnDownBlock2D"), + up_block_types=("AttnUpBlock2D", "UpBlock2D"), + ) + scheduler = DDPMScheduler(num_train_timesteps=10) + + ddpm = DDPMPipeline(model, scheduler).to(torch_device) + ddpm.set_progress_bar_config(leave=True) + ddpm(output_type="numpy")["sample"] + captured = capsys.readouterr() + assert "10/10" in captured.err, "Progress bar has to be displayed" + + +def test_progress_bar_no_leave(capsys): + model = UNet2DModel( + block_out_channels=(32, 64), + layers_per_block=2, + sample_size=32, + in_channels=3, + out_channels=3, + down_block_types=("DownBlock2D", "AttnDownBlock2D"), + up_block_types=("AttnUpBlock2D", "UpBlock2D"), + ) + scheduler = DDPMScheduler(num_train_timesteps=10) + + ddpm = DDPMPipeline(model, scheduler).to(torch_device) + ddpm.set_progress_bar_config(leave=False) + ddpm(output_type="numpy")["sample"] + captured = capsys.readouterr() + assert "10/10" not in captured.err, "Progress bar should not be displayed" + + class PipelineTesterMixin(unittest.TestCase): def test_from_pretrained_save_pretrained(self): # 1. Load models @@ -74,6 +112,31 @@ def test_from_pretrained_save_pretrained(self): assert np.abs(image - new_image).sum() < 1e-5, "Models don't give the same forward pass" + # def test_progress_bar(capsys): + # model = UNet2DModel( + # block_out_channels=(32, 64), + # layers_per_block=2, + # sample_size=32, + # in_channels=3, + # out_channels=3, + # down_block_types=("DownBlock2D", "AttnDownBlock2D"), + # up_block_types=("AttnUpBlock2D", "UpBlock2D"), + # ) + # scheduler = DDPMScheduler(num_train_timesteps=10) + # + # ddpm = DDPMPipeline(model, scheduler).to(torch_device) + # + # image = ddpm(output_type="numpy")["sample"] + # image = ddpm(output_type="numpy")["sample"] + # captured = capsys.readouterr() + # import ipdb; ipdb.set_trace() + # + # ddpm.set_progress_bar_config(leave=False) + # + # image = ddpm(output_type="numpy")["sample"] + # captured = capsys.readouterr() + # + @slow def test_from_pretrained_hub(self): model_path = "google/ddpm-cifar10-32" From 6988892627d66ba0f1af9c52ef421c9b7e5610b2 Mon Sep 17 00:00:00 2001 From: Patrick von Platen Date: Tue, 30 Aug 2022 11:49:50 +0200 Subject: [PATCH 5/8] remove file --- 1 | 437 -------------------------------------------------------------- 1 file changed, 437 deletions(-) delete mode 100644 1 diff --git a/1 b/1 deleted file mode 100644 index c842a330b354..000000000000 --- a/1 +++ /dev/null @@ -1,437 +0,0 @@ -# coding=utf-8 -# Copyright 2022 HuggingFace Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import tempfile -import unittest - -import numpy as np -import torch - -import PIL -from diffusers import ( - DDIMPipeline, - DDIMScheduler, - DDPMPipeline, - DDPMScheduler, - KarrasVePipeline, - KarrasVeScheduler, - LDMPipeline, - LDMTextToImagePipeline, - LMSDiscreteScheduler, - PNDMPipeline, - PNDMScheduler, - ScoreSdeVePipeline, - ScoreSdeVeScheduler, - StableDiffusionPipeline, - UNet2DModel, -) -from diffusers.pipeline_utils import DiffusionPipeline -from diffusers.testing_utils import slow, torch_device - - -torch.backends.cuda.matmul.allow_tf32 = False - - -class PipelineTesterMixin(unittest.TestCase): - def test_from_pretrained_save_pretrained(self): - # 1. Load models - model = UNet2DModel( - block_out_channels=(32, 64), - layers_per_block=2, - sample_size=32, - in_channels=3, - out_channels=3, - down_block_types=("DownBlock2D", "AttnDownBlock2D"), - up_block_types=("AttnUpBlock2D", "UpBlock2D"), - ) - schedular = DDPMScheduler(num_train_timesteps=10) - - ddpm = DDPMPipeline(model, schedular) - ddpm.to(torch_device) - - with tempfile.TemporaryDirectory() as tmpdirname: - ddpm.save_pretrained(tmpdirname) - new_ddpm = DDPMPipeline.from_pretrained(tmpdirname) - new_ddpm.to(torch_device) - - generator = torch.manual_seed(0) - - image = ddpm(generator=generator, output_type="numpy")["sample"] - generator = generator.manual_seed(0) - new_image = new_ddpm(generator=generator, output_type="numpy")["sample"] - - assert np.abs(image - new_image).sum() < 1e-5, "Models don't give the same forward pass" - - def test_progress_bar(self): - model = UNet2DModel( - block_out_channels=(32, 64), - layers_per_block=2, - sample_size=32, - in_channels=3, - out_channels=3, - down_block_types=("DownBlock2D", "AttnDownBlock2D"), - up_block_types=("AttnUpBlock2D", "UpBlock2D"), - ) - scheduler = DDPMScheduler(num_train_timesteps=10) - - ddpm = DDPMPipeline(model, scheduler).to(torch_device) - other_ddpm = DDPMPipeline(model, scheduler).to(torch_device) - - generator = torch.manual_seed(0) - _ = ddpm(generator=generator, output_type="numpy")["sample"] - generator = torch.manual_seed(0) - image = ddpm(generator=generator, output_type="numpy")["sample"] - - generator = torch.manual_seed(0) - other_ddpm.set_progress_bar_config(leave=False) - new_image = other_ddpm(generator=generator, output_type="numpy")["sample"] - - assert np.abs(image - new_image).sum() < 1e-5, "Models don't give the same forward pass" - - @slow - def test_from_pretrained_hub(self): - model_path = "google/ddpm-cifar10-32" - - scheduler = DDPMScheduler(num_train_timesteps=10) - - ddpm = DDPMPipeline.from_pretrained(model_path, scheduler=scheduler) - ddpm.to(torch_device) - ddpm_from_hub = DiffusionPipeline.from_pretrained(model_path, scheduler=scheduler) - ddpm_from_hub.to(torch_device) - - generator = torch.manual_seed(0) - - image = ddpm(generator=generator, output_type="numpy")["sample"] - generator = generator.manual_seed(0) - new_image = ddpm_from_hub(generator=generator, output_type="numpy")["sample"] - - assert np.abs(image - new_image).sum() < 1e-5, "Models don't give the same forward pass" - - @slow - def test_from_pretrained_hub_pass_model(self): - model_path = "google/ddpm-cifar10-32" - - scheduler = DDPMScheduler(num_train_timesteps=10) - - # pass unet into DiffusionPipeline - unet = UNet2DModel.from_pretrained(model_path) - ddpm_from_hub_custom_model = DiffusionPipeline.from_pretrained(model_path, unet=unet, scheduler=scheduler) - ddpm_from_hub_custom_model.to(torch_device) - - ddpm_from_hub = DiffusionPipeline.from_pretrained(model_path, scheduler=scheduler) - ddpm_from_hub.to(torch_device) - - generator = torch.manual_seed(0) - - image = ddpm_from_hub_custom_model(generator=generator, output_type="numpy")["sample"] - generator = generator.manual_seed(0) - new_image = ddpm_from_hub(generator=generator, output_type="numpy")["sample"] - - assert np.abs(image - new_image).sum() < 1e-5, "Models don't give the same forward pass" - - @slow - def test_output_format(self): - model_path = "google/ddpm-cifar10-32" - - pipe = DDIMPipeline.from_pretrained(model_path) - pipe.to(torch_device) - - generator = torch.manual_seed(0) - images = pipe(generator=generator, output_type="numpy")["sample"] - assert images.shape == (1, 32, 32, 3) - assert isinstance(images, np.ndarray) - - images = pipe(generator=generator, output_type="pil")["sample"] - assert isinstance(images, list) - assert len(images) == 1 - assert isinstance(images[0], PIL.Image.Image) - - # use PIL by default - images = pipe(generator=generator)["sample"] - assert isinstance(images, list) - assert isinstance(images[0], PIL.Image.Image) - - @slow - def test_ddpm_cifar10(self): - model_id = "google/ddpm-cifar10-32" - - unet = UNet2DModel.from_pretrained(model_id) - scheduler = DDPMScheduler.from_config(model_id) - scheduler = scheduler.set_format("pt") - - ddpm = DDPMPipeline(unet=unet, scheduler=scheduler) - ddpm.to(torch_device) - - generator = torch.manual_seed(0) - image = ddpm(generator=generator, output_type="numpy")["sample"] - - image_slice = image[0, -3:, -3:, -1] - - assert image.shape == (1, 32, 32, 3) - expected_slice = np.array([0.41995, 0.35885, 0.19385, 0.38475, 0.3382, 0.2647, 0.41545, 0.3582, 0.33845]) - assert np.abs(image_slice.flatten() - expected_slice).max() < 1e-2 - - @slow - def test_ddim_lsun(self): - model_id = "google/ddpm-ema-bedroom-256" - - unet = UNet2DModel.from_pretrained(model_id) - scheduler = DDIMScheduler.from_config(model_id) - - ddpm = DDIMPipeline(unet=unet, scheduler=scheduler) - ddpm.to(torch_device) - - generator = torch.manual_seed(0) - image = ddpm(generator=generator, output_type="numpy")["sample"] - - image_slice = image[0, -3:, -3:, -1] - - assert image.shape == (1, 256, 256, 3) - expected_slice = np.array([0.00605, 0.0201, 0.0344, 0.00235, 0.00185, 0.00025, 0.00215, 0.0, 0.00685]) - assert np.abs(image_slice.flatten() - expected_slice).max() < 1e-2 - - @slow - def test_ddim_cifar10(self): - model_id = "google/ddpm-cifar10-32" - - unet = UNet2DModel.from_pretrained(model_id) - scheduler = DDIMScheduler(tensor_format="pt") - - ddim = DDIMPipeline(unet=unet, scheduler=scheduler) - ddim.to(torch_device) - - generator = torch.manual_seed(0) - image = ddim(generator=generator, eta=0.0, output_type="numpy")["sample"] - - image_slice = image[0, -3:, -3:, -1] - - assert image.shape == (1, 32, 32, 3) - expected_slice = np.array([0.17235, 0.16175, 0.16005, 0.16255, 0.1497, 0.1513, 0.15045, 0.1442, 0.1453]) - assert np.abs(image_slice.flatten() - expected_slice).max() < 1e-2 - - @slow - def test_pndm_cifar10(self): - model_id = "google/ddpm-cifar10-32" - - unet = UNet2DModel.from_pretrained(model_id) - scheduler = PNDMScheduler(tensor_format="pt") - - pndm = PNDMPipeline(unet=unet, scheduler=scheduler) - pndm.to(torch_device) - generator = torch.manual_seed(0) - image = pndm(generator=generator, output_type="numpy")["sample"] - - image_slice = image[0, -3:, -3:, -1] - - assert image.shape == (1, 32, 32, 3) - expected_slice = np.array([0.1564, 0.14645, 0.1406, 0.14715, 0.12425, 0.14045, 0.13115, 0.12175, 0.125]) - assert np.abs(image_slice.flatten() - expected_slice).max() < 1e-2 - - @slow - def test_ldm_text2img(self): - ldm = LDMTextToImagePipeline.from_pretrained("CompVis/ldm-text2im-large-256") - ldm.to(torch_device) - - prompt = "A painting of a squirrel eating a burger" - generator = torch.manual_seed(0) - image = ldm([prompt], generator=generator, guidance_scale=6.0, num_inference_steps=20, output_type="numpy")[ - "sample" - ] - - image_slice = image[0, -3:, -3:, -1] - - assert image.shape == (1, 256, 256, 3) - expected_slice = np.array([0.9256, 0.9340, 0.8933, 0.9361, 0.9113, 0.8727, 0.9122, 0.8745, 0.8099]) - assert np.abs(image_slice.flatten() - expected_slice).max() < 1e-2 - - @slow - def test_ldm_text2img_fast(self): - ldm = LDMTextToImagePipeline.from_pretrained("CompVis/ldm-text2im-large-256") - ldm.to(torch_device) - - prompt = "A painting of a squirrel eating a burger" - generator = torch.manual_seed(0) - image = ldm(prompt, generator=generator, num_inference_steps=1, output_type="numpy")["sample"] - - image_slice = image[0, -3:, -3:, -1] - - assert image.shape == (1, 256, 256, 3) - expected_slice = np.array([0.3163, 0.8670, 0.6465, 0.1865, 0.6291, 0.5139, 0.2824, 0.3723, 0.4344]) - assert np.abs(image_slice.flatten() - expected_slice).max() < 1e-2 - - @slow - @unittest.skipIf(torch_device == "cpu", "Stable diffusion is supposed to run on GPU") - def test_stable_diffusion(self): - # make sure here that pndm scheduler skips prk - sd_pipe = StableDiffusionPipeline.from_pretrained("CompVis/stable-diffusion-v1-1").to(torch_device) - - prompt = "A painting of a squirrel eating a burger" - generator = torch.Generator(device=torch_device).manual_seed(0) - with torch.autocast("cuda"): - output = sd_pipe( - [prompt], generator=generator, guidance_scale=6.0, num_inference_steps=20, output_type="np" - ) - - image = output["sample"] - - image_slice = image[0, -3:, -3:, -1] - - assert image.shape == (1, 512, 512, 3) - expected_slice = np.array([0.8887, 0.915, 0.91, 0.894, 0.909, 0.912, 0.919, 0.925, 0.883]) - assert np.abs(image_slice.flatten() - expected_slice).max() < 1e-2 - - @slow - @unittest.skipIf(torch_device == "cpu", "Stable diffusion is supposed to run on GPU") - def test_stable_diffusion_fast_ddim(self): - sd_pipe = StableDiffusionPipeline.from_pretrained("CompVis/stable-diffusion-v1-1").to(torch_device) - - scheduler = DDIMScheduler( - beta_start=0.00085, - beta_end=0.012, - beta_schedule="scaled_linear", - clip_sample=False, - set_alpha_to_one=False, - ) - sd_pipe.scheduler = scheduler - - prompt = "A painting of a squirrel eating a burger" - generator = torch.Generator(device=torch_device).manual_seed(0) - - with torch.autocast("cuda"): - output = sd_pipe([prompt], generator=generator, num_inference_steps=2, output_type="numpy") - image = output["sample"] - - image_slice = image[0, -3:, -3:, -1] - - assert image.shape == (1, 512, 512, 3) - expected_slice = np.array([0.8354, 0.83, 0.866, 0.838, 0.8315, 0.867, 0.836, 0.8584, 0.869]) - assert np.abs(image_slice.flatten() - expected_slice).max() < 1e-3 - - @slow - def test_score_sde_ve_pipeline(self): - model_id = "google/ncsnpp-church-256" - model = UNet2DModel.from_pretrained(model_id) - - scheduler = ScoreSdeVeScheduler.from_config(model_id) - - sde_ve = ScoreSdeVePipeline(unet=model, scheduler=scheduler) - sde_ve.to(torch_device) - - torch.manual_seed(0) - image = sde_ve(num_inference_steps=300, output_type="numpy")["sample"] - - image_slice = image[0, -3:, -3:, -1] - - assert image.shape == (1, 256, 256, 3) - - expected_slice = np.array([0.64363, 0.5868, 0.3031, 0.2284, 0.7409, 0.3216, 0.25643, 0.6557, 0.2633]) - assert np.abs(image_slice.flatten() - expected_slice).max() < 1e-2 - - @slow - def test_ldm_uncond(self): - ldm = LDMPipeline.from_pretrained("CompVis/ldm-celebahq-256") - ldm.to(torch_device) - - generator = torch.manual_seed(0) - image = ldm(generator=generator, num_inference_steps=5, output_type="numpy")["sample"] - - image_slice = image[0, -3:, -3:, -1] - - assert image.shape == (1, 256, 256, 3) - expected_slice = np.array([0.4399, 0.44975, 0.46825, 0.474, 0.4359, 0.4581, 0.45095, 0.4341, 0.4447]) - assert np.abs(image_slice.flatten() - expected_slice).max() < 1e-2 - - @slow - def test_ddpm_ddim_equality(self): - model_id = "google/ddpm-cifar10-32" - - unet = UNet2DModel.from_pretrained(model_id) - ddpm_scheduler = DDPMScheduler(tensor_format="pt") - ddim_scheduler = DDIMScheduler(tensor_format="pt") - - ddpm = DDPMPipeline(unet=unet, scheduler=ddpm_scheduler) - ddpm.to(torch_device) - ddim = DDIMPipeline(unet=unet, scheduler=ddim_scheduler) - ddim.to(torch_device) - - generator = torch.manual_seed(0) - ddpm_image = ddpm(generator=generator, output_type="numpy")["sample"] - - generator = torch.manual_seed(0) - ddim_image = ddim(generator=generator, num_inference_steps=1000, eta=1.0, output_type="numpy")["sample"] - - # the values aren't exactly equal, but the images look the same visually - assert np.abs(ddpm_image - ddim_image).max() < 1e-1 - - @unittest.skip("(Anton) The test is failing for large batch sizes, needs investigation") - def test_ddpm_ddim_equality_batched(self): - model_id = "google/ddpm-cifar10-32" - - unet = UNet2DModel.from_pretrained(model_id) - ddpm_scheduler = DDPMScheduler(tensor_format="pt") - ddim_scheduler = DDIMScheduler(tensor_format="pt") - - ddpm = DDPMPipeline(unet=unet, scheduler=ddpm_scheduler) - ddpm.to(torch_device) - - ddim = DDIMPipeline(unet=unet, scheduler=ddim_scheduler) - ddim.to(torch_device) - - generator = torch.manual_seed(0) - ddpm_images = ddpm(batch_size=4, generator=generator, output_type="numpy")["sample"] - - generator = torch.manual_seed(0) - ddim_images = ddim(batch_size=4, generator=generator, num_inference_steps=1000, eta=1.0, output_type="numpy")[ - "sample" - ] - - # the values aren't exactly equal, but the images look the same visually - assert np.abs(ddpm_images - ddim_images).max() < 1e-1 - - @slow - def test_karras_ve_pipeline(self): - model_id = "google/ncsnpp-celebahq-256" - model = UNet2DModel.from_pretrained(model_id) - scheduler = KarrasVeScheduler(tensor_format="pt") - - pipe = KarrasVePipeline(unet=model, scheduler=scheduler) - pipe.to(torch_device) - - generator = torch.manual_seed(0) - image = pipe(num_inference_steps=20, generator=generator, output_type="numpy")["sample"] - - image_slice = image[0, -3:, -3:, -1] - assert image.shape == (1, 256, 256, 3) - expected_slice = np.array([0.26815, 0.1581, 0.2658, 0.23248, 0.1550, 0.2539, 0.1131, 0.1024, 0.0837]) - assert np.abs(image_slice.flatten() - expected_slice).max() < 1e-2 - - @slow - @unittest.skipIf(torch_device == "cpu", "Stable diffusion is supposed to run on GPU") - def test_lms_stable_diffusion_pipeline(self): - model_id = "CompVis/stable-diffusion-v1-1" - pipe = StableDiffusionPipeline.from_pretrained(model_id, use_auth_token=True).to(torch_device) - scheduler = LMSDiscreteScheduler.from_config(model_id, subfolder="scheduler", use_auth_token=True) - pipe.scheduler = scheduler - - prompt = "a photograph of an astronaut riding a horse" - generator = torch.Generator(device=torch_device).manual_seed(0) - image = pipe([prompt], generator=generator, guidance_scale=7.5, num_inference_steps=10, output_type="numpy")[ - "sample" - ] - - image_slice = image[0, -3:, -3:, -1] - assert image.shape == (1, 512, 512, 3) - expected_slice = np.array([0.9077, 0.9254, 0.9181, 0.9227, 0.9213, 0.9367, 0.9399, 0.9406, 0.9024]) - assert np.abs(image_slice.flatten() - expected_slice).max() < 1e-2 From f92a04a71b750fbe5417a07a358701fe9ae23d03 Mon Sep 17 00:00:00 2001 From: Patrick von Platen Date: Tue, 30 Aug 2022 11:51:19 +0200 Subject: [PATCH 6/8] finish --- .../score_sde_ve/pipeline_score_sde_ve.py | 3 +-- tests/test_pipelines.py | 25 ------------------- 2 files changed, 1 insertion(+), 27 deletions(-) diff --git a/src/diffusers/pipelines/score_sde_ve/pipeline_score_sde_ve.py b/src/diffusers/pipelines/score_sde_ve/pipeline_score_sde_ve.py index 884f1894f702..7d72ddf74625 100644 --- a/src/diffusers/pipelines/score_sde_ve/pipeline_score_sde_ve.py +++ b/src/diffusers/pipelines/score_sde_ve/pipeline_score_sde_ve.py @@ -4,7 +4,6 @@ import torch from diffusers import DiffusionPipeline -from tqdm.auto import tqdm class ScoreSdeVePipeline(DiffusionPipeline): @@ -37,7 +36,7 @@ def __call__(self, batch_size=1, num_inference_steps=2000, generator=None, outpu self.scheduler.set_timesteps(num_inference_steps) self.scheduler.set_sigmas(num_inference_steps) - for i, t in tqdm(enumerate(self.scheduler.timesteps)): + for i, t in enumerate(self.progress_bar(self.scheduler.timesteps)): sigma_t = self.scheduler.sigmas[i] * torch.ones(shape[0], device=self.device) # correction step diff --git a/tests/test_pipelines.py b/tests/test_pipelines.py index 25898e75188d..7f7ae281bc53 100644 --- a/tests/test_pipelines.py +++ b/tests/test_pipelines.py @@ -112,31 +112,6 @@ def test_from_pretrained_save_pretrained(self): assert np.abs(image - new_image).sum() < 1e-5, "Models don't give the same forward pass" - # def test_progress_bar(capsys): - # model = UNet2DModel( - # block_out_channels=(32, 64), - # layers_per_block=2, - # sample_size=32, - # in_channels=3, - # out_channels=3, - # down_block_types=("DownBlock2D", "AttnDownBlock2D"), - # up_block_types=("AttnUpBlock2D", "UpBlock2D"), - # ) - # scheduler = DDPMScheduler(num_train_timesteps=10) - # - # ddpm = DDPMPipeline(model, scheduler).to(torch_device) - # - # image = ddpm(output_type="numpy")["sample"] - # image = ddpm(output_type="numpy")["sample"] - # captured = capsys.readouterr() - # import ipdb; ipdb.set_trace() - # - # ddpm.set_progress_bar_config(leave=False) - # - # image = ddpm(output_type="numpy")["sample"] - # captured = capsys.readouterr() - # - @slow def test_from_pretrained_hub(self): model_path = "google/ddpm-cifar10-32" From caaf00af4d666702ebdc66a16904e858b4d19627 Mon Sep 17 00:00:00 2001 From: Patrick von Platen Date: Tue, 30 Aug 2022 09:56:22 +0000 Subject: [PATCH 7/8] make style --- .../stochatic_karras_ve/pipeline_stochastic_karras_ve.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/diffusers/pipelines/stochatic_karras_ve/pipeline_stochastic_karras_ve.py b/src/diffusers/pipelines/stochatic_karras_ve/pipeline_stochastic_karras_ve.py index b1898488c8f1..970272999c67 100644 --- a/src/diffusers/pipelines/stochatic_karras_ve/pipeline_stochastic_karras_ve.py +++ b/src/diffusers/pipelines/stochatic_karras_ve/pipeline_stochastic_karras_ve.py @@ -3,8 +3,6 @@ import torch -from tqdm.auto import tqdm - from ...models import UNet2DModel from ...pipeline_utils import DiffusionPipeline from ...schedulers import KarrasVeScheduler From 28311a9f3fb4b8d0b80e8985b2f060f46cdf4609 Mon Sep 17 00:00:00 2001 From: Patrick von Platen Date: Tue, 30 Aug 2022 10:06:55 +0000 Subject: [PATCH 8/8] improve progress bar test --- tests/test_pipelines.py | 21 +++------------------ 1 file changed, 3 insertions(+), 18 deletions(-) diff --git a/tests/test_pipelines.py b/tests/test_pipelines.py index 7f7ae281bc53..96d5995f05fd 100644 --- a/tests/test_pipelines.py +++ b/tests/test_pipelines.py @@ -44,7 +44,7 @@ torch.backends.cuda.matmul.allow_tf32 = False -def test_progress_bar_leave(capsys): +def test_progress_bar(capsys): model = UNet2DModel( block_out_channels=(32, 64), layers_per_block=2, @@ -57,29 +57,14 @@ def test_progress_bar_leave(capsys): scheduler = DDPMScheduler(num_train_timesteps=10) ddpm = DDPMPipeline(model, scheduler).to(torch_device) - ddpm.set_progress_bar_config(leave=True) ddpm(output_type="numpy")["sample"] captured = capsys.readouterr() assert "10/10" in captured.err, "Progress bar has to be displayed" - -def test_progress_bar_no_leave(capsys): - model = UNet2DModel( - block_out_channels=(32, 64), - layers_per_block=2, - sample_size=32, - in_channels=3, - out_channels=3, - down_block_types=("DownBlock2D", "AttnDownBlock2D"), - up_block_types=("AttnUpBlock2D", "UpBlock2D"), - ) - scheduler = DDPMScheduler(num_train_timesteps=10) - - ddpm = DDPMPipeline(model, scheduler).to(torch_device) - ddpm.set_progress_bar_config(leave=False) + ddpm.set_progress_bar_config(disable=True) ddpm(output_type="numpy")["sample"] captured = capsys.readouterr() - assert "10/10" not in captured.err, "Progress bar should not be displayed" + assert captured.err == "", "Progress bar should be disabled" class PipelineTesterMixin(unittest.TestCase):