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,596 @@
1
+ import torch
2
+ import pytorch_lightning as pl
3
+ import torch.nn.functional as F
4
+ from contextlib import contextmanager
5
+
6
+ from taming.modules.vqvae.quantize import VectorQuantizer2 as VectorQuantizer
7
+
8
+ from ldm.modules.diffusionmodules.model import Encoder, Decoder
9
+ from ldm.modules.distributions.distributions import (
10
+ DiagonalGaussianDistribution,
11
+ )
12
+
13
+ from ldm.util import instantiate_from_config
14
+
15
+
16
+ class VQModel(pl.LightningModule):
17
+ def __init__(
18
+ self,
19
+ ddconfig,
20
+ lossconfig,
21
+ n_embed,
22
+ embed_dim,
23
+ ckpt_path=None,
24
+ ignore_keys=[],
25
+ image_key='image',
26
+ colorize_nlabels=None,
27
+ monitor=None,
28
+ batch_resize_range=None,
29
+ scheduler_config=None,
30
+ lr_g_factor=1.0,
31
+ remap=None,
32
+ sane_index_shape=False, # tell vector quantizer to return indices as bhw
33
+ use_ema=False,
34
+ ):
35
+ super().__init__()
36
+ self.embed_dim = embed_dim
37
+ self.n_embed = n_embed
38
+ self.image_key = image_key
39
+ self.encoder = Encoder(**ddconfig)
40
+ self.decoder = Decoder(**ddconfig)
41
+ self.loss = instantiate_from_config(lossconfig)
42
+ self.quantize = VectorQuantizer(
43
+ n_embed,
44
+ embed_dim,
45
+ beta=0.25,
46
+ remap=remap,
47
+ sane_index_shape=sane_index_shape,
48
+ )
49
+ self.quant_conv = torch.nn.Conv2d(ddconfig['z_channels'], embed_dim, 1)
50
+ self.post_quant_conv = torch.nn.Conv2d(
51
+ embed_dim, ddconfig['z_channels'], 1
52
+ )
53
+ if colorize_nlabels is not None:
54
+ assert type(colorize_nlabels) == int
55
+ self.register_buffer(
56
+ 'colorize', torch.randn(3, colorize_nlabels, 1, 1)
57
+ )
58
+ if monitor is not None:
59
+ self.monitor = monitor
60
+ self.batch_resize_range = batch_resize_range
61
+ if self.batch_resize_range is not None:
62
+ print(
63
+ f'{self.__class__.__name__}: Using per-batch resizing in range {batch_resize_range}.'
64
+ )
65
+
66
+ self.use_ema = use_ema
67
+ if self.use_ema:
68
+ self.model_ema = LitEma(self)
69
+ print(f'>> Keeping EMAs of {len(list(self.model_ema.buffers()))}.')
70
+
71
+ if ckpt_path is not None:
72
+ self.init_from_ckpt(ckpt_path, ignore_keys=ignore_keys)
73
+ self.scheduler_config = scheduler_config
74
+ self.lr_g_factor = lr_g_factor
75
+
76
+ @contextmanager
77
+ def ema_scope(self, context=None):
78
+ if self.use_ema:
79
+ self.model_ema.store(self.parameters())
80
+ self.model_ema.copy_to(self)
81
+ if context is not None:
82
+ print(f'{context}: Switched to EMA weights')
83
+ try:
84
+ yield None
85
+ finally:
86
+ if self.use_ema:
87
+ self.model_ema.restore(self.parameters())
88
+ if context is not None:
89
+ print(f'{context}: Restored training weights')
90
+
91
+ def init_from_ckpt(self, path, ignore_keys=list()):
92
+ sd = torch.load(path, map_location='cpu')['state_dict']
93
+ keys = list(sd.keys())
94
+ for k in keys:
95
+ for ik in ignore_keys:
96
+ if k.startswith(ik):
97
+ print('Deleting key {} from state_dict.'.format(k))
98
+ del sd[k]
99
+ missing, unexpected = self.load_state_dict(sd, strict=False)
100
+ print(
101
+ f'Restored from {path} with {len(missing)} missing and {len(unexpected)} unexpected keys'
102
+ )
103
+ if len(missing) > 0:
104
+ print(f'Missing Keys: {missing}')
105
+ print(f'Unexpected Keys: {unexpected}')
106
+
107
+ def on_train_batch_end(self, *args, **kwargs):
108
+ if self.use_ema:
109
+ self.model_ema(self)
110
+
111
+ def encode(self, x):
112
+ h = self.encoder(x)
113
+ h = self.quant_conv(h)
114
+ quant, emb_loss, info = self.quantize(h)
115
+ return quant, emb_loss, info
116
+
117
+ def encode_to_prequant(self, x):
118
+ h = self.encoder(x)
119
+ h = self.quant_conv(h)
120
+ return h
121
+
122
+ def decode(self, quant):
123
+ quant = self.post_quant_conv(quant)
124
+ dec = self.decoder(quant)
125
+ return dec
126
+
127
+ def decode_code(self, code_b):
128
+ quant_b = self.quantize.embed_code(code_b)
129
+ dec = self.decode(quant_b)
130
+ return dec
131
+
132
+ def forward(self, input, return_pred_indices=False):
133
+ quant, diff, (_, _, ind) = self.encode(input)
134
+ dec = self.decode(quant)
135
+ if return_pred_indices:
136
+ return dec, diff, ind
137
+ return dec, diff
138
+
139
+ def get_input(self, batch, k):
140
+ x = batch[k]
141
+ if len(x.shape) == 3:
142
+ x = x[..., None]
143
+ x = (
144
+ x.permute(0, 3, 1, 2)
145
+ .to(memory_format=torch.contiguous_format)
146
+ .float()
147
+ )
148
+ if self.batch_resize_range is not None:
149
+ lower_size = self.batch_resize_range[0]
150
+ upper_size = self.batch_resize_range[1]
151
+ if self.global_step <= 4:
152
+ # do the first few batches with max size to avoid later oom
153
+ new_resize = upper_size
154
+ else:
155
+ new_resize = np.random.choice(
156
+ np.arange(lower_size, upper_size + 16, 16)
157
+ )
158
+ if new_resize != x.shape[2]:
159
+ x = F.interpolate(x, size=new_resize, mode='bicubic')
160
+ x = x.detach()
161
+ return x
162
+
163
+ def training_step(self, batch, batch_idx, optimizer_idx):
164
+ # https://github.com/pytorch/pytorch/issues/37142
165
+ # try not to fool the heuristics
166
+ x = self.get_input(batch, self.image_key)
167
+ xrec, qloss, ind = self(x, return_pred_indices=True)
168
+
169
+ if optimizer_idx == 0:
170
+ # autoencode
171
+ aeloss, log_dict_ae = self.loss(
172
+ qloss,
173
+ x,
174
+ xrec,
175
+ optimizer_idx,
176
+ self.global_step,
177
+ last_layer=self.get_last_layer(),
178
+ split='train',
179
+ predicted_indices=ind,
180
+ )
181
+
182
+ self.log_dict(
183
+ log_dict_ae,
184
+ prog_bar=False,
185
+ logger=True,
186
+ on_step=True,
187
+ on_epoch=True,
188
+ )
189
+ return aeloss
190
+
191
+ if optimizer_idx == 1:
192
+ # discriminator
193
+ discloss, log_dict_disc = self.loss(
194
+ qloss,
195
+ x,
196
+ xrec,
197
+ optimizer_idx,
198
+ self.global_step,
199
+ last_layer=self.get_last_layer(),
200
+ split='train',
201
+ )
202
+ self.log_dict(
203
+ log_dict_disc,
204
+ prog_bar=False,
205
+ logger=True,
206
+ on_step=True,
207
+ on_epoch=True,
208
+ )
209
+ return discloss
210
+
211
+ def validation_step(self, batch, batch_idx):
212
+ log_dict = self._validation_step(batch, batch_idx)
213
+ with self.ema_scope():
214
+ log_dict_ema = self._validation_step(
215
+ batch, batch_idx, suffix='_ema'
216
+ )
217
+ return log_dict
218
+
219
+ def _validation_step(self, batch, batch_idx, suffix=''):
220
+ x = self.get_input(batch, self.image_key)
221
+ xrec, qloss, ind = self(x, return_pred_indices=True)
222
+ aeloss, log_dict_ae = self.loss(
223
+ qloss,
224
+ x,
225
+ xrec,
226
+ 0,
227
+ self.global_step,
228
+ last_layer=self.get_last_layer(),
229
+ split='val' + suffix,
230
+ predicted_indices=ind,
231
+ )
232
+
233
+ discloss, log_dict_disc = self.loss(
234
+ qloss,
235
+ x,
236
+ xrec,
237
+ 1,
238
+ self.global_step,
239
+ last_layer=self.get_last_layer(),
240
+ split='val' + suffix,
241
+ predicted_indices=ind,
242
+ )
243
+ rec_loss = log_dict_ae[f'val{suffix}/rec_loss']
244
+ self.log(
245
+ f'val{suffix}/rec_loss',
246
+ rec_loss,
247
+ prog_bar=True,
248
+ logger=True,
249
+ on_step=False,
250
+ on_epoch=True,
251
+ sync_dist=True,
252
+ )
253
+ self.log(
254
+ f'val{suffix}/aeloss',
255
+ aeloss,
256
+ prog_bar=True,
257
+ logger=True,
258
+ on_step=False,
259
+ on_epoch=True,
260
+ sync_dist=True,
261
+ )
262
+ if version.parse(pl.__version__) >= version.parse('1.4.0'):
263
+ del log_dict_ae[f'val{suffix}/rec_loss']
264
+ self.log_dict(log_dict_ae)
265
+ self.log_dict(log_dict_disc)
266
+ return self.log_dict
267
+
268
+ def configure_optimizers(self):
269
+ lr_d = self.learning_rate
270
+ lr_g = self.lr_g_factor * self.learning_rate
271
+ print('lr_d', lr_d)
272
+ print('lr_g', lr_g)
273
+ opt_ae = torch.optim.Adam(
274
+ list(self.encoder.parameters())
275
+ + list(self.decoder.parameters())
276
+ + list(self.quantize.parameters())
277
+ + list(self.quant_conv.parameters())
278
+ + list(self.post_quant_conv.parameters()),
279
+ lr=lr_g,
280
+ betas=(0.5, 0.9),
281
+ )
282
+ opt_disc = torch.optim.Adam(
283
+ self.loss.discriminator.parameters(), lr=lr_d, betas=(0.5, 0.9)
284
+ )
285
+
286
+ if self.scheduler_config is not None:
287
+ scheduler = instantiate_from_config(self.scheduler_config)
288
+
289
+ print('Setting up LambdaLR scheduler...')
290
+ scheduler = [
291
+ {
292
+ 'scheduler': LambdaLR(
293
+ opt_ae, lr_lambda=scheduler.schedule
294
+ ),
295
+ 'interval': 'step',
296
+ 'frequency': 1,
297
+ },
298
+ {
299
+ 'scheduler': LambdaLR(
300
+ opt_disc, lr_lambda=scheduler.schedule
301
+ ),
302
+ 'interval': 'step',
303
+ 'frequency': 1,
304
+ },
305
+ ]
306
+ return [opt_ae, opt_disc], scheduler
307
+ return [opt_ae, opt_disc], []
308
+
309
+ def get_last_layer(self):
310
+ return self.decoder.conv_out.weight
311
+
312
+ def log_images(self, batch, only_inputs=False, plot_ema=False, **kwargs):
313
+ log = dict()
314
+ x = self.get_input(batch, self.image_key)
315
+ x = x.to(self.device)
316
+ if only_inputs:
317
+ log['inputs'] = x
318
+ return log
319
+ xrec, _ = self(x)
320
+ if x.shape[1] > 3:
321
+ # colorize with random projection
322
+ assert xrec.shape[1] > 3
323
+ x = self.to_rgb(x)
324
+ xrec = self.to_rgb(xrec)
325
+ log['inputs'] = x
326
+ log['reconstructions'] = xrec
327
+ if plot_ema:
328
+ with self.ema_scope():
329
+ xrec_ema, _ = self(x)
330
+ if x.shape[1] > 3:
331
+ xrec_ema = self.to_rgb(xrec_ema)
332
+ log['reconstructions_ema'] = xrec_ema
333
+ return log
334
+
335
+ def to_rgb(self, x):
336
+ assert self.image_key == 'segmentation'
337
+ if not hasattr(self, 'colorize'):
338
+ self.register_buffer(
339
+ 'colorize', torch.randn(3, x.shape[1], 1, 1).to(x)
340
+ )
341
+ x = F.conv2d(x, weight=self.colorize)
342
+ x = 2.0 * (x - x.min()) / (x.max() - x.min()) - 1.0
343
+ return x
344
+
345
+
346
+ class VQModelInterface(VQModel):
347
+ def __init__(self, embed_dim, *args, **kwargs):
348
+ super().__init__(embed_dim=embed_dim, *args, **kwargs)
349
+ self.embed_dim = embed_dim
350
+
351
+ def encode(self, x):
352
+ h = self.encoder(x)
353
+ h = self.quant_conv(h)
354
+ return h
355
+
356
+ def decode(self, h, force_not_quantize=False):
357
+ # also go through quantization layer
358
+ if not force_not_quantize:
359
+ quant, emb_loss, info = self.quantize(h)
360
+ else:
361
+ quant = h
362
+ quant = self.post_quant_conv(quant)
363
+ dec = self.decoder(quant)
364
+ return dec
365
+
366
+
367
+ class AutoencoderKL(pl.LightningModule):
368
+ def __init__(
369
+ self,
370
+ ddconfig,
371
+ lossconfig,
372
+ embed_dim,
373
+ ckpt_path=None,
374
+ ignore_keys=[],
375
+ image_key='image',
376
+ colorize_nlabels=None,
377
+ monitor=None,
378
+ ):
379
+ super().__init__()
380
+ self.image_key = image_key
381
+ self.encoder = Encoder(**ddconfig)
382
+ self.decoder = Decoder(**ddconfig)
383
+ self.loss = instantiate_from_config(lossconfig)
384
+ assert ddconfig['double_z']
385
+ self.quant_conv = torch.nn.Conv2d(
386
+ 2 * ddconfig['z_channels'], 2 * embed_dim, 1
387
+ )
388
+ self.post_quant_conv = torch.nn.Conv2d(
389
+ embed_dim, ddconfig['z_channels'], 1
390
+ )
391
+ self.embed_dim = embed_dim
392
+ if colorize_nlabels is not None:
393
+ assert type(colorize_nlabels) == int
394
+ self.register_buffer(
395
+ 'colorize', torch.randn(3, colorize_nlabels, 1, 1)
396
+ )
397
+ if monitor is not None:
398
+ self.monitor = monitor
399
+ if ckpt_path is not None:
400
+ self.init_from_ckpt(ckpt_path, ignore_keys=ignore_keys)
401
+
402
+ def init_from_ckpt(self, path, ignore_keys=list()):
403
+ sd = torch.load(path, map_location='cpu')['state_dict']
404
+ keys = list(sd.keys())
405
+ for k in keys:
406
+ for ik in ignore_keys:
407
+ if k.startswith(ik):
408
+ print('Deleting key {} from state_dict.'.format(k))
409
+ del sd[k]
410
+ self.load_state_dict(sd, strict=False)
411
+ print(f'Restored from {path}')
412
+
413
+ def encode(self, x):
414
+ h = self.encoder(x)
415
+ moments = self.quant_conv(h)
416
+ posterior = DiagonalGaussianDistribution(moments)
417
+ return posterior
418
+
419
+ def decode(self, z):
420
+ z = self.post_quant_conv(z)
421
+ dec = self.decoder(z)
422
+ return dec
423
+
424
+ def forward(self, input, sample_posterior=True):
425
+ posterior = self.encode(input)
426
+ if sample_posterior:
427
+ z = posterior.sample()
428
+ else:
429
+ z = posterior.mode()
430
+ dec = self.decode(z)
431
+ return dec, posterior
432
+
433
+ def get_input(self, batch, k):
434
+ x = batch[k]
435
+ if len(x.shape) == 3:
436
+ x = x[..., None]
437
+ x = (
438
+ x.permute(0, 3, 1, 2)
439
+ .to(memory_format=torch.contiguous_format)
440
+ .float()
441
+ )
442
+ return x
443
+
444
+ def training_step(self, batch, batch_idx, optimizer_idx):
445
+ inputs = self.get_input(batch, self.image_key)
446
+ reconstructions, posterior = self(inputs)
447
+
448
+ if optimizer_idx == 0:
449
+ # train encoder+decoder+logvar
450
+ aeloss, log_dict_ae = self.loss(
451
+ inputs,
452
+ reconstructions,
453
+ posterior,
454
+ optimizer_idx,
455
+ self.global_step,
456
+ last_layer=self.get_last_layer(),
457
+ split='train',
458
+ )
459
+ self.log(
460
+ 'aeloss',
461
+ aeloss,
462
+ prog_bar=True,
463
+ logger=True,
464
+ on_step=True,
465
+ on_epoch=True,
466
+ )
467
+ self.log_dict(
468
+ log_dict_ae,
469
+ prog_bar=False,
470
+ logger=True,
471
+ on_step=True,
472
+ on_epoch=False,
473
+ )
474
+ return aeloss
475
+
476
+ if optimizer_idx == 1:
477
+ # train the discriminator
478
+ discloss, log_dict_disc = self.loss(
479
+ inputs,
480
+ reconstructions,
481
+ posterior,
482
+ optimizer_idx,
483
+ self.global_step,
484
+ last_layer=self.get_last_layer(),
485
+ split='train',
486
+ )
487
+
488
+ self.log(
489
+ 'discloss',
490
+ discloss,
491
+ prog_bar=True,
492
+ logger=True,
493
+ on_step=True,
494
+ on_epoch=True,
495
+ )
496
+ self.log_dict(
497
+ log_dict_disc,
498
+ prog_bar=False,
499
+ logger=True,
500
+ on_step=True,
501
+ on_epoch=False,
502
+ )
503
+ return discloss
504
+
505
+ def validation_step(self, batch, batch_idx):
506
+ inputs = self.get_input(batch, self.image_key)
507
+ reconstructions, posterior = self(inputs)
508
+ aeloss, log_dict_ae = self.loss(
509
+ inputs,
510
+ reconstructions,
511
+ posterior,
512
+ 0,
513
+ self.global_step,
514
+ last_layer=self.get_last_layer(),
515
+ split='val',
516
+ )
517
+
518
+ discloss, log_dict_disc = self.loss(
519
+ inputs,
520
+ reconstructions,
521
+ posterior,
522
+ 1,
523
+ self.global_step,
524
+ last_layer=self.get_last_layer(),
525
+ split='val',
526
+ )
527
+
528
+ self.log('val/rec_loss', log_dict_ae['val/rec_loss'])
529
+ self.log_dict(log_dict_ae)
530
+ self.log_dict(log_dict_disc)
531
+ return self.log_dict
532
+
533
+ def configure_optimizers(self):
534
+ lr = self.learning_rate
535
+ opt_ae = torch.optim.Adam(
536
+ list(self.encoder.parameters())
537
+ + list(self.decoder.parameters())
538
+ + list(self.quant_conv.parameters())
539
+ + list(self.post_quant_conv.parameters()),
540
+ lr=lr,
541
+ betas=(0.5, 0.9),
542
+ )
543
+ opt_disc = torch.optim.Adam(
544
+ self.loss.discriminator.parameters(), lr=lr, betas=(0.5, 0.9)
545
+ )
546
+ return [opt_ae, opt_disc], []
547
+
548
+ def get_last_layer(self):
549
+ return self.decoder.conv_out.weight
550
+
551
+ @torch.no_grad()
552
+ def log_images(self, batch, only_inputs=False, **kwargs):
553
+ log = dict()
554
+ x = self.get_input(batch, self.image_key)
555
+ x = x.to(self.device)
556
+ if not only_inputs:
557
+ xrec, posterior = self(x)
558
+ if x.shape[1] > 3:
559
+ # colorize with random projection
560
+ assert xrec.shape[1] > 3
561
+ x = self.to_rgb(x)
562
+ xrec = self.to_rgb(xrec)
563
+ log['samples'] = self.decode(torch.randn_like(posterior.sample()))
564
+ log['reconstructions'] = xrec
565
+ log['inputs'] = x
566
+ return log
567
+
568
+ def to_rgb(self, x):
569
+ assert self.image_key == 'segmentation'
570
+ if not hasattr(self, 'colorize'):
571
+ self.register_buffer(
572
+ 'colorize', torch.randn(3, x.shape[1], 1, 1).to(x)
573
+ )
574
+ x = F.conv2d(x, weight=self.colorize)
575
+ x = 2.0 * (x - x.min()) / (x.max() - x.min()) - 1.0
576
+ return x
577
+
578
+
579
+ class IdentityFirstStage(torch.nn.Module):
580
+ def __init__(self, *args, vq_interface=False, **kwargs):
581
+ self.vq_interface = vq_interface # TODO: Should be true by default but check to not break older stuff
582
+ super().__init__()
583
+
584
+ def encode(self, x, *args, **kwargs):
585
+ return x
586
+
587
+ def decode(self, x, *args, **kwargs):
588
+ return x
589
+
590
+ def quantize(self, x, *args, **kwargs):
591
+ if self.vq_interface:
592
+ return x, None, [None, None, None]
593
+ return x
594
+
595
+ def forward(self, x, *args, **kwargs):
596
+ return x
File without changes