Path: blob/main/tests/pipelines/stable_diffusion/test_onnx_stable_diffusion_upscale.py
1448 views
# coding=utf-81# Copyright 2022 HuggingFace Inc.2#3# Licensed under the Apache License, Version 2.0 (the "License");4# you may not use this file except in compliance with the License.5# You may obtain a copy of the License at6#7# http://www.apache.org/licenses/LICENSE-2.08#9# Unless required by applicable law or agreed to in writing, software10# distributed under the License is distributed on an "AS IS" BASIS,11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.12# See the License for the specific language governing permissions and13# limitations under the License.1415import random16import unittest1718import numpy as np19import torch2021from diffusers import (22DPMSolverMultistepScheduler,23EulerAncestralDiscreteScheduler,24EulerDiscreteScheduler,25LMSDiscreteScheduler,26OnnxStableDiffusionUpscalePipeline,27PNDMScheduler,28)29from diffusers.utils import floats_tensor30from diffusers.utils.testing_utils import (31is_onnx_available,32load_image,33nightly,34require_onnxruntime,35require_torch_gpu,36)3738from ...test_pipelines_onnx_common import OnnxPipelineTesterMixin394041if is_onnx_available():42import onnxruntime as ort434445class OnnxStableDiffusionUpscalePipelineFastTests(OnnxPipelineTesterMixin, unittest.TestCase):46# TODO: is there an appropriate internal test set?47hub_checkpoint = "ssube/stable-diffusion-x4-upscaler-onnx"4849def get_dummy_inputs(self, seed=0):50image = floats_tensor((1, 3, 128, 128), rng=random.Random(seed))51generator = torch.manual_seed(seed)52inputs = {53"prompt": "A painting of a squirrel eating a burger",54"image": image,55"generator": generator,56"num_inference_steps": 3,57"guidance_scale": 7.5,58"output_type": "numpy",59}60return inputs6162def test_pipeline_default_ddpm(self):63pipe = OnnxStableDiffusionUpscalePipeline.from_pretrained(self.hub_checkpoint, provider="CPUExecutionProvider")64pipe.set_progress_bar_config(disable=None)6566inputs = self.get_dummy_inputs()67image = pipe(**inputs).images68image_slice = image[0, -3:, -3:, -1].flatten()6970# started as 128, should now be 51271assert image.shape == (1, 512, 512, 3)72expected_slice = np.array(73[0.6974782, 0.68902093, 0.70135885, 0.7583618, 0.7804545, 0.7854912, 0.78667426, 0.78743863, 0.78070223]74)75assert np.abs(image_slice - expected_slice).max() < 1e-17677def test_pipeline_pndm(self):78pipe = OnnxStableDiffusionUpscalePipeline.from_pretrained(self.hub_checkpoint, provider="CPUExecutionProvider")79pipe.scheduler = PNDMScheduler.from_config(pipe.scheduler.config, skip_prk_steps=True)80pipe.set_progress_bar_config(disable=None)8182inputs = self.get_dummy_inputs()83image = pipe(**inputs).images84image_slice = image[0, -3:, -3:, -1]8586assert image.shape == (1, 512, 512, 3)87expected_slice = np.array(88[0.6898892, 0.59240556, 0.52499527, 0.58866215, 0.52258235, 0.52572715, 0.62414473, 0.6174387, 0.6214964]89)90assert np.abs(image_slice.flatten() - expected_slice).max() < 1e-19192def test_pipeline_dpm_multistep(self):93pipe = OnnxStableDiffusionUpscalePipeline.from_pretrained(self.hub_checkpoint, provider="CPUExecutionProvider")94pipe.scheduler = DPMSolverMultistepScheduler.from_config(pipe.scheduler.config)95pipe.set_progress_bar_config(disable=None)9697inputs = self.get_dummy_inputs()98image = pipe(**inputs).images99image_slice = image[0, -3:, -3:, -1]100101assert image.shape == (1, 512, 512, 3)102expected_slice = np.array(103[0.7659278, 0.76437664, 0.75579107, 0.7691116, 0.77666986, 0.7727672, 0.7758664, 0.7812226, 0.76942515]104)105106assert np.abs(image_slice.flatten() - expected_slice).max() < 1e-1107108def test_pipeline_euler(self):109pipe = OnnxStableDiffusionUpscalePipeline.from_pretrained(self.hub_checkpoint, provider="CPUExecutionProvider")110pipe.scheduler = EulerDiscreteScheduler.from_config(pipe.scheduler.config)111pipe.set_progress_bar_config(disable=None)112113inputs = self.get_dummy_inputs()114image = pipe(**inputs).images115image_slice = image[0, -3:, -3:, -1]116117assert image.shape == (1, 512, 512, 3)118expected_slice = np.array(119[0.6974782, 0.68902093, 0.70135885, 0.7583618, 0.7804545, 0.7854912, 0.78667426, 0.78743863, 0.78070223]120)121assert np.abs(image_slice.flatten() - expected_slice).max() < 1e-1122123def test_pipeline_euler_ancestral(self):124pipe = OnnxStableDiffusionUpscalePipeline.from_pretrained(self.hub_checkpoint, provider="CPUExecutionProvider")125pipe.scheduler = EulerAncestralDiscreteScheduler.from_config(pipe.scheduler.config)126pipe.set_progress_bar_config(disable=None)127128inputs = self.get_dummy_inputs()129image = pipe(**inputs).images130image_slice = image[0, -3:, -3:, -1]131132assert image.shape == (1, 512, 512, 3)133expected_slice = np.array(134[0.77424496, 0.773601, 0.7645288, 0.7769598, 0.7772739, 0.7738688, 0.78187233, 0.77879584, 0.767043]135)136137assert np.abs(image_slice.flatten() - expected_slice).max() < 1e-1138139140@nightly141@require_onnxruntime142@require_torch_gpu143class OnnxStableDiffusionUpscalePipelineIntegrationTests(unittest.TestCase):144@property145def gpu_provider(self):146return (147"CUDAExecutionProvider",148{149"gpu_mem_limit": "15000000000", # 15GB150"arena_extend_strategy": "kSameAsRequested",151},152)153154@property155def gpu_options(self):156options = ort.SessionOptions()157options.enable_mem_pattern = False158return options159160def test_inference_default_ddpm(self):161init_image = load_image(162"https://huggingface.co/datasets/hf-internal-testing/diffusers-images/resolve/main"163"/img2img/sketch-mountains-input.jpg"164)165init_image = init_image.resize((128, 128))166# using the PNDM scheduler by default167pipe = OnnxStableDiffusionUpscalePipeline.from_pretrained(168"ssube/stable-diffusion-x4-upscaler-onnx",169provider=self.gpu_provider,170sess_options=self.gpu_options,171)172pipe.set_progress_bar_config(disable=None)173174prompt = "A fantasy landscape, trending on artstation"175176generator = torch.manual_seed(0)177output = pipe(178prompt=prompt,179image=init_image,180guidance_scale=7.5,181num_inference_steps=10,182generator=generator,183output_type="np",184)185images = output.images186image_slice = images[0, 255:258, 383:386, -1]187188assert images.shape == (1, 512, 512, 3)189expected_slice = np.array([0.4883, 0.4947, 0.4980, 0.4975, 0.4982, 0.4980, 0.5000, 0.5006, 0.4972])190# TODO: lower the tolerance after finding the cause of onnxruntime reproducibility issues191192assert np.abs(image_slice.flatten() - expected_slice).max() < 2e-2193194def test_inference_k_lms(self):195init_image = load_image(196"https://huggingface.co/datasets/hf-internal-testing/diffusers-images/resolve/main"197"/img2img/sketch-mountains-input.jpg"198)199init_image = init_image.resize((128, 128))200lms_scheduler = LMSDiscreteScheduler.from_pretrained(201"ssube/stable-diffusion-x4-upscaler-onnx", subfolder="scheduler"202)203pipe = OnnxStableDiffusionUpscalePipeline.from_pretrained(204"ssube/stable-diffusion-x4-upscaler-onnx",205scheduler=lms_scheduler,206provider=self.gpu_provider,207sess_options=self.gpu_options,208)209pipe.set_progress_bar_config(disable=None)210211prompt = "A fantasy landscape, trending on artstation"212213generator = torch.manual_seed(0)214output = pipe(215prompt=prompt,216image=init_image,217guidance_scale=7.5,218num_inference_steps=20,219generator=generator,220output_type="np",221)222images = output.images223image_slice = images[0, 255:258, 383:386, -1]224225assert images.shape == (1, 512, 512, 3)226expected_slice = np.array(227[0.50173753, 0.50223356, 0.502039, 0.50233036, 0.5023725, 0.5022601, 0.5018758, 0.50234085, 0.50241566]228)229# TODO: lower the tolerance after finding the cause of onnxruntime reproducibility issues230231assert np.abs(image_slice.flatten() - expected_slice).max() < 2e-2232233234