processing.py 66 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436
  1. import json
  2. import logging
  3. import math
  4. import os
  5. import sys
  6. import hashlib
  7. import torch
  8. import numpy as np
  9. from PIL import Image, ImageOps
  10. import random
  11. import cv2
  12. from skimage import exposure
  13. from typing import Any, Dict, List
  14. import modules.sd_hijack
  15. from modules import devices, prompt_parser, masking, sd_samplers, lowvram, generation_parameters_copypaste, extra_networks, sd_vae_approx, scripts, sd_samplers_common, sd_unet, errors
  16. from modules.sd_hijack import model_hijack
  17. from modules.sd_samplers_common import images_tensor_to_samples, decode_first_stage, approximation_indexes
  18. from modules.shared import opts, cmd_opts, state
  19. import modules.shared as shared
  20. import modules.paths as paths
  21. import modules.face_restoration
  22. import modules.images as images
  23. import modules.styles
  24. import modules.sd_models as sd_models
  25. import modules.sd_vae as sd_vae
  26. from ldm.data.util import AddMiDaS
  27. from ldm.models.diffusion.ddpm import LatentDepth2ImageDiffusion
  28. from einops import repeat, rearrange
  29. from blendmodes.blend import blendLayers, BlendType
  30. # some of those options should not be changed at all because they would break the model, so I removed them from options.
  31. opt_C = 4
  32. opt_f = 8
  33. def setup_color_correction(image):
  34. logging.info("Calibrating color correction.")
  35. correction_target = cv2.cvtColor(np.asarray(image.copy()), cv2.COLOR_RGB2LAB)
  36. return correction_target
  37. def apply_color_correction(correction, original_image):
  38. logging.info("Applying color correction.")
  39. image = Image.fromarray(cv2.cvtColor(exposure.match_histograms(
  40. cv2.cvtColor(
  41. np.asarray(original_image),
  42. cv2.COLOR_RGB2LAB
  43. ),
  44. correction,
  45. channel_axis=2
  46. ), cv2.COLOR_LAB2RGB).astype("uint8"))
  47. image = blendLayers(image, original_image, BlendType.LUMINOSITY)
  48. return image
  49. def apply_overlay(image, paste_loc, index, overlays):
  50. if overlays is None or index >= len(overlays):
  51. return image
  52. overlay = overlays[index]
  53. if paste_loc is not None:
  54. x, y, w, h = paste_loc
  55. base_image = Image.new('RGBA', (overlay.width, overlay.height))
  56. image = images.resize_image(1, image, w, h)
  57. base_image.paste(image, (x, y))
  58. image = base_image
  59. image = image.convert('RGBA')
  60. image.alpha_composite(overlay)
  61. image = image.convert('RGB')
  62. return image
  63. def txt2img_image_conditioning(sd_model, x, width, height):
  64. if sd_model.model.conditioning_key in {'hybrid', 'concat'}: # Inpainting models
  65. # The "masked-image" in this case will just be all zeros since the entire image is masked.
  66. image_conditioning = torch.zeros(x.shape[0], 3, height, width, device=x.device)
  67. image_conditioning = images_tensor_to_samples(image_conditioning, approximation_indexes.get(opts.sd_vae_encode_method))
  68. # Add the fake full 1s mask to the first dimension.
  69. image_conditioning = torch.nn.functional.pad(image_conditioning, (0, 0, 0, 0, 1, 0), value=1.0)
  70. image_conditioning = image_conditioning.to(x.dtype)
  71. return image_conditioning
  72. elif sd_model.model.conditioning_key == "crossattn-adm": # UnCLIP models
  73. return x.new_zeros(x.shape[0], 2*sd_model.noise_augmentor.time_embed.dim, dtype=x.dtype, device=x.device)
  74. else:
  75. # Dummy zero conditioning if we're not using inpainting or unclip models.
  76. # Still takes up a bit of memory, but no encoder call.
  77. # Pretty sure we can just make this a 1x1 image since its not going to be used besides its batch size.
  78. return x.new_zeros(x.shape[0], 5, 1, 1, dtype=x.dtype, device=x.device)
  79. class StableDiffusionProcessing:
  80. """
  81. The first set of paramaters: sd_models -> do_not_reload_embeddings represent the minimum required to create a StableDiffusionProcessing
  82. """
  83. cached_uc = [None, None]
  84. cached_c = [None, None]
  85. 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_min_uncond: float = 0.0, s_churn: float = 0.0, s_tmax: float = None, s_tmin: float = 0.0, s_noise: float = None, override_settings: Dict[str, Any] = None, override_settings_restore_afterwards: bool = True, sampler_index: int = None, script_args: list = None):
  86. if sampler_index is not None:
  87. print("sampler_index argument for StableDiffusionProcessing does not do anything; use sampler_name", file=sys.stderr)
  88. self.outpath_samples: str = outpath_samples
  89. self.outpath_grids: str = outpath_grids
  90. self.prompt: str = prompt
  91. self.prompt_for_display: str = None
  92. self.negative_prompt: str = (negative_prompt or "")
  93. self.styles: list = styles or []
  94. self.seed: int = seed
  95. self.subseed: int = subseed
  96. self.subseed_strength: float = subseed_strength
  97. self.seed_resize_from_h: int = seed_resize_from_h
  98. self.seed_resize_from_w: int = seed_resize_from_w
  99. self.sampler_name: str = sampler_name
  100. self.batch_size: int = batch_size
  101. self.n_iter: int = n_iter
  102. self.steps: int = steps
  103. self.cfg_scale: float = cfg_scale
  104. self.width: int = width
  105. self.height: int = height
  106. self.restore_faces: bool = restore_faces
  107. self.tiling: bool = tiling
  108. self.do_not_save_samples: bool = do_not_save_samples
  109. self.do_not_save_grid: bool = do_not_save_grid
  110. self.extra_generation_params: dict = extra_generation_params or {}
  111. self.overlay_images = overlay_images
  112. self.eta = eta
  113. self.do_not_reload_embeddings = do_not_reload_embeddings
  114. self.paste_to = None
  115. self.color_corrections = None
  116. self.denoising_strength: float = denoising_strength
  117. self.sampler_noise_scheduler_override = None
  118. self.ddim_discretize = ddim_discretize or opts.ddim_discretize
  119. self.s_min_uncond = s_min_uncond or opts.s_min_uncond
  120. self.s_churn = s_churn or opts.s_churn
  121. self.s_tmin = s_tmin or opts.s_tmin
  122. self.s_tmax = (s_tmax if s_tmax is not None else opts.s_tmax) or float('inf')
  123. self.s_noise = s_noise if s_noise is not None else opts.s_noise
  124. self.override_settings = {k: v for k, v in (override_settings or {}).items() if k not in shared.restricted_opts}
  125. self.override_settings_restore_afterwards = override_settings_restore_afterwards
  126. self.is_using_inpainting_conditioning = False
  127. self.disable_extra_networks = False
  128. self.token_merging_ratio = 0
  129. self.token_merging_ratio_hr = 0
  130. if not seed_enable_extras:
  131. self.subseed = -1
  132. self.subseed_strength = 0
  133. self.seed_resize_from_h = 0
  134. self.seed_resize_from_w = 0
  135. self.scripts = None
  136. self.script_args = script_args
  137. self.all_prompts = None
  138. self.all_negative_prompts = None
  139. self.all_seeds = None
  140. self.all_subseeds = None
  141. self.iteration = 0
  142. self.is_hr_pass = False
  143. self.sampler = None
  144. self.prompts = None
  145. self.negative_prompts = None
  146. self.extra_network_data = None
  147. self.seeds = None
  148. self.subseeds = None
  149. self.step_multiplier = 1
  150. self.cached_uc = StableDiffusionProcessing.cached_uc
  151. self.cached_c = StableDiffusionProcessing.cached_c
  152. self.uc = None
  153. self.c = None
  154. self.user = None
  155. @property
  156. def sd_model(self):
  157. return shared.sd_model
  158. def txt2img_image_conditioning(self, x, width=None, height=None):
  159. self.is_using_inpainting_conditioning = self.sd_model.model.conditioning_key in {'hybrid', 'concat'}
  160. return txt2img_image_conditioning(self.sd_model, x, width or self.width, height or self.height)
  161. def depth2img_image_conditioning(self, source_image):
  162. # Use the AddMiDaS helper to Format our source image to suit the MiDaS model
  163. transformer = AddMiDaS(model_type="dpt_hybrid")
  164. transformed = transformer({"jpg": rearrange(source_image[0], "c h w -> h w c")})
  165. midas_in = torch.from_numpy(transformed["midas_in"][None, ...]).to(device=shared.device)
  166. midas_in = repeat(midas_in, "1 ... -> n ...", n=self.batch_size)
  167. conditioning_image = images_tensor_to_samples(source_image*0.5+0.5, approximation_indexes.get(opts.sd_vae_encode_method))
  168. conditioning = torch.nn.functional.interpolate(
  169. self.sd_model.depth_model(midas_in),
  170. size=conditioning_image.shape[2:],
  171. mode="bicubic",
  172. align_corners=False,
  173. )
  174. (depth_min, depth_max) = torch.aminmax(conditioning)
  175. conditioning = 2. * (conditioning - depth_min) / (depth_max - depth_min) - 1.
  176. return conditioning
  177. def edit_image_conditioning(self, source_image):
  178. conditioning_image = images_tensor_to_samples(source_image*0.5+0.5, approximation_indexes.get(opts.sd_vae_encode_method))
  179. return conditioning_image
  180. def unclip_image_conditioning(self, source_image):
  181. c_adm = self.sd_model.embedder(source_image)
  182. if self.sd_model.noise_augmentor is not None:
  183. noise_level = 0 # TODO: Allow other noise levels?
  184. c_adm, noise_level_emb = self.sd_model.noise_augmentor(c_adm, noise_level=repeat(torch.tensor([noise_level]).to(c_adm.device), '1 -> b', b=c_adm.shape[0]))
  185. c_adm = torch.cat((c_adm, noise_level_emb), 1)
  186. return c_adm
  187. def inpainting_image_conditioning(self, source_image, latent_image, image_mask=None):
  188. self.is_using_inpainting_conditioning = True
  189. # Handle the different mask inputs
  190. if image_mask is not None:
  191. if torch.is_tensor(image_mask):
  192. conditioning_mask = image_mask
  193. else:
  194. conditioning_mask = np.array(image_mask.convert("L"))
  195. conditioning_mask = conditioning_mask.astype(np.float32) / 255.0
  196. conditioning_mask = torch.from_numpy(conditioning_mask[None, None])
  197. # Inpainting model uses a discretized mask as input, so we round to either 1.0 or 0.0
  198. conditioning_mask = torch.round(conditioning_mask)
  199. else:
  200. conditioning_mask = source_image.new_ones(1, 1, *source_image.shape[-2:])
  201. # Create another latent image, this time with a masked version of the original input.
  202. # Smoothly interpolate between the masked and unmasked latent conditioning image using a parameter.
  203. conditioning_mask = conditioning_mask.to(device=source_image.device, dtype=source_image.dtype)
  204. conditioning_image = torch.lerp(
  205. source_image,
  206. source_image * (1.0 - conditioning_mask),
  207. getattr(self, "inpainting_mask_weight", shared.opts.inpainting_mask_weight)
  208. )
  209. # Encode the new masked image using first stage of network.
  210. conditioning_image = self.sd_model.get_first_stage_encoding(self.sd_model.encode_first_stage(conditioning_image))
  211. # Create the concatenated conditioning tensor to be fed to `c_concat`
  212. conditioning_mask = torch.nn.functional.interpolate(conditioning_mask, size=latent_image.shape[-2:])
  213. conditioning_mask = conditioning_mask.expand(conditioning_image.shape[0], -1, -1, -1)
  214. image_conditioning = torch.cat([conditioning_mask, conditioning_image], dim=1)
  215. image_conditioning = image_conditioning.to(shared.device).type(self.sd_model.dtype)
  216. return image_conditioning
  217. def img2img_image_conditioning(self, source_image, latent_image, image_mask=None):
  218. source_image = devices.cond_cast_float(source_image)
  219. # HACK: Using introspection as the Depth2Image model doesn't appear to uniquely
  220. # identify itself with a field common to all models. The conditioning_key is also hybrid.
  221. if isinstance(self.sd_model, LatentDepth2ImageDiffusion):
  222. return self.depth2img_image_conditioning(source_image)
  223. if self.sd_model.cond_stage_key == "edit":
  224. return self.edit_image_conditioning(source_image)
  225. if self.sampler.conditioning_key in {'hybrid', 'concat'}:
  226. return self.inpainting_image_conditioning(source_image, latent_image, image_mask=image_mask)
  227. if self.sampler.conditioning_key == "crossattn-adm":
  228. return self.unclip_image_conditioning(source_image)
  229. # Dummy zero conditioning if we're not using inpainting or depth model.
  230. return latent_image.new_zeros(latent_image.shape[0], 5, 1, 1)
  231. def init(self, all_prompts, all_seeds, all_subseeds):
  232. pass
  233. def sample(self, conditioning, unconditional_conditioning, seeds, subseeds, subseed_strength, prompts):
  234. raise NotImplementedError()
  235. def close(self):
  236. self.sampler = None
  237. self.c = None
  238. self.uc = None
  239. if not opts.persistent_cond_cache:
  240. StableDiffusionProcessing.cached_c = [None, None]
  241. StableDiffusionProcessing.cached_uc = [None, None]
  242. def get_token_merging_ratio(self, for_hr=False):
  243. if for_hr:
  244. return self.token_merging_ratio_hr or opts.token_merging_ratio_hr or self.token_merging_ratio or opts.token_merging_ratio
  245. return self.token_merging_ratio or opts.token_merging_ratio
  246. def setup_prompts(self):
  247. if type(self.prompt) == list:
  248. self.all_prompts = self.prompt
  249. else:
  250. self.all_prompts = self.batch_size * self.n_iter * [self.prompt]
  251. if type(self.negative_prompt) == list:
  252. self.all_negative_prompts = self.negative_prompt
  253. else:
  254. self.all_negative_prompts = self.batch_size * self.n_iter * [self.negative_prompt]
  255. self.all_prompts = [shared.prompt_styles.apply_styles_to_prompt(x, self.styles) for x in self.all_prompts]
  256. self.all_negative_prompts = [shared.prompt_styles.apply_negative_styles_to_prompt(x, self.styles) for x in self.all_negative_prompts]
  257. def cached_params(self, required_prompts, steps, extra_network_data):
  258. """Returns parameters that invalidate the cond cache if changed"""
  259. return (
  260. required_prompts,
  261. steps,
  262. opts.CLIP_stop_at_last_layers,
  263. shared.sd_model.sd_checkpoint_info,
  264. extra_network_data,
  265. opts.sdxl_crop_left,
  266. opts.sdxl_crop_top,
  267. self.width,
  268. self.height,
  269. )
  270. def get_conds_with_caching(self, function, required_prompts, steps, caches, extra_network_data):
  271. """
  272. Returns the result of calling function(shared.sd_model, required_prompts, steps)
  273. using a cache to store the result if the same arguments have been used before.
  274. cache is an array containing two elements. The first element is a tuple
  275. representing the previously used arguments, or None if no arguments
  276. have been used before. The second element is where the previously
  277. computed result is stored.
  278. caches is a list with items described above.
  279. """
  280. cached_params = self.cached_params(required_prompts, steps, extra_network_data)
  281. for cache in caches:
  282. if cache[0] is not None and cached_params == cache[0]:
  283. return cache[1]
  284. cache = caches[0]
  285. with devices.autocast():
  286. cache[1] = function(shared.sd_model, required_prompts, steps)
  287. cache[0] = cached_params
  288. return cache[1]
  289. def setup_conds(self):
  290. prompts = prompt_parser.SdConditioning(self.prompts, width=self.width, height=self.height)
  291. negative_prompts = prompt_parser.SdConditioning(self.negative_prompts, width=self.width, height=self.height, is_negative_prompt=True)
  292. sampler_config = sd_samplers.find_sampler_config(self.sampler_name)
  293. self.step_multiplier = 2 if sampler_config and sampler_config.options.get("second_order", False) else 1
  294. self.uc = self.get_conds_with_caching(prompt_parser.get_learned_conditioning, negative_prompts, self.steps * self.step_multiplier, [self.cached_uc], self.extra_network_data)
  295. self.c = self.get_conds_with_caching(prompt_parser.get_multicond_learned_conditioning, prompts, self.steps * self.step_multiplier, [self.cached_c], self.extra_network_data)
  296. def parse_extra_network_prompts(self):
  297. self.prompts, self.extra_network_data = extra_networks.parse_prompts(self.prompts)
  298. def save_samples(self) -> bool:
  299. """Returns whether generated images need to be written to disk"""
  300. return opts.samples_save and not self.do_not_save_samples and (opts.save_incomplete_images or not state.interrupted and not state.skipped)
  301. class Processed:
  302. 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=""):
  303. self.images = images_list
  304. self.prompt = p.prompt
  305. self.negative_prompt = p.negative_prompt
  306. self.seed = seed
  307. self.subseed = subseed
  308. self.subseed_strength = p.subseed_strength
  309. self.info = info
  310. self.comments = comments
  311. self.width = p.width
  312. self.height = p.height
  313. self.sampler_name = p.sampler_name
  314. self.cfg_scale = p.cfg_scale
  315. self.image_cfg_scale = getattr(p, 'image_cfg_scale', None)
  316. self.steps = p.steps
  317. self.batch_size = p.batch_size
  318. self.restore_faces = p.restore_faces
  319. self.face_restoration_model = opts.face_restoration_model if p.restore_faces else None
  320. self.sd_model_hash = shared.sd_model.sd_model_hash
  321. self.seed_resize_from_w = p.seed_resize_from_w
  322. self.seed_resize_from_h = p.seed_resize_from_h
  323. self.denoising_strength = getattr(p, 'denoising_strength', None)
  324. self.extra_generation_params = p.extra_generation_params
  325. self.index_of_first_image = index_of_first_image
  326. self.styles = p.styles
  327. self.job_timestamp = state.job_timestamp
  328. self.clip_skip = opts.CLIP_stop_at_last_layers
  329. self.token_merging_ratio = p.token_merging_ratio
  330. self.token_merging_ratio_hr = p.token_merging_ratio_hr
  331. self.eta = p.eta
  332. self.ddim_discretize = p.ddim_discretize
  333. self.s_churn = p.s_churn
  334. self.s_tmin = p.s_tmin
  335. self.s_tmax = p.s_tmax
  336. self.s_noise = p.s_noise
  337. self.s_min_uncond = p.s_min_uncond
  338. self.sampler_noise_scheduler_override = p.sampler_noise_scheduler_override
  339. self.prompt = self.prompt if type(self.prompt) != list else self.prompt[0]
  340. self.negative_prompt = self.negative_prompt if type(self.negative_prompt) != list else self.negative_prompt[0]
  341. self.seed = int(self.seed if type(self.seed) != list else self.seed[0]) if self.seed is not None else -1
  342. self.subseed = int(self.subseed if type(self.subseed) != list else self.subseed[0]) if self.subseed is not None else -1
  343. self.is_using_inpainting_conditioning = p.is_using_inpainting_conditioning
  344. self.all_prompts = all_prompts or p.all_prompts or [self.prompt]
  345. self.all_negative_prompts = all_negative_prompts or p.all_negative_prompts or [self.negative_prompt]
  346. self.all_seeds = all_seeds or p.all_seeds or [self.seed]
  347. self.all_subseeds = all_subseeds or p.all_subseeds or [self.subseed]
  348. self.infotexts = infotexts or [info]
  349. def js(self):
  350. obj = {
  351. "prompt": self.all_prompts[0],
  352. "all_prompts": self.all_prompts,
  353. "negative_prompt": self.all_negative_prompts[0],
  354. "all_negative_prompts": self.all_negative_prompts,
  355. "seed": self.seed,
  356. "all_seeds": self.all_seeds,
  357. "subseed": self.subseed,
  358. "all_subseeds": self.all_subseeds,
  359. "subseed_strength": self.subseed_strength,
  360. "width": self.width,
  361. "height": self.height,
  362. "sampler_name": self.sampler_name,
  363. "cfg_scale": self.cfg_scale,
  364. "steps": self.steps,
  365. "batch_size": self.batch_size,
  366. "restore_faces": self.restore_faces,
  367. "face_restoration_model": self.face_restoration_model,
  368. "sd_model_hash": self.sd_model_hash,
  369. "seed_resize_from_w": self.seed_resize_from_w,
  370. "seed_resize_from_h": self.seed_resize_from_h,
  371. "denoising_strength": self.denoising_strength,
  372. "extra_generation_params": self.extra_generation_params,
  373. "index_of_first_image": self.index_of_first_image,
  374. "infotexts": self.infotexts,
  375. "styles": self.styles,
  376. "job_timestamp": self.job_timestamp,
  377. "clip_skip": self.clip_skip,
  378. "is_using_inpainting_conditioning": self.is_using_inpainting_conditioning,
  379. }
  380. return json.dumps(obj)
  381. def infotext(self, p: StableDiffusionProcessing, index):
  382. 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)
  383. def get_token_merging_ratio(self, for_hr=False):
  384. return self.token_merging_ratio_hr if for_hr else self.token_merging_ratio
  385. # from https://discuss.pytorch.org/t/help-regarding-slerp-function-for-generative-model-sampling/32475/3
  386. def slerp(val, low, high):
  387. low_norm = low/torch.norm(low, dim=1, keepdim=True)
  388. high_norm = high/torch.norm(high, dim=1, keepdim=True)
  389. dot = (low_norm*high_norm).sum(1)
  390. if dot.mean() > 0.9995:
  391. return low * val + high * (1 - val)
  392. omega = torch.acos(dot)
  393. so = torch.sin(omega)
  394. res = (torch.sin((1.0-val)*omega)/so).unsqueeze(1)*low + (torch.sin(val*omega)/so).unsqueeze(1) * high
  395. return res
  396. def create_random_tensors(shape, seeds, subseeds=None, subseed_strength=0.0, seed_resize_from_h=0, seed_resize_from_w=0, p=None):
  397. eta_noise_seed_delta = opts.eta_noise_seed_delta or 0
  398. xs = []
  399. # if we have multiple seeds, this means we are working with batch size>1; this then
  400. # enables the generation of additional tensors with noise that the sampler will use during its processing.
  401. # Using those pre-generated tensors instead of simple torch.randn allows a batch with seeds [100, 101] to
  402. # produce the same images as with two batches [100], [101].
  403. 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):
  404. sampler_noises = [[] for _ in range(p.sampler.number_of_needed_noises(p))]
  405. else:
  406. sampler_noises = None
  407. for i, seed in enumerate(seeds):
  408. 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)
  409. subnoise = None
  410. if subseeds is not None and subseed_strength != 0:
  411. subseed = 0 if i >= len(subseeds) else subseeds[i]
  412. subnoise = devices.randn(subseed, noise_shape)
  413. # randn results depend on device; gpu and cpu get different results for same seed;
  414. # the way I see it, it's better to do this on CPU, so that everyone gets same result;
  415. # but the original script had it like this, so I do not dare change it for now because
  416. # it will break everyone's seeds.
  417. noise = devices.randn(seed, noise_shape)
  418. if subnoise is not None:
  419. noise = slerp(subseed_strength, noise, subnoise)
  420. if noise_shape != shape:
  421. x = devices.randn(seed, shape)
  422. dx = (shape[2] - noise_shape[2]) // 2
  423. dy = (shape[1] - noise_shape[1]) // 2
  424. w = noise_shape[2] if dx >= 0 else noise_shape[2] + 2 * dx
  425. h = noise_shape[1] if dy >= 0 else noise_shape[1] + 2 * dy
  426. tx = 0 if dx < 0 else dx
  427. ty = 0 if dy < 0 else dy
  428. dx = max(-dx, 0)
  429. dy = max(-dy, 0)
  430. x[:, ty:ty+h, tx:tx+w] = noise[:, dy:dy+h, dx:dx+w]
  431. noise = x
  432. if sampler_noises is not None:
  433. cnt = p.sampler.number_of_needed_noises(p)
  434. if eta_noise_seed_delta > 0:
  435. devices.manual_seed(seed + eta_noise_seed_delta)
  436. for j in range(cnt):
  437. sampler_noises[j].append(devices.randn_without_seed(tuple(noise_shape)))
  438. xs.append(noise)
  439. if sampler_noises is not None:
  440. p.sampler.sampler_noises = [torch.stack(n).to(shared.device) for n in sampler_noises]
  441. x = torch.stack(xs).to(shared.device)
  442. return x
  443. class DecodedSamples(list):
  444. already_decoded = True
  445. def decode_latent_batch(model, batch, target_device=None, check_for_nans=False):
  446. samples = DecodedSamples()
  447. for i in range(batch.shape[0]):
  448. sample = decode_first_stage(model, batch[i:i + 1])[0]
  449. if check_for_nans:
  450. try:
  451. devices.test_for_nans(sample, "vae")
  452. except devices.NansException as e:
  453. if devices.dtype_vae == torch.float32 or not shared.opts.auto_vae_precision:
  454. raise e
  455. errors.print_error_explanation(
  456. "A tensor with all NaNs was produced in VAE.\n"
  457. "Web UI will now convert VAE into 32-bit float and retry.\n"
  458. "To disable this behavior, disable the 'Automaticlly revert VAE to 32-bit floats' setting.\n"
  459. "To always start with 32-bit VAE, use --no-half-vae commandline flag."
  460. )
  461. devices.dtype_vae = torch.float32
  462. model.first_stage_model.to(devices.dtype_vae)
  463. batch = batch.to(devices.dtype_vae)
  464. sample = decode_first_stage(model, batch[i:i + 1])[0]
  465. if target_device is not None:
  466. sample = sample.to(target_device)
  467. samples.append(sample)
  468. return samples
  469. def get_fixed_seed(seed):
  470. if seed is None or seed == '' or seed == -1:
  471. return int(random.randrange(4294967294))
  472. return seed
  473. def fix_seed(p):
  474. p.seed = get_fixed_seed(p.seed)
  475. p.subseed = get_fixed_seed(p.subseed)
  476. def program_version():
  477. import launch
  478. res = launch.git_tag()
  479. if res == "<none>":
  480. res = None
  481. return res
  482. def create_infotext(p, all_prompts, all_seeds, all_subseeds, comments=None, iteration=0, position_in_batch=0, use_main_prompt=False, index=None, all_negative_prompts=None):
  483. if index is None:
  484. index = position_in_batch + iteration * p.batch_size
  485. if all_negative_prompts is None:
  486. all_negative_prompts = p.all_negative_prompts
  487. clip_skip = getattr(p, 'clip_skip', opts.CLIP_stop_at_last_layers)
  488. enable_hr = getattr(p, 'enable_hr', False)
  489. token_merging_ratio = p.get_token_merging_ratio()
  490. token_merging_ratio_hr = p.get_token_merging_ratio(for_hr=True)
  491. uses_ensd = opts.eta_noise_seed_delta != 0
  492. if uses_ensd:
  493. uses_ensd = sd_samplers_common.is_sampler_using_eta_noise_seed_delta(p)
  494. generation_params = {
  495. "Steps": p.steps,
  496. "Sampler": p.sampler_name,
  497. "CFG scale": p.cfg_scale,
  498. "Image CFG scale": getattr(p, 'image_cfg_scale', None),
  499. "Seed": p.all_seeds[0] if use_main_prompt else all_seeds[index],
  500. "Face restoration": (opts.face_restoration_model if p.restore_faces else None),
  501. "Size": f"{p.width}x{p.height}",
  502. "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),
  503. "Model": (None if not opts.add_model_name_to_info else shared.sd_model.sd_checkpoint_info.name_for_extra),
  504. "Variation seed": (None if p.subseed_strength == 0 else (p.all_subseeds[0] if use_main_prompt else all_subseeds[index])),
  505. "Variation seed strength": (None if p.subseed_strength == 0 else p.subseed_strength),
  506. "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}"),
  507. "Denoising strength": getattr(p, 'denoising_strength', None),
  508. "Conditional mask weight": getattr(p, "inpainting_mask_weight", shared.opts.inpainting_mask_weight) if p.is_using_inpainting_conditioning else None,
  509. "Clip skip": None if clip_skip <= 1 else clip_skip,
  510. "ENSD": opts.eta_noise_seed_delta if uses_ensd else None,
  511. "Token merging ratio": None if token_merging_ratio == 0 else token_merging_ratio,
  512. "Token merging ratio hr": None if not enable_hr or token_merging_ratio_hr == 0 else token_merging_ratio_hr,
  513. "Init image hash": getattr(p, 'init_img_hash', None),
  514. "RNG": opts.randn_source if opts.randn_source != "GPU" and opts.randn_source != "NV" else None,
  515. "NGMS": None if p.s_min_uncond == 0 else p.s_min_uncond,
  516. **p.extra_generation_params,
  517. "Version": program_version() if opts.add_version_to_infotext else None,
  518. "User": p.user if opts.add_user_name_to_info else None,
  519. }
  520. 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])
  521. prompt_text = p.prompt if use_main_prompt else all_prompts[index]
  522. negative_prompt_text = f"\nNegative prompt: {all_negative_prompts[index]}" if all_negative_prompts[index] else ""
  523. return f"{prompt_text}{negative_prompt_text}\n{generation_params_text}".strip()
  524. def process_images(p: StableDiffusionProcessing) -> Processed:
  525. if p.scripts is not None:
  526. p.scripts.before_process(p)
  527. stored_opts = {k: opts.data[k] for k in p.override_settings.keys()}
  528. try:
  529. # if no checkpoint override or the override checkpoint can't be found, remove override entry and load opts checkpoint
  530. if sd_models.checkpoint_aliases.get(p.override_settings.get('sd_model_checkpoint')) is None:
  531. p.override_settings.pop('sd_model_checkpoint', None)
  532. sd_models.reload_model_weights()
  533. for k, v in p.override_settings.items():
  534. setattr(opts, k, v)
  535. if k == 'sd_model_checkpoint':
  536. sd_models.reload_model_weights()
  537. if k == 'sd_vae':
  538. sd_vae.reload_vae_weights()
  539. sd_models.apply_token_merging(p.sd_model, p.get_token_merging_ratio())
  540. res = process_images_inner(p)
  541. finally:
  542. sd_models.apply_token_merging(p.sd_model, 0)
  543. # restore opts to original state
  544. if p.override_settings_restore_afterwards:
  545. for k, v in stored_opts.items():
  546. setattr(opts, k, v)
  547. if k == 'sd_vae':
  548. sd_vae.reload_vae_weights()
  549. return res
  550. def process_images_inner(p: StableDiffusionProcessing) -> Processed:
  551. """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"""
  552. if type(p.prompt) == list:
  553. assert(len(p.prompt) > 0)
  554. else:
  555. assert p.prompt is not None
  556. devices.torch_gc()
  557. seed = get_fixed_seed(p.seed)
  558. subseed = get_fixed_seed(p.subseed)
  559. modules.sd_hijack.model_hijack.apply_circular(p.tiling)
  560. modules.sd_hijack.model_hijack.clear_comments()
  561. comments = {}
  562. p.setup_prompts()
  563. if type(seed) == list:
  564. p.all_seeds = seed
  565. else:
  566. p.all_seeds = [int(seed) + (x if p.subseed_strength == 0 else 0) for x in range(len(p.all_prompts))]
  567. if type(subseed) == list:
  568. p.all_subseeds = subseed
  569. else:
  570. p.all_subseeds = [int(subseed) + x for x in range(len(p.all_prompts))]
  571. if os.path.exists(cmd_opts.embeddings_dir) and not p.do_not_reload_embeddings:
  572. model_hijack.embedding_db.load_textual_inversion_embeddings()
  573. if p.scripts is not None:
  574. p.scripts.process(p)
  575. infotexts = []
  576. output_images = []
  577. with torch.no_grad(), p.sd_model.ema_scope():
  578. with devices.autocast():
  579. p.init(p.all_prompts, p.all_seeds, p.all_subseeds)
  580. # for OSX, loading the model during sampling changes the generated picture, so it is loaded here
  581. if shared.opts.live_previews_enable and opts.show_progress_type == "Approx NN":
  582. sd_vae_approx.model()
  583. sd_unet.apply_unet()
  584. if state.job_count == -1:
  585. state.job_count = p.n_iter
  586. for n in range(p.n_iter):
  587. p.iteration = n
  588. if state.skipped:
  589. state.skipped = False
  590. if state.interrupted:
  591. break
  592. p.prompts = p.all_prompts[n * p.batch_size:(n + 1) * p.batch_size]
  593. p.negative_prompts = p.all_negative_prompts[n * p.batch_size:(n + 1) * p.batch_size]
  594. p.seeds = p.all_seeds[n * p.batch_size:(n + 1) * p.batch_size]
  595. p.subseeds = p.all_subseeds[n * p.batch_size:(n + 1) * p.batch_size]
  596. if p.scripts is not None:
  597. p.scripts.before_process_batch(p, batch_number=n, prompts=p.prompts, seeds=p.seeds, subseeds=p.subseeds)
  598. if len(p.prompts) == 0:
  599. break
  600. p.parse_extra_network_prompts()
  601. if not p.disable_extra_networks:
  602. with devices.autocast():
  603. extra_networks.activate(p, p.extra_network_data)
  604. if p.scripts is not None:
  605. p.scripts.process_batch(p, batch_number=n, prompts=p.prompts, seeds=p.seeds, subseeds=p.subseeds)
  606. # params.txt should be saved after scripts.process_batch, since the
  607. # infotext could be modified by that callback
  608. # Example: a wildcard processed by process_batch sets an extra model
  609. # strength, which is saved as "Model Strength: 1.0" in the infotext
  610. if n == 0:
  611. with open(os.path.join(paths.data_path, "params.txt"), "w", encoding="utf8") as file:
  612. processed = Processed(p, [], p.seed, "")
  613. file.write(processed.infotext(p, 0))
  614. p.setup_conds()
  615. for comment in model_hijack.comments:
  616. comments[comment] = 1
  617. p.extra_generation_params.update(model_hijack.extra_generation_params)
  618. if p.n_iter > 1:
  619. shared.state.job = f"Batch {n+1} out of {p.n_iter}"
  620. with devices.without_autocast() if devices.unet_needs_upcast else devices.autocast():
  621. samples_ddim = p.sample(conditioning=p.c, unconditional_conditioning=p.uc, seeds=p.seeds, subseeds=p.subseeds, subseed_strength=p.subseed_strength, prompts=p.prompts)
  622. if getattr(samples_ddim, 'already_decoded', False):
  623. x_samples_ddim = samples_ddim
  624. else:
  625. if opts.sd_vae_decode_method != 'Full':
  626. p.extra_generation_params['VAE Decoder'] = opts.sd_vae_decode_method
  627. x_samples_ddim = decode_latent_batch(p.sd_model, samples_ddim, target_device=devices.cpu, check_for_nans=True)
  628. x_samples_ddim = torch.stack(x_samples_ddim).float()
  629. x_samples_ddim = torch.clamp((x_samples_ddim + 1.0) / 2.0, min=0.0, max=1.0)
  630. del samples_ddim
  631. if lowvram.is_enabled(shared.sd_model):
  632. lowvram.send_everything_to_cpu()
  633. devices.torch_gc()
  634. if p.scripts is not None:
  635. p.scripts.postprocess_batch(p, x_samples_ddim, batch_number=n)
  636. p.prompts = p.all_prompts[n * p.batch_size:(n + 1) * p.batch_size]
  637. p.negative_prompts = p.all_negative_prompts[n * p.batch_size:(n + 1) * p.batch_size]
  638. batch_params = scripts.PostprocessBatchListArgs(list(x_samples_ddim))
  639. p.scripts.postprocess_batch_list(p, batch_params, batch_number=n)
  640. x_samples_ddim = batch_params.images
  641. def infotext(index=0, use_main_prompt=False):
  642. return create_infotext(p, p.prompts, p.seeds, p.subseeds, use_main_prompt=use_main_prompt, index=index, all_negative_prompts=p.negative_prompts)
  643. save_samples = p.save_samples()
  644. for i, x_sample in enumerate(x_samples_ddim):
  645. p.batch_index = i
  646. x_sample = 255. * np.moveaxis(x_sample.cpu().numpy(), 0, 2)
  647. x_sample = x_sample.astype(np.uint8)
  648. if p.restore_faces:
  649. if save_samples and opts.save_images_before_face_restoration:
  650. images.save_image(Image.fromarray(x_sample), p.outpath_samples, "", p.seeds[i], p.prompts[i], opts.samples_format, info=infotext(i), p=p, suffix="-before-face-restoration")
  651. devices.torch_gc()
  652. x_sample = modules.face_restoration.restore_faces(x_sample)
  653. devices.torch_gc()
  654. image = Image.fromarray(x_sample)
  655. if p.scripts is not None:
  656. pp = scripts.PostprocessImageArgs(image)
  657. p.scripts.postprocess_image(p, pp)
  658. image = pp.image
  659. if p.color_corrections is not None and i < len(p.color_corrections):
  660. if save_samples and opts.save_images_before_color_correction:
  661. image_without_cc = apply_overlay(image, p.paste_to, i, p.overlay_images)
  662. images.save_image(image_without_cc, p.outpath_samples, "", p.seeds[i], p.prompts[i], opts.samples_format, info=infotext(i), p=p, suffix="-before-color-correction")
  663. image = apply_color_correction(p.color_corrections[i], image)
  664. image = apply_overlay(image, p.paste_to, i, p.overlay_images)
  665. if save_samples:
  666. images.save_image(image, p.outpath_samples, "", p.seeds[i], p.prompts[i], opts.samples_format, info=infotext(i), p=p)
  667. text = infotext(i)
  668. infotexts.append(text)
  669. if opts.enable_pnginfo:
  670. image.info["parameters"] = text
  671. output_images.append(image)
  672. if save_samples and hasattr(p, 'mask_for_overlay') and p.mask_for_overlay and any([opts.save_mask, opts.save_mask_composite, opts.return_mask, opts.return_mask_composite]):
  673. image_mask = p.mask_for_overlay.convert('RGB')
  674. image_mask_composite = Image.composite(image.convert('RGBA').convert('RGBa'), Image.new('RGBa', image.size), images.resize_image(2, p.mask_for_overlay, image.width, image.height).convert('L')).convert('RGBA')
  675. if opts.save_mask:
  676. images.save_image(image_mask, p.outpath_samples, "", p.seeds[i], p.prompts[i], opts.samples_format, info=infotext(i), p=p, suffix="-mask")
  677. if opts.save_mask_composite:
  678. images.save_image(image_mask_composite, p.outpath_samples, "", p.seeds[i], p.prompts[i], opts.samples_format, info=infotext(i), p=p, suffix="-mask-composite")
  679. if opts.return_mask:
  680. output_images.append(image_mask)
  681. if opts.return_mask_composite:
  682. output_images.append(image_mask_composite)
  683. del x_samples_ddim
  684. devices.torch_gc()
  685. state.nextjob()
  686. p.color_corrections = None
  687. index_of_first_image = 0
  688. unwanted_grid_because_of_img_count = len(output_images) < 2 and opts.grid_only_if_multiple
  689. if (opts.return_grid or opts.grid_save) and not p.do_not_save_grid and not unwanted_grid_because_of_img_count:
  690. grid = images.image_grid(output_images, p.batch_size)
  691. if opts.return_grid:
  692. text = infotext(use_main_prompt=True)
  693. infotexts.insert(0, text)
  694. if opts.enable_pnginfo:
  695. grid.info["parameters"] = text
  696. output_images.insert(0, grid)
  697. index_of_first_image = 1
  698. if opts.grid_save:
  699. images.save_image(grid, p.outpath_grids, "grid", p.all_seeds[0], p.all_prompts[0], opts.grid_format, info=infotext(use_main_prompt=True), short_filename=not opts.grid_extended_filename, p=p, grid=True)
  700. if not p.disable_extra_networks and p.extra_network_data:
  701. extra_networks.deactivate(p, p.extra_network_data)
  702. devices.torch_gc()
  703. res = Processed(
  704. p,
  705. images_list=output_images,
  706. seed=p.all_seeds[0],
  707. info=infotexts[0],
  708. comments="".join(f"{comment}\n" for comment in comments),
  709. subseed=p.all_subseeds[0],
  710. index_of_first_image=index_of_first_image,
  711. infotexts=infotexts,
  712. )
  713. if p.scripts is not None:
  714. p.scripts.postprocess(p, res)
  715. return res
  716. def old_hires_fix_first_pass_dimensions(width, height):
  717. """old algorithm for auto-calculating first pass size"""
  718. desired_pixel_count = 512 * 512
  719. actual_pixel_count = width * height
  720. scale = math.sqrt(desired_pixel_count / actual_pixel_count)
  721. width = math.ceil(scale * width / 64) * 64
  722. height = math.ceil(scale * height / 64) * 64
  723. return width, height
  724. class StableDiffusionProcessingTxt2Img(StableDiffusionProcessing):
  725. sampler = None
  726. cached_hr_uc = [None, None]
  727. cached_hr_c = [None, None]
  728. 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, hr_checkpoint_name: str = None, hr_sampler_name: str = None, hr_prompt: str = '', hr_negative_prompt: str = '', **kwargs):
  729. super().__init__(**kwargs)
  730. self.enable_hr = enable_hr
  731. self.denoising_strength = denoising_strength
  732. self.hr_scale = hr_scale
  733. self.hr_upscaler = hr_upscaler
  734. self.hr_second_pass_steps = hr_second_pass_steps
  735. self.hr_resize_x = hr_resize_x
  736. self.hr_resize_y = hr_resize_y
  737. self.hr_upscale_to_x = hr_resize_x
  738. self.hr_upscale_to_y = hr_resize_y
  739. self.hr_checkpoint_name = hr_checkpoint_name
  740. self.hr_checkpoint_info = None
  741. self.hr_sampler_name = hr_sampler_name
  742. self.hr_prompt = hr_prompt
  743. self.hr_negative_prompt = hr_negative_prompt
  744. self.all_hr_prompts = None
  745. self.all_hr_negative_prompts = None
  746. self.latent_scale_mode = None
  747. if firstphase_width != 0 or firstphase_height != 0:
  748. self.hr_upscale_to_x = self.width
  749. self.hr_upscale_to_y = self.height
  750. self.width = firstphase_width
  751. self.height = firstphase_height
  752. self.truncate_x = 0
  753. self.truncate_y = 0
  754. self.applied_old_hires_behavior_to = None
  755. self.hr_prompts = None
  756. self.hr_negative_prompts = None
  757. self.hr_extra_network_data = None
  758. self.cached_hr_uc = StableDiffusionProcessingTxt2Img.cached_hr_uc
  759. self.cached_hr_c = StableDiffusionProcessingTxt2Img.cached_hr_c
  760. self.hr_c = None
  761. self.hr_uc = None
  762. def init(self, all_prompts, all_seeds, all_subseeds):
  763. if self.enable_hr:
  764. if self.hr_checkpoint_name:
  765. self.hr_checkpoint_info = sd_models.get_closet_checkpoint_match(self.hr_checkpoint_name)
  766. if self.hr_checkpoint_info is None:
  767. raise Exception(f'Could not find checkpoint with name {self.hr_checkpoint_name}')
  768. self.extra_generation_params["Hires checkpoint"] = self.hr_checkpoint_info.short_title
  769. if self.hr_sampler_name is not None and self.hr_sampler_name != self.sampler_name:
  770. self.extra_generation_params["Hires sampler"] = self.hr_sampler_name
  771. if tuple(self.hr_prompt) != tuple(self.prompt):
  772. self.extra_generation_params["Hires prompt"] = self.hr_prompt
  773. if tuple(self.hr_negative_prompt) != tuple(self.negative_prompt):
  774. self.extra_generation_params["Hires negative prompt"] = self.hr_negative_prompt
  775. self.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")
  776. if self.enable_hr and self.latent_scale_mode is None:
  777. if not any(x.name == self.hr_upscaler for x in shared.sd_upscalers):
  778. raise Exception(f"could not find upscaler named {self.hr_upscaler}")
  779. if opts.use_old_hires_fix_width_height and self.applied_old_hires_behavior_to != (self.width, self.height):
  780. self.hr_resize_x = self.width
  781. self.hr_resize_y = self.height
  782. self.hr_upscale_to_x = self.width
  783. self.hr_upscale_to_y = self.height
  784. self.width, self.height = old_hires_fix_first_pass_dimensions(self.width, self.height)
  785. self.applied_old_hires_behavior_to = (self.width, self.height)
  786. if self.hr_resize_x == 0 and self.hr_resize_y == 0:
  787. self.extra_generation_params["Hires upscale"] = self.hr_scale
  788. self.hr_upscale_to_x = int(self.width * self.hr_scale)
  789. self.hr_upscale_to_y = int(self.height * self.hr_scale)
  790. else:
  791. self.extra_generation_params["Hires resize"] = f"{self.hr_resize_x}x{self.hr_resize_y}"
  792. if self.hr_resize_y == 0:
  793. self.hr_upscale_to_x = self.hr_resize_x
  794. self.hr_upscale_to_y = self.hr_resize_x * self.height // self.width
  795. elif self.hr_resize_x == 0:
  796. self.hr_upscale_to_x = self.hr_resize_y * self.width // self.height
  797. self.hr_upscale_to_y = self.hr_resize_y
  798. else:
  799. target_w = self.hr_resize_x
  800. target_h = self.hr_resize_y
  801. src_ratio = self.width / self.height
  802. dst_ratio = self.hr_resize_x / self.hr_resize_y
  803. if src_ratio < dst_ratio:
  804. self.hr_upscale_to_x = self.hr_resize_x
  805. self.hr_upscale_to_y = self.hr_resize_x * self.height // self.width
  806. else:
  807. self.hr_upscale_to_x = self.hr_resize_y * self.width // self.height
  808. self.hr_upscale_to_y = self.hr_resize_y
  809. self.truncate_x = (self.hr_upscale_to_x - target_w) // opt_f
  810. self.truncate_y = (self.hr_upscale_to_y - target_h) // opt_f
  811. if not state.processing_has_refined_job_count:
  812. if state.job_count == -1:
  813. state.job_count = self.n_iter
  814. shared.total_tqdm.updateTotal((self.steps + (self.hr_second_pass_steps or self.steps)) * state.job_count)
  815. state.job_count = state.job_count * 2
  816. state.processing_has_refined_job_count = True
  817. if self.hr_second_pass_steps:
  818. self.extra_generation_params["Hires steps"] = self.hr_second_pass_steps
  819. if self.hr_upscaler is not None:
  820. self.extra_generation_params["Hires upscaler"] = self.hr_upscaler
  821. def sample(self, conditioning, unconditional_conditioning, seeds, subseeds, subseed_strength, prompts):
  822. self.sampler = sd_samplers.create_sampler(self.sampler_name, self.sd_model)
  823. 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)
  824. samples = self.sampler.sample(self, x, conditioning, unconditional_conditioning, image_conditioning=self.txt2img_image_conditioning(x))
  825. del x
  826. if not self.enable_hr:
  827. return samples
  828. if self.latent_scale_mode is None:
  829. decoded_samples = torch.stack(decode_latent_batch(self.sd_model, samples, target_device=devices.cpu, check_for_nans=True)).to(dtype=torch.float32)
  830. else:
  831. decoded_samples = None
  832. current = shared.sd_model.sd_checkpoint_info
  833. try:
  834. if self.hr_checkpoint_info is not None:
  835. self.sampler = None
  836. sd_models.reload_model_weights(info=self.hr_checkpoint_info)
  837. devices.torch_gc()
  838. return self.sample_hr_pass(samples, decoded_samples, seeds, subseeds, subseed_strength, prompts)
  839. finally:
  840. self.sampler = None
  841. sd_models.reload_model_weights(info=current)
  842. devices.torch_gc()
  843. def sample_hr_pass(self, samples, decoded_samples, seeds, subseeds, subseed_strength, prompts):
  844. self.is_hr_pass = True
  845. target_width = self.hr_upscale_to_x
  846. target_height = self.hr_upscale_to_y
  847. def save_intermediate(image, index):
  848. """saves image before applying hires fix, if enabled in options; takes as an argument either an image or batch with latent space images"""
  849. if not self.save_samples() or not opts.save_images_before_highres_fix:
  850. return
  851. if not isinstance(image, Image.Image):
  852. image = sd_samplers.sample_to_image(image, index, approximation=0)
  853. info = create_infotext(self, self.all_prompts, self.all_seeds, self.all_subseeds, [], iteration=self.iteration, position_in_batch=index)
  854. images.save_image(image, self.outpath_samples, "", seeds[index], prompts[index], opts.samples_format, info=info, p=self, suffix="-before-highres-fix")
  855. img2img_sampler_name = self.hr_sampler_name or self.sampler_name
  856. if self.sampler_name in ['PLMS', 'UniPC']: # PLMS/UniPC do not support img2img so we just silently switch to DDIM
  857. img2img_sampler_name = 'DDIM'
  858. self.sampler = sd_samplers.create_sampler(img2img_sampler_name, self.sd_model)
  859. if self.latent_scale_mode is not None:
  860. for i in range(samples.shape[0]):
  861. save_intermediate(samples, i)
  862. samples = torch.nn.functional.interpolate(samples, size=(target_height // opt_f, target_width // opt_f), mode=self.latent_scale_mode["mode"], antialias=self.latent_scale_mode["antialias"])
  863. # Avoid making the inpainting conditioning unless necessary as
  864. # this does need some extra compute to decode / encode the image again.
  865. if getattr(self, "inpainting_mask_weight", shared.opts.inpainting_mask_weight) < 1.0:
  866. image_conditioning = self.img2img_image_conditioning(decode_first_stage(self.sd_model, samples), samples)
  867. else:
  868. image_conditioning = self.txt2img_image_conditioning(samples)
  869. else:
  870. lowres_samples = torch.clamp((decoded_samples + 1.0) / 2.0, min=0.0, max=1.0)
  871. batch_images = []
  872. for i, x_sample in enumerate(lowres_samples):
  873. x_sample = 255. * np.moveaxis(x_sample.cpu().numpy(), 0, 2)
  874. x_sample = x_sample.astype(np.uint8)
  875. image = Image.fromarray(x_sample)
  876. save_intermediate(image, i)
  877. image = images.resize_image(0, image, target_width, target_height, upscaler_name=self.hr_upscaler)
  878. image = np.array(image).astype(np.float32) / 255.0
  879. image = np.moveaxis(image, 2, 0)
  880. batch_images.append(image)
  881. decoded_samples = torch.from_numpy(np.array(batch_images))
  882. decoded_samples = decoded_samples.to(shared.device, dtype=devices.dtype_vae)
  883. if opts.sd_vae_encode_method != 'Full':
  884. self.extra_generation_params['VAE Encoder'] = opts.sd_vae_encode_method
  885. samples = images_tensor_to_samples(decoded_samples, approximation_indexes.get(opts.sd_vae_encode_method))
  886. image_conditioning = self.img2img_image_conditioning(decoded_samples, samples)
  887. shared.state.nextjob()
  888. 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]
  889. noise = create_random_tensors(samples.shape[1:], seeds=seeds, subseeds=subseeds, subseed_strength=subseed_strength, p=self)
  890. # GC now before running the next img2img to prevent running out of memory
  891. devices.torch_gc()
  892. if not self.disable_extra_networks:
  893. with devices.autocast():
  894. extra_networks.activate(self, self.hr_extra_network_data)
  895. with devices.autocast():
  896. self.calculate_hr_conds()
  897. sd_models.apply_token_merging(self.sd_model, self.get_token_merging_ratio(for_hr=True))
  898. if self.scripts is not None:
  899. self.scripts.before_hr(self)
  900. samples = self.sampler.sample_img2img(self, samples, noise, self.hr_c, self.hr_uc, steps=self.hr_second_pass_steps or self.steps, image_conditioning=image_conditioning)
  901. sd_models.apply_token_merging(self.sd_model, self.get_token_merging_ratio())
  902. decoded_samples = decode_latent_batch(self.sd_model, samples, target_device=devices.cpu, check_for_nans=True)
  903. self.is_hr_pass = False
  904. return decoded_samples
  905. def close(self):
  906. super().close()
  907. self.hr_c = None
  908. self.hr_uc = None
  909. if not opts.persistent_cond_cache:
  910. StableDiffusionProcessingTxt2Img.cached_hr_uc = [None, None]
  911. StableDiffusionProcessingTxt2Img.cached_hr_c = [None, None]
  912. def setup_prompts(self):
  913. super().setup_prompts()
  914. if not self.enable_hr:
  915. return
  916. if self.hr_prompt == '':
  917. self.hr_prompt = self.prompt
  918. if self.hr_negative_prompt == '':
  919. self.hr_negative_prompt = self.negative_prompt
  920. if type(self.hr_prompt) == list:
  921. self.all_hr_prompts = self.hr_prompt
  922. else:
  923. self.all_hr_prompts = self.batch_size * self.n_iter * [self.hr_prompt]
  924. if type(self.hr_negative_prompt) == list:
  925. self.all_hr_negative_prompts = self.hr_negative_prompt
  926. else:
  927. self.all_hr_negative_prompts = self.batch_size * self.n_iter * [self.hr_negative_prompt]
  928. self.all_hr_prompts = [shared.prompt_styles.apply_styles_to_prompt(x, self.styles) for x in self.all_hr_prompts]
  929. self.all_hr_negative_prompts = [shared.prompt_styles.apply_negative_styles_to_prompt(x, self.styles) for x in self.all_hr_negative_prompts]
  930. def calculate_hr_conds(self):
  931. if self.hr_c is not None:
  932. return
  933. hr_prompts = prompt_parser.SdConditioning(self.hr_prompts, width=self.hr_upscale_to_x, height=self.hr_upscale_to_y)
  934. hr_negative_prompts = prompt_parser.SdConditioning(self.hr_negative_prompts, width=self.hr_upscale_to_x, height=self.hr_upscale_to_y, is_negative_prompt=True)
  935. self.hr_uc = self.get_conds_with_caching(prompt_parser.get_learned_conditioning, hr_negative_prompts, self.steps * self.step_multiplier, [self.cached_hr_uc, self.cached_uc], self.hr_extra_network_data)
  936. self.hr_c = self.get_conds_with_caching(prompt_parser.get_multicond_learned_conditioning, hr_prompts, self.steps * self.step_multiplier, [self.cached_hr_c, self.cached_c], self.hr_extra_network_data)
  937. def setup_conds(self):
  938. super().setup_conds()
  939. self.hr_uc = None
  940. self.hr_c = None
  941. if self.enable_hr and self.hr_checkpoint_info is None:
  942. if shared.opts.hires_fix_use_firstpass_conds:
  943. self.calculate_hr_conds()
  944. elif lowvram.is_enabled(shared.sd_model): # if in lowvram mode, we need to calculate conds right away, before the cond NN is unloaded
  945. with devices.autocast():
  946. extra_networks.activate(self, self.hr_extra_network_data)
  947. self.calculate_hr_conds()
  948. with devices.autocast():
  949. extra_networks.activate(self, self.extra_network_data)
  950. def parse_extra_network_prompts(self):
  951. res = super().parse_extra_network_prompts()
  952. if self.enable_hr:
  953. self.hr_prompts = self.all_hr_prompts[self.iteration * self.batch_size:(self.iteration + 1) * self.batch_size]
  954. self.hr_negative_prompts = self.all_hr_negative_prompts[self.iteration * self.batch_size:(self.iteration + 1) * self.batch_size]
  955. self.hr_prompts, self.hr_extra_network_data = extra_networks.parse_prompts(self.hr_prompts)
  956. return res
  957. class StableDiffusionProcessingImg2Img(StableDiffusionProcessing):
  958. sampler = None
  959. def __init__(self, init_images: list = None, resize_mode: int = 0, denoising_strength: float = 0.75, image_cfg_scale: float = None, mask: Any = None, mask_blur: int = None, mask_blur_x: int = 4, mask_blur_y: 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):
  960. super().__init__(**kwargs)
  961. self.init_images = init_images
  962. self.resize_mode: int = resize_mode
  963. self.denoising_strength: float = denoising_strength
  964. self.image_cfg_scale: float = image_cfg_scale if shared.sd_model.cond_stage_key == "edit" else None
  965. self.init_latent = None
  966. self.image_mask = mask
  967. self.latent_mask = None
  968. self.mask_for_overlay = None
  969. if mask_blur is not None:
  970. mask_blur_x = mask_blur
  971. mask_blur_y = mask_blur
  972. self.mask_blur_x = mask_blur_x
  973. self.mask_blur_y = mask_blur_y
  974. self.inpainting_fill = inpainting_fill
  975. self.inpaint_full_res = inpaint_full_res
  976. self.inpaint_full_res_padding = inpaint_full_res_padding
  977. self.inpainting_mask_invert = inpainting_mask_invert
  978. self.initial_noise_multiplier = opts.initial_noise_multiplier if initial_noise_multiplier is None else initial_noise_multiplier
  979. self.mask = None
  980. self.nmask = None
  981. self.image_conditioning = None
  982. def init(self, all_prompts, all_seeds, all_subseeds):
  983. self.sampler = sd_samplers.create_sampler(self.sampler_name, self.sd_model)
  984. crop_region = None
  985. image_mask = self.image_mask
  986. if image_mask is not None:
  987. image_mask = image_mask.convert('L')
  988. if self.inpainting_mask_invert:
  989. image_mask = ImageOps.invert(image_mask)
  990. if self.mask_blur_x > 0:
  991. np_mask = np.array(image_mask)
  992. kernel_size = 2 * int(4 * self.mask_blur_x + 0.5) + 1
  993. np_mask = cv2.GaussianBlur(np_mask, (kernel_size, 1), self.mask_blur_x)
  994. image_mask = Image.fromarray(np_mask)
  995. if self.mask_blur_y > 0:
  996. np_mask = np.array(image_mask)
  997. kernel_size = 2 * int(4 * self.mask_blur_y + 0.5) + 1
  998. np_mask = cv2.GaussianBlur(np_mask, (1, kernel_size), self.mask_blur_y)
  999. image_mask = Image.fromarray(np_mask)
  1000. if self.inpaint_full_res:
  1001. self.mask_for_overlay = image_mask
  1002. mask = image_mask.convert('L')
  1003. crop_region = masking.get_crop_region(np.array(mask), self.inpaint_full_res_padding)
  1004. crop_region = masking.expand_crop_region(crop_region, self.width, self.height, mask.width, mask.height)
  1005. x1, y1, x2, y2 = crop_region
  1006. mask = mask.crop(crop_region)
  1007. image_mask = images.resize_image(2, mask, self.width, self.height)
  1008. self.paste_to = (x1, y1, x2-x1, y2-y1)
  1009. else:
  1010. image_mask = images.resize_image(self.resize_mode, image_mask, self.width, self.height)
  1011. np_mask = np.array(image_mask)
  1012. np_mask = np.clip((np_mask.astype(np.float32)) * 2, 0, 255).astype(np.uint8)
  1013. self.mask_for_overlay = Image.fromarray(np_mask)
  1014. self.overlay_images = []
  1015. latent_mask = self.latent_mask if self.latent_mask is not None else image_mask
  1016. add_color_corrections = opts.img2img_color_correction and self.color_corrections is None
  1017. if add_color_corrections:
  1018. self.color_corrections = []
  1019. imgs = []
  1020. for img in self.init_images:
  1021. # Save init image
  1022. if opts.save_init_img:
  1023. self.init_img_hash = hashlib.md5(img.tobytes()).hexdigest()
  1024. images.save_image(img, path=opts.outdir_init_images, basename=None, forced_filename=self.init_img_hash, save_to_dirs=False)
  1025. image = images.flatten(img, opts.img2img_background_color)
  1026. if crop_region is None and self.resize_mode != 3:
  1027. image = images.resize_image(self.resize_mode, image, self.width, self.height)
  1028. if image_mask is not None:
  1029. image_masked = Image.new('RGBa', (image.width, image.height))
  1030. image_masked.paste(image.convert("RGBA").convert("RGBa"), mask=ImageOps.invert(self.mask_for_overlay.convert('L')))
  1031. self.overlay_images.append(image_masked.convert('RGBA'))
  1032. # crop_region is not None if we are doing inpaint full res
  1033. if crop_region is not None:
  1034. image = image.crop(crop_region)
  1035. image = images.resize_image(2, image, self.width, self.height)
  1036. if image_mask is not None:
  1037. if self.inpainting_fill != 1:
  1038. image = masking.fill(image, latent_mask)
  1039. if add_color_corrections:
  1040. self.color_corrections.append(setup_color_correction(image))
  1041. image = np.array(image).astype(np.float32) / 255.0
  1042. image = np.moveaxis(image, 2, 0)
  1043. imgs.append(image)
  1044. if len(imgs) == 1:
  1045. batch_images = np.expand_dims(imgs[0], axis=0).repeat(self.batch_size, axis=0)
  1046. if self.overlay_images is not None:
  1047. self.overlay_images = self.overlay_images * self.batch_size
  1048. if self.color_corrections is not None and len(self.color_corrections) == 1:
  1049. self.color_corrections = self.color_corrections * self.batch_size
  1050. elif len(imgs) <= self.batch_size:
  1051. self.batch_size = len(imgs)
  1052. batch_images = np.array(imgs)
  1053. else:
  1054. raise RuntimeError(f"bad number of images passed: {len(imgs)}; expecting {self.batch_size} or less")
  1055. image = torch.from_numpy(batch_images)
  1056. image = image.to(shared.device, dtype=devices.dtype_vae)
  1057. if opts.sd_vae_encode_method != 'Full':
  1058. self.extra_generation_params['VAE Encoder'] = opts.sd_vae_encode_method
  1059. self.init_latent = images_tensor_to_samples(image, approximation_indexes.get(opts.sd_vae_encode_method), self.sd_model)
  1060. devices.torch_gc()
  1061. if self.resize_mode == 3:
  1062. self.init_latent = torch.nn.functional.interpolate(self.init_latent, size=(self.height // opt_f, self.width // opt_f), mode="bilinear")
  1063. if image_mask is not None:
  1064. init_mask = latent_mask
  1065. latmask = init_mask.convert('RGB').resize((self.init_latent.shape[3], self.init_latent.shape[2]))
  1066. latmask = np.moveaxis(np.array(latmask, dtype=np.float32), 2, 0) / 255
  1067. latmask = latmask[0]
  1068. latmask = np.around(latmask)
  1069. latmask = np.tile(latmask[None], (4, 1, 1))
  1070. self.mask = torch.asarray(1.0 - latmask).to(shared.device).type(self.sd_model.dtype)
  1071. self.nmask = torch.asarray(latmask).to(shared.device).type(self.sd_model.dtype)
  1072. # this needs to be fixed to be done in sample() using actual seeds for batches
  1073. if self.inpainting_fill == 2:
  1074. 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
  1075. elif self.inpainting_fill == 3:
  1076. self.init_latent = self.init_latent * self.mask
  1077. self.image_conditioning = self.img2img_image_conditioning(image, self.init_latent, image_mask)
  1078. def sample(self, conditioning, unconditional_conditioning, seeds, subseeds, subseed_strength, prompts):
  1079. 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)
  1080. if self.initial_noise_multiplier != 1.0:
  1081. self.extra_generation_params["Noise multiplier"] = self.initial_noise_multiplier
  1082. x *= self.initial_noise_multiplier
  1083. samples = self.sampler.sample_img2img(self, self.init_latent, x, conditioning, unconditional_conditioning, image_conditioning=self.image_conditioning)
  1084. if self.mask is not None:
  1085. samples = samples * self.nmask + self.init_latent * self.mask
  1086. del x
  1087. devices.torch_gc()
  1088. return samples
  1089. def get_token_merging_ratio(self, for_hr=False):
  1090. return self.token_merging_ratio or ("token_merging_ratio" in self.override_settings and opts.token_merging_ratio) or opts.token_merging_ratio_img2img or opts.token_merging_ratio