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.
- backend/__init__.py +0 -0
- backend/invoke_ai_web_server.py +1724 -0
- backend/modules/__init__.py +0 -0
- backend/modules/create_cmd_parser.py +55 -0
- backend/modules/get_canvas_generation_mode.py +117 -0
- backend/modules/parameters.py +71 -0
- backend/modules/parse_seed_weights.py +47 -0
- configs/INITIAL_MODELS.yaml +80 -0
- configs/models.yaml.example +29 -0
- configs/sd-concepts.txt +803 -0
- configs/stable-diffusion/v1-finetune.yaml +110 -0
- configs/stable-diffusion/v1-finetune_style.yaml +103 -0
- configs/stable-diffusion/v1-inference.yaml +79 -0
- configs/stable-diffusion/v1-inpainting-inference.yaml +79 -0
- configs/stable-diffusion/v1-m1-finetune.yaml +110 -0
- docs/assets/invoke-web-server-1.png +0 -0
- docs/assets/invoke_ai_banner.png +0 -0
- invokeai-2.2.4.5.data/data/assets/caution.png +0 -0
- invokeai-2.2.4.5.data/data/configs/INITIAL_MODELS.yaml +80 -0
- invokeai-2.2.4.5.data/data/configs/models.yaml.example +29 -0
- invokeai-2.2.4.5.data/data/configs/sd-concepts.txt +803 -0
- invokeai-2.2.4.5.data/data/configs/stable-diffusion/v1-finetune.yaml +110 -0
- invokeai-2.2.4.5.data/data/configs/stable-diffusion/v1-finetune_style.yaml +103 -0
- invokeai-2.2.4.5.data/data/configs/stable-diffusion/v1-inference.yaml +79 -0
- invokeai-2.2.4.5.data/data/configs/stable-diffusion/v1-inpainting-inference.yaml +79 -0
- invokeai-2.2.4.5.data/data/configs/stable-diffusion/v1-m1-finetune.yaml +110 -0
- invokeai-2.2.4.5.data/data/frontend/dist/assets/Inter-Bold.790c108b.ttf +0 -0
- invokeai-2.2.4.5.data/data/frontend/dist/assets/Inter.b9a8e5e2.ttf +0 -0
- invokeai-2.2.4.5.data/data/frontend/dist/assets/favicon.0d253ced.ico +0 -0
- invokeai-2.2.4.5.data/data/frontend/dist/assets/index-legacy-b741077f.js +48 -0
- invokeai-2.2.4.5.data/data/frontend/dist/assets/index.0dadf5d0.css +1 -0
- invokeai-2.2.4.5.data/data/frontend/dist/assets/index.21ff81eb.js +625 -0
- invokeai-2.2.4.5.data/data/frontend/dist/assets/logo.13003d72.png +0 -0
- invokeai-2.2.4.5.data/data/frontend/dist/assets/polyfills-legacy-dde3a68a.js +4 -0
- invokeai-2.2.4.5.data/data/frontend/dist/assets/polyfills.1ff60148.js +1 -0
- invokeai-2.2.4.5.data/data/frontend/dist/index.html +23 -0
- invokeai-2.2.4.5.data/data/scripts/configure_invokeai.py +797 -0
- invokeai-2.2.4.5.data/data/scripts/create_root.py +43 -0
- invokeai-2.2.4.5.data/data/scripts/dream.py +10 -0
- invokeai-2.2.4.5.data/data/scripts/images2prompt.py +30 -0
- invokeai-2.2.4.5.data/data/scripts/invoke.py +5 -0
- invokeai-2.2.4.5.data/data/scripts/legacy_api.py +681 -0
- invokeai-2.2.4.5.data/data/scripts/load_models.py +12 -0
- invokeai-2.2.4.5.data/data/scripts/merge_embeddings.py +124 -0
- invokeai-2.2.4.5.data/data/scripts/preload_models.py +12 -0
- invokeai-2.2.4.5.data/data/scripts/sd-metadata.py +22 -0
- invokeai-2.2.4.5.dist-info/LICENSE +21 -0
- invokeai-2.2.4.5.dist-info/LICENSE-ModelWeights.txt +294 -0
- invokeai-2.2.4.5.dist-info/METADATA +288 -0
- invokeai-2.2.4.5.dist-info/RECORD +169 -0
- invokeai-2.2.4.5.dist-info/WHEEL +5 -0
- invokeai-2.2.4.5.dist-info/entry_points.txt +4 -0
- invokeai-2.2.4.5.dist-info/top_level.txt +6 -0
- invokeai-2.2.4.5.dist-info/zip-safe +1 -0
- ldm/__init__.py +0 -0
- ldm/data/__init__.py +0 -0
- ldm/data/base.py +31 -0
- ldm/data/imagenet.py +466 -0
- ldm/data/lsun.py +126 -0
- ldm/data/personalized.py +202 -0
- ldm/data/personalized_style.py +169 -0
- ldm/generate.py +1159 -0
- ldm/invoke/CLI.py +960 -0
- ldm/invoke/__init__.py +3 -0
- ldm/invoke/args.py +1257 -0
- ldm/invoke/concepts_lib.py +169 -0
- ldm/invoke/conditioning.py +289 -0
- ldm/invoke/devices.py +27 -0
- ldm/invoke/generator/__init__.py +4 -0
- ldm/invoke/generator/base.py +335 -0
- ldm/invoke/generator/embiggen.py +501 -0
- ldm/invoke/generator/img2img.py +97 -0
- ldm/invoke/generator/inpaint.py +358 -0
- ldm/invoke/generator/omnibus.py +175 -0
- ldm/invoke/generator/txt2img.py +88 -0
- ldm/invoke/generator/txt2img2img.py +182 -0
- ldm/invoke/globals.py +31 -0
- ldm/invoke/image_util.py +70 -0
- ldm/invoke/log.py +66 -0
- ldm/invoke/model_cache.py +449 -0
- ldm/invoke/patchmatch.py +44 -0
- ldm/invoke/pngwriter.py +113 -0
- ldm/invoke/prompt_parser.py +655 -0
- ldm/invoke/readline.py +442 -0
- ldm/invoke/restoration/__init__.py +4 -0
- ldm/invoke/restoration/base.py +38 -0
- ldm/invoke/restoration/codeformer.py +103 -0
- ldm/invoke/restoration/codeformer_arch.py +276 -0
- ldm/invoke/restoration/gfpgan.py +84 -0
- ldm/invoke/restoration/outcrop.py +108 -0
- ldm/invoke/restoration/outpaint.py +92 -0
- ldm/invoke/restoration/realesrgan.py +90 -0
- ldm/invoke/restoration/vqgan_arch.py +435 -0
- ldm/invoke/seamless.py +30 -0
- ldm/invoke/server.py +282 -0
- ldm/invoke/server_legacy.py +246 -0
- ldm/invoke/txt2mask.py +136 -0
- ldm/lr_scheduler.py +143 -0
- ldm/models/__init__.py +0 -0
- ldm/models/autoencoder.py +596 -0
- ldm/models/diffusion/__init__.py +0 -0
- ldm/models/diffusion/classifier.py +355 -0
- ldm/models/diffusion/cross_attention_control.py +443 -0
- ldm/models/diffusion/cross_attention_map_saving.py +95 -0
- ldm/models/diffusion/ddim.py +111 -0
- ldm/models/diffusion/ddpm.py +2263 -0
- ldm/models/diffusion/ksampler.py +312 -0
- ldm/models/diffusion/plms.py +146 -0
- ldm/models/diffusion/sampler.py +450 -0
- ldm/models/diffusion/shared_invokeai_diffusion.py +244 -0
- ldm/modules/__init__.py +0 -0
- ldm/modules/attention.py +274 -0
- ldm/modules/diffusionmodules/__init__.py +0 -0
- ldm/modules/diffusionmodules/model.py +894 -0
- ldm/modules/diffusionmodules/openaimodel.py +1036 -0
- ldm/modules/diffusionmodules/util.py +314 -0
- ldm/modules/distributions/__init__.py +0 -0
- ldm/modules/distributions/distributions.py +104 -0
- ldm/modules/ema.py +88 -0
- ldm/modules/embedding_manager.py +413 -0
- ldm/modules/encoders/__init__.py +0 -0
- ldm/modules/encoders/modules.py +772 -0
- ldm/modules/image_degradation/__init__.py +6 -0
- ldm/modules/image_degradation/bsrgan.py +846 -0
- ldm/modules/image_degradation/bsrgan_light.py +751 -0
- ldm/modules/image_degradation/utils_image.py +1024 -0
- ldm/modules/losses/__init__.py +1 -0
- ldm/modules/losses/contperceptual.py +175 -0
- ldm/modules/losses/vqperceptual.py +240 -0
- ldm/modules/x_transformer.py +752 -0
- ldm/simplet2i.py +13 -0
- ldm/util.py +264 -0
- scripts/configure_invokeai.py +797 -0
- scripts/create_root.py +43 -0
- scripts/dream.py +10 -0
- scripts/images2prompt.py +30 -0
- scripts/invoke.py +5 -0
- scripts/legacy_api.py +681 -0
- scripts/load_models.py +12 -0
- scripts/merge_embeddings.py +124 -0
- scripts/orig_scripts/img2img.py +296 -0
- scripts/orig_scripts/inpaint.py +98 -0
- scripts/orig_scripts/knn2img.py +397 -0
- scripts/orig_scripts/sample_diffusion.py +313 -0
- scripts/orig_scripts/train_searcher.py +147 -0
- scripts/orig_scripts/txt2img.py +324 -0
- scripts/preload_models.py +12 -0
- scripts/sd-metadata.py +22 -0
- vendored/clip/clip/__init__.py +1 -0
- vendored/clip/clip/bpe_simple_vocab_16e6.txt.gz +0 -0
- vendored/clip/clip/clip.py +237 -0
- vendored/clip/clip/model.py +436 -0
- vendored/clip/clip/simple_tokenizer.py +132 -0
- vendored/clip/hubconf.py +42 -0
- vendored/clip/setup.py +21 -0
- vendored/clip/tests/test_consistency.py +25 -0
- vendored/clipseg/datasets/coco_wrapper.py +99 -0
- vendored/clipseg/datasets/pascal_zeroshot.py +60 -0
- vendored/clipseg/datasets/pfe_dataset.py +129 -0
- vendored/clipseg/datasets/phrasecut.py +380 -0
- vendored/clipseg/datasets/utils.py +68 -0
- vendored/clipseg/evaluation_utils.py +292 -0
- vendored/clipseg/general_utils.py +272 -0
- vendored/clipseg/metrics.py +271 -0
- vendored/clipseg/models/clipseg.py +538 -0
- vendored/clipseg/models/vitseg.py +286 -0
- vendored/clipseg/score.py +453 -0
- vendored/clipseg/setup.py +30 -0
- vendored/clipseg/training.py +266 -0
|
@@ -0,0 +1,2263 @@
|
|
|
1
|
+
"""
|
|
2
|
+
wild mixture of
|
|
3
|
+
https://github.com/lucidrains/denoising-diffusion-pytorch/blob/7706bdfc6f527f58d33f84b7b522e61e6e3164b3/denoising_diffusion_pytorch/denoising_diffusion_pytorch.py
|
|
4
|
+
https://github.com/openai/improved-diffusion/blob/e94489283bb876ac1477d5dd7709bbbd2d9902ce/improved_diffusion/gaussian_diffusion.py
|
|
5
|
+
https://github.com/CompVis/taming-transformers
|
|
6
|
+
-- merci
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
import torch
|
|
10
|
+
|
|
11
|
+
import torch.nn as nn
|
|
12
|
+
import os
|
|
13
|
+
import numpy as np
|
|
14
|
+
import pytorch_lightning as pl
|
|
15
|
+
from torch.optim.lr_scheduler import LambdaLR
|
|
16
|
+
from einops import rearrange, repeat
|
|
17
|
+
from contextlib import contextmanager
|
|
18
|
+
from functools import partial
|
|
19
|
+
from tqdm import tqdm
|
|
20
|
+
from torchvision.utils import make_grid
|
|
21
|
+
from pytorch_lightning.utilities.distributed import rank_zero_only
|
|
22
|
+
from omegaconf import ListConfig
|
|
23
|
+
import urllib
|
|
24
|
+
|
|
25
|
+
from ldm.util import (
|
|
26
|
+
log_txt_as_img,
|
|
27
|
+
exists,
|
|
28
|
+
default,
|
|
29
|
+
ismap,
|
|
30
|
+
isimage,
|
|
31
|
+
mean_flat,
|
|
32
|
+
count_params,
|
|
33
|
+
instantiate_from_config,
|
|
34
|
+
)
|
|
35
|
+
from ldm.modules.ema import LitEma
|
|
36
|
+
from ldm.modules.distributions.distributions import (
|
|
37
|
+
normal_kl,
|
|
38
|
+
DiagonalGaussianDistribution,
|
|
39
|
+
)
|
|
40
|
+
from ldm.models.autoencoder import (
|
|
41
|
+
VQModelInterface,
|
|
42
|
+
IdentityFirstStage,
|
|
43
|
+
AutoencoderKL,
|
|
44
|
+
)
|
|
45
|
+
from ldm.modules.diffusionmodules.util import (
|
|
46
|
+
make_beta_schedule,
|
|
47
|
+
extract_into_tensor,
|
|
48
|
+
noise_like,
|
|
49
|
+
)
|
|
50
|
+
from ldm.models.diffusion.ddim import DDIMSampler
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
__conditioning_keys__ = {
|
|
54
|
+
'concat': 'c_concat',
|
|
55
|
+
'crossattn': 'c_crossattn',
|
|
56
|
+
'adm': 'y',
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def disabled_train(self, mode=True):
|
|
61
|
+
"""Overwrite model.train with this function to make sure train/eval mode
|
|
62
|
+
does not change anymore."""
|
|
63
|
+
return self
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def uniform_on_device(r1, r2, shape, device):
|
|
67
|
+
return (r1 - r2) * torch.rand(*shape, device=device) + r2
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
class DDPM(pl.LightningModule):
|
|
71
|
+
# classic DDPM with Gaussian diffusion, in image space
|
|
72
|
+
def __init__(
|
|
73
|
+
self,
|
|
74
|
+
unet_config,
|
|
75
|
+
timesteps=1000,
|
|
76
|
+
beta_schedule='linear',
|
|
77
|
+
loss_type='l2',
|
|
78
|
+
ckpt_path=None,
|
|
79
|
+
ignore_keys=[],
|
|
80
|
+
load_only_unet=False,
|
|
81
|
+
monitor='val/loss',
|
|
82
|
+
use_ema=True,
|
|
83
|
+
first_stage_key='image',
|
|
84
|
+
image_size=256,
|
|
85
|
+
channels=3,
|
|
86
|
+
log_every_t=100,
|
|
87
|
+
clip_denoised=True,
|
|
88
|
+
linear_start=1e-4,
|
|
89
|
+
linear_end=2e-2,
|
|
90
|
+
cosine_s=8e-3,
|
|
91
|
+
given_betas=None,
|
|
92
|
+
original_elbo_weight=0.0,
|
|
93
|
+
embedding_reg_weight=0.0,
|
|
94
|
+
v_posterior=0.0, # weight for choosing posterior variance as sigma = (1-v) * beta_tilde + v * beta
|
|
95
|
+
l_simple_weight=1.0,
|
|
96
|
+
conditioning_key=None,
|
|
97
|
+
parameterization='eps', # all assuming fixed variance schedules
|
|
98
|
+
scheduler_config=None,
|
|
99
|
+
use_positional_encodings=False,
|
|
100
|
+
learn_logvar=False,
|
|
101
|
+
logvar_init=0.0,
|
|
102
|
+
):
|
|
103
|
+
super().__init__()
|
|
104
|
+
assert parameterization in [
|
|
105
|
+
'eps',
|
|
106
|
+
'x0',
|
|
107
|
+
], 'currently only supporting "eps" and "x0"'
|
|
108
|
+
self.parameterization = parameterization
|
|
109
|
+
print(
|
|
110
|
+
f' | {self.__class__.__name__}: Running in {self.parameterization}-prediction mode'
|
|
111
|
+
)
|
|
112
|
+
self.cond_stage_model = None
|
|
113
|
+
self.clip_denoised = clip_denoised
|
|
114
|
+
self.log_every_t = log_every_t
|
|
115
|
+
self.first_stage_key = first_stage_key
|
|
116
|
+
self.image_size = image_size # try conv?
|
|
117
|
+
self.channels = channels
|
|
118
|
+
self.use_positional_encodings = use_positional_encodings
|
|
119
|
+
self.model = DiffusionWrapper(unet_config, conditioning_key)
|
|
120
|
+
count_params(self.model, verbose=True)
|
|
121
|
+
self.use_ema = use_ema
|
|
122
|
+
if self.use_ema:
|
|
123
|
+
self.model_ema = LitEma(self.model)
|
|
124
|
+
print(f' | Keeping EMAs of {len(list(self.model_ema.buffers()))}.')
|
|
125
|
+
|
|
126
|
+
self.use_scheduler = scheduler_config is not None
|
|
127
|
+
if self.use_scheduler:
|
|
128
|
+
self.scheduler_config = scheduler_config
|
|
129
|
+
|
|
130
|
+
self.v_posterior = v_posterior
|
|
131
|
+
self.original_elbo_weight = original_elbo_weight
|
|
132
|
+
self.l_simple_weight = l_simple_weight
|
|
133
|
+
self.embedding_reg_weight = embedding_reg_weight
|
|
134
|
+
|
|
135
|
+
if monitor is not None:
|
|
136
|
+
self.monitor = monitor
|
|
137
|
+
if ckpt_path is not None:
|
|
138
|
+
self.init_from_ckpt(
|
|
139
|
+
ckpt_path, ignore_keys=ignore_keys, only_model=load_only_unet
|
|
140
|
+
)
|
|
141
|
+
|
|
142
|
+
self.register_schedule(
|
|
143
|
+
given_betas=given_betas,
|
|
144
|
+
beta_schedule=beta_schedule,
|
|
145
|
+
timesteps=timesteps,
|
|
146
|
+
linear_start=linear_start,
|
|
147
|
+
linear_end=linear_end,
|
|
148
|
+
cosine_s=cosine_s,
|
|
149
|
+
)
|
|
150
|
+
|
|
151
|
+
self.loss_type = loss_type
|
|
152
|
+
|
|
153
|
+
self.learn_logvar = learn_logvar
|
|
154
|
+
self.logvar = torch.full(
|
|
155
|
+
fill_value=logvar_init, size=(self.num_timesteps,)
|
|
156
|
+
)
|
|
157
|
+
if self.learn_logvar:
|
|
158
|
+
self.logvar = nn.Parameter(self.logvar, requires_grad=True)
|
|
159
|
+
|
|
160
|
+
def register_schedule(
|
|
161
|
+
self,
|
|
162
|
+
given_betas=None,
|
|
163
|
+
beta_schedule='linear',
|
|
164
|
+
timesteps=1000,
|
|
165
|
+
linear_start=1e-4,
|
|
166
|
+
linear_end=2e-2,
|
|
167
|
+
cosine_s=8e-3,
|
|
168
|
+
):
|
|
169
|
+
if exists(given_betas):
|
|
170
|
+
betas = given_betas
|
|
171
|
+
else:
|
|
172
|
+
betas = make_beta_schedule(
|
|
173
|
+
beta_schedule,
|
|
174
|
+
timesteps,
|
|
175
|
+
linear_start=linear_start,
|
|
176
|
+
linear_end=linear_end,
|
|
177
|
+
cosine_s=cosine_s,
|
|
178
|
+
)
|
|
179
|
+
alphas = 1.0 - betas
|
|
180
|
+
alphas_cumprod = np.cumprod(alphas, axis=0)
|
|
181
|
+
alphas_cumprod_prev = np.append(1.0, alphas_cumprod[:-1])
|
|
182
|
+
|
|
183
|
+
(timesteps,) = betas.shape
|
|
184
|
+
self.num_timesteps = int(timesteps)
|
|
185
|
+
self.linear_start = linear_start
|
|
186
|
+
self.linear_end = linear_end
|
|
187
|
+
assert (
|
|
188
|
+
alphas_cumprod.shape[0] == self.num_timesteps
|
|
189
|
+
), 'alphas have to be defined for each timestep'
|
|
190
|
+
|
|
191
|
+
to_torch = partial(torch.tensor, dtype=torch.float32)
|
|
192
|
+
|
|
193
|
+
self.register_buffer('betas', to_torch(betas))
|
|
194
|
+
self.register_buffer('alphas_cumprod', to_torch(alphas_cumprod))
|
|
195
|
+
self.register_buffer(
|
|
196
|
+
'alphas_cumprod_prev', to_torch(alphas_cumprod_prev)
|
|
197
|
+
)
|
|
198
|
+
|
|
199
|
+
# calculations for diffusion q(x_t | x_{t-1}) and others
|
|
200
|
+
self.register_buffer(
|
|
201
|
+
'sqrt_alphas_cumprod', to_torch(np.sqrt(alphas_cumprod))
|
|
202
|
+
)
|
|
203
|
+
self.register_buffer(
|
|
204
|
+
'sqrt_one_minus_alphas_cumprod',
|
|
205
|
+
to_torch(np.sqrt(1.0 - alphas_cumprod)),
|
|
206
|
+
)
|
|
207
|
+
self.register_buffer(
|
|
208
|
+
'log_one_minus_alphas_cumprod',
|
|
209
|
+
to_torch(np.log(1.0 - alphas_cumprod)),
|
|
210
|
+
)
|
|
211
|
+
self.register_buffer(
|
|
212
|
+
'sqrt_recip_alphas_cumprod',
|
|
213
|
+
to_torch(np.sqrt(1.0 / alphas_cumprod)),
|
|
214
|
+
)
|
|
215
|
+
self.register_buffer(
|
|
216
|
+
'sqrt_recipm1_alphas_cumprod',
|
|
217
|
+
to_torch(np.sqrt(1.0 / alphas_cumprod - 1)),
|
|
218
|
+
)
|
|
219
|
+
|
|
220
|
+
# calculations for posterior q(x_{t-1} | x_t, x_0)
|
|
221
|
+
posterior_variance = (1 - self.v_posterior) * betas * (
|
|
222
|
+
1.0 - alphas_cumprod_prev
|
|
223
|
+
) / (1.0 - alphas_cumprod) + self.v_posterior * betas
|
|
224
|
+
# above: equal to 1. / (1. / (1. - alpha_cumprod_tm1) + alpha_t / beta_t)
|
|
225
|
+
self.register_buffer(
|
|
226
|
+
'posterior_variance', to_torch(posterior_variance)
|
|
227
|
+
)
|
|
228
|
+
# below: log calculation clipped because the posterior variance is 0 at the beginning of the diffusion chain
|
|
229
|
+
self.register_buffer(
|
|
230
|
+
'posterior_log_variance_clipped',
|
|
231
|
+
to_torch(np.log(np.maximum(posterior_variance, 1e-20))),
|
|
232
|
+
)
|
|
233
|
+
self.register_buffer(
|
|
234
|
+
'posterior_mean_coef1',
|
|
235
|
+
to_torch(
|
|
236
|
+
betas * np.sqrt(alphas_cumprod_prev) / (1.0 - alphas_cumprod)
|
|
237
|
+
),
|
|
238
|
+
)
|
|
239
|
+
self.register_buffer(
|
|
240
|
+
'posterior_mean_coef2',
|
|
241
|
+
to_torch(
|
|
242
|
+
(1.0 - alphas_cumprod_prev)
|
|
243
|
+
* np.sqrt(alphas)
|
|
244
|
+
/ (1.0 - alphas_cumprod)
|
|
245
|
+
),
|
|
246
|
+
)
|
|
247
|
+
|
|
248
|
+
if self.parameterization == 'eps':
|
|
249
|
+
lvlb_weights = self.betas**2 / (
|
|
250
|
+
2
|
|
251
|
+
* self.posterior_variance
|
|
252
|
+
* to_torch(alphas)
|
|
253
|
+
* (1 - self.alphas_cumprod)
|
|
254
|
+
)
|
|
255
|
+
elif self.parameterization == 'x0':
|
|
256
|
+
lvlb_weights = (
|
|
257
|
+
0.5
|
|
258
|
+
* np.sqrt(torch.Tensor(alphas_cumprod))
|
|
259
|
+
/ (2.0 * 1 - torch.Tensor(alphas_cumprod))
|
|
260
|
+
)
|
|
261
|
+
else:
|
|
262
|
+
raise NotImplementedError('mu not supported')
|
|
263
|
+
# TODO how to choose this term
|
|
264
|
+
lvlb_weights[0] = lvlb_weights[1]
|
|
265
|
+
self.register_buffer('lvlb_weights', lvlb_weights, persistent=False)
|
|
266
|
+
assert not torch.isnan(self.lvlb_weights).all()
|
|
267
|
+
|
|
268
|
+
@contextmanager
|
|
269
|
+
def ema_scope(self, context=None):
|
|
270
|
+
if self.use_ema:
|
|
271
|
+
self.model_ema.store(self.model.parameters())
|
|
272
|
+
self.model_ema.copy_to(self.model)
|
|
273
|
+
if context is not None:
|
|
274
|
+
print(f'{context}: Switched to EMA weights')
|
|
275
|
+
try:
|
|
276
|
+
yield None
|
|
277
|
+
finally:
|
|
278
|
+
if self.use_ema:
|
|
279
|
+
self.model_ema.restore(self.model.parameters())
|
|
280
|
+
if context is not None:
|
|
281
|
+
print(f'{context}: Restored training weights')
|
|
282
|
+
|
|
283
|
+
def init_from_ckpt(self, path, ignore_keys=list(), only_model=False):
|
|
284
|
+
sd = torch.load(path, map_location='cpu')
|
|
285
|
+
if 'state_dict' in list(sd.keys()):
|
|
286
|
+
sd = sd['state_dict']
|
|
287
|
+
keys = list(sd.keys())
|
|
288
|
+
for k in keys:
|
|
289
|
+
for ik in ignore_keys:
|
|
290
|
+
if k.startswith(ik):
|
|
291
|
+
print('Deleting key {} from state_dict.'.format(k))
|
|
292
|
+
del sd[k]
|
|
293
|
+
missing, unexpected = (
|
|
294
|
+
self.load_state_dict(sd, strict=False)
|
|
295
|
+
if not only_model
|
|
296
|
+
else self.model.load_state_dict(sd, strict=False)
|
|
297
|
+
)
|
|
298
|
+
print(
|
|
299
|
+
f'Restored from {path} with {len(missing)} missing and {len(unexpected)} unexpected keys'
|
|
300
|
+
)
|
|
301
|
+
if len(missing) > 0:
|
|
302
|
+
print(f'Missing Keys: {missing}')
|
|
303
|
+
if len(unexpected) > 0:
|
|
304
|
+
print(f'Unexpected Keys: {unexpected}')
|
|
305
|
+
|
|
306
|
+
def q_mean_variance(self, x_start, t):
|
|
307
|
+
"""
|
|
308
|
+
Get the distribution q(x_t | x_0).
|
|
309
|
+
:param x_start: the [N x C x ...] tensor of noiseless inputs.
|
|
310
|
+
:param t: the number of diffusion steps (minus 1). Here, 0 means one step.
|
|
311
|
+
:return: A tuple (mean, variance, log_variance), all of x_start's shape.
|
|
312
|
+
"""
|
|
313
|
+
mean = (
|
|
314
|
+
extract_into_tensor(self.sqrt_alphas_cumprod, t, x_start.shape)
|
|
315
|
+
* x_start
|
|
316
|
+
)
|
|
317
|
+
variance = extract_into_tensor(
|
|
318
|
+
1.0 - self.alphas_cumprod, t, x_start.shape
|
|
319
|
+
)
|
|
320
|
+
log_variance = extract_into_tensor(
|
|
321
|
+
self.log_one_minus_alphas_cumprod, t, x_start.shape
|
|
322
|
+
)
|
|
323
|
+
return mean, variance, log_variance
|
|
324
|
+
|
|
325
|
+
def predict_start_from_noise(self, x_t, t, noise):
|
|
326
|
+
return (
|
|
327
|
+
extract_into_tensor(self.sqrt_recip_alphas_cumprod, t, x_t.shape)
|
|
328
|
+
* x_t
|
|
329
|
+
- extract_into_tensor(
|
|
330
|
+
self.sqrt_recipm1_alphas_cumprod, t, x_t.shape
|
|
331
|
+
)
|
|
332
|
+
* noise
|
|
333
|
+
)
|
|
334
|
+
|
|
335
|
+
def q_posterior(self, x_start, x_t, t):
|
|
336
|
+
posterior_mean = (
|
|
337
|
+
extract_into_tensor(self.posterior_mean_coef1, t, x_t.shape)
|
|
338
|
+
* x_start
|
|
339
|
+
+ extract_into_tensor(self.posterior_mean_coef2, t, x_t.shape)
|
|
340
|
+
* x_t
|
|
341
|
+
)
|
|
342
|
+
posterior_variance = extract_into_tensor(
|
|
343
|
+
self.posterior_variance, t, x_t.shape
|
|
344
|
+
)
|
|
345
|
+
posterior_log_variance_clipped = extract_into_tensor(
|
|
346
|
+
self.posterior_log_variance_clipped, t, x_t.shape
|
|
347
|
+
)
|
|
348
|
+
return (
|
|
349
|
+
posterior_mean,
|
|
350
|
+
posterior_variance,
|
|
351
|
+
posterior_log_variance_clipped,
|
|
352
|
+
)
|
|
353
|
+
|
|
354
|
+
def p_mean_variance(self, x, t, clip_denoised: bool):
|
|
355
|
+
model_out = self.model(x, t)
|
|
356
|
+
if self.parameterization == 'eps':
|
|
357
|
+
x_recon = self.predict_start_from_noise(x, t=t, noise=model_out)
|
|
358
|
+
elif self.parameterization == 'x0':
|
|
359
|
+
x_recon = model_out
|
|
360
|
+
if clip_denoised:
|
|
361
|
+
x_recon.clamp_(-1.0, 1.0)
|
|
362
|
+
|
|
363
|
+
(
|
|
364
|
+
model_mean,
|
|
365
|
+
posterior_variance,
|
|
366
|
+
posterior_log_variance,
|
|
367
|
+
) = self.q_posterior(x_start=x_recon, x_t=x, t=t)
|
|
368
|
+
return model_mean, posterior_variance, posterior_log_variance
|
|
369
|
+
|
|
370
|
+
@torch.no_grad()
|
|
371
|
+
def p_sample(self, x, t, clip_denoised=True, repeat_noise=False):
|
|
372
|
+
b, *_, device = *x.shape, x.device
|
|
373
|
+
model_mean, _, model_log_variance = self.p_mean_variance(
|
|
374
|
+
x=x, t=t, clip_denoised=clip_denoised
|
|
375
|
+
)
|
|
376
|
+
noise = noise_like(x.shape, device, repeat_noise)
|
|
377
|
+
# no noise when t == 0
|
|
378
|
+
nonzero_mask = (1 - (t == 0).float()).reshape(
|
|
379
|
+
b, *((1,) * (len(x.shape) - 1))
|
|
380
|
+
)
|
|
381
|
+
return (
|
|
382
|
+
model_mean
|
|
383
|
+
+ nonzero_mask * (0.5 * model_log_variance).exp() * noise
|
|
384
|
+
)
|
|
385
|
+
|
|
386
|
+
@torch.no_grad()
|
|
387
|
+
def p_sample_loop(self, shape, return_intermediates=False):
|
|
388
|
+
device = self.betas.device
|
|
389
|
+
b = shape[0]
|
|
390
|
+
img = torch.randn(shape, device=device)
|
|
391
|
+
intermediates = [img]
|
|
392
|
+
for i in tqdm(
|
|
393
|
+
reversed(range(0, self.num_timesteps)),
|
|
394
|
+
desc='Sampling t',
|
|
395
|
+
total=self.num_timesteps,
|
|
396
|
+
dynamic_ncols=True,
|
|
397
|
+
):
|
|
398
|
+
img = self.p_sample(
|
|
399
|
+
img,
|
|
400
|
+
torch.full((b,), i, device=device, dtype=torch.long),
|
|
401
|
+
clip_denoised=self.clip_denoised,
|
|
402
|
+
)
|
|
403
|
+
if i % self.log_every_t == 0 or i == self.num_timesteps - 1:
|
|
404
|
+
intermediates.append(img)
|
|
405
|
+
if return_intermediates:
|
|
406
|
+
return img, intermediates
|
|
407
|
+
return img
|
|
408
|
+
|
|
409
|
+
@torch.no_grad()
|
|
410
|
+
def sample(self, batch_size=16, return_intermediates=False):
|
|
411
|
+
image_size = self.image_size
|
|
412
|
+
channels = self.channels
|
|
413
|
+
return self.p_sample_loop(
|
|
414
|
+
(batch_size, channels, image_size, image_size),
|
|
415
|
+
return_intermediates=return_intermediates,
|
|
416
|
+
)
|
|
417
|
+
|
|
418
|
+
def q_sample(self, x_start, t, noise=None):
|
|
419
|
+
noise = default(noise, lambda: torch.randn_like(x_start))
|
|
420
|
+
return (
|
|
421
|
+
extract_into_tensor(self.sqrt_alphas_cumprod, t, x_start.shape)
|
|
422
|
+
* x_start
|
|
423
|
+
+ extract_into_tensor(
|
|
424
|
+
self.sqrt_one_minus_alphas_cumprod, t, x_start.shape
|
|
425
|
+
)
|
|
426
|
+
* noise
|
|
427
|
+
)
|
|
428
|
+
|
|
429
|
+
def get_loss(self, pred, target, mean=True):
|
|
430
|
+
if self.loss_type == 'l1':
|
|
431
|
+
loss = (target - pred).abs()
|
|
432
|
+
if mean:
|
|
433
|
+
loss = loss.mean()
|
|
434
|
+
elif self.loss_type == 'l2':
|
|
435
|
+
if mean:
|
|
436
|
+
loss = torch.nn.functional.mse_loss(target, pred)
|
|
437
|
+
else:
|
|
438
|
+
loss = torch.nn.functional.mse_loss(
|
|
439
|
+
target, pred, reduction='none'
|
|
440
|
+
)
|
|
441
|
+
else:
|
|
442
|
+
raise NotImplementedError("unknown loss type '{loss_type}'")
|
|
443
|
+
|
|
444
|
+
return loss
|
|
445
|
+
|
|
446
|
+
def p_losses(self, x_start, t, noise=None):
|
|
447
|
+
noise = default(noise, lambda: torch.randn_like(x_start))
|
|
448
|
+
x_noisy = self.q_sample(x_start=x_start, t=t, noise=noise)
|
|
449
|
+
model_out = self.model(x_noisy, t)
|
|
450
|
+
|
|
451
|
+
loss_dict = {}
|
|
452
|
+
if self.parameterization == 'eps':
|
|
453
|
+
target = noise
|
|
454
|
+
elif self.parameterization == 'x0':
|
|
455
|
+
target = x_start
|
|
456
|
+
else:
|
|
457
|
+
raise NotImplementedError(
|
|
458
|
+
f'Paramterization {self.parameterization} not yet supported'
|
|
459
|
+
)
|
|
460
|
+
|
|
461
|
+
loss = self.get_loss(model_out, target, mean=False).mean(dim=[1, 2, 3])
|
|
462
|
+
|
|
463
|
+
log_prefix = 'train' if self.training else 'val'
|
|
464
|
+
|
|
465
|
+
loss_dict.update({f'{log_prefix}/loss_simple': loss.mean()})
|
|
466
|
+
loss_simple = loss.mean() * self.l_simple_weight
|
|
467
|
+
|
|
468
|
+
loss_vlb = (self.lvlb_weights[t] * loss).mean()
|
|
469
|
+
loss_dict.update({f'{log_prefix}/loss_vlb': loss_vlb})
|
|
470
|
+
|
|
471
|
+
loss = loss_simple + self.original_elbo_weight * loss_vlb
|
|
472
|
+
|
|
473
|
+
loss_dict.update({f'{log_prefix}/loss': loss})
|
|
474
|
+
|
|
475
|
+
return loss, loss_dict
|
|
476
|
+
|
|
477
|
+
def forward(self, x, *args, **kwargs):
|
|
478
|
+
# b, c, h, w, device, img_size, = *x.shape, x.device, self.image_size
|
|
479
|
+
# assert h == img_size and w == img_size, f'height and width of image must be {img_size}'
|
|
480
|
+
t = torch.randint(
|
|
481
|
+
0, self.num_timesteps, (x.shape[0],), device=self.device
|
|
482
|
+
).long()
|
|
483
|
+
return self.p_losses(x, t, *args, **kwargs)
|
|
484
|
+
|
|
485
|
+
def get_input(self, batch, k):
|
|
486
|
+
x = batch[k]
|
|
487
|
+
if len(x.shape) == 3:
|
|
488
|
+
x = x[..., None]
|
|
489
|
+
x = rearrange(x, 'b h w c -> b c h w')
|
|
490
|
+
x = x.to(memory_format=torch.contiguous_format).float()
|
|
491
|
+
return x
|
|
492
|
+
|
|
493
|
+
def shared_step(self, batch):
|
|
494
|
+
x = self.get_input(batch, self.first_stage_key)
|
|
495
|
+
loss, loss_dict = self(x)
|
|
496
|
+
return loss, loss_dict
|
|
497
|
+
|
|
498
|
+
def training_step(self, batch, batch_idx):
|
|
499
|
+
loss, loss_dict = self.shared_step(batch)
|
|
500
|
+
|
|
501
|
+
self.log_dict(
|
|
502
|
+
loss_dict, prog_bar=True, logger=True, on_step=True, on_epoch=True
|
|
503
|
+
)
|
|
504
|
+
|
|
505
|
+
self.log(
|
|
506
|
+
'global_step',
|
|
507
|
+
self.global_step,
|
|
508
|
+
prog_bar=True,
|
|
509
|
+
logger=True,
|
|
510
|
+
on_step=True,
|
|
511
|
+
on_epoch=False,
|
|
512
|
+
)
|
|
513
|
+
|
|
514
|
+
if self.use_scheduler:
|
|
515
|
+
lr = self.optimizers().param_groups[0]['lr']
|
|
516
|
+
self.log(
|
|
517
|
+
'lr_abs',
|
|
518
|
+
lr,
|
|
519
|
+
prog_bar=True,
|
|
520
|
+
logger=True,
|
|
521
|
+
on_step=True,
|
|
522
|
+
on_epoch=False,
|
|
523
|
+
)
|
|
524
|
+
|
|
525
|
+
return loss
|
|
526
|
+
|
|
527
|
+
@torch.no_grad()
|
|
528
|
+
def validation_step(self, batch, batch_idx):
|
|
529
|
+
_, loss_dict_no_ema = self.shared_step(batch)
|
|
530
|
+
with self.ema_scope():
|
|
531
|
+
_, loss_dict_ema = self.shared_step(batch)
|
|
532
|
+
loss_dict_ema = {
|
|
533
|
+
key + '_ema': loss_dict_ema[key] for key in loss_dict_ema
|
|
534
|
+
}
|
|
535
|
+
self.log_dict(
|
|
536
|
+
loss_dict_no_ema,
|
|
537
|
+
prog_bar=False,
|
|
538
|
+
logger=True,
|
|
539
|
+
on_step=False,
|
|
540
|
+
on_epoch=True,
|
|
541
|
+
)
|
|
542
|
+
self.log_dict(
|
|
543
|
+
loss_dict_ema,
|
|
544
|
+
prog_bar=False,
|
|
545
|
+
logger=True,
|
|
546
|
+
on_step=False,
|
|
547
|
+
on_epoch=True,
|
|
548
|
+
)
|
|
549
|
+
|
|
550
|
+
def on_train_batch_end(self, *args, **kwargs):
|
|
551
|
+
if self.use_ema:
|
|
552
|
+
self.model_ema(self.model)
|
|
553
|
+
|
|
554
|
+
def _get_rows_from_list(self, samples):
|
|
555
|
+
n_imgs_per_row = len(samples)
|
|
556
|
+
denoise_grid = rearrange(samples, 'n b c h w -> b n c h w')
|
|
557
|
+
denoise_grid = rearrange(denoise_grid, 'b n c h w -> (b n) c h w')
|
|
558
|
+
denoise_grid = make_grid(denoise_grid, nrow=n_imgs_per_row)
|
|
559
|
+
return denoise_grid
|
|
560
|
+
|
|
561
|
+
@torch.no_grad()
|
|
562
|
+
def log_images(
|
|
563
|
+
self, batch, N=8, n_row=2, sample=True, return_keys=None, **kwargs
|
|
564
|
+
):
|
|
565
|
+
log = dict()
|
|
566
|
+
x = self.get_input(batch, self.first_stage_key)
|
|
567
|
+
N = min(x.shape[0], N)
|
|
568
|
+
n_row = min(x.shape[0], n_row)
|
|
569
|
+
x = x.to(self.device)[:N]
|
|
570
|
+
log['inputs'] = x
|
|
571
|
+
|
|
572
|
+
# get diffusion row
|
|
573
|
+
diffusion_row = list()
|
|
574
|
+
x_start = x[:n_row]
|
|
575
|
+
|
|
576
|
+
for t in range(self.num_timesteps):
|
|
577
|
+
if t % self.log_every_t == 0 or t == self.num_timesteps - 1:
|
|
578
|
+
t = repeat(torch.tensor([t]), '1 -> b', b=n_row)
|
|
579
|
+
t = t.to(self.device).long()
|
|
580
|
+
noise = torch.randn_like(x_start)
|
|
581
|
+
x_noisy = self.q_sample(x_start=x_start, t=t, noise=noise)
|
|
582
|
+
diffusion_row.append(x_noisy)
|
|
583
|
+
|
|
584
|
+
log['diffusion_row'] = self._get_rows_from_list(diffusion_row)
|
|
585
|
+
|
|
586
|
+
if sample:
|
|
587
|
+
# get denoise row
|
|
588
|
+
with self.ema_scope('Plotting'):
|
|
589
|
+
samples, denoise_row = self.sample(
|
|
590
|
+
batch_size=N, return_intermediates=True
|
|
591
|
+
)
|
|
592
|
+
|
|
593
|
+
log['samples'] = samples
|
|
594
|
+
log['denoise_row'] = self._get_rows_from_list(denoise_row)
|
|
595
|
+
|
|
596
|
+
if return_keys:
|
|
597
|
+
if np.intersect1d(list(log.keys()), return_keys).shape[0] == 0:
|
|
598
|
+
return log
|
|
599
|
+
else:
|
|
600
|
+
return {key: log[key] for key in return_keys}
|
|
601
|
+
return log
|
|
602
|
+
|
|
603
|
+
def configure_optimizers(self):
|
|
604
|
+
lr = self.learning_rate
|
|
605
|
+
params = list(self.model.parameters())
|
|
606
|
+
if self.learn_logvar:
|
|
607
|
+
params = params + [self.logvar]
|
|
608
|
+
opt = torch.optim.AdamW(params, lr=lr)
|
|
609
|
+
return opt
|
|
610
|
+
|
|
611
|
+
|
|
612
|
+
class LatentDiffusion(DDPM):
|
|
613
|
+
"""main class"""
|
|
614
|
+
|
|
615
|
+
def __init__(
|
|
616
|
+
self,
|
|
617
|
+
first_stage_config,
|
|
618
|
+
cond_stage_config,
|
|
619
|
+
personalization_config,
|
|
620
|
+
num_timesteps_cond=None,
|
|
621
|
+
cond_stage_key='image',
|
|
622
|
+
cond_stage_trainable=False,
|
|
623
|
+
concat_mode=True,
|
|
624
|
+
cond_stage_forward=None,
|
|
625
|
+
conditioning_key=None,
|
|
626
|
+
scale_factor=1.0,
|
|
627
|
+
scale_by_std=False,
|
|
628
|
+
*args,
|
|
629
|
+
**kwargs,
|
|
630
|
+
):
|
|
631
|
+
|
|
632
|
+
self.num_timesteps_cond = default(num_timesteps_cond, 1)
|
|
633
|
+
self.scale_by_std = scale_by_std
|
|
634
|
+
assert self.num_timesteps_cond <= kwargs['timesteps']
|
|
635
|
+
# for backwards compatibility after implementation of DiffusionWrapper
|
|
636
|
+
if conditioning_key is None:
|
|
637
|
+
conditioning_key = 'concat' if concat_mode else 'crossattn'
|
|
638
|
+
if cond_stage_config == '__is_unconditional__':
|
|
639
|
+
conditioning_key = None
|
|
640
|
+
ckpt_path = kwargs.pop('ckpt_path', None)
|
|
641
|
+
ignore_keys = kwargs.pop('ignore_keys', [])
|
|
642
|
+
super().__init__(conditioning_key=conditioning_key, *args, **kwargs)
|
|
643
|
+
self.concat_mode = concat_mode
|
|
644
|
+
self.cond_stage_trainable = cond_stage_trainable
|
|
645
|
+
self.cond_stage_key = cond_stage_key
|
|
646
|
+
|
|
647
|
+
try:
|
|
648
|
+
self.num_downs = (
|
|
649
|
+
len(first_stage_config.params.ddconfig.ch_mult) - 1
|
|
650
|
+
)
|
|
651
|
+
except:
|
|
652
|
+
self.num_downs = 0
|
|
653
|
+
if not scale_by_std:
|
|
654
|
+
self.scale_factor = scale_factor
|
|
655
|
+
else:
|
|
656
|
+
self.register_buffer('scale_factor', torch.tensor(scale_factor))
|
|
657
|
+
self.instantiate_first_stage(first_stage_config)
|
|
658
|
+
self.instantiate_cond_stage(cond_stage_config)
|
|
659
|
+
|
|
660
|
+
self.cond_stage_forward = cond_stage_forward
|
|
661
|
+
self.clip_denoised = False
|
|
662
|
+
self.bbox_tokenizer = None
|
|
663
|
+
|
|
664
|
+
self.restarted_from_ckpt = False
|
|
665
|
+
if ckpt_path is not None:
|
|
666
|
+
self.init_from_ckpt(ckpt_path, ignore_keys)
|
|
667
|
+
self.restarted_from_ckpt = True
|
|
668
|
+
|
|
669
|
+
self.cond_stage_model.train = disabled_train
|
|
670
|
+
for param in self.cond_stage_model.parameters():
|
|
671
|
+
param.requires_grad = False
|
|
672
|
+
|
|
673
|
+
self.model.eval()
|
|
674
|
+
self.model.train = disabled_train
|
|
675
|
+
for param in self.model.parameters():
|
|
676
|
+
param.requires_grad = False
|
|
677
|
+
|
|
678
|
+
self.embedding_manager = self.instantiate_embedding_manager(
|
|
679
|
+
personalization_config, self.cond_stage_model
|
|
680
|
+
)
|
|
681
|
+
|
|
682
|
+
self.emb_ckpt_counter = 0
|
|
683
|
+
|
|
684
|
+
# if self.embedding_manager.is_clip:
|
|
685
|
+
# self.cond_stage_model.update_embedding_func(self.embedding_manager)
|
|
686
|
+
|
|
687
|
+
for param in self.embedding_manager.embedding_parameters():
|
|
688
|
+
param.requires_grad = True
|
|
689
|
+
|
|
690
|
+
def make_cond_schedule(
|
|
691
|
+
self,
|
|
692
|
+
):
|
|
693
|
+
self.cond_ids = torch.full(
|
|
694
|
+
size=(self.num_timesteps,),
|
|
695
|
+
fill_value=self.num_timesteps - 1,
|
|
696
|
+
dtype=torch.long,
|
|
697
|
+
)
|
|
698
|
+
ids = torch.round(
|
|
699
|
+
torch.linspace(0, self.num_timesteps - 1, self.num_timesteps_cond)
|
|
700
|
+
).long()
|
|
701
|
+
self.cond_ids[: self.num_timesteps_cond] = ids
|
|
702
|
+
|
|
703
|
+
@rank_zero_only
|
|
704
|
+
@torch.no_grad()
|
|
705
|
+
def on_train_batch_start(self, batch, batch_idx, dataloader_idx=None):
|
|
706
|
+
# only for very first batch
|
|
707
|
+
if (
|
|
708
|
+
self.scale_by_std
|
|
709
|
+
and self.current_epoch == 0
|
|
710
|
+
and self.global_step == 0
|
|
711
|
+
and batch_idx == 0
|
|
712
|
+
and not self.restarted_from_ckpt
|
|
713
|
+
):
|
|
714
|
+
assert (
|
|
715
|
+
self.scale_factor == 1.0
|
|
716
|
+
), 'rather not use custom rescaling and std-rescaling simultaneously'
|
|
717
|
+
# set rescale weight to 1./std of encodings
|
|
718
|
+
print('### USING STD-RESCALING ###')
|
|
719
|
+
x = super().get_input(batch, self.first_stage_key)
|
|
720
|
+
x = x.to(self.device)
|
|
721
|
+
encoder_posterior = self.encode_first_stage(x)
|
|
722
|
+
z = self.get_first_stage_encoding(encoder_posterior).detach()
|
|
723
|
+
del self.scale_factor
|
|
724
|
+
self.register_buffer('scale_factor', 1.0 / z.flatten().std())
|
|
725
|
+
print(f'setting self.scale_factor to {self.scale_factor}')
|
|
726
|
+
print('### USING STD-RESCALING ###')
|
|
727
|
+
|
|
728
|
+
def register_schedule(
|
|
729
|
+
self,
|
|
730
|
+
given_betas=None,
|
|
731
|
+
beta_schedule='linear',
|
|
732
|
+
timesteps=1000,
|
|
733
|
+
linear_start=1e-4,
|
|
734
|
+
linear_end=2e-2,
|
|
735
|
+
cosine_s=8e-3,
|
|
736
|
+
):
|
|
737
|
+
super().register_schedule(
|
|
738
|
+
given_betas,
|
|
739
|
+
beta_schedule,
|
|
740
|
+
timesteps,
|
|
741
|
+
linear_start,
|
|
742
|
+
linear_end,
|
|
743
|
+
cosine_s,
|
|
744
|
+
)
|
|
745
|
+
|
|
746
|
+
self.shorten_cond_schedule = self.num_timesteps_cond > 1
|
|
747
|
+
if self.shorten_cond_schedule:
|
|
748
|
+
self.make_cond_schedule()
|
|
749
|
+
|
|
750
|
+
def instantiate_first_stage(self, config):
|
|
751
|
+
model = instantiate_from_config(config)
|
|
752
|
+
self.first_stage_model = model.eval()
|
|
753
|
+
self.first_stage_model.train = disabled_train
|
|
754
|
+
for param in self.first_stage_model.parameters():
|
|
755
|
+
param.requires_grad = False
|
|
756
|
+
|
|
757
|
+
def instantiate_cond_stage(self, config):
|
|
758
|
+
if not self.cond_stage_trainable:
|
|
759
|
+
if config == '__is_first_stage__':
|
|
760
|
+
print('Using first stage also as cond stage.')
|
|
761
|
+
self.cond_stage_model = self.first_stage_model
|
|
762
|
+
elif config == '__is_unconditional__':
|
|
763
|
+
print(
|
|
764
|
+
f'Training {self.__class__.__name__} as an unconditional model.'
|
|
765
|
+
)
|
|
766
|
+
self.cond_stage_model = None
|
|
767
|
+
# self.be_unconditional = True
|
|
768
|
+
else:
|
|
769
|
+
model = instantiate_from_config(config)
|
|
770
|
+
self.cond_stage_model = model.eval()
|
|
771
|
+
self.cond_stage_model.train = disabled_train
|
|
772
|
+
for param in self.cond_stage_model.parameters():
|
|
773
|
+
param.requires_grad = False
|
|
774
|
+
else:
|
|
775
|
+
assert config != '__is_first_stage__'
|
|
776
|
+
assert config != '__is_unconditional__'
|
|
777
|
+
try:
|
|
778
|
+
model = instantiate_from_config(config)
|
|
779
|
+
except urllib.error.URLError:
|
|
780
|
+
raise SystemExit(
|
|
781
|
+
"* Couldn't load a dependency. Try running scripts/preload_models.py from an internet-conected machine."
|
|
782
|
+
)
|
|
783
|
+
self.cond_stage_model = model
|
|
784
|
+
|
|
785
|
+
def instantiate_embedding_manager(self, config, embedder):
|
|
786
|
+
model = instantiate_from_config(config, embedder=embedder)
|
|
787
|
+
|
|
788
|
+
if config.params.get(
|
|
789
|
+
'embedding_manager_ckpt', None
|
|
790
|
+
): # do not load if missing OR empty string
|
|
791
|
+
model.load(config.params.embedding_manager_ckpt)
|
|
792
|
+
|
|
793
|
+
return model
|
|
794
|
+
|
|
795
|
+
def _get_denoise_row_from_list(
|
|
796
|
+
self, samples, desc='', force_no_decoder_quantization=False
|
|
797
|
+
):
|
|
798
|
+
denoise_row = []
|
|
799
|
+
for zd in tqdm(samples, desc=desc):
|
|
800
|
+
denoise_row.append(
|
|
801
|
+
self.decode_first_stage(
|
|
802
|
+
zd.to(self.device),
|
|
803
|
+
force_not_quantize=force_no_decoder_quantization,
|
|
804
|
+
)
|
|
805
|
+
)
|
|
806
|
+
n_imgs_per_row = len(denoise_row)
|
|
807
|
+
denoise_row = torch.stack(denoise_row) # n_log_step, n_row, C, H, W
|
|
808
|
+
denoise_grid = rearrange(denoise_row, 'n b c h w -> b n c h w')
|
|
809
|
+
denoise_grid = rearrange(denoise_grid, 'b n c h w -> (b n) c h w')
|
|
810
|
+
denoise_grid = make_grid(denoise_grid, nrow=n_imgs_per_row)
|
|
811
|
+
return denoise_grid
|
|
812
|
+
|
|
813
|
+
def get_first_stage_encoding(self, encoder_posterior):
|
|
814
|
+
if isinstance(encoder_posterior, DiagonalGaussianDistribution):
|
|
815
|
+
z = encoder_posterior.sample()
|
|
816
|
+
elif isinstance(encoder_posterior, torch.Tensor):
|
|
817
|
+
z = encoder_posterior
|
|
818
|
+
else:
|
|
819
|
+
raise NotImplementedError(
|
|
820
|
+
f"encoder_posterior of type '{type(encoder_posterior)}' not yet implemented"
|
|
821
|
+
)
|
|
822
|
+
return self.scale_factor * z
|
|
823
|
+
|
|
824
|
+
def get_learned_conditioning(self, c, **kwargs):
|
|
825
|
+
if self.cond_stage_forward is None:
|
|
826
|
+
if hasattr(self.cond_stage_model, 'encode') and callable(
|
|
827
|
+
self.cond_stage_model.encode
|
|
828
|
+
):
|
|
829
|
+
c = self.cond_stage_model.encode(
|
|
830
|
+
c, embedding_manager=self.embedding_manager,**kwargs
|
|
831
|
+
)
|
|
832
|
+
if isinstance(c, DiagonalGaussianDistribution):
|
|
833
|
+
c = c.mode()
|
|
834
|
+
else:
|
|
835
|
+
c = self.cond_stage_model(c, **kwargs)
|
|
836
|
+
else:
|
|
837
|
+
assert hasattr(self.cond_stage_model, self.cond_stage_forward)
|
|
838
|
+
c = getattr(self.cond_stage_model, self.cond_stage_forward)(c, **kwargs)
|
|
839
|
+
return c
|
|
840
|
+
|
|
841
|
+
def meshgrid(self, h, w):
|
|
842
|
+
y = torch.arange(0, h).view(h, 1, 1).repeat(1, w, 1)
|
|
843
|
+
x = torch.arange(0, w).view(1, w, 1).repeat(h, 1, 1)
|
|
844
|
+
|
|
845
|
+
arr = torch.cat([y, x], dim=-1)
|
|
846
|
+
return arr
|
|
847
|
+
|
|
848
|
+
def delta_border(self, h, w):
|
|
849
|
+
"""
|
|
850
|
+
:param h: height
|
|
851
|
+
:param w: width
|
|
852
|
+
:return: normalized distance to image border,
|
|
853
|
+
wtith min distance = 0 at border and max dist = 0.5 at image center
|
|
854
|
+
"""
|
|
855
|
+
lower_right_corner = torch.tensor([h - 1, w - 1]).view(1, 1, 2)
|
|
856
|
+
arr = self.meshgrid(h, w) / lower_right_corner
|
|
857
|
+
dist_left_up = torch.min(arr, dim=-1, keepdims=True)[0]
|
|
858
|
+
dist_right_down = torch.min(1 - arr, dim=-1, keepdims=True)[0]
|
|
859
|
+
edge_dist = torch.min(
|
|
860
|
+
torch.cat([dist_left_up, dist_right_down], dim=-1), dim=-1
|
|
861
|
+
)[0]
|
|
862
|
+
return edge_dist
|
|
863
|
+
|
|
864
|
+
def get_weighting(self, h, w, Ly, Lx, device):
|
|
865
|
+
weighting = self.delta_border(h, w)
|
|
866
|
+
weighting = torch.clip(
|
|
867
|
+
weighting,
|
|
868
|
+
self.split_input_params['clip_min_weight'],
|
|
869
|
+
self.split_input_params['clip_max_weight'],
|
|
870
|
+
)
|
|
871
|
+
weighting = (
|
|
872
|
+
weighting.view(1, h * w, 1).repeat(1, 1, Ly * Lx).to(device)
|
|
873
|
+
)
|
|
874
|
+
|
|
875
|
+
if self.split_input_params['tie_braker']:
|
|
876
|
+
L_weighting = self.delta_border(Ly, Lx)
|
|
877
|
+
L_weighting = torch.clip(
|
|
878
|
+
L_weighting,
|
|
879
|
+
self.split_input_params['clip_min_tie_weight'],
|
|
880
|
+
self.split_input_params['clip_max_tie_weight'],
|
|
881
|
+
)
|
|
882
|
+
|
|
883
|
+
L_weighting = L_weighting.view(1, 1, Ly * Lx).to(device)
|
|
884
|
+
weighting = weighting * L_weighting
|
|
885
|
+
return weighting
|
|
886
|
+
|
|
887
|
+
def get_fold_unfold(
|
|
888
|
+
self, x, kernel_size, stride, uf=1, df=1
|
|
889
|
+
): # todo load once not every time, shorten code
|
|
890
|
+
"""
|
|
891
|
+
:param x: img of size (bs, c, h, w)
|
|
892
|
+
:return: n img crops of size (n, bs, c, kernel_size[0], kernel_size[1])
|
|
893
|
+
"""
|
|
894
|
+
bs, nc, h, w = x.shape
|
|
895
|
+
|
|
896
|
+
# number of crops in image
|
|
897
|
+
Ly = (h - kernel_size[0]) // stride[0] + 1
|
|
898
|
+
Lx = (w - kernel_size[1]) // stride[1] + 1
|
|
899
|
+
|
|
900
|
+
if uf == 1 and df == 1:
|
|
901
|
+
fold_params = dict(
|
|
902
|
+
kernel_size=kernel_size, dilation=1, padding=0, stride=stride
|
|
903
|
+
)
|
|
904
|
+
unfold = torch.nn.Unfold(**fold_params)
|
|
905
|
+
|
|
906
|
+
fold = torch.nn.Fold(output_size=x.shape[2:], **fold_params)
|
|
907
|
+
|
|
908
|
+
weighting = self.get_weighting(
|
|
909
|
+
kernel_size[0], kernel_size[1], Ly, Lx, x.device
|
|
910
|
+
).to(x.dtype)
|
|
911
|
+
normalization = fold(weighting).view(
|
|
912
|
+
1, 1, h, w
|
|
913
|
+
) # normalizes the overlap
|
|
914
|
+
weighting = weighting.view(
|
|
915
|
+
(1, 1, kernel_size[0], kernel_size[1], Ly * Lx)
|
|
916
|
+
)
|
|
917
|
+
|
|
918
|
+
elif uf > 1 and df == 1:
|
|
919
|
+
fold_params = dict(
|
|
920
|
+
kernel_size=kernel_size, dilation=1, padding=0, stride=stride
|
|
921
|
+
)
|
|
922
|
+
unfold = torch.nn.Unfold(**fold_params)
|
|
923
|
+
|
|
924
|
+
fold_params2 = dict(
|
|
925
|
+
kernel_size=(kernel_size[0] * uf, kernel_size[0] * uf),
|
|
926
|
+
dilation=1,
|
|
927
|
+
padding=0,
|
|
928
|
+
stride=(stride[0] * uf, stride[1] * uf),
|
|
929
|
+
)
|
|
930
|
+
fold = torch.nn.Fold(
|
|
931
|
+
output_size=(x.shape[2] * uf, x.shape[3] * uf), **fold_params2
|
|
932
|
+
)
|
|
933
|
+
|
|
934
|
+
weighting = self.get_weighting(
|
|
935
|
+
kernel_size[0] * uf, kernel_size[1] * uf, Ly, Lx, x.device
|
|
936
|
+
).to(x.dtype)
|
|
937
|
+
normalization = fold(weighting).view(
|
|
938
|
+
1, 1, h * uf, w * uf
|
|
939
|
+
) # normalizes the overlap
|
|
940
|
+
weighting = weighting.view(
|
|
941
|
+
(1, 1, kernel_size[0] * uf, kernel_size[1] * uf, Ly * Lx)
|
|
942
|
+
)
|
|
943
|
+
|
|
944
|
+
elif df > 1 and uf == 1:
|
|
945
|
+
fold_params = dict(
|
|
946
|
+
kernel_size=kernel_size, dilation=1, padding=0, stride=stride
|
|
947
|
+
)
|
|
948
|
+
unfold = torch.nn.Unfold(**fold_params)
|
|
949
|
+
|
|
950
|
+
fold_params2 = dict(
|
|
951
|
+
kernel_size=(kernel_size[0] // df, kernel_size[0] // df),
|
|
952
|
+
dilation=1,
|
|
953
|
+
padding=0,
|
|
954
|
+
stride=(stride[0] // df, stride[1] // df),
|
|
955
|
+
)
|
|
956
|
+
fold = torch.nn.Fold(
|
|
957
|
+
output_size=(x.shape[2] // df, x.shape[3] // df),
|
|
958
|
+
**fold_params2,
|
|
959
|
+
)
|
|
960
|
+
|
|
961
|
+
weighting = self.get_weighting(
|
|
962
|
+
kernel_size[0] // df, kernel_size[1] // df, Ly, Lx, x.device
|
|
963
|
+
).to(x.dtype)
|
|
964
|
+
normalization = fold(weighting).view(
|
|
965
|
+
1, 1, h // df, w // df
|
|
966
|
+
) # normalizes the overlap
|
|
967
|
+
weighting = weighting.view(
|
|
968
|
+
(1, 1, kernel_size[0] // df, kernel_size[1] // df, Ly * Lx)
|
|
969
|
+
)
|
|
970
|
+
|
|
971
|
+
else:
|
|
972
|
+
raise NotImplementedError
|
|
973
|
+
|
|
974
|
+
return fold, unfold, normalization, weighting
|
|
975
|
+
|
|
976
|
+
@torch.no_grad()
|
|
977
|
+
def get_input(
|
|
978
|
+
self,
|
|
979
|
+
batch,
|
|
980
|
+
k,
|
|
981
|
+
return_first_stage_outputs=False,
|
|
982
|
+
force_c_encode=False,
|
|
983
|
+
cond_key=None,
|
|
984
|
+
return_original_cond=False,
|
|
985
|
+
bs=None,
|
|
986
|
+
):
|
|
987
|
+
x = super().get_input(batch, k)
|
|
988
|
+
if bs is not None:
|
|
989
|
+
x = x[:bs]
|
|
990
|
+
x = x.to(self.device)
|
|
991
|
+
encoder_posterior = self.encode_first_stage(x)
|
|
992
|
+
z = self.get_first_stage_encoding(encoder_posterior).detach()
|
|
993
|
+
|
|
994
|
+
if self.model.conditioning_key is not None:
|
|
995
|
+
if cond_key is None:
|
|
996
|
+
cond_key = self.cond_stage_key
|
|
997
|
+
if cond_key != self.first_stage_key:
|
|
998
|
+
if cond_key in ['caption', 'coordinates_bbox']:
|
|
999
|
+
xc = batch[cond_key]
|
|
1000
|
+
elif cond_key == 'class_label':
|
|
1001
|
+
xc = batch
|
|
1002
|
+
else:
|
|
1003
|
+
xc = super().get_input(batch, cond_key).to(self.device)
|
|
1004
|
+
else:
|
|
1005
|
+
xc = x
|
|
1006
|
+
if not self.cond_stage_trainable or force_c_encode:
|
|
1007
|
+
if isinstance(xc, dict) or isinstance(xc, list):
|
|
1008
|
+
# import pudb; pudb.set_trace()
|
|
1009
|
+
c = self.get_learned_conditioning(xc)
|
|
1010
|
+
else:
|
|
1011
|
+
c = self.get_learned_conditioning(xc.to(self.device))
|
|
1012
|
+
else:
|
|
1013
|
+
c = xc
|
|
1014
|
+
if bs is not None:
|
|
1015
|
+
c = c[:bs]
|
|
1016
|
+
|
|
1017
|
+
if self.use_positional_encodings:
|
|
1018
|
+
pos_x, pos_y = self.compute_latent_shifts(batch)
|
|
1019
|
+
ckey = __conditioning_keys__[self.model.conditioning_key]
|
|
1020
|
+
c = {ckey: c, 'pos_x': pos_x, 'pos_y': pos_y}
|
|
1021
|
+
|
|
1022
|
+
else:
|
|
1023
|
+
c = None
|
|
1024
|
+
xc = None
|
|
1025
|
+
if self.use_positional_encodings:
|
|
1026
|
+
pos_x, pos_y = self.compute_latent_shifts(batch)
|
|
1027
|
+
c = {'pos_x': pos_x, 'pos_y': pos_y}
|
|
1028
|
+
out = [z, c]
|
|
1029
|
+
if return_first_stage_outputs:
|
|
1030
|
+
xrec = self.decode_first_stage(z)
|
|
1031
|
+
out.extend([x, xrec])
|
|
1032
|
+
if return_original_cond:
|
|
1033
|
+
out.append(xc)
|
|
1034
|
+
return out
|
|
1035
|
+
|
|
1036
|
+
@torch.no_grad()
|
|
1037
|
+
def decode_first_stage(
|
|
1038
|
+
self, z, predict_cids=False, force_not_quantize=False
|
|
1039
|
+
):
|
|
1040
|
+
if predict_cids:
|
|
1041
|
+
if z.dim() == 4:
|
|
1042
|
+
z = torch.argmax(z.exp(), dim=1).long()
|
|
1043
|
+
z = self.first_stage_model.quantize.get_codebook_entry(
|
|
1044
|
+
z, shape=None
|
|
1045
|
+
)
|
|
1046
|
+
z = rearrange(z, 'b h w c -> b c h w').contiguous()
|
|
1047
|
+
|
|
1048
|
+
z = 1.0 / self.scale_factor * z
|
|
1049
|
+
|
|
1050
|
+
if hasattr(self, 'split_input_params'):
|
|
1051
|
+
if self.split_input_params['patch_distributed_vq']:
|
|
1052
|
+
ks = self.split_input_params['ks'] # eg. (128, 128)
|
|
1053
|
+
stride = self.split_input_params['stride'] # eg. (64, 64)
|
|
1054
|
+
uf = self.split_input_params['vqf']
|
|
1055
|
+
bs, nc, h, w = z.shape
|
|
1056
|
+
if ks[0] > h or ks[1] > w:
|
|
1057
|
+
ks = (min(ks[0], h), min(ks[1], w))
|
|
1058
|
+
print('reducing Kernel')
|
|
1059
|
+
|
|
1060
|
+
if stride[0] > h or stride[1] > w:
|
|
1061
|
+
stride = (min(stride[0], h), min(stride[1], w))
|
|
1062
|
+
print('reducing stride')
|
|
1063
|
+
|
|
1064
|
+
fold, unfold, normalization, weighting = self.get_fold_unfold(
|
|
1065
|
+
z, ks, stride, uf=uf
|
|
1066
|
+
)
|
|
1067
|
+
|
|
1068
|
+
z = unfold(z) # (bn, nc * prod(**ks), L)
|
|
1069
|
+
# 1. Reshape to img shape
|
|
1070
|
+
z = z.view(
|
|
1071
|
+
(z.shape[0], -1, ks[0], ks[1], z.shape[-1])
|
|
1072
|
+
) # (bn, nc, ks[0], ks[1], L )
|
|
1073
|
+
|
|
1074
|
+
# 2. apply model loop over last dim
|
|
1075
|
+
if isinstance(self.first_stage_model, VQModelInterface):
|
|
1076
|
+
output_list = [
|
|
1077
|
+
self.first_stage_model.decode(
|
|
1078
|
+
z[:, :, :, :, i],
|
|
1079
|
+
force_not_quantize=predict_cids
|
|
1080
|
+
or force_not_quantize,
|
|
1081
|
+
)
|
|
1082
|
+
for i in range(z.shape[-1])
|
|
1083
|
+
]
|
|
1084
|
+
else:
|
|
1085
|
+
|
|
1086
|
+
output_list = [
|
|
1087
|
+
self.first_stage_model.decode(z[:, :, :, :, i])
|
|
1088
|
+
for i in range(z.shape[-1])
|
|
1089
|
+
]
|
|
1090
|
+
|
|
1091
|
+
o = torch.stack(
|
|
1092
|
+
output_list, axis=-1
|
|
1093
|
+
) # # (bn, nc, ks[0], ks[1], L)
|
|
1094
|
+
o = o * weighting
|
|
1095
|
+
# Reverse 1. reshape to img shape
|
|
1096
|
+
o = o.view(
|
|
1097
|
+
(o.shape[0], -1, o.shape[-1])
|
|
1098
|
+
) # (bn, nc * ks[0] * ks[1], L)
|
|
1099
|
+
# stitch crops together
|
|
1100
|
+
decoded = fold(o)
|
|
1101
|
+
decoded = decoded / normalization # norm is shape (1, 1, h, w)
|
|
1102
|
+
return decoded
|
|
1103
|
+
else:
|
|
1104
|
+
if isinstance(self.first_stage_model, VQModelInterface):
|
|
1105
|
+
return self.first_stage_model.decode(
|
|
1106
|
+
z,
|
|
1107
|
+
force_not_quantize=predict_cids or force_not_quantize,
|
|
1108
|
+
)
|
|
1109
|
+
else:
|
|
1110
|
+
return self.first_stage_model.decode(z)
|
|
1111
|
+
|
|
1112
|
+
else:
|
|
1113
|
+
if isinstance(self.first_stage_model, VQModelInterface):
|
|
1114
|
+
return self.first_stage_model.decode(
|
|
1115
|
+
z, force_not_quantize=predict_cids or force_not_quantize
|
|
1116
|
+
)
|
|
1117
|
+
else:
|
|
1118
|
+
return self.first_stage_model.decode(z)
|
|
1119
|
+
|
|
1120
|
+
# same as above but without decorator
|
|
1121
|
+
def differentiable_decode_first_stage(
|
|
1122
|
+
self, z, predict_cids=False, force_not_quantize=False
|
|
1123
|
+
):
|
|
1124
|
+
if predict_cids:
|
|
1125
|
+
if z.dim() == 4:
|
|
1126
|
+
z = torch.argmax(z.exp(), dim=1).long()
|
|
1127
|
+
z = self.first_stage_model.quantize.get_codebook_entry(
|
|
1128
|
+
z, shape=None
|
|
1129
|
+
)
|
|
1130
|
+
z = rearrange(z, 'b h w c -> b c h w').contiguous()
|
|
1131
|
+
|
|
1132
|
+
z = 1.0 / self.scale_factor * z
|
|
1133
|
+
|
|
1134
|
+
if hasattr(self, 'split_input_params'):
|
|
1135
|
+
if self.split_input_params['patch_distributed_vq']:
|
|
1136
|
+
ks = self.split_input_params['ks'] # eg. (128, 128)
|
|
1137
|
+
stride = self.split_input_params['stride'] # eg. (64, 64)
|
|
1138
|
+
uf = self.split_input_params['vqf']
|
|
1139
|
+
bs, nc, h, w = z.shape
|
|
1140
|
+
if ks[0] > h or ks[1] > w:
|
|
1141
|
+
ks = (min(ks[0], h), min(ks[1], w))
|
|
1142
|
+
print('reducing Kernel')
|
|
1143
|
+
|
|
1144
|
+
if stride[0] > h or stride[1] > w:
|
|
1145
|
+
stride = (min(stride[0], h), min(stride[1], w))
|
|
1146
|
+
print('reducing stride')
|
|
1147
|
+
|
|
1148
|
+
fold, unfold, normalization, weighting = self.get_fold_unfold(
|
|
1149
|
+
z, ks, stride, uf=uf
|
|
1150
|
+
)
|
|
1151
|
+
|
|
1152
|
+
z = unfold(z) # (bn, nc * prod(**ks), L)
|
|
1153
|
+
# 1. Reshape to img shape
|
|
1154
|
+
z = z.view(
|
|
1155
|
+
(z.shape[0], -1, ks[0], ks[1], z.shape[-1])
|
|
1156
|
+
) # (bn, nc, ks[0], ks[1], L )
|
|
1157
|
+
|
|
1158
|
+
# 2. apply model loop over last dim
|
|
1159
|
+
if isinstance(self.first_stage_model, VQModelInterface):
|
|
1160
|
+
output_list = [
|
|
1161
|
+
self.first_stage_model.decode(
|
|
1162
|
+
z[:, :, :, :, i],
|
|
1163
|
+
force_not_quantize=predict_cids
|
|
1164
|
+
or force_not_quantize,
|
|
1165
|
+
)
|
|
1166
|
+
for i in range(z.shape[-1])
|
|
1167
|
+
]
|
|
1168
|
+
else:
|
|
1169
|
+
|
|
1170
|
+
output_list = [
|
|
1171
|
+
self.first_stage_model.decode(z[:, :, :, :, i])
|
|
1172
|
+
for i in range(z.shape[-1])
|
|
1173
|
+
]
|
|
1174
|
+
|
|
1175
|
+
o = torch.stack(
|
|
1176
|
+
output_list, axis=-1
|
|
1177
|
+
) # # (bn, nc, ks[0], ks[1], L)
|
|
1178
|
+
o = o * weighting
|
|
1179
|
+
# Reverse 1. reshape to img shape
|
|
1180
|
+
o = o.view(
|
|
1181
|
+
(o.shape[0], -1, o.shape[-1])
|
|
1182
|
+
) # (bn, nc * ks[0] * ks[1], L)
|
|
1183
|
+
# stitch crops together
|
|
1184
|
+
decoded = fold(o)
|
|
1185
|
+
decoded = decoded / normalization # norm is shape (1, 1, h, w)
|
|
1186
|
+
return decoded
|
|
1187
|
+
else:
|
|
1188
|
+
if isinstance(self.first_stage_model, VQModelInterface):
|
|
1189
|
+
return self.first_stage_model.decode(
|
|
1190
|
+
z,
|
|
1191
|
+
force_not_quantize=predict_cids or force_not_quantize,
|
|
1192
|
+
)
|
|
1193
|
+
else:
|
|
1194
|
+
return self.first_stage_model.decode(z)
|
|
1195
|
+
|
|
1196
|
+
else:
|
|
1197
|
+
if isinstance(self.first_stage_model, VQModelInterface):
|
|
1198
|
+
return self.first_stage_model.decode(
|
|
1199
|
+
z, force_not_quantize=predict_cids or force_not_quantize
|
|
1200
|
+
)
|
|
1201
|
+
else:
|
|
1202
|
+
return self.first_stage_model.decode(z)
|
|
1203
|
+
|
|
1204
|
+
@torch.no_grad()
|
|
1205
|
+
def encode_first_stage(self, x):
|
|
1206
|
+
if hasattr(self, 'split_input_params'):
|
|
1207
|
+
if self.split_input_params['patch_distributed_vq']:
|
|
1208
|
+
ks = self.split_input_params['ks'] # eg. (128, 128)
|
|
1209
|
+
stride = self.split_input_params['stride'] # eg. (64, 64)
|
|
1210
|
+
df = self.split_input_params['vqf']
|
|
1211
|
+
self.split_input_params['original_image_size'] = x.shape[-2:]
|
|
1212
|
+
bs, nc, h, w = x.shape
|
|
1213
|
+
if ks[0] > h or ks[1] > w:
|
|
1214
|
+
ks = (min(ks[0], h), min(ks[1], w))
|
|
1215
|
+
print('reducing Kernel')
|
|
1216
|
+
|
|
1217
|
+
if stride[0] > h or stride[1] > w:
|
|
1218
|
+
stride = (min(stride[0], h), min(stride[1], w))
|
|
1219
|
+
print('reducing stride')
|
|
1220
|
+
|
|
1221
|
+
fold, unfold, normalization, weighting = self.get_fold_unfold(
|
|
1222
|
+
x, ks, stride, df=df
|
|
1223
|
+
)
|
|
1224
|
+
z = unfold(x) # (bn, nc * prod(**ks), L)
|
|
1225
|
+
# Reshape to img shape
|
|
1226
|
+
z = z.view(
|
|
1227
|
+
(z.shape[0], -1, ks[0], ks[1], z.shape[-1])
|
|
1228
|
+
) # (bn, nc, ks[0], ks[1], L )
|
|
1229
|
+
|
|
1230
|
+
output_list = [
|
|
1231
|
+
self.first_stage_model.encode(z[:, :, :, :, i])
|
|
1232
|
+
for i in range(z.shape[-1])
|
|
1233
|
+
]
|
|
1234
|
+
|
|
1235
|
+
o = torch.stack(output_list, axis=-1)
|
|
1236
|
+
o = o * weighting
|
|
1237
|
+
|
|
1238
|
+
# Reverse reshape to img shape
|
|
1239
|
+
o = o.view(
|
|
1240
|
+
(o.shape[0], -1, o.shape[-1])
|
|
1241
|
+
) # (bn, nc * ks[0] * ks[1], L)
|
|
1242
|
+
# stitch crops together
|
|
1243
|
+
decoded = fold(o)
|
|
1244
|
+
decoded = decoded / normalization
|
|
1245
|
+
return decoded
|
|
1246
|
+
|
|
1247
|
+
else:
|
|
1248
|
+
return self.first_stage_model.encode(x)
|
|
1249
|
+
else:
|
|
1250
|
+
return self.first_stage_model.encode(x)
|
|
1251
|
+
|
|
1252
|
+
def shared_step(self, batch, **kwargs):
|
|
1253
|
+
x, c = self.get_input(batch, self.first_stage_key)
|
|
1254
|
+
loss = self(x, c)
|
|
1255
|
+
return loss
|
|
1256
|
+
|
|
1257
|
+
def forward(self, x, c, *args, **kwargs):
|
|
1258
|
+
t = torch.randint(
|
|
1259
|
+
0, self.num_timesteps, (x.shape[0],), device=self.device
|
|
1260
|
+
).long()
|
|
1261
|
+
if self.model.conditioning_key is not None:
|
|
1262
|
+
assert c is not None
|
|
1263
|
+
if self.cond_stage_trainable:
|
|
1264
|
+
c = self.get_learned_conditioning(c)
|
|
1265
|
+
if self.shorten_cond_schedule: # TODO: drop this option
|
|
1266
|
+
tc = self.cond_ids[t].to(self.device)
|
|
1267
|
+
c = self.q_sample(
|
|
1268
|
+
x_start=c, t=tc, noise=torch.randn_like(c.float())
|
|
1269
|
+
)
|
|
1270
|
+
|
|
1271
|
+
return self.p_losses(x, c, t, *args, **kwargs)
|
|
1272
|
+
|
|
1273
|
+
def _rescale_annotations(
|
|
1274
|
+
self, bboxes, crop_coordinates
|
|
1275
|
+
): # TODO: move to dataset
|
|
1276
|
+
def rescale_bbox(bbox):
|
|
1277
|
+
x0 = clamp((bbox[0] - crop_coordinates[0]) / crop_coordinates[2])
|
|
1278
|
+
y0 = clamp((bbox[1] - crop_coordinates[1]) / crop_coordinates[3])
|
|
1279
|
+
w = min(bbox[2] / crop_coordinates[2], 1 - x0)
|
|
1280
|
+
h = min(bbox[3] / crop_coordinates[3], 1 - y0)
|
|
1281
|
+
return x0, y0, w, h
|
|
1282
|
+
|
|
1283
|
+
return [rescale_bbox(b) for b in bboxes]
|
|
1284
|
+
|
|
1285
|
+
def apply_model(self, x_noisy, t, cond, return_ids=False):
|
|
1286
|
+
|
|
1287
|
+
if isinstance(cond, dict):
|
|
1288
|
+
# hybrid case, cond is exptected to be a dict
|
|
1289
|
+
pass
|
|
1290
|
+
else:
|
|
1291
|
+
if not isinstance(cond, list):
|
|
1292
|
+
cond = [cond]
|
|
1293
|
+
key = (
|
|
1294
|
+
'c_concat'
|
|
1295
|
+
if self.model.conditioning_key == 'concat'
|
|
1296
|
+
else 'c_crossattn'
|
|
1297
|
+
)
|
|
1298
|
+
cond = {key: cond}
|
|
1299
|
+
|
|
1300
|
+
if hasattr(self, 'split_input_params'):
|
|
1301
|
+
assert (
|
|
1302
|
+
len(cond) == 1
|
|
1303
|
+
) # todo can only deal with one conditioning atm
|
|
1304
|
+
assert not return_ids
|
|
1305
|
+
ks = self.split_input_params['ks'] # eg. (128, 128)
|
|
1306
|
+
stride = self.split_input_params['stride'] # eg. (64, 64)
|
|
1307
|
+
|
|
1308
|
+
h, w = x_noisy.shape[-2:]
|
|
1309
|
+
|
|
1310
|
+
fold, unfold, normalization, weighting = self.get_fold_unfold(
|
|
1311
|
+
x_noisy, ks, stride
|
|
1312
|
+
)
|
|
1313
|
+
|
|
1314
|
+
z = unfold(x_noisy) # (bn, nc * prod(**ks), L)
|
|
1315
|
+
# Reshape to img shape
|
|
1316
|
+
z = z.view(
|
|
1317
|
+
(z.shape[0], -1, ks[0], ks[1], z.shape[-1])
|
|
1318
|
+
) # (bn, nc, ks[0], ks[1], L )
|
|
1319
|
+
z_list = [z[:, :, :, :, i] for i in range(z.shape[-1])]
|
|
1320
|
+
|
|
1321
|
+
if (
|
|
1322
|
+
self.cond_stage_key
|
|
1323
|
+
in ['image', 'LR_image', 'segmentation', 'bbox_img']
|
|
1324
|
+
and self.model.conditioning_key
|
|
1325
|
+
): # todo check for completeness
|
|
1326
|
+
c_key = next(iter(cond.keys())) # get key
|
|
1327
|
+
c = next(iter(cond.values())) # get value
|
|
1328
|
+
assert (
|
|
1329
|
+
len(c) == 1
|
|
1330
|
+
) # todo extend to list with more than one elem
|
|
1331
|
+
c = c[0] # get element
|
|
1332
|
+
|
|
1333
|
+
c = unfold(c)
|
|
1334
|
+
c = c.view(
|
|
1335
|
+
(c.shape[0], -1, ks[0], ks[1], c.shape[-1])
|
|
1336
|
+
) # (bn, nc, ks[0], ks[1], L )
|
|
1337
|
+
|
|
1338
|
+
cond_list = [
|
|
1339
|
+
{c_key: [c[:, :, :, :, i]]} for i in range(c.shape[-1])
|
|
1340
|
+
]
|
|
1341
|
+
|
|
1342
|
+
elif self.cond_stage_key == 'coordinates_bbox':
|
|
1343
|
+
assert (
|
|
1344
|
+
'original_image_size' in self.split_input_params
|
|
1345
|
+
), 'BoudingBoxRescaling is missing original_image_size'
|
|
1346
|
+
|
|
1347
|
+
# assuming padding of unfold is always 0 and its dilation is always 1
|
|
1348
|
+
n_patches_per_row = int((w - ks[0]) / stride[0] + 1)
|
|
1349
|
+
full_img_h, full_img_w = self.split_input_params[
|
|
1350
|
+
'original_image_size'
|
|
1351
|
+
]
|
|
1352
|
+
# as we are operating on latents, we need the factor from the original image size to the
|
|
1353
|
+
# spatial latent size to properly rescale the crops for regenerating the bbox annotations
|
|
1354
|
+
num_downs = self.first_stage_model.encoder.num_resolutions - 1
|
|
1355
|
+
rescale_latent = 2 ** (num_downs)
|
|
1356
|
+
|
|
1357
|
+
# get top left positions of patches as conforming for the bbbox tokenizer, therefore we
|
|
1358
|
+
# need to rescale the tl patch coordinates to be in between (0,1)
|
|
1359
|
+
tl_patch_coordinates = [
|
|
1360
|
+
(
|
|
1361
|
+
rescale_latent
|
|
1362
|
+
* stride[0]
|
|
1363
|
+
* (patch_nr % n_patches_per_row)
|
|
1364
|
+
/ full_img_w,
|
|
1365
|
+
rescale_latent
|
|
1366
|
+
* stride[1]
|
|
1367
|
+
* (patch_nr // n_patches_per_row)
|
|
1368
|
+
/ full_img_h,
|
|
1369
|
+
)
|
|
1370
|
+
for patch_nr in range(z.shape[-1])
|
|
1371
|
+
]
|
|
1372
|
+
|
|
1373
|
+
# patch_limits are tl_coord, width and height coordinates as (x_tl, y_tl, h, w)
|
|
1374
|
+
patch_limits = [
|
|
1375
|
+
(
|
|
1376
|
+
x_tl,
|
|
1377
|
+
y_tl,
|
|
1378
|
+
rescale_latent * ks[0] / full_img_w,
|
|
1379
|
+
rescale_latent * ks[1] / full_img_h,
|
|
1380
|
+
)
|
|
1381
|
+
for x_tl, y_tl in tl_patch_coordinates
|
|
1382
|
+
]
|
|
1383
|
+
# patch_values = [(np.arange(x_tl,min(x_tl+ks, 1.)),np.arange(y_tl,min(y_tl+ks, 1.))) for x_tl, y_tl in tl_patch_coordinates]
|
|
1384
|
+
|
|
1385
|
+
# tokenize crop coordinates for the bounding boxes of the respective patches
|
|
1386
|
+
patch_limits_tknzd = [
|
|
1387
|
+
torch.LongTensor(self.bbox_tokenizer._crop_encoder(bbox))[
|
|
1388
|
+
None
|
|
1389
|
+
].to(self.device)
|
|
1390
|
+
for bbox in patch_limits
|
|
1391
|
+
] # list of length l with tensors of shape (1, 2)
|
|
1392
|
+
print(patch_limits_tknzd[0].shape)
|
|
1393
|
+
# cut tknzd crop position from conditioning
|
|
1394
|
+
assert isinstance(
|
|
1395
|
+
cond, dict
|
|
1396
|
+
), 'cond must be dict to be fed into model'
|
|
1397
|
+
cut_cond = cond['c_crossattn'][0][..., :-2].to(self.device)
|
|
1398
|
+
print(cut_cond.shape)
|
|
1399
|
+
|
|
1400
|
+
adapted_cond = torch.stack(
|
|
1401
|
+
[
|
|
1402
|
+
torch.cat([cut_cond, p], dim=1)
|
|
1403
|
+
for p in patch_limits_tknzd
|
|
1404
|
+
]
|
|
1405
|
+
)
|
|
1406
|
+
adapted_cond = rearrange(adapted_cond, 'l b n -> (l b) n')
|
|
1407
|
+
print(adapted_cond.shape)
|
|
1408
|
+
adapted_cond = self.get_learned_conditioning(adapted_cond)
|
|
1409
|
+
print(adapted_cond.shape)
|
|
1410
|
+
adapted_cond = rearrange(
|
|
1411
|
+
adapted_cond, '(l b) n d -> l b n d', l=z.shape[-1]
|
|
1412
|
+
)
|
|
1413
|
+
print(adapted_cond.shape)
|
|
1414
|
+
|
|
1415
|
+
cond_list = [{'c_crossattn': [e]} for e in adapted_cond]
|
|
1416
|
+
|
|
1417
|
+
else:
|
|
1418
|
+
cond_list = [
|
|
1419
|
+
cond for i in range(z.shape[-1])
|
|
1420
|
+
] # Todo make this more efficient
|
|
1421
|
+
|
|
1422
|
+
# apply model by loop over crops
|
|
1423
|
+
output_list = [
|
|
1424
|
+
self.model(z_list[i], t, **cond_list[i])
|
|
1425
|
+
for i in range(z.shape[-1])
|
|
1426
|
+
]
|
|
1427
|
+
assert not isinstance(
|
|
1428
|
+
output_list[0], tuple
|
|
1429
|
+
) # todo cant deal with multiple model outputs check this never happens
|
|
1430
|
+
|
|
1431
|
+
o = torch.stack(output_list, axis=-1)
|
|
1432
|
+
o = o * weighting
|
|
1433
|
+
# Reverse reshape to img shape
|
|
1434
|
+
o = o.view(
|
|
1435
|
+
(o.shape[0], -1, o.shape[-1])
|
|
1436
|
+
) # (bn, nc * ks[0] * ks[1], L)
|
|
1437
|
+
# stitch crops together
|
|
1438
|
+
x_recon = fold(o) / normalization
|
|
1439
|
+
|
|
1440
|
+
else:
|
|
1441
|
+
x_recon = self.model(x_noisy, t, **cond)
|
|
1442
|
+
|
|
1443
|
+
if isinstance(x_recon, tuple) and not return_ids:
|
|
1444
|
+
return x_recon[0]
|
|
1445
|
+
else:
|
|
1446
|
+
return x_recon
|
|
1447
|
+
|
|
1448
|
+
def _predict_eps_from_xstart(self, x_t, t, pred_xstart):
|
|
1449
|
+
return (
|
|
1450
|
+
extract_into_tensor(self.sqrt_recip_alphas_cumprod, t, x_t.shape)
|
|
1451
|
+
* x_t
|
|
1452
|
+
- pred_xstart
|
|
1453
|
+
) / extract_into_tensor(self.sqrt_recipm1_alphas_cumprod, t, x_t.shape)
|
|
1454
|
+
|
|
1455
|
+
def _prior_bpd(self, x_start):
|
|
1456
|
+
"""
|
|
1457
|
+
Get the prior KL term for the variational lower-bound, measured in
|
|
1458
|
+
bits-per-dim.
|
|
1459
|
+
This term can't be optimized, as it only depends on the encoder.
|
|
1460
|
+
:param x_start: the [N x C x ...] tensor of inputs.
|
|
1461
|
+
:return: a batch of [N] KL values (in bits), one per batch element.
|
|
1462
|
+
"""
|
|
1463
|
+
batch_size = x_start.shape[0]
|
|
1464
|
+
t = torch.tensor(
|
|
1465
|
+
[self.num_timesteps - 1] * batch_size, device=x_start.device
|
|
1466
|
+
)
|
|
1467
|
+
qt_mean, _, qt_log_variance = self.q_mean_variance(x_start, t)
|
|
1468
|
+
kl_prior = normal_kl(
|
|
1469
|
+
mean1=qt_mean, logvar1=qt_log_variance, mean2=0.0, logvar2=0.0
|
|
1470
|
+
)
|
|
1471
|
+
return mean_flat(kl_prior) / np.log(2.0)
|
|
1472
|
+
|
|
1473
|
+
def p_losses(self, x_start, cond, t, noise=None):
|
|
1474
|
+
noise = default(noise, lambda: torch.randn_like(x_start))
|
|
1475
|
+
x_noisy = self.q_sample(x_start=x_start, t=t, noise=noise)
|
|
1476
|
+
model_output = self.apply_model(x_noisy, t, cond)
|
|
1477
|
+
|
|
1478
|
+
loss_dict = {}
|
|
1479
|
+
prefix = 'train' if self.training else 'val'
|
|
1480
|
+
|
|
1481
|
+
if self.parameterization == 'x0':
|
|
1482
|
+
target = x_start
|
|
1483
|
+
elif self.parameterization == 'eps':
|
|
1484
|
+
target = noise
|
|
1485
|
+
else:
|
|
1486
|
+
raise NotImplementedError()
|
|
1487
|
+
|
|
1488
|
+
loss_simple = self.get_loss(model_output, target, mean=False).mean(
|
|
1489
|
+
[1, 2, 3]
|
|
1490
|
+
)
|
|
1491
|
+
loss_dict.update({f'{prefix}/loss_simple': loss_simple.mean()})
|
|
1492
|
+
|
|
1493
|
+
logvar_t = self.logvar[t.item()].to(self.device)
|
|
1494
|
+
loss = loss_simple / torch.exp(logvar_t) + logvar_t
|
|
1495
|
+
# loss = loss_simple / torch.exp(self.logvar) + self.logvar
|
|
1496
|
+
if self.learn_logvar:
|
|
1497
|
+
loss_dict.update({f'{prefix}/loss_gamma': loss.mean()})
|
|
1498
|
+
loss_dict.update({'logvar': self.logvar.data.mean()})
|
|
1499
|
+
|
|
1500
|
+
loss = self.l_simple_weight * loss.mean()
|
|
1501
|
+
|
|
1502
|
+
loss_vlb = self.get_loss(model_output, target, mean=False).mean(
|
|
1503
|
+
dim=(1, 2, 3)
|
|
1504
|
+
)
|
|
1505
|
+
loss_vlb = (self.lvlb_weights[t] * loss_vlb).mean()
|
|
1506
|
+
loss_dict.update({f'{prefix}/loss_vlb': loss_vlb})
|
|
1507
|
+
loss += self.original_elbo_weight * loss_vlb
|
|
1508
|
+
loss_dict.update({f'{prefix}/loss': loss})
|
|
1509
|
+
|
|
1510
|
+
if self.embedding_reg_weight > 0:
|
|
1511
|
+
loss_embedding_reg = (
|
|
1512
|
+
self.embedding_manager.embedding_to_coarse_loss().mean()
|
|
1513
|
+
)
|
|
1514
|
+
|
|
1515
|
+
loss_dict.update({f'{prefix}/loss_emb_reg': loss_embedding_reg})
|
|
1516
|
+
|
|
1517
|
+
loss += self.embedding_reg_weight * loss_embedding_reg
|
|
1518
|
+
loss_dict.update({f'{prefix}/loss': loss})
|
|
1519
|
+
|
|
1520
|
+
return loss, loss_dict
|
|
1521
|
+
|
|
1522
|
+
def p_mean_variance(
|
|
1523
|
+
self,
|
|
1524
|
+
x,
|
|
1525
|
+
c,
|
|
1526
|
+
t,
|
|
1527
|
+
clip_denoised: bool,
|
|
1528
|
+
return_codebook_ids=False,
|
|
1529
|
+
quantize_denoised=False,
|
|
1530
|
+
return_x0=False,
|
|
1531
|
+
score_corrector=None,
|
|
1532
|
+
corrector_kwargs=None,
|
|
1533
|
+
):
|
|
1534
|
+
t_in = t
|
|
1535
|
+
model_out = self.apply_model(
|
|
1536
|
+
x, t_in, c, return_ids=return_codebook_ids
|
|
1537
|
+
)
|
|
1538
|
+
|
|
1539
|
+
if score_corrector is not None:
|
|
1540
|
+
assert self.parameterization == 'eps'
|
|
1541
|
+
model_out = score_corrector.modify_score(
|
|
1542
|
+
self, model_out, x, t, c, **corrector_kwargs
|
|
1543
|
+
)
|
|
1544
|
+
|
|
1545
|
+
if return_codebook_ids:
|
|
1546
|
+
model_out, logits = model_out
|
|
1547
|
+
|
|
1548
|
+
if self.parameterization == 'eps':
|
|
1549
|
+
x_recon = self.predict_start_from_noise(x, t=t, noise=model_out)
|
|
1550
|
+
elif self.parameterization == 'x0':
|
|
1551
|
+
x_recon = model_out
|
|
1552
|
+
else:
|
|
1553
|
+
raise NotImplementedError()
|
|
1554
|
+
|
|
1555
|
+
if clip_denoised:
|
|
1556
|
+
x_recon.clamp_(-1.0, 1.0)
|
|
1557
|
+
if quantize_denoised:
|
|
1558
|
+
x_recon, _, [_, _, indices] = self.first_stage_model.quantize(
|
|
1559
|
+
x_recon
|
|
1560
|
+
)
|
|
1561
|
+
(
|
|
1562
|
+
model_mean,
|
|
1563
|
+
posterior_variance,
|
|
1564
|
+
posterior_log_variance,
|
|
1565
|
+
) = self.q_posterior(x_start=x_recon, x_t=x, t=t)
|
|
1566
|
+
if return_codebook_ids:
|
|
1567
|
+
return (
|
|
1568
|
+
model_mean,
|
|
1569
|
+
posterior_variance,
|
|
1570
|
+
posterior_log_variance,
|
|
1571
|
+
logits,
|
|
1572
|
+
)
|
|
1573
|
+
elif return_x0:
|
|
1574
|
+
return (
|
|
1575
|
+
model_mean,
|
|
1576
|
+
posterior_variance,
|
|
1577
|
+
posterior_log_variance,
|
|
1578
|
+
x_recon,
|
|
1579
|
+
)
|
|
1580
|
+
else:
|
|
1581
|
+
return model_mean, posterior_variance, posterior_log_variance
|
|
1582
|
+
|
|
1583
|
+
@torch.no_grad()
|
|
1584
|
+
def p_sample(
|
|
1585
|
+
self,
|
|
1586
|
+
x,
|
|
1587
|
+
c,
|
|
1588
|
+
t,
|
|
1589
|
+
clip_denoised=False,
|
|
1590
|
+
repeat_noise=False,
|
|
1591
|
+
return_codebook_ids=False,
|
|
1592
|
+
quantize_denoised=False,
|
|
1593
|
+
return_x0=False,
|
|
1594
|
+
temperature=1.0,
|
|
1595
|
+
noise_dropout=0.0,
|
|
1596
|
+
score_corrector=None,
|
|
1597
|
+
corrector_kwargs=None,
|
|
1598
|
+
):
|
|
1599
|
+
b, *_, device = *x.shape, x.device
|
|
1600
|
+
outputs = self.p_mean_variance(
|
|
1601
|
+
x=x,
|
|
1602
|
+
c=c,
|
|
1603
|
+
t=t,
|
|
1604
|
+
clip_denoised=clip_denoised,
|
|
1605
|
+
return_codebook_ids=return_codebook_ids,
|
|
1606
|
+
quantize_denoised=quantize_denoised,
|
|
1607
|
+
return_x0=return_x0,
|
|
1608
|
+
score_corrector=score_corrector,
|
|
1609
|
+
corrector_kwargs=corrector_kwargs,
|
|
1610
|
+
)
|
|
1611
|
+
if return_codebook_ids:
|
|
1612
|
+
raise DeprecationWarning('Support dropped.')
|
|
1613
|
+
model_mean, _, model_log_variance, logits = outputs
|
|
1614
|
+
elif return_x0:
|
|
1615
|
+
model_mean, _, model_log_variance, x0 = outputs
|
|
1616
|
+
else:
|
|
1617
|
+
model_mean, _, model_log_variance = outputs
|
|
1618
|
+
|
|
1619
|
+
noise = noise_like(x.shape, device, repeat_noise) * temperature
|
|
1620
|
+
if noise_dropout > 0.0:
|
|
1621
|
+
noise = torch.nn.functional.dropout(noise, p=noise_dropout)
|
|
1622
|
+
# no noise when t == 0
|
|
1623
|
+
nonzero_mask = (1 - (t == 0).float()).reshape(
|
|
1624
|
+
b, *((1,) * (len(x.shape) - 1))
|
|
1625
|
+
)
|
|
1626
|
+
|
|
1627
|
+
if return_codebook_ids:
|
|
1628
|
+
return model_mean + nonzero_mask * (
|
|
1629
|
+
0.5 * model_log_variance
|
|
1630
|
+
).exp() * noise, logits.argmax(dim=1)
|
|
1631
|
+
if return_x0:
|
|
1632
|
+
return (
|
|
1633
|
+
model_mean
|
|
1634
|
+
+ nonzero_mask * (0.5 * model_log_variance).exp() * noise,
|
|
1635
|
+
x0,
|
|
1636
|
+
)
|
|
1637
|
+
else:
|
|
1638
|
+
return (
|
|
1639
|
+
model_mean
|
|
1640
|
+
+ nonzero_mask * (0.5 * model_log_variance).exp() * noise
|
|
1641
|
+
)
|
|
1642
|
+
|
|
1643
|
+
@torch.no_grad()
|
|
1644
|
+
def progressive_denoising(
|
|
1645
|
+
self,
|
|
1646
|
+
cond,
|
|
1647
|
+
shape,
|
|
1648
|
+
verbose=True,
|
|
1649
|
+
callback=None,
|
|
1650
|
+
quantize_denoised=False,
|
|
1651
|
+
img_callback=None,
|
|
1652
|
+
mask=None,
|
|
1653
|
+
x0=None,
|
|
1654
|
+
temperature=1.0,
|
|
1655
|
+
noise_dropout=0.0,
|
|
1656
|
+
score_corrector=None,
|
|
1657
|
+
corrector_kwargs=None,
|
|
1658
|
+
batch_size=None,
|
|
1659
|
+
x_T=None,
|
|
1660
|
+
start_T=None,
|
|
1661
|
+
log_every_t=None,
|
|
1662
|
+
):
|
|
1663
|
+
if not log_every_t:
|
|
1664
|
+
log_every_t = self.log_every_t
|
|
1665
|
+
timesteps = self.num_timesteps
|
|
1666
|
+
if batch_size is not None:
|
|
1667
|
+
b = batch_size if batch_size is not None else shape[0]
|
|
1668
|
+
shape = [batch_size] + list(shape)
|
|
1669
|
+
else:
|
|
1670
|
+
b = batch_size = shape[0]
|
|
1671
|
+
if x_T is None:
|
|
1672
|
+
img = torch.randn(shape, device=self.device)
|
|
1673
|
+
else:
|
|
1674
|
+
img = x_T
|
|
1675
|
+
intermediates = []
|
|
1676
|
+
if cond is not None:
|
|
1677
|
+
if isinstance(cond, dict):
|
|
1678
|
+
cond = {
|
|
1679
|
+
key: cond[key][:batch_size]
|
|
1680
|
+
if not isinstance(cond[key], list)
|
|
1681
|
+
else list(map(lambda x: x[:batch_size], cond[key]))
|
|
1682
|
+
for key in cond
|
|
1683
|
+
}
|
|
1684
|
+
else:
|
|
1685
|
+
cond = (
|
|
1686
|
+
[c[:batch_size] for c in cond]
|
|
1687
|
+
if isinstance(cond, list)
|
|
1688
|
+
else cond[:batch_size]
|
|
1689
|
+
)
|
|
1690
|
+
|
|
1691
|
+
if start_T is not None:
|
|
1692
|
+
timesteps = min(timesteps, start_T)
|
|
1693
|
+
iterator = (
|
|
1694
|
+
tqdm(
|
|
1695
|
+
reversed(range(0, timesteps)),
|
|
1696
|
+
desc='Progressive Generation',
|
|
1697
|
+
total=timesteps,
|
|
1698
|
+
)
|
|
1699
|
+
if verbose
|
|
1700
|
+
else reversed(range(0, timesteps))
|
|
1701
|
+
)
|
|
1702
|
+
if type(temperature) == float:
|
|
1703
|
+
temperature = [temperature] * timesteps
|
|
1704
|
+
|
|
1705
|
+
for i in iterator:
|
|
1706
|
+
ts = torch.full((b,), i, device=self.device, dtype=torch.long)
|
|
1707
|
+
if self.shorten_cond_schedule:
|
|
1708
|
+
assert self.model.conditioning_key != 'hybrid'
|
|
1709
|
+
tc = self.cond_ids[ts].to(cond.device)
|
|
1710
|
+
cond = self.q_sample(
|
|
1711
|
+
x_start=cond, t=tc, noise=torch.randn_like(cond)
|
|
1712
|
+
)
|
|
1713
|
+
|
|
1714
|
+
img, x0_partial = self.p_sample(
|
|
1715
|
+
img,
|
|
1716
|
+
cond,
|
|
1717
|
+
ts,
|
|
1718
|
+
clip_denoised=self.clip_denoised,
|
|
1719
|
+
quantize_denoised=quantize_denoised,
|
|
1720
|
+
return_x0=True,
|
|
1721
|
+
temperature=temperature[i],
|
|
1722
|
+
noise_dropout=noise_dropout,
|
|
1723
|
+
score_corrector=score_corrector,
|
|
1724
|
+
corrector_kwargs=corrector_kwargs,
|
|
1725
|
+
)
|
|
1726
|
+
if mask is not None:
|
|
1727
|
+
assert x0 is not None
|
|
1728
|
+
img_orig = self.q_sample(x0, ts)
|
|
1729
|
+
img = img_orig * mask + (1.0 - mask) * img
|
|
1730
|
+
|
|
1731
|
+
if i % log_every_t == 0 or i == timesteps - 1:
|
|
1732
|
+
intermediates.append(x0_partial)
|
|
1733
|
+
if callback:
|
|
1734
|
+
callback(i)
|
|
1735
|
+
if img_callback:
|
|
1736
|
+
img_callback(img, i)
|
|
1737
|
+
return img, intermediates
|
|
1738
|
+
|
|
1739
|
+
@torch.no_grad()
|
|
1740
|
+
def p_sample_loop(
|
|
1741
|
+
self,
|
|
1742
|
+
cond,
|
|
1743
|
+
shape,
|
|
1744
|
+
return_intermediates=False,
|
|
1745
|
+
x_T=None,
|
|
1746
|
+
verbose=True,
|
|
1747
|
+
callback=None,
|
|
1748
|
+
timesteps=None,
|
|
1749
|
+
quantize_denoised=False,
|
|
1750
|
+
mask=None,
|
|
1751
|
+
x0=None,
|
|
1752
|
+
img_callback=None,
|
|
1753
|
+
start_T=None,
|
|
1754
|
+
log_every_t=None,
|
|
1755
|
+
):
|
|
1756
|
+
|
|
1757
|
+
if not log_every_t:
|
|
1758
|
+
log_every_t = self.log_every_t
|
|
1759
|
+
device = self.betas.device
|
|
1760
|
+
b = shape[0]
|
|
1761
|
+
if x_T is None:
|
|
1762
|
+
img = torch.randn(shape, device=device)
|
|
1763
|
+
else:
|
|
1764
|
+
img = x_T
|
|
1765
|
+
|
|
1766
|
+
intermediates = [img]
|
|
1767
|
+
if timesteps is None:
|
|
1768
|
+
timesteps = self.num_timesteps
|
|
1769
|
+
|
|
1770
|
+
if start_T is not None:
|
|
1771
|
+
timesteps = min(timesteps, start_T)
|
|
1772
|
+
iterator = (
|
|
1773
|
+
tqdm(
|
|
1774
|
+
reversed(range(0, timesteps)),
|
|
1775
|
+
desc='Sampling t',
|
|
1776
|
+
total=timesteps,
|
|
1777
|
+
)
|
|
1778
|
+
if verbose
|
|
1779
|
+
else reversed(range(0, timesteps))
|
|
1780
|
+
)
|
|
1781
|
+
|
|
1782
|
+
if mask is not None:
|
|
1783
|
+
assert x0 is not None
|
|
1784
|
+
assert (
|
|
1785
|
+
x0.shape[2:3] == mask.shape[2:3]
|
|
1786
|
+
) # spatial size has to match
|
|
1787
|
+
|
|
1788
|
+
for i in iterator:
|
|
1789
|
+
ts = torch.full((b,), i, device=device, dtype=torch.long)
|
|
1790
|
+
if self.shorten_cond_schedule:
|
|
1791
|
+
assert self.model.conditioning_key != 'hybrid'
|
|
1792
|
+
tc = self.cond_ids[ts].to(cond.device)
|
|
1793
|
+
cond = self.q_sample(
|
|
1794
|
+
x_start=cond, t=tc, noise=torch.randn_like(cond)
|
|
1795
|
+
)
|
|
1796
|
+
|
|
1797
|
+
img = self.p_sample(
|
|
1798
|
+
img,
|
|
1799
|
+
cond,
|
|
1800
|
+
ts,
|
|
1801
|
+
clip_denoised=self.clip_denoised,
|
|
1802
|
+
quantize_denoised=quantize_denoised,
|
|
1803
|
+
)
|
|
1804
|
+
if mask is not None:
|
|
1805
|
+
img_orig = self.q_sample(x0, ts)
|
|
1806
|
+
img = img_orig * mask + (1.0 - mask) * img
|
|
1807
|
+
|
|
1808
|
+
if i % log_every_t == 0 or i == timesteps - 1:
|
|
1809
|
+
intermediates.append(img)
|
|
1810
|
+
if callback:
|
|
1811
|
+
callback(i)
|
|
1812
|
+
if img_callback:
|
|
1813
|
+
img_callback(img, i)
|
|
1814
|
+
|
|
1815
|
+
if return_intermediates:
|
|
1816
|
+
return img, intermediates
|
|
1817
|
+
return img
|
|
1818
|
+
|
|
1819
|
+
@torch.no_grad()
|
|
1820
|
+
def sample(
|
|
1821
|
+
self,
|
|
1822
|
+
cond,
|
|
1823
|
+
batch_size=16,
|
|
1824
|
+
return_intermediates=False,
|
|
1825
|
+
x_T=None,
|
|
1826
|
+
verbose=True,
|
|
1827
|
+
timesteps=None,
|
|
1828
|
+
quantize_denoised=False,
|
|
1829
|
+
mask=None,
|
|
1830
|
+
x0=None,
|
|
1831
|
+
shape=None,
|
|
1832
|
+
**kwargs,
|
|
1833
|
+
):
|
|
1834
|
+
if shape is None:
|
|
1835
|
+
shape = (
|
|
1836
|
+
batch_size,
|
|
1837
|
+
self.channels,
|
|
1838
|
+
self.image_size,
|
|
1839
|
+
self.image_size,
|
|
1840
|
+
)
|
|
1841
|
+
if cond is not None:
|
|
1842
|
+
if isinstance(cond, dict):
|
|
1843
|
+
cond = {
|
|
1844
|
+
key: cond[key][:batch_size]
|
|
1845
|
+
if not isinstance(cond[key], list)
|
|
1846
|
+
else list(map(lambda x: x[:batch_size], cond[key]))
|
|
1847
|
+
for key in cond
|
|
1848
|
+
}
|
|
1849
|
+
else:
|
|
1850
|
+
cond = (
|
|
1851
|
+
[c[:batch_size] for c in cond]
|
|
1852
|
+
if isinstance(cond, list)
|
|
1853
|
+
else cond[:batch_size]
|
|
1854
|
+
)
|
|
1855
|
+
return self.p_sample_loop(
|
|
1856
|
+
cond,
|
|
1857
|
+
shape,
|
|
1858
|
+
return_intermediates=return_intermediates,
|
|
1859
|
+
x_T=x_T,
|
|
1860
|
+
verbose=verbose,
|
|
1861
|
+
timesteps=timesteps,
|
|
1862
|
+
quantize_denoised=quantize_denoised,
|
|
1863
|
+
mask=mask,
|
|
1864
|
+
x0=x0,
|
|
1865
|
+
)
|
|
1866
|
+
|
|
1867
|
+
@torch.no_grad()
|
|
1868
|
+
def sample_log(self, cond, batch_size, ddim, ddim_steps, **kwargs):
|
|
1869
|
+
|
|
1870
|
+
if ddim:
|
|
1871
|
+
ddim_sampler = DDIMSampler(self)
|
|
1872
|
+
shape = (self.channels, self.image_size, self.image_size)
|
|
1873
|
+
samples, intermediates = ddim_sampler.sample(
|
|
1874
|
+
ddim_steps, batch_size, shape, cond, verbose=False, **kwargs
|
|
1875
|
+
)
|
|
1876
|
+
|
|
1877
|
+
else:
|
|
1878
|
+
samples, intermediates = self.sample(
|
|
1879
|
+
cond=cond,
|
|
1880
|
+
batch_size=batch_size,
|
|
1881
|
+
return_intermediates=True,
|
|
1882
|
+
**kwargs,
|
|
1883
|
+
)
|
|
1884
|
+
|
|
1885
|
+
return samples, intermediates
|
|
1886
|
+
|
|
1887
|
+
@torch.no_grad()
|
|
1888
|
+
def get_unconditional_conditioning(self, batch_size, null_label=None):
|
|
1889
|
+
if null_label is not None:
|
|
1890
|
+
xc = null_label
|
|
1891
|
+
if isinstance(xc, ListConfig):
|
|
1892
|
+
xc = list(xc)
|
|
1893
|
+
if isinstance(xc, dict) or isinstance(xc, list):
|
|
1894
|
+
c = self.get_learned_conditioning(xc)
|
|
1895
|
+
else:
|
|
1896
|
+
if hasattr(xc, "to"):
|
|
1897
|
+
xc = xc.to(self.device)
|
|
1898
|
+
c = self.get_learned_conditioning(xc)
|
|
1899
|
+
else:
|
|
1900
|
+
# todo: get null label from cond_stage_model
|
|
1901
|
+
raise NotImplementedError()
|
|
1902
|
+
c = repeat(c, "1 ... -> b ...", b=batch_size).to(self.device)
|
|
1903
|
+
return c
|
|
1904
|
+
|
|
1905
|
+
@torch.no_grad()
|
|
1906
|
+
def log_images(
|
|
1907
|
+
self,
|
|
1908
|
+
batch,
|
|
1909
|
+
N=8,
|
|
1910
|
+
n_row=4,
|
|
1911
|
+
sample=True,
|
|
1912
|
+
ddim_steps=50,
|
|
1913
|
+
ddim_eta=1.0,
|
|
1914
|
+
return_keys=None,
|
|
1915
|
+
quantize_denoised=True,
|
|
1916
|
+
inpaint=False,
|
|
1917
|
+
plot_denoise_rows=False,
|
|
1918
|
+
plot_progressive_rows=False,
|
|
1919
|
+
plot_diffusion_rows=False,
|
|
1920
|
+
**kwargs,
|
|
1921
|
+
):
|
|
1922
|
+
|
|
1923
|
+
use_ddim = ddim_steps is not None
|
|
1924
|
+
|
|
1925
|
+
log = dict()
|
|
1926
|
+
z, c, x, xrec, xc = self.get_input(
|
|
1927
|
+
batch,
|
|
1928
|
+
self.first_stage_key,
|
|
1929
|
+
return_first_stage_outputs=True,
|
|
1930
|
+
force_c_encode=True,
|
|
1931
|
+
return_original_cond=True,
|
|
1932
|
+
bs=N,
|
|
1933
|
+
)
|
|
1934
|
+
N = min(x.shape[0], N)
|
|
1935
|
+
n_row = min(x.shape[0], n_row)
|
|
1936
|
+
log['inputs'] = x
|
|
1937
|
+
log['reconstruction'] = xrec
|
|
1938
|
+
if self.model.conditioning_key is not None:
|
|
1939
|
+
if hasattr(self.cond_stage_model, 'decode'):
|
|
1940
|
+
xc = self.cond_stage_model.decode(c)
|
|
1941
|
+
log['conditioning'] = xc
|
|
1942
|
+
elif self.cond_stage_key in ['caption']:
|
|
1943
|
+
xc = log_txt_as_img((x.shape[2], x.shape[3]), batch['caption'])
|
|
1944
|
+
log['conditioning'] = xc
|
|
1945
|
+
elif self.cond_stage_key == 'class_label':
|
|
1946
|
+
xc = log_txt_as_img(
|
|
1947
|
+
(x.shape[2], x.shape[3]), batch['human_label']
|
|
1948
|
+
)
|
|
1949
|
+
log['conditioning'] = xc
|
|
1950
|
+
elif isimage(xc):
|
|
1951
|
+
log['conditioning'] = xc
|
|
1952
|
+
if ismap(xc):
|
|
1953
|
+
log['original_conditioning'] = self.to_rgb(xc)
|
|
1954
|
+
|
|
1955
|
+
if plot_diffusion_rows:
|
|
1956
|
+
# get diffusion row
|
|
1957
|
+
diffusion_row = list()
|
|
1958
|
+
z_start = z[:n_row]
|
|
1959
|
+
for t in range(self.num_timesteps):
|
|
1960
|
+
if t % self.log_every_t == 0 or t == self.num_timesteps - 1:
|
|
1961
|
+
t = repeat(torch.tensor([t]), '1 -> b', b=n_row)
|
|
1962
|
+
t = t.to(self.device).long()
|
|
1963
|
+
noise = torch.randn_like(z_start)
|
|
1964
|
+
z_noisy = self.q_sample(x_start=z_start, t=t, noise=noise)
|
|
1965
|
+
diffusion_row.append(self.decode_first_stage(z_noisy))
|
|
1966
|
+
|
|
1967
|
+
diffusion_row = torch.stack(
|
|
1968
|
+
diffusion_row
|
|
1969
|
+
) # n_log_step, n_row, C, H, W
|
|
1970
|
+
diffusion_grid = rearrange(diffusion_row, 'n b c h w -> b n c h w')
|
|
1971
|
+
diffusion_grid = rearrange(
|
|
1972
|
+
diffusion_grid, 'b n c h w -> (b n) c h w'
|
|
1973
|
+
)
|
|
1974
|
+
diffusion_grid = make_grid(
|
|
1975
|
+
diffusion_grid, nrow=diffusion_row.shape[0]
|
|
1976
|
+
)
|
|
1977
|
+
log['diffusion_row'] = diffusion_grid
|
|
1978
|
+
|
|
1979
|
+
if sample:
|
|
1980
|
+
# get denoise row
|
|
1981
|
+
with self.ema_scope('Plotting'):
|
|
1982
|
+
samples, z_denoise_row = self.sample_log(
|
|
1983
|
+
cond=c,
|
|
1984
|
+
batch_size=N,
|
|
1985
|
+
ddim=use_ddim,
|
|
1986
|
+
ddim_steps=ddim_steps,
|
|
1987
|
+
eta=ddim_eta,
|
|
1988
|
+
)
|
|
1989
|
+
# samples, z_denoise_row = self.sample(cond=c, batch_size=N, return_intermediates=True)
|
|
1990
|
+
x_samples = self.decode_first_stage(samples)
|
|
1991
|
+
log['samples'] = x_samples
|
|
1992
|
+
if plot_denoise_rows:
|
|
1993
|
+
denoise_grid = self._get_denoise_row_from_list(z_denoise_row)
|
|
1994
|
+
log['denoise_row'] = denoise_grid
|
|
1995
|
+
|
|
1996
|
+
uc = self.get_learned_conditioning(len(c) * [''])
|
|
1997
|
+
sample_scaled, _ = self.sample_log(
|
|
1998
|
+
cond=c,
|
|
1999
|
+
batch_size=N,
|
|
2000
|
+
ddim=use_ddim,
|
|
2001
|
+
ddim_steps=ddim_steps,
|
|
2002
|
+
eta=ddim_eta,
|
|
2003
|
+
unconditional_guidance_scale=5.0,
|
|
2004
|
+
unconditional_conditioning=uc,
|
|
2005
|
+
)
|
|
2006
|
+
log['samples_scaled'] = self.decode_first_stage(sample_scaled)
|
|
2007
|
+
|
|
2008
|
+
if (
|
|
2009
|
+
quantize_denoised
|
|
2010
|
+
and not isinstance(self.first_stage_model, AutoencoderKL)
|
|
2011
|
+
and not isinstance(self.first_stage_model, IdentityFirstStage)
|
|
2012
|
+
):
|
|
2013
|
+
# also display when quantizing x0 while sampling
|
|
2014
|
+
with self.ema_scope('Plotting Quantized Denoised'):
|
|
2015
|
+
samples, z_denoise_row = self.sample_log(
|
|
2016
|
+
cond=c,
|
|
2017
|
+
batch_size=N,
|
|
2018
|
+
ddim=use_ddim,
|
|
2019
|
+
ddim_steps=ddim_steps,
|
|
2020
|
+
eta=ddim_eta,
|
|
2021
|
+
quantize_denoised=True,
|
|
2022
|
+
)
|
|
2023
|
+
# samples, z_denoise_row = self.sample(cond=c, batch_size=N, return_intermediates=True,
|
|
2024
|
+
# quantize_denoised=True)
|
|
2025
|
+
x_samples = self.decode_first_stage(samples.to(self.device))
|
|
2026
|
+
log['samples_x0_quantized'] = x_samples
|
|
2027
|
+
|
|
2028
|
+
if inpaint:
|
|
2029
|
+
# make a simple center square
|
|
2030
|
+
b, h, w = z.shape[0], z.shape[2], z.shape[3]
|
|
2031
|
+
mask = torch.ones(N, h, w).to(self.device)
|
|
2032
|
+
# zeros will be filled in
|
|
2033
|
+
mask[:, h // 4 : 3 * h // 4, w // 4 : 3 * w // 4] = 0.0
|
|
2034
|
+
mask = mask[:, None, ...]
|
|
2035
|
+
with self.ema_scope('Plotting Inpaint'):
|
|
2036
|
+
|
|
2037
|
+
samples, _ = self.sample_log(
|
|
2038
|
+
cond=c,
|
|
2039
|
+
batch_size=N,
|
|
2040
|
+
ddim=use_ddim,
|
|
2041
|
+
eta=ddim_eta,
|
|
2042
|
+
ddim_steps=ddim_steps,
|
|
2043
|
+
x0=z[:N],
|
|
2044
|
+
mask=mask,
|
|
2045
|
+
)
|
|
2046
|
+
x_samples = self.decode_first_stage(samples.to(self.device))
|
|
2047
|
+
log['samples_inpainting'] = x_samples
|
|
2048
|
+
log['mask'] = mask
|
|
2049
|
+
|
|
2050
|
+
# outpaint
|
|
2051
|
+
with self.ema_scope('Plotting Outpaint'):
|
|
2052
|
+
samples, _ = self.sample_log(
|
|
2053
|
+
cond=c,
|
|
2054
|
+
batch_size=N,
|
|
2055
|
+
ddim=use_ddim,
|
|
2056
|
+
eta=ddim_eta,
|
|
2057
|
+
ddim_steps=ddim_steps,
|
|
2058
|
+
x0=z[:N],
|
|
2059
|
+
mask=mask,
|
|
2060
|
+
)
|
|
2061
|
+
x_samples = self.decode_first_stage(samples.to(self.device))
|
|
2062
|
+
log['samples_outpainting'] = x_samples
|
|
2063
|
+
|
|
2064
|
+
if plot_progressive_rows:
|
|
2065
|
+
with self.ema_scope('Plotting Progressives'):
|
|
2066
|
+
img, progressives = self.progressive_denoising(
|
|
2067
|
+
c,
|
|
2068
|
+
shape=(self.channels, self.image_size, self.image_size),
|
|
2069
|
+
batch_size=N,
|
|
2070
|
+
)
|
|
2071
|
+
prog_row = self._get_denoise_row_from_list(
|
|
2072
|
+
progressives, desc='Progressive Generation'
|
|
2073
|
+
)
|
|
2074
|
+
log['progressive_row'] = prog_row
|
|
2075
|
+
|
|
2076
|
+
if return_keys:
|
|
2077
|
+
if np.intersect1d(list(log.keys()), return_keys).shape[0] == 0:
|
|
2078
|
+
return log
|
|
2079
|
+
else:
|
|
2080
|
+
return {key: log[key] for key in return_keys}
|
|
2081
|
+
return log
|
|
2082
|
+
|
|
2083
|
+
def configure_optimizers(self):
|
|
2084
|
+
lr = self.learning_rate
|
|
2085
|
+
|
|
2086
|
+
if self.embedding_manager is not None:
|
|
2087
|
+
params = list(self.embedding_manager.embedding_parameters())
|
|
2088
|
+
# params = list(self.cond_stage_model.transformer.text_model.embeddings.embedding_manager.embedding_parameters())
|
|
2089
|
+
else:
|
|
2090
|
+
params = list(self.model.parameters())
|
|
2091
|
+
if self.cond_stage_trainable:
|
|
2092
|
+
print(
|
|
2093
|
+
f'{self.__class__.__name__}: Also optimizing conditioner params!'
|
|
2094
|
+
)
|
|
2095
|
+
params = params + list(self.cond_stage_model.parameters())
|
|
2096
|
+
if self.learn_logvar:
|
|
2097
|
+
print('Diffusion model optimizing logvar')
|
|
2098
|
+
params.append(self.logvar)
|
|
2099
|
+
opt = torch.optim.AdamW(params, lr=lr)
|
|
2100
|
+
if self.use_scheduler:
|
|
2101
|
+
assert 'target' in self.scheduler_config
|
|
2102
|
+
scheduler = instantiate_from_config(self.scheduler_config)
|
|
2103
|
+
|
|
2104
|
+
print('Setting up LambdaLR scheduler...')
|
|
2105
|
+
scheduler = [
|
|
2106
|
+
{
|
|
2107
|
+
'scheduler': LambdaLR(opt, lr_lambda=scheduler.schedule),
|
|
2108
|
+
'interval': 'step',
|
|
2109
|
+
'frequency': 1,
|
|
2110
|
+
}
|
|
2111
|
+
]
|
|
2112
|
+
return [opt], scheduler
|
|
2113
|
+
return opt
|
|
2114
|
+
|
|
2115
|
+
@torch.no_grad()
|
|
2116
|
+
def to_rgb(self, x):
|
|
2117
|
+
x = x.float()
|
|
2118
|
+
if not hasattr(self, 'colorize'):
|
|
2119
|
+
self.colorize = torch.randn(3, x.shape[1], 1, 1).to(x)
|
|
2120
|
+
x = nn.functional.conv2d(x, weight=self.colorize)
|
|
2121
|
+
x = 2.0 * (x - x.min()) / (x.max() - x.min()) - 1.0
|
|
2122
|
+
return x
|
|
2123
|
+
|
|
2124
|
+
@rank_zero_only
|
|
2125
|
+
def on_save_checkpoint(self, checkpoint):
|
|
2126
|
+
checkpoint.clear()
|
|
2127
|
+
|
|
2128
|
+
if os.path.isdir(self.trainer.checkpoint_callback.dirpath):
|
|
2129
|
+
self.embedding_manager.save(
|
|
2130
|
+
os.path.join(
|
|
2131
|
+
self.trainer.checkpoint_callback.dirpath, 'embeddings.pt'
|
|
2132
|
+
)
|
|
2133
|
+
)
|
|
2134
|
+
|
|
2135
|
+
if (self.global_step - self.emb_ckpt_counter) > 500:
|
|
2136
|
+
self.embedding_manager.save(
|
|
2137
|
+
os.path.join(
|
|
2138
|
+
self.trainer.checkpoint_callback.dirpath,
|
|
2139
|
+
f'embeddings_gs-{self.global_step}.pt',
|
|
2140
|
+
)
|
|
2141
|
+
)
|
|
2142
|
+
|
|
2143
|
+
self.emb_ckpt_counter += 500
|
|
2144
|
+
|
|
2145
|
+
|
|
2146
|
+
class DiffusionWrapper(pl.LightningModule):
|
|
2147
|
+
def __init__(self, diff_model_config, conditioning_key):
|
|
2148
|
+
super().__init__()
|
|
2149
|
+
self.diffusion_model = instantiate_from_config(diff_model_config)
|
|
2150
|
+
self.conditioning_key = conditioning_key
|
|
2151
|
+
assert self.conditioning_key in [
|
|
2152
|
+
None,
|
|
2153
|
+
'concat',
|
|
2154
|
+
'crossattn',
|
|
2155
|
+
'hybrid',
|
|
2156
|
+
'adm',
|
|
2157
|
+
]
|
|
2158
|
+
|
|
2159
|
+
def forward(self, x, t, c_concat: list = None, c_crossattn: list = None):
|
|
2160
|
+
if self.conditioning_key is None:
|
|
2161
|
+
out = self.diffusion_model(x, t)
|
|
2162
|
+
elif self.conditioning_key == 'concat':
|
|
2163
|
+
xc = torch.cat([x] + c_concat, dim=1)
|
|
2164
|
+
out = self.diffusion_model(xc, t)
|
|
2165
|
+
elif self.conditioning_key == 'crossattn':
|
|
2166
|
+
cc = torch.cat(c_crossattn, 1)
|
|
2167
|
+
out = self.diffusion_model(x, t, context=cc)
|
|
2168
|
+
elif self.conditioning_key == 'hybrid':
|
|
2169
|
+
cc = torch.cat(c_crossattn, 1)
|
|
2170
|
+
xc = torch.cat([x] + c_concat, dim=1)
|
|
2171
|
+
out = self.diffusion_model(xc, t, context=cc)
|
|
2172
|
+
elif self.conditioning_key == 'adm':
|
|
2173
|
+
cc = c_crossattn[0]
|
|
2174
|
+
out = self.diffusion_model(x, t, y=cc)
|
|
2175
|
+
else:
|
|
2176
|
+
raise NotImplementedError()
|
|
2177
|
+
|
|
2178
|
+
return out
|
|
2179
|
+
|
|
2180
|
+
|
|
2181
|
+
class Layout2ImgDiffusion(LatentDiffusion):
|
|
2182
|
+
# TODO: move all layout-specific hacks to this class
|
|
2183
|
+
def __init__(self, cond_stage_key, *args, **kwargs):
|
|
2184
|
+
assert (
|
|
2185
|
+
cond_stage_key == 'coordinates_bbox'
|
|
2186
|
+
), 'Layout2ImgDiffusion only for cond_stage_key="coordinates_bbox"'
|
|
2187
|
+
super().__init__(cond_stage_key=cond_stage_key, *args, **kwargs)
|
|
2188
|
+
|
|
2189
|
+
def log_images(self, batch, N=8, *args, **kwargs):
|
|
2190
|
+
logs = super().log_images(batch=batch, N=N, *args, **kwargs)
|
|
2191
|
+
|
|
2192
|
+
key = 'train' if self.training else 'validation'
|
|
2193
|
+
dset = self.trainer.datamodule.datasets[key]
|
|
2194
|
+
mapper = dset.conditional_builders[self.cond_stage_key]
|
|
2195
|
+
|
|
2196
|
+
bbox_imgs = []
|
|
2197
|
+
map_fn = lambda catno: dset.get_textual_label(
|
|
2198
|
+
dset.get_category_id(catno)
|
|
2199
|
+
)
|
|
2200
|
+
for tknzd_bbox in batch[self.cond_stage_key][:N]:
|
|
2201
|
+
bboximg = mapper.plot(
|
|
2202
|
+
tknzd_bbox.detach().cpu(), map_fn, (256, 256)
|
|
2203
|
+
)
|
|
2204
|
+
bbox_imgs.append(bboximg)
|
|
2205
|
+
|
|
2206
|
+
cond_img = torch.stack(bbox_imgs, dim=0)
|
|
2207
|
+
logs['bbox_image'] = cond_img
|
|
2208
|
+
return logs
|
|
2209
|
+
|
|
2210
|
+
class LatentInpaintDiffusion(LatentDiffusion):
|
|
2211
|
+
def __init__(
|
|
2212
|
+
self,
|
|
2213
|
+
concat_keys=("mask", "masked_image"),
|
|
2214
|
+
masked_image_key="masked_image",
|
|
2215
|
+
finetune_keys=None,
|
|
2216
|
+
*args,
|
|
2217
|
+
**kwargs,
|
|
2218
|
+
):
|
|
2219
|
+
super().__init__(*args, **kwargs)
|
|
2220
|
+
self.masked_image_key = masked_image_key
|
|
2221
|
+
assert self.masked_image_key in concat_keys
|
|
2222
|
+
self.concat_keys = concat_keys
|
|
2223
|
+
|
|
2224
|
+
|
|
2225
|
+
@torch.no_grad()
|
|
2226
|
+
def get_input(
|
|
2227
|
+
self, batch, k, cond_key=None, bs=None, return_first_stage_outputs=False
|
|
2228
|
+
):
|
|
2229
|
+
# note: restricted to non-trainable encoders currently
|
|
2230
|
+
assert (
|
|
2231
|
+
not self.cond_stage_trainable
|
|
2232
|
+
), "trainable cond stages not yet supported for inpainting"
|
|
2233
|
+
z, c, x, xrec, xc = super().get_input(
|
|
2234
|
+
batch,
|
|
2235
|
+
self.first_stage_key,
|
|
2236
|
+
return_first_stage_outputs=True,
|
|
2237
|
+
force_c_encode=True,
|
|
2238
|
+
return_original_cond=True,
|
|
2239
|
+
bs=bs,
|
|
2240
|
+
)
|
|
2241
|
+
|
|
2242
|
+
assert exists(self.concat_keys)
|
|
2243
|
+
c_cat = list()
|
|
2244
|
+
for ck in self.concat_keys:
|
|
2245
|
+
cc = (
|
|
2246
|
+
rearrange(batch[ck], "b h w c -> b c h w")
|
|
2247
|
+
.to(memory_format=torch.contiguous_format)
|
|
2248
|
+
.float()
|
|
2249
|
+
)
|
|
2250
|
+
if bs is not None:
|
|
2251
|
+
cc = cc[:bs]
|
|
2252
|
+
cc = cc.to(self.device)
|
|
2253
|
+
bchw = z.shape
|
|
2254
|
+
if ck != self.masked_image_key:
|
|
2255
|
+
cc = torch.nn.functional.interpolate(cc, size=bchw[-2:])
|
|
2256
|
+
else:
|
|
2257
|
+
cc = self.get_first_stage_encoding(self.encode_first_stage(cc))
|
|
2258
|
+
c_cat.append(cc)
|
|
2259
|
+
c_cat = torch.cat(c_cat, dim=1)
|
|
2260
|
+
all_conds = {"c_concat": [c_cat], "c_crossattn": [c]}
|
|
2261
|
+
if return_first_stage_outputs:
|
|
2262
|
+
return z, all_conds, x, xrec, xc
|
|
2263
|
+
return z, all_conds
|