sd_models_xl.py 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. from __future__ import annotations
  2. import torch
  3. import sgm.models.diffusion
  4. import sgm.modules.diffusionmodules.denoiser_scaling
  5. import sgm.modules.diffusionmodules.discretizer
  6. from modules import devices, shared, prompt_parser
  7. def get_learned_conditioning(self: sgm.models.diffusion.DiffusionEngine, batch: prompt_parser.SdConditioning | list[str]):
  8. for embedder in self.conditioner.embedders:
  9. embedder.ucg_rate = 0.0
  10. width = getattr(batch, 'width', 1024)
  11. height = getattr(batch, 'height', 1024)
  12. is_negative_prompt = getattr(batch, 'is_negative_prompt', False)
  13. aesthetic_score = shared.opts.sdxl_refiner_low_aesthetic_score if is_negative_prompt else shared.opts.sdxl_refiner_high_aesthetic_score
  14. devices_args = dict(device=devices.device, dtype=devices.dtype)
  15. sdxl_conds = {
  16. "txt": batch,
  17. "original_size_as_tuple": torch.tensor([height, width], **devices_args).repeat(len(batch), 1),
  18. "crop_coords_top_left": torch.tensor([shared.opts.sdxl_crop_top, shared.opts.sdxl_crop_left], **devices_args).repeat(len(batch), 1),
  19. "target_size_as_tuple": torch.tensor([height, width], **devices_args).repeat(len(batch), 1),
  20. "aesthetic_score": torch.tensor([aesthetic_score], **devices_args).repeat(len(batch), 1),
  21. }
  22. force_zero_negative_prompt = is_negative_prompt and all(x == '' for x in batch)
  23. c = self.conditioner(sdxl_conds, force_zero_embeddings=['txt'] if force_zero_negative_prompt else [])
  24. return c
  25. def apply_model(self: sgm.models.diffusion.DiffusionEngine, x, t, cond):
  26. return self.model(x, t, cond)
  27. def get_first_stage_encoding(self, x): # SDXL's encode_first_stage does everything so get_first_stage_encoding is just there for compatibility
  28. return x
  29. sgm.models.diffusion.DiffusionEngine.get_learned_conditioning = get_learned_conditioning
  30. sgm.models.diffusion.DiffusionEngine.apply_model = apply_model
  31. sgm.models.diffusion.DiffusionEngine.get_first_stage_encoding = get_first_stage_encoding
  32. def encode_embedding_init_text(self: sgm.modules.GeneralConditioner, init_text, nvpt):
  33. res = []
  34. for embedder in [embedder for embedder in self.embedders if hasattr(embedder, 'encode_embedding_init_text')]:
  35. encoded = embedder.encode_embedding_init_text(init_text, nvpt)
  36. res.append(encoded)
  37. return torch.cat(res, dim=1)
  38. def process_texts(self, texts):
  39. for embedder in [embedder for embedder in self.embedders if hasattr(embedder, 'process_texts')]:
  40. return embedder.process_texts(texts)
  41. def get_target_prompt_token_count(self, token_count):
  42. for embedder in [embedder for embedder in self.embedders if hasattr(embedder, 'get_target_prompt_token_count')]:
  43. return embedder.get_target_prompt_token_count(token_count)
  44. # those additions to GeneralConditioner make it possible to use it as model.cond_stage_model from SD1.5 in exist
  45. sgm.modules.GeneralConditioner.encode_embedding_init_text = encode_embedding_init_text
  46. sgm.modules.GeneralConditioner.process_texts = process_texts
  47. sgm.modules.GeneralConditioner.get_target_prompt_token_count = get_target_prompt_token_count
  48. def extend_sdxl(model):
  49. """this adds a bunch of parameters to make SDXL model look a bit more like SD1.5 to the rest of the codebase."""
  50. dtype = next(model.model.diffusion_model.parameters()).dtype
  51. model.model.diffusion_model.dtype = dtype
  52. model.model.conditioning_key = 'crossattn'
  53. model.cond_stage_key = 'txt'
  54. # model.cond_stage_model will be set in sd_hijack
  55. model.parameterization = "v" if isinstance(model.denoiser.scaling, sgm.modules.diffusionmodules.denoiser_scaling.VScaling) else "eps"
  56. discretization = sgm.modules.diffusionmodules.discretizer.LegacyDDPMDiscretization()
  57. model.alphas_cumprod = torch.asarray(discretization.alphas_cumprod, device=devices.device, dtype=dtype)
  58. model.conditioner.wrapped = torch.nn.Module()
  59. sgm.modules.attention.print = lambda *args: None
  60. sgm.modules.diffusionmodules.model.print = lambda *args: None
  61. sgm.modules.diffusionmodules.openaimodel.print = lambda *args: None
  62. sgm.modules.encoders.modules.print = lambda *args: None
  63. # this gets the code to load the vanilla attention that we override
  64. sgm.modules.attention.SDP_IS_AVAILABLE = True
  65. sgm.modules.attention.XFORMERS_IS_AVAILABLE = False