processing.py 48 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026
  1. import json
  2. import math
  3. import os
  4. import sys
  5. import warnings
  6. import torch
  7. import numpy as np
  8. from PIL import Image, ImageFilter, ImageOps
  9. import random
  10. import cv2
  11. from skimage import exposure
  12. from typing import Any, Dict, List, Optional
  13. import modules.sd_hijack
  14. from modules import devices, prompt_parser, masking, sd_samplers, lowvram, generation_parameters_copypaste, script_callbacks, extra_networks
  15. from modules.sd_hijack import model_hijack
  16. from modules.shared import opts, cmd_opts, state
  17. import modules.shared as shared
  18. import modules.face_restoration
  19. import modules.images as images
  20. import modules.styles
  21. import modules.sd_models as sd_models
  22. import modules.sd_vae as sd_vae
  23. import logging
  24. from ldm.data.util import AddMiDaS
  25. from ldm.models.diffusion.ddpm import LatentDepth2ImageDiffusion
  26. from einops import repeat, rearrange
  27. from blendmodes.blend import blendLayers, BlendType
  28. # some of those options should not be changed at all because they would break the model, so I removed them from options.
  29. opt_C = 4
  30. opt_f = 8
  31. def setup_color_correction(image):
  32. logging.info("Calibrating color correction.")
  33. correction_target = cv2.cvtColor(np.asarray(image.copy()), cv2.COLOR_RGB2LAB)
  34. return correction_target
  35. def apply_color_correction(correction, original_image):
  36. logging.info("Applying color correction.")
  37. image = Image.fromarray(cv2.cvtColor(exposure.match_histograms(
  38. cv2.cvtColor(
  39. np.asarray(original_image),
  40. cv2.COLOR_RGB2LAB
  41. ),
  42. correction,
  43. channel_axis=2
  44. ), cv2.COLOR_LAB2RGB).astype("uint8"))
  45. image = blendLayers(image, original_image, BlendType.LUMINOSITY)
  46. return image
  47. def apply_overlay(image, paste_loc, index, overlays):
  48. if overlays is None or index >= len(overlays):
  49. return image
  50. overlay = overlays[index]
  51. if paste_loc is not None:
  52. x, y, w, h = paste_loc
  53. base_image = Image.new('RGBA', (overlay.width, overlay.height))
  54. image = images.resize_image(1, image, w, h)
  55. base_image.paste(image, (x, y))
  56. image = base_image
  57. image = image.convert('RGBA')
  58. image.alpha_composite(overlay)
  59. image = image.convert('RGB')
  60. return image
  61. def txt2img_image_conditioning(sd_model, x, width, height):
  62. if sd_model.model.conditioning_key not in {'hybrid', 'concat'}:
  63. # Dummy zero conditioning if we're not using inpainting model.
  64. # Still takes up a bit of memory, but no encoder call.
  65. # Pretty sure we can just make this a 1x1 image since its not going to be used besides its batch size.
  66. return x.new_zeros(x.shape[0], 5, 1, 1, dtype=x.dtype, device=x.device)
  67. # The "masked-image" in this case will just be all zeros since the entire image is masked.
  68. image_conditioning = torch.zeros(x.shape[0], 3, height, width, device=x.device)
  69. image_conditioning = sd_model.get_first_stage_encoding(sd_model.encode_first_stage(image_conditioning))
  70. # Add the fake full 1s mask to the first dimension.
  71. image_conditioning = torch.nn.functional.pad(image_conditioning, (0, 0, 0, 0, 1, 0), value=1.0)
  72. image_conditioning = image_conditioning.to(x.dtype)
  73. return image_conditioning
  74. class StableDiffusionProcessing:
  75. """
  76. The first set of paramaters: sd_models -> do_not_reload_embeddings represent the minimum required to create a StableDiffusionProcessing
  77. """
  78. def __init__(self, sd_model=None, outpath_samples=None, outpath_grids=None, prompt: str = "", styles: List[str] = None, seed: int = -1, subseed: int = -1, subseed_strength: float = 0, seed_resize_from_h: int = -1, seed_resize_from_w: int = -1, seed_enable_extras: bool = True, sampler_name: str = None, batch_size: int = 1, n_iter: int = 1, steps: int = 50, cfg_scale: float = 7.0, width: int = 512, height: int = 512, restore_faces: bool = False, tiling: bool = False, do_not_save_samples: bool = False, do_not_save_grid: bool = False, extra_generation_params: Dict[Any, Any] = None, overlay_images: Any = None, negative_prompt: str = None, eta: float = None, do_not_reload_embeddings: bool = False, denoising_strength: float = 0, ddim_discretize: str = None, s_churn: float = 0.0, s_tmax: float = None, s_tmin: float = 0.0, s_noise: float = 1.0, override_settings: Dict[str, Any] = None, override_settings_restore_afterwards: bool = True, sampler_index: int = None, script_args: list = None):
  79. if sampler_index is not None:
  80. print("sampler_index argument for StableDiffusionProcessing does not do anything; use sampler_name", file=sys.stderr)
  81. self.outpath_samples: str = outpath_samples
  82. self.outpath_grids: str = outpath_grids
  83. self.prompt: str = prompt
  84. self.prompt_for_display: str = None
  85. self.negative_prompt: str = (negative_prompt or "")
  86. self.styles: list = styles or []
  87. self.seed: int = seed
  88. self.subseed: int = subseed
  89. self.subseed_strength: float = subseed_strength
  90. self.seed_resize_from_h: int = seed_resize_from_h
  91. self.seed_resize_from_w: int = seed_resize_from_w
  92. self.sampler_name: str = sampler_name
  93. self.batch_size: int = batch_size
  94. self.n_iter: int = n_iter
  95. self.steps: int = steps
  96. self.cfg_scale: float = cfg_scale
  97. self.width: int = width
  98. self.height: int = height
  99. self.restore_faces: bool = restore_faces
  100. self.tiling: bool = tiling
  101. self.do_not_save_samples: bool = do_not_save_samples
  102. self.do_not_save_grid: bool = do_not_save_grid
  103. self.extra_generation_params: dict = extra_generation_params or {}
  104. self.overlay_images = overlay_images
  105. self.eta = eta
  106. self.do_not_reload_embeddings = do_not_reload_embeddings
  107. self.paste_to = None
  108. self.color_corrections = None
  109. self.denoising_strength: float = denoising_strength
  110. self.sampler_noise_scheduler_override = None
  111. self.ddim_discretize = ddim_discretize or opts.ddim_discretize
  112. self.s_churn = s_churn or opts.s_churn
  113. self.s_tmin = s_tmin or opts.s_tmin
  114. self.s_tmax = s_tmax or float('inf') # not representable as a standard ui option
  115. self.s_noise = s_noise or opts.s_noise
  116. self.override_settings = {k: v for k, v in (override_settings or {}).items() if k not in shared.restricted_opts}
  117. self.override_settings_restore_afterwards = override_settings_restore_afterwards
  118. self.is_using_inpainting_conditioning = False
  119. if not seed_enable_extras:
  120. self.subseed = -1
  121. self.subseed_strength = 0
  122. self.seed_resize_from_h = 0
  123. self.seed_resize_from_w = 0
  124. self.scripts = None
  125. self.script_args = script_args
  126. self.all_prompts = None
  127. self.all_negative_prompts = None
  128. self.all_seeds = None
  129. self.all_subseeds = None
  130. self.iteration = 0
  131. @property
  132. def sd_model(self):
  133. return shared.sd_model
  134. def txt2img_image_conditioning(self, x, width=None, height=None):
  135. self.is_using_inpainting_conditioning = self.sd_model.model.conditioning_key in {'hybrid', 'concat'}
  136. return txt2img_image_conditioning(self.sd_model, x, width or self.width, height or self.height)
  137. def depth2img_image_conditioning(self, source_image):
  138. # Use the AddMiDaS helper to Format our source image to suit the MiDaS model
  139. transformer = AddMiDaS(model_type="dpt_hybrid")
  140. transformed = transformer({"jpg": rearrange(source_image[0], "c h w -> h w c")})
  141. midas_in = torch.from_numpy(transformed["midas_in"][None, ...]).to(device=shared.device)
  142. midas_in = repeat(midas_in, "1 ... -> n ...", n=self.batch_size)
  143. conditioning_image = self.sd_model.get_first_stage_encoding(self.sd_model.encode_first_stage(source_image))
  144. conditioning = torch.nn.functional.interpolate(
  145. self.sd_model.depth_model(midas_in),
  146. size=conditioning_image.shape[2:],
  147. mode="bicubic",
  148. align_corners=False,
  149. )
  150. (depth_min, depth_max) = torch.aminmax(conditioning)
  151. conditioning = 2. * (conditioning - depth_min) / (depth_max - depth_min) - 1.
  152. return conditioning
  153. def inpainting_image_conditioning(self, source_image, latent_image, image_mask = None):
  154. self.is_using_inpainting_conditioning = True
  155. # Handle the different mask inputs
  156. if image_mask is not None:
  157. if torch.is_tensor(image_mask):
  158. conditioning_mask = image_mask
  159. else:
  160. conditioning_mask = np.array(image_mask.convert("L"))
  161. conditioning_mask = conditioning_mask.astype(np.float32) / 255.0
  162. conditioning_mask = torch.from_numpy(conditioning_mask[None, None])
  163. # Inpainting model uses a discretized mask as input, so we round to either 1.0 or 0.0
  164. conditioning_mask = torch.round(conditioning_mask)
  165. else:
  166. conditioning_mask = source_image.new_ones(1, 1, *source_image.shape[-2:])
  167. # Create another latent image, this time with a masked version of the original input.
  168. # Smoothly interpolate between the masked and unmasked latent conditioning image using a parameter.
  169. conditioning_mask = conditioning_mask.to(source_image.device).to(source_image.dtype)
  170. conditioning_image = torch.lerp(
  171. source_image,
  172. source_image * (1.0 - conditioning_mask),
  173. getattr(self, "inpainting_mask_weight", shared.opts.inpainting_mask_weight)
  174. )
  175. # Encode the new masked image using first stage of network.
  176. conditioning_image = self.sd_model.get_first_stage_encoding(self.sd_model.encode_first_stage(conditioning_image))
  177. # Create the concatenated conditioning tensor to be fed to `c_concat`
  178. conditioning_mask = torch.nn.functional.interpolate(conditioning_mask, size=latent_image.shape[-2:])
  179. conditioning_mask = conditioning_mask.expand(conditioning_image.shape[0], -1, -1, -1)
  180. image_conditioning = torch.cat([conditioning_mask, conditioning_image], dim=1)
  181. image_conditioning = image_conditioning.to(shared.device).type(self.sd_model.dtype)
  182. return image_conditioning
  183. def img2img_image_conditioning(self, source_image, latent_image, image_mask=None):
  184. # HACK: Using introspection as the Depth2Image model doesn't appear to uniquely
  185. # identify itself with a field common to all models. The conditioning_key is also hybrid.
  186. if isinstance(self.sd_model, LatentDepth2ImageDiffusion):
  187. return self.depth2img_image_conditioning(source_image)
  188. if self.sampler.conditioning_key in {'hybrid', 'concat'}:
  189. return self.inpainting_image_conditioning(source_image, latent_image, image_mask=image_mask)
  190. # Dummy zero conditioning if we're not using inpainting or depth model.
  191. return latent_image.new_zeros(latent_image.shape[0], 5, 1, 1)
  192. def init(self, all_prompts, all_seeds, all_subseeds):
  193. pass
  194. def sample(self, conditioning, unconditional_conditioning, seeds, subseeds, subseed_strength, prompts):
  195. raise NotImplementedError()
  196. def close(self):
  197. self.sampler = None
  198. class Processed:
  199. def __init__(self, p: StableDiffusionProcessing, images_list, seed=-1, info="", subseed=None, all_prompts=None, all_negative_prompts=None, all_seeds=None, all_subseeds=None, index_of_first_image=0, infotexts=None, comments=""):
  200. self.images = images_list
  201. self.prompt = p.prompt
  202. self.negative_prompt = p.negative_prompt
  203. self.seed = seed
  204. self.subseed = subseed
  205. self.subseed_strength = p.subseed_strength
  206. self.info = info
  207. self.comments = comments
  208. self.width = p.width
  209. self.height = p.height
  210. self.sampler_name = p.sampler_name
  211. self.cfg_scale = p.cfg_scale
  212. self.steps = p.steps
  213. self.batch_size = p.batch_size
  214. self.restore_faces = p.restore_faces
  215. self.face_restoration_model = opts.face_restoration_model if p.restore_faces else None
  216. self.sd_model_hash = shared.sd_model.sd_model_hash
  217. self.seed_resize_from_w = p.seed_resize_from_w
  218. self.seed_resize_from_h = p.seed_resize_from_h
  219. self.denoising_strength = getattr(p, 'denoising_strength', None)
  220. self.extra_generation_params = p.extra_generation_params
  221. self.index_of_first_image = index_of_first_image
  222. self.styles = p.styles
  223. self.job_timestamp = state.job_timestamp
  224. self.clip_skip = opts.CLIP_stop_at_last_layers
  225. self.eta = p.eta
  226. self.ddim_discretize = p.ddim_discretize
  227. self.s_churn = p.s_churn
  228. self.s_tmin = p.s_tmin
  229. self.s_tmax = p.s_tmax
  230. self.s_noise = p.s_noise
  231. self.sampler_noise_scheduler_override = p.sampler_noise_scheduler_override
  232. self.prompt = self.prompt if type(self.prompt) != list else self.prompt[0]
  233. self.negative_prompt = self.negative_prompt if type(self.negative_prompt) != list else self.negative_prompt[0]
  234. self.seed = int(self.seed if type(self.seed) != list else self.seed[0]) if self.seed is not None else -1
  235. self.subseed = int(self.subseed if type(self.subseed) != list else self.subseed[0]) if self.subseed is not None else -1
  236. self.is_using_inpainting_conditioning = p.is_using_inpainting_conditioning
  237. self.all_prompts = all_prompts or p.all_prompts or [self.prompt]
  238. self.all_negative_prompts = all_negative_prompts or p.all_negative_prompts or [self.negative_prompt]
  239. self.all_seeds = all_seeds or p.all_seeds or [self.seed]
  240. self.all_subseeds = all_subseeds or p.all_subseeds or [self.subseed]
  241. self.infotexts = infotexts or [info]
  242. def js(self):
  243. obj = {
  244. "prompt": self.all_prompts[0],
  245. "all_prompts": self.all_prompts,
  246. "negative_prompt": self.all_negative_prompts[0],
  247. "all_negative_prompts": self.all_negative_prompts,
  248. "seed": self.seed,
  249. "all_seeds": self.all_seeds,
  250. "subseed": self.subseed,
  251. "all_subseeds": self.all_subseeds,
  252. "subseed_strength": self.subseed_strength,
  253. "width": self.width,
  254. "height": self.height,
  255. "sampler_name": self.sampler_name,
  256. "cfg_scale": self.cfg_scale,
  257. "steps": self.steps,
  258. "batch_size": self.batch_size,
  259. "restore_faces": self.restore_faces,
  260. "face_restoration_model": self.face_restoration_model,
  261. "sd_model_hash": self.sd_model_hash,
  262. "seed_resize_from_w": self.seed_resize_from_w,
  263. "seed_resize_from_h": self.seed_resize_from_h,
  264. "denoising_strength": self.denoising_strength,
  265. "extra_generation_params": self.extra_generation_params,
  266. "index_of_first_image": self.index_of_first_image,
  267. "infotexts": self.infotexts,
  268. "styles": self.styles,
  269. "job_timestamp": self.job_timestamp,
  270. "clip_skip": self.clip_skip,
  271. "is_using_inpainting_conditioning": self.is_using_inpainting_conditioning,
  272. }
  273. return json.dumps(obj)
  274. def infotext(self, p: StableDiffusionProcessing, index):
  275. return create_infotext(p, self.all_prompts, self.all_seeds, self.all_subseeds, comments=[], position_in_batch=index % self.batch_size, iteration=index // self.batch_size)
  276. # from https://discuss.pytorch.org/t/help-regarding-slerp-function-for-generative-model-sampling/32475/3
  277. def slerp(val, low, high):
  278. low_norm = low/torch.norm(low, dim=1, keepdim=True)
  279. high_norm = high/torch.norm(high, dim=1, keepdim=True)
  280. dot = (low_norm*high_norm).sum(1)
  281. if dot.mean() > 0.9995:
  282. return low * val + high * (1 - val)
  283. omega = torch.acos(dot)
  284. so = torch.sin(omega)
  285. res = (torch.sin((1.0-val)*omega)/so).unsqueeze(1)*low + (torch.sin(val*omega)/so).unsqueeze(1) * high
  286. return res
  287. def create_random_tensors(shape, seeds, subseeds=None, subseed_strength=0.0, seed_resize_from_h=0, seed_resize_from_w=0, p=None):
  288. eta_noise_seed_delta = opts.eta_noise_seed_delta or 0
  289. xs = []
  290. # if we have multiple seeds, this means we are working with batch size>1; this then
  291. # enables the generation of additional tensors with noise that the sampler will use during its processing.
  292. # Using those pre-generated tensors instead of simple torch.randn allows a batch with seeds [100, 101] to
  293. # produce the same images as with two batches [100], [101].
  294. if p is not None and p.sampler is not None and (len(seeds) > 1 and opts.enable_batch_seeds or eta_noise_seed_delta > 0):
  295. sampler_noises = [[] for _ in range(p.sampler.number_of_needed_noises(p))]
  296. else:
  297. sampler_noises = None
  298. for i, seed in enumerate(seeds):
  299. noise_shape = shape if seed_resize_from_h <= 0 or seed_resize_from_w <= 0 else (shape[0], seed_resize_from_h//8, seed_resize_from_w//8)
  300. subnoise = None
  301. if subseeds is not None:
  302. subseed = 0 if i >= len(subseeds) else subseeds[i]
  303. subnoise = devices.randn(subseed, noise_shape)
  304. # randn results depend on device; gpu and cpu get different results for same seed;
  305. # the way I see it, it's better to do this on CPU, so that everyone gets same result;
  306. # but the original script had it like this, so I do not dare change it for now because
  307. # it will break everyone's seeds.
  308. noise = devices.randn(seed, noise_shape)
  309. if subnoise is not None:
  310. noise = slerp(subseed_strength, noise, subnoise)
  311. if noise_shape != shape:
  312. x = devices.randn(seed, shape)
  313. dx = (shape[2] - noise_shape[2]) // 2
  314. dy = (shape[1] - noise_shape[1]) // 2
  315. w = noise_shape[2] if dx >= 0 else noise_shape[2] + 2 * dx
  316. h = noise_shape[1] if dy >= 0 else noise_shape[1] + 2 * dy
  317. tx = 0 if dx < 0 else dx
  318. ty = 0 if dy < 0 else dy
  319. dx = max(-dx, 0)
  320. dy = max(-dy, 0)
  321. x[:, ty:ty+h, tx:tx+w] = noise[:, dy:dy+h, dx:dx+w]
  322. noise = x
  323. if sampler_noises is not None:
  324. cnt = p.sampler.number_of_needed_noises(p)
  325. if eta_noise_seed_delta > 0:
  326. torch.manual_seed(seed + eta_noise_seed_delta)
  327. for j in range(cnt):
  328. sampler_noises[j].append(devices.randn_without_seed(tuple(noise_shape)))
  329. xs.append(noise)
  330. if sampler_noises is not None:
  331. p.sampler.sampler_noises = [torch.stack(n).to(shared.device) for n in sampler_noises]
  332. x = torch.stack(xs).to(shared.device)
  333. return x
  334. def decode_first_stage(model, x):
  335. with devices.autocast(disable=x.dtype == devices.dtype_vae):
  336. x = model.decode_first_stage(x)
  337. return x
  338. def get_fixed_seed(seed):
  339. if seed is None or seed == '' or seed == -1:
  340. return int(random.randrange(4294967294))
  341. return seed
  342. def fix_seed(p):
  343. p.seed = get_fixed_seed(p.seed)
  344. p.subseed = get_fixed_seed(p.subseed)
  345. def create_infotext(p, all_prompts, all_seeds, all_subseeds, comments=None, iteration=0, position_in_batch=0):
  346. index = position_in_batch + iteration * p.batch_size
  347. clip_skip = getattr(p, 'clip_skip', opts.CLIP_stop_at_last_layers)
  348. generation_params = {
  349. "Steps": p.steps,
  350. "Sampler": p.sampler_name,
  351. "CFG scale": p.cfg_scale,
  352. "Seed": all_seeds[index],
  353. "Face restoration": (opts.face_restoration_model if p.restore_faces else None),
  354. "Size": f"{p.width}x{p.height}",
  355. "Model hash": getattr(p, 'sd_model_hash', None if not opts.add_model_hash_to_info or not shared.sd_model.sd_model_hash else shared.sd_model.sd_model_hash),
  356. "Model": (None if not opts.add_model_name_to_info or not shared.sd_model.sd_checkpoint_info.model_name else shared.sd_model.sd_checkpoint_info.model_name.replace(',', '').replace(':', '')),
  357. "Batch size": (None if p.batch_size < 2 else p.batch_size),
  358. "Batch pos": (None if p.batch_size < 2 else position_in_batch),
  359. "Variation seed": (None if p.subseed_strength == 0 else all_subseeds[index]),
  360. "Variation seed strength": (None if p.subseed_strength == 0 else p.subseed_strength),
  361. "Seed resize from": (None if p.seed_resize_from_w == 0 or p.seed_resize_from_h == 0 else f"{p.seed_resize_from_w}x{p.seed_resize_from_h}"),
  362. "Denoising strength": getattr(p, 'denoising_strength', None),
  363. "Conditional mask weight": getattr(p, "inpainting_mask_weight", shared.opts.inpainting_mask_weight) if p.is_using_inpainting_conditioning else None,
  364. "Eta": (None if p.sampler is None or p.sampler.eta == p.sampler.default_eta else p.sampler.eta),
  365. "Clip skip": None if clip_skip <= 1 else clip_skip,
  366. "ENSD": None if opts.eta_noise_seed_delta == 0 else opts.eta_noise_seed_delta,
  367. }
  368. generation_params.update(p.extra_generation_params)
  369. generation_params_text = ", ".join([k if k == v else f'{k}: {generation_parameters_copypaste.quote(v)}' for k, v in generation_params.items() if v is not None])
  370. negative_prompt_text = "\nNegative prompt: " + p.all_negative_prompts[index] if p.all_negative_prompts[index] else ""
  371. return f"{all_prompts[index]}{negative_prompt_text}\n{generation_params_text}".strip()
  372. def process_images(p: StableDiffusionProcessing) -> Processed:
  373. stored_opts = {k: opts.data[k] for k in p.override_settings.keys()}
  374. try:
  375. for k, v in p.override_settings.items():
  376. setattr(opts, k, v)
  377. if k == 'sd_model_checkpoint':
  378. sd_models.reload_model_weights()
  379. if k == 'sd_vae':
  380. sd_vae.reload_vae_weights()
  381. res = process_images_inner(p)
  382. finally:
  383. # restore opts to original state
  384. if p.override_settings_restore_afterwards:
  385. for k, v in stored_opts.items():
  386. setattr(opts, k, v)
  387. if k == 'sd_model_checkpoint':
  388. sd_models.reload_model_weights()
  389. if k == 'sd_vae':
  390. sd_vae.reload_vae_weights()
  391. return res
  392. def process_images_inner(p: StableDiffusionProcessing) -> Processed:
  393. """this is the main loop that both txt2img and img2img use; it calls func_init once inside all the scopes and func_sample once per batch"""
  394. if type(p.prompt) == list:
  395. assert(len(p.prompt) > 0)
  396. else:
  397. assert p.prompt is not None
  398. devices.torch_gc()
  399. seed = get_fixed_seed(p.seed)
  400. subseed = get_fixed_seed(p.subseed)
  401. modules.sd_hijack.model_hijack.apply_circular(p.tiling)
  402. modules.sd_hijack.model_hijack.clear_comments()
  403. comments = {}
  404. if type(p.prompt) == list:
  405. p.all_prompts = [shared.prompt_styles.apply_styles_to_prompt(x, p.styles) for x in p.prompt]
  406. else:
  407. p.all_prompts = p.batch_size * p.n_iter * [shared.prompt_styles.apply_styles_to_prompt(p.prompt, p.styles)]
  408. if type(p.negative_prompt) == list:
  409. p.all_negative_prompts = [shared.prompt_styles.apply_negative_styles_to_prompt(x, p.styles) for x in p.negative_prompt]
  410. else:
  411. p.all_negative_prompts = p.batch_size * p.n_iter * [shared.prompt_styles.apply_negative_styles_to_prompt(p.negative_prompt, p.styles)]
  412. if type(seed) == list:
  413. p.all_seeds = seed
  414. else:
  415. p.all_seeds = [int(seed) + (x if p.subseed_strength == 0 else 0) for x in range(len(p.all_prompts))]
  416. if type(subseed) == list:
  417. p.all_subseeds = subseed
  418. else:
  419. p.all_subseeds = [int(subseed) + x for x in range(len(p.all_prompts))]
  420. def infotext(iteration=0, position_in_batch=0):
  421. return create_infotext(p, p.all_prompts, p.all_seeds, p.all_subseeds, comments, iteration, position_in_batch)
  422. if os.path.exists(cmd_opts.embeddings_dir) and not p.do_not_reload_embeddings:
  423. model_hijack.embedding_db.load_textual_inversion_embeddings()
  424. if p.scripts is not None:
  425. p.scripts.process(p)
  426. infotexts = []
  427. output_images = []
  428. cached_uc = [None, None]
  429. cached_c = [None, None]
  430. def get_conds_with_caching(function, required_prompts, steps, cache):
  431. """
  432. Returns the result of calling function(shared.sd_model, required_prompts, steps)
  433. using a cache to store the result if the same arguments have been used before.
  434. cache is an array containing two elements. The first element is a tuple
  435. representing the previously used arguments, or None if no arguments
  436. have been used before. The second element is where the previously
  437. computed result is stored.
  438. """
  439. if cache[0] is not None and (required_prompts, steps) == cache[0]:
  440. return cache[1]
  441. with devices.autocast():
  442. cache[1] = function(shared.sd_model, required_prompts, steps)
  443. cache[0] = (required_prompts, steps)
  444. return cache[1]
  445. p.all_prompts, extra_network_data = extra_networks.parse_prompts(p.all_prompts)
  446. with torch.no_grad(), p.sd_model.ema_scope():
  447. with devices.autocast():
  448. p.init(p.all_prompts, p.all_seeds, p.all_subseeds)
  449. extra_networks.activate(p, extra_network_data)
  450. with open(os.path.join(shared.script_path, "params.txt"), "w", encoding="utf8") as file:
  451. processed = Processed(p, [], p.seed, "")
  452. file.write(processed.infotext(p, 0))
  453. if state.job_count == -1:
  454. state.job_count = p.n_iter
  455. for n in range(p.n_iter):
  456. p.iteration = n
  457. if state.skipped:
  458. state.skipped = False
  459. if state.interrupted:
  460. break
  461. prompts = p.all_prompts[n * p.batch_size:(n + 1) * p.batch_size]
  462. negative_prompts = p.all_negative_prompts[n * p.batch_size:(n + 1) * p.batch_size]
  463. seeds = p.all_seeds[n * p.batch_size:(n + 1) * p.batch_size]
  464. subseeds = p.all_subseeds[n * p.batch_size:(n + 1) * p.batch_size]
  465. if len(prompts) == 0:
  466. break
  467. if p.scripts is not None:
  468. p.scripts.process_batch(p, batch_number=n, prompts=prompts, seeds=seeds, subseeds=subseeds)
  469. uc = get_conds_with_caching(prompt_parser.get_learned_conditioning, negative_prompts, p.steps, cached_uc)
  470. c = get_conds_with_caching(prompt_parser.get_multicond_learned_conditioning, prompts, p.steps, cached_c)
  471. if len(model_hijack.comments) > 0:
  472. for comment in model_hijack.comments:
  473. comments[comment] = 1
  474. if p.n_iter > 1:
  475. shared.state.job = f"Batch {n+1} out of {p.n_iter}"
  476. with devices.autocast():
  477. samples_ddim = p.sample(conditioning=c, unconditional_conditioning=uc, seeds=seeds, subseeds=subseeds, subseed_strength=p.subseed_strength, prompts=prompts)
  478. x_samples_ddim = [decode_first_stage(p.sd_model, samples_ddim[i:i+1].to(dtype=devices.dtype_vae))[0].cpu() for i in range(samples_ddim.size(0))]
  479. for x in x_samples_ddim:
  480. devices.test_for_nans(x, "vae")
  481. x_samples_ddim = torch.stack(x_samples_ddim).float()
  482. x_samples_ddim = torch.clamp((x_samples_ddim + 1.0) / 2.0, min=0.0, max=1.0)
  483. del samples_ddim
  484. if shared.cmd_opts.lowvram or shared.cmd_opts.medvram:
  485. lowvram.send_everything_to_cpu()
  486. devices.torch_gc()
  487. if p.scripts is not None:
  488. p.scripts.postprocess_batch(p, x_samples_ddim, batch_number=n)
  489. for i, x_sample in enumerate(x_samples_ddim):
  490. x_sample = 255. * np.moveaxis(x_sample.cpu().numpy(), 0, 2)
  491. x_sample = x_sample.astype(np.uint8)
  492. if p.restore_faces:
  493. if opts.save and not p.do_not_save_samples and opts.save_images_before_face_restoration:
  494. images.save_image(Image.fromarray(x_sample), p.outpath_samples, "", seeds[i], prompts[i], opts.samples_format, info=infotext(n, i), p=p, suffix="-before-face-restoration")
  495. devices.torch_gc()
  496. x_sample = modules.face_restoration.restore_faces(x_sample)
  497. devices.torch_gc()
  498. image = Image.fromarray(x_sample)
  499. if p.color_corrections is not None and i < len(p.color_corrections):
  500. if opts.save and not p.do_not_save_samples and opts.save_images_before_color_correction:
  501. image_without_cc = apply_overlay(image, p.paste_to, i, p.overlay_images)
  502. images.save_image(image_without_cc, p.outpath_samples, "", seeds[i], prompts[i], opts.samples_format, info=infotext(n, i), p=p, suffix="-before-color-correction")
  503. image = apply_color_correction(p.color_corrections[i], image)
  504. image = apply_overlay(image, p.paste_to, i, p.overlay_images)
  505. if opts.samples_save and not p.do_not_save_samples:
  506. images.save_image(image, p.outpath_samples, "", seeds[i], prompts[i], opts.samples_format, info=infotext(n, i), p=p)
  507. text = infotext(n, i)
  508. infotexts.append(text)
  509. if opts.enable_pnginfo:
  510. image.info["parameters"] = text
  511. output_images.append(image)
  512. del x_samples_ddim
  513. devices.torch_gc()
  514. state.nextjob()
  515. p.color_corrections = None
  516. index_of_first_image = 0
  517. unwanted_grid_because_of_img_count = len(output_images) < 2 and opts.grid_only_if_multiple
  518. if (opts.return_grid or opts.grid_save) and not p.do_not_save_grid and not unwanted_grid_because_of_img_count:
  519. grid = images.image_grid(output_images, p.batch_size)
  520. if opts.return_grid:
  521. text = infotext()
  522. infotexts.insert(0, text)
  523. if opts.enable_pnginfo:
  524. grid.info["parameters"] = text
  525. output_images.insert(0, grid)
  526. index_of_first_image = 1
  527. if opts.grid_save:
  528. images.save_image(grid, p.outpath_grids, "grid", p.all_seeds[0], p.all_prompts[0], opts.grid_format, info=infotext(), short_filename=not opts.grid_extended_filename, p=p, grid=True)
  529. extra_networks.deactivate(p, extra_network_data)
  530. devices.torch_gc()
  531. res = Processed(p, output_images, p.all_seeds[0], infotext(), comments="".join(["\n\n" + x for x in comments]), subseed=p.all_subseeds[0], index_of_first_image=index_of_first_image, infotexts=infotexts)
  532. if p.scripts is not None:
  533. p.scripts.postprocess(p, res)
  534. return res
  535. def old_hires_fix_first_pass_dimensions(width, height):
  536. """old algorithm for auto-calculating first pass size"""
  537. desired_pixel_count = 512 * 512
  538. actual_pixel_count = width * height
  539. scale = math.sqrt(desired_pixel_count / actual_pixel_count)
  540. width = math.ceil(scale * width / 64) * 64
  541. height = math.ceil(scale * height / 64) * 64
  542. return width, height
  543. class StableDiffusionProcessingTxt2Img(StableDiffusionProcessing):
  544. sampler = None
  545. def __init__(self, enable_hr: bool = False, denoising_strength: float = 0.75, firstphase_width: int = 0, firstphase_height: int = 0, hr_scale: float = 2.0, hr_upscaler: str = None, hr_second_pass_steps: int = 0, hr_resize_x: int = 0, hr_resize_y: int = 0, **kwargs):
  546. super().__init__(**kwargs)
  547. self.enable_hr = enable_hr
  548. self.denoising_strength = denoising_strength
  549. self.hr_scale = hr_scale
  550. self.hr_upscaler = hr_upscaler
  551. self.hr_second_pass_steps = hr_second_pass_steps
  552. self.hr_resize_x = hr_resize_x
  553. self.hr_resize_y = hr_resize_y
  554. self.hr_upscale_to_x = hr_resize_x
  555. self.hr_upscale_to_y = hr_resize_y
  556. if firstphase_width != 0 or firstphase_height != 0:
  557. self.hr_upscale_to_x = self.width
  558. self.hr_upscale_to_y = self.height
  559. self.width = firstphase_width
  560. self.height = firstphase_height
  561. self.truncate_x = 0
  562. self.truncate_y = 0
  563. self.applied_old_hires_behavior_to = None
  564. def init(self, all_prompts, all_seeds, all_subseeds):
  565. if self.enable_hr:
  566. if opts.use_old_hires_fix_width_height and self.applied_old_hires_behavior_to != (self.width, self.height):
  567. self.hr_resize_x = self.width
  568. self.hr_resize_y = self.height
  569. self.hr_upscale_to_x = self.width
  570. self.hr_upscale_to_y = self.height
  571. self.width, self.height = old_hires_fix_first_pass_dimensions(self.width, self.height)
  572. self.applied_old_hires_behavior_to = (self.width, self.height)
  573. if self.hr_resize_x == 0 and self.hr_resize_y == 0:
  574. self.extra_generation_params["Hires upscale"] = self.hr_scale
  575. self.hr_upscale_to_x = int(self.width * self.hr_scale)
  576. self.hr_upscale_to_y = int(self.height * self.hr_scale)
  577. else:
  578. self.extra_generation_params["Hires resize"] = f"{self.hr_resize_x}x{self.hr_resize_y}"
  579. if self.hr_resize_y == 0:
  580. self.hr_upscale_to_x = self.hr_resize_x
  581. self.hr_upscale_to_y = self.hr_resize_x * self.height // self.width
  582. elif self.hr_resize_x == 0:
  583. self.hr_upscale_to_x = self.hr_resize_y * self.width // self.height
  584. self.hr_upscale_to_y = self.hr_resize_y
  585. else:
  586. target_w = self.hr_resize_x
  587. target_h = self.hr_resize_y
  588. src_ratio = self.width / self.height
  589. dst_ratio = self.hr_resize_x / self.hr_resize_y
  590. if src_ratio < dst_ratio:
  591. self.hr_upscale_to_x = self.hr_resize_x
  592. self.hr_upscale_to_y = self.hr_resize_x * self.height // self.width
  593. else:
  594. self.hr_upscale_to_x = self.hr_resize_y * self.width // self.height
  595. self.hr_upscale_to_y = self.hr_resize_y
  596. self.truncate_x = (self.hr_upscale_to_x - target_w) // opt_f
  597. self.truncate_y = (self.hr_upscale_to_y - target_h) // opt_f
  598. # special case: the user has chosen to do nothing
  599. if self.hr_upscale_to_x == self.width and self.hr_upscale_to_y == self.height:
  600. self.enable_hr = False
  601. self.denoising_strength = None
  602. self.extra_generation_params.pop("Hires upscale", None)
  603. self.extra_generation_params.pop("Hires resize", None)
  604. return
  605. if not state.processing_has_refined_job_count:
  606. if state.job_count == -1:
  607. state.job_count = self.n_iter
  608. shared.total_tqdm.updateTotal((self.steps + (self.hr_second_pass_steps or self.steps)) * state.job_count)
  609. state.job_count = state.job_count * 2
  610. state.processing_has_refined_job_count = True
  611. if self.hr_second_pass_steps:
  612. self.extra_generation_params["Hires steps"] = self.hr_second_pass_steps
  613. if self.hr_upscaler is not None:
  614. self.extra_generation_params["Hires upscaler"] = self.hr_upscaler
  615. def sample(self, conditioning, unconditional_conditioning, seeds, subseeds, subseed_strength, prompts):
  616. self.sampler = sd_samplers.create_sampler(self.sampler_name, self.sd_model)
  617. latent_scale_mode = shared.latent_upscale_modes.get(self.hr_upscaler, None) if self.hr_upscaler is not None else shared.latent_upscale_modes.get(shared.latent_upscale_default_mode, "nearest")
  618. if self.enable_hr and latent_scale_mode is None:
  619. assert len([x for x in shared.sd_upscalers if x.name == self.hr_upscaler]) > 0, f"could not find upscaler named {self.hr_upscaler}"
  620. x = create_random_tensors([opt_C, self.height // opt_f, self.width // opt_f], seeds=seeds, subseeds=subseeds, subseed_strength=self.subseed_strength, seed_resize_from_h=self.seed_resize_from_h, seed_resize_from_w=self.seed_resize_from_w, p=self)
  621. samples = self.sampler.sample(self, x, conditioning, unconditional_conditioning, image_conditioning=self.txt2img_image_conditioning(x))
  622. if not self.enable_hr:
  623. return samples
  624. target_width = self.hr_upscale_to_x
  625. target_height = self.hr_upscale_to_y
  626. def save_intermediate(image, index):
  627. """saves image before applying hires fix, if enabled in options; takes as an argument either an image or batch with latent space images"""
  628. if not opts.save or self.do_not_save_samples or not opts.save_images_before_highres_fix:
  629. return
  630. if not isinstance(image, Image.Image):
  631. image = sd_samplers.sample_to_image(image, index, approximation=0)
  632. info = create_infotext(self, self.all_prompts, self.all_seeds, self.all_subseeds, [], iteration=self.iteration, position_in_batch=index)
  633. images.save_image(image, self.outpath_samples, "", seeds[index], prompts[index], opts.samples_format, info=info, suffix="-before-highres-fix")
  634. if latent_scale_mode is not None:
  635. for i in range(samples.shape[0]):
  636. save_intermediate(samples, i)
  637. samples = torch.nn.functional.interpolate(samples, size=(target_height // opt_f, target_width // opt_f), mode=latent_scale_mode["mode"], antialias=latent_scale_mode["antialias"])
  638. # Avoid making the inpainting conditioning unless necessary as
  639. # this does need some extra compute to decode / encode the image again.
  640. if getattr(self, "inpainting_mask_weight", shared.opts.inpainting_mask_weight) < 1.0:
  641. image_conditioning = self.img2img_image_conditioning(decode_first_stage(self.sd_model, samples), samples)
  642. else:
  643. image_conditioning = self.txt2img_image_conditioning(samples)
  644. else:
  645. decoded_samples = decode_first_stage(self.sd_model, samples)
  646. lowres_samples = torch.clamp((decoded_samples + 1.0) / 2.0, min=0.0, max=1.0)
  647. batch_images = []
  648. for i, x_sample in enumerate(lowres_samples):
  649. x_sample = 255. * np.moveaxis(x_sample.cpu().numpy(), 0, 2)
  650. x_sample = x_sample.astype(np.uint8)
  651. image = Image.fromarray(x_sample)
  652. save_intermediate(image, i)
  653. image = images.resize_image(0, image, target_width, target_height, upscaler_name=self.hr_upscaler)
  654. image = np.array(image).astype(np.float32) / 255.0
  655. image = np.moveaxis(image, 2, 0)
  656. batch_images.append(image)
  657. decoded_samples = torch.from_numpy(np.array(batch_images))
  658. decoded_samples = decoded_samples.to(shared.device)
  659. decoded_samples = 2. * decoded_samples - 1.
  660. samples = self.sd_model.get_first_stage_encoding(self.sd_model.encode_first_stage(decoded_samples))
  661. image_conditioning = self.img2img_image_conditioning(decoded_samples, samples)
  662. shared.state.nextjob()
  663. img2img_sampler_name = self.sampler_name if self.sampler_name != 'PLMS' else 'DDIM' # PLMS does not support img2img so we just silently switch ot DDIM
  664. self.sampler = sd_samplers.create_sampler(img2img_sampler_name, self.sd_model)
  665. samples = samples[:, :, self.truncate_y//2:samples.shape[2]-(self.truncate_y+1)//2, self.truncate_x//2:samples.shape[3]-(self.truncate_x+1)//2]
  666. noise = create_random_tensors(samples.shape[1:], seeds=seeds, subseeds=subseeds, subseed_strength=subseed_strength, p=self)
  667. # GC now before running the next img2img to prevent running out of memory
  668. x = None
  669. devices.torch_gc()
  670. samples = self.sampler.sample_img2img(self, samples, noise, conditioning, unconditional_conditioning, steps=self.hr_second_pass_steps or self.steps, image_conditioning=image_conditioning)
  671. return samples
  672. class StableDiffusionProcessingImg2Img(StableDiffusionProcessing):
  673. sampler = None
  674. def __init__(self, init_images: list = None, resize_mode: int = 0, denoising_strength: float = 0.75, mask: Any = None, mask_blur: int = 4, inpainting_fill: int = 0, inpaint_full_res: bool = True, inpaint_full_res_padding: int = 0, inpainting_mask_invert: int = 0, initial_noise_multiplier: float = None, **kwargs):
  675. super().__init__(**kwargs)
  676. self.init_images = init_images
  677. self.resize_mode: int = resize_mode
  678. self.denoising_strength: float = denoising_strength
  679. self.init_latent = None
  680. self.image_mask = mask
  681. self.latent_mask = None
  682. self.mask_for_overlay = None
  683. self.mask_blur = mask_blur
  684. self.inpainting_fill = inpainting_fill
  685. self.inpaint_full_res = inpaint_full_res
  686. self.inpaint_full_res_padding = inpaint_full_res_padding
  687. self.inpainting_mask_invert = inpainting_mask_invert
  688. self.initial_noise_multiplier = opts.initial_noise_multiplier if initial_noise_multiplier is None else initial_noise_multiplier
  689. self.mask = None
  690. self.nmask = None
  691. self.image_conditioning = None
  692. def init(self, all_prompts, all_seeds, all_subseeds):
  693. self.sampler = sd_samplers.create_sampler(self.sampler_name, self.sd_model)
  694. crop_region = None
  695. image_mask = self.image_mask
  696. if image_mask is not None:
  697. image_mask = image_mask.convert('L')
  698. if self.inpainting_mask_invert:
  699. image_mask = ImageOps.invert(image_mask)
  700. if self.mask_blur > 0:
  701. image_mask = image_mask.filter(ImageFilter.GaussianBlur(self.mask_blur))
  702. if self.inpaint_full_res:
  703. self.mask_for_overlay = image_mask
  704. mask = image_mask.convert('L')
  705. crop_region = masking.get_crop_region(np.array(mask), self.inpaint_full_res_padding)
  706. crop_region = masking.expand_crop_region(crop_region, self.width, self.height, mask.width, mask.height)
  707. x1, y1, x2, y2 = crop_region
  708. mask = mask.crop(crop_region)
  709. image_mask = images.resize_image(2, mask, self.width, self.height)
  710. self.paste_to = (x1, y1, x2-x1, y2-y1)
  711. else:
  712. image_mask = images.resize_image(self.resize_mode, image_mask, self.width, self.height)
  713. np_mask = np.array(image_mask)
  714. np_mask = np.clip((np_mask.astype(np.float32)) * 2, 0, 255).astype(np.uint8)
  715. self.mask_for_overlay = Image.fromarray(np_mask)
  716. self.overlay_images = []
  717. latent_mask = self.latent_mask if self.latent_mask is not None else image_mask
  718. add_color_corrections = opts.img2img_color_correction and self.color_corrections is None
  719. if add_color_corrections:
  720. self.color_corrections = []
  721. imgs = []
  722. for img in self.init_images:
  723. image = images.flatten(img, opts.img2img_background_color)
  724. if crop_region is None and self.resize_mode != 3:
  725. image = images.resize_image(self.resize_mode, image, self.width, self.height)
  726. if image_mask is not None:
  727. image_masked = Image.new('RGBa', (image.width, image.height))
  728. image_masked.paste(image.convert("RGBA").convert("RGBa"), mask=ImageOps.invert(self.mask_for_overlay.convert('L')))
  729. self.overlay_images.append(image_masked.convert('RGBA'))
  730. # crop_region is not None if we are doing inpaint full res
  731. if crop_region is not None:
  732. image = image.crop(crop_region)
  733. image = images.resize_image(2, image, self.width, self.height)
  734. if image_mask is not None:
  735. if self.inpainting_fill != 1:
  736. image = masking.fill(image, latent_mask)
  737. if add_color_corrections:
  738. self.color_corrections.append(setup_color_correction(image))
  739. image = np.array(image).astype(np.float32) / 255.0
  740. image = np.moveaxis(image, 2, 0)
  741. imgs.append(image)
  742. if len(imgs) == 1:
  743. batch_images = np.expand_dims(imgs[0], axis=0).repeat(self.batch_size, axis=0)
  744. if self.overlay_images is not None:
  745. self.overlay_images = self.overlay_images * self.batch_size
  746. if self.color_corrections is not None and len(self.color_corrections) == 1:
  747. self.color_corrections = self.color_corrections * self.batch_size
  748. elif len(imgs) <= self.batch_size:
  749. self.batch_size = len(imgs)
  750. batch_images = np.array(imgs)
  751. else:
  752. raise RuntimeError(f"bad number of images passed: {len(imgs)}; expecting {self.batch_size} or less")
  753. image = torch.from_numpy(batch_images)
  754. image = 2. * image - 1.
  755. image = image.to(shared.device)
  756. self.init_latent = self.sd_model.get_first_stage_encoding(self.sd_model.encode_first_stage(image))
  757. if self.resize_mode == 3:
  758. self.init_latent = torch.nn.functional.interpolate(self.init_latent, size=(self.height // opt_f, self.width // opt_f), mode="bilinear")
  759. if image_mask is not None:
  760. init_mask = latent_mask
  761. latmask = init_mask.convert('RGB').resize((self.init_latent.shape[3], self.init_latent.shape[2]))
  762. latmask = np.moveaxis(np.array(latmask, dtype=np.float32), 2, 0) / 255
  763. latmask = latmask[0]
  764. latmask = np.around(latmask)
  765. latmask = np.tile(latmask[None], (4, 1, 1))
  766. self.mask = torch.asarray(1.0 - latmask).to(shared.device).type(self.sd_model.dtype)
  767. self.nmask = torch.asarray(latmask).to(shared.device).type(self.sd_model.dtype)
  768. # this needs to be fixed to be done in sample() using actual seeds for batches
  769. if self.inpainting_fill == 2:
  770. self.init_latent = self.init_latent * self.mask + create_random_tensors(self.init_latent.shape[1:], all_seeds[0:self.init_latent.shape[0]]) * self.nmask
  771. elif self.inpainting_fill == 3:
  772. self.init_latent = self.init_latent * self.mask
  773. self.image_conditioning = self.img2img_image_conditioning(image, self.init_latent, image_mask)
  774. def sample(self, conditioning, unconditional_conditioning, seeds, subseeds, subseed_strength, prompts):
  775. x = create_random_tensors([opt_C, self.height // opt_f, self.width // opt_f], seeds=seeds, subseeds=subseeds, subseed_strength=self.subseed_strength, seed_resize_from_h=self.seed_resize_from_h, seed_resize_from_w=self.seed_resize_from_w, p=self)
  776. if self.initial_noise_multiplier != 1.0:
  777. self.extra_generation_params["Noise multiplier"] = self.initial_noise_multiplier
  778. x *= self.initial_noise_multiplier
  779. samples = self.sampler.sample_img2img(self, self.init_latent, x, conditioning, unconditional_conditioning, image_conditioning=self.image_conditioning)
  780. if self.mask is not None:
  781. samples = samples * self.nmask + self.init_latent * self.mask
  782. del x
  783. devices.torch_gc()
  784. return samples