patrickvonplaten commited on
Commit
c74cf55
1 Parent(s): 6d5e373

Create new file

Browse files
Files changed (1) hide show
  1. pipeline.py +102 -0
pipeline.py ADDED
@@ -0,0 +1,102 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2022 The HuggingFace Team. All rights reserved.
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 at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # 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 and
13
+
14
+ # limitations under the License.
15
+
16
+
17
+ from typing import Optional, Tuple, Union
18
+
19
+ import torch
20
+
21
+ from diffusers.pipeline_utils import DiffusionPipeline, ImagePipelineOutput
22
+
23
+
24
+ class DDIMPipeline(DiffusionPipeline):
25
+ r"""
26
+ This model inherits from [`DiffusionPipeline`]. Check the superclass documentation for the generic methods the
27
+ library implements for all the pipelines (such as downloading or saving, running on a particular device, etc.)
28
+
29
+ Parameters:
30
+ unet ([`UNet2DModel`]): U-Net architecture to denoise the encoded image.
31
+ scheduler ([`SchedulerMixin`]):
32
+ A scheduler to be used in combination with `unet` to denoise the encoded image. Can be one of
33
+ [`DDPMScheduler`], or [`DDIMScheduler`].
34
+ """
35
+
36
+ def __init__(self, unet, scheduler):
37
+ super().__init__()
38
+ self.register_modules(unet=unet, scheduler=scheduler)
39
+
40
+ @torch.no_grad()
41
+ def __call__(
42
+ self,
43
+ batch_size: int = 1,
44
+ generator: Optional[torch.Generator] = None,
45
+ eta: float = 0.0,
46
+ num_inference_steps: int = 50,
47
+ output_type: Optional[str] = "pil",
48
+ return_dict: bool = True,
49
+ **kwargs,
50
+ ) -> Union[ImagePipelineOutput, Tuple]:
51
+ r"""
52
+ Args:
53
+ batch_size (`int`, *optional*, defaults to 1):
54
+ The number of images to generate.
55
+ generator (`torch.Generator`, *optional*):
56
+ A [torch generator](https://pytorch.org/docs/stable/generated/torch.Generator.html) to make generation
57
+ deterministic.
58
+ eta (`float`, *optional*, defaults to 0.0):
59
+ The eta parameter which controls the scale of the variance (0 is DDIM and 1 is one type of DDPM).
60
+ num_inference_steps (`int`, *optional*, defaults to 50):
61
+ The number of denoising steps. More denoising steps usually lead to a higher quality image at the
62
+ expense of slower inference.
63
+ output_type (`str`, *optional*, defaults to `"pil"`):
64
+ The output format of the generate image. Choose between
65
+ [PIL](https://pillow.readthedocs.io/en/stable/): `PIL.Image.Image` or `np.array`.
66
+ return_dict (`bool`, *optional*, defaults to `True`):
67
+ Whether or not to return a [`~pipeline_utils.ImagePipelineOutput`] instead of a plain tuple.
68
+
69
+ Returns:
70
+ [`~pipeline_utils.ImagePipelineOutput`] or `tuple`: [`~pipelines.utils.ImagePipelineOutput`] if
71
+ `return_dict` is True, otherwise a `tuple. When returning a tuple, the first element is a list with the
72
+ generated images.
73
+ """
74
+
75
+ # Sample gaussian noise to begin loop
76
+ image = torch.randn(
77
+ (batch_size, self.unet.in_channels, self.unet.sample_size, self.unet.sample_size),
78
+ generator=generator,
79
+ )
80
+ image = image.to(self.device)
81
+
82
+ # set step values
83
+ self.scheduler.set_timesteps(num_inference_steps)
84
+
85
+ for t in self.progress_bar(self.scheduler.timesteps):
86
+ # 1. predict noise model_output
87
+ model_output = self.unet(image, t).sample
88
+
89
+ # 2. predict previous mean of image x_t-1 and add variance depending on eta
90
+ # eta corresponds to η in paper and should be between [0, 1]
91
+ # do x_t -> x_t-1
92
+ image = self.scheduler.step(model_output, t, image, eta).prev_sample
93
+
94
+ image = (image / 2 + 0.5).clamp(0, 1)
95
+ image = image.cpu().permute(0, 2, 3, 1).numpy()
96
+ if output_type == "pil":
97
+ image = self.numpy_to_pil(image)
98
+
99
+ if not return_dict:
100
+ return (image,)
101
+
102
+ return ImagePipelineOutput(images=image)