ddim.py 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. """SAMPLING ONLY."""
  2. import torch
  3. import numpy as np
  4. from tqdm import tqdm
  5. from functools import partial
  6. from ldm.modules.diffusionmodules.util import make_ddim_sampling_parameters, make_ddim_timesteps, noise_like
  7. class DDIMSampler(object):
  8. def __init__(self, model, schedule="linear", **kwargs):
  9. super().__init__()
  10. self.model = model
  11. self.ddpm_num_timesteps = model.num_timesteps
  12. self.schedule = schedule
  13. def register_buffer(self, name, attr):
  14. if type(attr) == torch.Tensor:
  15. if attr.device != torch.device("cuda"):
  16. attr = attr.to(torch.device("cuda"))
  17. setattr(self, name, attr)
  18. def make_schedule(self, ddim_num_steps, ddim_discretize="uniform", ddim_eta=0., verbose=True):
  19. self.ddim_timesteps = make_ddim_timesteps(ddim_discr_method=ddim_discretize, num_ddim_timesteps=ddim_num_steps,
  20. num_ddpm_timesteps=self.ddpm_num_timesteps,verbose=verbose)
  21. alphas_cumprod = self.model.alphas_cumprod
  22. assert alphas_cumprod.shape[0] == self.ddpm_num_timesteps, 'alphas have to be defined for each timestep'
  23. to_torch = lambda x: x.clone().detach().to(torch.float32).to(self.model.device)
  24. self.register_buffer('betas', to_torch(self.model.betas))
  25. self.register_buffer('alphas_cumprod', to_torch(alphas_cumprod))
  26. self.register_buffer('alphas_cumprod_prev', to_torch(self.model.alphas_cumprod_prev))
  27. # calculations for diffusion q(x_t | x_{t-1}) and others
  28. self.register_buffer('sqrt_alphas_cumprod', to_torch(np.sqrt(alphas_cumprod.cpu())))
  29. self.register_buffer('sqrt_one_minus_alphas_cumprod', to_torch(np.sqrt(1. - alphas_cumprod.cpu())))
  30. self.register_buffer('log_one_minus_alphas_cumprod', to_torch(np.log(1. - alphas_cumprod.cpu())))
  31. self.register_buffer('sqrt_recip_alphas_cumprod', to_torch(np.sqrt(1. / alphas_cumprod.cpu())))
  32. self.register_buffer('sqrt_recipm1_alphas_cumprod', to_torch(np.sqrt(1. / alphas_cumprod.cpu() - 1)))
  33. # ddim sampling parameters
  34. ddim_sigmas, ddim_alphas, ddim_alphas_prev = make_ddim_sampling_parameters(alphacums=alphas_cumprod.cpu(),
  35. ddim_timesteps=self.ddim_timesteps,
  36. eta=ddim_eta,verbose=verbose)
  37. self.register_buffer('ddim_sigmas', ddim_sigmas)
  38. self.register_buffer('ddim_alphas', ddim_alphas)
  39. self.register_buffer('ddim_alphas_prev', ddim_alphas_prev)
  40. self.register_buffer('ddim_sqrt_one_minus_alphas', np.sqrt(1. - ddim_alphas))
  41. sigmas_for_original_sampling_steps = ddim_eta * torch.sqrt(
  42. (1 - self.alphas_cumprod_prev) / (1 - self.alphas_cumprod) * (
  43. 1 - self.alphas_cumprod / self.alphas_cumprod_prev))
  44. self.register_buffer('ddim_sigmas_for_original_num_steps', sigmas_for_original_sampling_steps)
  45. @torch.no_grad()
  46. def sample(self,
  47. S,
  48. batch_size,
  49. shape,
  50. conditioning=None,
  51. callback=None,
  52. normals_sequence=None,
  53. img_callback=None,
  54. quantize_x0=False,
  55. eta=0.,
  56. mask=None,
  57. x0=None,
  58. temperature=1.,
  59. noise_dropout=0.,
  60. score_corrector=None,
  61. corrector_kwargs=None,
  62. verbose=True,
  63. x_T=None,
  64. log_every_t=100,
  65. **kwargs
  66. ):
  67. if conditioning is not None:
  68. if isinstance(conditioning, dict):
  69. cbs = conditioning[list(conditioning.keys())[0]].shape[0]
  70. if cbs != batch_size:
  71. print(f"Warning: Got {cbs} conditionings but batch-size is {batch_size}")
  72. else:
  73. if conditioning.shape[0] != batch_size:
  74. print(f"Warning: Got {conditioning.shape[0]} conditionings but batch-size is {batch_size}")
  75. self.make_schedule(ddim_num_steps=S, ddim_eta=eta, verbose=verbose)
  76. # sampling
  77. C, H, W = shape
  78. size = (batch_size, C, H, W)
  79. print(f'Data shape for DDIM sampling is {size}, eta {eta}')
  80. samples, intermediates = self.ddim_sampling(conditioning, size,
  81. callback=callback,
  82. img_callback=img_callback,
  83. quantize_denoised=quantize_x0,
  84. mask=mask, x0=x0,
  85. ddim_use_original_steps=False,
  86. noise_dropout=noise_dropout,
  87. temperature=temperature,
  88. score_corrector=score_corrector,
  89. corrector_kwargs=corrector_kwargs,
  90. x_T=x_T,
  91. log_every_t=log_every_t
  92. )
  93. return samples, intermediates
  94. @torch.no_grad()
  95. def ddim_sampling(self, cond, shape,
  96. x_T=None, ddim_use_original_steps=False,
  97. callback=None, timesteps=None, quantize_denoised=False,
  98. mask=None, x0=None, img_callback=None, log_every_t=100,
  99. temperature=1., noise_dropout=0., score_corrector=None, corrector_kwargs=None):
  100. device = self.model.betas.device
  101. b = shape[0]
  102. if x_T is None:
  103. img = torch.randn(shape, device=device)
  104. else:
  105. img = x_T
  106. if timesteps is None:
  107. timesteps = self.ddpm_num_timesteps if ddim_use_original_steps else self.ddim_timesteps
  108. elif timesteps is not None and not ddim_use_original_steps:
  109. subset_end = int(min(timesteps / self.ddim_timesteps.shape[0], 1) * self.ddim_timesteps.shape[0]) - 1
  110. timesteps = self.ddim_timesteps[:subset_end]
  111. intermediates = {'x_inter': [img], 'pred_x0': [img]}
  112. time_range = reversed(range(0,timesteps)) if ddim_use_original_steps else np.flip(timesteps)
  113. total_steps = timesteps if ddim_use_original_steps else timesteps.shape[0]
  114. print(f"Running DDIM Sampling with {total_steps} timesteps")
  115. iterator = tqdm(time_range, desc='DDIM Sampler', total=total_steps)
  116. for i, step in enumerate(iterator):
  117. index = total_steps - i - 1
  118. ts = torch.full((b,), step, device=device, dtype=torch.long)
  119. if mask is not None:
  120. assert x0 is not None
  121. img_orig = self.model.q_sample(x0, ts) # TODO: deterministic forward pass?
  122. img = img_orig * mask + (1. - mask) * img
  123. outs = self.p_sample_ddim(img, cond, ts, index=index, use_original_steps=ddim_use_original_steps,
  124. quantize_denoised=quantize_denoised, temperature=temperature,
  125. noise_dropout=noise_dropout, score_corrector=score_corrector,
  126. corrector_kwargs=corrector_kwargs)
  127. img, pred_x0 = outs
  128. if callback: callback(i)
  129. if img_callback: img_callback(pred_x0, i)
  130. if index % log_every_t == 0 or index == total_steps - 1:
  131. intermediates['x_inter'].append(img)
  132. intermediates['pred_x0'].append(pred_x0)
  133. return img, intermediates
  134. @torch.no_grad()
  135. def p_sample_ddim(self, x, c, t, index, repeat_noise=False, use_original_steps=False, quantize_denoised=False,
  136. temperature=1., noise_dropout=0., score_corrector=None, corrector_kwargs=None):
  137. b, *_, device = *x.shape, x.device
  138. e_t = self.model.apply_model(x, t, c)
  139. if score_corrector is not None:
  140. assert self.model.parameterization == "eps"
  141. e_t = score_corrector.modify_score(self.model, e_t, x, t, c, **corrector_kwargs)
  142. alphas = self.model.alphas_cumprod if use_original_steps else self.ddim_alphas
  143. alphas_prev = self.model.alphas_cumprod_prev if use_original_steps else self.ddim_alphas_prev
  144. sqrt_one_minus_alphas = self.model.sqrt_one_minus_alphas_cumprod if use_original_steps else self.ddim_sqrt_one_minus_alphas
  145. sigmas = self.model.ddim_sigmas_for_original_num_steps if use_original_steps else self.ddim_sigmas
  146. # select parameters corresponding to the currently considered timestep
  147. a_t = torch.full((b, 1, 1, 1), alphas[index], device=device)
  148. a_prev = torch.full((b, 1, 1, 1), alphas_prev[index], device=device)
  149. sigma_t = torch.full((b, 1, 1, 1), sigmas[index], device=device)
  150. sqrt_one_minus_at = torch.full((b, 1, 1, 1), sqrt_one_minus_alphas[index],device=device)
  151. # current prediction for x_0
  152. pred_x0 = (x - sqrt_one_minus_at * e_t) / a_t.sqrt()
  153. if quantize_denoised:
  154. pred_x0, _, *_ = self.model.first_stage_model.quantize(pred_x0)
  155. # direction pointing to x_t
  156. dir_xt = (1. - a_prev - sigma_t**2).sqrt() * e_t
  157. noise = sigma_t * noise_like(x.shape, device, repeat_noise) * temperature
  158. if noise_dropout > 0.:
  159. noise = torch.nn.functional.dropout(noise, p=noise_dropout)
  160. x_prev = a_prev.sqrt() * pred_x0 + dir_xt + noise
  161. return x_prev, pred_x0