3434 VQModel ,
3535)
3636from diffusers .utils import floats_tensor , load_image , nightly , slow , torch_device
37- from diffusers .utils .testing_utils import load_numpy , require_torch_gpu
37+ from diffusers .utils .testing_utils import load_numpy , preprocess_image , require_torch_gpu
3838
3939
4040torch .backends .cuda .matmul .allow_tf32 = False
@@ -217,6 +217,55 @@ def test_stable_diffusion_inpaint_legacy(self):
217217 assert np .abs (image_slice .flatten () - expected_slice ).max () < 1e-2
218218 assert np .abs (image_from_tuple_slice .flatten () - expected_slice ).max () < 1e-2
219219
220+ def test_stable_diffusion_inpaint_legacy_batched (self ):
221+ device = "cpu" # ensure determinism for the device-dependent torch.Generator
222+ unet = self .dummy_cond_unet
223+ scheduler = PNDMScheduler (skip_prk_steps = True )
224+ vae = self .dummy_vae
225+ bert = self .dummy_text_encoder
226+ tokenizer = CLIPTokenizer .from_pretrained ("hf-internal-testing/tiny-random-clip" )
227+
228+ image = self .dummy_image .cpu ().permute (0 , 2 , 3 , 1 )[0 ]
229+ init_image = Image .fromarray (np .uint8 (image )).convert ("RGB" )
230+ init_images_tens = preprocess_image (init_image , batch_size = 2 )
231+ init_masks_tens = init_images_tens + 4
232+
233+ # make sure here that pndm scheduler skips prk
234+ sd_pipe = StableDiffusionInpaintPipelineLegacy (
235+ unet = unet ,
236+ scheduler = scheduler ,
237+ vae = vae ,
238+ text_encoder = bert ,
239+ tokenizer = tokenizer ,
240+ safety_checker = None ,
241+ feature_extractor = self .dummy_extractor ,
242+ )
243+ sd_pipe = sd_pipe .to (device )
244+ sd_pipe .set_progress_bar_config (disable = None )
245+
246+ prompt = "A painting of a squirrel eating a burger"
247+ generator = torch .Generator (device = device ).manual_seed (0 )
248+ images = sd_pipe (
249+ [prompt ] * 2 ,
250+ generator = generator ,
251+ guidance_scale = 6.0 ,
252+ num_inference_steps = 2 ,
253+ output_type = "np" ,
254+ image = init_images_tens ,
255+ mask_image = init_masks_tens ,
256+ ).images
257+
258+ assert images .shape == (2 , 32 , 32 , 3 )
259+
260+ image_slice_0 = images [0 , - 3 :, - 3 :, - 1 ].flatten ()
261+ image_slice_1 = images [1 , - 3 :, - 3 :, - 1 ].flatten ()
262+
263+ expected_slice_0 = np .array ([0.4697 , 0.3770 , 0.4096 , 0.4653 , 0.4497 , 0.4183 , 0.3950 , 0.4668 , 0.4672 ])
264+ expected_slice_1 = np .array ([0.4105 , 0.4987 , 0.5771 , 0.4921 , 0.4237 , 0.5684 , 0.5496 , 0.4645 , 0.5272 ])
265+
266+ assert np .abs (expected_slice_0 - image_slice_0 ).max () < 1e-2
267+ assert np .abs (expected_slice_1 - image_slice_1 ).max () < 1e-2
268+
220269 def test_stable_diffusion_inpaint_legacy_negative_prompt (self ):
221270 device = "cpu" # ensure determinism for the device-dependent torch.Generator
222271 unet = self .dummy_cond_unet
@@ -349,7 +398,7 @@ def tearDown(self):
349398 gc .collect ()
350399 torch .cuda .empty_cache ()
351400
352- def get_inputs (self , device , generator_device = "cpu" , dtype = torch . float32 , seed = 0 ):
401+ def get_inputs (self , generator_device = "cpu" , seed = 0 ):
353402 generator = torch .Generator (device = generator_device ).manual_seed (seed )
354403 init_image = load_image (
355404 "https://huggingface.co/datasets/diffusers/test-arrays/resolve/main"
@@ -379,7 +428,7 @@ def test_stable_diffusion_inpaint_legacy_pndm(self):
379428 pipe .set_progress_bar_config (disable = None )
380429 pipe .enable_attention_slicing ()
381430
382- inputs = self .get_inputs (torch_device )
431+ inputs = self .get_inputs ()
383432 image = pipe (** inputs ).images
384433 image_slice = image [0 , 253 :256 , 253 :256 , - 1 ].flatten ()
385434
@@ -388,6 +437,40 @@ def test_stable_diffusion_inpaint_legacy_pndm(self):
388437
389438 assert np .abs (expected_slice - image_slice ).max () < 1e-4
390439
440+ def test_stable_diffusion_inpaint_legacy_batched (self ):
441+ pipe = StableDiffusionInpaintPipelineLegacy .from_pretrained (
442+ "CompVis/stable-diffusion-v1-4" , safety_checker = None
443+ )
444+ pipe .to (torch_device )
445+ pipe .set_progress_bar_config (disable = None )
446+ pipe .enable_attention_slicing ()
447+
448+ inputs = self .get_inputs ()
449+ inputs ["prompt" ] = [inputs ["prompt" ]] * 2
450+ inputs ["image" ] = preprocess_image (inputs ["image" ], batch_size = 2 )
451+
452+ mask = inputs ["mask_image" ].convert ("L" )
453+ mask = np .array (mask ).astype (np .float32 ) / 255.0
454+ mask = torch .from_numpy (1 - mask )
455+ masks = torch .vstack ([mask [None ][None ]] * 2 )
456+ inputs ["mask_image" ] = masks
457+
458+ image = pipe (** inputs ).images
459+ assert image .shape == (2 , 512 , 512 , 3 )
460+
461+ image_slice_0 = image [0 , 253 :256 , 253 :256 , - 1 ].flatten ()
462+ image_slice_1 = image [1 , 253 :256 , 253 :256 , - 1 ].flatten ()
463+
464+ expected_slice_0 = np .array (
465+ [0.52093095 , 0.4176447 , 0.32752383 , 0.6175223 , 0.50563973 , 0.36470804 , 0.65460044 , 0.5775188 , 0.44332123 ]
466+ )
467+ expected_slice_1 = np .array (
468+ [0.3592432 , 0.4233033 , 0.3914635 , 0.31014425 , 0.3702293 , 0.39412856 , 0.17526966 , 0.2642669 , 0.37480092 ]
469+ )
470+
471+ assert np .abs (expected_slice_0 - image_slice_0 ).max () < 1e-4
472+ assert np .abs (expected_slice_1 - image_slice_1 ).max () < 1e-4
473+
391474 def test_stable_diffusion_inpaint_legacy_k_lms (self ):
392475 pipe = StableDiffusionInpaintPipelineLegacy .from_pretrained (
393476 "CompVis/stable-diffusion-v1-4" , safety_checker = None
@@ -397,7 +480,7 @@ def test_stable_diffusion_inpaint_legacy_k_lms(self):
397480 pipe .set_progress_bar_config (disable = None )
398481 pipe .enable_attention_slicing ()
399482
400- inputs = self .get_inputs (torch_device )
483+ inputs = self .get_inputs ()
401484 image = pipe (** inputs ).images
402485 image_slice = image [0 , 253 :256 , 253 :256 , - 1 ].flatten ()
403486
@@ -437,7 +520,7 @@ def callback_fn(step: int, timestep: int, latents: torch.FloatTensor) -> None:
437520 pipe .set_progress_bar_config (disable = None )
438521 pipe .enable_attention_slicing ()
439522
440- inputs = self .get_inputs (torch_device , dtype = torch . float16 )
523+ inputs = self .get_inputs ()
441524 pipe (** inputs , callback = callback_fn , callback_steps = 1 )
442525 assert callback_fn .has_been_called
443526 assert number_of_steps == 2
0 commit comments