sd_samplers_common.py 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326
  1. import inspect
  2. from collections import namedtuple
  3. import numpy as np
  4. import torch
  5. from PIL import Image
  6. from modules import devices, images, sd_vae_approx, sd_samplers, sd_vae_taesd, shared, sd_models
  7. from modules.shared import opts, state
  8. import k_diffusion.sampling
  9. SamplerDataTuple = namedtuple('SamplerData', ['name', 'constructor', 'aliases', 'options'])
  10. class SamplerData(SamplerDataTuple):
  11. def total_steps(self, steps):
  12. if self.options.get("second_order", False):
  13. steps = steps * 2
  14. return steps
  15. def setup_img2img_steps(p, steps=None):
  16. if opts.img2img_fix_steps or steps is not None:
  17. requested_steps = (steps or p.steps)
  18. steps = int(requested_steps / min(p.denoising_strength, 0.999)) if p.denoising_strength > 0 else 0
  19. t_enc = requested_steps - 1
  20. else:
  21. steps = p.steps
  22. t_enc = int(min(p.denoising_strength, 0.999) * steps)
  23. return steps, t_enc
  24. approximation_indexes = {"Full": 0, "Approx NN": 1, "Approx cheap": 2, "TAESD": 3}
  25. def samples_to_images_tensor(sample, approximation=None, model=None):
  26. """Transforms 4-channel latent space images into 3-channel RGB image tensors, with values in range [-1, 1]."""
  27. if approximation is None or (shared.state.interrupted and opts.live_preview_fast_interrupt):
  28. approximation = approximation_indexes.get(opts.show_progress_type, 0)
  29. from modules import lowvram
  30. if approximation == 0 and lowvram.is_enabled(shared.sd_model) and not shared.opts.live_preview_allow_lowvram_full:
  31. approximation = 1
  32. if approximation == 2:
  33. x_sample = sd_vae_approx.cheap_approximation(sample)
  34. elif approximation == 1:
  35. x_sample = sd_vae_approx.model()(sample.to(devices.device, devices.dtype)).detach()
  36. elif approximation == 3:
  37. x_sample = sd_vae_taesd.decoder_model()(sample.to(devices.device, devices.dtype)).detach()
  38. x_sample = x_sample * 2 - 1
  39. else:
  40. if model is None:
  41. model = shared.sd_model
  42. with devices.without_autocast(): # fixes an issue with unstable VAEs that are flaky even in fp32
  43. x_sample = model.decode_first_stage(sample.to(model.first_stage_model.dtype))
  44. return x_sample
  45. def single_sample_to_image(sample, approximation=None):
  46. x_sample = samples_to_images_tensor(sample.unsqueeze(0), approximation)[0] * 0.5 + 0.5
  47. x_sample = torch.clamp(x_sample, min=0.0, max=1.0)
  48. x_sample = 255. * np.moveaxis(x_sample.cpu().numpy(), 0, 2)
  49. x_sample = x_sample.astype(np.uint8)
  50. return Image.fromarray(x_sample)
  51. def decode_first_stage(model, x):
  52. x = x.to(devices.dtype_vae)
  53. approx_index = approximation_indexes.get(opts.sd_vae_decode_method, 0)
  54. return samples_to_images_tensor(x, approx_index, model)
  55. def sample_to_image(samples, index=0, approximation=None):
  56. return single_sample_to_image(samples[index], approximation)
  57. def samples_to_image_grid(samples, approximation=None):
  58. return images.image_grid([single_sample_to_image(sample, approximation) for sample in samples])
  59. def images_tensor_to_samples(image, approximation=None, model=None):
  60. '''image[0, 1] -> latent'''
  61. if approximation is None:
  62. approximation = approximation_indexes.get(opts.sd_vae_encode_method, 0)
  63. if approximation == 3:
  64. image = image.to(devices.device, devices.dtype)
  65. x_latent = sd_vae_taesd.encoder_model()(image)
  66. else:
  67. if model is None:
  68. model = shared.sd_model
  69. image = image.to(shared.device, dtype=devices.dtype_vae)
  70. image = image * 2 - 1
  71. if len(image) > 1:
  72. x_latent = torch.stack([
  73. model.get_first_stage_encoding(
  74. model.encode_first_stage(torch.unsqueeze(img, 0))
  75. )[0]
  76. for img in image
  77. ])
  78. else:
  79. x_latent = model.get_first_stage_encoding(model.encode_first_stage(image))
  80. return x_latent
  81. def store_latent(decoded):
  82. state.current_latent = decoded
  83. if opts.live_previews_enable and opts.show_progress_every_n_steps > 0 and shared.state.sampling_step % opts.show_progress_every_n_steps == 0:
  84. if not shared.parallel_processing_allowed:
  85. shared.state.assign_current_image(sample_to_image(decoded))
  86. def is_sampler_using_eta_noise_seed_delta(p):
  87. """returns whether sampler from config will use eta noise seed delta for image creation"""
  88. sampler_config = sd_samplers.find_sampler_config(p.sampler_name)
  89. eta = p.eta
  90. if eta is None and p.sampler is not None:
  91. eta = p.sampler.eta
  92. if eta is None and sampler_config is not None:
  93. eta = 0 if sampler_config.options.get("default_eta_is_0", False) else 1.0
  94. if eta == 0:
  95. return False
  96. return sampler_config.options.get("uses_ensd", False)
  97. class InterruptedException(BaseException):
  98. pass
  99. def replace_torchsde_browinan():
  100. import torchsde._brownian.brownian_interval
  101. def torchsde_randn(size, dtype, device, seed):
  102. return devices.randn_local(seed, size).to(device=device, dtype=dtype)
  103. torchsde._brownian.brownian_interval._randn = torchsde_randn
  104. replace_torchsde_browinan()
  105. def apply_refiner(cfg_denoiser):
  106. completed_ratio = cfg_denoiser.step / cfg_denoiser.total_steps
  107. refiner_switch_at = cfg_denoiser.p.refiner_switch_at
  108. refiner_checkpoint_info = cfg_denoiser.p.refiner_checkpoint_info
  109. if refiner_switch_at is not None and completed_ratio < refiner_switch_at:
  110. return False
  111. if refiner_checkpoint_info is None or shared.sd_model.sd_checkpoint_info == refiner_checkpoint_info:
  112. return False
  113. if getattr(cfg_denoiser.p, "enable_hr", False) and not cfg_denoiser.p.is_hr_pass:
  114. return False
  115. cfg_denoiser.p.extra_generation_params['Refiner'] = refiner_checkpoint_info.short_title
  116. cfg_denoiser.p.extra_generation_params['Refiner switch at'] = refiner_switch_at
  117. with sd_models.SkipWritingToConfig():
  118. sd_models.reload_model_weights(info=refiner_checkpoint_info)
  119. devices.torch_gc()
  120. cfg_denoiser.p.setup_conds()
  121. cfg_denoiser.update_inner_model()
  122. return True
  123. class TorchHijack:
  124. """This is here to replace torch.randn_like of k-diffusion.
  125. k-diffusion has random_sampler argument for most samplers, but not for all, so
  126. this is needed to properly replace every use of torch.randn_like.
  127. We need to replace to make images generated in batches to be same as images generated individually."""
  128. def __init__(self, p):
  129. self.rng = p.rng
  130. def __getattr__(self, item):
  131. if item == 'randn_like':
  132. return self.randn_like
  133. if hasattr(torch, item):
  134. return getattr(torch, item)
  135. raise AttributeError(f"'{type(self).__name__}' object has no attribute '{item}'")
  136. def randn_like(self, x):
  137. return self.rng.next()
  138. class Sampler:
  139. def __init__(self, funcname):
  140. self.funcname = funcname
  141. self.func = funcname
  142. self.extra_params = []
  143. self.sampler_noises = None
  144. self.stop_at = None
  145. self.eta = None
  146. self.config: SamplerData = None # set by the function calling the constructor
  147. self.last_latent = None
  148. self.s_min_uncond = None
  149. self.s_churn = 0.0
  150. self.s_tmin = 0.0
  151. self.s_tmax = float('inf')
  152. self.s_noise = 1.0
  153. self.eta_option_field = 'eta_ancestral'
  154. self.eta_infotext_field = 'Eta'
  155. self.eta_default = 1.0
  156. self.conditioning_key = shared.sd_model.model.conditioning_key
  157. self.p = None
  158. self.model_wrap_cfg = None
  159. self.sampler_extra_args = None
  160. self.options = {}
  161. def callback_state(self, d):
  162. step = d['i']
  163. if self.stop_at is not None and step > self.stop_at:
  164. raise InterruptedException
  165. state.sampling_step = step
  166. shared.total_tqdm.update()
  167. def launch_sampling(self, steps, func):
  168. self.model_wrap_cfg.steps = steps
  169. self.model_wrap_cfg.total_steps = self.config.total_steps(steps)
  170. state.sampling_steps = steps
  171. state.sampling_step = 0
  172. try:
  173. return func()
  174. except RecursionError:
  175. print(
  176. 'Encountered RecursionError during sampling, returning last latent. '
  177. 'rho >5 with a polyexponential scheduler may cause this error. '
  178. 'You should try to use a smaller rho value instead.'
  179. )
  180. return self.last_latent
  181. except InterruptedException:
  182. return self.last_latent
  183. def number_of_needed_noises(self, p):
  184. return p.steps
  185. def initialize(self, p) -> dict:
  186. self.p = p
  187. self.model_wrap_cfg.p = p
  188. self.model_wrap_cfg.mask = p.mask if hasattr(p, 'mask') else None
  189. self.model_wrap_cfg.nmask = p.nmask if hasattr(p, 'nmask') else None
  190. self.model_wrap_cfg.step = 0
  191. self.model_wrap_cfg.image_cfg_scale = getattr(p, 'image_cfg_scale', None)
  192. self.eta = p.eta if p.eta is not None else getattr(opts, self.eta_option_field, 0.0)
  193. self.s_min_uncond = getattr(p, 's_min_uncond', 0.0)
  194. k_diffusion.sampling.torch = TorchHijack(p)
  195. extra_params_kwargs = {}
  196. for param_name in self.extra_params:
  197. if hasattr(p, param_name) and param_name in inspect.signature(self.func).parameters:
  198. extra_params_kwargs[param_name] = getattr(p, param_name)
  199. if 'eta' in inspect.signature(self.func).parameters:
  200. if self.eta != self.eta_default:
  201. p.extra_generation_params[self.eta_infotext_field] = self.eta
  202. extra_params_kwargs['eta'] = self.eta
  203. if len(self.extra_params) > 0:
  204. s_churn = getattr(opts, 's_churn', p.s_churn)
  205. s_tmin = getattr(opts, 's_tmin', p.s_tmin)
  206. s_tmax = getattr(opts, 's_tmax', p.s_tmax) or self.s_tmax # 0 = inf
  207. s_noise = getattr(opts, 's_noise', p.s_noise)
  208. if 's_churn' in extra_params_kwargs and s_churn != self.s_churn:
  209. extra_params_kwargs['s_churn'] = s_churn
  210. p.s_churn = s_churn
  211. p.extra_generation_params['Sigma churn'] = s_churn
  212. if 's_tmin' in extra_params_kwargs and s_tmin != self.s_tmin:
  213. extra_params_kwargs['s_tmin'] = s_tmin
  214. p.s_tmin = s_tmin
  215. p.extra_generation_params['Sigma tmin'] = s_tmin
  216. if 's_tmax' in extra_params_kwargs and s_tmax != self.s_tmax:
  217. extra_params_kwargs['s_tmax'] = s_tmax
  218. p.s_tmax = s_tmax
  219. p.extra_generation_params['Sigma tmax'] = s_tmax
  220. if 's_noise' in extra_params_kwargs and s_noise != self.s_noise:
  221. extra_params_kwargs['s_noise'] = s_noise
  222. p.s_noise = s_noise
  223. p.extra_generation_params['Sigma noise'] = s_noise
  224. return extra_params_kwargs
  225. def create_noise_sampler(self, x, sigmas, p):
  226. """For DPM++ SDE: manually create noise sampler to enable deterministic results across different batch sizes"""
  227. if shared.opts.no_dpmpp_sde_batch_determinism:
  228. return None
  229. from k_diffusion.sampling import BrownianTreeNoiseSampler
  230. sigma_min, sigma_max = sigmas[sigmas > 0].min(), sigmas.max()
  231. current_iter_seeds = p.all_seeds[p.iteration * p.batch_size:(p.iteration + 1) * p.batch_size]
  232. return BrownianTreeNoiseSampler(x, sigma_min, sigma_max, seed=current_iter_seeds)
  233. def sample(self, p, x, conditioning, unconditional_conditioning, steps=None, image_conditioning=None):
  234. raise NotImplementedError()
  235. def sample_img2img(self, p, x, noise, conditioning, unconditional_conditioning, steps=None, image_conditioning=None):
  236. raise NotImplementedError()