InvokeAI 2.2.4.5__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (169) hide show
  1. backend/__init__.py +0 -0
  2. backend/invoke_ai_web_server.py +1724 -0
  3. backend/modules/__init__.py +0 -0
  4. backend/modules/create_cmd_parser.py +55 -0
  5. backend/modules/get_canvas_generation_mode.py +117 -0
  6. backend/modules/parameters.py +71 -0
  7. backend/modules/parse_seed_weights.py +47 -0
  8. configs/INITIAL_MODELS.yaml +80 -0
  9. configs/models.yaml.example +29 -0
  10. configs/sd-concepts.txt +803 -0
  11. configs/stable-diffusion/v1-finetune.yaml +110 -0
  12. configs/stable-diffusion/v1-finetune_style.yaml +103 -0
  13. configs/stable-diffusion/v1-inference.yaml +79 -0
  14. configs/stable-diffusion/v1-inpainting-inference.yaml +79 -0
  15. configs/stable-diffusion/v1-m1-finetune.yaml +110 -0
  16. docs/assets/invoke-web-server-1.png +0 -0
  17. docs/assets/invoke_ai_banner.png +0 -0
  18. invokeai-2.2.4.5.data/data/assets/caution.png +0 -0
  19. invokeai-2.2.4.5.data/data/configs/INITIAL_MODELS.yaml +80 -0
  20. invokeai-2.2.4.5.data/data/configs/models.yaml.example +29 -0
  21. invokeai-2.2.4.5.data/data/configs/sd-concepts.txt +803 -0
  22. invokeai-2.2.4.5.data/data/configs/stable-diffusion/v1-finetune.yaml +110 -0
  23. invokeai-2.2.4.5.data/data/configs/stable-diffusion/v1-finetune_style.yaml +103 -0
  24. invokeai-2.2.4.5.data/data/configs/stable-diffusion/v1-inference.yaml +79 -0
  25. invokeai-2.2.4.5.data/data/configs/stable-diffusion/v1-inpainting-inference.yaml +79 -0
  26. invokeai-2.2.4.5.data/data/configs/stable-diffusion/v1-m1-finetune.yaml +110 -0
  27. invokeai-2.2.4.5.data/data/frontend/dist/assets/Inter-Bold.790c108b.ttf +0 -0
  28. invokeai-2.2.4.5.data/data/frontend/dist/assets/Inter.b9a8e5e2.ttf +0 -0
  29. invokeai-2.2.4.5.data/data/frontend/dist/assets/favicon.0d253ced.ico +0 -0
  30. invokeai-2.2.4.5.data/data/frontend/dist/assets/index-legacy-b741077f.js +48 -0
  31. invokeai-2.2.4.5.data/data/frontend/dist/assets/index.0dadf5d0.css +1 -0
  32. invokeai-2.2.4.5.data/data/frontend/dist/assets/index.21ff81eb.js +625 -0
  33. invokeai-2.2.4.5.data/data/frontend/dist/assets/logo.13003d72.png +0 -0
  34. invokeai-2.2.4.5.data/data/frontend/dist/assets/polyfills-legacy-dde3a68a.js +4 -0
  35. invokeai-2.2.4.5.data/data/frontend/dist/assets/polyfills.1ff60148.js +1 -0
  36. invokeai-2.2.4.5.data/data/frontend/dist/index.html +23 -0
  37. invokeai-2.2.4.5.data/data/scripts/configure_invokeai.py +797 -0
  38. invokeai-2.2.4.5.data/data/scripts/create_root.py +43 -0
  39. invokeai-2.2.4.5.data/data/scripts/dream.py +10 -0
  40. invokeai-2.2.4.5.data/data/scripts/images2prompt.py +30 -0
  41. invokeai-2.2.4.5.data/data/scripts/invoke.py +5 -0
  42. invokeai-2.2.4.5.data/data/scripts/legacy_api.py +681 -0
  43. invokeai-2.2.4.5.data/data/scripts/load_models.py +12 -0
  44. invokeai-2.2.4.5.data/data/scripts/merge_embeddings.py +124 -0
  45. invokeai-2.2.4.5.data/data/scripts/preload_models.py +12 -0
  46. invokeai-2.2.4.5.data/data/scripts/sd-metadata.py +22 -0
  47. invokeai-2.2.4.5.dist-info/LICENSE +21 -0
  48. invokeai-2.2.4.5.dist-info/LICENSE-ModelWeights.txt +294 -0
  49. invokeai-2.2.4.5.dist-info/METADATA +288 -0
  50. invokeai-2.2.4.5.dist-info/RECORD +169 -0
  51. invokeai-2.2.4.5.dist-info/WHEEL +5 -0
  52. invokeai-2.2.4.5.dist-info/entry_points.txt +4 -0
  53. invokeai-2.2.4.5.dist-info/top_level.txt +6 -0
  54. invokeai-2.2.4.5.dist-info/zip-safe +1 -0
  55. ldm/__init__.py +0 -0
  56. ldm/data/__init__.py +0 -0
  57. ldm/data/base.py +31 -0
  58. ldm/data/imagenet.py +466 -0
  59. ldm/data/lsun.py +126 -0
  60. ldm/data/personalized.py +202 -0
  61. ldm/data/personalized_style.py +169 -0
  62. ldm/generate.py +1159 -0
  63. ldm/invoke/CLI.py +960 -0
  64. ldm/invoke/__init__.py +3 -0
  65. ldm/invoke/args.py +1257 -0
  66. ldm/invoke/concepts_lib.py +169 -0
  67. ldm/invoke/conditioning.py +289 -0
  68. ldm/invoke/devices.py +27 -0
  69. ldm/invoke/generator/__init__.py +4 -0
  70. ldm/invoke/generator/base.py +335 -0
  71. ldm/invoke/generator/embiggen.py +501 -0
  72. ldm/invoke/generator/img2img.py +97 -0
  73. ldm/invoke/generator/inpaint.py +358 -0
  74. ldm/invoke/generator/omnibus.py +175 -0
  75. ldm/invoke/generator/txt2img.py +88 -0
  76. ldm/invoke/generator/txt2img2img.py +182 -0
  77. ldm/invoke/globals.py +31 -0
  78. ldm/invoke/image_util.py +70 -0
  79. ldm/invoke/log.py +66 -0
  80. ldm/invoke/model_cache.py +449 -0
  81. ldm/invoke/patchmatch.py +44 -0
  82. ldm/invoke/pngwriter.py +113 -0
  83. ldm/invoke/prompt_parser.py +655 -0
  84. ldm/invoke/readline.py +442 -0
  85. ldm/invoke/restoration/__init__.py +4 -0
  86. ldm/invoke/restoration/base.py +38 -0
  87. ldm/invoke/restoration/codeformer.py +103 -0
  88. ldm/invoke/restoration/codeformer_arch.py +276 -0
  89. ldm/invoke/restoration/gfpgan.py +84 -0
  90. ldm/invoke/restoration/outcrop.py +108 -0
  91. ldm/invoke/restoration/outpaint.py +92 -0
  92. ldm/invoke/restoration/realesrgan.py +90 -0
  93. ldm/invoke/restoration/vqgan_arch.py +435 -0
  94. ldm/invoke/seamless.py +30 -0
  95. ldm/invoke/server.py +282 -0
  96. ldm/invoke/server_legacy.py +246 -0
  97. ldm/invoke/txt2mask.py +136 -0
  98. ldm/lr_scheduler.py +143 -0
  99. ldm/models/__init__.py +0 -0
  100. ldm/models/autoencoder.py +596 -0
  101. ldm/models/diffusion/__init__.py +0 -0
  102. ldm/models/diffusion/classifier.py +355 -0
  103. ldm/models/diffusion/cross_attention_control.py +443 -0
  104. ldm/models/diffusion/cross_attention_map_saving.py +95 -0
  105. ldm/models/diffusion/ddim.py +111 -0
  106. ldm/models/diffusion/ddpm.py +2263 -0
  107. ldm/models/diffusion/ksampler.py +312 -0
  108. ldm/models/diffusion/plms.py +146 -0
  109. ldm/models/diffusion/sampler.py +450 -0
  110. ldm/models/diffusion/shared_invokeai_diffusion.py +244 -0
  111. ldm/modules/__init__.py +0 -0
  112. ldm/modules/attention.py +274 -0
  113. ldm/modules/diffusionmodules/__init__.py +0 -0
  114. ldm/modules/diffusionmodules/model.py +894 -0
  115. ldm/modules/diffusionmodules/openaimodel.py +1036 -0
  116. ldm/modules/diffusionmodules/util.py +314 -0
  117. ldm/modules/distributions/__init__.py +0 -0
  118. ldm/modules/distributions/distributions.py +104 -0
  119. ldm/modules/ema.py +88 -0
  120. ldm/modules/embedding_manager.py +413 -0
  121. ldm/modules/encoders/__init__.py +0 -0
  122. ldm/modules/encoders/modules.py +772 -0
  123. ldm/modules/image_degradation/__init__.py +6 -0
  124. ldm/modules/image_degradation/bsrgan.py +846 -0
  125. ldm/modules/image_degradation/bsrgan_light.py +751 -0
  126. ldm/modules/image_degradation/utils_image.py +1024 -0
  127. ldm/modules/losses/__init__.py +1 -0
  128. ldm/modules/losses/contperceptual.py +175 -0
  129. ldm/modules/losses/vqperceptual.py +240 -0
  130. ldm/modules/x_transformer.py +752 -0
  131. ldm/simplet2i.py +13 -0
  132. ldm/util.py +264 -0
  133. scripts/configure_invokeai.py +797 -0
  134. scripts/create_root.py +43 -0
  135. scripts/dream.py +10 -0
  136. scripts/images2prompt.py +30 -0
  137. scripts/invoke.py +5 -0
  138. scripts/legacy_api.py +681 -0
  139. scripts/load_models.py +12 -0
  140. scripts/merge_embeddings.py +124 -0
  141. scripts/orig_scripts/img2img.py +296 -0
  142. scripts/orig_scripts/inpaint.py +98 -0
  143. scripts/orig_scripts/knn2img.py +397 -0
  144. scripts/orig_scripts/sample_diffusion.py +313 -0
  145. scripts/orig_scripts/train_searcher.py +147 -0
  146. scripts/orig_scripts/txt2img.py +324 -0
  147. scripts/preload_models.py +12 -0
  148. scripts/sd-metadata.py +22 -0
  149. vendored/clip/clip/__init__.py +1 -0
  150. vendored/clip/clip/bpe_simple_vocab_16e6.txt.gz +0 -0
  151. vendored/clip/clip/clip.py +237 -0
  152. vendored/clip/clip/model.py +436 -0
  153. vendored/clip/clip/simple_tokenizer.py +132 -0
  154. vendored/clip/hubconf.py +42 -0
  155. vendored/clip/setup.py +21 -0
  156. vendored/clip/tests/test_consistency.py +25 -0
  157. vendored/clipseg/datasets/coco_wrapper.py +99 -0
  158. vendored/clipseg/datasets/pascal_zeroshot.py +60 -0
  159. vendored/clipseg/datasets/pfe_dataset.py +129 -0
  160. vendored/clipseg/datasets/phrasecut.py +380 -0
  161. vendored/clipseg/datasets/utils.py +68 -0
  162. vendored/clipseg/evaluation_utils.py +292 -0
  163. vendored/clipseg/general_utils.py +272 -0
  164. vendored/clipseg/metrics.py +271 -0
  165. vendored/clipseg/models/clipseg.py +538 -0
  166. vendored/clipseg/models/vitseg.py +286 -0
  167. vendored/clipseg/score.py +453 -0
  168. vendored/clipseg/setup.py +30 -0
  169. vendored/clipseg/training.py +266 -0
@@ -0,0 +1,314 @@
1
+ # adopted from
2
+ # https://github.com/openai/improved-diffusion/blob/main/improved_diffusion/gaussian_diffusion.py
3
+ # and
4
+ # https://github.com/lucidrains/denoising-diffusion-pytorch/blob/7706bdfc6f527f58d33f84b7b522e61e6e3164b3/denoising_diffusion_pytorch/denoising_diffusion_pytorch.py
5
+ # and
6
+ # https://github.com/openai/guided-diffusion/blob/0ba878e517b276c45d1195eb29f6f5f72659a05b/guided_diffusion/nn.py
7
+ #
8
+ # thanks!
9
+
10
+
11
+ import os
12
+ import math
13
+ import torch
14
+ import torch.nn as nn
15
+ import numpy as np
16
+ from einops import repeat
17
+
18
+ from ldm.util import instantiate_from_config
19
+
20
+
21
+ def make_beta_schedule(
22
+ schedule, n_timestep, linear_start=1e-4, linear_end=2e-2, cosine_s=8e-3
23
+ ):
24
+ if schedule == 'linear':
25
+ betas = (
26
+ torch.linspace(
27
+ linear_start**0.5,
28
+ linear_end**0.5,
29
+ n_timestep,
30
+ dtype=torch.float64,
31
+ )
32
+ ** 2
33
+ )
34
+
35
+ elif schedule == 'cosine':
36
+ timesteps = (
37
+ torch.arange(n_timestep + 1, dtype=torch.float64) / n_timestep
38
+ + cosine_s
39
+ )
40
+ alphas = timesteps / (1 + cosine_s) * np.pi / 2
41
+ alphas = torch.cos(alphas).pow(2)
42
+ alphas = alphas / alphas[0]
43
+ betas = 1 - alphas[1:] / alphas[:-1]
44
+ betas = np.clip(betas, a_min=0, a_max=0.999)
45
+
46
+ elif schedule == 'sqrt_linear':
47
+ betas = torch.linspace(
48
+ linear_start, linear_end, n_timestep, dtype=torch.float64
49
+ )
50
+ elif schedule == 'sqrt':
51
+ betas = (
52
+ torch.linspace(
53
+ linear_start, linear_end, n_timestep, dtype=torch.float64
54
+ )
55
+ ** 0.5
56
+ )
57
+ else:
58
+ raise ValueError(f"schedule '{schedule}' unknown.")
59
+ return betas.numpy()
60
+
61
+
62
+ def make_ddim_timesteps(
63
+ ddim_discr_method, num_ddim_timesteps, num_ddpm_timesteps, verbose=True
64
+ ):
65
+ if ddim_discr_method == 'uniform':
66
+ c = num_ddpm_timesteps // num_ddim_timesteps
67
+ if c < 1:
68
+ c = 1
69
+ ddim_timesteps = (np.arange(0, num_ddim_timesteps) * c).astype(int)
70
+ elif ddim_discr_method == 'quad':
71
+ ddim_timesteps = (
72
+ (
73
+ np.linspace(
74
+ 0, np.sqrt(num_ddpm_timesteps * 0.8), num_ddim_timesteps
75
+ )
76
+ )
77
+ ** 2
78
+ ).astype(int)
79
+ else:
80
+ raise NotImplementedError(
81
+ f'There is no ddim discretization method called "{ddim_discr_method}"'
82
+ )
83
+
84
+ # assert ddim_timesteps.shape[0] == num_ddim_timesteps
85
+ # add one to get the final alpha values right (the ones from first scale to data during sampling)
86
+ steps_out = ddim_timesteps + 1
87
+ # steps_out = ddim_timesteps
88
+
89
+ if verbose:
90
+ print(f'Selected timesteps for ddim sampler: {steps_out}')
91
+ return steps_out
92
+
93
+
94
+ def make_ddim_sampling_parameters(
95
+ alphacums, ddim_timesteps, eta, verbose=True
96
+ ):
97
+ # select alphas for computing the variance schedule
98
+ alphas = alphacums[ddim_timesteps]
99
+ alphas_prev = np.asarray(
100
+ [alphacums[0]] + alphacums[ddim_timesteps[:-1]].tolist()
101
+ )
102
+
103
+ # according the the formula provided in https://arxiv.org/abs/2010.02502
104
+ sigmas = eta * np.sqrt(
105
+ (1 - alphas_prev) / (1 - alphas) * (1 - alphas / alphas_prev)
106
+ )
107
+ if verbose:
108
+ print(
109
+ f'Selected alphas for ddim sampler: a_t: {alphas}; a_(t-1): {alphas_prev}'
110
+ )
111
+ print(
112
+ f'For the chosen value of eta, which is {eta}, '
113
+ f'this results in the following sigma_t schedule for ddim sampler {sigmas}'
114
+ )
115
+ return sigmas, alphas, alphas_prev
116
+
117
+
118
+ def betas_for_alpha_bar(num_diffusion_timesteps, alpha_bar, max_beta=0.999):
119
+ """
120
+ Create a beta schedule that discretizes the given alpha_t_bar function,
121
+ which defines the cumulative product of (1-beta) over time from t = [0,1].
122
+ :param num_diffusion_timesteps: the number of betas to produce.
123
+ :param alpha_bar: a lambda that takes an argument t from 0 to 1 and
124
+ produces the cumulative product of (1-beta) up to that
125
+ part of the diffusion process.
126
+ :param max_beta: the maximum beta to use; use values lower than 1 to
127
+ prevent singularities.
128
+ """
129
+ betas = []
130
+ for i in range(num_diffusion_timesteps):
131
+ t1 = i / num_diffusion_timesteps
132
+ t2 = (i + 1) / num_diffusion_timesteps
133
+ betas.append(min(1 - alpha_bar(t2) / alpha_bar(t1), max_beta))
134
+ return np.array(betas)
135
+
136
+
137
+ def extract_into_tensor(a, t, x_shape):
138
+ b, *_ = t.shape
139
+ out = a.gather(-1, t)
140
+ return out.reshape(b, *((1,) * (len(x_shape) - 1)))
141
+
142
+
143
+ def checkpoint(func, inputs, params, flag):
144
+ """
145
+ Evaluate a function without caching intermediate activations, allowing for
146
+ reduced memory at the expense of extra compute in the backward pass.
147
+ :param func: the function to evaluate.
148
+ :param inputs: the argument sequence to pass to `func`.
149
+ :param params: a sequence of parameters `func` depends on but does not
150
+ explicitly take as arguments.
151
+ :param flag: if False, disable gradient checkpointing.
152
+ """
153
+ if (
154
+ False
155
+ ): # disabled checkpointing to allow requires_grad = False for main model
156
+ args = tuple(inputs) + tuple(params)
157
+ return CheckpointFunction.apply(func, len(inputs), *args)
158
+ else:
159
+ return func(*inputs)
160
+
161
+
162
+ class CheckpointFunction(torch.autograd.Function):
163
+ @staticmethod
164
+ def forward(ctx, run_function, length, *args):
165
+ ctx.run_function = run_function
166
+ ctx.input_tensors = list(args[:length])
167
+ ctx.input_params = list(args[length:])
168
+
169
+ with torch.no_grad():
170
+ output_tensors = ctx.run_function(*ctx.input_tensors)
171
+ return output_tensors
172
+
173
+ @staticmethod
174
+ def backward(ctx, *output_grads):
175
+ ctx.input_tensors = [
176
+ x.detach().requires_grad_(True) for x in ctx.input_tensors
177
+ ]
178
+ with torch.enable_grad():
179
+ # Fixes a bug where the first op in run_function modifies the
180
+ # Tensor storage in place, which is not allowed for detach()'d
181
+ # Tensors.
182
+ shallow_copies = [x.view_as(x) for x in ctx.input_tensors]
183
+ output_tensors = ctx.run_function(*shallow_copies)
184
+ input_grads = torch.autograd.grad(
185
+ output_tensors,
186
+ ctx.input_tensors + ctx.input_params,
187
+ output_grads,
188
+ allow_unused=True,
189
+ )
190
+ del ctx.input_tensors
191
+ del ctx.input_params
192
+ del output_tensors
193
+ return (None, None) + input_grads
194
+
195
+
196
+ def timestep_embedding(timesteps, dim, max_period=10000, repeat_only=False):
197
+ """
198
+ Create sinusoidal timestep embeddings.
199
+ :param timesteps: a 1-D Tensor of N indices, one per batch element.
200
+ These may be fractional.
201
+ :param dim: the dimension of the output.
202
+ :param max_period: controls the minimum frequency of the embeddings.
203
+ :return: an [N x dim] Tensor of positional embeddings.
204
+ """
205
+ if not repeat_only:
206
+ half = dim // 2
207
+ freqs = torch.exp(
208
+ -math.log(max_period)
209
+ * torch.arange(start=0, end=half, dtype=torch.float32)
210
+ / half
211
+ ).to(device=timesteps.device)
212
+ args = timesteps[:, None].float() * freqs[None]
213
+ embedding = torch.cat([torch.cos(args), torch.sin(args)], dim=-1)
214
+ if dim % 2:
215
+ embedding = torch.cat(
216
+ [embedding, torch.zeros_like(embedding[:, :1])], dim=-1
217
+ )
218
+ else:
219
+ embedding = repeat(timesteps, 'b -> b d', d=dim)
220
+ return embedding
221
+
222
+
223
+ def zero_module(module):
224
+ """
225
+ Zero out the parameters of a module and return it.
226
+ """
227
+ for p in module.parameters():
228
+ p.detach().zero_()
229
+ return module
230
+
231
+
232
+ def scale_module(module, scale):
233
+ """
234
+ Scale the parameters of a module and return it.
235
+ """
236
+ for p in module.parameters():
237
+ p.detach().mul_(scale)
238
+ return module
239
+
240
+
241
+ def mean_flat(tensor):
242
+ """
243
+ Take the mean over all non-batch dimensions.
244
+ """
245
+ return tensor.mean(dim=list(range(1, len(tensor.shape))))
246
+
247
+
248
+ def normalization(channels):
249
+ """
250
+ Make a standard normalization layer.
251
+ :param channels: number of input channels.
252
+ :return: an nn.Module for normalization.
253
+ """
254
+ return GroupNorm32(32, channels)
255
+
256
+
257
+ class GroupNorm32(nn.GroupNorm):
258
+ def forward(self, x):
259
+ return super().forward(x.float()).type(x.dtype)
260
+
261
+
262
+ def conv_nd(dims, *args, **kwargs):
263
+ """
264
+ Create a 1D, 2D, or 3D convolution module.
265
+ """
266
+ if dims == 1:
267
+ return nn.Conv1d(*args, **kwargs)
268
+ elif dims == 2:
269
+ return nn.Conv2d(*args, **kwargs)
270
+ elif dims == 3:
271
+ return nn.Conv3d(*args, **kwargs)
272
+ raise ValueError(f'unsupported dimensions: {dims}')
273
+
274
+
275
+ def linear(*args, **kwargs):
276
+ """
277
+ Create a linear module.
278
+ """
279
+ return nn.Linear(*args, **kwargs)
280
+
281
+
282
+ def avg_pool_nd(dims, *args, **kwargs):
283
+ """
284
+ Create a 1D, 2D, or 3D average pooling module.
285
+ """
286
+ if dims == 1:
287
+ return nn.AvgPool1d(*args, **kwargs)
288
+ elif dims == 2:
289
+ return nn.AvgPool2d(*args, **kwargs)
290
+ elif dims == 3:
291
+ return nn.AvgPool3d(*args, **kwargs)
292
+ raise ValueError(f'unsupported dimensions: {dims}')
293
+
294
+
295
+ class HybridConditioner(nn.Module):
296
+ def __init__(self, c_concat_config, c_crossattn_config):
297
+ super().__init__()
298
+ self.concat_conditioner = instantiate_from_config(c_concat_config)
299
+ self.crossattn_conditioner = instantiate_from_config(
300
+ c_crossattn_config
301
+ )
302
+
303
+ def forward(self, c_concat, c_crossattn):
304
+ c_concat = self.concat_conditioner(c_concat)
305
+ c_crossattn = self.crossattn_conditioner(c_crossattn)
306
+ return {'c_concat': [c_concat], 'c_crossattn': [c_crossattn]}
307
+
308
+
309
+ def noise_like(shape, device, repeat=False):
310
+ repeat_noise = lambda: torch.randn((1, *shape[1:]), device=device).repeat(
311
+ shape[0], *((1,) * (len(shape) - 1))
312
+ )
313
+ noise = lambda: torch.randn(shape, device=device)
314
+ return repeat_noise() if repeat else noise()
File without changes
@@ -0,0 +1,104 @@
1
+ import torch
2
+ import numpy as np
3
+
4
+
5
+ class AbstractDistribution:
6
+ def sample(self):
7
+ raise NotImplementedError()
8
+
9
+ def mode(self):
10
+ raise NotImplementedError()
11
+
12
+
13
+ class DiracDistribution(AbstractDistribution):
14
+ def __init__(self, value):
15
+ self.value = value
16
+
17
+ def sample(self):
18
+ return self.value
19
+
20
+ def mode(self):
21
+ return self.value
22
+
23
+
24
+ class DiagonalGaussianDistribution(object):
25
+ def __init__(self, parameters, deterministic=False):
26
+ self.parameters = parameters
27
+ self.mean, self.logvar = torch.chunk(parameters, 2, dim=1)
28
+ self.logvar = torch.clamp(self.logvar, -30.0, 20.0)
29
+ self.deterministic = deterministic
30
+ self.std = torch.exp(0.5 * self.logvar)
31
+ self.var = torch.exp(self.logvar)
32
+ if self.deterministic:
33
+ self.var = self.std = torch.zeros_like(self.mean).to(
34
+ device=self.parameters.device
35
+ )
36
+
37
+ def sample(self):
38
+ x = self.mean + self.std * torch.randn(self.mean.shape).to(
39
+ device=self.parameters.device
40
+ )
41
+ return x
42
+
43
+ def kl(self, other=None):
44
+ if self.deterministic:
45
+ return torch.Tensor([0.0])
46
+ else:
47
+ if other is None:
48
+ return 0.5 * torch.sum(
49
+ torch.pow(self.mean, 2) + self.var - 1.0 - self.logvar,
50
+ dim=[1, 2, 3],
51
+ )
52
+ else:
53
+ return 0.5 * torch.sum(
54
+ torch.pow(self.mean - other.mean, 2) / other.var
55
+ + self.var / other.var
56
+ - 1.0
57
+ - self.logvar
58
+ + other.logvar,
59
+ dim=[1, 2, 3],
60
+ )
61
+
62
+ def nll(self, sample, dims=[1, 2, 3]):
63
+ if self.deterministic:
64
+ return torch.Tensor([0.0])
65
+ logtwopi = np.log(2.0 * np.pi)
66
+ return 0.5 * torch.sum(
67
+ logtwopi
68
+ + self.logvar
69
+ + torch.pow(sample - self.mean, 2) / self.var,
70
+ dim=dims,
71
+ )
72
+
73
+ def mode(self):
74
+ return self.mean
75
+
76
+
77
+ def normal_kl(mean1, logvar1, mean2, logvar2):
78
+ """
79
+ source: https://github.com/openai/guided-diffusion/blob/27c20a8fab9cb472df5d6bdd6c8d11c8f430b924/guided_diffusion/losses.py#L12
80
+ Compute the KL divergence between two gaussians.
81
+ Shapes are automatically broadcasted, so batches can be compared to
82
+ scalars, among other use cases.
83
+ """
84
+ tensor = None
85
+ for obj in (mean1, logvar1, mean2, logvar2):
86
+ if isinstance(obj, torch.Tensor):
87
+ tensor = obj
88
+ break
89
+ assert tensor is not None, 'at least one argument must be a Tensor'
90
+
91
+ # Force variances to be Tensors. Broadcasting helps convert scalars to
92
+ # Tensors, but it does not work for torch.exp().
93
+ logvar1, logvar2 = [
94
+ x if isinstance(x, torch.Tensor) else torch.tensor(x).to(tensor)
95
+ for x in (logvar1, logvar2)
96
+ ]
97
+
98
+ return 0.5 * (
99
+ -1.0
100
+ + logvar2
101
+ - logvar1
102
+ + torch.exp(logvar1 - logvar2)
103
+ + ((mean1 - mean2) ** 2) * torch.exp(-logvar2)
104
+ )
ldm/modules/ema.py ADDED
@@ -0,0 +1,88 @@
1
+ import torch
2
+ from torch import nn
3
+
4
+
5
+ class LitEma(nn.Module):
6
+ def __init__(self, model, decay=0.9999, use_num_upates=True):
7
+ super().__init__()
8
+ if decay < 0.0 or decay > 1.0:
9
+ raise ValueError('Decay must be between 0 and 1')
10
+
11
+ self.m_name2s_name = {}
12
+ self.register_buffer('decay', torch.tensor(decay, dtype=torch.float32))
13
+ self.register_buffer(
14
+ 'num_updates',
15
+ torch.tensor(0, dtype=torch.int)
16
+ if use_num_upates
17
+ else torch.tensor(-1, dtype=torch.int),
18
+ )
19
+
20
+ for name, p in model.named_parameters():
21
+ if p.requires_grad:
22
+ # remove as '.'-character is not allowed in buffers
23
+ s_name = name.replace('.', '')
24
+ self.m_name2s_name.update({name: s_name})
25
+ self.register_buffer(s_name, p.clone().detach().data)
26
+
27
+ self.collected_params = []
28
+
29
+ def forward(self, model):
30
+ decay = self.decay
31
+
32
+ if self.num_updates >= 0:
33
+ self.num_updates += 1
34
+ decay = min(
35
+ self.decay, (1 + self.num_updates) / (10 + self.num_updates)
36
+ )
37
+
38
+ one_minus_decay = 1.0 - decay
39
+
40
+ with torch.no_grad():
41
+ m_param = dict(model.named_parameters())
42
+ shadow_params = dict(self.named_buffers())
43
+
44
+ for key in m_param:
45
+ if m_param[key].requires_grad:
46
+ sname = self.m_name2s_name[key]
47
+ shadow_params[sname] = shadow_params[sname].type_as(
48
+ m_param[key]
49
+ )
50
+ shadow_params[sname].sub_(
51
+ one_minus_decay * (shadow_params[sname] - m_param[key])
52
+ )
53
+ else:
54
+ assert not key in self.m_name2s_name
55
+
56
+ def copy_to(self, model):
57
+ m_param = dict(model.named_parameters())
58
+ shadow_params = dict(self.named_buffers())
59
+ for key in m_param:
60
+ if m_param[key].requires_grad:
61
+ m_param[key].data.copy_(
62
+ shadow_params[self.m_name2s_name[key]].data
63
+ )
64
+ else:
65
+ assert not key in self.m_name2s_name
66
+
67
+ def store(self, parameters):
68
+ """
69
+ Save the current parameters for restoring later.
70
+ Args:
71
+ parameters: Iterable of `torch.nn.Parameter`; the parameters to be
72
+ temporarily stored.
73
+ """
74
+ self.collected_params = [param.clone() for param in parameters]
75
+
76
+ def restore(self, parameters):
77
+ """
78
+ Restore the parameters stored with the `store` method.
79
+ Useful to validate the model with EMA parameters without affecting the
80
+ original optimization process. Store the parameters before the
81
+ `copy_to` method. After validation (or model saving), use this to
82
+ restore the former parameters.
83
+ Args:
84
+ parameters: Iterable of `torch.nn.Parameter`; the parameters to be
85
+ updated with the stored parameters.
86
+ """
87
+ for c_param, param in zip(self.collected_params, parameters):
88
+ param.data.copy_(c_param.data)